diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index fbb35cf84..af9faec1b 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,6 @@ +2006-04-26 Alex Roitman + * src/plugins/Check.py: Adapt to new family relation types. + 2006-04-26 Don Allingham * src/ViewManager.py: force uimanager updates * src/Bookmarks.py: force uimanager updates diff --git a/gramps2/src/plugins/Check.py b/gramps2/src/plugins/Check.py index 7e1c130c5..c5822fc9d 100644 --- a/gramps2/src/plugins/Check.py +++ b/gramps2/src/plugins/Check.py @@ -514,9 +514,9 @@ class CheckIntegrity: else: fgender = father.get_gender() mgender = mother.get_gender() - if rel_type != RelLib.Family.CIVIL_UNION: + if rel_type != RelLib.FamilyRelType.CIVIL_UNION: if fgender == mgender and fgender != RelLib.Person.UNKNOWN: - family.set_relationship(RelLib.Family.CIVIL_UNION) + family.set_relationship(RelLib.FamilyRelType.CIVIL_UNION) self.fam_rel.append(family_handle) self.db.commit_family(family,self.trans) elif fgender == RelLib.Person.FEMALE or mgender == RelLib.Person.MALE: @@ -525,7 +525,7 @@ class CheckIntegrity: self.fam_rel.append(family_handle) self.db.commit_family(family,self.trans) elif fgender != mgender: - family.set_relationship(RelLib.Family.UNKNOWN) + family.set_relationship(RelLib.FamilyRelType.UNKNOWN) self.fam_rel.append(family_handle) if fgender == RelLib.Person.FEMALE or mgender == RelLib.Person.MALE: family.set_father_handle(mother_handle) @@ -888,18 +888,18 @@ class Report(ManagedWindow.ManagedWindow): topDialog = gtk.glade.XML(glade_file,"summary","gramps") topDialog.get_widget("close").connect('clicked',self.close) - self.window = topDialog.get_widget("summary") + window = topDialog.get_widget("summary") textwindow = topDialog.get_widget("textwindow") textwindow.get_buffer().set_text(text) - Utils.set_titles(self.window, - topDialog.get_widget("title"), - _("Integrity Check Results")) + self.set_window(window, + topDialog.get_widget("title"), + _("Integrity Check Results")) self.show() def build_menu_names(self, obj): - return (_('Check and Repair'),_('Check and Repair')) + return (_('Check and Repair'),None) #------------------------------------------------------------------------ # diff --git a/gramps2/src/plugins/Merge.py b/gramps2/src/plugins/Merge.py index 3a3150b3a..6e9206352 100644 --- a/gramps2/src/plugins/Merge.py +++ b/gramps2/src/plugins/Merge.py @@ -1,7 +1,7 @@ # # Gramps - a GTK+/GNOME based genealogy program # -# Copyright (C) 2000-2005 Donald N. Allingham +# Copyright (C) 2000-2006 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 @@ -51,7 +51,6 @@ import ListModel import MergePeople import GrampsDisplay import ManagedWindow - from PluginUtils import Tool, register_tool #------------------------------------------------------------------------- @@ -84,12 +83,15 @@ def is_initial(name): # # #------------------------------------------------------------------------- -class Merge(Tool.Tool): +class Merge(Tool.Tool,ManagedWindow.ManagedWindow): def __init__(self, dbstate, uistate, options_class, name, callback=None): Tool.Tool.__init__(self, dbstate, options_class, name) - + ManagedWindow.ManagedWindow.__init__(self, uistate, [], + self.__class__) + self.dbstate = dbstate + self.uistate = uistate self.map = {} self.list = [] self.index = 0 @@ -127,29 +129,25 @@ class Merge(Tool.Tool): self.menu = top.get_widget("menu") self.menu.set_menu(my_menu) - self.window = top.get_widget('dialog') - Utils.set_titles(self.window, top.get_widget('title'), - _('Merge people')) + window = top.get_widget('dialog') + self.set_window(window, top.get_widget('title'),_('Merge people')) top.signal_autoconnect({ "on_merge_ok_clicked" : self.on_merge_ok_clicked, "destroy_passed_object" : self.close, "on_help_clicked" : self.on_help_clicked, - "on_delete_merge_event" : self.on_delete_event, + "on_delete_merge_event" : self.close, }) self.show() + def build_menu_names(self,obj): + return (_("Tool settings"),_("Find Duplicates tool")) + def on_help_clicked(self,obj): """Display the relevant portion of GRAMPS manual""" GrampsDisplay.help('tools-db') - def on_delete_event(self,obj,b): - pass - - def close(self,obj): - self.window.destroy() - def ancestors_of(self,p1_id,id_list): if (not p1_id) or (p1_id in id_list): return @@ -164,7 +162,6 @@ class Merge(Tool.Tool): def on_merge_ok_clicked(self,obj): threshold = self.menu.get_menu().get_active().get_data("v") self.use_soundex = int(self.soundex_obj.get_active()) - self.close() self.find_potentials(threshold) self.options.handler.options_dict['threshold'] = threshold @@ -178,7 +175,8 @@ class Merge(Tool.Tool): _("No matches found"), _("No potential duplicate people were found")) else: - self.show() + ShowMatches(self.dbstate,self.uistate,self.track, + self.list,self.map,self.update) def find_potentials(self,thresh): self.progress = Utils.ProgressMeter(_('Find duplicates'), @@ -245,98 +243,7 @@ class Merge(Tool.Tool): self.list.sort() self.length = len(self.list) self.progress.close() - self.dellist = {} - def show(self): - - top = gtk.glade.XML(self.glade_file,"mergelist","gramps") - self.window = top.get_widget("mergelist") - - Utils.set_titles(self.window, top.get_widget('title'), - _('Potential Merges')) - - self.mlist = top.get_widget("mlist") - top.signal_autoconnect({ - "destroy_passed_object" : self.close, - "on_do_merge_clicked" : self.on_do_merge_clicked, - "on_help_show_clicked" : self.on_help_clicked, - "on_delete_show_event" : self.on_delete_event, - }) - - mtitles = [(_('Rating'),3,75),(_('First Person'),1,200), - (_('Second Person'),2,200),('',-1,0)] - self.list = ListModel.ListModel(self.mlist,mtitles, - event_func=self.on_do_merge_clicked) - - self.redraw() - self.window.show() - - def redraw(self): - list = [] - for p1key in self.map.keys(): - if self.dellist.has_key(p1key): - continue - (p2key,c) = self.map[p1key] - if p1key == p2key: - continue - list.append((c,p1key,p2key)) - - self.list.clear() - for (c,p1key,p2key) in list: - c1 = "%5.2f" % c - c2 = "%5.2f" % (100-c) - p1 = self.db.get_person_from_handle(p1key) - p2 = self.db.get_person_from_handle(p2key) - if not p1 or not p2: - continue - pn1 = NameDisplay.displayer.display(p1) - pn2 = NameDisplay.displayer.display(p2) - self.list.add([c, pn1, pn2,c2],(p1key,p2key)) - - def on_do_merge_clicked(self,obj): - store,iter = self.list.selection.get_selected() - if not iter: - return - - (self.p1,self.p2) = self.list.get_object(iter) - pn1 = self.db.get_person_from_handle(self.p1) - pn2 = self.db.get_person_from_handle(self.p2) - - MergePeople.Compare(self.db,pn1,pn2,self.on_update) - - def on_update(self): - self.dellist[self.p2] = self.p1 - for key in self.dellist.keys(): - if self.dellist[key] == self.p2: - self.dellist[key] = self.p1 - self.update(None,None) - self.redraw() - - def update_and_destroy(self,obj): - self.update(1) - Utils.destroy_passed_object(obj) - - def list_reduce(self,list1,list2): - value = 0 - for name in list1: - for name2 in list2: - if is_initial(name) and name[0] == name2[0]: - value = value + 0.25 - break - if is_initial(name2) and name2[0] == name[0]: - value = value + 0.25 - break - if name == name2: - value = value + 0.5 - break - if name[0] == name2[0] and self.name_compare(name,name2): - value = value + 0.25 - break - if value == 0: - return -1 - else: - return min(value,1) - def gen_key(self,val): if self.use_soundex: try: @@ -346,6 +253,148 @@ class Merge(Tool.Tool): else: return val + def compare_people(self,p1,p2): + + name1 = p1.get_primary_name() + name2 = p2.get_primary_name() + + chance = self.name_match(name1,name2) + if chance == -1 : + return -1 + + birth1_ref = p1.get_birth_ref() + if birth1_ref: + birth1 = self.db.get_event_from_handle(birth1_ref.ref) + else: + birth1 = RelLib.Event() + + death1_ref = p1.get_death_ref() + if death1_ref: + death1 = self.db.get_event_from_handle(death1_ref.ref) + else: + death1 = RelLib.Event() + + birth2_ref = p2.get_birth_ref() + if birth2_ref: + birth2 = self.db.get_event_from_handle(birth2_ref.ref) + else: + birth2 = RelLib.Event() + + death2_ref = p2.get_death_ref() + if death2_ref: + death2 = self.db.get_event_from_handle(death2_ref.ref) + else: + death2 = RelLib.Event() + + value = self.date_match(birth1.get_date_object(), + birth2.get_date_object()) + if value == -1 : + return -1 + chance = chance + value + + value = self.date_match(death1.get_date_object(), + death2.get_date_object()) + if value == -1 : + return -1 + chance = chance + value + + value = self.place_match(birth1.get_place_handle(), + birth2.get_place_handle()) + if value == -1 : + return -1 + chance = chance + value + + value = self.place_match(death1.get_place_handle(), + death2.get_place_handle()) + if value == -1 : + return -1 + chance = chance + value + + ancestors = [] + self.ancestors_of(p1.get_handle(),ancestors) + if p2.get_handle() in ancestors: + return -1 + + ancestors = [] + self.ancestors_of(p2.get_handle(),ancestors) + if p1.get_handle() in ancestors: + return -1 + + f1_id = p1.get_main_parents_family_handle() + f2_id = p2.get_main_parents_family_handle() + + if f1_id and f2_id: + f1 = self.db.get_family_from_handle(f1_id) + f2 = self.db.get_family_from_handle(f2_id) + dad1_id = f1.get_father_handle() + if dad1_id: + dad1 = get_name_obj(self.db.get_person_from_handle(dad1_id)) + else: + dad1 = None + dad2_id = f2.get_father_handle() + if dad2_id: + dad2 = get_name_obj(self.db.get_person_from_handle(dad2_id)) + else: + dad2 = None + + value = self.name_match(dad1,dad2) + + if value == -1: + return -1 + + chance = chance + value + + mom1_id = f1.get_mother_handle() + if mom1_id: + mom1 = get_name_obj(self.db.get_person_from_handle(mom1_id)) + else: + mom1 = None + mom2_id = f2.get_mother_handle() + if mom2_id: + mom2 = get_name_obj(self.db.get_person_from_handle(mom2_id)) + else: + mom2 = None + + value = self.name_match(mom1,mom2) + if value == -1: + return -1 + + chance = chance + value + + for f1_id in p1.get_family_handle_list(): + f1 = self.db.get_family_from_handle(f1_id) + for f2_id in p2.get_family_handle_list(): + f2 = self.db.get_family_from_handle(f2_id) + if p1.get_gender() == RelLib.Person.FEMALE: + father1_id = f1.get_father_handle() + father2_id = f2.get_father_handle() + if father1_id and father2_id: + if father1_id == father2_id: + chance = chance + 1 + else: + father1 = self.db.get_person_from_handle(father1_id) + father2 = self.db.get_person_from_handle(father2_id) + fname1 = get_name_obj(father1) + fname2 = get_name_obj(father2) + value = self.name_match(fname1,fname2) + if value != -1: + chance = chance + value + else: + mother1_id = f1.get_mother_handle() + mother2_id = f2.get_mother_handle() + if mother1_id and mother2_id: + if mother1_id == mother2_id: + chance = chance + 1 + else: + mother1 = self.db.get_person_from_handle(mother1_id) + mother2 = self.db.get_person_from_handle(mother2_id) + mname1 = get_name_obj(mother1) + mname2 = get_name_obj(mother2) + value = self.name_match(mname1,mname2) + if value != -1: + chance = chance + value + return chance + def name_compare(self,s1,s2): if self.use_soundex: try: @@ -463,143 +512,115 @@ class Merge(Tool.Tool): else: return min(value,1) - def compare_people(self,p1,p2): - - name1 = p1.get_primary_name() - name2 = p2.get_primary_name() - - chance = self.name_match(name1,name2) - if chance == -1 : + def list_reduce(self,list1,list2): + value = 0 + for name in list1: + for name2 in list2: + if is_initial(name) and name[0] == name2[0]: + value = value + 0.25 + break + if is_initial(name2) and name2[0] == name[0]: + value = value + 0.25 + break + if name == name2: + value = value + 0.5 + break + if name[0] == name2[0] and self.name_compare(name,name2): + value = value + 0.25 + break + if value == 0: return -1 - - birth1_id = p1.get_birth_handle() - if birth1_id: - birth1 = self.db.get_event_from_handle(birth1_id) else: - birth1 = RelLib.Event() - - death1_id = p1.get_death_handle() - if death1_id: - death1 = self.db.get_event_from_handle(death1_id) - else: - death1 = RelLib.Event() - - birth2_id = p2.get_birth_handle() - if birth2_id: - birth2 = self.db.get_event_from_handle(birth2_id) - else: - birth2 = RelLib.Event() - - death2_id = p2.get_death_handle() - if death2_id: - death2 = self.db.get_event_from_handle(death2_id) - else: - death2 = RelLib.Event() - - value = self.date_match(birth1.get_date_object(),birth2.get_date_object()) - if value == -1 : - return -1 - chance = chance + value - - value = self.date_match(death1.get_date_object(),death2.get_date_object()) - if value == -1 : - return -1 - chance = chance + value - - value = self.place_match(birth1.get_place_handle(),birth2.get_place_handle()) - if value == -1 : - return -1 - chance = chance + value - - value = self.place_match(death1.get_place_handle(),death2.get_place_handle()) - if value == -1 : - return -1 - chance = chance + value - - ancestors = [] - self.ancestors_of(p1.get_handle(),ancestors) - if p2.get_handle() in ancestors: - return -1 - - ancestors = [] - self.ancestors_of(p2.get_handle(),ancestors) - if p1.get_handle() in ancestors: - return -1 + return min(value,1) - f1_id = p1.get_main_parents_family_handle() - f2_id = p2.get_main_parents_family_handle() - if f1_id and f2_id: - f1 = self.db.get_family_from_handle(f1_id) - f2 = self.db.get_family_from_handle(f2_id) - dad1_id = f1.get_father_handle() - if dad1_id: - dad1 = get_name_obj(self.db.get_person_from_handle(dad1_id)) - else: - dad1 = None - dad2_id = f2.get_father_handle() - if dad2_id: - dad2 = get_name_obj(self.db.get_person_from_handle(dad2_id)) - else: - dad2 = None - - value = self.name_match(dad1,dad2) - - if value == -1: - return -1 +class ShowMatches(ManagedWindow.ManagedWindow): - chance = chance + value - - mom1_id = f1.get_mother_handle() - if mom1_id: - mom1 = get_name_obj(self.db.get_person_from_handle(mom1_id)) - else: - mom1 = None - mom2_id = f2.get_mother_handle() - if mom2_id: - mom2 = get_name_obj(self.db.get_person_from_handle(mom2_id)) - else: - mom2 = None + def __init__(self,dbstate,uistate,track,the_list,the_map,callback): + ManagedWindow.ManagedWindow.__init__(self,uistate,track,self.__class__) - value = self.name_match(mom1,mom2) - if value == -1: - return -1 - - chance = chance + value + self.dellist = {} + self.list = the_list + self.map = the_map + self.length = len(self.list) + self.update = callback + self.db = dbstate.db + + base = os.path.dirname(__file__) + self.glade_file = "%s/%s" % (base,"merge.glade") + top = gtk.glade.XML(self.glade_file,"mergelist","gramps") + window = top.get_widget("mergelist") + self.set_window(window, top.get_widget('title'), + _('Potential Merges')) + + self.mlist = top.get_widget("mlist") + top.signal_autoconnect({ + "destroy_passed_object" : self.close, + "on_do_merge_clicked" : self.on_do_merge_clicked, + "on_help_show_clicked" : self.on_help_clicked, + "on_delete_show_event" : self.close, + }) - for f1_id in p1.get_family_handle_list(): - f1 = self.db.get_family_from_handle(f1_id) - for f2_id in p2.get_family_handle_list(): - f2 = self.db.get_family_from_handle(f2_id) - if p1.get_gender() == RelLib.Person.FEMALE: - father1_id = f1.get_father_handle() - father2_id = f2.get_father_handle() - if father1_id and father2_id: - if father1_id == father2_id: - chance = chance + 1 - else: - father1 = self.db.get_person_from_handle(father1_id) - father2 = self.db.get_person_from_handle(father2_id) - fname1 = get_name_obj(father1) - fname2 = get_name_obj(father2) - value = self.name_match(fname1,fname2) - if value != -1: - chance = chance + value - else: - mother1_id = f1.get_mother_handle() - mother2_id = f2.get_mother_handle() - if mother1_id and mother2_id: - if mother1_id == mother2_id: - chance = chance + 1 - else: - mother1 = self.db.get_person_from_handle(mother1_id) - mother2 = self.db.get_person_from_handle(mother2_id) - mname1 = get_name_obj(mother1) - mname2 = get_name_obj(mother2) - value = self.name_match(mname1,mname2) - if value != -1: - chance = chance + value - return chance + mtitles = [(_('Rating'),3,75),(_('First Person'),1,200), + (_('Second Person'),2,200),('',-1,0)] + self.list = ListModel.ListModel(self.mlist,mtitles, + event_func=self.on_do_merge_clicked) + + self.redraw() + self.show() + + def build_menu_names(self,obj): + return (_("Merge candidates"),None) + + def on_help_clicked(self,obj): + """Display the relevant portion of GRAMPS manual""" + GrampsDisplay.help('tools-db') + + def redraw(self): + list = [] + for p1key in self.map.keys(): + if self.dellist.has_key(p1key): + continue + (p2key,c) = self.map[p1key] + if p1key == p2key: + continue + list.append((c,p1key,p2key)) + + self.list.clear() + for (c,p1key,p2key) in list: + c1 = "%5.2f" % c + c2 = "%5.2f" % (100-c) + p1 = self.db.get_person_from_handle(p1key) + p2 = self.db.get_person_from_handle(p2key) + if not p1 or not p2: + continue + pn1 = NameDisplay.displayer.display(p1) + pn2 = NameDisplay.displayer.display(p2) + self.list.add([c, pn1, pn2,c2],(p1key,p2key)) + + def on_do_merge_clicked(self,obj): + store,iter = self.list.selection.get_selected() + if not iter: + return + + (self.p1,self.p2) = self.list.get_object(iter) + pn1 = self.db.get_person_from_handle(self.p1) + pn2 = self.db.get_person_from_handle(self.p2) + + MergePeople.Compare(self.db,pn1,pn2,self.on_update) + + def on_update(self): + self.dellist[self.p2] = self.p1 + for key in self.dellist.keys(): + if self.dellist[key] == self.p2: + self.dellist[key] = self.p1 + self.update(None,None) + self.redraw() + + def update_and_destroy(self,obj): + self.update(1) + self.close() + #------------------------------------------------------------------------- #