From cced1bce3794884b74ab11b6e350be2b16a5f612 Mon Sep 17 00:00:00 2001 From: Richard Taylor Date: Thu, 24 Mar 2005 13:44:54 +0000 Subject: [PATCH] 2005-03-24 Richard Taylor * src/DdTargets.py: new module to manage drag and drop target data. * src/Makefile.am: added DdTargets.py * src/ScratchPad.py: modified to use DdTargets.py. This is the first stage. I will look at modifying EditPersons.py to use DdTargets.py next svn: r4231 --- gramps2/ChangeLog | 6 + gramps2/src/DdTargets.py | 187 ++++++++++++++++++++++++++++++ gramps2/src/Makefile.am | 1 + gramps2/src/plugins/ScratchPad.py | 97 ++++++++-------- 4 files changed, 240 insertions(+), 51 deletions(-) create mode 100644 gramps2/src/DdTargets.py diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 81b2e4001..ed80ed39c 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,9 @@ +2005-03-24 Richard Taylor + * src/DdTargets.py: new module to manage drag and drop target data. + * src/Makefile.am: added DdTargets.py + * src/ScratchPad.py: modified to use DdTargets.py. This is the first + stage. I will look at modifying EditPersons.py to use DdTargets.py next. + 2005-03-23 Martin Hawlisch * src/RelLib.py: Added self.get_date() to get_text_data_child_list(). This way the date is searchable in the full-text search filter. diff --git a/gramps2/src/DdTargets.py b/gramps2/src/DdTargets.py new file mode 100644 index 000000000..3b8e1d40d --- /dev/null +++ b/gramps2/src/DdTargets.py @@ -0,0 +1,187 @@ +# -*- python -*- +# -*- coding: utf-8 -*- +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2005 Donald N. Allingham +# +# 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$ + +""" + This module provides management of all the drag and drop target information + required by gramps widgets. + + Adding a new drag and drop target. + ================================== + + To add a new target: add a new _DdType to in _DdTargets.__init__ and + then add this new type to the list returned from either all_text_types() + and all_text_targets() or or all_gramps_targets() and all_gramps_types(). + + Usage + ===== + + The module defines a singleton instance of _DdTargets called DdTargets. + + from DdTargets import DdTargets + + drag_dest_set(gtk.DEST_DEFAULT_ALL, + DdTargets.all_targets(), + ACTION_COPY) + +""" + +class _DdType: + """Represents the fields needed by a drag and drop traget.""" + + _APP_ID_OFFSET = 40 # Starting value of app_ids + + def __init__(self,container,drag_type,target_flags=0,app_id=None): + """Create a new DdType: + + drag_type: string holding the name of the type. + target_flags: int value that will be passed to drop target. + app_id: integer target id passed to drop target. + """ + + self.drag_type = drag_type + self.target_flags = target_flags + self.app_id = app_id or self._calculate_id() + container.insert(self) + + def _calculate_id(self): + """return the next available app_id.""" + + id = _DdType._APP_ID_OFFSET + _DdType._APP_ID_OFFSET += 1 + return id + + def target(self): + """return the full target information in the format + required by the Gtk functions.""" + return (self.drag_type,self.target_flags,self.app_id) + + + +class _DdTargets(object): + """A single class that manages all the drag and drop targets.""" + + _instance = None # Singleton instance + + def __new__(cls): + """Ensure that we never have more than one instance.""" + + if _DdTargets._instance is not None: + return _DdTargets._instance + _DdTargets._instance = object.__new__(cls) + return _DdTargets._instance + + def __init__(self): + """Set up the drag and drop targets.""" + + self._type_map = {} + self._app_id_map = {} + + self.URL = _DdType(self,'url',0,0) + self.EVENT = _DdType(self,'pevent',0,1) + self.ATTRIBUTE = _DdType(self,'pattr',0,2) + self.ADDRESS = _DdType(self,'paddr',0,3) + self.SOURCEREF = _DdType(self,'srcref',0,4) + + self.TEXT = _DdType(self,'TEXT',0,1) + self.TEXT_MIME = _DdType(self,'text/plain',0,0) + self.STRING = _DdType(self,'STRING', 0, 2) + self.COMPOUND_TEXT = _DdType(self,'COMPOUND_TEXT', 0, 3) + self.UTF8_STRING = _DdType(self,'UTF8_STRING', 0, 4) + + def insert(self,dd_type): + """Add a target to the lookup lists. These lists are + used purely for performance reasons.""" + + self._type_map[dd_type.drag_type] = dd_type + self._app_id_map[dd_type.app_id] = dd_type + + def get_dd_type_from_type_name(self,type_name): + return self._type_map.get(type_name,None) + + def get_dd_type_from_app_id(self,app_id): + return self._app_id_map.get(app_id,None) + + def is_text_type(self,type_name): + return type_name in self.all_text_types() + + def all_text_types(self): + """return a list of all the type names that could be + used as the type of a string.""" + + return (self.TEXT.drag_type, + self.TEXT_MIME.drag_type, + self.STRING.drag_type, + self.COMPOUND_TEXT.drag_type, + self.UTF8_STRING.drag_type) + + def is_gramps_type(self,type_name): + return type_name in self.all_gramps_types() + + def all_gramps_types(self): + """return a list of all the type names that are internal + to gramps.""" + + return (self.URL.drag_type, + self.EVENT.drag_type, + self.ATTRIBUTE.drag_type, + self.ADDRESS.drag_type, + self.SOURCEREF.drag_type) + + def all_text_targets(self): + """return a list of all the targets that could be used + for text.""" + + return (self.TEXT.target(), + self.TEXT_MIME.target(), + self.STRING.target(), + self.COMPOUND_TEXT.target(), + self.UTF8_STRING.target()) + + + def all_gramps_targets(self): + """return a list off the internal gramps targets.""" + + return (self.URL.target(), + self.EVENT.target(), + self.ATTRIBUTE.target(), + self.ADDRESS.target(), + self.SOURCEREF.target()) + + def all_targets(self): + """return a list of all the known targets.""" + return self.all_gramps_targets() + self.all_text_targets() + +# Create the singleton instance. + +DdTargets = _DdTargets() + + +# +# Below here is test code. +# +if __name__ == "__main__": + + print repr(DdTargets.all_text_types()) + print repr(DdTargets.URL) + print DdTargets.is_gramps_type('pevent') diff --git a/gramps2/src/Makefile.am b/gramps2/src/Makefile.am index 30d606538..95ac70dfd 100644 --- a/gramps2/src/Makefile.am +++ b/gramps2/src/Makefile.am @@ -40,6 +40,7 @@ gdir_PYTHON = \ DateHandler.py\ DateDisplay.py\ DbPrompter.py\ + DdTargets.py\ DisplayModels.py\ DisplayTrace.py\ EditPerson.py\ diff --git a/gramps2/src/plugins/ScratchPad.py b/gramps2/src/plugins/ScratchPad.py index 6ecabb194..c078b08a1 100644 --- a/gramps2/src/plugins/ScratchPad.py +++ b/gramps2/src/plugins/ScratchPad.py @@ -54,39 +54,41 @@ from gtk.gdk import ACTION_COPY, BUTTON1_MASK # #------------------------------------------------------------------------- -text_targets = ['text/plain', - 'TEXT', - 'STRING', - 'COMPOUND_TEXT', - 'UTF8_STRING'] +from DdTargets import DdTargets -text_tgts = [('text/plain',0,0), - ('TEXT', 0, 1), - ('STRING', 0, 2), - ('COMPOUND_TEXT', 0, 3), - ('UTF8_STRING', 0, 4)] +##text_targets = ['text/plain', +## 'TEXT', +## 'STRING', +## 'COMPOUND_TEXT', +## 'UTF8_STRING'] -gramps_targets = ['url', - 'pevent', - 'pattr', - 'paddr', - 'srcref'] +##text_tgts = [('text/plain',0,0), +## ('TEXT', 0, 1), +## ('STRING', 0, 2), +## ('COMPOUND_TEXT', 0, 3), +## ('UTF8_STRING', 0, 4)] -pycode_tgts = [('url', 0, 0), - ('pevent', 0, 1), - ('pattr', 0, 2), - ('paddr', 0, 3), - ('srcref', 0, 4)] + text_tgts +##gramps_targets = ['url', +## 'pevent', +## 'pattr', +## 'paddr', +## 'srcref'] + +##pycode_tgts = [('url', 0, 0), +## ('pevent', 0, 1), +## ('pattr', 0, 2), +## ('paddr', 0, 3), +## ('srcref', 0, 4)] + text_tgts -TEXT_TARGET = 'TEXT' +##TEXT_TARGET = 'TEXT' -target_map = {'url':[('url', 0, 0)], - 'pevent': [('pevent', 0, 1)], - 'pattr': [('pattr', 0, 2)], - 'paddr': [('paddr', 0, 3)], - 'srcref': [('srcref', 0, 4)], - TEXT_TARGET: text_tgts} +##target_map = {'url':[('url', 0, 0)], +## 'pevent': [('pevent', 0, 1)], +## 'pattr': [('pattr', 0, 2)], +## 'paddr': [('paddr', 0, 3)], +## 'srcref': [('srcref', 0, 4)], +## TEXT_TARGET: text_tgts} @@ -149,8 +151,9 @@ class ScratchPadWindow: "on_scratchPad_delete_event": self.on_delete_event }) - self.object_list.drag_dest_set(gtk.DEST_DEFAULT_ALL, pycode_tgts, - ACTION_COPY) + self.object_list.drag_dest_set(gtk.DEST_DEFAULT_ALL, + DdTargets.all_targets(), + ACTION_COPY) self.object_list.connect('drag_data_get', self.object_drag_data_get) self.object_list.connect('drag_begin', self.object_drag_begin) @@ -259,8 +262,6 @@ class ScratchPadWindow: self.redraw_object_list() def on_object_select_row(self,obj): - global target_map - global TEXT_TARGET o = self.otree.get_selected_objects() @@ -271,19 +272,19 @@ class ScratchPadWindow: # union with gramps_types if len([target for target \ - in obj_targets if target in gramps_targets]) > 0: + in obj_targets if DdTargets.is_gramps_type(target)]) > 0: exec 'data = %s' % o[0]['data'] exec 'mytype = "%s"' % data[0] - target = target_map[mytype] + target = DdTargets.get_dd_type_from_type_name(mytype).target() # Union with text targets elif len([target for target \ - in obj_targets if target in text_targets]) > 0: - target = target_map[TEXT_TARGET] + in obj_targets if DdTargets.is_text_type(target)]) > 0: + target = DdTargets.TEXT.target() self.object_list.drag_source_unset() - self.object_list.drag_source_set(BUTTON1_MASK, target, ACTION_COPY) + self.object_list.drag_source_set(BUTTON1_MASK, [target], ACTION_COPY) def on_update_object_clicked(self, obj): @@ -293,9 +294,6 @@ class ScratchPadWindow: return def object_drag_data_get(self,widget, context, sel_data, info, time): - - global gramps_targets - global text_targets o = self.otree.get_selected_objects() @@ -306,7 +304,7 @@ class ScratchPadWindow: # union with gramps_types if len([target for target \ - in obj_targets if target in gramps_targets]) > 0: + in obj_targets if DdTargets.is_gramps_type(target)]) > 0: exec 'data = %s' % o[0]['data'] exec 'mytype = "%s"' % data[0] @@ -317,7 +315,7 @@ class ScratchPadWindow: # Union with text targets elif len([target for target \ - in obj_targets if target in text_targets]) > 0: + in obj_targets if DdTargets.is_text_type(target)]) > 0: send_data = str(o[0]['data']) sel_data.set(sel_data.target, bits_per, send_data) @@ -335,9 +333,6 @@ class ScratchPadWindow: def redraw_object_list(self): """Redraws the address list""" - global gramps_targets - global text_targets - self.otree.clear() for obj in self.olist: @@ -345,7 +340,7 @@ class ScratchPadWindow: # union with gramps_types if len([target for target \ - in obj_targets if target in gramps_targets]) > 0: + in obj_targets if DdTargets.is_gramps_type(target)]) > 0: exec 'unpack_data = %s' % obj['data'] exec 'mytype = "%s"' % unpack_data[0] @@ -353,7 +348,7 @@ class ScratchPadWindow: node = None - if mytype == 'paddr': + if mytype == DdTargets.ADDRESS.drag_type: location = "%s %s %s %s" % (data.get_street(),data.get_city(), data.get_state(),data.get_country()) node = self.otree.add([_("Address"), @@ -361,23 +356,23 @@ class ScratchPadWindow: location, self.generate_addr_tooltip(data)],obj) - elif mytype == 'pevent': + elif mytype == DdTargets.EVENT.drag_type: node = self.otree.add([_("Event"), const.display_pevent(data.get_name()), data.get_description(), self.generate_event_tooltip(data)],obj) - elif mytype == 'url': + elif mytype == DdTargets.URL.drag_type: node = self.otree.add([_("Url"), data.get_path(), data.get_description(), self.generate_url_tooltip(data)],obj) - elif mytype == 'pattr': + elif mytype == DdTargets.ATTRIBUTE.drag_type: node = self.otree.add([_("Attribute"), const.display_pattr(data.get_type()), data.get_value(), self.generate_pattr_tooltip(data)],obj) - elif mytype == 'srcref': + elif mytype == DdTargets.SOURCEREF.drag_type: base = self.db.get_source_from_handle(data.get_base_handle()) node = self.otree.add([_("SourceRef"), base.get_title(), @@ -386,7 +381,7 @@ class ScratchPadWindow: # Union with text targets elif len([target for target \ - in obj_targets if target in text_targets]) > 0: + in obj_targets if DdTargets.is_text_type(target)]) > 0: node = self.otree.add([_("Text"), "", obj['data'],