From 42f6070d8c2bee93f2a0eee868ca993975b3628e Mon Sep 17 00:00:00 2001 From: Tim G L Lyons Date: Mon, 16 Sep 2013 21:39:47 +0000 Subject: [PATCH] Fix citation filters so they no longer try to filter citations with a sources filter. Citation filter now allows specification of both source and citation data. When a citation is shown in a search or a filtered citation tree view, the corresponding source is also shown. svn: r23143 --- gramps/gen/filters/rules/citation/__init__.py | 4 ++ .../filters/rules/citation/_hassourceidof.py | 58 ++++++++++++++++++ .../rules/citation/_regexpsourceidof.py | 60 +++++++++++++++++++ .../filters/sidebar/_citationsidebarfilter.py | 54 ++++++++++++++--- .../gui/views/treemodels/citationtreemodel.py | 14 +++-- gramps/gui/views/treemodels/treebasemodel.py | 23 ++++--- gramps/plugins/view/citationtreeview.py | 2 +- 7 files changed, 193 insertions(+), 22 deletions(-) create mode 100644 gramps/gen/filters/rules/citation/_hassourceidof.py create mode 100644 gramps/gen/filters/rules/citation/_regexpsourceidof.py diff --git a/gramps/gen/filters/rules/citation/__init__.py b/gramps/gen/filters/rules/citation/__init__.py index 67c523c12..692874d3e 100644 --- a/gramps/gen/filters/rules/citation/__init__.py +++ b/gramps/gen/filters/rules/citation/__init__.py @@ -37,11 +37,13 @@ from ._hasnotematchingsubstringof import HasNoteMatchingSubstringOf from ._hasnoteregexp import HasNoteRegexp from ._hasreferencecountof import HasReferenceCountOf from ._hassource import HasSource +from ._hassourceidof import HasSourceIdOf from ._matchesfilter import MatchesFilter from ._matchespagesubstringof import MatchesPageSubstringOf from ._matchesrepositoryfilter import MatchesRepositoryFilter from ._matchessourcefilter import MatchesSourceFilter from ._regexpidof import RegExpIdOf +from ._regexpsourceidof import RegExpSourceIdOf from ._hastag import HasTag editor_rule_list = [ @@ -55,10 +57,12 @@ editor_rule_list = [ HasNoteRegexp, HasReferenceCountOf, HasSource, + HasSourceIdOf, MatchesFilter, MatchesPageSubstringOf, MatchesRepositoryFilter, MatchesSourceFilter, RegExpIdOf, + RegExpSourceIdOf, HasTag ] diff --git a/gramps/gen/filters/rules/citation/_hassourceidof.py b/gramps/gen/filters/rules/citation/_hassourceidof.py new file mode 100644 index 000000000..f6ff7236f --- /dev/null +++ b/gramps/gen/filters/rules/citation/_hassourceidof.py @@ -0,0 +1,58 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2002-2006 Donald N. Allingham +# Copyright (C) 2011-2013 Tim G L Lyons +# +# 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$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from ....const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from .._hasgrampsid import HasGrampsId + +#------------------------------------------------------------------------- +# +# HasSourceIdOf +# +#------------------------------------------------------------------------- +class HasSourceIdOf(HasGrampsId): + """Rule that checks for a citation with a source which has a specific + GRAMPS ID""" + + name = _('Citation with Source ') + description = _("Matches a citation with a source with a specified Gramps " + "ID") + category = _('Source filters') + + def apply(self, dbase, citation): + source = dbase.get_source_from_handle( + citation.get_reference_handle()) + if HasGrampsId.apply(self, dbase, source): + return True + return False diff --git a/gramps/gen/filters/rules/citation/_regexpsourceidof.py b/gramps/gen/filters/rules/citation/_regexpsourceidof.py new file mode 100644 index 000000000..b4c972a37 --- /dev/null +++ b/gramps/gen/filters/rules/citation/_regexpsourceidof.py @@ -0,0 +1,60 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2002-2006 Donald N. Allingham +# Copyright (C) 2011 Tim G L Lyons +# +# 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$ + +#------------------------------------------------------------------------- +# +# Standard Python modules +# +#------------------------------------------------------------------------- +from ....const import GRAMPS_LOCALE as glocale +_ = glocale.translation.gettext + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from .._regexpidbase import RegExpIdBase + +#------------------------------------------------------------------------- +# +# HasIdOf +# +#------------------------------------------------------------------------- +class RegExpSourceIdOf(RegExpIdBase): + """ + Rule that checks for a citation whose GRAMPS ID + matches regular expression. + """ + + name = _('Citations with Source Id containing ') + description = _("Matches citations whose source has a Gramps ID that " + "matches the regular expression") + category = _('Source filters') + + def apply(self, dbase, citation): + source = dbase.get_source_from_handle( + citation.get_reference_handle()) + if RegExpIdBase.apply(self, dbase, source): + return True + return False diff --git a/gramps/gui/filters/sidebar/_citationsidebarfilter.py b/gramps/gui/filters/sidebar/_citationsidebarfilter.py index cd7cea680..5cc8352bd 100644 --- a/gramps/gui/filters/sidebar/_citationsidebarfilter.py +++ b/gramps/gui/filters/sidebar/_citationsidebarfilter.py @@ -41,14 +41,15 @@ from gi.repository import Gtk # GRAMPS modules # #------------------------------------------------------------------------- -from ...widgets import MonitoredMenu, DateEntry +from ...widgets import MonitoredMenu, DateEntry, BasicEntry from gramps.gen.lib import Citation from .. import build_filter_model from . import SidebarFilter from gramps.gen.constfunc import cuni from gramps.gen.filters import GenericFilterFactory, rules from gramps.gen.filters.rules.citation import (RegExpIdOf, HasCitation, HasTag, - HasNoteRegexp, MatchesFilter) + HasNoteRegexp, MatchesFilter, + HasSource, RegExpSourceIdOf) from gramps.gen.utils.string import confidence GenericCitationFilter = GenericFilterFactory('Citation') #------------------------------------------------------------------------- @@ -60,6 +61,12 @@ class CitationSidebarFilter(SidebarFilter): def __init__(self, dbstate, uistate, clicked): self.clicked_func = clicked + self.filter_src_id = BasicEntry() + self.filter_src_title = BasicEntry() + self.filter_src_author = BasicEntry() + self.filter_src_abbr = BasicEntry() + self.filter_src_pub = BasicEntry() + self.filter_src_note = BasicEntry() self.filter_id = Gtk.Entry() self.filter_page = Gtk.Entry() self.filter_date = DateEntry(uistate, []) @@ -100,16 +107,28 @@ class CitationSidebarFilter(SidebarFilter): self.tag.pack_start(cell, True) self.tag.add_attribute(cell, 'text', 0) - self.add_text_entry(_('ID'), self.filter_id) - self.add_text_entry(_('Volume/Page'), self.filter_page) - self.add_text_entry(_('Date'), self.filter_date) - self.add_entry(_('Minimum Confidence|Min. Conf.'), self.filter_conf) - self.add_text_entry(_('Note'), self.filter_note) + self.add_text_entry(_('Source: ID'), self.filter_src_id) + self.add_text_entry(_('Source: Title'), self.filter_src_title) + self.add_text_entry(_('Source: Author'), self.filter_src_author) + self.add_text_entry(_('Source: Abbreviation'), self.filter_src_abbr) + self.add_text_entry(_('Source: Publication'), self.filter_src_pub) + self.add_text_entry(_('Source: Note'), self.filter_src_note) + self.add_text_entry(_('Citation: ID'), self.filter_id) + self.add_text_entry(_('Citation: Volume/Page'), self.filter_page) + self.add_text_entry(_('Citation: Date'), self.filter_date) + self.add_entry(_('Citation: Minimum Confidence|Min. Conf.'), self.filter_conf) + self.add_text_entry(_('Citation: Note'), self.filter_note) self.add_entry(_('Tag'), self.tag) self.add_filter_entry(_('Custom filter'), self.generic) self.add_entry(None, self.filter_regex) def clear(self, obj): + self.filter_src_id.set_text('') + self.filter_src_title.set_text('') + self.filter_src_author.set_text('') + self.filter_src_abbr.set_text('') + self.filter_src_pub.set_text('') + self.filter_src_note.set_text('') self.filter_id.set_text('') self.filter_page.set_text('') self.filter_date.set_text('') @@ -119,6 +138,15 @@ class CitationSidebarFilter(SidebarFilter): self.generic.set_active(0) def get_filter(self): + src_id = unicode(self.filter_src_id.get_text()).strip() + src_title = unicode(self.filter_src_title.get_text()).strip() + src_author = unicode(self.filter_src_author.get_text()).strip() + src_abbr = unicode(self.filter_src_abbr.get_text()).strip() + src_pub = unicode(self.filter_src_pub.get_text()).strip() + src_note = unicode(self.filter_src_note.get_text()).strip() + gid = unicode(self.filter_id.get_text()).strip() + page = unicode(self.filter_page.get_text()).strip() + date = unicode(self.filter_date.get_text()).strip() gid = cuni(self.filter_id.get_text()).strip() page = cuni(self.filter_page.get_text()).strip() date = cuni(self.filter_date.get_text()).strip() @@ -136,7 +164,9 @@ class CitationSidebarFilter(SidebarFilter): tag = self.tag.get_active() > 0 gen = self.generic.get_active() > 0 - empty = not (gid or page or date or conf or note or regex or tag or gen) + empty = not (src_id or src_title or src_author or src_abbr or src_pub or + src_note or + gid or page or date or conf or note or regex or gen) if empty: generic_filter = None else: @@ -147,6 +177,14 @@ class CitationSidebarFilter(SidebarFilter): rule = HasCitation([page, date, conf], use_regex=regex) generic_filter.add_rule(rule) + + if src_id: + rule = RegExpSourceIdOf([src_id], use_regex=regex) + generic_filter.add_rule(rule) + + rule = HasSource([src_title, src_author, src_abbr, src_pub], + use_regex=regex) + generic_filter.add_rule(rule) if note: rule = HasNoteRegexp([note], use_regex=regex) diff --git a/gramps/gui/views/treemodels/citationtreemodel.py b/gramps/gui/views/treemodels/citationtreemodel.py index e6f9d7fae..2446a9465 100644 --- a/gramps/gui/views/treemodels/citationtreemodel.py +++ b/gramps/gui/views/treemodels/citationtreemodel.py @@ -189,14 +189,20 @@ class CitationTreeModel(CitationBaseModel, TreeBaseModel): """ sort_key = self.sort_func2(data) # If the source for this citation already exists (in the tree model) we - # add the citation as a child of the source. Otherwise (if a search has - # found the citation) we add the citation as a child of nothing. + # add the citation as a child of the source. Otherwise we add the source + # first (because citations don't have any meaning without the associated + # source) if self._get_node(data[5]): # parent child sortkey handle self.add_node(data[5], handle, sort_key, handle, secondary=True) else: - # parent child sortkey handle - self.add_node(None, handle, sort_key, handle, secondary=True) + # add the source node first + source_sort_key = self.sort_func(self.map(data[5])) + # parent child sortkey handle + self.add_node(None, data[5], source_sort_key, data[5]) + + # parent child sortkey handle + self.add_node(data[5], handle, sort_key, handle, secondary=True) def on_get_n_columns(self): return len(self.fmap)+1 diff --git a/gramps/gui/views/treemodels/treebasemodel.py b/gramps/gui/views/treemodels/treebasemodel.py index 5739f4f1d..9e06616a9 100644 --- a/gramps/gui/views/treemodels/treebasemodel.py +++ b/gramps/gui/views/treemodels/treebasemodel.py @@ -578,15 +578,20 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel): self.__total = 0 self.__displayed = 0 - items = self.number_items() - _LOG.debug("rebuild filter primary") - self.__rebuild_filter(dfilter, skip, items, - self.gen_cursor, self.map, self.add_row) - if self.has_secondary: - items = self.number_items2() - _LOG.debug("rebuild filter secondary") - self.__rebuild_filter(dfilter2, skip, items, - self.gen_cursor2, self.map2, self.add_row2) + if not self.has_secondary: + # The tree only has primary data + items = self.number_items() + _LOG.debug("rebuild filter primary") + self.__rebuild_filter(dfilter, skip, items, + self.gen_cursor, self.map, self.add_row) + else: + # The tree has both primary and secondary data. The navigation type + # (navtype) which governs the filters that are offered, is for the + # secondary data. + items = self.number_items2() + _LOG.debug("rebuild filter secondary") + self.__rebuild_filter(dfilter2, skip, items, + self.gen_cursor2, self.map2, self.add_row2) def __rebuild_filter(self, dfilter, skip, items, gen_cursor, data_map, add_func): diff --git a/gramps/plugins/view/citationtreeview.py b/gramps/plugins/view/citationtreeview.py index 2a005f3c3..f09ac8736 100644 --- a/gramps/plugins/view/citationtreeview.py +++ b/gramps/plugins/view/citationtreeview.py @@ -581,7 +581,7 @@ class CitationTreeView(ListView): """ Define the default gramplets for the sidebar and bottombar. """ - return (("Source Filter",), + return (("Citation Filter",), ("Citation Gallery", "Citation Notes", "Citation Backlinks"))