bug 8333; fix merge issue with Person Tree View

This commit is contained in:
prculley 2016-12-07 11:52:21 -06:00 committed by Nick Hall
parent 5ad32042c6
commit 2359633198
5 changed files with 67 additions and 15 deletions

View File

@ -57,7 +57,7 @@ from .navigationview import NavigationView
from ..actiongroup import ActionGroup
from ..columnorder import ColumnOrder
from gramps.gen.config import config
from gramps.gen.errors import WindowActiveError, FilterError
from gramps.gen.errors import WindowActiveError, FilterError, HandleError
from ..filters import SearchBar
from ..widgets.menuitem import add_menuitem
from gramps.gen.const import CUSTOM_FILTERS
@ -707,7 +707,13 @@ class ListView(NavigationView):
"""
selected_ids = self.selected_handles()
if len(selected_ids) > 0:
self.change_active(selected_ids[0])
# In certain cases the tree models do row updates which result in a
# selection changed signal to a handle in progress of being
# deleted. In these cases we don't want to change the active to
# non-existant handles.
if hasattr(self.model, "dont_change_active"):
if not self.model.dont_change_active:
self.change_active(selected_ids[0])
if len(selected_ids) == 1:
if self.drag_info():
@ -804,10 +810,15 @@ class ListView(NavigationView):
lookup_handle = self.dbstate.db.get_table_metadata(nav_type)['handle_func']
for handle in selected_ids:
# Still exist?
if lookup_handle(handle):
# should really use db.has_handle(nav_type, handle) but doesn't
# exist for bsddb
try:
lookup_handle(handle)
# Select it, and stop selecting:
self.change_active(handle)
break
except HandleError:
continue
self.change_active(handle)
break
def _button_press(self, obj, event):
"""

View File

@ -283,6 +283,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
cput = time.clock()
GObject.GObject.__init__(self)
BaseModel.__init__(self)
#We create a stamp to recognize invalid iterators. From the docs:
#Set the stamp to be equal to your model's stamp, to mark the
#iterator as valid. When your model's structure changes, you should
@ -300,6 +301,7 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
self.group_can_have_handle = group_can_have_handle
self.has_secondary = has_secondary
self.db = db
self.dont_change_active = False
self._set_base_data()
@ -796,18 +798,26 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel, BaseModel):
def update_row_by_handle(self, handle):
"""
Update a row in the model.
We have to do delete/add because sometimes row position changes when
object name changes.
A delete action causes the listview module to set a prior row to
active. In some cases (merge) the prior row may have been already
removed from the db. To avoid invalid handle exceptions in gramplets
at the change active, we tell listview not to change active.
The add_row below changes to current active again so we end up in right
place.
"""
assert isinstance(handle, str)
self.clear_cache(handle)
if self._get_node(handle) is None:
return # row not currently displayed
return # row not currently displayed
self.dont_change_active = True
self.delete_row_by_handle(handle)
self.dont_change_active = False
self.add_row_by_handle(handle)
# If the node hasn't moved, all we need is to call row_changed.
#self.row_changed(path, node)
def _new_iter(self, nodeid):
"""
Return a new iter containing the nodeid in the nodemap

View File

@ -139,6 +139,9 @@ 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,
}
ListView.__init__(

View File

@ -212,7 +212,12 @@ class CitationTreeView(ListView):
def _source_row_update(self, handle_list):
self._print_handles("source row update", handle_list)
self.row_update(handle_list)
# if the source update changes the title or other item being sorted
# then it may change position on tree; it's easier to just rebuild the
# whole tree. row_update cannot fix changes to first level of tree
#self.row_update(handle_list)
self.dirty = True
self.build_tree()
def _source_row_delete(self, handle_list):
self._print_handles("source row delete", handle_list)
@ -225,6 +230,25 @@ class CitationTreeView(ListView):
def navigation_type(self):
return 'Citation'
def object_build(self, *args):
"""
Called when the tree must be rebuilt and bookmarks redrawn.
"""
self.dirty = True
if self.active:
# Save the currently selected handles, if any:
selected_ids = self.selected_handles()
self.bookmarks.redraw()
self.build_tree()
# Reselect one, if it still exists after rebuild:
for handle in selected_ids:
# Still exist? It might be either a source or citation handle.
if (self.dbstate.db.has_citation_handle(handle) or
self.dbstate.db.has_source_handle(handle)):
# Select it, and stop selecting:
self.change_active(handle)
break
def drag_info(self):
# Since drag only needs to work when just one row is selected, ideally,
# this should just return SOURCE_LINK if one source is selected and

View File

@ -167,14 +167,17 @@ class PlaceTreeView(PlaceBaseView):
for handle in handle_list:
# Rebuild the model if the primary parent has changed.
if self._parent_changed(handle):
if self._significant_change(handle):
self.build_tree()
break
def _parent_changed(self, handle):
def _significant_change(self, handle):
"""
Return True if the primary parent is different from the parent
displayed in the tree, else return False.
displayed in the tree, or if there are children.
The first occurs if a change moves a child to a different parent,
the second if a change to a parent occurs (a rename might shift
position in the tree).
"""
new_handle = None
place = self.dbstate.db.get_place_from_handle(handle)
@ -183,10 +186,11 @@ class PlaceTreeView(PlaceBaseView):
new_handle = placeref_list[0].ref
old_handle = None
children = False
iter_ = self.model.get_iter_from_handle(handle)
if iter_:
parent_iter = self.model.iter_parent(iter_)
if parent_iter:
old_handle = self.model.get_handle_from_iter(parent_iter)
return True if new_handle != old_handle else False
children = self.model.get_node_from_iter(iter_).children
return new_handle != old_handle or children