diff --git a/gramps/src/EditPerson.py b/gramps/src/EditPerson.py index d82646880..56586ce5d 100644 --- a/gramps/src/EditPerson.py +++ b/gramps/src/EditPerson.py @@ -455,9 +455,9 @@ class EditPerson: def set_lds_seal(self,obj): self.seal_stat = obj.get_data("val") - def ev_drag_data_received(self,widget,context,x,y,selection_data,info,time): - if selection_data and selection_data.data: - exec 'data = %s' % selection_data.data + def ev_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data exec 'mytype = "%s"' % data[0] exec 'person = "%s"' % data[1] if person == self.person.getId() or mytype != 'pevent': @@ -474,17 +474,17 @@ class EditPerson: self.lists_changed = 1 self.redraw_event_list() - def ev_drag_data_get(self,widget, context, selection_data, info, time): + def ev_drag_data_get(self,widget, context, sel_data, info, time): ev = widget.get_row_data(widget.focus_row) bits_per = 8; # we're going to pass a string pickled = pickle.dumps(ev); data = str(('pevent',self.person.getId(),pickled)); - selection_data.set(selection_data.target, bits_per, data) + sel_data.set(sel_data.target, bits_per, data) - def url_drag_data_received(self,widget,context,x,y,selection_data,info,time): - if selection_data and selection_data.data: - exec 'data = %s' % selection_data.data + def url_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data exec 'mytype = "%s"' % data[0] exec 'person = "%s"' % data[1] if person == self.person.getId() or mytype != 'url': @@ -494,17 +494,17 @@ class EditPerson: self.lists_changed = 1 self.redraw_url_list() - def url_drag_data_get(self,widget, context, selection_data, info, time): + def url_drag_data_get(self,widget, context, sel_data, info, time): ev = widget.get_row_data(widget.focus_row) bits_per = 8; # we're going to pass a string pickled = pickle.dumps(ev); data = str(('url',self.person.getId(),pickled)); - selection_data.set(selection_data.target, bits_per, data) + sel_data.set(sel_data.target, bits_per, data) - def at_drag_data_received(self,widget,context,x,y,selection_data,info,time): - if selection_data and selection_data.data: - exec 'data = %s' % selection_data.data + def at_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data exec 'mytype = "%s"' % data[0] exec 'person = "%s"' % data[1] if person == self.person.getId() or mytype != 'pattr': @@ -518,17 +518,17 @@ class EditPerson: self.lists_changed = 1 self.redraw_attr_list() - def at_drag_data_get(self,widget, context, selection_data, info, time): + def at_drag_data_get(self,widget, context, sel_data, info, time): ev = widget.get_row_data(widget.focus_row) bits_per = 8; # we're going to pass a string pickled = pickle.dumps(ev); data = str(('pattr',self.person.getId(),pickled)); - selection_data.set(selection_data.target, bits_per, data) + sel_data.set(sel_data.target, bits_per, data) - def ad_drag_data_received(self,widget,context,x,y,selection_data,info,time): - if selection_data and selection_data.data: - exec 'data = %s' % selection_data.data + def ad_drag_data_received(self,widget,context,x,y,sel_data,info,time): + if sel_data and sel_data.data: + exec 'data = %s' % sel_data.data exec 'mytype = "%s"' % data[0] exec 'person = "%s"' % data[1] if person == self.person.getId() or mytype != 'paddr': @@ -542,13 +542,13 @@ class EditPerson: self.lists_changed = 1 self.redraw_addr_list() - def ad_drag_data_get(self,widget, context, selection_data, info, time): + def ad_drag_data_get(self,widget, context, sel_data, info, time): ev = widget.get_row_data(widget.focus_row) bits_per = 8; # we're going to pass a string pickled = pickle.dumps(ev); data = str(('paddr',self.person.getId(),pickled)); - selection_data.set(selection_data.target, bits_per, data) + sel_data.set(sel_data.target, bits_per, data) def menu_changed(self,obj): self.ldsfam = obj.get_data("f") @@ -1012,8 +1012,8 @@ class EditPerson: item = gtk.GtkTearoffMenuItem() item.show() menu.append(item) - Utils.add_menuitem(menu,_("Make the selected name the preferred name"), - None,self.change_name) + msg = _("Make the selected name the preferred name") + Utils.add_menuitem(menu,msg,None,self.change_name) menu.popup(None,None,None,0,0) def on_aka_update_clicked(self,obj): @@ -1029,7 +1029,8 @@ class EditPerson: else: try: i = GdkImlib.Image(photo) - scale = float(const.picWidth)/float(max(i.rgb_height,i.rgb_width)) + ratio = float(max(i.rgb_height,i.rgb_width)) + scale = float(const.picWidth)/ratio x = int(scale*(i.rgb_width)) y = int(scale*(i.rgb_height)) i = i.clone_scaled_image(x,y) @@ -1177,9 +1178,10 @@ class EditPerson: Utils.modified() if error == 1: - msg = _("Changing the gender caused problems with marriage information.") - msg2 = _("Please check the person's marriages.") - GnomeErrorDialog("%s\n%s" % (msg,msg2)) + msg = _("Changing the gender caused problems " + "with marriage information.\nPlease check " + "the person's marriages.") + GnomeErrorDialog(msg) text = self.notes_field.get_chars(0,-1) if text != self.person.getNote(): @@ -1195,7 +1197,8 @@ class EditPerson: temple = "" ord = self.person.getLdsBaptism() place = self.get_place(self.ldsbapplace,1) - update_ord(self.person.setLdsBaptism,ord,date,temple,self.bap_stat,place) + update_ord(self.person.setLdsBaptism,ord,date, + temple,self.bap_stat,place) date = self.ldsend_date.get_text() temple = self.ldsend_temple.entry.get_text() @@ -1205,7 +1208,8 @@ class EditPerson: temple = "" ord = self.person.getLdsEndowment() place = self.get_place(self.ldsendowplace,1) - update_ord(self.person.setLdsEndowment,ord,date,temple,self.end_stat,place) + update_ord(self.person.setLdsEndowment,ord,date, + temple,self.end_stat,place) date = self.ldsseal_date.get_text() temple = self.ldsseal_temple.entry.get_text() @@ -1359,7 +1363,8 @@ class EditPerson: def write_primary_name(self): # initial values - self.get_widget("activepersonTitle").set_text(GrampsCfg.nameof(self.person)) + name = GrampsCfg.nameof(self.person) + self.get_widget("activepersonTitle").set_text(name) self.suffix.set_text(self.pname.getSuffix()) self.surname_field.set_text(self.pname.getSurname()) diff --git a/gramps/src/GenericFilter.py b/gramps/src/GenericFilter.py index fc20316ac..92dae4f2d 100644 --- a/gramps/src/GenericFilter.py +++ b/gramps/src/GenericFilter.py @@ -39,7 +39,7 @@ except: #------------------------------------------------------------------------- import types import os -from string import find,join +from string import find,join,strip,replace #------------------------------------------------------------------------- # @@ -48,6 +48,8 @@ from string import find,join #------------------------------------------------------------------------- from RelLib import * import Date +from intl import gettext +_ = gettext #------------------------------------------------------------------------- # @@ -82,6 +84,9 @@ class Rule: def values(self): return self.list + + def trans_name(self): + return _(self.name()) def name(self): return 'None' @@ -123,7 +128,7 @@ class Everyone(Rule): class HasIdOf(Rule): """Rule that checks for a person with a specific GID""" - labels = [ 'ID' ] + labels = [ _('ID') ] def name(self): return 'Has the Id' @@ -156,7 +161,7 @@ class IsDescendantOf(Rule): """Rule that checks for a person that is a descendant of a specified person""" - labels = ['ID'] + labels = [ _('ID') ] def name(self): return 'Is a descendant of' @@ -182,7 +187,7 @@ class IsDescendantOf(Rule): class IsAncestorOf(Rule): """Rule that checks for a person that is an ancestor of a specified person""" - labels = ['ID'] + labels = [ _('ID') ] def name(self): return 'Is an ancestor of' @@ -225,7 +230,7 @@ class IsMale(Rule): class HasEvent(Rule): """Rule that checks for a person with a particular value""" - labels = [ 'Event', 'Date', 'Place', 'Description' ] + labels = [ _('Personal Event'), _('Date'), _('Place'), _('Description') ] def __init__(self,list): Rule.__init__(self,list) @@ -236,19 +241,114 @@ class HasEvent(Rule): self.date = None def name(self): - return 'Has the event' + return 'Has the personal event' def apply(self,p): for event in p.getEventList(): + val = 1 if self.list[0] and event.getName() != self.list[0]: - return 0 + val = 0 if self.list[3] and find(event.getDescription(),self.list[3])==-1: - return 0 + val = 0 if self.date: - return date_cmp(self.date,event.getDateObj()) + if date_cmp(self.date,event.getDateObj()): + val = 0 if self.list[2] and find(p.getPlaceName(),self.list[2]) == -1: + val = 0 + if val == 1: + return 1 + return 0 + +#------------------------------------------------------------------------- +# +# HasFamilyEvent +# +#------------------------------------------------------------------------- +class HasFamilyEvent(Rule): + """Rule that checks for a person who has a relationship event + with a particular value""" + + labels = [ _('Family Event'), _('Date'), _('Place'), _('Description') ] + + def __init__(self,list): + Rule.__init__(self,list) + if self.list[0]: + self.date = Date.Date() + self.date.set(self.list[0]) + else: + self.date = None + + def name(self): + return 'Has the family event' + + def apply(self,p): + for f in p.getFamilyList(): + for event in f.getEventList(): + val = 1 + if self.list[0] and event.getName() != self.list[0]: + val = 0 + v = self.list[3] + if v and find(event.getDescription(),v)==-1: + val = 0 + if self.date: + if date_cmp(self.date,event.getDateObj()): + val = 0 + if self.list[2] and find(p.getPlaceName(),self.list[2]) == -1: + val = 0 + if val == 1: + return 1 + return 0 + +#------------------------------------------------------------------------- +# +# HasRelationship +# +#------------------------------------------------------------------------- +class HasRelationship(Rule): + """Rule that checks for a person who has a particular relationship""" + + labels = [ _('Number of Relationships'), + _('Relationship Type'), + _('Number of Children') ] + + def name(self): + return 'Has the relationships' + + def apply(self,p): + rel_type = 0 + cnt = 0 + num_rel = len(p.getFamilyList()) + + # count children and look for a relationship type match + for f in p.getFamilyList(): + cnt = cnt + len(f.getChildList()) + if self.list[1] and f.getRelationship() == self.list[1]: + rel_type = 1 + rval = 0 + + # if number of relations specified + if self.list[0]: + try: + v = int(self.list[0]) + except: return 0 - return 1 + if v != num_rel: + return 0 + + # number of childred + if self.list[2]: + try: + v = int(self.list[2]) + except: + return 0 + if v != cnt: + return 0 + + # relation + if self.list[1]: + return rel_type == 1 + else: + return 1 #------------------------------------------------------------------------- # @@ -258,7 +358,7 @@ class HasEvent(Rule): class HasBirth(Rule): """Rule that checks for a person with a birth of a particular value""" - labels = [ 'Date', 'Place', 'Description' ] + labels = [ _('Date'), _('Place'), _('Description') ] def __init__(self,list): Rule.__init__(self,list) @@ -276,7 +376,8 @@ class HasBirth(Rule): if self.list[2] and find(event.getDescription(),self.list[2])==-1: return 0 if self.date: - return date_cmp(self.date,event.getDateObj()) + if date_cmp(self.date,event.getDateObj()) == 0: + return 0 if self.list[1] and find(p.getPlaceName(),self.list[1]) == -1: return 0 return 1 @@ -289,7 +390,7 @@ class HasBirth(Rule): class HasDeath(Rule): """Rule that checks for a person with a death of a particular value""" - labels = [ 'Date', 'Place', 'Description' ] + labels = [ _('Date'), _('Place'), _('Description') ] def __init__(self,list): Rule.__init__(self,list) @@ -307,7 +408,8 @@ class HasDeath(Rule): if self.list[2] and find(event.getDescription(),self.list[2])==-1: return 0 if self.date: - date_cmp(self.date,event.getDateObj()) + if date_cmp(self.date,event.getDateObj()) == 0: + return 0 if self.list[1] and find(p.getPlaceName(),self.list[1]) == -1: return 0 return 1 @@ -318,12 +420,12 @@ class HasDeath(Rule): # #------------------------------------------------------------------------- class HasAttribute(Rule): - """Rule that checks for a person with a particular attribute""" + """Rule that checks for a person with a particular personal attribute""" - labels = [ 'Attribute', 'Value' ] + labels = [ _('Personal Attribute'), _('Value') ] def name(self): - return 'Has the attribute' + return 'Has the personal attribute' def apply(self,p): for event in p.getAttributes(): @@ -333,6 +435,31 @@ class HasAttribute(Rule): return 0 return 1 +#------------------------------------------------------------------------- +# +# HasFamilyAttribute +# +#------------------------------------------------------------------------- +class HasFamilyAttribute(Rule): + """Rule that checks for a person with a particular family attribute""" + + labels = [ _('Family Attribute'), _('Value') ] + + def name(self): + return 'Has the family attribute' + + def apply(self,p): + for f in p.getFamilyList(): + for event in f.getAttributes(): + val = 1 + if self.list[0] and event.getType() != self.list[0]: + val = 0 + if self.list[1] and find(event.getValue(),self.list[1])==-1: + val = 0 + if val == 1: + return 1 + return 0 + #------------------------------------------------------------------------- # # HasNameOf @@ -341,7 +468,7 @@ class HasAttribute(Rule): class HasNameOf(Rule): """Rule that checks for full or partial name matches""" - labels = ['Given Name','Surname','Suffix','Title'] + labels = [_('Given Name'),_('Surname'),_('Suffix'),_('Title')] def name(self): return 'Has a name' @@ -352,15 +479,18 @@ class HasNameOf(Rule): self.s = self.list[2] self.t = self.list[3] for name in [p.getPrimaryName()] + p.getAlternateNames(): + val = 1 if self.f and find(name.getFirstName(),self.f) == -1: - return 0 + val = 0 if self.l and find(name.getSurname(),self.l) == -1: - return 0 + val = 0 if self.s and find(name.getSuffix(),self.s) == -1: - return 0 + val = 0 if self.t and find(name.getTitle(),self.t) == -1: - return 0 - return 1 + val = 0 + if val == 1: + return 1 + return 0 #------------------------------------------------------------------------- # @@ -417,17 +547,20 @@ class GenericFilter: # #------------------------------------------------------------------------- tasks = { - "Everyone" : Everyone, - "Has the Id" : HasIdOf, - "Has a name" : HasNameOf, - "Has the death" : HasDeath, - "Has the birth" : HasBirth, - "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, + _("Everyone") : Everyone, + _("Has the Id") : HasIdOf, + _("Has a name") : HasNameOf, + _("Has the relationships") : HasRelationship, + _("Has the death") : HasDeath, + _("Has the birth") : HasBirth, + _("Is the descendant of") : IsDescendantOf, + _("Is an ancestor of") : IsAncestorOf, + _("Is a female") : IsFemale, + _("Is a male") : IsMale, + _("Has the personal event") : HasEvent, + _("Has the family event") : HasFamilyEvent, + _("Has the personal attribute") : HasAttribute, + _("Has the family attribute") : HasFamilyAttribute, } #------------------------------------------------------------------------- @@ -457,6 +590,13 @@ class GenericFilterList: except (IOError,OSError,SAXParseException): pass + def fix(self,line): + l = strip(line) + l = replace(l,'&','&') + l = replace(l,'>','>') + l = replace(l,'<','<') + return replace(l,'"','"') + def save(self): try: f = open(self.file,'w') @@ -466,15 +606,15 @@ class GenericFilterList: f.write("\n") f.write('\n') for i in self.filter_list: - f.write(' \n') for rule in i.get_rules(): - f.write(' \n' % rule.name()) + f.write(' \n' % self.fix(rule.name())) for v in rule.values(): - f.write(' \n' % v) + f.write(' \n' % self.fix(v)) f.write(' \n') f.write(' \n') f.write('\n') diff --git a/gramps/src/RelLib.py b/gramps/src/RelLib.py index e2c4dc3c1..37086f6df 100644 --- a/gramps/src/RelLib.py +++ b/gramps/src/RelLib.py @@ -872,7 +872,6 @@ class Url: if self.desc != other.desc: return 0 return 1 - class Person: """Represents an individual person in the gramps database""" diff --git a/gramps/src/Report.py b/gramps/src/Report.py index db7b6bf0a..425082c34 100644 --- a/gramps/src/Report.py +++ b/gramps/src/Report.py @@ -25,8 +25,10 @@ import const import os import string import Utils -import intl import Plugins +import GenericFilter + +import intl _ = intl.gettext @@ -258,11 +260,11 @@ class ReportDialog: is the name of menu item to pre-select.""" return (None, None) - def get_report_filter_strings(self): + def get_report_filters(self): """Return the data used to fill out the 'filter' combo box in the report options box. The return value is the list of strings to be inserted into the pulldown.""" - return None + return [] def get_report_generations(self): """Return the default number of generations to start the @@ -624,12 +626,14 @@ class ReportDialog: self.template_combo.entry.set_editable(0) self.template_combo.entry.connect('changed',self.html_file_enable) - table.attach(self.template_combo,1,2,0,1,FILL|EXPAND,FILL|EXPAND,pad,pad) - - table.attach(GtkLabel(_("User Template")),0,1,1,2,FILL,FILL,pad,pad) + table.attach(self.template_combo,1,2,0,1, + FILL|EXPAND,FILL|EXPAND,pad,pad) + table.attach(GtkLabel(_("User Template")),0,1,1,2, + FILL,FILL,pad,pad) self.html_fileentry = GnomeFileEntry(_("HTML Template"),_("Choose File")) self.html_fileentry.set_sensitive(0) - table.attach(self.html_fileentry,1,2,1,2,FILL|EXPAND,FILL|EXPAND,pad,pad) + table.attach(self.html_fileentry,1,2,1,2, + FILL|EXPAND,FILL|EXPAND,pad,pad) def setup_report_options_frame(self): """Set up the report options frame of the dialog. This @@ -640,7 +644,7 @@ class ReportDialog: (but not all) dialog boxes.""" (use_gen, use_break) = self.get_report_generations() - filter_strings = self.get_report_filter_strings() + local_filter = self.get_report_filters() (em_label, extra_map, preset, em_tip) = self.get_report_extra_menu_info() (et_label, string, et_tip) = self.get_report_extra_textbox_info() @@ -650,7 +654,7 @@ class ReportDialog: max_rows = max_rows + 1 if use_break: max_rows = max_rows + 1 - if filter_strings: + if len(local_filter): max_rows = max_rows + 1 if extra_map: max_rows = max_rows + 1 @@ -669,14 +673,24 @@ class ReportDialog: frame.add(table) pad = ReportDialog.border_pad - if filter_strings: - self.filter_combo = GtkCombo() + if len(local_filter): + myMenu = GtkMenu() + self.filter_combo = GtkOptionMenu() l = GtkLabel(_("Filter")) l.set_alignment(1.0,0.5) table.attach(l,0,1,row,row+1,FILL,FILL,pad,pad) - table.attach(self.filter_combo,1,2,row,row+1,xpadding=pad,ypadding=pad) - filter_strings.sort() - self.filter_combo.set_popdown_strings(filter_strings) + table.attach(self.filter_combo,1,2,row,row+1, + xpadding=pad,ypadding=pad) + + flist = GenericFilter.GenericFilterList(const.custom_filters) + flist.load() + for f in local_filter + flist.get_filters(): + menuitem = gtk.GtkMenuItem(_(f.get_name())) + myMenu.append(menuitem) + menuitem.set_data("filter",f) + menuitem.show() + self.filter_combo.set_menu(myMenu) + self.filter_menu = myMenu row = row + 1 # Set up the generations spin and page break checkbox @@ -689,12 +703,15 @@ class ReportDialog: l = GtkLabel(_("Generations")) l.set_alignment(1.0,0.5) table.attach(l,0,1,row,row+1,FILL,FILL,pad,pad) - table.attach(self.generations_spinbox,1,2,row,row+1,xpadding=pad,ypadding=pad) + table.attach(self.generations_spinbox,1,2,row,row+1, + xpadding=pad,ypadding=pad) row = row + 1 if use_break: - self.pagebreak_checkbox = GtkCheckButton(_("Page break between generations")) - table.attach(self.pagebreak_checkbox,1,2,row,row+1,xpadding=pad,ypadding=pad) + msg = _("Page break between generations") + self.pagebreak_checkbox = GtkCheckButton(msg) + table.attach(self.pagebreak_checkbox,1,2,row,row+1, + xpadding=pad,ypadding=pad) row = row + 1 # Now the "extra" option menu @@ -706,8 +723,10 @@ class ReportDialog: self.extra_menu.set_menu(myMenu) self.extra_menu.set_sensitive(len(extra_map) > 1) self.add_tooltip(self.extra_menu,em_tip) - table.attach(self.extra_menu_label,0,1,row,row+1,FILL,FILL,pad,pad) - table.attach(self.extra_menu,1,2,row,row+1,xpadding=pad,ypadding=pad) + table.attach(self.extra_menu_label,0,1,row,row+1, + FILL,FILL,pad,pad) + table.attach(self.extra_menu,1,2,row,row+1, + xpadding=pad,ypadding=pad) row = row + 1 # Now the "extra" text box @@ -746,12 +765,14 @@ class ReportDialog: row = 0 for (text,widget) in list: if text == None: - table.attach(widget,0,2,row,row+1,xpadding=pad,ypadding=pad) + table.attach(widget,0,2,row,row+1, + xpadding=pad,ypadding=pad) else: text_widget = GtkLabel(text) text_widget.set_alignment(1.0,0) table.attach(text_widget,0,1,row,row+1,FILL,FILL,pad,pad) - table.attach(widget,1,2,row,row+1,xpadding=pad,ypadding=pad) + table.attach(widget,1,2,row,row+1, + xpadding=pad,ypadding=pad) row = row + 1 #------------------------------------------------------------------------ @@ -832,9 +853,9 @@ class ReportDialog: self.pg_brk = 0 if self.filter_combo: - self.filter = self.filter_combo.entry.get_text() + self.filter = self.filter_menu.get_active().get_data("filter") else: - self.filter = "" + self.filter = None if self.extra_menu: self.report_menu = self.extra_menu.get_menu().get_active().get_data("d") diff --git a/gramps/src/const.py b/gramps/src/const.py index e19940a7c..34a190faa 100644 --- a/gramps/src/const.py +++ b/gramps/src/const.py @@ -91,10 +91,12 @@ startup = 1 # #------------------------------------------------------------------------- progName = "gramps" -version = "0.7.3-snap20020330" +version = "0.7.3-snap20020406" copyright = "© 2001 Donald N. Allingham" authors = ["Donald N. Allingham", "David Hampton","Donald A. Peterson"] -comments = _("GRAMPS (Genealogical Research and Analysis Management Programming System) is a personal genealogy program.") +comments = _("GRAMPS (Genealogical Research and Analysis " + "Management Programming System) is a personal " + "genealogy program.") #------------------------------------------------------------------------- # diff --git a/gramps/src/docgen/HtmlDoc.py b/gramps/src/docgen/HtmlDoc.py index eb5ba408c..396f082a1 100644 --- a/gramps/src/docgen/HtmlDoc.py +++ b/gramps/src/docgen/HtmlDoc.py @@ -45,7 +45,7 @@ _top = [ ' \n', ' \n', '