From 0b6456511eabad072708ae0b0716189a32e4271a Mon Sep 17 00:00:00 2001 From: Richard Taylor Date: Wed, 6 Apr 2005 13:28:51 +0000 Subject: [PATCH] 2005-04-06 Richard Taylor * src/DdTargets.py: added PERSON_LINK_LIST target. * src/FamilyView.py: corrected bug when person is droped if there is no current family. * src/PeopleView.py: enabled dnd of lists of people. * src/plugins/ScratchPad.py: support lists of people. svn: r4308 --- ChangeLog | 7 +++++ src/DdTargets.py | 4 ++- src/FamilyView.py | 15 ++++++---- src/PeopleView.py | 30 ++++++++++++++++---- src/plugins/ScratchPad.py | 58 +++++++++++++++++++++++++++++++-------- 5 files changed, 90 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index c269a5abb..eae8beb73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2005-04-06 Richard Taylor + * src/DdTargets.py: added PERSON_LINK_LIST target. + * src/FamilyView.py: corrected bug when person is droped if there is no current + family. + * src/PeopleView.py: enabled dnd of lists of people. + * src/plugins/ScratchPad.py: support lists of people. + 2005-04-06 Richard Taylor * src/GrampsDBCallback.py: improved error reporting when there is an error in a callback function. Added unittest for exception in callback function. diff --git a/src/DdTargets.py b/src/DdTargets.py index 1ba7cfdc5..7dc52a33d 100644 --- a/src/DdTargets.py +++ b/src/DdTargets.py @@ -106,6 +106,7 @@ class _DdTargets(object): self.MEDIAOBJ = _DdType(self,'mediaobj') self.PERSON_LINK = _DdType(self,'person-link') + self.PERSON_LINK_LIST = _DdType(self,'person-link-list') self.FAMILY_EVENT = _DdType(self,'fevent') self.FAMILY_ATTRIBUTE = _DdType(self,'fattr') @@ -120,7 +121,8 @@ class _DdTargets(object): self.SOURCEREF, self.NAME, self.MEDIAOBJ, - self.PERSON_LINK] + self.PERSON_LINK, + self.PERSON_LINK_LIST] self.CHILD = _DdType(self,'child') self.SPOUSE = _DdType(self,'spouce') diff --git a/src/FamilyView.py b/src/FamilyView.py index 309a295b1..03e559f60 100644 --- a/src/FamilyView.py +++ b/src/FamilyView.py @@ -1389,17 +1389,13 @@ class FamilyView: self.load_family() def drag_data_received(self,widget,context,x,y,sel_data,info,time): - path = self.child_list.get_path_at_pos(x,y) - if path == None: - row = len(self.family.get_child_handle_list()) - else: - row = path[0][0] -1 if DdTargets.PERSON_LINK.drag_type in context.targets: drop_person_handle = sel_data.data # Check child is not already in the family - if drop_person_handle in self.family.get_child_handle_list(): + if self.family and \ + drop_person_handle in self.family.get_child_handle_list(): return family = self.family @@ -1429,6 +1425,13 @@ class FamilyView: self.display_marriage(family) elif sel_data and sel_data.data: + + path = self.child_list.get_path_at_pos(x,y) + if path == None: + row = len(self.family.get_child_handle_list()) + else: + row = path[0][0] -1 + exec 'data = %s' % sel_data.data exec 'mytype = "%s"' % data[0] exec 'person = "%s"' % data[1] diff --git a/src/PeopleView.py b/src/PeopleView.py index d88e930f4..06712b7b5 100644 --- a/src/PeopleView.py +++ b/src/PeopleView.py @@ -21,6 +21,13 @@ # $Id$ + +#------------------------------------------------------------------------ +# +# standard python modules +# +#------------------------------------------------------------------------ +import cPickle as pickle #------------------------------------------------------------------------- # # internationalization @@ -87,6 +94,7 @@ class PeopleView: self.person_selection = self.person_tree.get_selection() self.person_selection.set_mode(gtk.SELECTION_MULTIPLE) self.person_selection.connect('changed',self.row_changed) + self.person_selection.connect('changed',self.set_dnd_target) self.person_tree.connect('row_activated', self.alpha_event) self.person_tree.connect('button-press-event', self.on_plist_button_press) @@ -94,9 +102,6 @@ class PeopleView: # # DnD support # - self.person_tree.drag_source_set(BUTTON1_MASK, - [DdTargets.PERSON_LINK.target()], - ACTION_COPY) self.person_tree.connect('drag_data_get', self.person_drag_data_get) def person_drag_data_get(self, widget, context, sel_data, info, time): @@ -105,9 +110,22 @@ class PeopleView: if len(selected_ids) == 1: sel_data.set(sel_data.target, 8, selected_ids[0]) elif len(selected_ids) > 1: - # TBD - pass - + sel_data.set(DdTargets.PERSON_LINK_LIST.drag_type,8, + pickle.dumps(selected_ids)) + + def set_dnd_target(self,obj): + selected_ids = self.get_selected_objects() + + if len(selected_ids) == 1: + self.person_tree.drag_source_set(BUTTON1_MASK, + [DdTargets.PERSON_LINK.target()], + ACTION_COPY) + elif len(selected_ids) > 1: + self.person_tree.drag_source_set(BUTTON1_MASK, + [DdTargets.PERSON_LINK_LIST.target()], + ACTION_COPY) + + def sort_clicked(self,obj): for col in self.columns: diff --git a/src/plugins/ScratchPad.py b/src/plugins/ScratchPad.py index f24abda0d..32e473017 100644 --- a/src/plugins/ScratchPad.py +++ b/src/plugins/ScratchPad.py @@ -63,7 +63,7 @@ BLANK_PIC = gtk.gdk.Pixbuf(0,0,8,1,1) #------------------------------------------------------------------------- # -# wrapper classes to provide objecy specific listing in the ListView +# wrapper classes to provide object specific listing in the ListView # #------------------------------------------------------------------------- @@ -469,6 +469,32 @@ class ScratchPersonLink(ScratchPadWrapper): return s +#------------------------------------------------------------------------- +# +# Wrapper classes to deal with lists of objects +# +#------------------------------------------------------------------------- + +class ScratchDropList(object): + + def __init__(self,db,obj_list): + self._db = db + self._obj_list = pickle.loads(obj_list) + + def get_objects(self): + return [self._cls(self._db,obj) for obj in self._obj_list] + +class ScratchPersonLinkList(ScratchDropList): + + DROP_TARGETS = [DdTargets.PERSON_LINK_LIST] + DRAG_TARGET = None + + def __init__(self,db,obj_list): + ScratchDropList.__init__(self,db,obj_list) + self._cls = ScratchPersonLink + + + #------------------------------------------------------------------------- # # ScratchPadListModel class @@ -562,6 +588,7 @@ class ScratchPadListView: self.register_wrapper_class(ScratchPadText) self.register_wrapper_class(ScratchMediaObj) self.register_wrapper_class(ScratchPersonLink) + self.register_wrapper_class(ScratchPersonLinkList) def register_wrapper_class(self,wrapper_class): @@ -643,17 +670,26 @@ class ScratchPadListView: o = wrapper_class(self._db,sel_data) - drop_info = widget.get_dest_row_at_pos(x, y) - if drop_info: - path, position = drop_info - iter = model.get_iter(path) - if (position == gtk.TREE_VIEW_DROP_BEFORE - or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE): - model.insert_before(iter,[o.__class__.DRAG_TARGET.drag_type,o,o.tooltip]) - else: - model.insert_after(iter,[o.__class__.DRAG_TARGET.drag_type,o,o.tooltip]) + # If the wrapper object is a subclass of ScratchDropList then + # the drag data was a list of objects and we need to decode + # all of them. + if isinstance(o,ScratchDropList): + o_list = o.get_objects() else: - model.append([o.__class__.DRAG_TARGET.drag_type,o,o.tooltip]) + o_list = [o] + + for o in o_list: + drop_info = widget.get_dest_row_at_pos(x, y) + if drop_info: + path, position = drop_info + iter = model.get_iter(path) + if (position == gtk.TREE_VIEW_DROP_BEFORE + or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE): + model.insert_before(iter,[o.__class__.DRAG_TARGET.drag_type,o,o.tooltip]) + else: + model.insert_after(iter,[o.__class__.DRAG_TARGET.drag_type,o,o.tooltip]) + else: + model.append([o.__class__.DRAG_TARGET.drag_type,o,o.tooltip]) # remember time for double drop workaround.