From 0cc0915c031a64578ea80dec0e94aedea8353533 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Mon, 4 Jun 2012 00:47:19 +0000 Subject: [PATCH] Accept control-click as an alternative for right-click when the Gdk backend is Quartz. This is a standard behavior on Macs, since they often have single-button mice or trackpads. svn: r19752 --- src/ScratchPad.py | 3 ++- src/gui/editors/displaytabs/embeddedlist.py | 3 ++- src/gui/editors/displaytabs/gallerytab.py | 6 ++--- .../editors/displaytabs/groupembeddedlist.py | 4 ++-- src/gui/editors/editperson.py | 13 +++++----- src/gui/editors/editprimary.py | 3 ++- src/gui/grampsbar.py | 4 ++-- src/gui/utils.py | 24 +++++++++++++++++-- src/gui/views/listview.py | 3 ++- src/gui/widgets/grampletpane.py | 14 ++++++----- src/plugins/BookReport.py | 8 +++---- src/plugins/gramplet/FanChartGramplet.py | 6 +++-- src/plugins/tool/Leak.py | 3 ++- src/plugins/tool/OwnerEditor.py | 3 ++- src/plugins/view/fanchartview.py | 5 ++-- src/plugins/view/pedigreeview.py | 9 +++---- 16 files changed, 72 insertions(+), 39 deletions(-) diff --git a/src/ScratchPad.py b/src/ScratchPad.py index 55a4fff88..c4d4ff98f 100644 --- a/src/ScratchPad.py +++ b/src/ScratchPad.py @@ -56,6 +56,7 @@ from constfunc import mac from glade import Glade from DdTargets import DdTargets from gui.makefilter import make_filter +import gui.utils #------------------------------------------------------------------------- # @@ -1420,7 +1421,7 @@ class MultiTreeView(gtk.TreeView): # Here we intercept mouse clicks on selected items so that we can # drag multiple items without the click selecting only one target = self.get_path_at_pos(int(event.x), int(event.y)) - if event.button == 3: # right mouse + if gui.utils.is_right_click(event): selection = widget.get_selection() store, paths = selection.get_selected_rows() tpath = paths[0] if len(paths) > 0 else None diff --git a/src/gui/editors/displaytabs/embeddedlist.py b/src/gui/editors/displaytabs/embeddedlist.py index a202153dd..a4390cb35 100644 --- a/src/gui/editors/displaytabs/embeddedlist.py +++ b/src/gui/editors/displaytabs/embeddedlist.py @@ -43,6 +43,7 @@ import pango # GRAMPS classes # #------------------------------------------------------------------------- +import gui.utils from buttontab import ButtonTab #------------------------------------------------------------------------- @@ -97,7 +98,7 @@ class EmbeddedList(ButtonTab): """ Handle button press, not double-click, that is done in init_interface """ - if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + if gui.utils.is_right_click(event): ref = self.get_selected() if ref: self.right_click(obj, event) diff --git a/src/gui/editors/displaytabs/gallerytab.py b/src/gui/editors/displaytabs/gallerytab.py index 490d51dc2..6c6887ac7 100644 --- a/src/gui/editors/displaytabs/gallerytab.py +++ b/src/gui/editors/displaytabs/gallerytab.py @@ -47,7 +47,7 @@ import gobject # GRAMPS classes # #------------------------------------------------------------------------- -from gui.utils import open_file_with_default_application +import gui.utils from gui.dbguielement import DbGUIElement from gui.selectors import SelectorFactory import gen.lib @@ -66,7 +66,7 @@ import const # #------------------------------------------------------------------------- def make_launcher(path): - return lambda x: open_file_with_default_application(path) + return lambda x: gui.utils.open_file_with_default_application(path) #------------------------------------------------------------------------- # @@ -112,7 +112,7 @@ class GalleryTab(ButtonTab, DbGUIElement): if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: self.edit_button_clicked(obj) return True - elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + elif gui.utils.is_right_click(event): reflist = self.iconlist.get_selected_items() if len(reflist) == 1: ref = self.media_list[reflist[0][0]] diff --git a/src/gui/editors/displaytabs/groupembeddedlist.py b/src/gui/editors/displaytabs/groupembeddedlist.py index c213c422c..8e044b0ac 100644 --- a/src/gui/editors/displaytabs/groupembeddedlist.py +++ b/src/gui/editors/displaytabs/groupembeddedlist.py @@ -36,12 +36,12 @@ import cPickle as pickle import gtk import pango import gobject - #------------------------------------------------------------------------- # # GRAMPS classes # #------------------------------------------------------------------------- +import gui.utils from embeddedlist import EmbeddedList #------------------------------------------------------------------------- @@ -103,7 +103,7 @@ class GroupEmbeddedList(EmbeddedList): """ Handle button press, not double-click, that is done in init_interface """ - if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + if gui.utils.is_right_click(event): obj = self.get_selected() if obj and obj[1]: self._tmpgroup = obj[0] diff --git a/src/gui/editors/editperson.py b/src/gui/editors/editperson.py index 9b04a92a7..860a3fce9 100644 --- a/src/gui/editors/editperson.py +++ b/src/gui/editors/editperson.py @@ -51,7 +51,7 @@ import pango #------------------------------------------------------------------------- import Utils import ThumbNails -from gui.utils import add_menuitem, open_file_with_default_application +import gui.utils from gen.utils import get_birth_or_fallback import gen.lib from gen.db import DbTxn @@ -603,7 +603,7 @@ class EditPerson(EditPrimary): except Errors.WindowActiveError: pass - elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + elif gui.utils.is_right_click(event): media_list = self.obj.get_media_list() if media_list: photo = media_list[0] @@ -621,9 +621,10 @@ class EditPerson(EditPrimary): menu.set_title(_("Media Object")) obj = self.db.get_object_from_handle(photo.get_reference_handle()) if obj: - add_menuitem(menu, _("View"), photo, self._popup_view_photo) - add_menuitem(menu, _("Edit Object Properties"), photo, - self._popup_change_description) + gui.utils.add_menuitem(menu, _("View"), photo, + self._popup_view_photo) + gui.utils.add_menuitem(menu, _("Edit Object Properties"), photo, + self._popup_change_description) menu.popup(None, None, None, event.button, event.time) def _popup_view_photo(self, obj): @@ -636,7 +637,7 @@ class EditPerson(EditPrimary): object_handle = photo.get_reference_handle() ref_obj = self.db.get_object_from_handle(object_handle) photo_path = Utils.media_path_full(self.db, ref_obj.get_path()) - open_file_with_default_application(photo_path) + gui.utils.open_file_with_default_application(photo_path) def _popup_change_description(self, obj): """ diff --git a/src/gui/editors/editprimary.py b/src/gui/editors/editprimary.py index 362f7e762..90f149686 100644 --- a/src/gui/editors/editprimary.py +++ b/src/gui/editors/editprimary.py @@ -44,6 +44,7 @@ import ManagedWindow import gen.datehandler from gen.display.name import displayer as name_displayer import config +import gui.utils import GrampsDisplay from QuestionDialog import SaveDialog import gen.lib @@ -283,7 +284,7 @@ class EditPrimary(ManagedWindow.ManagedWindow, DbGUIElement): pressed while on contexteventbox It opens a context menu with possible actions """ - if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3 : + if gui.utils.is_right_click(event): if self.obj.get_handle() == 0 : return False diff --git a/src/gui/grampsbar.py b/src/gui/grampsbar.py index 52b058495..083552542 100644 --- a/src/gui/grampsbar.py +++ b/src/gui/grampsbar.py @@ -57,7 +57,7 @@ from gui.widgets.grampletpane import (AVAILABLE_GRAMPLETS, make_requested_gramplet, GuiGramplet) from gui.widgets.undoablebuffer import UndoableBuffer -from gui.utils import add_menuitem +import gui.utils from QuestionDialog import QuestionDialog #------------------------------------------------------------------------- @@ -415,7 +415,7 @@ class GrampsBar(gtk.Notebook): """ Called when a button is pressed in the tabs section of the GrampsBar. """ - if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + if gui.utils.is_right_click(event): menu = gtk.Menu() ag_menu = gtk.MenuItem(_('Add a gramplet')) diff --git a/src/gui/utils.py b/src/gui/utils.py index 788631ad6..ec44fde38 100644 --- a/src/gui/utils.py +++ b/src/gui/utils.py @@ -32,7 +32,7 @@ Utility functions that depend on GUI components or for GUI components import os import sys from gen.ggettext import gettext as _ -from constfunc import has_display +import constfunc # gtk is not included here, because this file is currently imported # by code that needs to run without the DISPLAY variable (eg, in # the cli only). @@ -144,7 +144,7 @@ class ProgressMeter(object): else: self.__cancel_callback = self.handle_cancel - if has_display(): + if constfunc.has_display(): self.__dialog = gtk.Dialog() else: self.__dialog = CLIDialog() @@ -363,3 +363,23 @@ def process_pending_events(max_count=10): count += 1 if count >= max_count: break + +# Then there's the infamous Mac one-button mouse (or more likely these +# days, one-button trackpad). The canonical mac way to generate what +# Gdk calls a button-3 is button-1, but that's not baked into +# Gdk. We'll emulate the behavior here. + +def is_right_click(event): + """ + Returns True if the event is a button-3 or equivalent + """ + import gtk + + if event.type == gtk.gdk.BUTTON_PRESS: + if constfunc.is_quartz(): + if (event.button == 3 + or (event.button == 1 and event.state & gtk.gdk.CONTROL_MASK)): + return True + + if event.button == 3: + return True diff --git a/src/gui/views/listview.py b/src/gui/views/listview.py index d3cad6511..011d20bbd 100644 --- a/src/gui/views/listview.py +++ b/src/gui/views/listview.py @@ -65,6 +65,7 @@ from gui.filtereditor import FilterEditor from gen.ggettext import sgettext as _ from DdTargets import DdTargets from gui.plug.quick import create_quickreport_menu, create_web_connect_menu +import gui.utils #---------------------------------------------------------------- # @@ -759,7 +760,7 @@ class ListView(NavigationView): else: self.edit(obj) return True - elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + elif gui.utils.is_right_click(event): menu = self.uistate.uimanager.get_widget('/Popup') #construct quick reports if needed if menu and self.QR_CATEGORY > -1 : diff --git a/src/gui/widgets/grampletpane.py b/src/gui/widgets/grampletpane.py index 06fa7e7cc..fb5d9c45a 100644 --- a/src/gui/widgets/grampletpane.py +++ b/src/gui/widgets/grampletpane.py @@ -46,7 +46,7 @@ import const from gui.editors import EditPerson, EditFamily import ManagedWindow import ConfigParser -from gui.utils import add_menuitem +import gui.utils from gui.plug.quick import run_quick_report_by_name import GrampsDisplay from glade import Glade @@ -603,7 +603,7 @@ class GuiGramplet(object): elif event.type == gtk.gdk.BUTTON_PRESS: # single self.uistate.set_active(handle, 'Person') return True # handled event - elif event.button == 3: # right mouse + elif gui.utils.is_right_click(event): #FIXME: add a popup menu with options try: EditPerson(self.dbstate, @@ -664,7 +664,7 @@ class GuiGramplet(object): elif event.type == gtk.gdk.BUTTON_PRESS: # single self.uistate.set_active(handle, 'Family') return True # handle event - elif event.button == 3: # right mouse + elif gui.utils.is_right_click(event): #FIXME: add a popup menu with options try: EditFamily(self.dbstate, @@ -1373,7 +1373,7 @@ class GrampletPane(gtk.ScrolledWindow): print "Can't make gramplet of type '%s'." % name def _button_press(self, obj, event): - if event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + if gui.utils.is_right_click(event): self._popup_xy = (event.x, event.y) uiman = self.uistate.uimanager ag_menu = uiman.get_widget('/GrampletPopup/AddGramplet') @@ -1384,7 +1384,8 @@ class GrampletPane(gtk.ScrolledWindow): if gplug.navtypes == []] names.sort() for name in names: - add_menuitem(qr_menu, name, None, self.add_gramplet) + gui.utils.add_menuitem(qr_menu, name, None, + self.add_gramplet) ag_menu.set_submenu(qr_menu) rg_menu = uiman.get_widget('/GrampletPopup/RestoreGramplet') if rg_menu: @@ -1397,7 +1398,8 @@ class GrampletPane(gtk.ScrolledWindow): if len(names) > 0: qr_menu = gtk.Menu() for name in names: - add_menuitem(qr_menu, name, None, self.restore_gramplet) + gui.utils.add_menuitem(qr_menu, name, None, + self.restore_gramplet) rg_menu.set_submenu(qr_menu) menu = uiman.get_widget('/GrampletPopup') if menu: diff --git a/src/plugins/BookReport.py b/src/plugins/BookReport.py index 6a11cca37..64b57c64a 100644 --- a/src/plugins/BookReport.py +++ b/src/plugins/BookReport.py @@ -77,7 +77,7 @@ from QuestionDialog import WarningDialog, ErrorDialog from gen.plug.menu import PersonOption, FilterOption, FamilyOption import ManagedWindow from glade import Glade -from gui.utils import open_file_with_default_application +import gui.utils import gui.user # Import from specific modules in ReportBase @@ -970,7 +970,7 @@ class BookReportSelector(ManagedWindow.ManagedWindow): """ if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: self.on_setup_clicked(obj) - elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + elif gui.utils.is_right_click(event): self.build_book_context_menu(event) def avail_button_press(self, obj, event): @@ -980,7 +980,7 @@ class BookReportSelector(ManagedWindow.ManagedWindow): """ if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: self.on_add_clicked(obj) - elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + elif gui.utils.is_right_click(event): self.build_avail_context_menu(event) def build_book_context_menu(self, event): @@ -1287,7 +1287,7 @@ class BookReportDialog(DocReportDialog): self.doc.close() if self.open_with_app.get_active(): - open_file_with_default_application(self.target_path) + gui.utils.open_file_with_default_application(self.target_path) #------------------------------------------------------------------------ # diff --git a/src/plugins/gramplet/FanChartGramplet.py b/src/plugins/gramplet/FanChartGramplet.py index 8abb1f605..8a054721a 100644 --- a/src/plugins/gramplet/FanChartGramplet.py +++ b/src/plugins/gramplet/FanChartGramplet.py @@ -60,6 +60,7 @@ from libformatting import FormattingHelper import gen.lib import Errors from gui.editors import EditPerson +import gui.utils #------------------------------------------------------------------------- # @@ -523,7 +524,8 @@ class FanChartWidget(gtk.Widget): if selected is None: # clicked in open area, or center if radius < self.center: # right mouse - if event.button == 3 and self.context_popup_callback: + if (gui.utils.is_right_click(event) + and self.context_popup_callback): if self.data[0][0][1]: self.context_popup_callback(widget, event, self.data[0][0][1].handle) @@ -538,7 +540,7 @@ class FanChartWidget(gtk.Widget): # Do things based on state, event.state, or button, event.button if event.button == 1: # left mouse self.change_slice(generation, selected) - elif event.button == 3: # right mouse + elif gui.utils.is_right_click(event): # right mouse text, person, parents, child = self.data[generation][selected] if person and self.context_popup_callback: self.context_popup_callback(widget, event, person.handle) diff --git a/src/plugins/tool/Leak.py b/src/plugins/tool/Leak.py index 68bd312d4..1c35966f4 100644 --- a/src/plugins/tool/Leak.py +++ b/src/plugins/tool/Leak.py @@ -56,6 +56,7 @@ from gui.plug import tool import ManagedWindow from QuestionDialog import InfoDialog from glade import Glade +import gui.utils #------------------------------------------------------------------------- # @@ -116,7 +117,7 @@ class Leak(tool.Tool, ManagedWindow.ManagedWindow): if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1: self.referenced_in() return True - elif event.type == gtk.gdk.BUTTON_PRESS and event.button == 3: + elif gui.utils.is_right_click(event): self.refers_to() return True diff --git a/src/plugins/tool/OwnerEditor.py b/src/plugins/tool/OwnerEditor.py index 5d46fa586..6cf622d0a 100644 --- a/src/plugins/tool/OwnerEditor.py +++ b/src/plugins/tool/OwnerEditor.py @@ -46,6 +46,7 @@ import ManagedWindow from gui.plug import tool from gen.ggettext import sgettext as _ from glade import Glade +import gui.utils #------------------------------------------------------------------------- # @@ -154,7 +155,7 @@ class OwnerEditor(tool.Tool, ManagedWindow.ManagedWindow): def on_button_press_event(self, obj, event): """Shows popup-menu for db <-> preferences copying""" - if event.button == 3 and event.type == gtk.gdk.BUTTON_PRESS: + if gui.utils.is_right_click(event): self.menu.popup(None,None,None,0,0) def build_menu_names(self, obj): diff --git a/src/plugins/view/fanchartview.py b/src/plugins/view/fanchartview.py index 8993e5241..8884d7198 100644 --- a/src/plugins/view/fanchartview.py +++ b/src/plugins/view/fanchartview.py @@ -61,6 +61,7 @@ from gui.views.navigationview import NavigationView import Errors import Bookmarks from gui.editors import EditPerson +import gui.utils #------------------------------------------------------------------------- # @@ -539,7 +540,7 @@ class FanChartWidget(gtk.Widget): if selected is None: # clicked in open area, or center if radius < self.center: # right mouse - if event.button == 3 and self.context_popup_callback: + if gui.utils.is_right_click(event): if self.data[0][0][1]: self.context_popup_callback(widget, event, self.data[0][0][1].handle) @@ -554,7 +555,7 @@ class FanChartWidget(gtk.Widget): # Do things based on state, event.state, or button, event.button if event.button == 1: # left mouse self.change_slice(generation, selected) - elif event.button == 3: # right mouse + elif gui.utils.is_right_click(event): text, person, parents, child = self.data[generation][selected] if person and self.context_popup_callback: self.context_popup_callback(widget, event, person.handle) diff --git a/src/plugins/view/pedigreeview.py b/src/plugins/view/pedigreeview.py index 663bcfb53..df97401fb 100644 --- a/src/plugins/view/pedigreeview.py +++ b/src/plugins/view/pedigreeview.py @@ -64,6 +64,7 @@ import Bookmarks import const import constfunc from QuestionDialog import RunDatabaseRepair, ErrorDialog +import gui.utils #------------------------------------------------------------------------- # @@ -1511,7 +1512,7 @@ class PedigreeView(NavigationView): self._last_y = event.y self._in_move = True return True - elif event.button == 3 and event.type == gtk.gdk.BUTTON_PRESS: + elif gui.utils.is_right_click(event): self.cb_on_show_option_menu(widget, event) return True return False @@ -1565,7 +1566,7 @@ class PedigreeView(NavigationView): or submenu for person for mouse right click. And setup plug for button press on person widget. """ - if event.button == 3 and event.type == gtk.gdk.BUTTON_PRESS: + if gui.utils.is_right_click(event): self.cb_build_full_nav_menu(obj, event, person_handle, family_handle) return True @@ -1580,7 +1581,7 @@ class PedigreeView(NavigationView): on family line or call full submenu for mouse right click. And setup plug for button press on family line. """ - if event.button == 3 and event.type == gtk.gdk.BUTTON_PRESS: + if gui.utils.is_right_click(event): self.cb_build_relation_nav_menu(obj, event, family_handle) return True elif event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: @@ -1597,7 +1598,7 @@ class PedigreeView(NavigationView): if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS: self.cb_add_parents(obj, person_handle, family_handle) return True - elif event.button == 3 and event.type == gtk.gdk.BUTTON_PRESS: + elif gui.utils.is_right_click(event): self.cb_build_missing_parent_nav_menu(obj, event, person_handle, family_handle) return True