/* * Copyright © Dave Perrett and Malcolm Jarvis * This code is licensed under the GPL version 2. * For more details, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Class Transmission */ function Transmission(){ // Constants this._FilterAll = 'all'; this._FilterSeeding = 'seeding'; this._FilterDownloading = 'downloading'; this._FilterPaused = 'paused'; this._SortAscending = 'ascending'; this._SortDescending = 'descending'; this._EncryptionPreferred = 'preferred'; this._EncryptionRequired = 'required'; this._current_filter = this._FilterAll; this._current_sort_method = 'queue_order'; this._current_sort_direction = this._SortAscending; this._current_search = ''; this.initialize(); } Transmission.prototype = { /* * Constructor */ initialize: function() { // Before we do anything, browser compatability test if ($.browser.msie) { $('div.torrent_footer').hide(); $('div#unsupported_browser').show(); return; } // Initialize the helper classes this.remote = new TransmissionRemote(this); /* * Private Variables */ this._filter_visible = false; this._inspector_visible = false; this._speed_limit_active = false; // Initialise the torrent lists this._torrents = new Hash(); this._selected_torrents = new Hash(); this._num_paused_torrents = 0; this._num_active_torrents = 0; this._num_selected_paused_torrents = 0; this._num_selected_active_torrents = 0; // Pre-load the images this.preloadImages(); // Get the initial settings from the remote server this.remote.request('requestSettings'); // Observe key presses $(document).bind('keydown', {transmission: this}, this.keyDown); // Buttons $('#pause_all_link').bind('click', {transmission: this}, this.releasePauseAllButton); $('#resume_all_link').bind('click', {transmission: this}, this.releaseResumeAllButton); $('#pause_selected_link').bind('click', {transmission: this}, this.releasePauseSelectedButton); $('#resume_selected_link').bind('click', {transmission: this}, this.releaseResumeSelectedButton); $('#open_link').bind('click', {transmission: this}, this.releaseOpenButton); $('#remove_link').bind('click', {transmission: this}, this.releaseRemoveButton); $('#filter_toggle_link').bind('click', {transmission: this}, this.releaseFilterToggleButton); $('#inspector_link').bind('click', {transmission: this}, this.releaseInspectorButton); $('#filter_all_link').bind('click', {transmission: this}, this.releaseFilterAllButton); $('#filter_downloading_link').bind('click', {transmission: this}, this.releaseFilterDownloadingButton); $('#filter_seeding_link').bind('click', {transmission: this}, this.releaseFilterSeedingButton); $('#filter_paused_link').bind('click', {transmission: this}, this.releaseFilterPausedButton); $('#upload_confirm_button').bind('click', {transmission: this}, this.releaseUploadConfirmButton); $('#upload_cancel_button').bind('click', {transmission: this}, this.releaseUploadCancelButton); $('#prefs_save_button').bind('click', {transmission: this}, this.releasePrefsSaveButton); $('#prefs_cancel_button').bind('click', {transmission: this}, this.releasePrefsCancelButton); $('#speed_limit_button').bind('click', {transmission: this}, this.releaseSpeedLimitButton); // Inspector tabs $('#inspector_tab_info').bind('click', {transmission: this}, this.releaseInspectorTab); $('#inspector_tab_activity').bind('click', {transmission: this}, this.releaseInspectorTab); // Setup the search box this.setupSearchBox(); // Set up the right-click context menu this.createContextMenu(); // Setup the footer settings menu this.createSettingsMenu(); // Setup the preference box this.setupPrefs(); }, /*-------------------------------------------- * * S E T T E R S / G E T T E R S * *--------------------------------------------*/ /* * Return the current filter */ currentFilter: function() { return this._current_filter; }, /* * Set the current filter */ setCurrentFilter: function(filter) { this._current_filter = filter; }, /* * Return the current sort method */ currentSortMethod: function() { return this._current_sort_method; }, /* * Set the current sort method */ setCurrentSortMethod: function(sort_method) { this._current_sort_method = sort_method; }, /* * Return the current sort direction */ currentSortDirection: function() { return this._current_sort_direction; }, /* * Set the current sort direction */ setCurrentSortDirection: function(sort_direction) { this._current_sort_direction = sort_direction; }, /* * Return the current search criteria */ currentSearch: function() { return this._current_search; }, /* * Return the last torrent clicked */ lastTorrentClicked: function() { return this._last_torrent_clicked; }, /* * Set the last torrent clicked */ setLastTorrentClicked: function(torrent) { this._last_torrent_clicked = torrent; }, /* * Return the highest selected (ie closest to the top) torrent in the list */ highestSelected: function() { return this._highest_selected; }, /* * Set the highest selected (ie closest to the top) torrent in the list */ setHighestSelected: function(torrent) { this._highest_selected = torrent; }, /* * Return the lowest selected (ie closest to the bottom) torrent in the list */ lowestSelected: function() { return this._lowest_selected; }, /* * Set the lowest selected (ie closest to the bottom) torrent in the list */ setLowestSelected: function(torrent) { this._lowest_selected = torrent; }, /* * Return the number of selected torrents */ numTorrents: function() { return this._torrents.length(); }, /* * Return the number of selected torrents */ numSelectedTorrents: function() { return this._selected_torrents.length(); }, /* * Return the number of selected active torrents */ numSelectedActiveTorrents: function() { return this._num_selected_active_torrents; }, /* * Return the list of selected torrents */ selectedTorrents: function() { return this._selected_torrents; }, /*-------------------------------------------- * * E V E N T F U N C T I O N S * *--------------------------------------------*/ /* * Process key event */ keyDown: function(event) { var transmission = event.data.transmission; var selected_torrent; // Down Arrow Key if (event.keyCode == 40 && transmission._lowest_selected != null) { selected_torrent = transmission._lowest_selected; if (selected_torrent.nextTorrent() != null) { selected_torrent = selected_torrent.nextTorrent(); } transmission.deselectAll(); selected_torrent.select(); transmission._last_torrent_clicked = selected_torrent; // Up Arrow key } else if (event.keyCode == 38) { selected_torrent = transmission._highest_selected; if (selected_torrent.previousTorrent() != null) { selected_torrent = selected_torrent.previousTorrent(); } transmission.deselectAll(); selected_torrent.select(); transmission._last_torrent_clicked = selected_torrent; } }, /* * Register the specified torrent as selected */ selectTorrent: function(torrent) { // Figure out if this is the highest selected torrent if (this._highestSelected == null || this._highestSelected.position() > torrent.position()) { this.setHighestSelected(torrent); } // Figure out if this is the lowest selected torrent if (this._lowestSelected == null || this._lowestSelected.position() < torrent.position()) { this.setLowestSelected(torrent); } // Store this in the list of selected torrents if (!this._selected_torrents.hasKey(torrent.id())) { this._selected_torrents.set(torrent.id(), torrent); } // Enable/disabled buttons based on the selection if (torrent.isActive()) { this._num_selected_active_torrents++; } else { this._num_selected_paused_torrents++; } this.updateButtonStates(); // Display in Inspector this.updateInspector(); }, /* * Register the specified torrent as de-selected */ deselectTorrent: function(torrent, ignore_inspector_update) { var temp_torrent; var found; if (ignore_inspector_update == null) { ignore_inspector_update = false } // De-select the torrent via css torrent.element().removeClass('selected'); // Remove this from the list of selected torrents transmission._selected_torrents.remove(torrent.id()); if (! ignore_inspector_update) { // May need to re-calculate the controllers highest selected torrent : // work down the list until the next selected torrent if (torrent == transmission._highestSelected) { temp_torrent = torrent._next_torrent; found = false; while (found == false && temp_torrent != null) { if (temp_torrent.isSelected()) { found = true; transmission._highestSelected = temp_torrent; } temp_torrent = temp_torrent.nextTorrent(); } } // May need to re-calculate the controllers lowest selected torrent : // work down the list until the next selected torrent if (torrent == transmission._lowestSelected) { temp_torrent = torrent._previous_torrent; found = false; while (found == false && temp_torrent != null) { if (temp_torrent.isSelected()) { found = true; transmission._lowestSelected = temp_torrent; } temp_torrent = temp_torrent.previousTorrent(); } } // Enable/disabled buttons based on the selection if (torrent.isActive()) { transmission._num_selected_active_torrents--; } else { transmission._num_selected_paused_torrents--; } transmission.updateButtonStates(); // Display in Inspector if (!ignore_inspector_update) { transmission.updateInspector(); } } }, /* * Process a mouse-up event on the 'pause all' button */ releasePauseAllButton: function(event) { event.data.transmission.remote.pauseTorrents([]); }, /* * Process a mouse-up event on the 'resume all' button */ releaseResumeAllButton: function(event) { event.data.transmission.remote.resumeTorrents([]); }, /* * Process a mouse-up event on the 'pause selected' button */ releasePauseSelectedButton: function(event) { event.data.transmission.pauseSelectedTorrents(); }, /* * Process a mouse-up event on the 'resume selected' button */ releaseResumeSelectedButton: function(event) { event.data.transmission.resumeSelectedTorrents(); }, /* * Process a mouse-up event on the 'open' button */ releaseOpenButton: function(event) { event.data.transmission.uploadTorrentFile(); }, /* * Process a mouse-up event on the 'open' button */ releaseUploadCancelButton: function(event) { $('#upload_container').hide(); }, /* * Process a mouse-up event on the 'open' button */ releaseUploadConfirmButton: function(event) { var url_data = jQuery.fieldValue($("#torrent_upload_url")[0]); if (url_data.length == 0) event.data.transmission.uploadTorrentFile(true); else event.data.transmission.remote.addTorrentByURL(); }, /* * Process a mouse-up event on the 'cancel' button in the preferences dialog */ releasePrefsCancelButton: function(event) { $('#prefs_container').hide(); // Reset all the settings transmission.remote.request('resetPrefs'); }, /* * Process a mouse-up event on the 'open' button */ releasePrefsSaveButton: function(event) { event.data.transmission.remote.savePrefs(); }, /* * Process a mouse-up event on the 'remove' button */ releaseRemoveButton: function(event) { event.data.transmission.remote.removeSelectedTorrents(); }, /* * Process a mouse-up event on the 'inspector' button */ releaseInspectorButton: function(event) { event.data.transmission.toggleInspector(); }, /* * Process a mouse-up event on an 'inspector' tab */ releaseInspectorTab: function(event) { // Unselect all the tabs, select the clicked tab, and display the appropriate info var tab_ids = ['inspector_tab_info', 'inspector_tab_activity']; for (i=0; i this._last_torrent_clicked.position()) { torrent.select(); torrent = torrent.previousTorrent(); } // The last clicked torrent is below this one in the list } else if (this._last_torrent_clicked.position() > torrent.position()) { // if the last clicked torrent is not selected, walk up the // list until we find one that is while (!this._last_torrent_clicked.isSelected() && this._last_torrent_clicked.previousTorrent() != null) { this._last_torrent_clicked = this._last_torrent_clicked.previousTorrent(); } while (torrent != null && torrent.position() < this._last_torrent_clicked.position()) { torrent.select(); torrent = torrent.nextTorrent(); } } }, /* * Load a list of torrents into the application */ addTorrents: function(torrent_list, previous_torrent) { var torrent_data; var torrent; // Clear the inspector this.deselectAll(); this.updateInspector(); var num_existing_torrents = this._torrents.length(); var num_new_torrents = torrent_list.length; for (i=0; i 0 && torrent_ids.length != torrent_list.length) { transmission.removeTorrents(transmission._torrents.keys().clone()); torrent_ids = []; } for (i=0; i 0) { transmission.addTorrents(new_torrents, last_torrent); } // Remove any torrents that are displayed but not in the refresh list // The 'update_only' flag is sent went pausing/resuming torrents if (torrent_ids.length > 0) { transmission.removeTorrents(torrent_ids); } // Update the alternating torrent background colors transmission.setTorrentBgColors(); // Update global upload and download speed display transmission.setGlobalSpeeds(torrent_list.length, data.total_upload_rate, data.total_download_rate); // Update the button states transmission.updateButtonStates(); // Update the inspector transmission.updateInspector(); }, /* * Load a list of torrents into the application */ removeTorrents: function(torrent_id_list) { var torrent; if (torrent_id_list.length != 0) { for (i=0; i 0) { transmission.remote.pauseTorrents(transmission._selected_torrents.keys()); } }, /* * Resume any currently selected torrents */ resumeSelectedTorrents: function() { if (transmission.numSelectedTorrents() > 0) { transmission.remote.resumeTorrents(transmission._selected_torrents.keys()); } }, /* * Pre-load the images */ preloadImages: function() { $.preloadImages( 'images/buttons/filter.png', 'images/buttons/filter_on.png', 'images/buttons/footer_action_button.png', 'images/buttons/footer_speed_limit_button.png', 'images/buttons/footer_speed_limit_button_blue.png', 'images/buttons/footer_speed_limit_button_graphite.png', 'images/buttons/footer_speed_limit_button_on.png', 'images/buttons/info.png', 'images/buttons/info_off.png', 'images/buttons/info_on.png', 'images/buttons/info_toolbar_on.png', 'images/buttons/open.png', 'images/buttons/open_on.png', 'images/buttons/pause_all.png', 'images/buttons/pause_all_disabled.png', 'images/buttons/pause_all_on.png', 'images/buttons/pause_off.png', 'images/buttons/pause_on.png', 'images/buttons/pause_selected.png', 'images/buttons/pause_selected_disabled.png', 'images/buttons/pause_selected_on.png', 'images/buttons/remove.png', 'images/buttons/remove_disabled.png', 'images/buttons/remove_on.png', 'images/buttons/resume_all.png', 'images/buttons/resume_all_disabled.png', 'images/buttons/resume_all_on.png', 'images/buttons/resume_off.png', 'images/buttons/resume_on.png', 'images/buttons/resume_selected.png', 'images/buttons/resume_selected_disabled.png', 'images/buttons/resume_selected_on.png', 'images/graphics/browser_firefox.gif', 'images/graphics/browser_opera.gif', 'images/graphics/browser_safari.gif', 'images/graphics/dialog_top.png', 'images/graphics/filter_bar_bg.png', 'images/graphics/filter_hover_left.png', 'images/graphics/filter_hover_right.png', 'images/graphics/filter_selected_left.png', 'images/graphics/filter_selected_right.png', 'images/graphics/footer_bg.png', 'images/graphics/logo.png', 'images/graphics/menu_bg.gif', 'images/graphics/menu_divider.png', 'images/graphics/pause_all_disabled.png', 'images/graphics/status_bar_background.png', 'images/graphics/status_bar_divider.png', 'images/progress/complete.png', 'images/progress/complete_stopped.png', 'images/progress/in_progress.png', 'images/progress/incomplete.png', 'images/progress/incomplete_stopped.png' ); } }