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
This commit is contained in:
Tim G L Lyons 2013-09-16 21:39:47 +00:00
parent f31a74d271
commit 42f6070d8c
7 changed files with 193 additions and 22 deletions

View File

@ -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
]

View File

@ -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 <Id>')
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

View File

@ -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 <text>')
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

View File

@ -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:
@ -148,6 +178,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)
generic_filter.add_rule(rule)

View File

@ -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

View File

@ -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):

View File

@ -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"))