From 74ef92bc55b6dd363bebf2cc0b190d5178562fb7 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Wed, 3 Jan 2024 14:07:32 -0500 Subject: [PATCH] BTextView: Update word-wise/line-wise shortcuts ... and set alternates. This is updated because we can now set shortcuts without B_COMMAND_KEY. Setup Alt for Win/Linux mode. * Word-wise shortcuts Option+arrows. * Line-wise shortcuts Alt+arrows AND Ctrl+arrows for Win/Linux mode and for when there's a conflict. Otherwise these shortcuts are not expected to conflict. Add shortcuts for Alt+Backspace and Alt+Delete to delete to the beginning or end of line instead of word. Split out vertical and horizontal shortcuts so that if one is used by an app we at least get the other one. Fixes #9913 Change-Id: I0124fec7df4585a70ded8d3e7bf2aa8cb4acecb4 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7289 Tested-by: Commit checker robot Reviewed-by: John Scipione Haiku-Format: Haiku-format Bot --- headers/os/interface/TextView.h | 22 +- src/kits/interface/TextView.cpp | 519 +++++++++++++++++++------------- 2 files changed, 330 insertions(+), 211 deletions(-) diff --git a/headers/os/interface/TextView.h b/headers/os/interface/TextView.h index ec9e109c31..c7dafc27dd 100644 --- a/headers/os/interface/TextView.h +++ b/headers/os/interface/TextView.h @@ -470,19 +470,23 @@ private: LayoutData* fLayoutData; int32 fLastClickOffset; - bool fInstalledNavigateCommandWordwiseShortcuts : 1; bool fInstalledNavigateOptionWordwiseShortcuts : 1; - bool fInstalledNavigateOptionLinewiseShortcuts : 1; - bool fInstalledNavigateHomeEndDocwiseShortcuts : 1; - - bool fInstalledSelectCommandWordwiseShortcuts : 1; bool fInstalledSelectOptionWordwiseShortcuts : 1; - bool fInstalledSelectOptionLinewiseShortcuts : 1; - bool fInstalledSelectHomeEndDocwiseShortcuts : 1; - - bool fInstalledRemoveCommandWordwiseShortcuts : 1; + bool fInstalledRemoveCommandLinewiseShortcuts : 1; bool fInstalledRemoveOptionWordwiseShortcuts : 1; + bool fInstalledNavigateCommandHorizontalLinewiseShortcuts : 1; + bool fInstalledNavigateCommandVerticalLinewiseShortcuts : 1; + bool fInstalledNavigateControlHorizontalLinewiseShortcuts : 1; + bool fInstalledNavigateControlVerticalLinewiseShortcuts : 1; + bool fInstalledSelectCommandHorizontalLinewiseShortcuts : 1; + bool fInstalledSelectCommandVerticalLinewiseShortcuts : 1; + bool fInstalledSelectControlHorizontalLinewiseShortcuts : 1; + bool fInstalledSelectControlVerticalLinewiseShortcuts : 1; + + bool fInstalledNavigateHomeEndDocwiseShortcuts : 1; + bool fInstalledSelectHomeEndDocwiseShortcuts : 1; + uint32 _reserved[6]; }; diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp index d010df2686..29277bdff9 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -3216,19 +3216,23 @@ BTextView::_InitObject(BRect textRect, const BFont* initialFont, fLines = new LineBuffer; fStyles = new StyleBuffer(&font, initialColor); - fInstalledNavigateCommandWordwiseShortcuts = false; fInstalledNavigateOptionWordwiseShortcuts = false; - fInstalledNavigateOptionLinewiseShortcuts = false; - fInstalledNavigateHomeEndDocwiseShortcuts = false; - - fInstalledSelectCommandWordwiseShortcuts = false; fInstalledSelectOptionWordwiseShortcuts = false; - fInstalledSelectOptionLinewiseShortcuts = false; - fInstalledSelectHomeEndDocwiseShortcuts = false; - - fInstalledRemoveCommandWordwiseShortcuts = false; + fInstalledRemoveCommandLinewiseShortcuts = false; fInstalledRemoveOptionWordwiseShortcuts = false; + fInstalledNavigateCommandHorizontalLinewiseShortcuts = false; + fInstalledNavigateCommandVerticalLinewiseShortcuts = false; + fInstalledNavigateControlHorizontalLinewiseShortcuts = false; + fInstalledNavigateControlVerticalLinewiseShortcuts = false; + fInstalledSelectCommandHorizontalLinewiseShortcuts = false; + fInstalledSelectCommandVerticalLinewiseShortcuts = false; + fInstalledSelectControlHorizontalLinewiseShortcuts = false; + fInstalledSelectControlVerticalLinewiseShortcuts = false; + + fInstalledNavigateHomeEndDocwiseShortcuts = false; + fInstalledSelectHomeEndDocwiseShortcuts = false; + // We put these here instead of in the constructor initializer list // to have less code duplication, and a single place where to do changes // if needed. @@ -3294,9 +3298,14 @@ BTextView::_HandleBackspace(int32 modifiers) bool optionKeyDown = (modifiers & B_OPTION_KEY) != 0; bool commandKeyDown = (modifiers & B_COMMAND_KEY) != 0; - if ((commandKeyDown || optionKeyDown) && !controlKeyDown) { + if (optionKeyDown) { + // delete previous word with option held down fSelStart = _PreviousWordStart(fCaretOffset - 1); fSelEnd = fCaretOffset; + } else if (commandKeyDown && !controlKeyDown) { + // delete to beginning of line with command held down + fSelStart = _PreviousLineStart(fCaretOffset); + fSelEnd = fCaretOffset; } if (fUndo) { @@ -3362,8 +3371,10 @@ BTextView::_HandleArrowKey(uint32 arrowKey, int32 modifiers) else if (fSelStart != fSelEnd && !shiftKeyDown) fCaretOffset = fSelStart; else { - if ((commandKeyDown || optionKeyDown) && !controlKeyDown) + if (optionKeyDown) fCaretOffset = _PreviousWordStart(fCaretOffset - 1); + else if (commandKeyDown || controlKeyDown) + fCaretOffset = _PreviousLineStart(fCaretOffset); else fCaretOffset = _PreviousInitialByte(fCaretOffset); @@ -3389,8 +3400,10 @@ BTextView::_HandleArrowKey(uint32 arrowKey, int32 modifiers) else if (fSelStart != fSelEnd && !shiftKeyDown) fCaretOffset = fSelEnd; else { - if ((commandKeyDown || optionKeyDown) && !controlKeyDown) + if (optionKeyDown) fCaretOffset = _NextWordEnd(fCaretOffset); + else if (commandKeyDown || controlKeyDown) + fCaretOffset = _NextLineEnd(fCaretOffset); else fCaretOffset = _NextInitialByte(fCaretOffset); @@ -3417,9 +3430,9 @@ BTextView::_HandleArrowKey(uint32 arrowKey, int32 modifiers) else if (fSelStart != fSelEnd && !shiftKeyDown) fCaretOffset = fSelStart; else { - if (optionKeyDown && !commandKeyDown && !controlKeyDown) + if (optionKeyDown) { fCaretOffset = _PreviousLineStart(fCaretOffset); - else if (commandKeyDown && !optionKeyDown && !controlKeyDown) { + } else if (commandKeyDown || controlKeyDown) { _ScrollTo(0, 0); fCaretOffset = 0; } else { @@ -3461,9 +3474,9 @@ BTextView::_HandleArrowKey(uint32 arrowKey, int32 modifiers) else if (fSelStart != fSelEnd && !shiftKeyDown) fCaretOffset = fSelEnd; else { - if (optionKeyDown && !commandKeyDown && !controlKeyDown) + if (optionKeyDown) { fCaretOffset = _NextLineEnd(fCaretOffset); - else if (commandKeyDown && !optionKeyDown && !controlKeyDown) { + } else if (commandKeyDown || controlKeyDown) { _ScrollTo(0, fTextRect.bottom + fLayoutData->bottomInset); fCaretOffset = fText->Length(); } else { @@ -3524,9 +3537,14 @@ BTextView::_HandleDelete(int32 modifiers) bool optionKeyDown = (modifiers & B_OPTION_KEY) != 0; bool commandKeyDown = (modifiers & B_COMMAND_KEY) != 0; - if ((commandKeyDown || optionKeyDown) && !controlKeyDown) { + if (optionKeyDown) { + // delete next word with option held down fSelStart = fCaretOffset; fSelEnd = _NextWordEnd(fCaretOffset) + 1; + } else if (commandKeyDown && !controlKeyDown) { + // delete to end of line with command held down + fSelStart = fCaretOffset; + fSelEnd = _NextLineEnd(fCaretOffset); } if (fUndo) { @@ -5206,163 +5224,237 @@ BTextView::_Activate() if (Bounds().Contains(where)) _TrackMouse(where, NULL); - if (Window() != NULL) { - BMessage* message; + // bail out if not connected to app server + if (Window() == NULL) + return; - if (!Window()->HasShortcut(B_LEFT_ARROW, B_COMMAND_KEY) - && !Window()->HasShortcut(B_RIGHT_ARROW, B_COMMAND_KEY)) { - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_LEFT_ARROW); - message->AddInt32("modifiers", B_COMMAND_KEY); - Window()->AddShortcut(B_LEFT_ARROW, B_COMMAND_KEY, message, this); + // Define alternate shorcuts for Windows/Linux mode, these shortcuts + // may be already be taken by application shortcuts. - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_RIGHT_ARROW); - message->AddInt32("modifiers", B_COMMAND_KEY); - Window()->AddShortcut(B_RIGHT_ARROW, B_COMMAND_KEY, message, this); + BMessage* message; - fInstalledNavigateCommandWordwiseShortcuts = true; - } - if (!Window()->HasShortcut(B_LEFT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY) - && !Window()->HasShortcut(B_RIGHT_ARROW, - B_COMMAND_KEY | B_SHIFT_KEY)) { - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_LEFT_ARROW); - message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); - Window()->AddShortcut(B_LEFT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY, - message, this); + // set Option+Left/Right for word-wise navigation + if (!Window()->HasShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY) + && !Window()->HasShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_LEFT_ARROW); + message->AddInt32("modifiers", B_OPTION_KEY); + Window()->AddShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY, message, this); - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_RIGHT_ARROW); - message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); - Window()->AddShortcut(B_RIGHT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY, - message, this); + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_RIGHT_ARROW); + message->AddInt32("modifiers", B_OPTION_KEY); + Window()->AddShortcut(B_RIGHT_ARROW, B_OPTION_KEY, message, this); - fInstalledSelectCommandWordwiseShortcuts = true; - } - if (!Window()->HasShortcut(B_DELETE, B_COMMAND_KEY) - && !Window()->HasShortcut(B_BACKSPACE, B_COMMAND_KEY)) { - message = new BMessage(kMsgRemoveWord); - message->AddInt32("key", B_DELETE); - message->AddInt32("modifiers", B_COMMAND_KEY); - Window()->AddShortcut(B_DELETE, B_COMMAND_KEY, message, this); + fInstalledNavigateOptionWordwiseShortcuts = true; + } - message = new BMessage(kMsgRemoveWord); - message->AddInt32("key", B_BACKSPACE); - message->AddInt32("modifiers", B_COMMAND_KEY); - Window()->AddShortcut(B_BACKSPACE, B_COMMAND_KEY, message, this); + // set Shift+Option+Left/Right for word-wise selection + if (!Window()->HasShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_LEFT_ARROW); + message->AddInt32("modifiers", B_OPTION_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY | B_SHIFT_KEY, message, + this); - fInstalledRemoveCommandWordwiseShortcuts = true; - } + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_RIGHT_ARROW); + message->AddInt32("modifiers", B_OPTION_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY | B_SHIFT_KEY, message, + this); - if (!Window()->HasShortcut(B_LEFT_ARROW, B_OPTION_KEY) - && !Window()->HasShortcut(B_RIGHT_ARROW, B_OPTION_KEY)) { - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_LEFT_ARROW); - message->AddInt32("modifiers", B_OPTION_KEY); - Window()->AddShortcut(B_LEFT_ARROW, B_OPTION_KEY, message, this); + fInstalledSelectOptionWordwiseShortcuts = true; + } - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_RIGHT_ARROW); - message->AddInt32("modifiers", B_OPTION_KEY); - Window()->AddShortcut(B_RIGHT_ARROW, B_OPTION_KEY, message, this); + // set Command+Delete for line-wise deletion + if (!Window()->HasShortcut(B_DELETE, B_COMMAND_KEY) + && !Window()->HasShortcut(B_BACKSPACE, B_COMMAND_KEY)) { + message = new BMessage(kMsgRemoveWord); + message->AddInt32("key", B_DELETE); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_DELETE, B_COMMAND_KEY, message, this); - fInstalledNavigateOptionWordwiseShortcuts = true; - } - if (!Window()->HasShortcut(B_LEFT_ARROW, B_OPTION_KEY | B_SHIFT_KEY) - && !Window()->HasShortcut(B_RIGHT_ARROW, - B_OPTION_KEY | B_SHIFT_KEY)) { - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_LEFT_ARROW); - message->AddInt32("modifiers", B_OPTION_KEY | B_SHIFT_KEY); - Window()->AddShortcut(B_LEFT_ARROW, B_OPTION_KEY | B_SHIFT_KEY, - message, this); + message = new BMessage(kMsgRemoveWord); + message->AddInt32("key", B_BACKSPACE); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_BACKSPACE, B_COMMAND_KEY, message, this); - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_RIGHT_ARROW); - message->AddInt32("modifiers", B_OPTION_KEY | B_SHIFT_KEY); - Window()->AddShortcut(B_RIGHT_ARROW, B_OPTION_KEY | B_SHIFT_KEY, - message, this); + fInstalledRemoveCommandLinewiseShortcuts = true; + } + // set Option+Delete for word-wise deletion + if (!Window()->HasShortcut(B_DELETE, B_NO_COMMAND_KEY | B_OPTION_KEY) + && !Window()->HasShortcut(B_BACKSPACE, B_NO_COMMAND_KEY | B_OPTION_KEY)) { + message = new BMessage(kMsgRemoveWord); + message->AddInt32("key", B_DELETE); + message->AddInt32("modifiers", B_OPTION_KEY); + Window()->AddShortcut(B_DELETE, B_NO_COMMAND_KEY | B_OPTION_KEY, message, this); - fInstalledSelectOptionWordwiseShortcuts = true; - } - if (!Window()->HasShortcut(B_DELETE, B_OPTION_KEY) - && !Window()->HasShortcut(B_BACKSPACE, B_OPTION_KEY)) { - message = new BMessage(kMsgRemoveWord); - message->AddInt32("key", B_DELETE); - message->AddInt32("modifiers", B_OPTION_KEY); - Window()->AddShortcut(B_DELETE, B_OPTION_KEY, message, this); + message = new BMessage(kMsgRemoveWord); + message->AddInt32("key", B_BACKSPACE); + message->AddInt32("modifiers", B_OPTION_KEY); + Window()->AddShortcut(B_BACKSPACE, B_NO_COMMAND_KEY | B_OPTION_KEY, message, this); - message = new BMessage(kMsgRemoveWord); - message->AddInt32("key", B_BACKSPACE); - message->AddInt32("modifiers", B_OPTION_KEY); - Window()->AddShortcut(B_BACKSPACE, B_OPTION_KEY, message, this); + fInstalledRemoveOptionWordwiseShortcuts = true; + } - fInstalledRemoveOptionWordwiseShortcuts = true; - } + // set Command+Left/Right to navigate to the beginning and end of a line + if (!Window()->HasShortcut(B_LEFT_ARROW, B_COMMAND_KEY) + && !Window()->HasShortcut(B_RIGHT_ARROW, B_COMMAND_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_LEFT_ARROW); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_LEFT_ARROW, B_COMMAND_KEY, message, this); - if (!Window()->HasShortcut(B_UP_ARROW, B_OPTION_KEY) - && !Window()->HasShortcut(B_DOWN_ARROW, B_OPTION_KEY)) { - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_UP_ARROW); - message->AddInt32("modifiers", B_OPTION_KEY); - Window()->AddShortcut(B_UP_ARROW, B_OPTION_KEY, message, this); + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_RIGHT_ARROW); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_RIGHT_ARROW, B_COMMAND_KEY, message, this); - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_DOWN_ARROW); - message->AddInt32("modifiers", B_OPTION_KEY); - Window()->AddShortcut(B_DOWN_ARROW, B_OPTION_KEY, message, this); + fInstalledNavigateCommandHorizontalLinewiseShortcuts = true; + } + // set Control+Left/Right alternate for Win/Linux mode + if (!Window()->HasShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY) + && !Window()->HasShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_LEFT_ARROW); + message->AddInt32("modifiers", B_CONTROL_KEY); + Window()->AddShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY, message, this); - fInstalledNavigateOptionLinewiseShortcuts = true; - } - if (!Window()->HasShortcut(B_UP_ARROW, B_OPTION_KEY | B_SHIFT_KEY) - && !Window()->HasShortcut(B_DOWN_ARROW, - B_OPTION_KEY | B_SHIFT_KEY)) { - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_UP_ARROW); - message->AddInt32("modifiers", B_OPTION_KEY | B_SHIFT_KEY); - Window()->AddShortcut(B_UP_ARROW, B_OPTION_KEY | B_SHIFT_KEY, - message, this); + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_RIGHT_ARROW); + message->AddInt32("modifiers", B_CONTROL_KEY); + Window()->AddShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY, message, this); - message = new BMessage(kMsgNavigateArrow); - message->AddInt32("key", B_DOWN_ARROW); - message->AddInt32("modifiers", B_OPTION_KEY | B_SHIFT_KEY); - Window()->AddShortcut(B_DOWN_ARROW, B_OPTION_KEY | B_SHIFT_KEY, - message, this); + fInstalledNavigateControlHorizontalLinewiseShortcuts = true; + } - fInstalledSelectOptionLinewiseShortcuts = true; - } + // set Command+Up/Down to navigate to the beginning and end of a line + if (!Window()->HasShortcut(B_UP_ARROW, B_COMMAND_KEY) + && !Window()->HasShortcut(B_DOWN_ARROW, B_COMMAND_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_UP_ARROW); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_UP_ARROW, B_COMMAND_KEY, message, this); - if (!Window()->HasShortcut(B_HOME, B_COMMAND_KEY) - && !Window()->HasShortcut(B_END, B_COMMAND_KEY)) { - message = new BMessage(kMsgNavigatePage); - message->AddInt32("key", B_HOME); - message->AddInt32("modifiers", B_COMMAND_KEY); - Window()->AddShortcut(B_HOME, B_COMMAND_KEY, message, this); + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_DOWN_ARROW); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY, message, this); - message = new BMessage(kMsgNavigatePage); - message->AddInt32("key", B_END); - message->AddInt32("modifiers", B_COMMAND_KEY); - Window()->AddShortcut(B_END, B_COMMAND_KEY, message, this); + fInstalledNavigateCommandVerticalLinewiseShortcuts = true; + } + // set Control+Up/Down alternative to Win/Linux mode + if (!Window()->HasShortcut(B_UP_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY) + && !Window()->HasShortcut(B_DOWN_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_UP_ARROW); + message->AddInt32("modifiers", B_CONTROL_KEY); + Window()->AddShortcut(B_UP_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY, message, this); - fInstalledNavigateHomeEndDocwiseShortcuts = true; - } - if (!Window()->HasShortcut(B_HOME, B_COMMAND_KEY | B_SHIFT_KEY) - && !Window()->HasShortcut(B_END, B_COMMAND_KEY | B_SHIFT_KEY)) { - message = new BMessage(kMsgNavigatePage); - message->AddInt32("key", B_HOME); - message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); - Window()->AddShortcut(B_HOME, B_COMMAND_KEY | B_SHIFT_KEY, - message, this); + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_DOWN_ARROW); + message->AddInt32("modifiers", B_CONTROL_KEY); + Window()->AddShortcut(B_DOWN_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY, message, this); - message = new BMessage(kMsgNavigatePage); - message->AddInt32("key", B_END); - message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); - Window()->AddShortcut(B_END, B_COMMAND_KEY | B_SHIFT_KEY, - message, this); + fInstalledNavigateControlVerticalLinewiseShortcuts = true; + } - fInstalledSelectHomeEndDocwiseShortcuts = true; - } + // set Shift+Command+Left/Right to select to the beginning/end of line + if (!Window()->HasShortcut(B_LEFT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_RIGHT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_LEFT_ARROW); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_LEFT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY, message, this); + + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_RIGHT_ARROW); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_RIGHT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY, message, this); + + fInstalledSelectCommandHorizontalLinewiseShortcuts = true; + } + // set Shift+Control+Left/Right alternate for Win/Linux mode + if (!Window()->HasShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_LEFT_ARROW); + message->AddInt32("modifiers", B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY, message, + this); + + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_RIGHT_ARROW); + message->AddInt32("modifiers", B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY, + message, this); + + fInstalledSelectControlHorizontalLinewiseShortcuts = true; + } + + // set Shift+Command+Up/Down to select to the beginning/end of line + if (!Window()->HasShortcut(B_UP_ARROW, B_COMMAND_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_DOWN_ARROW, B_COMMAND_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_UP_ARROW); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_UP_ARROW, B_COMMAND_KEY | B_SHIFT_KEY, message, this); + + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_DOWN_ARROW); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_DOWN_ARROW, B_COMMAND_KEY | B_SHIFT_KEY, message, this); + + fInstalledSelectCommandVerticalLinewiseShortcuts = true; + } + // set Shift+Control+Up/Down alternate for Win/Linux mode + if (!Window()->HasShortcut(B_UP_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_DOWN_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_UP_ARROW); + message->AddInt32("modifiers", B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_UP_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY, message, + this); + + message = new BMessage(kMsgNavigateArrow); + message->AddInt32("key", B_DOWN_ARROW); + message->AddInt32("modifiers", B_CONTROL_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_DOWN_ARROW, B_CONTROL_KEY | B_SHIFT_KEY, message, this); + + fInstalledSelectControlVerticalLinewiseShortcuts = true; + } + + // set Command+Home/End for doc-wise navigation + if (!Window()->HasShortcut(B_HOME, B_COMMAND_KEY) + && !Window()->HasShortcut(B_END, B_COMMAND_KEY)) { + message = new BMessage(kMsgNavigatePage); + message->AddInt32("key", B_HOME); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_HOME, B_COMMAND_KEY, message, this); + + message = new BMessage(kMsgNavigatePage); + message->AddInt32("key", B_END); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_END, B_COMMAND_KEY, message, this); + + fInstalledNavigateHomeEndDocwiseShortcuts = true; + } + + // set Shift+Commmand Home/End for doc-wise selection + if (!Window()->HasShortcut(B_HOME, B_COMMAND_KEY | B_SHIFT_KEY) + && !Window()->HasShortcut(B_END, B_COMMAND_KEY | B_SHIFT_KEY)) { + message = new BMessage(kMsgNavigatePage); + message->AddInt32("key", B_HOME); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_HOME, B_COMMAND_KEY | B_SHIFT_KEY, message, this); + + message = new BMessage(kMsgNavigatePage); + message->AddInt32("key", B_END); + message->AddInt32("modifiers", B_COMMAND_KEY | B_SHIFT_KEY); + Window()->AddShortcut(B_END, B_COMMAND_KEY | B_SHIFT_KEY, message, this); + + fInstalledSelectHomeEndDocwiseShortcuts = true; } } @@ -5382,61 +5474,84 @@ BTextView::_Deactivate() } else _HideCaret(); - if (Window() != NULL) { - if (fInstalledNavigateCommandWordwiseShortcuts) { - Window()->RemoveShortcut(B_LEFT_ARROW, B_COMMAND_KEY); - Window()->RemoveShortcut(B_RIGHT_ARROW, B_COMMAND_KEY); - fInstalledNavigateCommandWordwiseShortcuts = false; - } - if (fInstalledSelectCommandWordwiseShortcuts) { - Window()->RemoveShortcut(B_LEFT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY); - Window()->RemoveShortcut(B_RIGHT_ARROW, - B_COMMAND_KEY | B_SHIFT_KEY); - fInstalledSelectCommandWordwiseShortcuts = false; - } - if (fInstalledRemoveCommandWordwiseShortcuts) { - Window()->RemoveShortcut(B_DELETE, B_COMMAND_KEY); - Window()->RemoveShortcut(B_BACKSPACE, B_COMMAND_KEY); - fInstalledRemoveCommandWordwiseShortcuts = false; - } + // bail out if not connected to app server + if (Window() == NULL) + return; - if (fInstalledNavigateOptionWordwiseShortcuts) { - Window()->RemoveShortcut(B_LEFT_ARROW, B_OPTION_KEY); - Window()->RemoveShortcut(B_RIGHT_ARROW, B_OPTION_KEY); - fInstalledNavigateOptionWordwiseShortcuts = false; - } - if (fInstalledSelectOptionWordwiseShortcuts) { - Window()->RemoveShortcut(B_LEFT_ARROW, B_OPTION_KEY | B_SHIFT_KEY); - Window()->RemoveShortcut(B_RIGHT_ARROW, B_OPTION_KEY | B_SHIFT_KEY); - fInstalledSelectOptionWordwiseShortcuts = false; - } - if (fInstalledRemoveOptionWordwiseShortcuts) { - Window()->RemoveShortcut(B_DELETE, B_OPTION_KEY); - Window()->RemoveShortcut(B_BACKSPACE, B_OPTION_KEY); - fInstalledRemoveOptionWordwiseShortcuts = false; - } + // word-wise shortcuts use option or command+control + if (fInstalledNavigateOptionWordwiseShortcuts) { + Window()->RemoveShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY); + Window()->RemoveShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY); + fInstalledNavigateOptionWordwiseShortcuts = false; + } + if (fInstalledSelectOptionWordwiseShortcuts) { + Window()->RemoveShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY | B_SHIFT_KEY); + Window()->RemoveShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_OPTION_KEY | B_SHIFT_KEY); + fInstalledSelectOptionWordwiseShortcuts = false; + } + if (fInstalledRemoveCommandLinewiseShortcuts) { + Window()->RemoveShortcut(B_DELETE, B_COMMAND_KEY); + Window()->RemoveShortcut(B_BACKSPACE, B_COMMAND_KEY); + fInstalledRemoveCommandLinewiseShortcuts = false; + } + if (fInstalledRemoveOptionWordwiseShortcuts) { + Window()->RemoveShortcut(B_DELETE, B_NO_COMMAND_KEY | B_OPTION_KEY); + Window()->RemoveShortcut(B_BACKSPACE, B_NO_COMMAND_KEY | B_OPTION_KEY); + fInstalledRemoveOptionWordwiseShortcuts = false; + } - if (fInstalledNavigateOptionLinewiseShortcuts) { - Window()->RemoveShortcut(B_UP_ARROW, B_OPTION_KEY); - Window()->RemoveShortcut(B_DOWN_ARROW, B_OPTION_KEY); - fInstalledNavigateOptionLinewiseShortcuts = false; - } - if (fInstalledSelectOptionLinewiseShortcuts) { - Window()->RemoveShortcut(B_UP_ARROW, B_OPTION_KEY | B_SHIFT_KEY); - Window()->RemoveShortcut(B_DOWN_ARROW, B_OPTION_KEY | B_SHIFT_KEY); - fInstalledSelectOptionLinewiseShortcuts = false; - } + // line-wise shortcuts use command or control + if (fInstalledNavigateCommandHorizontalLinewiseShortcuts) { + Window()->RemoveShortcut(B_LEFT_ARROW, B_COMMAND_KEY); + Window()->RemoveShortcut(B_RIGHT_ARROW, B_COMMAND_KEY); + fInstalledNavigateCommandHorizontalLinewiseShortcuts = false; + } + if (fInstalledNavigateCommandVerticalLinewiseShortcuts) { + Window()->RemoveShortcut(B_UP_ARROW, B_COMMAND_KEY); + Window()->RemoveShortcut(B_DOWN_ARROW, B_COMMAND_KEY); + fInstalledNavigateCommandVerticalLinewiseShortcuts = false; + } + if (fInstalledNavigateControlHorizontalLinewiseShortcuts) { + Window()->RemoveShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY); + Window()->RemoveShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY); + fInstalledNavigateControlHorizontalLinewiseShortcuts = false; + } + if (fInstalledNavigateControlVerticalLinewiseShortcuts) { + Window()->RemoveShortcut(B_UP_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY); + Window()->RemoveShortcut(B_DOWN_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY); + fInstalledNavigateControlVerticalLinewiseShortcuts = false; + } + if (fInstalledSelectCommandHorizontalLinewiseShortcuts) { + Window()->RemoveShortcut(B_LEFT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY); + Window()->RemoveShortcut(B_RIGHT_ARROW, B_COMMAND_KEY | B_SHIFT_KEY); + fInstalledSelectCommandHorizontalLinewiseShortcuts = false; + } + if (fInstalledSelectCommandVerticalLinewiseShortcuts) { + Window()->RemoveShortcut(B_UP_ARROW, B_COMMAND_KEY | B_SHIFT_KEY); + Window()->RemoveShortcut(B_DOWN_ARROW, B_COMMAND_KEY | B_SHIFT_KEY); + fInstalledSelectCommandVerticalLinewiseShortcuts = false; + } + if (fInstalledSelectControlHorizontalLinewiseShortcuts) { + Window()->RemoveShortcut(B_LEFT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY); + Window()->RemoveShortcut(B_RIGHT_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY); + fInstalledSelectControlHorizontalLinewiseShortcuts = false; + } + if (fInstalledSelectControlVerticalLinewiseShortcuts) { + Window()->RemoveShortcut(B_UP_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY); + Window()->RemoveShortcut(B_DOWN_ARROW, B_NO_COMMAND_KEY | B_CONTROL_KEY | B_SHIFT_KEY); + fInstalledSelectControlVerticalLinewiseShortcuts = false; + } - if (fInstalledNavigateHomeEndDocwiseShortcuts) { - Window()->RemoveShortcut(B_HOME, B_COMMAND_KEY); - Window()->RemoveShortcut(B_END, B_COMMAND_KEY); - fInstalledNavigateHomeEndDocwiseShortcuts = false; - } - if (fInstalledSelectHomeEndDocwiseShortcuts) { - Window()->RemoveShortcut(B_HOME, B_COMMAND_KEY | B_SHIFT_KEY); - Window()->RemoveShortcut(B_END, B_COMMAND_KEY | B_SHIFT_KEY); - fInstalledSelectHomeEndDocwiseShortcuts = false; - } + // doc-wise shortcuts use command + if (fInstalledNavigateHomeEndDocwiseShortcuts) { + Window()->RemoveShortcut(B_HOME, B_COMMAND_KEY); + Window()->RemoveShortcut(B_END, B_COMMAND_KEY); + fInstalledNavigateHomeEndDocwiseShortcuts = false; + } + if (fInstalledSelectHomeEndDocwiseShortcuts) { + Window()->RemoveShortcut(B_HOME, B_COMMAND_KEY | B_SHIFT_KEY); + Window()->RemoveShortcut(B_END, B_COMMAND_KEY | B_SHIFT_KEY); + fInstalledSelectHomeEndDocwiseShortcuts = false; } }