Author: leavengood Date: 2011-01-28 06:09:52 +0100 (Fri, 28 Jan 2011) New Revision: 40305 Changeset: http://dev.haiku-os.org/changeset/40305 Ticket: http://dev.haiku-os.org/ticket/7022 Modified: haiku/trunk/headers/os/interface/TextView.h haiku/trunk/src/kits/interface/TextView.cpp haiku/trunk/src/kits/locale/Jamfile Log: 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. Modified: haiku/trunk/headers/os/interface/TextView.h =================================================================== --- haiku/trunk/headers/os/interface/TextView.h 2011-01-28 02:06:39 UTC (rev 40304) +++ haiku/trunk/headers/os/interface/TextView.h 2011-01-28 05:09:52 UTC (rev 40305) @@ -357,6 +357,10 @@ 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 @@ float _NullStyleHeight() const; - void _ScrollBy(float horizontalStep, - float verticalStep); - void _ScrollTo(float x, float y); + void _ShowContextMenu(BPoint where); private: BPrivate::TextGapBuffer* fText; Modified: haiku/trunk/src/kits/interface/TextView.cpp =================================================================== --- haiku/trunk/src/kits/interface/TextView.cpp 2011-01-28 02:06:39 UTC (rev 40304) +++ haiku/trunk/src/kits/interface/TextView.cpp 2011-01-28 05:09:52 UTC (rev 40305) @@ -34,9 +34,11 @@ #include <Debug.h> #include <Entry.h> #include <Input.h> +#include <LayoutBuilder.h> #include <LayoutUtils.h> #include <MessageRunner.h> #include <Path.h> +#include <PopUpMenu.h> #include <PropertyInfo.h> #include <Region.h> #include <ScrollBar.h> @@ -52,9 +54,22 @@ #include "UndoBuffer.h" #include "WidthBuffer.h" +#include <Catalog.h> +#include <LocaleBackend.h> + 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 //#define TRACE_TEXT_VIEW @@ -558,19 +573,24 @@ _StopMouseTracking(); - BMessenger messenger(this); - fTrackingMouse = new (nothrow) TextTrackState(messenger); - if (fTrackingMouse == NULL) - return; - int32 modifiers = 0; - //uint32 buttons; + uint32 buttons; BMessage *currentMessage = Window()->CurrentMessage(); if (currentMessage != NULL) { currentMessage->FindInt32("modifiers", &modifiers); - //currentMessage->FindInt32("buttons", (int32 *)&buttons); + 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; + fTrackingMouse->clickOffset = OffsetAt(where); fTrackingMouse->shiftDown = modifiers & B_SHIFT_KEY; fTrackingMouse->where = where; @@ -3238,6 +3258,11 @@ 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 @@ } +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 Modified: haiku/trunk/src/kits/locale/Jamfile =================================================================== --- haiku/trunk/src/kits/locale/Jamfile 2011-01-28 02:06:39 UTC (rev 40304) +++ haiku/trunk/src/kits/locale/Jamfile 2011-01-28 05:09:52 UTC (rev 40305) @@ -67,6 +67,7 @@ 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 @@ AboutWindow.cpp ColorControl.cpp StringForSize.cpp + TextView.cpp ;