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
This commit is contained in:
Tim G L Lyons 2013-09-16 21:38:16 +00:00
parent 4b76d67c07
commit abb7efcb01
7 changed files with 188 additions and 23 deletions

View File

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

@ -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
editor_rule_list = [ editor_rule_list = [
HasCitation, HasCitation,
@ -54,9 +56,11 @@ editor_rule_list = [
HasNoteRegexp, HasNoteRegexp,
HasReferenceCountOf, HasReferenceCountOf,
HasSource, HasSource,
HasSourceIdOf,
MatchesFilter, MatchesFilter,
MatchesPageSubstringOf, MatchesPageSubstringOf,
MatchesRepositoryFilter, MatchesRepositoryFilter,
MatchesSourceFilter, MatchesSourceFilter,
RegExpIdOf RegExpIdOf,
RegExpSourceIdOf
] ]

View File

@ -40,12 +40,12 @@ import gtk
# GRAMPS modules # GRAMPS modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gui.widgets import MonitoredMenu, DateEntry from gui.widgets import MonitoredMenu, DateEntry, BasicEntry
import gen.lib import gen.lib
from Filters.SideBar import SidebarFilter from Filters.SideBar import SidebarFilter
from Filters import GenericFilterFactory, build_filter_model, Rules from Filters import GenericFilterFactory, build_filter_model, Rules
from Filters.Rules.Citation import (RegExpIdOf, HasCitation, HasNoteRegexp, from Filters.Rules.Citation import (RegExpIdOf, HasCitation, HasNoteRegexp,
MatchesFilter) MatchesFilter, HasSource, RegExpSourceIdOf)
from Utils import confidence from Utils import confidence
GenericCitationFilter = GenericFilterFactory('Citation') GenericCitationFilter = GenericFilterFactory('Citation')
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -57,6 +57,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, [])
@ -90,15 +96,27 @@ class CitationSidebarFilter(SidebarFilter):
self.filter_conf.pack_start(cell, True) self.filter_conf.pack_start(cell, True)
self.filter_conf.add_attribute(cell, 'text', 0) self.filter_conf.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_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('')
@ -107,6 +125,12 @@ 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() gid = unicode(self.filter_id.get_text()).strip()
page = unicode(self.filter_page.get_text()).strip() page = unicode(self.filter_page.get_text()).strip()
date = unicode(self.filter_date.get_text()).strip() date = unicode(self.filter_date.get_text()).strip()
@ -123,7 +147,9 @@ class CitationSidebarFilter(SidebarFilter):
regex = self.filter_regex.get_active() regex = self.filter_regex.get_active()
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 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:
@ -134,6 +160,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

@ -179,14 +179,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

@ -570,15 +570,20 @@ class TreeBaseModel(gtk.GenericTreeModel):
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"))