From 91f0846f8a689e0d8c4da6fc5f1c584556b2249d Mon Sep 17 00:00:00 2001 From: Ryan Leavengood Date: Fri, 28 Jan 2011 05:09:52 +0000 Subject: [PATCH] Add a default right click context menu to BTextView. This fixes #7022 and is mostly based on the patch attached to that ticket, with these changes: - The patch was adding this to the private _TextInput_ class, not BTextView. - The patch had a Clear menu item too. I removed that due to the different semantics between Clear in a BTextView and in a TextInput. The former just clears the selection where the latter clears the whole view. We could later add a virtual callback for adding menu items to this context menu which could be used to add Clear with the two semantics in each class (this is mainly needed for the enabling logic...each class could handle a clear message in its own way.) This callback could also obviously be used for other things, like a spell-check menu or whatever an application would want to add. Since BTextView has 10 free virtual slots it seems reasonable to add. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40305 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/TextView.h | 8 ++-- src/kits/interface/TextView.cpp | 79 +++++++++++++++++++++++++++++---- src/kits/locale/Jamfile | 2 + 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/headers/os/interface/TextView.h b/headers/os/interface/TextView.h index caaeeaf746..e43c116c18 100644 --- a/headers/os/interface/TextView.h +++ b/headers/os/interface/TextView.h @@ -357,6 +357,10 @@ private: void _PerformAutoScrolling(); void _UpdateScrollbars(); + void _ScrollBy(float horizontalStep, + float verticalStep); + void _ScrollTo(float x, float y); + void _AutoResize(bool doRedraw = true); void _NewOffscreen(float padding = 0.0); @@ -405,9 +409,7 @@ private: float _NullStyleHeight() const; - void _ScrollBy(float horizontalStep, - float verticalStep); - void _ScrollTo(float x, float y); + void _ShowContextMenu(BPoint where); private: BPrivate::TextGapBuffer* fText; diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp index 2e991133a3..b50d1e47a0 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -34,9 +34,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -52,8 +54,21 @@ #include "UndoBuffer.h" #include "WidthBuffer.h" +#include +#include + using namespace std; +using BPrivate::gLocaleBackend; +using BPrivate::LocaleBackend; + + +#undef B_TRANSLATE_CONTEXT +#define B_TRANSLATE_CONTEXT "TextView" + + +#define TRANSLATE(str) gLocaleBackend->GetString(B_TRANSLATE_MARK(str), \ + "TextView") #undef TRACE #undef CALLED @@ -558,19 +573,24 @@ BTextView::MouseDown(BPoint where) _StopMouseTracking(); + int32 modifiers = 0; + uint32 buttons; + BMessage *currentMessage = Window()->CurrentMessage(); + if (currentMessage != NULL) { + currentMessage->FindInt32("modifiers", &modifiers); + currentMessage->FindInt32("buttons", (int32 *)&buttons); + } + + if (buttons == B_SECONDARY_MOUSE_BUTTON) { + _ShowContextMenu(where); + return; + } + BMessenger messenger(this); fTrackingMouse = new (nothrow) TextTrackState(messenger); if (fTrackingMouse == NULL) return; - int32 modifiers = 0; - //uint32 buttons; - BMessage *currentMessage = Window()->CurrentMessage(); - if (currentMessage != NULL) { - currentMessage->FindInt32("modifiers", &modifiers); - //currentMessage->FindInt32("buttons", (int32 *)&buttons); - } - fTrackingMouse->clickOffset = OffsetAt(where); fTrackingMouse->shiftDown = modifiers & B_SHIFT_KEY; fTrackingMouse->where = where; @@ -3238,6 +3258,11 @@ BTextView::_InitObject(BRect textRect, const BFont *initialFont, fLastClickOffset = -1; SetDoesUndo(true); + + // We need to translate some strings, and in order to do so, we need + // to use the LocaleBackend to reach liblocale.so + if (gLocaleBackend == NULL) + LocaleBackend::LoadBackend(); } @@ -5539,6 +5564,44 @@ BTextView::_NullStyleHeight() const } +void +BTextView::_ShowContextMenu(BPoint where) +{ + bool isRedo; + undo_state state = UndoState(&isRedo); + bool isUndo = state != B_UNDO_UNAVAILABLE && !isRedo; + + int32 start; + int32 finish; + GetSelection(&start, &finish); + + bool canEdit = IsEditable(); + int32 length = TextLength(); + + BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false); + + BLayoutBuilder::Menu<>(menu) + .AddItem(TRANSLATE("Undo"), B_UNDO/*, 'Z'*/) + .SetEnabled(canEdit && isUndo) + .AddItem(TRANSLATE("Redo"), B_UNDO/*, 'Z', B_SHIFT_KEY*/) + .SetEnabled(canEdit && isRedo) + .AddSeparator() + .AddItem(TRANSLATE("Cut"), B_CUT, 'X') + .SetEnabled(canEdit && start != finish) + .AddItem(TRANSLATE("Copy"), B_COPY, 'C') + .SetEnabled(start != finish) + .AddItem(TRANSLATE("Paste"), B_PASTE, 'V') + .SetEnabled(canEdit && be_clipboard->SystemCount() > 0) + .AddSeparator() + .AddItem(TRANSLATE("Select All"), B_SELECT_ALL, 'A') + .SetEnabled(!(start == 0 && finish == length)) + ; + + menu->SetTargetForItems(this); + ConvertToScreen(&where); + menu->Go(where, true, true, true); +} + // #pragma mark - BTextView::TextTrackState diff --git a/src/kits/locale/Jamfile b/src/kits/locale/Jamfile index de642c1526..73df30bda3 100644 --- a/src/kits/locale/Jamfile +++ b/src/kits/locale/Jamfile @@ -67,6 +67,7 @@ StaticLibrary liblocalestub.a SEARCH on [ FGristFiles StringForSize.cpp ] += [ FDirName $(HAIKU_TOP) src kits shared ] ; SEARCH on [ FGristFiles AboutWindow.cpp ] += [ FDirName $(HAIKU_TOP) src kits shared ] ; SEARCH on [ FGristFiles ColorControl.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; +SEARCH on [ FGristFiles TextView.cpp ] += [ FDirName $(HAIKU_TOP) src kits interface ] ; DoCatalogs liblocale.so : system @@ -74,4 +75,5 @@ DoCatalogs liblocale.so AboutWindow.cpp ColorControl.cpp StringForSize.cpp + TextView.cpp ;