* src/GenericFilter.py: Add a generic filter that can take a

parameter
* src/PeopleModel.py: Support for top level visibility
* src/gramps.glade: clean up filtering widgets
* src/gramps_main.py: build basic filters


svn: r3115
This commit is contained in:
Don Allingham 2004-04-30 03:01:51 +00:00
parent a13eb68a88
commit 5ed94ff9ee
6 changed files with 138 additions and 220 deletions

View File

@ -1,3 +1,10 @@
2004-04-29 Don Allingham <dallingham@users.sourceforge.net>
* src/GenericFilter.py: Add a generic filter that can take a
parameter
* src/PeopleModel.py: Support for top level visibility
* src/gramps.glade: clean up filtering widgets
* src/gramps_main.py: build basic filters
2004-04-27 Don Allingham <dallingham@users.sourceforge.net>
* src/DbPrompter.py: remove unused functions
* src/DisplayModels.py: filtering support

View File

@ -29,10 +29,7 @@ __author__ = "Don Allingham"
# Try to abstract SAX1 from SAX2
#
#-------------------------------------------------------------------------
try:
from xml.sax import make_parser,handler,SAXParseException
except:
from _xmlplus.sax import make_parser,handler,SAXParseException
from xml.sax import make_parser,handler,SAXParseException
#-------------------------------------------------------------------------
#
@ -40,8 +37,7 @@ except:
#
#-------------------------------------------------------------------------
import os
from string import find,join
import string
import gtk
#-------------------------------------------------------------------------
@ -85,6 +81,9 @@ class Rule:
labels = []
def __init__(self,list):
self.set_list(list)
def set_list(self,list):
assert type(list) == type([]) or list == None, "Argument is not a list"
self.list = list
@ -976,8 +975,8 @@ class HasEvent(Rule):
val = 1
if self.list[0] and event.get_name() != self.list[0]:
val = 0
if self.list[3] and find(event.get_description().upper(),
self.list[3].upper())==-1:
if self.list[3] and string.find(event.get_description().upper(),
self.list[3].upper())==-1:
val = 0
if self.date:
if date_cmp(self.date,event.get_date_object()):
@ -987,7 +986,7 @@ class HasEvent(Rule):
if pl_id:
pl = db.find_place_from_id(pl_id)
pn = pl.get_title()
if find(pn.upper(),self.list[2].upper()) == -1:
if string.find(pn.upper(),self.list[2].upper()) == -1:
val = 0
if val == 1:
return 1
@ -1033,7 +1032,7 @@ class HasFamilyEvent(Rule):
if self.list[0] and event.get_name() != self.list[0]:
val = 0
v = self.list[3]
if v and find(event.get_description().upper(),v.upper())==-1:
if v and string.find(event.get_description().upper(),v.upper())==-1:
val = 0
if self.date:
if date_cmp(self.date,event.get_date_object()):
@ -1042,7 +1041,7 @@ class HasFamilyEvent(Rule):
if pl_id:
pl = db.find_place_from_id(pl_id)
pn = pl.get_title()
if self.list[2] and find(pn,self.list[2].upper()) == -1:
if self.list[2] and string.find(pn,self.list[2].upper()) == -1:
val = 0
if val == 1:
return 1
@ -1140,7 +1139,7 @@ class HasBirth(Rule):
return 0
event = db.find_event_from_id(event_id)
ed = event.get_description().upper()
if len(self.list) > 2 and find(ed,self.list[2].upper())==-1:
if len(self.list) > 2 and string.find(ed,self.list[2].upper())==-1:
return 0
if self.date:
if date_cmp(self.date,event.get_date_object()) == 0:
@ -1149,7 +1148,7 @@ class HasBirth(Rule):
if pl_id:
pl = db.find_place_from_id(pl_id)
pn = pl.get_title()
if len(self.list) > 1 and find(pn,self.list[1].upper()) == -1:
if len(self.list) > 1 and string.find(pn,self.list[1].upper()) == -1:
return 0
return 1
@ -1187,7 +1186,7 @@ class HasDeath(Rule):
return 0
event = db.find_event_from_id(event_id)
ed = event.get_description().upper()
if self.list[2] and find(ed,self.list[2].upper())==-1:
if self.list[2] and string.find(ed,self.list[2].upper())==-1:
return 0
if self.date:
if date_cmp(self.date,event.get_date_object()) == 0:
@ -1196,7 +1195,7 @@ class HasDeath(Rule):
if pl_id:
pl = db.find_place_from_id(pl_id)
pn = pl.get_title()
if self.list[1] and find(pn,self.list[1].upper()) == -1:
if self.list[1] and string.find(pn,self.list[1].upper()) == -1:
return 0
return 1
@ -1219,7 +1218,7 @@ class HasAttribute(Rule):
if self.list[0] and event.get_type() != self.list[0]:
return 0
ev = event.get_value().upper()
if self.list[1] and find(ev,self.list[1].upper())==-1:
if self.list[1] and string.find(ev,self.list[1].upper())==-1:
return 0
return 1
@ -1245,7 +1244,7 @@ class HasFamilyAttribute(Rule):
if self.list[0] and event.get_type() != self.list[0]:
val = 0
ev = event.get_value().upper()
if self.list[1] and find(ev,self.list[1].upper())==-1:
if self.list[1] and string.find(ev,self.list[1].upper())==-1:
val = 0
if val == 1:
return 1
@ -1278,18 +1277,41 @@ class HasNameOf(Rule):
p = db.find_person_from_id(p_id)
for name in [p.get_primary_name()] + p.get_alternate_names():
val = 1
if self.f and find(name.get_first_name().upper(),self.f.upper()) == -1:
if self.f and string.find(name.get_first_name().upper(),self.f.upper()) == -1:
val = 0
if self.l and find(name.get_surname().upper(),self.l.upper()) == -1:
if self.l and string.find(name.get_surname().upper(),self.l.upper()) == -1:
val = 0
if self.s and find(name.get_suffix().upper(),self.s.upper()) == -1:
if self.s and string.find(name.get_suffix().upper(),self.s.upper()) == -1:
val = 0
if self.t and find(name.get_title().upper(),self.t.upper()) == -1:
if self.t and string.find(name.get_title().upper(),self.t.upper()) == -1:
val = 0
if val == 1:
return 1
return 0
#-------------------------------------------------------------------------
#
# HasNameOf
#
#-------------------------------------------------------------------------
class SearchName(Rule):
"""Rule that checks for full or partial name matches"""
labels = [_('Substring:')]
def name(self):
return 'Matches name'
def description(self):
return _("Matches the person with a specified (partial) name")
def category(self):
return _('General filters')
def apply(self,db,p_id):
self.f = self.list[0]
p = db.find_person_from_id(p_id)
return self.f and string.find(p.get_primary_name().get_name().upper(),self.f.upper()) != -1
#-------------------------------------------------------------------------
#
@ -1357,12 +1379,14 @@ class GenericFilter:
def __init__(self,source=None):
if source:
self.need_param = source.need_param
self.flist = source.flist[:]
self.name = source.name
self.comment = source.comment
self.logical_op = source.logical_op
self.invert = source.invert
else:
self.need_param = 0
self.flist = []
self.name = ''
self.comment = ''
@ -1477,7 +1501,7 @@ class GenericFilter:
#
#-------------------------------------------------------------------------
tasks = {
unicode(_("Everyone")) : Everyone,
unicode(_("Everyone")) : Everyone,
unicode(_("Has the Id")) : HasIdOf,
unicode(_("Has a name")) : HasNameOf,
unicode(_("Has the relationships")) : HasRelationship,
@ -1487,20 +1511,20 @@ tasks = {
unicode(_("Is a descendant family member of")) : IsDescendantFamilyOf,
unicode(_("Is a descendant of filter match")) : IsDescendantOfFilterMatch,
unicode(_("Is a descendant of person not more than N generations away"))
: IsLessThanNthGenerationDescendantOf,
: IsLessThanNthGenerationDescendantOf,
unicode(_("Is a descendant of person at least N generations away"))
: IsMoreThanNthGenerationDescendantOf,
: IsMoreThanNthGenerationDescendantOf,
unicode(_("Is a child of filter match")) : IsChildOfFilterMatch,
unicode(_("Is an ancestor of")) : IsAncestorOf,
unicode(_("Is an ancestor of filter match")) : IsAncestorOfFilterMatch,
unicode(_("Is an ancestor of person not more than N generations away"))
: IsLessThanNthGenerationAncestorOf,
: IsLessThanNthGenerationAncestorOf,
unicode(_("Is an ancestor of person at least N generations away"))
: IsMoreThanNthGenerationAncestorOf,
: IsMoreThanNthGenerationAncestorOf,
unicode(_("Is a parent of filter match")) : IsParentOfFilterMatch,
unicode(_("Has a common ancestor with")) : HasCommonAncestorWith,
unicode(_("Has a common ancestor with filter match"))
: HasCommonAncestorWithFilterMatch,
: HasCommonAncestorWithFilterMatch,
unicode(_("Is a female")) : IsFemale,
unicode(_("Is a male")) : IsMale,
unicode(_("Has complete record")) : HasCompleteRecord,
@ -1634,6 +1658,21 @@ class FilterParser(handler.ContentHandler):
def characters(self, data):
pass
class ParamFilter(GenericFilter):
def __init__(self,source=None):
GenericFilter.__init__(self,source)
self.need_param = 1
self.param_list = []
def set_parameter(self,param):
self.param_list = [param]
def apply(self,db,id_list):
for rule in self.flist:
rule.set_list(self.param_list)
return GenericFilter.apply(self,db,id_list)
#-------------------------------------------------------------------------
#
#

View File

@ -64,6 +64,7 @@ class PeopleModel(gtk.GenericTreeModel):
self.db = db
self.filter = filter
self.visible = {}
self.top_visible = {}
self.fmap = [
self.column_name,
@ -115,6 +116,7 @@ class PeopleModel(gtk.GenericTreeModel):
self.path2iter = {}
self.sname_sub = {}
self.visible = {}
self.top_visible = {}
if not self.db.is_open():
return
@ -231,7 +233,7 @@ class PeopleModel(gtk.GenericTreeModel):
return pango.WEIGHT_NORMAL
elif col == COLUMN_VIEW:
if self.top_iter2path.has_key(iter):
return 1
return self.top_visible.has_key(iter)
return self.visible.has_key(iter)
elif self.top_iter2path.has_key(iter):
if col == 0:
@ -246,8 +248,11 @@ class PeopleModel(gtk.GenericTreeModel):
def reset_visible(self):
self.visible = {}
self.top_visible = {}
def set_visible(self,iter,val):
col = self.iter2path[iter]
self.top_visible[col[0]] = val
self.visible[iter] = val
def on_iter_next(self, node):

View File

@ -103,6 +103,7 @@ class PeopleView:
column.set_resizable(gtk.TRUE)
column.set_min_width(225)
column.set_clickable(gtk.TRUE)
column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
column.set_sort_column_id(PeopleModel.COLUMN_NAME_SORT)
self.person_tree.append_column(column)
self.columns = [column]
@ -116,6 +117,7 @@ class PeopleView:
column.set_resizable(gtk.TRUE)
#column.set_clickable(gtk.TRUE)
column.set_min_width(60)
column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY)
column.set_sort_column_id(index)
self.columns.append(column)
self.person_tree.append_column(column)
@ -197,6 +199,8 @@ class PeopleView:
qualifer = unicode(self.parent.filter_text.get_text())
mi = self.parent.filter_list.get_menu().get_active()
self.DataFilter = mi.get_data("filter")
if self.DataFilter.need_param:
self.DataFilter.set_parameter(unicode(self.parent.filter_text.get_text()))
self.apply_filter()
self.goto_active_person()

View File

@ -1249,54 +1249,37 @@
<widget class="GtkHBox" id="filterbar">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<property name="spacing">6</property>
<child>
<widget class="GtkHBox" id="hbox15">
<widget class="GtkButton" id="apply_filter">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<property name="tooltip" translatable="yes">Apply filter using the selected controls</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_Apply</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_apply_filter_clicked" object="filter"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label184">
<child>
<widget class="GtkOptionMenu" id="filter_list">
<property name="width_request">200</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="history">-1</property>
<child internal-child="menu">
<widget class="GtkMenu" id="convertwidget12">
<property name="visible">True</property>
<property name="label" translatable="yes">Fi_lter:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">5</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">filter_list</property>
</widget>
<packing>
<property name="padding">4</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkOptionMenu" id="filter_list">
<property name="width_request">200</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="history">-1</property>
<child internal-child="menu">
<widget class="GtkMenu" id="convertwidget12">
<property name="visible">True</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
@ -1307,149 +1290,26 @@
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkLabel" id="qual">
<property name="label" translatable="yes">Qualifier:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_CENTER</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">5</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">filter</property>
</widget>
<packing>
<property name="padding">3</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="filter">
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">False</property>
<signal name="activate" handler="on_apply_filter_clicked"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<widget class="GtkEntry" id="filter">
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">False</property>
<signal name="activate" handler="on_apply_filter_clicked"/>
</widget>
<packing>
<property name="padding">5</property>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox74">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkButton" id="apply_filter">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Apply filter using the selected controls</property>
<property name="can_focus">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<signal name="clicked" handler="on_apply_filter_clicked" object="filter"/>
<child>
<widget class="GtkAlignment" id="alignment2">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">0</property>
<property name="yscale">0</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">0</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkHBox" id="hbox90">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">2</property>
<child>
<widget class="GtkImage" id="image352">
<property name="visible">True</property>
<property name="stock">gtk-apply</property>
<property name="icon_size">4</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label371">
<property name="visible">True</property>
<property name="label" translatable="yes">_Apply</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">3</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">5</property>
<property name="padding">6</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>

View File

@ -203,7 +203,6 @@ class Gramps:
self.toolbar = self.gtop.get_widget("toolbar1")
self.toolbardock = self.gtop.get_widget("dockitem2")
self.filter_text = self.gtop.get_widget('filter')
self.filter_inv = self.gtop.get_widget("invert")
self.qual_label = self.gtop.get_widget("qual")
self.child_type = self.gtop.get_widget("childtype")
self.spouse_tab = self.gtop.get_widget("lab_or_list")
@ -716,6 +715,11 @@ class Gramps:
filter_list = []
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
filter_list.append(all)
all = GenericFilter.GenericFilter()
all.set_name(_("Females"))
all.add_rule(GenericFilter.IsFemale([]))
@ -726,14 +730,16 @@ class Gramps:
all.add_rule(GenericFilter.IsMale([]))
filter_list.append(all)
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
all = GenericFilter.ParamFilter()
all.set_name(_("Name contains..."))
all.add_rule(GenericFilter.SearchName([]))
filter_list.append(all)
menu = GenericFilter.build_filter_menu(filter_list)
menu = GenericFilter.build_filter_menu(filter_list)
self.filter_list.set_menu(menu)
self.filter_list.set_history(0)
self.filter_list.connect('changed',self.on_filter_name_changed)
self.filter_text.set_sensitive(0)
def on_find_activate(self,obj):
@ -1485,17 +1491,14 @@ class Gramps:
self.people_view.apply_filter_clicked()
def on_filter_name_changed(self,obj):
filter = obj.get_data("filter")
qual = obj.get_data('qual')
filter = obj.get_menu().get_active().get_data('filter')
qual = filter.need_param
if qual:
self.qual_label.show()
self.qual_label.set_sensitive(1)
self.qual_label.set_text(obj.get_data("label"))
filter.show()
self.filter_text.show()
self.filter_text.set_sensitive(1)
else:
self.qual_label.hide()
filter.hide()
filter.set_sensitive(qual)
self.filter_text.hide()
self.filter_text.set_sensitive(0)
def new_after_edit(self,epo,trans):
if epo: