diff --git a/gramps/plugins/view/relview.py b/gramps/plugins/view/relview.py
index 674ff2c96..b8034ddab 100644
--- a/gramps/plugins/view/relview.py
+++ b/gramps/plugins/view/relview.py
@@ -33,6 +33,12 @@ _ = glocale.translation.sgettext
ngettext = glocale.translation.ngettext # else "nearby" comments are ignored
import cgi
+import sys
+if sys.version_info[0] < 3:
+ import cPickle as pickle
+else:
+ import pickle
+
#-------------------------------------------------------------------------
#
# Set up logging
@@ -77,6 +83,7 @@ from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gen.const import CUSTOM_FILTERS
from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback,
preset_name)
+from gramps.gui.ddtargets import DdTargets
_GenderCode = {
Person.MALE : '\u2642',
@@ -608,9 +615,13 @@ class RelationshipView(NavigationView):
button.set_tooltip_text(_('Edit %s') % name)
else:
button = None
+ eventbox = Gtk.EventBox()
+ eventbox.set_visible_window(False)
+ self._set_draggable_person(eventbox, person.get_handle())
hbox = widgets.LinkBox(label, button)
+ eventbox.add(hbox)
- table.attach(hbox, 0, 2, 0, 1)
+ table.attach(eventbox, 0, 2, 0, 1)
eventbox = Gtk.EventBox()
if self.use_shade:
@@ -620,7 +631,7 @@ class RelationshipView(NavigationView):
subtbl.set_col_spacings(12)
subtbl.set_row_spacings(0)
eventbox.add(subtbl)
-
+ self._set_draggable_person(eventbox, person.get_handle())
# GRAMPS ID
subtbl.attach(widgets.BasicLabel("%s:" % _('ID')),
@@ -776,6 +787,11 @@ class RelationshipView(NavigationView):
self.row += 1
def write_label(self, title, family, is_parent, person = None):
+ """
+ Write a Family header row
+ Shows following elements:
+ (collapse/expand arrow, Parents/Family title label, Family gramps_id, and add-choose-edit-delete buttons)
+ """
msg = '%s' % cgi.escape(title)
hbox = Gtk.HBox()
label = widgets.MarkupLabel(msg, x_align=1)
@@ -1031,6 +1047,11 @@ class RelationshipView(NavigationView):
return vbox
def write_person(self, title, handle):
+ """
+ Create and show a person cell in the GUI at the current row
+ @param title: left column label
+ @param handle: person handle
+ """
if title:
format = '%s: '
else:
@@ -1045,7 +1066,7 @@ class RelationshipView(NavigationView):
yoptions=Gtk.AttachOptions.FILL|Gtk.AttachOptions.SHRINK)
vbox = Gtk.VBox()
-
+ eventbox = Gtk.EventBox()
if handle:
name = self.get_name(handle, True)
person = self.dbstate.db.get_person_from_handle(handle)
@@ -1067,6 +1088,7 @@ class RelationshipView(NavigationView):
else:
button = None
vbox.pack_start(widgets.LinkBox(link_label, button), True, True, 0)
+ self._set_draggable_person(eventbox, handle)
else:
link_label = Gtk.Label(label=_('Unknown'))
link_label.set_alignment(0, 1)
@@ -1078,7 +1100,6 @@ class RelationshipView(NavigationView):
if value:
vbox.pack_start(widgets.MarkupLabel(value), True, True, 0)
- eventbox = Gtk.EventBox()
if self.use_shade:
eventbox.override_background_color(Gtk.StateType.NORMAL, self.color)
eventbox.add(vbox)
@@ -1088,6 +1109,31 @@ class RelationshipView(NavigationView):
self.row += 1
return vbox
+ def _set_draggable_person(self, eventbox, person_handle):
+ """
+ Register the given eventbox as a drag_source with given person_handle
+ """
+ eventbox.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
+ [], Gdk.DragAction.COPY)
+ tglist = Gtk.TargetList.new([])
+ tglist.add(DdTargets.PERSON_LINK.atom_drag_type,
+ DdTargets.PERSON_LINK.target_flags,
+ DdTargets.PERSON_LINK.app_id)
+ eventbox.drag_source_set_target_list(tglist)
+ eventbox.drag_source_set_icon_stock('gramps-person')
+ eventbox.connect('drag_data_get',
+ self._make_person_drag_data_get_func(person_handle))
+
+ def _make_person_drag_data_get_func(self, person_h):
+ """
+ Generate at runtime a drag_data_get function returning the given person_h
+ """
+ def drag_data_get(widget, context, sel_data, info, time):
+ if info == DdTargets.PERSON_LINK.app_id:
+ data = (DdTargets.PERSON_LINK.drag_type, id(self), person_h, 0)
+ sel_data.set(DdTargets.PERSON_LINK.atom_drag_type, 8, pickle.dumps(data))
+ return drag_data_get
+
def build_label_cell(self, title):
if title:
format = '%s: '
@@ -1101,19 +1147,25 @@ class RelationshipView(NavigationView):
return lbl
def write_child(self, vbox, handle, index, child_should_be_linked):
+ """
+ Write a child cell (used for children and siblings of active person)
+ """
+ original_vbox = vbox
+ # Always create a transparent eventbox to allow dnd drag
+ ev = Gtk.EventBox()
+ ev.set_visible_window(False)
+ if handle:
+ self._set_draggable_person(ev, handle)
+ vbox = Gtk.VBox()
+ ev.add(vbox)
+
if not child_should_be_linked:
- original_vbox = vbox
- vbox = Gtk.VBox()
frame = Gtk.Frame()
frame.set_shadow_type(Gtk.ShadowType.ETCHED_IN)
- if self.use_shade:
- ev = Gtk.EventBox()
- ev.override_background_color(Gtk.StateType.NORMAL, self.color)
- ev.add(vbox)
- frame.add(ev)
- else:
- frame.add(vbox)
- original_vbox.add(frame)
+ frame.add(ev)
+ original_vbox.pack_start(frame, True, True, 0)
+ else:
+ original_vbox.pack_start(ev, True, True, 0)
parent = has_children(self.dbstate.db,
self.dbstate.db.get_person_from_handle(handle))