Added Russian translation and custom filter editor

svn: r892
This commit is contained in:
Don Allingham 2002-04-05 00:23:13 +00:00
parent d5f2a14a50
commit cace1a74aa
10 changed files with 6367 additions and 34 deletions

447
gramps/src/GenericFilter.py Normal file
View File

@ -0,0 +1,447 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2002 Donald N. Allingham
#
# 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
#
"""Generic Filtering Routines"""
__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
#-------------------------------------------------------------------------
#
# Standard Python modules
#
#-------------------------------------------------------------------------
import types
import os
from string import find,join
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from RelLib import *
from Date import Date
#-------------------------------------------------------------------------
#
# Rule
#
#-------------------------------------------------------------------------
class Rule:
"""Base rule class"""
labels = []
def __init__(self,list):
assert(type(list) == type([]),"Argument is not a list")
self.list = list
def values(self):
return self.list
def name(self):
return 'None'
def check(self):
return len(self.list) == len(self.labels)
def apply(self,p):
return 1
def display_values(self):
v = []
for i in range(0,len(self.list)):
if self.list[i]:
v.append('%s="%s"' % (self.labels[i],self.list[i]))
return join(v,'; ')
#-------------------------------------------------------------------------
#
# Everyone
#
#-------------------------------------------------------------------------
class Everyone(Rule):
"""Matches Everyone"""
labels = []
def name(self):
return 'Everyone'
def apply(self,p):
return 1
#-------------------------------------------------------------------------
#
# HasIdOf
#
#-------------------------------------------------------------------------
class HasIdOf(Rule):
"""Rule that checks for a person with a specific GID"""
labels = [ 'ID' ]
def name(self):
return 'Has the Id'
def apply(self,p):
return p.getId() == self.list[0]
#-------------------------------------------------------------------------
#
# IsFemale
#
#-------------------------------------------------------------------------
class IsFemale(Rule):
"""Rule that checks for a person that is a female"""
labels = []
def name(self):
return 'Is a female'
def apply(self,p):
return p.getGender() == Person.female
#-------------------------------------------------------------------------
#
# IsDescendantOf
#
#-------------------------------------------------------------------------
class IsDescendantOf(Rule):
"""Rule that checks for a person that is a descendant of a specified person"""
labels = ['ID']
def name(self):
return 'Is a descendant of'
def apply(self,p):
return self.search(p)
def search(self,p):
if p.getId() == self.list[0]:
return 1
for (f,r1,r2) in p.getParentList():
for p1 in [f.getMother(),f.getFather()]:
if p1:
if self.search(p1):
return 1
return 0
#-------------------------------------------------------------------------
#
# IsAncestorOf
#
#-------------------------------------------------------------------------
class IsAncestorOf(Rule):
"""Rule that checks for a person that is an ancestor of a specified person"""
labels = ['ID']
def name(self):
return 'Is an ancestor of'
def apply(self,p):
return self.search(p)
def search(self,p):
if p.getId() == self.list[0]:
return 1
for f in p.getFamilyList():
for p1 in f.getChildList():
if p1:
if self.search(p1):
return 1
return 0
#-------------------------------------------------------------------------
#
# IsMale
#
#-------------------------------------------------------------------------
class IsMale(Rule):
"""Rule that checks for a person that is a male"""
labels = []
def name(self):
return 'Is a male'
def apply(self,p):
return p.getGender() == Person.male
#-------------------------------------------------------------------------
#
# HasEvent
#
#-------------------------------------------------------------------------
class HasEvent(Rule):
"""Rule that checks for a person with a particular value"""
labels = [ 'Event', 'Date', 'Place', 'Description' ]
def name(self):
return 'Has the event'
def apply(self,p):
for event in [p.getBirth(),p.getDeath()] + p.getEventList():
if self.list[0] and event.getName() != self.list[0]:
return 0
if self.list[3] and find(event.getDescription(),self.list[3])==-1:
return 0
if self.list[1]:
try:
d = Date.Date(self.list[1])
except:
return 0
if Date.compare_dates(d,event.getDateObj()):
return 0
if self.list[2] and find(p.getPlaceName(),self.list[2]) == -1:
return 0
return 1
#-------------------------------------------------------------------------
#
# HasAttribute
#
#-------------------------------------------------------------------------
class HasAttribute(Rule):
"""Rule that checks for a person with a particular attribute"""
labels = [ 'Attribute', 'Value' ]
def name(self):
return 'Has the attribute'
def apply(self,p):
for event in p.getAttributes():
if self.list[0] and event.getType() != self.list[0]:
return 0
if self.list[1] and find(event.getValue(),self.list[1])==-1:
return 0
return 1
#-------------------------------------------------------------------------
#
# HasNameOf
#
#-------------------------------------------------------------------------
class HasNameOf(Rule):
"""Rule that checks for full or partial name matches"""
labels = ['Given Name','Surname','Suffix','Title']
def name(self):
return 'Has a name'
def apply(self,p):
self.f = self.list[0]
self.l = self.list[1]
self.s = self.list[2]
self.t = self.list[3]
for name in [p.getPrimaryName()] + p.getAlternateNames():
if self.f and find(name.getFirstName(),self.f) == -1:
return 0
if self.l and find(name.getSurname(),self.l) == -1:
return 0
if self.s and find(name.getSuffix(),self.s) == -1:
return 0
if self.t and find(name.getTitle(),self.t) == -1:
return 0
return 1
#-------------------------------------------------------------------------
#
# GenericFilter
#
#-------------------------------------------------------------------------
class GenericFilter:
"""Filter class that consists of several rules"""
def __init__(self,source=None):
if source:
self.flist = source.flist[:]
self.name = source.name
self.comment = source.comment
else:
self.flist = []
self.name = 'NoName'
self.comment = ''
def get_name(self):
return self.name
def set_name(self,name):
self.name = name
def set_comment(self,comment):
self.comment = comment
def get_comment(self):
return self.comment
def add_rule(self,rule):
self.flist.append(rule)
def set_rules(self,rules):
self.flist = rules
def get_rules(self):
return self.flist
def apply(self,list):
result = []
for p in list:
for rule in self.flist:
if rule.apply(p) == 0:
break
else:
result.append(p)
return result
#-------------------------------------------------------------------------
#
# Name to class mappings
#
#-------------------------------------------------------------------------
tasks = {
"Everyone" : Everyone,
"Has the Id" : HasIdOf,
"Has a name" : HasNameOf,
"Is the descendant of" : IsDescendantOf,
"Is an ancestor of" : IsAncestorOf,
"Is a female" : IsFemale,
"Is a male" : IsMale,
"Has the event" : HasEvent,
"Has the attribute" : HasAttribute,
}
#-------------------------------------------------------------------------
#
# GenericFilterList
#
#-------------------------------------------------------------------------
class GenericFilterList:
"""Container class for the generic filters. Stores, saves, and
loads the filters."""
def __init__(self,file):
self.filter_list = []
self.file = os.path.expanduser(file)
def get_filters(self):
return self.filter_list
def add(self,filter):
self.filter_list.append(filter)
def load(self):
try:
parser = make_parser()
parser.setContentHandler(FilterParser(self))
parser.parse(self.file)
except (IOError,OSError,SAXParseException):
pass
def save(self):
f = open(self.file,'w')
f.write("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n")
f.write('<filters>\n')
for i in self.filter_list:
f.write(' <filter name="%s"' % i.get_name())
comment = i.get_comment()
if comment:
f.write(' comment="%s"' % comment)
f.write('>\n')
for rule in i.get_rules():
f.write(' <rule class="%s">\n' % rule.name())
for v in rule.values():
f.write(' <arg value="%s"/>\n' % v)
f.write(' </rule>\n')
f.write(' </filter>\n')
f.write('</filters>\n')
f.close()
#-------------------------------------------------------------------------
#
# FilterParser
#
#-------------------------------------------------------------------------
class FilterParser(handler.ContentHandler):
"""Parses the XML file and builds the list of filters"""
def __init__(self,gfilter_list):
handler.ContentHandler.__init__(self)
self.gfilter_list = gfilter_list
self.f = None
self.r = None
self.a = []
self.cname = None
def setDocumentLocator(self,locator):
self.locator = locator
def startElement(self,tag,attrs):
if tag == "filter":
self.f = GenericFilter()
self.f.set_name(attrs['name'])
if attrs.has_key('comment'):
self.f.set_comment(attrs['comment'])
self.gfilter_list.add(self.f)
elif tag == "rule":
name = attrs['class']
self.a = []
self.cname = tasks[name]
elif tag == "arg":
self.a.append(attrs['value'])
def endElement(self,tag):
if tag == "rule":
rule = self.cname(self.a)
self.f.add_rule(rule)
def characters(self, data):
pass
if __name__ == '__main__':
g = GenericFilter()
g.set_name("Everyone")
rule = Everyone([])
g.add_rule(rule)
l = GenericFilterList('/home/dona/.gramps/custom_filters.xml')
l.load()
l.add(g)
l.save()

View File

@ -183,13 +183,9 @@ class ImageSelect:
Utils.destroy_passed_object(obj)
self.load_images()
#-------------------------------------------------------------------------
#
# savephoto - Save the photo in the dataobj object. (Placeholder)
#
#-------------------------------------------------------------------------
def savephoto(self, photo):
assert 0, "The savephoto function must be subclassed"
"""Save the photo in the dataobj object - must be overridden"""
pass
#-------------------------------------------------------------------------
#

View File

@ -9,7 +9,7 @@ p22_inc = @P22_INCLUDES@
pycomp = ${srcdir}/py-compile
CFLAGS = -fPIC -shared -O @CFLAGS@ @CPPFLAGS@ -I@includedir@
LDFLAGS = @LDFLAGS@ -L@libdir@ @LIBS@
LANG = sv de fr es it pt_BR
LANG = sv de fr es it pt_BR ru
# Use GNU make's ':=' syntax for nice wildcard use.
# If not using GNU make, then list all .py files individually

View File

@ -54,6 +54,7 @@ if os.environ.has_key('GRAMPSDIR'):
else:
rootDir = "."
custom_filters = "~/.gramps/custom_filters.xml"
icon = "%s/gramps.xpm" % rootDir
logo = "%s/logo.png" % rootDir
gladeFile = "%s/gramps.glade" % rootDir
@ -73,6 +74,8 @@ srcselFile = "%s/srcsel.glade" % rootDir
findFile = "%s/find.glade" % rootDir
mergeFile = "%s/mergedata.glade" % rootDir
traceFile = "%s/trace.glade" % rootDir
filterFile = "%s/rule.glade" % rootDir
pluginsDir = "%s/plugins" % rootDir
docgenDir = "%s/docgen" % rootDir
filtersDir = "%s/filters" % rootDir

Binary file not shown.

View File

@ -158,7 +158,6 @@ class AncestorChart:
#
#--------------------------------------------------------------------
def calc(self):
width = 0
self.filter(self.start,1)
self.height = self.lines*pt2cm((125.0*self.font.get_size())/100.0)

View File

@ -0,0 +1,272 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000 Donald N. Allingham
#
# 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
#
"""Generic Filtering Routines"""
__author__ = "Don Allingham"
from GTK import FILL,EXPAND
import gtk
import gnome.ui
import libglade
import string
import os
import const
from RelLib import *
import GenericFilter
import intl
_ = intl.gettext
class FilterEditor:
def __init__(self,filterdb):
self.filterdb = GenericFilter.GenericFilterList(filterdb)
self.filterdb.load()
self.editor = libglade.GladeXML(const.filterFile,'filter_list')
self.editor_top = self.editor.get_widget('filter_list')
self.filter_list = self.editor.get_widget('filters')
self.draw_filters()
self.editor.signal_autoconnect({
'on_add_clicked' : self.add_new_filter,
'on_edit_clicked' : self.edit_filter,
'on_close_clicked' : self.close_filter_editor,
'on_delete_clicked' : self.delete_filter,
})
def close_filter_editor(self,obj):
self.filterdb.save()
self.editor_top.destroy()
def draw_filters(self):
row = 0
self.filter_list.clear()
for f in self.filterdb.get_filters():
self.filter_list.append([f.get_name(),f.get_comment()])
self.filter_list.set_row_data(row,f)
row = row + 1
def add_new_filter(self,obj):
filter = GenericFilter.GenericFilter()
filter.set_name('NoName')
self.filter_editor(filter)
def edit_filter(self,obj):
sel = self.filter_list.selection
if len(sel) != 1:
return
filter = self.filter_list.get_row_data(sel[0])
self.filter_editor(GenericFilter.GenericFilter(filter))
def delete_filter(self,obj):
sel = self.filter_list.selection
if len(sel) != 1:
return
filter = self.filter_list.get_row_data(sel[0])
self.filterdb.get_filters().remove(filter)
self.draw_filters()
def filter_editor(self,filter):
self.filter = filter
self.glade = libglade.GladeXML(const.filterFile,'define_filter')
self.top = self.glade.get_widget('define_filter')
self.rule_list = self.glade.get_widget('rule_list')
self.fname = self.glade.get_widget('filter_name')
self.comment = self.glade.get_widget('comment')
self.glade.signal_autoconnect({
'on_ok_clicked' : self.on_ok_clicked,
'on_cancel_clicked' : self.on_cancel_clicked,
'on_delete_clicked' : self.on_delete_clicked,
'on_add_clicked' : self.on_add_clicked,
'on_edit_clicked' : self.on_edit_clicked,
'on_cancel_clicked' : self.on_cancel_clicked,
})
self.fname.set_text(self.filter.get_name())
self.comment.set_text(self.filter.get_comment())
self.draw_rules()
def draw_rules(self):
self.rule_list.clear()
row = 0
for r in self.filter.get_rules():
self.rule_list.append([r.name(),r.display_values()])
self.rule_list.set_row_data(row,r)
row = row + 1
def on_cancel_clicked(self,obj):
self.top.destroy()
def on_ok_clicked(self,obj):
n = string.strip(self.fname.get_text())
if n == '':
return
self.filter.set_name(n)
self.filter.set_comment(string.strip(self.comment.get_text()))
for f in self.filterdb.get_filters()[:]:
if n == f.get_name():
self.filterdb.get_filters().remove(f)
break
self.filterdb.add(self.filter)
self.draw_filters()
self.top.destroy()
def on_add_clicked(self,obj):
self.edit_rule(None)
def on_edit_clicked(self,obj):
if len(self.rule_list.selection) != 1:
return
row = self.rule_list.selection[0]
d = self.rule_list.get_row_data(row)
self.edit_rule(d)
def edit_rule(self,val):
self.active_rule = val
self.rule = libglade.GladeXML(const.filterFile,'add_rule')
self.rule_top = self.rule.get_widget('add_rule')
self.frame = self.rule.get_widget('values')
self.rname = self.rule.get_widget('rule_name')
self.notebook = gtk.GtkNotebook()
self.notebook.set_show_tabs(0)
self.notebook.set_show_border(0)
self.notebook.show()
self.frame.add(self.notebook)
self.page_num = 0
self.page = []
self.name2page = {}
map = {}
list = []
for name in GenericFilter.tasks.keys():
cname = GenericFilter.tasks[name]
arglist = cname.labels
vallist = []
tlist = []
self.page.append((name,cname,vallist,tlist))
table = gtk.GtkTable(2,len(arglist))
table.show()
pos = 0
l2 = gtk.GtkLabel(name)
l2.set_alignment(0,0.5)
l2.show()
c = gtk.GtkListItem()
c.add(l2)
c.set_data('d',pos)
c.show()
list.append(c)
map[name] = c
for v in arglist:
l = gtk.GtkLabel(v)
l.set_alignment(1,0.5)
l.show()
if v == 'Event':
t = gtk.GtkCombo()
t.set_popdown_strings(const.personalEvents)
t.set_value_in_list(1,0)
t.entry.set_editable(0)
tlist.append(t.entry)
elif v == 'Attribute':
t = gtk.GtkCombo()
t.set_popdown_strings(const.personalAttributes)
t.set_value_in_list(1,0)
t.entry.set_editable(0)
tlist.append(t.entry)
else:
t = gtk.GtkEntry()
tlist.append(t)
t.show()
table.attach(l,0,1,pos,pos+1,EXPAND|FILL,0,5,5)
table.attach(t,1,2,pos,pos+1,EXPAND|FILL,0,5,5)
pos = pos + 1
self.notebook.append_page(table,gtk.GtkLabel(name))
self.name2page[name] = self.page_num
self.page_num = self.page_num + 1
self.page_num = 0
self.rname.disable_activate()
self.rname.list.clear_items(0,-1)
self.rname.list.append_items(list)
for v in map.keys():
self.rname.set_item_string(map[v],v)
if self.active_rule:
page = self.name2page[self.active_rule.name()]
self.rname.entry.set_text(self.active_rule.name())
self.notebook.set_page(page)
(n,c,v,t) = self.page[page]
r = self.active_rule.values()
for i in range(0,len(t)):
t[i].set_text(r[i])
self.rname.entry.connect('changed',self.rule_changed)
self.rule.get_widget('ok').connect('clicked',self.rule_ok)
self.rule.get_widget('cancel').connect('clicked',self.rule_cancel)
def on_delete_clicked(self,obj):
if len(self.rule_list.selection) != 1:
return
row = self.rule_list.selection[0]
del self.filter.get_rules()[row]
self.draw_rules()
def rule_changed(self,obj):
name = obj.get_text()
page = self.name2page[name]
self.notebook.set_page(page)
def rule_ok(self,obj):
name = self.rname.entry.get_text()
page = self.name2page[name]
(n,c,v,t) = self.page[page]
value_list = []
for x in t:
value_list.append(x.get_text())
new_rule = c(value_list)
if self.active_rule:
index = self.rule_list.selection[0]
self.filter.get_rules()[index] = new_rule
else:
self.filter.add_rule(new_rule)
self.draw_rules()
self.rule_top.destroy()
def rule_cancel(self,obj):
self.rule_top.destroy()
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
def runTool(database,person,callback):
FilterEditor(const.custom_filters)
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
from Plugins import register_tool
register_tool(
runTool,
_("Custom Filter Editor"),
category=_("Utilities"),
description=_("The Custom Filter Editor builds custom filters that can be used to select people included reports, exports, and other utilities.")
)

View File

@ -416,27 +416,28 @@ class GedcomWriter:
filter_obj = self.topDialog.get_widget("filter")
myMenu = gtk.GtkMenu()
menuitem = gtk.GtkMenuItem(_("Entire Database"))
myMenu.append(menuitem)
menuitem.set_data("filter",entire_database)
menuitem.show()
name = person.getPrimaryName().getRegularName()
menuitem = gtk.GtkMenuItem(_("Ancestors of %s") % name)
myMenu.append(menuitem)
menuitem.set_data("filter",active_person_ancestors)
menuitem.show()
menuitem = gtk.GtkMenuItem(_("Descendants of %s") % name)
myMenu.append(menuitem)
menuitem.set_data("filter",active_person_descendants)
menuitem.show()
menuitem = gtk.GtkMenuItem(_("Ancestors and Descendants of %s") % name)
myMenu.append(menuitem)
menuitem.set_data("filter",active_person_ancestors_and_descendants)
menuitem.show()
menuitem = gtk.GtkMenuItem(_("People somehow connected to %s") % name)
myMenu.append(menuitem)
menuitem.set_data("filter",interconnected)
menuitem.show()
import GenericFilter
all = GenericFilter.GenericFilter()
all.set_name(_("Entire Database"))
all.add_rule(GenericFilter.Everyone([]))
des = GenericFilter.GenericFilter()
des.set_name(_("Descendants of %s") % person.getPrimaryName().getName())
des.add_rule(GenericFilter.IsDescendantOf([person.getId()]))
ans = GenericFilter.GenericFilter()
ans.set_name(_("Ancestors of %s") % person.getPrimaryName().getName())
ans.add_rule(GenericFilter.IsAncestorOf([person.getId()]))
flist = GenericFilter.GenericFilterList(const.custom_filters)
flist.load()
for f in [all,des,ans] + flist.get_filters():
menuitem = gtk.GtkMenuItem(_(f.get_name()))
myMenu.append(menuitem)
menuitem.set_data("filter",f)
menuitem.show()
filter_obj.set_menu(myMenu)
self.filter_menu = myMenu
@ -461,7 +462,7 @@ class GedcomWriter:
self.restrict = self.topDialog.get_widget("restrict").get_active()
self.private = self.topDialog.get_widget("private").get_active()
filter = self.filter_menu.get_active().get_data("filter")
cfilter = self.filter_menu.get_active().get_data("filter")
act_tgt = self.target_menu.get_active()
self.target_ged = act_tgt.get_data("data")
@ -482,8 +483,19 @@ class GedcomWriter:
name = self.topDialog.get_widget("filename").get_text()
(self.plist,self.flist,self.slist) = filter(self.db,self.person,self.private)
if cfilter == None:
self.plist = self.db.getPersonMap().values()
else:
self.plist = cfilter.apply(self.db.getPersonMap().values())
self.flist = []
self.slist = []
for p in self.plist[:]:
add_persons_sources(p,self.slist,self.private)
for family in p.getFamilyList():
add_familys_sources(family,self.slist,self.private)
self.flist.append(family)
Utils.destroy_passed_object(obj)
glade_file = "%s/gedcomexport.glade" % os.path.dirname(__file__)
@ -592,12 +604,12 @@ class GedcomWriter:
father_alive = mother_alive = 0
self.g.write("0 @%s@ FAM\n" % self.fid(family.getId()))
person = family.getFather()
if person != None:
if person != None and person in self.plist:
self.g.write("1 HUSB @%s@\n" % self.pid(person.getId()))
father_alive = person.probablyAlive()
person = family.getMother()
if person != None:
if person != None and person in self.plist:
self.g.write("1 WIFE @%s@\n" % self.pid(person.getId()))
mother_alive = person.probablyAlive()
@ -624,6 +636,8 @@ class GedcomWriter:
self.dump_event_stats(event)
for person in family.getChildList():
if person not in self.plist:
continue
self.g.write("1 CHIL @%s@\n" % self.pid(person.getId()))
if self.adopt == ADOPT_FTW:
if person.getMainParents() == family:

4870
gramps/src/po/ru.po Normal file

File diff suppressed because it is too large Load Diff

732
gramps/src/rule.glade Normal file
View File

@ -0,0 +1,732 @@
<?xml version="1.0"?>
<GTK-Interface>
<project>
<name>Rule</name>
<program_name>rule</program_name>
<directory></directory>
<source_directory>src</source_directory>
<pixmaps_directory>pixmaps</pixmaps_directory>
<language>C</language>
<gnome_support>True</gnome_support>
<gettext_support>True</gettext_support>
</project>
<widget>
<class>GnomeDialog</class>
<name>define_filter</name>
<title>Define Filter - GRAMPS</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
<modal>False</modal>
<allow_shrink>False</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>False</auto_shrink>
<auto_close>False</auto_close>
<hide_on_close>False</hide_on_close>
<widget>
<class>GtkVBox</class>
<child_name>GnomeDialog:vbox</child_name>
<name>dialog-vbox1</name>
<homogeneous>False</homogeneous>
<spacing>8</spacing>
<child>
<padding>4</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkHButtonBox</class>
<child_name>GnomeDialog:action_area</child_name>
<name>dialog-action_area1</name>
<layout_style>GTK_BUTTONBOX_END</layout_style>
<spacing>8</spacing>
<child_min_width>85</child_min_width>
<child_min_height>27</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
<pack>GTK_PACK_END</pack>
</child>
<widget>
<class>GtkButton</class>
<name>ok</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_ok_clicked</handler>
<last_modification_time>Mon, 01 Apr 2002 02:49:31 GMT</last_modification_time>
</signal>
<stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
</widget>
<widget>
<class>GtkButton</class>
<name>button6</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_cancel_clicked</handler>
<last_modification_time>Thu, 04 Apr 2002 18:31:55 GMT</last_modification_time>
</signal>
<stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
</widget>
</widget>
<widget>
<class>GtkVBox</class>
<name>vbox1</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label1</name>
<label>Define Filter</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkHSeparator</class>
<name>hseparator1</name>
<child>
<padding>5</padding>
<expand>False</expand>
<fill>True</fill>
</child>
</widget>
<widget>
<class>GtkTable</class>
<name>table1</name>
<rows>2</rows>
<columns>2</columns>
<homogeneous>False</homogeneous>
<row_spacing>0</row_spacing>
<column_spacing>0</column_spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label2</name>
<label>Name</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>1</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<left_attach>0</left_attach>
<right_attach>1</right_attach>
<top_attach>0</top_attach>
<bottom_attach>1</bottom_attach>
<xpad>5</xpad>
<ypad>5</ypad>
<xexpand>False</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
<widget>
<class>GtkLabel</class>
<name>label10</name>
<label>Comment</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>1</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<left_attach>0</left_attach>
<right_attach>1</right_attach>
<top_attach>1</top_attach>
<bottom_attach>2</bottom_attach>
<xpad>5</xpad>
<ypad>5</ypad>
<xexpand>False</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
<widget>
<class>GtkEntry</class>
<name>filter_name</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
<top_attach>0</top_attach>
<bottom_attach>1</bottom_attach>
<xpad>5</xpad>
<ypad>5</ypad>
<xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
<widget>
<class>GtkEntry</class>
<name>comment</name>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<child>
<left_attach>1</left_attach>
<right_attach>2</right_attach>
<top_attach>1</top_attach>
<bottom_attach>2</bottom_attach>
<xpad>5</xpad>
<ypad>5</ypad>
<xexpand>True</xexpand>
<yexpand>False</yexpand>
<xshrink>False</xshrink>
<yshrink>False</yshrink>
<xfill>True</xfill>
<yfill>False</yfill>
</child>
</widget>
</widget>
<widget>
<class>GtkScrolledWindow</class>
<name>scrolledwindow1</name>
<hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkCList</class>
<name>rule_list</name>
<width>450</width>
<height>200</height>
<can_focus>True</can_focus>
<columns>2</columns>
<column_widths>147,80</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label3</name>
<label>Rule</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label4</name>
<label>Values</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
<widget>
<class>GtkHButtonBox</class>
<name>hbuttonbox1</name>
<layout_style>GTK_BUTTONBOX_SPREAD</layout_style>
<spacing>30</spacing>
<child_min_width>85</child_min_width>
<child_min_height>27</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkButton</class>
<name>add</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_add_clicked</handler>
<last_modification_time>Mon, 01 Apr 2002 02:47:47 GMT</last_modification_time>
</signal>
<label>Add</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkButton</class>
<name>edit</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_edit_clicked</handler>
<last_modification_time>Mon, 01 Apr 2002 02:48:18 GMT</last_modification_time>
</signal>
<label>Edit</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkButton</class>
<name>delete</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_delete_clicked</handler>
<last_modification_time>Mon, 01 Apr 2002 02:48:53 GMT</last_modification_time>
</signal>
<label>Delete</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GnomeDialog</class>
<name>add_rule</name>
<title>Add Rule - GRAMPS</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
<modal>False</modal>
<allow_shrink>False</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>False</auto_shrink>
<auto_close>False</auto_close>
<hide_on_close>False</hide_on_close>
<widget>
<class>GtkVBox</class>
<child_name>GnomeDialog:vbox</child_name>
<name>dialog-vbox2</name>
<homogeneous>False</homogeneous>
<spacing>8</spacing>
<child>
<padding>4</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkHButtonBox</class>
<child_name>GnomeDialog:action_area</child_name>
<name>dialog-action_area2</name>
<layout_style>GTK_BUTTONBOX_END</layout_style>
<spacing>8</spacing>
<child_min_width>85</child_min_width>
<child_min_height>27</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
<pack>GTK_PACK_END</pack>
</child>
<widget>
<class>GtkButton</class>
<name>ok</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
</widget>
<widget>
<class>GtkButton</class>
<name>cancel</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
</widget>
</widget>
<widget>
<class>GtkVBox</class>
<name>vbox2</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label5</name>
<label>Add Rule</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>5</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkHSeparator</class>
<name>hseparator2</name>
<child>
<padding>5</padding>
<expand>False</expand>
<fill>True</fill>
</child>
</widget>
<widget>
<class>GtkHBox</class>
<name>hbox2</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>5</padding>
<expand>False</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label6</name>
<label>Rule</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>5</padding>
<expand>False</expand>
<fill>True</fill>
</child>
</widget>
<widget>
<class>GtkCombo</class>
<name>rule_name</name>
<value_in_list>True</value_in_list>
<ok_if_empty>False</ok_if_empty>
<case_sensitive>False</case_sensitive>
<use_arrows>True</use_arrows>
<use_arrows_always>False</use_arrows_always>
<items></items>
<child>
<padding>5</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkEntry</class>
<child_name>GtkCombo:entry</child_name>
<name>combo-entry1</name>
<can_focus>True</can_focus>
<editable>False</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
</widget>
</widget>
</widget>
<widget>
<class>GtkFrame</class>
<name>values</name>
<label>Values</label>
<label_xalign>0</label_xalign>
<shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>Placeholder</class>
</widget>
</widget>
</widget>
</widget>
</widget>
<widget>
<class>GnomeDialog</class>
<name>filter_list</name>
<title>User Defined Filters - GRAMPS</title>
<type>GTK_WINDOW_TOPLEVEL</type>
<position>GTK_WIN_POS_NONE</position>
<modal>False</modal>
<allow_shrink>False</allow_shrink>
<allow_grow>True</allow_grow>
<auto_shrink>False</auto_shrink>
<auto_close>False</auto_close>
<hide_on_close>False</hide_on_close>
<widget>
<class>GtkVBox</class>
<child_name>GnomeDialog:vbox</child_name>
<name>dialog-vbox3</name>
<homogeneous>False</homogeneous>
<spacing>8</spacing>
<child>
<padding>4</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkHButtonBox</class>
<child_name>GnomeDialog:action_area</child_name>
<name>dialog-action_area3</name>
<layout_style>GTK_BUTTONBOX_END</layout_style>
<spacing>8</spacing>
<child_min_width>85</child_min_width>
<child_min_height>27</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>True</fill>
<pack>GTK_PACK_END</pack>
</child>
<widget>
<class>GtkButton</class>
<name>button1</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_close_clicked</handler>
<last_modification_time>Thu, 04 Apr 2002 02:05:50 GMT</last_modification_time>
</signal>
<stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button>
</widget>
</widget>
<widget>
<class>GtkVBox</class>
<name>vbox3</name>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkLabel</class>
<name>label7</name>
<label>User Defined Filters</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
<child>
<padding>5</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
<widget>
<class>GtkHSeparator</class>
<name>hseparator3</name>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
</widget>
<widget>
<class>GtkScrolledWindow</class>
<name>scrolledwindow2</name>
<hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
<child>
<padding>5</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkCList</class>
<name>filters</name>
<width>450</width>
<height>150</height>
<can_focus>True</can_focus>
<columns>2</columns>
<column_widths>117,80</column_widths>
<selection_mode>GTK_SELECTION_SINGLE</selection_mode>
<show_titles>True</show_titles>
<shadow_type>GTK_SHADOW_IN</shadow_type>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label8</name>
<label>Name</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
<widget>
<class>GtkLabel</class>
<child_name>CList:title</child_name>
<name>label9</name>
<label>Comment</label>
<justify>GTK_JUSTIFY_CENTER</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
<yalign>0.5</yalign>
<xpad>0</xpad>
<ypad>0</ypad>
</widget>
</widget>
</widget>
<widget>
<class>GtkHButtonBox</class>
<name>hbuttonbox2</name>
<layout_style>GTK_BUTTONBOX_SPREAD</layout_style>
<spacing>30</spacing>
<child_min_width>85</child_min_width>
<child_min_height>27</child_min_height>
<child_ipad_x>7</child_ipad_x>
<child_ipad_y>0</child_ipad_y>
<child>
<padding>0</padding>
<expand>True</expand>
<fill>True</fill>
</child>
<widget>
<class>GtkButton</class>
<name>button3</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_add_clicked</handler>
<last_modification_time>Thu, 04 Apr 2002 02:04:34 GMT</last_modification_time>
</signal>
<label>Add</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkButton</class>
<name>button4</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_edit_clicked</handler>
<last_modification_time>Thu, 04 Apr 2002 02:04:53 GMT</last_modification_time>
</signal>
<label>Edit</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
<widget>
<class>GtkButton</class>
<name>button5</name>
<can_default>True</can_default>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>on_delete_clicked</handler>
<last_modification_time>Thu, 04 Apr 2002 02:05:15 GMT</last_modification_time>
</signal>
<label>Delete</label>
<relief>GTK_RELIEF_NORMAL</relief>
</widget>
</widget>
</widget>
</widget>
</widget>
</GTK-Interface>