From 14a5f9a1b811720f4d0c7edfbfef5b4eab9543cc Mon Sep 17 00:00:00 2001 From: Doug Blank Date: Mon, 16 Aug 2010 11:20:45 +0000 Subject: [PATCH] New MultiTreeView to allow left-click to drag a multi-selected group svn: r15750 --- src/Simple/_SimpleTable.py | 3 +- src/gui/widgets/Makefile.am | 1 + src/gui/widgets/multitreeview.py | 83 ++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/gui/widgets/multitreeview.py diff --git a/src/Simple/_SimpleTable.py b/src/Simple/_SimpleTable.py index 92195cfd3..594fff0fb 100644 --- a/src/Simple/_SimpleTable.py +++ b/src/Simple/_SimpleTable.py @@ -471,6 +471,7 @@ class SimpleTable(object): doc.end_paragraph() elif self.simpledoc.doc.type == "gtk": import gtk + from gui.widgets.multitreeview import MultiTreeView from ScratchPad import ScratchPadListView, ACTION_COPY from DdTargets import DdTargets buffer = self.simpledoc.doc.buffer @@ -480,7 +481,7 @@ class SimpleTable(object): sort_index = self.__columns.index(self.__sort_col) else: sort_index = 0 - treeview = gtk.TreeView() + treeview = MultiTreeView() treeview.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, [(DdTargets.HANDLE_LIST.drag_type, gtk.TARGET_SAME_WIDGET, 0)], gtk.gdk.ACTION_COPY) diff --git a/src/gui/widgets/Makefile.am b/src/gui/widgets/Makefile.am index 2c16045a3..c64c85291 100644 --- a/src/gui/widgets/Makefile.am +++ b/src/gui/widgets/Makefile.am @@ -14,6 +14,7 @@ pkgdata_PYTHON = \ linkbox.py \ menutoolbuttonaction.py \ monitoredwidgets.py \ + multitreeview.py \ progressdialog.py \ shortlistcomboentry.py \ springseparator.py \ diff --git a/src/gui/widgets/multitreeview.py b/src/gui/widgets/multitreeview.py new file mode 100644 index 000000000..09ada9827 --- /dev/null +++ b/src/gui/widgets/multitreeview.py @@ -0,0 +1,83 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2010 Doug Blank +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# $Id: $ + +""" +An override to allow easy multiselections. +""" + +import gtk + +#------------------------------------------------------------------------- +# +# MultiTreeView class +# +#------------------------------------------------------------------------- +class MultiTreeView(gtk.TreeView): + ''' + TreeView that captures mouse events to make drag and drop work properly + ''' + def __init__(self): + super(MultiTreeView, self).__init__() + self.connect('button_press_event', self.on_button_press) + self.connect('button_release_event', self.on_button_release) + self.connect('key_press_event', self.key_press_event) + self.defer_select = False + + def key_press_event(self, widget, event): + if event.type == gtk.gdk.KEY_PRESS: + if event.keyval == gtk.keysyms.Delete: + model, paths = self.get_selection().get_selected_rows() + # reverse, to delete from the end + paths.sort(key=lambda x:-x[0]) + for path in paths: + try: + node = model.get_iter(path) + except: + node = None + if node: + model.remove(node) + return True + + def on_button_press(self, widget, event): + # 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 (target + and event.type == gtk.gdk.BUTTON_PRESS + and not (event.state & (gtk.gdk.CONTROL_MASK|gtk.gdk.SHIFT_MASK)) + and self.get_selection().path_is_selected(target[0])): + # disable selection + self.get_selection().set_select_function(lambda *ignore: False) + self.defer_select = target[0] + + def on_button_release(self, widget, event): + # re-enable selection + self.get_selection().set_select_function(lambda *ignore: True) + + target = self.get_path_at_pos(int(event.x), int(event.y)) + if (self.defer_select and target + and self.defer_select == target[0] + and not (event.x==0 and event.y==0)): # certain drag and drop + self.set_cursor(target[0], target[1], False) + + self.defer_select=False +