diff --git a/web/index.html b/web/index.html index d99f35164..55626330b 100755 --- a/web/index.html +++ b/web/index.html @@ -330,6 +330,14 @@ DEL Delete selected torrents + + i + Toggle inspector + + + l + Move torrent/Set location + m Move torrent/Set location diff --git a/web/javascript/transmission.js b/web/javascript/transmission.js index 9cc2436ba..af3ca6752 100644 --- a/web/javascript/transmission.js +++ b/web/javascript/transmission.js @@ -455,11 +455,17 @@ Transmission.prototype = { keyDown: function (ev) { var handled = false; var rows = this._rows; + var isInputFocused = $(ev.target).is('input'); + var isDialogVisible = ($('.dialog_heading:visible').length > 0 || $('.ui-dialog:visible').length > 0); + + // hotkeys var up_key = ev.keyCode === 38; // up key pressed var dn_key = ev.keyCode === 40; // down key pressed var a_key = ev.keyCode === 65; // a key pressed var c_key = ev.keyCode === 67; // c key pressed var d_key = ev.keyCode === 68; // d key pressed + var i_key = ev.keyCode === 73; // i key pressed + var l_key = ev.keyCode === 76; // l key pressed var m_key = ev.keyCode === 77; // m key pressed var o_key = ev.keyCode === 79; // o key pressed var p_key = ev.keyCode === 80; // p key pressed @@ -474,62 +480,6 @@ Transmission.prototype = { var esc_key = ev.keyCode === 27; // esc key pressed var comma_key = ev.keyCode === 188; // comma key pressed - if ($('.dialog_heading:visible').length == 0) { - if (comma_key) { - this.togglePrefsDialogClicked(); - handled = true; - } - - if (a_key) { - if (ev.shiftKey) { - this.deselectAll(); - } else { - this.selectAll(); - } - handled = true; - } - - if (c_key) { - this.toggleCompactClicked(); - handled = true; - } - - if ((backspace_key || del_key || d_key) && rows.length) { - this.removeSelectedTorrents(); - handled = true; - } - - if (m_key) { - this.moveSelectedTorrents() - handled = true; - } - - if (o_key || u_key) { - this.openTorrentClicked(ev); - handled = true; - } - - if (p_key) { - this.stopSelectedTorrents(); - handled = true; - } - - if (r_key) { - this.startSelectedTorrents(); - handled = true; - } - - if (t_key) { - this.toggleTurtleClicked(); - handled = true; - } - } - - if (slash_key) { - this.showHotkeysDialog(); - handled = true; - } - if (enter_key) { // handle other dialogs if (dialog && dialog.isVisible()) { @@ -582,42 +532,107 @@ Transmission.prototype = { } } - if ((up_key || dn_key) && rows.length) { - var last = this.indexOfLastTorrent(), - i = last, - anchor = this._shift_index, - r, - min = 0, - max = rows.length - 1; - - if (dn_key && (i + 1 <= max)) { - ++i; - } else if (up_key && (i - 1 >= min)) { - --i; - }; - - var r = rows[i]; - - if (anchor >= 0) { - // user is extending the selection - // with the shift + arrow keys... - if (((anchor <= last) && (last < i)) || ((anchor >= last) && (last > i))) { - this.selectRow(r); - } else if (((anchor >= last) && (i > last)) || ((anchor <= last) && (last > i))) { - this.deselectRow(rows[last]); - } - } else { - if (ev.shiftKey) { - this.selectRange(r); - } else { - this.setSelectedRow(r); - }; + // Some hotkeys can only be used if the following conditions are met: + // 1. when no input fields are focused + // 2. when no other dialogs are visible + // 3. when the meta or ctrl key isn't pressed (i.e. opening dev tools shouldn't trigger the info panel) + if (!isInputFocused && !isDialogVisible && !ev.metaKey && !ev.ctrlKey) { + if (comma_key) { + this.togglePrefsDialogClicked(); + handled = true; + } + + if (slash_key) { + this.showHotkeysDialog(); + handled = true; + } + + if (a_key) { + if (ev.shiftKey) { + this.deselectAll(); + } else { + this.selectAll(); + } + handled = true; + } + + if (c_key) { + this.toggleCompactClicked(); + handled = true; + } + + if ((backspace_key || del_key || d_key) && rows.length) { + this.removeSelectedTorrents(); + handled = true; + } + + if (i_key) { + this.toggleInspector(); + handled = true; + } + + if (m_key || l_key) { + this.moveSelectedTorrents() + handled = true; + } + + if (o_key || u_key) { + this.openTorrentClicked(ev); + handled = true; + } + + if (p_key) { + this.stopSelectedTorrents(); + handled = true; + } + + if (r_key) { + this.startSelectedTorrents(); + handled = true; + } + + if (t_key) { + this.toggleTurtleClicked(); + handled = true; + } + + if ((up_key || dn_key) && rows.length) { + var last = this.indexOfLastTorrent(), + i = last, + anchor = this._shift_index, + r, + min = 0, + max = rows.length - 1; + + if (dn_key && (i + 1 <= max)) { + ++i; + } else if (up_key && (i - 1 >= min)) { + --i; + }; + + var r = rows[i]; + + if (anchor >= 0) { + // user is extending the selection + // with the shift + arrow keys... + if (((anchor <= last) && (last < i)) || ((anchor >= last) && (last > i))) { + this.selectRow(r); + } else if (((anchor >= last) && (i > last)) || ((anchor <= last) && (last > i))) { + this.deselectRow(rows[last]); + } + } else { + if (ev.shiftKey) { + this.selectRange(r); + } else { + this.setSelectedRow(r); + }; + } + this._last_torrent_clicked = r.getTorrentId(); + this.scrollToRow(r); + handled = true; + } else if (shift_key) { + this._shift_index = this.indexOfLastTorrent(); } - this._last_torrent_clicked = r.getTorrentId(); - this.scrollToRow(r); - handled = true; - } else if (shift_key) { - this._shift_index = this.indexOfLastTorrent(); } return !handled; @@ -841,74 +856,74 @@ Transmission.prototype = { remote.savePrefs(o); } else { switch (id) { - case 'statistics': - this.showStatsDialog(); - break; + case 'statistics': + this.showStatsDialog(); + break; - case 'hotkeys': - this.showHotkeysDialog(); - break; + case 'hotkeys': + this.showHotkeysDialog(); + break; - case 'about-button': - o = 'Transmission ' + this.serverVersion; - $('#about-dialog #about-title').html(o); - $('#about-dialog').dialog({ - title: 'About', - show: 'fade', - hide: 'fade' - }); - break; + case 'about-button': + o = 'Transmission ' + this.serverVersion; + $('#about-dialog #about-title').html(o); + $('#about-dialog').dialog({ + title: 'About', + show: 'fade', + hide: 'fade' + }); + break; - case 'homepage': - window.open('https://transmissionbt.com/'); - break; + case 'homepage': + window.open('https://transmissionbt.com/'); + break; - case 'tipjar': - window.open('https://transmissionbt.com/donate/'); - break; + case 'tipjar': + window.open('https://transmissionbt.com/donate/'); + break; - case 'unlimited_download_rate': - o = {}; - o[RPC._DownSpeedLimited] = false; - remote.savePrefs(o); - break; + case 'unlimited_download_rate': + o = {}; + o[RPC._DownSpeedLimited] = false; + remote.savePrefs(o); + break; - case 'limited_download_rate': - o = {}; - o[RPC._DownSpeedLimited] = true; - remote.savePrefs(o); - break; + case 'limited_download_rate': + o = {}; + o[RPC._DownSpeedLimited] = true; + remote.savePrefs(o); + break; - case 'unlimited_upload_rate': - o = {}; - o[RPC._UpSpeedLimited] = false; - remote.savePrefs(o); - break; + case 'unlimited_upload_rate': + o = {}; + o[RPC._UpSpeedLimited] = false; + remote.savePrefs(o); + break; - case 'limited_upload_rate': - o = {}; - o[RPC._UpSpeedLimited] = true; - remote.savePrefs(o); - break; + case 'limited_upload_rate': + o = {}; + o[RPC._UpSpeedLimited] = true; + remote.savePrefs(o); + break; - case 'reverse_sort_order': - if (element.menuItemIsSelected()) { - dir = Prefs._SortAscending; - element.deselectMenuItem(); - } else { - dir = Prefs._SortDescending; - element.selectMenuItem(); - } - this.setSortDirection(dir); - break; + case 'reverse_sort_order': + if (element.menuItemIsSelected()) { + dir = Prefs._SortAscending; + element.deselectMenuItem(); + } else { + dir = Prefs._SortDescending; + element.selectMenuItem(); + } + this.setSortDirection(dir); + break; - case 'toggle_notifications': - Notifications && Notifications.toggle(); - break; + case 'toggle_notifications': + Notifications && Notifications.toggle(); + break; - default: - console.log('unhandled: ' + id); - break; + default: + console.log('unhandled: ' + id); + break; }; }; },