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 ._hasnoteregexp import HasNoteRegexp
from ._hasreferencecountof import HasReferenceCountOf from ._hasreferencecountof import HasReferenceCountOf
from ._hassource import HasSource from ._hassource import HasSource
from ._hassourceidof import HasSourceIdOf
from ._matchesfilter import MatchesFilter from ._matchesfilter import MatchesFilter
from ._matchespagesubstringof import MatchesPageSubstringOf from ._matchespagesubstringof import MatchesPageSubstringOf
from ._matchesrepositoryfilter import MatchesRepositoryFilter from ._matchesrepositoryfilter import MatchesRepositoryFilter
from ._matchessourcefilter import MatchesSourceFilter from ._matchessourcefilter import MatchesSourceFilter
from ._regexpidof import RegExpIdOf from ._regexpidof import RegExpIdOf
from ._regexpsourceidof import RegExpSourceIdOf
from ._hastag import HasTag from ._hastag import HasTag
editor_rule_list = [ editor_rule_list = [
@ -55,10 +57,12 @@ editor_rule_list = [
HasNoteRegexp, HasNoteRegexp,
HasReferenceCountOf, HasReferenceCountOf,
HasSource, HasSource,
HasSourceIdOf,
MatchesFilter, MatchesFilter,
MatchesPageSubstringOf, MatchesPageSubstringOf,
MatchesRepositoryFilter, MatchesRepositoryFilter,
MatchesSourceFilter, MatchesSourceFilter,
RegExpIdOf, RegExpIdOf,
RegExpSourceIdOf,
HasTag 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 # GRAMPS modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from ...widgets import MonitoredMenu, DateEntry from ...widgets import MonitoredMenu, DateEntry, BasicEntry
from gramps.gen.lib import Citation from gramps.gen.lib import Citation
from .. import build_filter_model from .. import build_filter_model
from . import SidebarFilter from . import SidebarFilter
from gramps.gen.constfunc import cuni from gramps.gen.constfunc import cuni
from gramps.gen.filters import GenericFilterFactory, rules from gramps.gen.filters import GenericFilterFactory, rules
from gramps.gen.filters.rules.citation import (RegExpIdOf, HasCitation, HasTag, from gramps.gen.filters.rules.citation import (RegExpIdOf, HasCitation, HasTag,
HasNoteRegexp, MatchesFilter) HasNoteRegexp, MatchesFilter,
HasSource, RegExpSourceIdOf)
from gramps.gen.utils.string import confidence from gramps.gen.utils.string import confidence
GenericCitationFilter = GenericFilterFactory('Citation') GenericCitationFilter = GenericFilterFactory('Citation')
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -60,6 +61,12 @@ class CitationSidebarFilter(SidebarFilter):
def __init__(self, dbstate, uistate, clicked): def __init__(self, dbstate, uistate, clicked):
self.clicked_func = 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_id = Gtk.Entry()
self.filter_page = Gtk.Entry() self.filter_page = Gtk.Entry()
self.filter_date = DateEntry(uistate, []) self.filter_date = DateEntry(uistate, [])
@ -100,16 +107,28 @@ class CitationSidebarFilter(SidebarFilter):
self.tag.pack_start(cell, True) self.tag.pack_start(cell, True)
self.tag.add_attribute(cell, 'text', 0) self.tag.add_attribute(cell, 'text', 0)
self.add_text_entry(_('ID'), self.filter_id) self.add_text_entry(_('Source: ID'), self.filter_src_id)
self.add_text_entry(_('Volume/Page'), self.filter_page) self.add_text_entry(_('Source: Title'), self.filter_src_title)
self.add_text_entry(_('Date'), self.filter_date) self.add_text_entry(_('Source: Author'), self.filter_src_author)
self.add_entry(_('Minimum Confidence|Min. Conf.'), self.filter_conf) self.add_text_entry(_('Source: Abbreviation'), self.filter_src_abbr)
self.add_text_entry(_('Note'), self.filter_note) 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_entry(_('Tag'), self.tag)
self.add_filter_entry(_('Custom filter'), self.generic) self.add_filter_entry(_('Custom filter'), self.generic)
self.add_entry(None, self.filter_regex) self.add_entry(None, self.filter_regex)
def clear(self, obj): 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_id.set_text('')
self.filter_page.set_text('') self.filter_page.set_text('')
self.filter_date.set_text('') self.filter_date.set_text('')
@ -119,6 +138,15 @@ class CitationSidebarFilter(SidebarFilter):
self.generic.set_active(0) self.generic.set_active(0)
def get_filter(self): 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() gid = cuni(self.filter_id.get_text()).strip()
page = cuni(self.filter_page.get_text()).strip() page = cuni(self.filter_page.get_text()).strip()
date = cuni(self.filter_date.get_text()).strip() date = cuni(self.filter_date.get_text()).strip()
@ -136,7 +164,9 @@ class CitationSidebarFilter(SidebarFilter):
tag = self.tag.get_active() > 0 tag = self.tag.get_active() > 0
gen = self.generic.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: if empty:
generic_filter = None generic_filter = None
else: else:
@ -147,6 +177,14 @@ class CitationSidebarFilter(SidebarFilter):
rule = HasCitation([page, date, conf], use_regex=regex) rule = HasCitation([page, date, conf], use_regex=regex)
generic_filter.add_rule(rule) 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: if note:
rule = HasNoteRegexp([note], use_regex=regex) rule = HasNoteRegexp([note], use_regex=regex)

View File

@ -189,14 +189,20 @@ class CitationTreeModel(CitationBaseModel, TreeBaseModel):
""" """
sort_key = self.sort_func2(data) sort_key = self.sort_func2(data)
# If the source for this citation already exists (in the tree model) we # 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 # add the citation as a child of the source. Otherwise we add the source
# found the citation) we add the citation as a child of nothing. # first (because citations don't have any meaning without the associated
# source)
if self._get_node(data[5]): if self._get_node(data[5]):
# parent child sortkey handle # parent child sortkey handle
self.add_node(data[5], handle, sort_key, handle, secondary=True) self.add_node(data[5], handle, sort_key, handle, secondary=True)
else: else:
# parent child sortkey handle # add the source node first
self.add_node(None, handle, sort_key, handle, secondary=True) 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): def on_get_n_columns(self):
return len(self.fmap)+1 return len(self.fmap)+1

View File

@ -578,15 +578,20 @@ class TreeBaseModel(GObject.GObject, Gtk.TreeModel):
self.__total = 0 self.__total = 0
self.__displayed = 0 self.__displayed = 0
items = self.number_items() if not self.has_secondary:
_LOG.debug("rebuild filter primary") # The tree only has primary data
self.__rebuild_filter(dfilter, skip, items, items = self.number_items()
self.gen_cursor, self.map, self.add_row) _LOG.debug("rebuild filter primary")
if self.has_secondary: self.__rebuild_filter(dfilter, skip, items,
items = self.number_items2() self.gen_cursor, self.map, self.add_row)
_LOG.debug("rebuild filter secondary") else:
self.__rebuild_filter(dfilter2, skip, items, # The tree has both primary and secondary data. The navigation type
self.gen_cursor2, self.map2, self.add_row2) # (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, def __rebuild_filter(self, dfilter, skip, items, gen_cursor, data_map,
add_func): add_func):

View File

@ -581,7 +581,7 @@ class CitationTreeView(ListView):
""" """
Define the default gramplets for the sidebar and bottombar. Define the default gramplets for the sidebar and bottombar.
""" """
return (("Source Filter",), return (("Citation Filter",),
("Citation Gallery", ("Citation Gallery",
"Citation Notes", "Citation Notes",
"Citation Backlinks")) "Citation Backlinks"))