diff --git a/gramps/gui/editors/displaytabs/eventembedlist.py b/gramps/gui/editors/displaytabs/eventembedlist.py index 30e7bcb62..aa0c9f73f 100644 --- a/gramps/gui/editors/displaytabs/eventembedlist.py +++ b/gramps/gui/editors/displaytabs/eventembedlist.py @@ -131,15 +131,15 @@ class EventEmbedList(DbGUIElement, GroupEmbeddedList): refs = self.get_data()[self._WORKGROUP] ref_list = [eref.ref for eref in refs] indexlist = [] - last = 0 + last = -1 while True: try: - last = ref_list.index(handle) + last = ref_list.index(handle, last + 1) indexlist.append(last) except ValueError: break #remove the deleted workgroup events from the object - for index in indexlist.reverse(): + for index in reversed(indexlist): del refs[index] #now rebuild the display tab self.rebuild_callback() diff --git a/gramps/gui/editors/displaytabs/personrefembedlist.py b/gramps/gui/editors/displaytabs/personrefembedlist.py index cf74fc292..32e2a98dd 100644 --- a/gramps/gui/editors/displaytabs/personrefembedlist.py +++ b/gramps/gui/editors/displaytabs/personrefembedlist.py @@ -38,13 +38,15 @@ from gramps.gen.errors import WindowActiveError from ...ddtargets import DdTargets from .personrefmodel import PersonRefModel from .embeddedlist import EmbeddedList, TEXT_COL, MARKUP_COL, ICON_COL +from ...dbguielement import DbGUIElement + #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- -class PersonRefEmbedList(EmbeddedList): +class PersonRefEmbedList(DbGUIElement, EmbeddedList): _HANDLE_COL = 4 _DND_TYPE = DdTargets.PERSONREF @@ -69,15 +71,61 @@ class PersonRefEmbedList(EmbeddedList): def __init__(self, dbstate, uistate, track, data): self.data = data + DbGUIElement.__init__(self, dbstate.db) EmbeddedList.__init__(self, dbstate, uistate, track, _('_Associations'), PersonRefModel, move_buttons=True) + def _connect_db_signals(self): + """ + called on init of DbGUIElement, connect to db as required. + """ + #note: person-rebuild closes the editors, so no need to connect to it + self.callman.register_callbacks( + {'person-update': self.person_change, # change to person we track + 'person-delete': self.person_delete, # delete of person we track + }) + self.callman.connect_all(keys=['person']) + + def person_change(self, *obj): + """ + Callback method called when a tracked person changes (description + changes...) + """ + self.rebuild() + + def person_delete(self, hndls): + """ + Callback method called when a tracked person is deleted. + There are two possibilities: + * a tracked non-workgroup person is deleted, just rebuilding the view + will correct this. + * a workgroup person is deleted. The person must be removed from the + obj so that no inconsistent data is shown. + """ + for handle in hndls: + ref_list = [pref.ref for pref in self.data] + indexlist = [] + last = -1 + while True: + try: + last = ref_list.index(handle, last + 1) + indexlist.append(last) + except ValueError: + break + #remove the deleted workgroup persons from the object + for index in reversed(indexlist): + del self.data[index] + #now rebuild the display tab + self.rebuild() + def get_ref_editor(self): from .. import EditPersonRef return EditPersonRef def get_data(self): + self.callman.register_handles( + {'person': [pref.ref for pref in self.data]}) return self.data def column_order(self): diff --git a/gramps/gui/editors/displaytabs/placerefembedlist.py b/gramps/gui/editors/displaytabs/placerefembedlist.py index 2cd431514..8f37bead0 100644 --- a/gramps/gui/editors/displaytabs/placerefembedlist.py +++ b/gramps/gui/editors/displaytabs/placerefembedlist.py @@ -40,13 +40,15 @@ from ...ddtargets import DdTargets from .placerefmodel import PlaceRefModel from .embeddedlist import EmbeddedList, TEXT_COL from ...selectors import SelectorFactory +from ...dbguielement import DbGUIElement + #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- -class PlaceRefEmbedList(EmbeddedList): +class PlaceRefEmbedList(DbGUIElement, EmbeddedList): _HANDLE_COL = 4 _DND_TYPE = DdTargets.PLACEREF @@ -65,11 +67,57 @@ class PlaceRefEmbedList(EmbeddedList): self.data = data self.handle = handle self.callback = callback + DbGUIElement.__init__(self, dbstate.db) EmbeddedList.__init__(self, dbstate, uistate, track, _('Enclosed By'), PlaceRefModel, share_button=True, move_buttons=True) + def _connect_db_signals(self): + """ + called on init of DbGUIElement, connect to db as required. + """ + #note: place-rebuild closes the editors, so no need to connect to it + self.callman.register_callbacks( + {'place-update': self.place_change, # change to place we track + 'place-delete': self.place_delete, # delete of place we track + }) + self.callman.connect_all(keys=['place']) + + def place_change(self, *obj): + """ + Callback method called when a tracked place changes (description + changes...) + """ + self.rebuild() + + def place_delete(self, hndls): + """ + Callback method called when a tracked place is deleted. + There are two possibilities: + * a tracked non-workgroup place is deleted, just rebuilding the view + will correct this. + * a workgroup place is deleted. The place must be removed from the + obj so that no inconsistent data is shown. + """ + for handle in hndls: + ref_list = [pref.ref for pref in self.data] + indexlist = [] + last = -1 + while True: + try: + last = ref_list.index(handle, last + 1) + indexlist.append(last) + except ValueError: + break + #remove the deleted workgroup places from the object + for index in reversed(indexlist): + del self.data[index] + #now rebuild the display tab + self.rebuild() + def get_data(self): + self.callman.register_handles( + {'place': [pref.ref for pref in self.data]}) return self.data def column_order(self): diff --git a/gramps/gui/editors/editcitation.py b/gramps/gui/editors/editcitation.py index a607f8295..fc5c6eba4 100644 --- a/gramps/gui/editors/editcitation.py +++ b/gramps/gui/editors/editcitation.py @@ -174,6 +174,8 @@ class EditCitation(EditPrimary): self._add_db_signal('citation-rebuild', self._do_close) self._add_db_signal('citation-delete', self.check_for_close) + self._add_db_signal('source-delete', self.source_delete) + self._add_db_signal('source-update', self.source_update) def _setup_fields(self): """ @@ -269,6 +271,26 @@ class EditCitation(EditPrimary): author = '' self.glade.get_object("author").set_text(author) + def source_update(self, hndls): + ''' Source changed outside of dialog, update text if its ours ''' + handle = self.obj.get_reference_handle() + if handle and handle in hndls: + source = self.db.get_source_from_handle(handle) + s_lbl = "%s [%s]" % (source.get_title(), source.gramps_id) + self.glade.get_object("source").set_text(s_lbl) + author = source.get_author() + self.glade.get_object("author").set_text(author) + + def source_delete(self, hndls): + ''' Source deleted outside of dialog, remove it if its ours''' + handle = self.obj.get_reference_handle() + if handle and handle in hndls: + self.obj.set_reference_handle(None) + self.glade.get_object("source").set_markup( + self.source_field.EMPTY_TEXT) + self.glade.get_object("author").set_text('') + self.source_field.set_button(False) + def build_menu_names(self, source): """ Provide the information needed by the base class to define the diff --git a/gramps/gui/editors/editevent.py b/gramps/gui/editors/editevent.py index f2726f292..ccda9ef48 100644 --- a/gramps/gui/editors/editevent.py +++ b/gramps/gui/editors/editevent.py @@ -129,6 +129,8 @@ class EditEvent(EditPrimary): """ self._add_db_signal('event-rebuild', self._do_close) self._add_db_signal('event-delete', self.check_for_close) + self._add_db_signal('place-delete', self.place_delete) + self._add_db_signal('place-update', self.place_update) def _setup_fields(self): @@ -301,6 +303,24 @@ class EditEvent(EditPrimary): cmp_obj = self.empty_object() return cmp_obj.serialize(True)[1:] != self.obj.serialize()[1:] + def place_update(self, hndls): + ''' Place changed outside of dialog, update text if its ours ''' + handle = self.obj.get_place_handle() + if handle and handle in hndls: + place = self.db.get_place_from_handle(handle) + p_lbl = "%s [%s]" % (place.get_title(), place.gramps_id) + self.top.get_object("place").set_text(p_lbl) + + def place_delete(self, hndls): + ''' Place deleted outside of dialog, remove it if its ours''' + handle = self.obj.get_place_handle() + if handle and handle in hndls: + self.obj.set_place_handle(None) + self.top.get_object("place").set_markup( + self.place_field.EMPTY_TEXT) + self.place_field.set_button(False) + + #------------------------------------------------------------------------- # # Delete Query class diff --git a/gramps/gui/editors/editeventref.py b/gramps/gui/editors/editeventref.py index 676b1d78c..2e96427a2 100644 --- a/gramps/gui/editors/editeventref.py +++ b/gramps/gui/editors/editeventref.py @@ -120,6 +120,8 @@ class EditEventRef(EditReference): """ self._add_db_signal('event-rebuild', self.close) self._add_db_signal('event-delete', self.check_for_close) + self._add_db_signal('place-delete', self.place_delete) + self._add_db_signal('place-update', self.place_update) def _setup_fields(self): @@ -279,3 +281,20 @@ class EditEventRef(EditReference): self.update(self.source_ref,self.source) self.close() + + def place_update(self, hndls): + ''' Place changed outside of dialog, update text if its ours ''' + handle = self.source.get_place_handle() + if handle and handle in hndls: + place = self.db.get_place_from_handle(handle) + p_lbl = "%s [%s]" % (place.get_title(), place.gramps_id) + self.top.get_object("eer_place").set_text(p_lbl) + + def place_delete(self, hndls): + ''' Place deleted outside of dialog, remove it if its ours''' + handle = self.source.get_place_handle() + if handle and handle in hndls: + self.source.set_place_handle(None) + self.top.get_object("eer_place").set_markup( + self.place_field.EMPTY_TEXT) + self.place_field.set_button(False) diff --git a/gramps/gui/editors/editfamily.py b/gramps/gui/editors/editfamily.py index eb90c4818..675a31d38 100644 --- a/gramps/gui/editors/editfamily.py +++ b/gramps/gui/editors/editfamily.py @@ -80,6 +80,7 @@ from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback, from ..selectors import SelectorFactory from gramps.gen.utils.id import create_id from gramps.gen.const import URL_MANUAL_SECT1 +from ..dbguielement import DbGUIElement #------------------------------------------------------------------------- # @@ -97,7 +98,8 @@ _KP_ENTER = Gdk.keyval_from_name("KP_Enter") _LEFT_BUTTON = 1 _RIGHT_BUTTON = 3 -class ChildEmbedList(EmbeddedList): + +class ChildEmbedList(DbGUIElement, EmbeddedList): """ The child embed list is specific to the Edit Family dialog, so it is contained here instead of in displaytabs. @@ -139,9 +141,54 @@ class ChildEmbedList(EmbeddedList): Create the object, storing the passed family value """ self.family = family + DbGUIElement.__init__(self, dbstate.db) EmbeddedList.__init__(self, dbstate, uistate, track, _('Chil_dren'), ChildModel, share_button=True, move_buttons=True) + def _connect_db_signals(self): + """ + called on init of DbGUIElement, connect to db as required. + """ + #note: event-rebuild closes the editors, so no need to connect to it + self.callman.register_callbacks( + {'person-update': self.person_change, # change to person we track + 'person-delete': self.person_delete, # delete of person we track + }) + self.callman.connect_all(keys=['person']) + + def person_change(self, *obj): + """ + Callback method called when a tracked person changes (description + changes...) + """ + self.rebuild() + + def person_delete(self, hndls): + """ + Callback method called when a tracked person is deleted. + There are two possibilities: + * a tracked non-workgroup person is deleted, just rebuilding the view + will correct this. + * a workgroup person is deleted. The person must be removed from the + obj so that no inconsistent data is shown. + """ + for handle in hndls: + prefs = self.get_data() + ref_list = [pref.ref for pref in prefs] + indexlist = [] + last = -1 + while True: + try: + last = ref_list.index(handle, last + 1) + indexlist.append(last) + except ValueError: + break + #remove the deleted workgroup persons from the object + for index in reversed(indexlist): + del prefs[index] + #now rebuild the display tab + self.rebuild() + def get_popup_menu_items(self): return [ (False, _('Edit child'), self.edit_child_button_clicked), @@ -163,7 +210,10 @@ class ChildEmbedList(EmbeddedList): Normally, get_data returns a list. However, we return family object here instead. """ - return self.family.get_child_ref_list() + prefs = self.family.get_child_ref_list() + self.callman.register_handles( + {'person': [eref.ref for eref in prefs]}) + return prefs def column_order(self): return [(1, 13), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), @@ -413,11 +463,22 @@ class EditFamily(EditPrimary): 'event-update': self.topdata_updated, # change eg birth event fath 'event-rebuild': self.topdata_updated, 'event-delete': self.topdata_updated, # delete eg birth event fath - 'person-update': self.topdata_updated, # change eg name of father + 'person-update': self.topdata_updated, # change eg name of father + 'person-delete' : self.person_delete, # mother/father deleted? 'person-rebuild': self._do_close, }) self.callman.connect_all(keys=['family', 'event', 'person']) + def person_delete(self, handles): + """ This checks if mother/father is deleted, specifically when newly + added before data is saved """ + for hndl in handles: + if self.obj.father_handle == hndl: + self.obj.father_handle = None + if self.obj.mother_handle == hndl: + self.obj.mother_handle = None + self.load_data() + def check_for_family_change(self, handles): """ Callback for family-update signal diff --git a/gramps/gui/editors/editperson.py b/gramps/gui/editors/editperson.py index 90f052f54..596bacd61 100644 --- a/gramps/gui/editors/editperson.py +++ b/gramps/gui/editors/editperson.py @@ -274,9 +274,7 @@ class EditPerson(EditPrimary): self._add_db_signal('family-delete', self.family_change) self._add_db_signal('family-update', self.family_change) self._add_db_signal('family-add', self.family_change) - self._add_db_signal('event-update', self.event_updated) self._add_db_signal('event-rebuild', self.event_updated) - self._add_db_signal('event-delete', self.event_updated) def family_change(self, handle_list=[]): """