Use ObjEntry to select a person as an association

Uses existing code to make the user interface consistent with
similar object selections.

Adds person add and remove buttons.
This commit is contained in:
Nick Hall 2022-03-19 23:20:27 +00:00
parent d830918289
commit 6eedf4a142
3 changed files with 199 additions and 147 deletions

View File

@ -48,9 +48,9 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from gramps.gen.display.name import displayer as name_displayer
from .editsecondary import EditSecondary
from .objectentries import PersonEntry
from gramps.gen.lib import NoteType
from ..widgets import MonitoredEntry, PrivacyButton
from ..selectors import SelectorFactory
from .displaytabs import CitationEmbedList, NoteTab
from ..glade import Glade
from ..ddtargets import DdTargets
@ -94,32 +94,17 @@ class EditPersonRef(EditSecondary):
self.setup_configs('interface.person-ref', 600, 350)
self.person_label = self.top.get_object('person')
#allow for drop:
self.person_label.drag_dest_set(Gtk.DestDefaults.MOTION |
Gtk.DestDefaults.DROP,
[DdTargets.PERSON_LINK.target()],
Gdk.DragAction.COPY)
self.person_label.connect('drag_data_received', self.on_drag_persondata_received)
self._update_dnd_capability()
def _update_dnd_capability(self):
self.label_event_box = self.top.get_object('person_event_box')
# Set the drag action from the label
if self.obj.ref:
self.label_event_box.drag_source_set(
Gdk.ModifierType.BUTTON1_MASK,
[DdTargets.PERSON_LINK.target()], Gdk.DragAction.COPY)
self.label_event_box.drag_source_set_icon_name('gramps-person')
self.label_event_box.connect('drag_data_get', self.drag_data_get)
else:
self.label_event_box.drag_source_unset()
self.share_btn = self.top.get_object('select')
self.add_del_btn = self.top.get_object('add_del')
def _setup_fields(self):
if self.obj.ref:
p = self.dbstate.db.get_person_from_handle(self.obj.ref)
self.person_label.set_text(name_displayer.display(p))
self.person_field = PersonEntry(self.dbstate, self.uistate, self.track,
self.top.get_object("person"),
self.top.get_object("person_event_box"),
self.obj.set_reference_handle,
self.obj.get_reference_handle,
self.add_del_btn, self.share_btn)
self.street = MonitoredEntry(
self.top.get_object("relationship"),
@ -135,7 +120,6 @@ class EditPersonRef(EditSecondary):
def _connect_signals(self):
self.define_cancel_button(self.top.get_object('cancel'))
self.define_ok_button(self.top.get_object('ok'),self.save)
self.top.get_object('select').connect('clicked',self._select_person)
self.define_help_button(self.top.get_object('help'),
WIKI_HELP_PAGE, WIKI_HELP_SEC)
@ -156,35 +140,6 @@ class EditPersonRef(EditSecondary):
if self.obj.ref in handles:
self.close()
def _select_person(self, obj):
SelectPerson = SelectorFactory('Person')
sel = SelectPerson(self.dbstate, self.uistate, self.track)
person = sel.run()
self.update_person(person)
def update_person(self, person):
if person:
self.obj.ref = person.get_handle()
self.person_label.set_text(name_displayer.display(person))
self._update_dnd_capability()
def on_drag_persondata_received(self, widget, context, x, y, sel_data,
info, time):
"""
Handle the standard gtk interface for drag_data_received.
"""
if sel_data and sel_data.get_data():
(drag_type, idval, handle, val) = pickle.loads(sel_data.get_data())
person = self.db.get_person_from_handle(handle)
self.update_person(person)
def drag_data_get(self, widget, context, sel_data, info, time):
# get the selected object, returning if not is defined
if info == DdTargets.PERSON_LINK.app_id:
data = (DdTargets.PERSON_LINK.drag_type, id(self), self.obj.ref, 0)
sel_data.set(DdTargets.PERSON_LINK.atom_drag_type, 8, pickle.dumps(data))
def _create_tabbed_pages(self):
"""
Create the notebook tabs and inserts them into the main

View File

@ -44,7 +44,8 @@ from gi.repository import Pango
# Gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import (Place, Source, Media, Note)
from gramps.gen.lib import (Person, Place, Source, Media, Note)
from .editperson import EditPerson
from .editplace import EditPlace
from .editsource import EditSource
from .editmedia import EditMedia
@ -53,6 +54,7 @@ from ..selectors import SelectorFactory
from ..ddtargets import DdTargets
from gramps.gen.errors import WindowActiveError
from gramps.gen.display.place import displayer as place_displayer
from gramps.gen.display.name import displayer as name_displayer
#-------------------------------------------------------------------------
#
@ -283,6 +285,53 @@ class ObjEntry:
self.add_edt.set_tooltip_text(self.ADD_STR)
self._update_dnd_capability()
class PersonEntry(ObjEntry):
"""
Handles the selection of a existing or new Person. Supports Drag and Drop
to select a person.
"""
EMPTY_TEXT = "<i>%s</i>" % _('To select a person, use drag-and-drop '
'or use the buttons')
EMPTY_TEXT_RED = "<i>%s</i>" % _('No person given, click button to select one')
EDIT_STR = _('Edit person')
SHARE_STR = _('Select an existing person')
ADD_STR = _('Add a new person')
DEL_STR = _('Remove person')
_DND_TYPE = DdTargets.PERSON_LINK
_DND_ICON = 'gramps-person'
def __init__(self, dbstate, uistate, track, label, label_event_box, set_val,
get_val, add_edt, share, skip=[]):
ObjEntry.__init__(self, dbstate, uistate, track, label, label_event_box, set_val,
get_val, add_edt, share)
self.skip = skip
def get_from_handle(self, handle):
""" return the object given the hande
"""
return self.db.get_person_from_handle(handle)
def get_label(self, person):
person_name = name_displayer.display(person)
return "%s \u2068[%s]\u200e\u2069" % (person_name, person.gramps_id)
def call_editor(self, obj=None):
if obj is None:
person = Person()
func = self.obj_added
else:
person = obj
func = self.after_edit
try:
EditPerson(self.dbstate, self.uistate, self.track,
person, func)
except WindowActiveError:
pass
def call_selector(self):
cls = SelectorFactory('Person')
return cls(self.dbstate, self.uistate, self.track, skip=self.skip)
class PlaceEntry(ObjEntry):
"""
Handles the selection of a existing or new Place. Supports Drag and Drop

View File

@ -1,30 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<!-- Generated with glade 3.38.2 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<requires lib="grampswidgets" version="0.0"/>
<object class="GtkDialog" id="pref_edit">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
<property name="can-focus">False</property>
<property name="type-hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox21">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area21">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<property name="can-focus">False</property>
<property name="layout-style">end</property>
<child>
<object class="GtkButton" id="cancel">
<property name="label" translatable="yes">_Cancel</property>
<property name="use_action_appearance">False</property>
<property name="use-action-appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
@ -35,16 +35,16 @@
<child>
<object class="GtkButton" id="ok">
<property name="label" translatable="yes">_OK</property>
<property name="use_action_appearance">False</property>
<property name="use-action-appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Accept changes and close window</property>
<property name="tooltip_text" translatable="yes">Accept changes and close window</property>
<property name="use_underline">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="has-default">True</property>
<property name="receives-default">True</property>
<property name="has-tooltip">True</property>
<property name="tooltip-markup">Accept changes and close window</property>
<property name="tooltip-text" translatable="yes">Accept changes and close window</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
@ -55,12 +55,12 @@
<child>
<object class="GtkButton" id="help">
<property name="label" translatable="yes">_Help</property>
<property name="use_action_appearance">False</property>
<property name="use-action-appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
<property name="can-focus">True</property>
<property name="can-default">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
@ -72,130 +72,100 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="pack-type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<!-- n-columns=4 n-rows=3 -->
<object class="GtkGrid" id="table73">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<property name="can-focus">False</property>
<property name="border-width">12</property>
<property name="row-spacing">6</property>
<property name="column-spacing">12</property>
<child>
<object class="GtkLabel" id="label649">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Person:</property>
<property name="use_underline">True</property>
<property name="use-underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">person</property>
<property name="mnemonic-widget">person</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label650">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Association:</property>
<property name="use_underline">True</property>
<property name="use-underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">relationship</property>
<property name="mnemonic-widget">relationship</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="left-attach">0</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="relationship">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Description of the association, eg. Godfather, Friend, ...
<property name="can-focus">True</property>
<property name="tooltip-text" translatable="yes">Description of the association, eg. Godfather, Friend, ...
Note: Use Events instead for relations connected to specific time frames or occasions. Events can be shared between people, each indicating their role in the event.</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<property name="invisible-char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="private">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2694">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-password</property>
<property name="icon_size">1</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2694-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="private-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Private</property>
</object>
</child>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
<property name="left-attach">1</property>
<property name="top-attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="person_event_box">
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<property name="can-focus">False</property>
<property name="visible-window">False</property>
<child>
<object class="GtkLabel" id="person">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Use the select button to choose a person that has an association to the edited person.</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Use the select button to choose a person that has an association to the edited person.</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="left-attach">1</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="select">
<property name="use_action_appearance">False</property>
<property name="use-action-appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Select a person that has an association to the edited person.</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Select a person that has an association to the edited person.</property>
<child>
<object class="GtkImage" id="image2695">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-index</property>
<property name="can-focus">False</property>
<property name="icon-name">gtk-index</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2695-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Selector</property>
@ -214,10 +184,88 @@ Note: Use Events instead for relations connected to specific time frames or occa
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
<property name="left-attach">2</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="private">
<property name="use-action-appearance">False</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2694">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">dialog-password</property>
<property name="icon_size">1</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2694-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="private-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Private</property>
</object>
</child>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left-attach">3</property>
<property name="top-attach">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="add_del">
<property name="use-action-appearance">False</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="tooltip-text" translatable="yes">Select a person that has an association to the edited person.</property>
<child>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">gtk-index</property>
<child internal-child="accessible">
<object class="AtkObject" id="image1-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Selector</property>
</object>
</child>
</object>
</child>
<accessibility>
<relation type="labelled-by" target="label649"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="add_del-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Person</property>
</object>
</child>
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left-attach">3</property>
<property name="top-attach">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>