diff --git a/UI/Common/English.lproj/Localizable.strings b/UI/Common/English.lproj/Localizable.strings index 2d12770ce..e7107095b 100644 --- a/UI/Common/English.lproj/Localizable.strings +++ b/UI/Common/English.lproj/Localizable.strings @@ -124,12 +124,18 @@ /* Toggle visibility (ex: mail account in left navigation menu) */ "Toggle visibility" = "Toggle visibility"; +/* Toggle multiple items at the same time (hotkeys cheatsheet) */ +"Toggle range of items" = "Toggle range of items"; + /* Question mark shows list of hotkeys */ "Show or hide this help" = "Show or hide this help"; /* Space key */ "key_space" = "space"; +/* Shift and space key */ +"key_shift+space" = "shift + space"; + /* Up arrow key */ "key_up" = "↑"; diff --git a/UI/WebServerResources/js/Contacts/AddressBookController.js b/UI/WebServerResources/js/Contacts/AddressBookController.js index c57275d7a..dfa53e26e 100644 --- a/UI/WebServerResources/js/Contacts/AddressBookController.js +++ b/UI/WebServerResources/js/Contacts/AddressBookController.js @@ -63,6 +63,11 @@ description: l('Toggle item'), callback: toggleCardSelection })); + keys.push(sgHotkeys.createHotkey({ + key: 'shift+space', + description: l('Toggle range of items'), + callback: toggleCardSelection + })); keys.push(sgHotkeys.createHotkey({ key: 'up', description: l('View next item'), @@ -100,9 +105,37 @@ } function toggleCardSelection($event, card) { - if (!card) card = vm.selectedFolder.$selectedCard(); + var folder = vm.selectedFolder, + selectedIndex, nextSelectedIndex, i; + + if (!card) + card = folder.$selectedCard(); card.selected = !card.selected; vm.mode.multiple += card.selected? 1 : -1; + + // Select closest range of cards when shift key is pressed + if ($event.shiftKey && folder.$selectedCount() > 1) { + selectedIndex = folder.idsMap[card.id]; + // Search for next selected card above + nextSelectedIndex = selectedIndex - 2; + while (nextSelectedIndex >= 0 && + !folder.$cards[nextSelectedIndex].selected) + nextSelectedIndex--; + if (nextSelectedIndex < 0) { + // Search for next selected card bellow + nextSelectedIndex = selectedIndex + 2; + while (nextSelectedIndex < folder.getLength() && + !folder.$cards[nextSelectedIndex].selected) + nextSelectedIndex++; + } + if (nextSelectedIndex >= 0 && nextSelectedIndex < folder.getLength()) { + for (i = Math.min(selectedIndex, nextSelectedIndex); + i <= Math.max(selectedIndex, nextSelectedIndex); + i++) + folder.$cards[i].selected = true; + } + } + $event.preventDefault(); $event.stopPropagation(); } @@ -130,7 +163,7 @@ vm.selectedFolder.$topIndex--; } else { - // No message is selected, show oldest message + // No card is selected, show oldest card index = vm.selectedFolder.$cards.length() - 1; vm.selectedFolder.$topIndex = vm.selectedFolder.getLength(); } @@ -155,7 +188,7 @@ vm.selectedFolder.$topIndex++; } else - // No message is selected, show newest + // No card is selected, show newest index = 0; if (index < vm.selectedFolder.$cards.length) diff --git a/UI/WebServerResources/js/Mailer/MailboxController.js b/UI/WebServerResources/js/Mailer/MailboxController.js index a12c07b20..78bf823cb 100644 --- a/UI/WebServerResources/js/Mailer/MailboxController.js +++ b/UI/WebServerResources/js/Mailer/MailboxController.js @@ -83,6 +83,11 @@ description: l('Toggle item'), callback: toggleMessageSelection })); + keys.push(sgHotkeys.createHotkey({ + key: 'shift+space', + description: l('Toggle range of items'), + callback: toggleMessageSelection + })); keys.push(sgHotkeys.createHotkey({ key: 'up', description: l('View next item'), @@ -251,9 +256,37 @@ } function toggleMessageSelection($event, message) { - if (!message) message = vm.selectedFolder.$selectedMessage(); + var folder = vm.selectedFolder, + selectedIndex, nextSelectedIndex, i; + + if (!message) + message = folder.$selectedMessage(); message.selected = !message.selected; vm.mode.multiple += message.selected? 1 : -1; + + // Select closest range of messages when shift key is pressed + if ($event.shiftKey && folder.$selectedCount() > 1) { + selectedIndex = folder.uidsMap[message.uid]; + // Search for next selected message above + nextSelectedIndex = selectedIndex - 2; + while (nextSelectedIndex >= 0 && + !folder.$messages[nextSelectedIndex].selected) + nextSelectedIndex--; + if (nextSelectedIndex < 0) { + // Search for next selected message bellow + nextSelectedIndex = selectedIndex + 2; + while (nextSelectedIndex < folder.getLength() && + !folder.$messages[nextSelectedIndex].selected) + nextSelectedIndex++; + } + if (nextSelectedIndex >= 0 && nextSelectedIndex < folder.getLength()) { + for (i = Math.min(selectedIndex, nextSelectedIndex); + i <= Math.max(selectedIndex, nextSelectedIndex); + i++) + folder.$messages[i].selected = true; + } + } + $event.preventDefault(); $event.stopPropagation(); }