* src/EditPlace.py: changed display_references to use find_backlink_handles

* src/EditRepository.py: modified to use  find_backlink_handles and fixed subtle bug
	* src/RelLib/_Source.py: added reporef_list to referent object lists so that backref
	are put in reference_map
	* test/GrampsDb/GrampsDbBase_Test.py: added unittest for source/reference backlinks
	* test/GrampsDb/GrampsDbTestBase.py: added unittest for source/reference backlinks


svn: r5616
This commit is contained in:
Richard Taylor 2005-12-22 12:02:06 +00:00
parent 55f22b5550
commit b2b6cb0ad5
6 changed files with 148 additions and 9 deletions

View File

@ -1,3 +1,11 @@
2005-12-22 Richard Taylor <rjt-gramps@thegrindstone.me.uk>
* src/EditPlace.py: changed display_references to use find_backlink_handles
* src/EditRepository.py: modified to use find_backlink_handles and fixed subtle bug
* src/RelLib/_Source.py: added reporef_list to referent object lists so that backref
are put in reference_map
* test/GrampsDb/GrampsDbBase_Test.py: added unittest for source/reference backlinks
* test/GrampsDb/GrampsDbTestBase.py: added unittest for source/reference backlinks
2005-12-21 Don Allingham <don@gramps-project.org> 2005-12-21 Don Allingham <don@gramps-project.org>
* src/DisplayState.py: remove print statements * src/DisplayState.py: remove print statements
* src/ViewManger.py: Fix const.app_* * src/ViewManger.py: Fix const.app_*

View File

@ -28,6 +28,9 @@
import cPickle as pickle import cPickle as pickle
import gc import gc
from gettext import gettext as _ from gettext import gettext as _
import sys
log = sys.stderr.write
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -75,6 +78,7 @@ class EditPlace(DisplayState.ManagedWindow):
self.db = dbstate.db self.db = dbstate.db
self.path = dbstate.db.get_save_path() self.path = dbstate.db.get_save_path()
self.not_loaded = True self.not_loaded = True
self.model = None # becomes the model for back references.
self.lists_changed = 0 self.lists_changed = 0
if place: if place:
self.srcreflist = place.get_source_references() self.srcreflist = place.get_source_references()
@ -165,8 +169,9 @@ class EditPlace(DisplayState.ManagedWindow):
self.country.set_text(mloc.get_country()) self.country.set_text(mloc.get_country())
self.longitude.set_text(place.get_longitude()) self.longitude.set_text(place.get_longitude())
self.latitude.set_text(place.get_latitude()) self.latitude.set_text(place.get_latitude())
self.plist = self.top_window.get_widget("plist") self.plist = self.top_window.get_widget("refinfo")
self.slist = self.top_window.get_widget("slist") self.slist = self.top_window.get_widget("slist")
self.sources_label = self.top_window.get_widget("sourcesPlaceEdit") self.sources_label = self.top_window.get_widget("sourcesPlaceEdit")
self.names_label = self.top_window.get_widget("namesPlaceEdit") self.names_label = self.top_window.get_widget("namesPlaceEdit")
self.notes_label = self.top_window.get_widget("notesPlaceEdit") self.notes_label = self.top_window.get_widget("notesPlaceEdit")
@ -524,6 +529,104 @@ class EditPlace(DisplayState.ManagedWindow):
self,", ", event, None, 0, None, None, self.db.readonly) self,", ", event, None, 0, None, None, self.db.readonly)
def display_references(self): def display_references(self):
if not self.model:
self.any_refs = False
place_handle = self.place.get_handle()
titles = [(_('Type'),0,150),(_('Name'),1,150),
(_('ID'),2,75),(_('Event Name'),3,150)]
self.model = ListModel.ListModel(self.plist,
titles,
event_func=self.button_press)
self.backlink_generator = self.db.find_backlink_handles(place_handle)
while True: # The loop is broken when the backlink_generator finishes
try:
reference = self.backlink_generator.next()
except StopIteration:
# Last reference reached.
break
cls_name,handle = reference
if cls_name == 'Person':
person = self.db.get_person_from_handle(handle)
for event_handle in [person.get_birth_handle(),
person.get_death_handle()] \
+ person.get_event_list():
event = self.db.get_event_from_handle(event_handle)
if event and event.get_place_handle() == place_handle:
pname = self.name_display(person)
gramps_id = person.get_gramps_id()
ename = event.get_name()
self.model.add(
[_("Personal Event"),pname,gramps_id,ename],
(0,event_handle))
self.any_refs = True
elif cls_name == 'Family':
family = self.db.get_family_from_handle(handle)
for event_handle in family.get_event_list():
event = self.db.get_event_from_handle(event_handle)
if event and event.get_place_handle() == place_handle:
father = family.get_father_handle()
mother = family.get_mother_handle()
if father and mother:
fname = _("%(father)s and %(mother)s") % {
"father" : self.name_display(
self.db.get_person_from_handle(father)),
"mother" : self.name_display(
self.db.get_person_from_handle(mother))
}
elif father:
fname = self.name_display(
self.db.get_person_from_handle(father))
else:
fname = self.name_display(
self.db.get_person_from_handle(mother))
gramps_id = family.get_gramps_id()
ename = event.get_name()
self.model.add(
[_("Family Event"),fname,gramps_id,ename],
(1,event_handle))
self.any_refs = True
elif cls_name == 'Event':
event = self.db.get_event_from_handle(handle)
ev_type = event.get_type()[1]
description = event.get_description()
gramps_id = event.get_gramps_id()
self.model.add([_("Event"),str(ev_type),gramps_id,description],(2,handle))
else:
# If we get here it means there is a new Primary object type
# that has been added to the database or that Place has started
# to be referenced by a different primary object. Print a warning
# to remind us that this code need updating.
log("WARNING: Unhandled Primary object type returned from "
"find_backlink_handles(): %s \n" % str(cls_name))
if gtk.events_pending():
return True
if self.any_refs:
Utils.bold_label(self.refs_label,self.top)
else:
Utils.unbold_label(self.refs_label,self.top)
self.ref_not_loaded = 0
self.backlink_generator = None
return False
place_handle = self.place.get_handle() place_handle = self.place.get_handle()
# Initialize things if we're entering this functioin # Initialize things if we're entering this functioin
# for the first time # for the first time

View File

@ -76,10 +76,10 @@ class ReposSrcListModel(gtk.ListStore):
# Get the list of sources that reference this repository # Get the list of sources that reference this repository
repos_handle = self._repos.get_handle() repos_handle = self._repos.get_handle()
source_list = [ src_handle for src_handle \
in self._db.get_source_handles() \
if self._db.get_source_from_handle(src_handle).has_repo_reference(repos_handle)]
# find_backlink_handles returns a list of (class_name,handle) tuples
# so src[1] is just the handle of the source.
source_list = [ src[1] for src in self._db.find_backlink_handles(repos_handle,['Source']) ]
# Add each (source,repos_ref) to list. It is possible for # Add each (source,repos_ref) to list. It is possible for
# a source to reference to same repository more than once. # a source to reference to same repository more than once.
@ -116,7 +116,7 @@ class ReposSrcListModel(gtk.ListStore):
found = False found = False
for val in range(0,len(self)): for val in range(0,len(self)):
iter = self.get_iter(val) iter = self.get_iter(val)
if source.get_handle() == self.get_value(iter,0).get_handle and \ if source.get_handle() == self.get_value(iter,0).get_handle() and \
repos_ref == self.get_value(iter,1): repos_ref == self.get_value(iter,1):
self.row_changed(self.get_path(iter),iter) self.row_changed(self.get_path(iter),iter)
found = True found = True
@ -558,6 +558,7 @@ class EditRepository:
# These are the ones that are in the list model but not in the # These are the ones that are in the list model but not in the
# original sources list. # original sources list.
items_added = self.repos_source_model.get_added_items() items_added = self.repos_source_model.get_added_items()
for item in items_added: for item in items_added:
item[1].set_reference_handle(handle) item[1].set_reference_handle(handle)
@ -580,10 +581,11 @@ class EditRepository:
stripped_list = [ repos_ref for repos_ref \ stripped_list = [ repos_ref for repos_ref \
in original_list \ in original_list \
if repos_ref.get_reference_handle() != self.repository.get_handle() ] if repos_ref.get_reference_handle() != self.repository.get_handle() ]
# Now add back in those to be added and updated # Now add back in those to be added and updated
new_list = stripped_list + \ new_list = stripped_list + \
[ item[1] for item in items_added ] + \ [ item[1] for item in items_added if item[0] == source_hdl ] + \
[ item[1] for item in items_updated ] [ item[1] for item in items_updated if item[0] == source_hdl ]
# Set the new list on the source # Set the new list on the source

View File

@ -112,7 +112,7 @@ class Source(PrimaryObject,MediaBase,NoteBase):
@return: Returns the list of objects refereincing primary objects. @return: Returns the list of objects refereincing primary objects.
@rtype: list @rtype: list
""" """
return self.media_list return self.media_list + self.reporef_list
def has_source_reference(self,src_handle) : def has_source_reference(self,src_handle) :
""" """

View File

@ -89,6 +89,17 @@ class ReferenceMapTest (GrampsDbBaseTest):
assert len(references) == 1 assert len(references) == 1
assert references[0] == (RelLib.Person.__name__,person.get_handle()) assert references[0] == (RelLib.Person.__name__,person.get_handle())
def test_backlink_for_repository(self):
"""check that the source / repos backlink lookup works."""
repos = self._add_repository()
source = self._add_source(repos=repos)
references = [ ref for ref in self._db.find_backlink_handles(repos.get_handle()) ]
assert len(references) == 1
assert references[0] == (RelLib.Source.__name__,source.get_handle())
def test_class_limited_lookup(self): def test_class_limited_lookup(self):
"""check that class limited lookups work.""" """check that class limited lookups work."""

View File

@ -79,17 +79,32 @@ class GrampsDbBaseTest(unittest.TestCase):
return return
def _add_source(self): def _add_source(self,repos=None):
# Add a Source # Add a Source
tran = self._db.transaction_begin() tran = self._db.transaction_begin()
source = RelLib.Source() source = RelLib.Source()
if repos != None:
repo_ref = RelLib.RepoRef()
repo_ref.set_reference_handle(repos.get_handle())
source.add_repo_reference(repo_ref)
self._db.add_source(source,tran) self._db.add_source(source,tran)
self._db.commit_source(source,tran) self._db.commit_source(source,tran)
self._db.transaction_commit(tran, "Add Source") self._db.transaction_commit(tran, "Add Source")
return source return source
def _add_repository(self):
# Add a Repository
tran = self._db.transaction_begin()
repos = RelLib.Repository()
self._db.add_repository(repos,tran)
self._db.commit_repository(repos,tran)
self._db.transaction_commit(tran, "Add Repository")
return repos
def _add_object_with_source(self,sources,object_class,add_method,commit_method): def _add_object_with_source(self,sources,object_class,add_method,commit_method):