From c474e5e6386c4bc55b21d906aa1e3d9c0c795232 Mon Sep 17 00:00:00 2001 From: Tim G L Lyons Date: Sat, 3 Sep 2011 22:19:15 +0000 Subject: [PATCH] * change CitationtreeModel so that building the view starts from sources so that it displays sources that have no citations consequent restructuring: * introduce separate CitationBaseModel module which encapsulates access to both citation and source fields for the views * introduce separate CitationListModel and CitationTreeModel modules * move configuration data from libcitationview to citationtreeview and citationlistview, because the two different views have different data svn: r18110 --- src/gui/views/treemodels/Makefile.am | 4 +- src/gui/views/treemodels/__init__.py | 4 +- src/gui/views/treemodels/citationbasemodel.py | 214 +++++++++++ src/gui/views/treemodels/citationlistmodel.py | 109 ++++++ src/gui/views/treemodels/citationmodel.py | 355 ------------------ src/gui/views/treemodels/citationtreemodel.py | 201 ++++++++++ src/plugins/gramplet/PopulateGramplet.py | 28 +- src/plugins/lib/libcitationview.py | 51 +-- src/plugins/view/citationlistview.py | 50 ++- src/plugins/view/citationtreeview.py | 45 ++- 10 files changed, 638 insertions(+), 423 deletions(-) create mode 100644 src/gui/views/treemodels/citationbasemodel.py create mode 100644 src/gui/views/treemodels/citationlistmodel.py delete mode 100644 src/gui/views/treemodels/citationmodel.py create mode 100644 src/gui/views/treemodels/citationtreemodel.py diff --git a/src/gui/views/treemodels/Makefile.am b/src/gui/views/treemodels/Makefile.am index 0dc601d5c..413d96b35 100644 --- a/src/gui/views/treemodels/Makefile.am +++ b/src/gui/views/treemodels/Makefile.am @@ -16,7 +16,9 @@ pkgdata_PYTHON = \ placemodel.py \ repomodel.py \ sourcemodel.py \ - citationmodel.py \ + citationbasemodel.py \ + citationlistmodel.py \ + citationtreemodel.py \ treebasemodel.py pkgpyexecdir = @pkgpyexecdir@/gui/views/treemodels diff --git a/src/gui/views/treemodels/__init__.py b/src/gui/views/treemodels/__init__.py index 967c69cda..4094f6076 100644 --- a/src/gui/views/treemodels/__init__.py +++ b/src/gui/views/treemodels/__init__.py @@ -32,4 +32,6 @@ from placemodel import PlaceBaseModel, PlaceListModel, PlaceTreeModel from mediamodel import MediaModel from repomodel import RepositoryModel from notemodel import NoteModel -from citationmodel import CitationBaseModel, CitationListModel, CitationTreeModel +from citationbasemodel import CitationBaseModel +from citationlistmodel import CitationListModel +from citationtreemodel import CitationTreeModel diff --git a/src/gui/views/treemodels/citationbasemodel.py b/src/gui/views/treemodels/citationbasemodel.py new file mode 100644 index 000000000..18071f3c6 --- /dev/null +++ b/src/gui/views/treemodels/citationbasemodel.py @@ -0,0 +1,214 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2006 Donald N. Allingham +# Copyright (C) 2011 Tim G L Lyons, Nick Hall +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# $Id$ + +""" +CitationBaseModel classes for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# python modules +# +#------------------------------------------------------------------------- +import cgi +import logging +log = logging.getLogger(".") +LOG = logging.getLogger(".citation") + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +import const +import ToolTips +import DateHandler +import gen.lib +from Utils import confidence, format_time +import config + +#------------------------------------------------------------------------- +# +# COLUMN constants +# +#------------------------------------------------------------------------- +# These are the column numbers in the serialize/unserialize interfaces in +# the Citation object +COLUMN_HANDLE = 0 +COLUMN_ID = 1 +COLUMN_DATE = 2 +COLUMN_PAGE = 3 +COLUMN_CONFIDENCE = 4 +COLUMN_SOURCE = 5 +COLUMN_CHANGE = 9 + +# Data for the Source object +COLUMN2_HANDLE = 0 +COLUMN2_ID = 1 +COLUMN2_TITLE = 2 +COLUMN2_AUTHOR = 3 +COLUMN2_PUBINFO = 4 +COLUMN2_ABBREV = 7 +COLUMN2_CHANGE = 8 + +INVALID_DATE_FORMAT = config.get('preferences.invalid-date-format') + +#------------------------------------------------------------------------- +# +# CitationModel +# +#------------------------------------------------------------------------- +class CitationBaseModel(object): + +# Fields access when 'data' is a Citation + + def citation_date(self, data): + if data[COLUMN_DATE]: + citation = gen.lib.Citation() + citation.unserialize(data) + date_str = DateHandler.get_date(citation) + if date_str != "": + retval = cgi.escape(date_str) + if not DateHandler.get_date_valid(citation): + return INVALID_DATE_FORMAT % retval + else: + return retval + return u'' + + def citation_id(self, data): + return unicode(data[COLUMN_ID]) + + def citation_page(self, data): + return unicode(data[COLUMN_PAGE]) + + def citation_confidence(self, data): + return unicode(confidence[data[COLUMN_CONFIDENCE]]) + + def citation_handle(self, data): + return unicode(data[COLUMN_HANDLE]) + + def citation_change(self, data): + return format_time(data[COLUMN_CHANGE]) + + def citation_sort_change(self, data): + return "%012x" % data[COLUMN_CHANGE] + + def citation_src_title(self, data): + source_handle = data[COLUMN_SOURCE] + try: + source = self.db.get_source_from_handle(source_handle) + return unicode(source.get_title()) + except: + return u'' + + def citation_src_id(self, data): + source_handle = data[COLUMN_SOURCE] + try: + source = self.db.get_source_from_handle(source_handle) + return unicode(source.gramps_id) + except: + return u'' + + def citation_src_auth(self, data): + source_handle = data[COLUMN_SOURCE] + try: + source = self.db.get_source_from_handle(source_handle) + return unicode(source.get_author()) + except: + return u'' + + def citation_src_abbr(self, data): + source_handle = data[COLUMN_SOURCE] + try: + source = self.db.get_source_from_handle(source_handle) + return unicode(source.get_abbreviation()) + except: + return u'' + + def citation_src_pinfo(self, data): + source_handle = data[COLUMN_SOURCE] + try: + source = self.db.get_source_from_handle(source_handle) + return unicode(source.get_publication_info()) + except: + return u'' + + def citation_src_chan(self, data): + source_handle = data[COLUMN_SOURCE] + try: + source = self.db.get_source_from_handle(source_handle) + return format_time(source.change) + except: + return u'' + + def citation_tooltip(self, data): + if const.USE_TIPS: + try: + t = ToolTips.TipFromFunction(self.db, lambda: + self.db.get_citation_from_handle(data[0])) + except: + log.error("Failed to create tooltip.", exc_info=True) + return t + else: + return u'' + +# Fields access when 'data' is a Source + + def source_handle(self, data): + return unicode(data[COLUMN2_HANDLE]) + + def source_src_title(self, data): + return unicode(data[COLUMN2_TITLE]) + + def source_src_id(self, data): + return unicode(data[COLUMN2_ID]) + + def source_src_auth(self, data): + return unicode(data[COLUMN2_AUTHOR]) + + def source_src_abbr(self, data): + return unicode(data[COLUMN2_ABBREV]) + + def source_src_pinfo(self, data): + return unicode(data[COLUMN2_PUBINFO]) + + def source_src_chan(self, data): + return format_time(data[COLUMN2_CHANGE]) + + def source_sort2_change(self, data): + return "%012x" % data[COLUMN2_CHANGE] + + def source_tooltip(self, data): + if const.USE_TIPS: + try: + t = ToolTips.TipFromFunction(self.db, lambda: + self.db.get_source_from_handle(data[0])) + except: + log.error("Failed to create tooltip.", exc_info=True) + return t + else: + return u'' + + def dummy_sort_key(self, data): + # dummy sort key for columns that don't have data + return None + \ No newline at end of file diff --git a/src/gui/views/treemodels/citationlistmodel.py b/src/gui/views/treemodels/citationlistmodel.py new file mode 100644 index 000000000..dc68403de --- /dev/null +++ b/src/gui/views/treemodels/citationlistmodel.py @@ -0,0 +1,109 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2006 Donald N. Allingham +# Copyright (C) 2011 Tim G L Lyons, Nick Hall +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# $Id$ + +""" +CitationBaseModel, CitationListModel and CitationTreeModel classes for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# python modules +# +#------------------------------------------------------------------------- +import logging +log = logging.getLogger(".") +LOG = logging.getLogger(".citation") + +#------------------------------------------------------------------------- +# +# GNOME/GTK modules +# +#------------------------------------------------------------------------- +import gtk + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from gui.views.treemodels.flatbasemodel import FlatBaseModel +from gui.views.treemodels.citationbasemodel import CitationBaseModel + +#------------------------------------------------------------------------- +# +# CitationListModel +# +#------------------------------------------------------------------------- +class CitationListModel(CitationBaseModel, FlatBaseModel): + """ + Flat citation model. (Original code in CitationBaseModel). + """ + def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None, + skip=set(), sort_map=None): + self.map = db.get_raw_citation_data + self.gen_cursor = db.get_citation_cursor + self.fmap = [ + self.citation_page, + self.citation_id, + self.citation_date, + self.citation_confidence, + self.citation_change, + self.citation_src_title, + self.citation_src_id, + self.citation_src_auth, + self.citation_src_abbr, + self.citation_src_pinfo, + self.citation_src_chan, + self.citation_handle, + self.citation_tooltip + ] + self.smap = [ + self.citation_page, + self.citation_id, + self.citation_date, + self.citation_confidence, + self.citation_sort_change, + self.citation_src_title, + self.citation_src_id, + self.citation_src_auth, + self.citation_src_abbr, + self.citation_src_pinfo, + self.citation_src_chan, + self.citation_handle, + self.citation_tooltip + ] + FlatBaseModel.__init__(self, db, scol, order, tooltip_column=12, + search=search, skip=skip, sort_map=sort_map) + + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.smap = None + FlatBaseModel.destroy(self) + + def on_get_n_columns(self): + return len(self.fmap)+1 diff --git a/src/gui/views/treemodels/citationmodel.py b/src/gui/views/treemodels/citationmodel.py deleted file mode 100644 index a19f21e85..000000000 --- a/src/gui/views/treemodels/citationmodel.py +++ /dev/null @@ -1,355 +0,0 @@ -# -# Gramps - a GTK+/GNOME based genealogy program -# -# Copyright (C) 2000-2006 Donald N. Allingham -# Copyright (C) 2011 Tim G L Lyons, Nick Hall -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# $Id$ - -""" -CitationBaseModel, CitationListModel and CitationTreeModel classes for GRAMPS. -""" - -#------------------------------------------------------------------------- -# -# python modules -# -#------------------------------------------------------------------------- -import cgi -import logging -log = logging.getLogger(".") -LOG = logging.getLogger(".citation") - -#------------------------------------------------------------------------- -# -# internationalization -# -#------------------------------------------------------------------------- -from gen.ggettext import gettext as _ - -#------------------------------------------------------------------------- -# -# GNOME/GTK modules -# -#------------------------------------------------------------------------- -import gtk - -#------------------------------------------------------------------------- -# -# GRAMPS modules -# -#------------------------------------------------------------------------- -import const -import ToolTips -import DateHandler -import gen.lib -from Utils import confidence, format_time -import config -from gui.views.treemodels.flatbasemodel import FlatBaseModel -from gui.views.treemodels.treebasemodel import TreeBaseModel - -#------------------------------------------------------------------------- -# -# COLUMN constants -# -#------------------------------------------------------------------------- -# These are the column numbers in the serialize/unserialize interfaces in -# the Citation object -COLUMN_HANDLE = 0 -COLUMN_ID = 1 -COLUMN_DATE = 2 -COLUMN_PAGE = 3 -COLUMN_CONFIDENCE = 4 -COLUMN_SOURCE = 5 -COLUMN_CHANGE = 9 - -COLUMN2_HANDLE = 0 -COLUMN2_ID = 1 -COLUMN2_TITLE = 2 - -INVALID_DATE_FORMAT = config.get('preferences.invalid-date-format') - -#------------------------------------------------------------------------- -# -# CitationModel -# -#------------------------------------------------------------------------- -class CitationBaseModel(object): - - def __init__(self, db): - self.map = db.get_raw_citation_data - self.gen_cursor = db.get_citation_cursor - self.fmap = [ - self.column_page, - self.column_id, - self.column_date, - self.column_confidence, - self.column_change, - self.column_src_title, - self.column_src_id, - self.column_src_auth, - self.column_src_abbr, - self.column_src_pinfo, - self.column_src_chan, - self.column_handle, - self.column_tooltip - ] - self.smap = [ - self.column_page, - self.column_id, - self.column_date, - self.column_confidence, - self.sort_change, - self.column_src_title, - self.column_src_id, - self.column_src_auth, - self.column_src_abbr, - self.column_src_pinfo, - self.column_src_chan, - self.column_handle, - self.column_tooltip - ] - - def destroy(self): - """ - Unset all elements that can prevent garbage collection - """ - self.db = None - self.gen_cursor = None - self.map = None - self.fmap = None - self.smap = None - FlatBaseModel.destroy(self) - - def on_get_n_columns(self): - return len(self.fmap)+1 - - def column_date(self, data): - if data[COLUMN_DATE]: - citation = gen.lib.Citation() - citation.unserialize(data) - date_str = DateHandler.get_date(citation) - if date_str != "": - retval = cgi.escape(date_str) - if not DateHandler.get_date_valid(citation): - return INVALID_DATE_FORMAT % retval - else: - return retval - return u'' - - def column_id(self, data): - return unicode(data[COLUMN_ID]) - - def column_page(self, data): - return unicode(data[COLUMN_PAGE]) - - def column_confidence(self, data): - return unicode(confidence[data[COLUMN_CONFIDENCE]]) - - def column_handle(self, data): - return unicode(data[COLUMN_HANDLE]) - - def column_change(self, data): - return format_time(data[COLUMN_CHANGE]) - - def sort_change(self, data): - return "%012x" % data[COLUMN_CHANGE] - - def column_src_title(self, data): - source_handle = data[COLUMN_SOURCE] - try: - source = self.db.get_source_from_handle(source_handle) - return unicode(source.get_title()) - except: - return u'' - - def column_src_id(self, data): - source_handle = data[COLUMN_SOURCE] - try: - source = self.db.get_source_from_handle(source_handle) - return unicode(source.gramps_id) - except: - return u'' - - def column_src_auth(self, data): - source_handle = data[COLUMN_SOURCE] - try: - source = self.db.get_source_from_handle(source_handle) - return unicode(source.get_author()) - except: - return u'' - - def column_src_abbr(self, data): - source_handle = data[COLUMN_SOURCE] - try: - source = self.db.get_source_from_handle(source_handle) - return unicode(source.get_abbreviation()) - except: - return u'' - - def column_src_pinfo(self, data): - source_handle = data[COLUMN_SOURCE] - try: - source = self.db.get_source_from_handle(source_handle) - return unicode(source.get_publication_info()) - except: - return u'' - - def column_src_chan(self, data): - source_handle = data[COLUMN_SOURCE] - try: - source = self.db.get_source_from_handle(source_handle) - return format_time(source.change) - except: - return u'' - - def column_tooltip(self, data): - if const.USE_TIPS: - try: - t = ToolTips.TipFromFunction(self.db, lambda: - self.db.get_citation_from_handle(data[0])) - except: - log.error("Failed to create tooltip.", exc_info=True) - return t - else: - return u'' - -#------------------------------------------------------------------------- -# -# CitationListModel -# -#------------------------------------------------------------------------- -class CitationListModel(CitationBaseModel, FlatBaseModel): - """ - Flat citation model. (Original code in CitationBaseModel). - """ - def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None, - skip=set(), sort_map=None): - - CitationBaseModel.__init__(self, db) - FlatBaseModel.__init__(self, db, scol, order, tooltip_column=12, - search=search, skip=skip, sort_map=sort_map) - - def destroy(self): - """ - Unset all elements that can prevent garbage collection - """ - CitationBaseModel.destroy(self) - FlatBaseModel.destroy(self) - -#------------------------------------------------------------------------- -# -# CitationTreeModel -# -#------------------------------------------------------------------------- -class CitationTreeModel(CitationBaseModel, TreeBaseModel): - """ - Hierarchical citation model. - """ - def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None, - skip=set(), sort_map=None): - - CitationBaseModel.__init__(self, db) - TreeBaseModel.__init__(self, db, scol=scol, order=order, - tooltip_column=12, - search=search, skip=skip, sort_map=sort_map, - nrgroups = 1, - group_can_have_handle = True) - - def destroy(self): - """ - Unset all elements that can prevent garbage collection - """ - self.db = None - self.gen_cursor = None - self.map = None - self.fmap = None - self.map2 = None - self.fmap2 = None - self.smap = None -# Can't call FlatBaseModel.destroy(self), because it fails when a treemodel -# is passed, so can't just do: -# CitationBaseModel.destroy(self) - self.number_items = None - TreeBaseModel.destroy(self) - - def _set_base_data(self): - """See TreeBaseModel, for place, most have been set in init of - CitationBaseModel - """ - self.number_items = self.db.get_number_of_citations - self.map2 = self.db.get_raw_source_data - self.fmap2 = [ - self.column2_src_title, - self.column2_src_id, - None, - None, - None, - None, - None, - None, - None, - None, - None, - self.column2_handle, - None - ] - - def get_tree_levels(self): - """ - Return the headings of the levels in the hierarchy. - """ - return [_('Source'), _('Citation')] - - def add_row(self, handle, data): - """ - Add nodes to the node map for a single citation. - - handle The handle of the gramps object. - data The object data. - """ - source_handle = data[COLUMN_SOURCE] - source = self.db.get_source_from_handle(source_handle) - if source is not None: - source_name = source.get_title() - sort_key = self.sort_func(data) - # add as node: parent, child, sortkey, handle; parent and child are - # nodes in the treebasemodel, and will be used as iters - if self.get_node(source_handle) is None: - self.add_node(None, source_handle, source_name, source_handle, - secondary=True) - self.add_node(source_handle, handle, sort_key, handle) - else: - log.warn("Citation %s does not have a source" % - unicode(data[COLUMN_PAGE]), - exc_info=True) - - def column2_handle(self, data): - return unicode(data[COLUMN2_HANDLE]) - - def column2_src_title(self, data): - return unicode(data[COLUMN2_TITLE]) - - def column2_src_id(self, data): - return unicode(data[COLUMN2_ID]) - - def column_header(self, node): - """ - Return a column heading. This is called for nodes with no associated - Gramps handle. - """ - return node.name diff --git a/src/gui/views/treemodels/citationtreemodel.py b/src/gui/views/treemodels/citationtreemodel.py new file mode 100644 index 000000000..047f7cb4b --- /dev/null +++ b/src/gui/views/treemodels/citationtreemodel.py @@ -0,0 +1,201 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2006 Donald N. Allingham +# Copyright (C) 2011 Tim G L Lyons, Nick Hall +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# $Id$ + +""" +CitationTreeModel classes for GRAMPS. +""" + +#------------------------------------------------------------------------- +# +# python modules +# +#------------------------------------------------------------------------- +import logging +log = logging.getLogger(".") +LOG = logging.getLogger(".citation") + +#------------------------------------------------------------------------- +# +# internationalization +# +#------------------------------------------------------------------------- +from gen.ggettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GNOME/GTK modules +# +#------------------------------------------------------------------------- +import gtk + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Utils import get_source_referents +from gui.views.treemodels.treebasemodel import TreeBaseModel +from gui.views.treemodels.citationbasemodel import CitationBaseModel + +#------------------------------------------------------------------------- +# +# CitationModel +# +#------------------------------------------------------------------------- +class CitationTreeModel(CitationBaseModel, TreeBaseModel): + """ + Hierarchical citation model. + """ + def __init__(self, db, scol=0, order=gtk.SORT_ASCENDING, search=None, + skip=set(), sort_map=None): + self.db = db + self.map = self.db.get_raw_source_data + self.gen_cursor = self.db.get_source_cursor + # The items here must correspond, in order, with data in + # CitationTreeView, and with the items in the secondary fmap, fmap2 + self.fmap = [ + self.source_src_title, # COL_TITLE_PAGE (both Source & Citation) + self.source_src_id, # COL_ID (both Source & Citation) + None, # COL_DATE (not for Source) + None, # COL_CONFIDENCE (not for Source) + self.source_src_chan, # COL_CHAN (both Source & Citation) + self.source_src_auth, # COL_SRC_AUTH (Source only) + self.source_src_abbr, # COL_SRC_ABBR (Source only) + self.source_src_pinfo, # COL_SRC_PINFO (Source only) + self.source_handle, + self.source_tooltip + ] + self.smap = [ + self.source_src_title, + self.source_src_id, + self.dummy_sort_key, + self.dummy_sort_key, + self.source_sort2_change, + self.source_src_auth, + self.source_src_abbr, + self.source_src_pinfo, + self.source_handle, + self.source_tooltip + ] + + TreeBaseModel.__init__(self, self.db, scol=scol, order=order, + tooltip_column=9, + search=search, skip=skip, sort_map=sort_map, + nrgroups = 1, + group_can_have_handle = True) + + def destroy(self): + """ + Unset all elements that can prevent garbage collection + """ + self.db = None + self.gen_cursor = None + self.map = None + self.fmap = None + self.map2 = None + self.fmap2 = None + self.smap = None + self.number_items = None + TreeBaseModel.destroy(self) + + def _set_base_data(self): + """See TreeBaseModel, for citations, most have been set in init of + CitationBaseModel + """ + self.number_items = self.db.get_number_of_citations + self.map2 = self.db.get_raw_citation_data + self.fmap2 = [ + self.citation_page, + self.citation_id, + self.citation_date, + self.citation_confidence, + self.citation_change, + None, + None, + None, + self.citation_handle, + self.citation_tooltip + ] + + def get_tree_levels(self): + """ + Return the headings of the levels in the hierarchy. + """ + return [_('Source'), _('Citation')] + + def add_row(self, handle, data): + """ + Add nodes to the node map for a single citation. + + handle The handle of the gramps object. + data The object data. + """ + # first add the source +# source_name = self.source_src_title(data) + sort_key = self.sort_func(data) + # add as node: parent, child, sortkey, handle; parent and child are + # nodes in the treebasemodel, and will be used as iters + if self.get_node(handle) is None: + self.add_node(None, handle, sort_key, handle) + # now add all the related citations + source_handle_list = [] + for i in get_source_referents(handle, self.db): + for j in i: + source_handle_list.append(j) + for citation_handle in source_handle_list: +# # add as node: parent, child, sortkey, handle; parent and child are +# # nodes in the treebasemodel, and will be used as iters + citation = self.db.get_citation_from_handle(citation_handle) + citation_page = citation.get_page() + self.add_node(handle, citation_handle, citation_page, + citation_handle, secondary=True) + + + +# try: +# source_handle = data[COLUMN_SOURCE] +# except: +# LOG.debug("add_row: data %s is empty, handle %s citation %s data %s" % +# (data, handle, self.db.get_citation_from_handle(handle), +# self.db.get_citation_from_handle(handle).serialize())) +# source = self.db.get_source_from_handle(source_handle) +# if source is not None: +# source_name = source.get_title() +# sort_key = self.sort_func(data) +# if self.get_node(source_handle) is None: +# self.add_node(None, source_handle, source_name, source_handle, +# secondary=True) +# self.add_node(source_handle, handle, sort_key, handle) +# else: +# log.warn("Citation %s does not have a source" % +# unicode(data[COLUMN_PAGE]), +# exc_info=True) + + def on_get_n_columns(self): + return len(self.fmap)+1 + + def column_header(self, node): + """ + Return a column heading. This is called for nodes with no associated + Gramps handle. + """ + return node.name diff --git a/src/plugins/gramplet/PopulateGramplet.py b/src/plugins/gramplet/PopulateGramplet.py index ca6635f46..cca7c2ce1 100644 --- a/src/plugins/gramplet/PopulateGramplet.py +++ b/src/plugins/gramplet/PopulateGramplet.py @@ -111,18 +111,20 @@ class PopulateGramplet(Gramplet): citation = gen.lib.Citation() db = self.gui.dbstate.db - for i in range(num_sources): - source.gramps_id = None - source.handle = None - source.title = "Source %04d" % i - with DbTxn('savesource', db) as trans: - db.add_source(source, trans) - - for j in range(num_citations): - citation.gramps_id = None - citation.handle = None - citation.ref = source.handle - citation.page = "Page %04d" % j - with DbTxn('savecitation', db) as trans: + db.disable_signals() + with DbTxn('Populate citations', db) as trans: + for i in range(num_sources): + source.gramps_id = None + source.handle = None + source.title = "Source %04d" % (i + 1) + source_handle = db.add_source(source, trans) + + for j in range(num_citations): + citation.gramps_id = None + citation.handle = None + citation.source_handle = source_handle + citation.page = "Page %04d" % (j + 1) db.add_citation(citation, trans) + LOG.debug("sources and citations added") + db.enable_signals() diff --git a/src/plugins/lib/libcitationview.py b/src/plugins/lib/libcitationview.py index 6e17a7dd3..ca658aeb5 100644 --- a/src/plugins/lib/libcitationview.py +++ b/src/plugins/lib/libcitationview.py @@ -54,7 +54,6 @@ from QuestionDialog import ErrorDialog from gui.editors import EditCitation, DeleteCitationQuery, EditSource, \ DeleteSrcQuery from Filters.SideBar import SourceSidebarFilter -from gen.plug import CATEGORY_QR_SOURCE #------------------------------------------------------------------------- # @@ -71,52 +70,8 @@ from gen.ggettext import gettext as _ class BaseCitationView(ListView): """ citation listview class """ - # The data items here have to correspond, in order, to the items in - # src/giu.views/treemodels/citationmodel.py - COL_TITLE_PAGE = 0 - COL_ID = 1 - COL_DATE = 2 - COL_CONFIDENCE = 3 - COL_CHAN = 4 - COL_SRC_TITLE = 5 - COL_SRC_ID = 6 - COL_SRC_AUTH = 7 - COL_SRC_ABBR = 8 - COL_SRC_PINFO = 9 - COL_SRC_CHAN = 10 - # name of the columns - COLUMN_NAMES = [ - _('Title/Page'), - _('ID'), - _('Date'), - _('Confidence'), - _('Last Changed'), - _('Source: Title'), - _('Source: ID'), - _('Source: Author'), - _('Source: Abbreviation'), - _('Source: Publication Information'), - _('Source: Last Changed'), - ] - # default setting with visible columns, order of the col, and their size - CONFIGSETTINGS = ( - ('columns.visible', [COL_TITLE_PAGE, COL_ID, COL_DATE, - COL_CONFIDENCE]), - ('columns.rank', [COL_TITLE_PAGE, COL_ID, COL_DATE, COL_CONFIDENCE, - COL_CHAN, COL_SRC_TITLE, COL_SRC_ID, COL_SRC_AUTH, - COL_SRC_ABBR, COL_SRC_PINFO, COL_SRC_CHAN]), - ('columns.size', [200, 75, 100, 100, 100, 200, 75, 75, 100, 150, 100]) - ) - ADD_MSG = _("Add a new citation and a new source") - ADD_SOURCE_MSG = _("Add a new source") - ADD_CITATION_MSG = _("Add a new citation to an existing source") - # Edit delete and merge messages are overridden for the tree view as - # they can apply to sources or citations - EDIT_MSG = _("Edit the selected citation") - DEL_MSG = _("Delete the selected citation") - MERGE_MSG = _("Merge the selected citations") - FILTER_TYPE = "Citation" - QR_CATEGORY = CATEGORY_QR_SOURCE + # The configuration parameters have been moved to CitationTreeView and + # CitationListView, because they differ for the two different views. def __init__(self, pdata, dbstate, uistate, title, model, nav_group=0): @@ -133,7 +88,7 @@ class BaseCitationView(ListView): ListView.__init__( self, title, pdata, dbstate, uistate, - BaseCitationView.COLUMN_NAMES, len(BaseCitationView.COLUMN_NAMES), + self.COLUMN_NAMES, len(self.COLUMN_NAMES), model, signal_map, dbstate.db.get_citation_bookmarks(), Bookmarks.CitationBookmarks, nav_group, diff --git a/src/plugins/view/citationlistview.py b/src/plugins/view/citationlistview.py index d1c1f7843..ff0ea4bc4 100644 --- a/src/plugins/view/citationlistview.py +++ b/src/plugins/view/citationlistview.py @@ -31,7 +31,8 @@ Citation List View # #------------------------------------------------------------------------- from libcitationview import BaseCitationView -from gui.views.treemodels.citationmodel import CitationListModel +from gui.views.treemodels.citationlistmodel import CitationListModel +from gen.plug import CATEGORY_QR_SOURCE #------------------------------------------------------------------------- # @@ -50,6 +51,53 @@ class CitationListView(BaseCitationView): """ A list view of citations. """ + # The data items here have to correspond, in order, to the items in + # src/giu.views/treemodels/citationlistmodel.py + COL_TITLE_PAGE = 0 + COL_ID = 1 + COL_DATE = 2 + COL_CONFIDENCE = 3 + COL_CHAN = 4 + COL_SRC_TITLE = 5 + COL_SRC_ID = 6 + COL_SRC_AUTH = 7 + COL_SRC_ABBR = 8 + COL_SRC_PINFO = 9 + COL_SRC_CHAN = 10 + # name of the columns + COLUMN_NAMES = [ + _('Title/Page'), + _('ID'), + _('Date'), + _('Confidence'), + _('Last Changed'), + _('Source: Title'), + _('Source: ID'), + _('Source: Author'), + _('Source: Abbreviation'), + _('Source: Publication Information'), + _('Source: Last Changed'), + ] + # default setting with visible columns, order of the col, and their size + CONFIGSETTINGS = ( + ('columns.visible', [COL_TITLE_PAGE, COL_ID, COL_DATE, + COL_CONFIDENCE]), + ('columns.rank', [COL_TITLE_PAGE, COL_ID, COL_DATE, COL_CONFIDENCE, + COL_CHAN, COL_SRC_TITLE, COL_SRC_ID, COL_SRC_AUTH, + COL_SRC_ABBR, COL_SRC_PINFO, COL_SRC_CHAN]), + ('columns.size', [200, 75, 100, 100, 100, 200, 75, 75, 100, 150, 100]) + ) + ADD_MSG = _("Add a new citation and a new source") + ADD_SOURCE_MSG = _("Add a new source") + ADD_CITATION_MSG = _("Add a new citation to an existing source") + # Edit delete and merge messages are overridden for the tree view as + # they can apply to sources or citations + EDIT_MSG = _("Edit the selected citation") + DEL_MSG = _("Delete the selected citation") + MERGE_MSG = _("Merge the selected citations") + FILTER_TYPE = "Citation" + QR_CATEGORY = CATEGORY_QR_SOURCE + def __init__(self, pdata, dbstate, uistate, nav_group=0): BaseCitationView.__init__(self, pdata, dbstate, uistate, _('Citation View'), CitationListModel, diff --git a/src/plugins/view/citationtreeview.py b/src/plugins/view/citationtreeview.py index 1b9b656a9..1cf89ef94 100644 --- a/src/plugins/view/citationtreeview.py +++ b/src/plugins/view/citationtreeview.py @@ -38,7 +38,8 @@ LOG = logging.getLogger(".citation") #------------------------------------------------------------------------- from gui.views.listview import LISTTREE from libcitationview import BaseCitationView -from gui.views.treemodels.citationmodel import CitationTreeModel +from gui.views.treemodels.citationtreemodel import CitationTreeModel +from gen.plug import CATEGORY_QR_SOURCE #------------------------------------------------------------------------- # @@ -56,6 +57,45 @@ class CitationTreeView(BaseCitationView): """ A hierarchical view of the top three levels of places. """ + # The data items here have to correspond, in order, to the items in + # src/giu.views/treemodels/citationtreemodel.py + COL_TITLE_PAGE = 0 + COL_ID = 1 + COL_DATE = 2 + COL_CONFIDENCE = 3 + COL_CHAN = 4 + COL_SRC_AUTH = 5 + COL_SRC_ABBR = 6 + COL_SRC_PINFO = 7 + # name of the columns + COLUMN_NAMES = [ + _('Title/Page'), + _('ID'), + _('Date'), + _('Confidence'), + _('Last Changed'), + _('Source: Author'), + _('Source: Abbreviation'), + _('Source: Publication Information'), + ] + # default setting with visible columns, order of the col, and their size + CONFIGSETTINGS = ( + ('columns.visible', [COL_TITLE_PAGE, COL_ID, COL_DATE, + COL_CONFIDENCE]), + ('columns.rank', [COL_TITLE_PAGE, COL_ID, COL_DATE, COL_CONFIDENCE, + COL_CHAN, COL_SRC_AUTH, + COL_SRC_ABBR, COL_SRC_PINFO]), + ('columns.size', [200, 75, 100, 100, 100, 75, 100, 150]) + ) + ADD_MSG = _("Add a new citation and a new source") + ADD_SOURCE_MSG = _("Add a new source") + ADD_CITATION_MSG = _("Add a new citation to an existing source") + EDIT_MSG = _("Edit the selected citation or source") + DEL_MSG = _("Delete the selected citation or source") + MERGE_MSG = _("Merge the selected citations or selected sources") + FILTER_TYPE = "Citation" + QR_CATEGORY = CATEGORY_QR_SOURCE + def __init__(self, pdata, dbstate, uistate, nav_group=0): BaseCitationView.__init__(self, pdata, dbstate, uistate, @@ -78,9 +118,6 @@ class CitationTreeView(BaseCitationView): """ Define actions for the popup menu specific to the tree view. """ - self.EDIT_MSG = _("Edit the selected citation or source") - self.DEL_MSG = _("Delete the selected citation or source") - self.MERGE_MSG = _("Merge the selected citations or selected sources") BaseCitationView.define_actions(self) self.all_action.add_actions([