diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index 4afa96843..b6801d3b6 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,10 @@ +2004-04-29 Don Allingham + * 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 * src/DbPrompter.py: remove unused functions * src/DisplayModels.py: filtering support diff --git a/gramps2/src/GenericFilter.py b/gramps2/src/GenericFilter.py index 4e365a25e..f5efc88bf 100644 --- a/gramps2/src/GenericFilter.py +++ b/gramps2/src/GenericFilter.py @@ -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) + #------------------------------------------------------------------------- # # diff --git a/gramps2/src/PeopleModel.py b/gramps2/src/PeopleModel.py index ace2a6263..ef66d7892 100644 --- a/gramps2/src/PeopleModel.py +++ b/gramps2/src/PeopleModel.py @@ -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): diff --git a/gramps2/src/PeopleView.py b/gramps2/src/PeopleView.py index b05decb31..d5f6e2548 100644 --- a/gramps2/src/PeopleView.py +++ b/gramps2/src/PeopleView.py @@ -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() diff --git a/gramps2/src/gramps.glade b/gramps2/src/gramps.glade index 8d283d4c7..98f18f5bc 100644 --- a/gramps2/src/gramps.glade +++ b/gramps2/src/gramps.glade @@ -1249,54 +1249,37 @@ True False - 0 + 6 - + True - False - 0 + Apply filter using the selected controls + True + _Apply + True + GTK_RELIEF_NORMAL + True + + + + 0 + False + False + + - - + + + 200 + True + True + -1 + + + True - Fi_lter: - True - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 5 - 0 - filter_list - - 4 - False - False - - - - - - 200 - True - True - -1 - - - - True - - - - - 0 - True - True - @@ -1307,149 +1290,26 @@ - - True - False - 0 - - - - Qualifier: - True - False - GTK_JUSTIFY_CENTER - False - False - 0.5 - 0.5 - 5 - 0 - filter - - - 3 - False - False - - - - - - True - True - True - 0 - - True - * - False - - - - 0 - True - True - - + + True + True + True + 0 + + True + * + False + - 5 + 0 True True - - - - True - False - 0 - - - - True - Apply filter using the selected controls - True - GTK_RELIEF_NORMAL - True - - - - - True - 0.5 - 0.5 - 0 - 0 - 0 - 0 - 0 - 0 - - - - True - False - 2 - - - - True - gtk-apply - 4 - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - _Apply - True - False - GTK_JUSTIFY_LEFT - False - False - 0.5 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - - - - 0 - False - False - - - - - 3 - False - False - - - 5 + 6 False True diff --git a/gramps2/src/gramps_main.py b/gramps2/src/gramps_main.py index 7e97cd789..02d6ad359 100755 --- a/gramps2/src/gramps_main.py +++ b/gramps2/src/gramps_main.py @@ -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: