From 67dcffee2040d1c4dba03b88dd2a2709cc1288ae Mon Sep 17 00:00:00 2001 From: Paul Culley Date: Mon, 30 Apr 2018 18:09:49 -0500 Subject: [PATCH] Fix Person/Family/Event view updates on various associated changes (#603) * Fix Person/Family/Event view updates on various associated changes Fixes #10532 * Fix Event view for changes in Main Participants * Fix Person/Event/Place views for update to a Place or enclosing place --- gramps/gui/views/listview.py | 28 +++++++++++++++++++++++++ gramps/plugins/lib/libpersonview.py | 9 ++++---- gramps/plugins/view/eventview.py | 32 +++++++++++++++++++++++++++++ gramps/plugins/view/familyview.py | 3 ++- 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/gramps/gui/views/listview.py b/gramps/gui/views/listview.py index 106fe4030..84255bdb6 100644 --- a/gramps/gui/views/listview.py +++ b/gramps/gui/views/listview.py @@ -33,6 +33,7 @@ from abc import abstractmethod import pickle import time import logging +from collections import deque LOG = logging.getLogger('.gui.listview') @@ -817,6 +818,33 @@ class ListView(NavigationView): self.change_active(handle) break + def related_update(self, hndl_list): + """ Find handles pointing to the view from a related object update; + for example if an event update occurs, find person handles referenced + by that event. Use the created list to perfom row_updates. + Places need a bit more work, as they could be enclosing other places. + In addition, for People view the birth/death place name could change. + So we recursively check places and events until we find our class + object handle to use for updating rows. + """ + nav_type = self.navigation_type() + upd_list = [] + done = set() + queue = deque(hndl_list) + while queue: + hndl = queue.pop() + if hndl in done: # make sure we aren't in infinite loop + continue # in case places can enclose each other + done.add(hndl) + for cl_name, handle in self.dbstate.db.find_backlink_handles(hndl): + if cl_name == nav_type: + upd_list.append(handle) + if (cl_name == 'Place' or cl_name == 'Event' and + nav_type == 'Person'): + queue.append(handle) + if upd_list: + self.row_update(upd_list) + def _button_press(self, obj, event): """ Called when a mouse is clicked. diff --git a/gramps/plugins/lib/libpersonview.py b/gramps/plugins/lib/libpersonview.py index a36c8d66d..58579f90a 100644 --- a/gramps/plugins/lib/libpersonview.py +++ b/gramps/plugins/lib/libpersonview.py @@ -139,11 +139,10 @@ class BasePersonView(ListView): 'person-rebuild' : self.object_build, 'person-groupname-rebuild' : self.object_build, 'no-database': self.no_database, - 'family-update' : self.object_build, - 'family-add' : self.object_build, - 'family-delete' : self.object_build, - 'event-update' : self.object_build, - 'place-update' : self.object_build, + 'family-update' : self.related_update, + 'family-add' : self.related_update, + 'event-update' : self.related_update, + 'place-update' : self.related_update, } ListView.__init__( diff --git a/gramps/plugins/view/eventview.py b/gramps/plugins/view/eventview.py index 16dd5e895..29ab33204 100644 --- a/gramps/plugins/view/eventview.py +++ b/gramps/plugins/view/eventview.py @@ -113,6 +113,13 @@ class EventView(ListView): 'event-update' : self.row_update, 'event-delete' : self.row_delete, 'event-rebuild' : self.object_build, + 'person-update' : self.person_update, + 'person-add' : self.person_update, + 'person-delete' : self.object_build, # TODO slow way to do this + 'family-update' : self.family_update, + 'family-add' : self.family_update, + 'family-delete' : self.object_build, # TODO slow way to do this + 'place-update' : self.related_update, } ListView.__init__( @@ -133,6 +140,31 @@ class EventView(ListView): self.additional_uis.append(self.additional_ui()) + def person_update(self, hndl_list): + """ Deal with person updates thay may effect the Main Participants + column. These cannot use the more generic mechanism because Person + objects use EventRef to point to events, rather than Events pointing + to persons. Example: A person's name change or add event to person""" + update_list = [] + for hndl in hndl_list: + person = self.dbstate.db.get_person_from_handle(hndl) + for eventref in person.get_event_ref_list(): + update_list.append(eventref.ref) + self.row_update(update_list) + + def family_update(self, hndl_list): + """ Deal with family updates thay may effect the Main Participants + column. These cannot use the more generic mechanism because Family + objects use EventRef to point to events, rather than Events pointing + to Families. Example: Change/add/removal of parent, or add family to + event""" + update_list = [] + for hndl in hndl_list: + family = self.dbstate.db.get_family_from_handle(hndl) + for eventref in family.get_event_ref_list(): + update_list.append(eventref.ref) + self.row_update(update_list) + def navigation_type(self): return 'Event' diff --git a/gramps/plugins/view/familyview.py b/gramps/plugins/view/familyview.py index 5ebee6075..3c3f71730 100644 --- a/gramps/plugins/view/familyview.py +++ b/gramps/plugins/view/familyview.py @@ -108,7 +108,8 @@ class FamilyView(ListView): 'family-update' : self.row_update, 'family-delete' : self.row_delete, 'family-rebuild' : self.object_build, - 'event-update' : self.object_build, + 'event-update' : self.related_update, + 'person-update' : self.related_update, } ListView.__init__(