From 17c9e987431f0a838ea579b9b77a6ad3bf4d7a29 Mon Sep 17 00:00:00 2001 From: Kacper Kasper Date: Wed, 10 Jul 2019 21:30:02 +0200 Subject: [PATCH] TextView: add shortcuts for wordwise delete Change-Id: Ie67f6255c3f5d9d8ccc6699ed42dd71ae593fa16 Reviewed-on: https://review.haiku-os.org/c/1573 Reviewed-by: Adrien Destugues --- headers/os/interface/TextView.h | 25 +++++---- src/kits/interface/TextView.cpp | 91 ++++++++++++++++++++++++++++++++- 2 files changed, 103 insertions(+), 13 deletions(-) diff --git a/headers/os/interface/TextView.h b/headers/os/interface/TextView.h index 6fa15ca118..b4a684afce 100644 --- a/headers/os/interface/TextView.h +++ b/headers/os/interface/TextView.h @@ -287,10 +287,10 @@ private: void _ValidateLayoutData(); void _ResetTextRect(); - void _HandleBackspace(); + void _HandleBackspace(int32 modifiers = -1); void _HandleArrowKey(uint32 arrowKey, int32 modifiers = -1); - void _HandleDelete(); + void _HandleDelete(int32 modifiers = -1); void _HandlePageKey(uint32 pageKey, int32 modifiers = -1); void _HandleAlphaKey(const char* bytes, @@ -450,17 +450,20 @@ private: LayoutData* fLayoutData; int32 fLastClickOffset; - bool fInstalledNavigateCommandWordwiseShortcuts; - bool fInstalledNavigateOptionWordwiseShortcuts; - bool fInstalledNavigateOptionLinewiseShortcuts; - bool fInstalledNavigateHomeEndDocwiseShortcuts; + bool fInstalledNavigateCommandWordwiseShortcuts : 1; + bool fInstalledNavigateOptionWordwiseShortcuts : 1; + bool fInstalledNavigateOptionLinewiseShortcuts : 1; + bool fInstalledNavigateHomeEndDocwiseShortcuts : 1; - bool fInstalledSelectCommandWordwiseShortcuts; - bool fInstalledSelectOptionWordwiseShortcuts; - bool fInstalledSelectOptionLinewiseShortcuts; - bool fInstalledSelectHomeEndDocwiseShortcuts; + bool fInstalledSelectCommandWordwiseShortcuts : 1; + bool fInstalledSelectOptionWordwiseShortcuts : 1; + bool fInstalledSelectOptionLinewiseShortcuts : 1; + bool fInstalledSelectHomeEndDocwiseShortcuts : 1; - uint32 _reserved[5]; + bool fInstalledRemoveCommandWordwiseShortcuts : 1; + bool fInstalledRemoveOptionWordwiseShortcuts : 1; + + uint32 _reserved[6]; }; #endif // _TEXTVIEW_H diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp index 6dcebadc9b..5e70ff46c1 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -196,6 +196,7 @@ static const float kVerticalScrollBarStep = 12.0; static const int32 kMsgNavigateArrow = '_NvA'; static const int32 kMsgNavigatePage = '_NvP'; +static const int32 kMsgRemoveWord = '_RmW'; static property_info sPropertyList[] = { @@ -954,6 +955,17 @@ BTextView::MessageReceived(BMessage* message) break; } + case kMsgRemoveWord: + { + int32 key = message->GetInt32("key", 0); + int32 modifiers = message->GetInt32("modifiers", 0); + if (key == B_DELETE) + _HandleDelete(modifiers); + else if (key == B_BACKSPACE) + _HandleBackspace(modifiers); + break; + } + default: BView::MessageReceived(message); break; @@ -3064,6 +3076,9 @@ BTextView::_InitObject(BRect textRect, const BFont* initialFont, fInstalledSelectOptionLinewiseShortcuts = false; fInstalledSelectHomeEndDocwiseShortcuts = false; + fInstalledRemoveCommandWordwiseShortcuts = false; + fInstalledRemoveOptionWordwiseShortcuts = 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. @@ -3115,8 +3130,25 @@ BTextView::_InitObject(BRect textRect, const BFont* initialFont, //! Handles when Backspace key is pressed. void -BTextView::_HandleBackspace() +BTextView::_HandleBackspace(int32 modifiers) { + if (modifiers < 0) { + BMessage* currentMessage = Window()->CurrentMessage(); + if (currentMessage == NULL + || currentMessage->FindInt32("modifiers", &modifiers) != B_OK) { + modifiers = 0; + } + } + + bool controlKeyDown = (modifiers & B_CONTROL_KEY) != 0; + bool optionKeyDown = (modifiers & B_OPTION_KEY) != 0; + bool commandKeyDown = (modifiers & B_COMMAND_KEY) != 0; + + if ((commandKeyDown || optionKeyDown) && !controlKeyDown) { + fSelStart = _PreviousWordStart(fCaretOffset - 1); + fSelEnd = fCaretOffset; + } + if (fUndo) { TypingUndoBuffer* undoBuffer = dynamic_cast( fUndo); @@ -3320,8 +3352,25 @@ BTextView::_HandleArrowKey(uint32 arrowKey, int32 modifiers) //! Handles when the Delete key is pressed. void -BTextView::_HandleDelete() +BTextView::_HandleDelete(int32 modifiers) { + if (modifiers < 0) { + BMessage* currentMessage = Window()->CurrentMessage(); + if (currentMessage == NULL + || currentMessage->FindInt32("modifiers", &modifiers) != B_OK) { + modifiers = 0; + } + } + + bool controlKeyDown = (modifiers & B_CONTROL_KEY) != 0; + bool optionKeyDown = (modifiers & B_OPTION_KEY) != 0; + bool commandKeyDown = (modifiers & B_COMMAND_KEY) != 0; + + if ((commandKeyDown || optionKeyDown) && !controlKeyDown) { + fSelStart = fCaretOffset; + fSelEnd = _NextWordEnd(fCaretOffset) + 1; + } + if (fUndo) { TypingUndoBuffer* undoBuffer = dynamic_cast( fUndo); @@ -4972,6 +5021,20 @@ BTextView::_Activate() 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); + + message = new BMessage(kMsgRemoveWord); + message->AddInt32("key", B_BACKSPACE); + message->AddInt32("modifiers", B_COMMAND_KEY); + Window()->AddShortcut(B_BACKSPACE, B_COMMAND_KEY, message, this); + + fInstalledRemoveCommandWordwiseShortcuts = true; + } if (!Window()->HasShortcut(B_LEFT_ARROW, B_OPTION_KEY) && !Window()->HasShortcut(B_RIGHT_ARROW, B_OPTION_KEY)) { @@ -5004,6 +5067,20 @@ BTextView::_Activate() 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_OPTION_KEY, message, this); + + fInstalledRemoveOptionWordwiseShortcuts = true; + } if (!Window()->HasShortcut(B_UP_ARROW, B_OPTION_KEY) && !Window()->HasShortcut(B_DOWN_ARROW, B_OPTION_KEY)) { @@ -5098,6 +5175,11 @@ BTextView::_Deactivate() 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; + } if (fInstalledNavigateOptionWordwiseShortcuts) { Window()->RemoveShortcut(B_LEFT_ARROW, B_OPTION_KEY); @@ -5109,6 +5191,11 @@ BTextView::_Deactivate() 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; + } if (fInstalledNavigateOptionLinewiseShortcuts) { Window()->RemoveShortcut(B_UP_ARROW, B_OPTION_KEY);