From abb7efcb01a792428316ca78af80d5312e16297e Mon Sep 17 00:00:00 2001 From: Tim G L Lyons Date: Mon, 16 Sep 2013 21:38:16 +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: r23141 --- src/Filters/Rules/Citation/_HasSourceIdOf.py | 57 ++++++++++++++++++ .../Rules/Citation/_RegExpSourceIdOf.py | 59 +++++++++++++++++++ src/Filters/Rules/Citation/__init__.py | 6 +- src/Filters/SideBar/_CitationSidebarFilter.py | 50 +++++++++++++--- src/gui/views/treemodels/citationtreemodel.py | 14 +++-- src/gui/views/treemodels/treebasemodel.py | 23 +++++--- src/plugins/view/citationtreeview.py | 2 +- 7 files changed, 188 insertions(+), 23 deletions(-) create mode 100644 src/Filters/Rules/Citation/_HasSourceIdOf.py create mode 100644 src/Filters/Rules/Citation/_RegExpSourceIdOf.py diff --git a/src/Filters/Rules/Citation/_HasSourceIdOf.py b/src/Filters/Rules/Citation/_HasSourceIdOf.py new file mode 100644 index 000000000..85a4c8aca --- /dev/null +++ b/src/Filters/Rules/Citation/_HasSourceIdOf.py @@ -0,0 +1,57 @@ +# +# 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 gen.ggettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Filters.Rules 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/src/Filters/Rules/Citation/_RegExpSourceIdOf.py b/src/Filters/Rules/Citation/_RegExpSourceIdOf.py new file mode 100644 index 000000000..d55817a03 --- /dev/null +++ b/src/Filters/Rules/Citation/_RegExpSourceIdOf.py @@ -0,0 +1,59 @@ +# +# 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 gen.ggettext import gettext as _ + +#------------------------------------------------------------------------- +# +# GRAMPS modules +# +#------------------------------------------------------------------------- +from Filters.Rules._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/src/Filters/Rules/Citation/__init__.py b/src/Filters/Rules/Citation/__init__.py index c8d8353ed..301178322 100644 --- a/src/Filters/Rules/Citation/__init__.py +++ b/src/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 editor_rule_list = [ HasCitation, @@ -54,9 +56,11 @@ editor_rule_list = [ HasNoteRegexp, HasReferenceCountOf, HasSource, + HasSourceIdOf, MatchesFilter, MatchesPageSubstringOf, MatchesRepositoryFilter, MatchesSourceFilter, - RegExpIdOf + RegExpIdOf, + RegExpSourceIdOf ] diff --git a/src/Filters/SideBar/_CitationSidebarFilter.py b/src/Filters/SideBar/_CitationSidebarFilter.py index 38ad752f8..bbfe431e9 100644 --- a/src/Filters/SideBar/_CitationSidebarFilter.py +++ b/src/Filters/SideBar/_CitationSidebarFilter.py @@ -40,12 +40,12 @@ import gtk # GRAMPS modules # #------------------------------------------------------------------------- -from gui.widgets import MonitoredMenu, DateEntry +from gui.widgets import MonitoredMenu, DateEntry, BasicEntry import gen.lib from Filters.SideBar import SidebarFilter from Filters import GenericFilterFactory, build_filter_model, Rules from Filters.Rules.Citation import (RegExpIdOf, HasCitation, HasNoteRegexp, - MatchesFilter) + MatchesFilter, HasSource, RegExpSourceIdOf) from Utils import confidence GenericCitationFilter = GenericFilterFactory('Citation') #------------------------------------------------------------------------- @@ -57,6 +57,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, []) @@ -90,15 +96,27 @@ class CitationSidebarFilter(SidebarFilter): self.filter_conf.pack_start(cell, True) self.filter_conf.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_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('') @@ -107,6 +125,12 @@ 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() @@ -123,7 +147,9 @@ class CitationSidebarFilter(SidebarFilter): regex = self.filter_regex.get_active() gen = self.generic.get_active() > 0 - empty = not (gid or page or date or conf or note or regex 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: @@ -134,6 +160,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/src/gui/views/treemodels/citationtreemodel.py b/src/gui/views/treemodels/citationtreemodel.py index 4b4087c03..73e1992a3 100644 --- a/src/gui/views/treemodels/citationtreemodel.py +++ b/src/gui/views/treemodels/citationtreemodel.py @@ -179,14 +179,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/src/gui/views/treemodels/treebasemodel.py b/src/gui/views/treemodels/treebasemodel.py index 715ef2c79..52bf34566 100644 --- a/src/gui/views/treemodels/treebasemodel.py +++ b/src/gui/views/treemodels/treebasemodel.py @@ -570,15 +570,20 @@ class TreeBaseModel(gtk.GenericTreeModel): 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/src/plugins/view/citationtreeview.py b/src/plugins/view/citationtreeview.py index 0ddd4b1e9..780391f5d 100644 --- a/src/plugins/view/citationtreeview.py +++ b/src/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"))