diff --git a/src/gui/viewmanager.py b/src/gui/viewmanager.py index 682c5b9af..e4ee1ae4f 100644 --- a/src/gui/viewmanager.py +++ b/src/gui/viewmanager.py @@ -110,6 +110,10 @@ UIDEFAULT = ''' + + + + @@ -509,6 +513,12 @@ class ViewManager(CLIManager): ('ConfigView', 'gramps-config', _('_Configure View...'), 'c', _('Configure the active view'), self.config_view), + ('Copy', gtk.STOCK_COPY, _('Copy'), "c", + _(""), self.__keypress), + ('Paste', gtk.STOCK_PASTE, _('Paste'), "v", + _(""), self.__keypress), + ('Cut', gtk.STOCK_CUT, _('Cut'), "x", + _(""), self.__keypress), ] self._file_toggle_action_list = [ @@ -1222,7 +1232,7 @@ class ViewManager(CLIManager): ToolPluginDialog(self.dbstate, self.uistate, []) except Errors.WindowActiveError: return - + def scratchpad(self, obj): """ Displays the Clipboard (was scratchpad) diff --git a/src/gui/views/navigationview.py b/src/gui/views/navigationview.py index df4e01ead..3b5aa6b49 100644 --- a/src/gui/views/navigationview.py +++ b/src/gui/views/navigationview.py @@ -484,6 +484,70 @@ class NavigationView(PageView): """ raise NotImplementedError + def call_copy(self): + """ + This code is called on Control+C in a navigation view. If the + copy can be handled, it returns true, otherwise false. + + The code brings up the Clipboard (if already exists) or + creates it. The copy is handled through the drag and drop + system. + """ + import cPickle as pickle + from ScratchPad import ScratchPadWindow, obj2target + nav_type, nav_group = self.navigation_type(), self.navigation_group() + active_handle = self.uistate.get_active(nav_type, nav_group) + if active_handle: + clipboard = None + for widget in self.uistate.gwm.window_tree: + if isinstance(widget, ScratchPadWindow): + clipboard = widget + if clipboard is None: + clipboard = ScratchPadWindow(self.dbstate, self.uistate) + # Construct a drop: + drag_type = obj2target(nav_type) + if drag_type: + class Selection(object): + def __init__(self, data): + self.data = data + class Context(object): + targets = [drag_type] + action = 1 + # eg: ('person-link', 23767, '27365123671', 0) + data = (drag_type, id(self), active_handle, 0) + clipboard.object_list.object_drag_data_received( + clipboard.object_list._widget, # widget + Context(), # drag type and action + 0, 0, # x, y + Selection(pickle.dumps(data)), # pickled data + None, # info (not used) + -1) # time + return True + return False + + def call_paste(self): + """ + This code is called on Control+V in a navigation view. If the + copy can be handled, it returns true, otherwise false. + + The code creates the Clipboard if it does not already exist. + """ + from ScratchPad import ScratchPadWindow, obj2target + clipboard = None + for widget in self.uistate.gwm.window_tree: + if isinstance(widget, ScratchPadWindow): + clipboard = widget + if clipboard is None: + clipboard = ScratchPadWindow(self.dbstate, self.uistate) + return True + return False + + def call_cut(self): + """ + This method would be great to move items between databases. + """ + return False + def make_callback(func, handle): """ Generates a callback function based off the passed arguments diff --git a/src/gui/views/pageview.py b/src/gui/views/pageview.py index fc0212f6c..d007f9988 100644 --- a/src/gui/views/pageview.py +++ b/src/gui/views/pageview.py @@ -105,7 +105,11 @@ class PageView(DbGUIElement): self.dirty = True self.active = False self._dirty_on_change_inactive = True - self.func_list = {} + self.func_list = { + "Copy": self.call_copy, + "Paste": self.call_paste, + "Cut": self.call_cut, + } self.category = "Miscellaneous" self.ident = None self.translated_category = _("Miscellaneous") @@ -128,6 +132,15 @@ class PageView(DbGUIElement): """ self.func_list.get(key)() + def call_copy(self): + return False + + def call_paste(self): + return False + + def call_cut(self): + return False + def post(self): """ Called after a page is created. diff --git a/src/gui/widgets/grampletpane.py b/src/gui/widgets/grampletpane.py index 60faffdb4..0299bb2e5 100644 --- a/src/gui/widgets/grampletpane.py +++ b/src/gui/widgets/grampletpane.py @@ -1425,6 +1425,15 @@ class GrampletPane(gtk.ScrolledWindow): return gramplet.title, table return gramplet_panel + def call_copy(self): + return False + + def call_paste(self): + return False + + def call_cut(self): + return False + class Configuration(object): """ A config wrapper to redirect set/get to GrampletPane. diff --git a/src/plugins/lib/libpersonview.py b/src/plugins/lib/libpersonview.py index 5efa194ef..cbda32f95 100644 --- a/src/plugins/lib/libpersonview.py +++ b/src/plugins/lib/libpersonview.py @@ -132,10 +132,10 @@ class BasePersonView(ListView): filter_class=PersonSidebarFilter, markup=BasePersonView.MARKUP_COLS) - self.func_list = { + self.func_list.update({ 'J' : self.jump, 'BackSpace' : self.key_delete, - } + }) config.connect("interface.filter", self.filter_toggle) uistate.connect('nameformat-changed', self.build_tree) diff --git a/src/plugins/lib/libplaceview.py b/src/plugins/lib/libplaceview.py index 2505b3c47..f2e2e8b37 100644 --- a/src/plugins/lib/libplaceview.py +++ b/src/plugins/lib/libplaceview.py @@ -127,11 +127,6 @@ class PlaceBaseView(ListView): 'place-rebuild' : self.object_build, } - self.func_list = { - 'J' : self.jump, - 'BackSpace' : self.key_delete, - } - self.mapservice = config.get('interface.mapservice') self.mapservicedata = {} @@ -144,6 +139,11 @@ class PlaceBaseView(ListView): multiple=True, filter_class=PlaceSidebarFilter, markup=markup) + self.func_list.update({ + 'J' : self.jump, + 'BackSpace' : self.key_delete, + }) + config.connect("interface.filter", self.filter_toggle) diff --git a/src/plugins/view/eventview.py b/src/plugins/view/eventview.py index 88245c236..64b6eea1e 100644 --- a/src/plugins/view/eventview.py +++ b/src/plugins/view/eventview.py @@ -121,10 +121,10 @@ class EventView(ListView): filter_class=EventSidebarFilter, markup = EventView.MARKUP_COLS) - self.func_list = { + self.func_list.update({ 'J' : self.jump, 'BackSpace' : self.key_delete, - } + }) config.connect("interface.filter", self.filter_toggle) uistate.connect('nameformat-changed', self.build_tree) diff --git a/src/plugins/view/familyview.py b/src/plugins/view/familyview.py index 3c0c63a45..0a68714e9 100644 --- a/src/plugins/view/familyview.py +++ b/src/plugins/view/familyview.py @@ -112,10 +112,10 @@ class FamilyView(ListView): multiple=True, filter_class=FamilySidebarFilter) - self.func_list = { + self.func_list.update({ 'J' : self.jump, 'BackSpace' : self.key_delete, - } + }) config.connect("interface.filter", self.filter_toggle) uistate.connect('nameformat-changed', self.build_tree) diff --git a/src/plugins/view/mediaview.py b/src/plugins/view/mediaview.py index e6b9a4c45..372289503 100644 --- a/src/plugins/view/mediaview.py +++ b/src/plugins/view/mediaview.py @@ -128,10 +128,10 @@ class MediaView(ListView): filter_class=MediaSidebarFilter, multiple=True) - self.func_list = { + self.func_list.update({ 'J' : self.jump, 'BackSpace' : self.key_delete, - } + }) config.connect("interface.filter", self.filter_toggle) diff --git a/src/plugins/view/noteview.py b/src/plugins/view/noteview.py index 8fda27aeb..db227740a 100644 --- a/src/plugins/view/noteview.py +++ b/src/plugins/view/noteview.py @@ -101,11 +101,6 @@ class NoteView(ListView): 'note-rebuild' : self.object_build, } - self.func_list = { - 'J' : self.jump, - 'BackSpace' : self.key_delete, - } - ListView.__init__( self, _('Notes'), dbstate, uistate, NoteView.COLUMN_NAMES, len(NoteView.COLUMN_NAMES), NoteModel, signal_map, @@ -114,6 +109,11 @@ class NoteView(ListView): filter_class=NoteSidebarFilter, multiple=True) + self.func_list.update({ + 'J' : self.jump, + 'BackSpace' : self.key_delete, + }) + config.connect("interface.filter", self.filter_toggle) diff --git a/src/plugins/view/pedigreeview.py b/src/plugins/view/pedigreeview.py index 7e7e10aea..2c352dd81 100644 --- a/src/plugins/view/pedigreeview.py +++ b/src/plugins/view/pedigreeview.py @@ -670,10 +670,10 @@ class PedigreeView(NavigationView): Bookmarks.PersonBookmarks, nav_group) - self.func_list = { + self.func_list.update({ 'F2' : self.kb_goto_home, 'J' : self.jump, - } + }) self.dbstate = dbstate self.dbstate.connect('database-changed', self.change_db) diff --git a/src/plugins/view/relview.py b/src/plugins/view/relview.py index 693806ef6..b2f4b600e 100644 --- a/src/plugins/view/relview.py +++ b/src/plugins/view/relview.py @@ -136,9 +136,9 @@ class RelationshipView(NavigationView): Bookmarks.PersonBookmarks, nav_group) - self.func_list = { + self.func_list.update({ 'J' : self.jump, - } + }) dbstate.connect('database-changed', self.change_db) uistate.connect('nameformat-changed', self.build_tree) diff --git a/src/plugins/view/repoview.py b/src/plugins/view/repoview.py index 203e3c14d..b03c957bc 100644 --- a/src/plugins/view/repoview.py +++ b/src/plugins/view/repoview.py @@ -119,11 +119,6 @@ class RepositoryView(ListView): 'repository-rebuild' : self.object_build, } - self.func_list = { - 'J' : self.jump, - 'BackSpace' : self.key_delete, - } - ListView.__init__( self, _('Repositories'), dbstate, uistate, RepositoryView.COLUMN_NAMES, len(RepositoryView.COLUMN_NAMES), @@ -133,6 +128,11 @@ class RepositoryView(ListView): multiple=True, filter_class=RepoSidebarFilter) + self.func_list.update({ + 'J' : self.jump, + 'BackSpace' : self.key_delete, + }) + config.connect("interface.filter", self.filter_toggle) diff --git a/src/plugins/view/sourceview.py b/src/plugins/view/sourceview.py index 9f89da36e..5ecd46e34 100644 --- a/src/plugins/view/sourceview.py +++ b/src/plugins/view/sourceview.py @@ -102,11 +102,6 @@ class SourceView(ListView): 'source-rebuild' : self.object_build, } - self.func_list = { - 'J' : self.jump, - 'BackSpace' : self.key_delete, - } - ListView.__init__( self, _('Sources'), dbstate, uistate, SourceView.COLUMN_NAMES, len(SourceView.COLUMN_NAMES), @@ -116,6 +111,11 @@ class SourceView(ListView): multiple=True, filter_class=SourceSidebarFilter) + self.func_list.update({ + 'J' : self.jump, + 'BackSpace' : self.key_delete, + }) + config.connect("interface.filter", self.filter_toggle)