From b0d3ab87aa56c86ed3610d6038bf67b79bf1eb3c Mon Sep 17 00:00:00 2001 From: Don Allingham Date: Sat, 26 Mar 2005 15:27:39 +0000 Subject: [PATCH] * src/EventEdit.py: Display error message if event type not specified. * src/gramps_main.py: fix merge callback svn: r4240 --- ChangeLog | 4 + src/MergeData.py | 1140 ++++++++++++++++++++++++++++++++++------------ src/const.py.in | 1 + 3 files changed, 845 insertions(+), 300 deletions(-) diff --git a/ChangeLog b/ChangeLog index b744b6a2c..9719820fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,10 @@ * src/DdTargets.py: added targets for FAMILY_EVENT, FAMILY_ATTRIBUTE, CHILD and SPOUSE +2005-03-24 Don Allingham + * src/EventEdit.py: Display error message if event type not specified. + * src/gramps_main.py: fix merge callback + 2005-03-24 Alex Roitman * src/RelLib.py (Witness.__init__): Typo. * src/plugins/Check.py (cleanup_missing_photos): Use new mediaref diff --git a/src/MergeData.py b/src/MergeData.py index a09a01918..c2bd0beb6 100644 --- a/src/MergeData.py +++ b/src/MergeData.py @@ -32,7 +32,9 @@ import string # GNOME # #------------------------------------------------------------------------- -import gtk.glade +import gtk +import gnome +from gnome.ui import Druid, DruidPageEdge, DruidPageStandard #------------------------------------------------------------------------- # @@ -60,148 +62,648 @@ class MergePeople: self.p2 = person2 self.update = update self.ep_update = ep_update + self.parent = parent - self.glade = gtk.glade.XML(const.mergeFile,"merge","gramps") - self.top = self.glade.get_widget("merge") + self.need_birth = self.p1.get_birth_handle() and self.p2.get_birth_handle() + self.need_death = self.p1.get_death_handle() and self.p2.get_death_handle() + self.need_spouse = len(self.p1.get_family_handle_list()) + \ + len(self.p2.get_family_handle_list()) > 1 - Utils.set_titles(self.top,self.glade.get_widget('title'), - _('Merge Places'), _('Select the title for the merged place')) + self.need_parents = len(self.p1.get_parent_family_handle_list()) + \ + len(self.p2.get_parent_family_handle_list()) > 1 + self.build_interface() + + def build_interface(self): + + self.confirm_label = gtk.Label() + self.extra_pages = [] + + self.w = gtk.Window() + + self.fg_color = gtk.gdk.color_parse('#7d684a') + self.bg_color = gtk.gdk.color_parse('#e1dbc5') + self.logo = gtk.gdk.pixbuf_new_from_file("%s/gramps.png" % const.rootDir) + self.splash = gtk.gdk.pixbuf_new_from_file("%s/splash.jpg" % const.rootDir) + + self.d = Druid() + self.w.add(self.d) + self.w.set_title(_('GRAMPS - Merge People')) + self.d.add(self.build_info_page()) + self.d.add(self.build_name_page()) + self.d.add(self.build_id_page()) + self.last_page = self.build_last_page() + self.d.add(self.last_page) + + self.d.set_show_help(True) + self.d.connect('cancel',self.close) + #self.d.connect('help',self.help) + self.w.connect("destroy_event",self.close) + self.w.show_all() + + def close(self,obj,obj2=None): + """ + Close and delete handler. + """ + self.w.destroy() + + def build_last_page(self): + """ + Build the last druid page. The actual text will be added after the + save is performed and the success status us known. + """ + p = DruidPageEdge(1) + p.set_title_color(self.fg_color) + p.set_bg_color(self.bg_color) + p.set_logo(self.logo) + p.set_watermark(self.splash) + p.set_text(_('Pressing APPLY will merge the two selected people ' + 'into a single person. If you do not wish to do this, ' + 'press CANCEL')) + p.connect('finish',self.close) + return p + + def build_name_page(self): + """ + Build a page with the table of format radio buttons and + their descriptions. + """ + self.format_buttons = [] + + p = DruidPageStandard() + p.set_title(_('Select primary name')) + p.set_title_foreground(self.fg_color) + p.set_background(self.bg_color) + p.set_logo(self.logo) + + box = gtk.VBox() + box.set_spacing(12) + p.append_item("",box,"") + + fname = NameDisplay.displayer.display(self.p1) + mname = NameDisplay.displayer.display(self.p2) + + self.name1 = gtk.RadioButton(None,fname) + self.name2 = gtk.RadioButton(self.name1,mname) + self.altnames = gtk.CheckButton(_('Keep unselected name as an alternate name')) - self.altname = self.glade.get_widget("altname") - self.altbirth = self.glade.get_widget("altbirth") - self.altdeath = self.glade.get_widget("altdeath") + table = gtk.Table(6,2) + table.set_row_spacings(6) + table.set_col_spacings(6) - self.glade.signal_autoconnect({ - "on_merge_clicked" : self.on_merge_clicked, - "on_next_clicked" : self.on_merge_edit_clicked, - "destroy_passed_object" : Utils.destroy_passed_object, - }) + label = gtk.Label('%s' % _('Primary name')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,0,1,xoptions=gtk.EXPAND|gtk.FILL) - fname = NameDisplay.displayer.display(person1) - mname = NameDisplay.displayer.display(person2) + label = gtk.Label('%s' % _('Options')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,3,4,xoptions=gtk.EXPAND|gtk.FILL) - Utils.set_titles(self.top, self.glade.get_widget('title'), - _("Merge %s and %s") % (fname,mname), - _("Merge people")) - - f1_handle = person1.get_main_parents_family_handle() - f2_handle = person2.get_main_parents_family_handle() + table.attach(self.name1,1,2,1,2) + table.attach(self.name2,1,2,2,3) + table.attach(self.altnames,1,2,4,5) - name1 = NameDisplay.displayer.display(person1) - death1_handle = person1.get_death_handle() - if death1_handle: - death1 = death1_handle.get_date() - dplace1 = self.place_name(death1_handle) - else: - death1 = "" - dplace1 = "" - birth1_handle = person1.get_birth_handle() - if birth1_handle: - birth1 = birth1_handle.get_date() - bplace1 = self.place_name(birth1_handle) - else: - birth1 = "" - bplace1 = "" - - name2 = NameDisplay.displayer.display(person2) - death2_handle = person2.get_death_handle() - if death2_handle: - death2 = death2_handle.get_date() - dplace2 = self.place_name(death2_handle) - else: - death2 = "" - dplace2 = "" - birth2_handle = person2.get_birth_handle() - if birth2_handle: - birth2 = birth2_handle.get_date() - bplace2 = self.place_name(birth2_handle) - else: - birth2 = "" - bplace2 = "" + box.add(table) + box.show_all() + return p - if f2_handle and not f1_handle: - self.glade.get_widget("bfather2").set_active(1) - else: - self.glade.get_widget("bfather1").set_active(1) + def build_id_page(self): + """ + Build a page with the table of format radio buttons and + their descriptions. + """ + p = DruidPageStandard() + p.set_title(_('Select GRAMPS ID')) + p.set_title_foreground(self.fg_color) + p.set_background(self.bg_color) + p.set_logo(self.logo) + + box = gtk.VBox() + box.set_spacing(12) + p.append_item("",box,"") + + self.id1 = gtk.RadioButton(None,self.p1.get_gramps_id()) + self.id2 = gtk.RadioButton(self.id1,self.p2.get_gramps_id()) + self.keepid = gtk.CheckButton(_('Keep old ID as an Attribute')) + + table = gtk.Table(6,2) + table.set_row_spacings(6) + table.set_col_spacings(6) + + label = gtk.Label('%s' % _('GRAMPS ID')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,0,1,xoptions=gtk.EXPAND|gtk.FILL) + + label = gtk.Label('%s' % _('Options')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,3,4,xoptions=gtk.EXPAND|gtk.FILL) + + table.attach(self.id1,1,2,1,2) + table.attach(self.id2,1,2,2,3) + table.attach(self.keepid,1,2,4,5) + + box.add(table) + box.show_all() + if self.need_birth: + print "birth" + p.connect('next',self.build_birth_page) + elif self.need_death: + print "death" + p.connect('next',self.build_death_page) + elif self.need_parents: + print "parents" + p.connect('next',self.build_parents_page) + elif self.need_spouse: + print "spouse" + p.connect('next',self.build_spouse_page) + return p + + def build_birth_page(self,obj1,obj2): + """ + Build a page with the table of format radio buttons and + their descriptions. + """ + p = DruidPageStandard() + p.set_title(_('Select Birth Event')) + p.set_title_foreground(self.fg_color) + p.set_background(self.bg_color) + p.set_logo(self.logo) + + box = gtk.VBox() + box.set_spacing(12) + p.append_item("",box,"") + + (birth1,bplace1) = self.get_event_info(self.p1, + self.p1.get_birth_handle()) + (birth2,bplace2) = self.get_event_info(self.p2, + self.p2.get_birth_handle()) + bstr1 = ", ".join([birth1,bplace1]) + bstr2 = ", ".join([birth2,bplace2]) + + self.birth1 = gtk.RadioButton(None,bstr1) + self.birth2 = gtk.RadioButton(self.birth1,bstr2) + self.keepbirth = gtk.CheckButton(_('Add unselected birth event as an Alternate Birth event')) + + table = gtk.Table(6,2) + table.set_row_spacings(6) + table.set_col_spacings(6) + + label = gtk.Label('%s' % _('Birth Event')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,0,1,xoptions=gtk.EXPAND|gtk.FILL) + + label = gtk.Label('%s' % _('Options')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,3,4,xoptions=gtk.EXPAND|gtk.FILL) + + table.attach(self.birth1,1,2,1,2) + table.attach(self.birth2,1,2,2,3) + table.attach(self.keepbirth,1,2,4,5) + + box.add(table) + box.show_all() + if self.need_death: + p.connect('next',self.build_death_page) + elif self.need_parents: + p.connect('next',self.build_parents_page) + elif self.need_spouse: + p.connect('next',self.build_spouse_page) + return p + + def build_death_page(self,obj1,obj2): + """ + Build a page with the table of format radio buttons and + their descriptions. + """ + p = DruidPageStandard() + p.set_title(_('Select Death Event')) + p.set_title_foreground(self.fg_color) + p.set_background(self.bg_color) + p.set_logo(self.logo) + + box = gtk.VBox() + box.set_spacing(12) + p.append_item("",box,"") + + (birth1,bplace1) = self.get_event_info(self.p1, + self.p1.get_death_handle()) + (birth2,bplace2) = self.get_event_info(self.p2, + self.p2.get_death_handle()) + bstr1 = ", ".join([birth1,bplace1]) + bstr2 = ", ".join([birth2,bplace2]) + + self.death1 = gtk.RadioButton(None,bstr1) + self.death2 = gtk.RadioButton(self.death1,bstr2) + self.keepdeath = gtk.CheckButton(_('Add unselected death event as an Alternate Death event')) + + table = gtk.Table(6,2) + table.set_row_spacings(6) + table.set_col_spacings(6) + + label = gtk.Label('%s' % _('Death Event')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,0,1,xoptions=gtk.EXPAND|gtk.FILL) + + label = gtk.Label('%s' % _('Options')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,3,4,xoptions=gtk.EXPAND|gtk.FILL) + + table.attach(self.death1,1,2,1,2) + table.attach(self.death2,1,2,2,3) + table.attach(self.keepdeath,1,2,4,5) + + box.add(table) + box.show_all() + if self.need_parents: + p.connect('next',self.build_parents_page) + elif self.need_spouse: + p.connect('next',self.build_spouse_page) + return p + + def build_spouse_page(self,obj1,obj2): + """ + Build a page with the table of format radio buttons and + their descriptions. + """ + p = DruidPageStandard() + p.set_title(_('Select Spouses')) + p.set_title_foreground(self.fg_color) + p.set_background(self.bg_color) + p.set_logo(self.logo) + + box = gtk.VBox() + box.set_spacing(12) + p.append_item("",box,"") + + f1_list = self.p1.get_family_handle_list() + f2_list = self.p2.get_family_handle_list() + + if len(f1_list) > 0 and len(f2_list) > 0: + import ReportUtils + + f1 = self.db.get_family_from_handle(f1_list[0]) + f2 = self.db.get_family_from_handle(f2_list[0]) - if f1_handle: - f1 = self.db.get_family_from_handle(f1_handle) - father1 = name_of(self.db.get_person_from_handle(f1.get_father_handle())) - mother1 = name_of(self.db.get_person_from_handle(f1.get_mother_handle())) - else: - father1 = "" - mother1 = "" + sp1_id = ReportUtils.find_spouse(self.p1,f1) + sp2_id = ReportUtils.find_spouse(self.p2,f2) - if f2_handle: - f2 = self.db.get_family_from_handle(f2_handle) - father2 = name_of(self.db.get_person_from_handle(f2.get_father_handle())) - mother2 = name_of(self.db.get_person_from_handle(f2.get_mother_handle())) - else: - father2 = "" - mother2 = "" + sp1 = self.db.get_person_from_handle(sp1_id) + sp2 = self.db.get_person_from_handle(sp2_id) - self.set_field(self.glade.get_widget("id1_text"),person1.get_gramps_id()) - self.set_field(self.glade.get_widget("id2_text"),person2.get_gramps_id()) - self.set_field(self.glade.get_widget("name1_text"),name1) - self.set_field(self.glade.get_widget("name2_text"),name2) + bstr1 = NameDisplay.displayer.display(sp1) + bstr2 = NameDisplay.displayer.display(sp2) - self.bname1 = self.glade.get_widget("bname1") - self.bname1.set_active(1) - - self.set_field(self.glade.get_widget("birth1_text"),birth1) - self.set_field(self.glade.get_widget("birth2_text"),birth2) - self.set_field(self.glade.get_widget("bplace1_text"),bplace1) - self.set_field(self.glade.get_widget("bplace2_text"),bplace2) - - if ((not birth1 and not bplace1) and (birth2 or bplace2) or - (not birth1 or not bplace1) and (birth2 and bplace2)): - self.glade.get_widget('bbirth2').set_active(1) - else: - self.glade.get_widget('bbirth1').set_active(1) - - if ((not death1 and not dplace1) and (death2 or dplace2) or - (not death1 or not dplace1) and (death2 and dplace2)): - self.glade.get_widget('death2').set_active(1) - else: - self.glade.get_widget('death1').set_active(1) - - self.set_field(self.glade.get_widget("death1_text"),death1) - self.set_field(self.glade.get_widget("dplace1_text"),dplace1) - self.set_field(self.glade.get_widget("death2_text"),death2) - self.set_field(self.glade.get_widget("dplace2_text"),dplace2) - - self.set_field(self.glade.get_widget("father1"),father1) - self.set_field(self.glade.get_widget("father2"),father2) - self.set_field(self.glade.get_widget("mother1"),mother1) - self.set_field(self.glade.get_widget("mother2"),mother2) - - sp1_list = [('-',0,100)] - self.sp1 = ListModel.ListModel(self.glade.get_widget('spouse1'),sp1_list) - self.sp2 = ListModel.ListModel(self.glade.get_widget('spouse2'),sp1_list) + self.spouse1 = gtk.RadioButton(None,bstr1) + self.spouse2 = gtk.RadioButton(self.spouse1,bstr2) + self.keepspouse = gtk.CheckButton(_('Keep unselected spouse')) - self.build_spouse_list(person1,self.sp1) - self.build_spouse_list(person2,self.sp2) + table = gtk.Table(8,2) + table.set_row_spacings(6) + table.set_col_spacings(6) - if name1 != name2: - self.altname.set_sensitive(1) - self.altname.set_active(1) - else: - self.altname.set_sensitive(0) - self.altname.set_active(0) + label = gtk.Label('%s' % _('Spouses')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,0,1,xoptions=gtk.EXPAND|gtk.FILL) - if birth1 and birth2 and birth1 != birth2: - self.altbirth.set_active(1) - if bplace1 and bplace2 or bplace1 != bplace2: - self.altbirth.set_active(1) - else: - self.altbirth.set_active(0) + label = gtk.Label('%s' % _('Options')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,3,4,xoptions=gtk.EXPAND|gtk.FILL) + + table.attach(self.spouse1,1,2,1,2) + table.attach(self.spouse2,1,2,2,3) + table.attach(self.keepspouse,1,2,4,5) - if death1 and death2 and death1 != death2: - self.altdeath.set_active(1) - if dplace1 and dplace2 or dplace1 != dplace2: - self.altdeath.set_active(1) + expand = [] + if len(f1_list) > 1: + expand += f1_list[1:] + if len(f2_list) > 1: + expand += f2_list[1:] + + if len(expand) > 0: + label = gtk.Label('%s' % + _('Select spouse relationships')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,6,7,xoptions=gtk.EXPAND|gtk.FILL) + + self.spouse_view = gtk.TreeView() + self.spouse_list = gtk.ListStore(bool,str,str) + self.spouse_view.set_model(self.spouse_list) + scroll = gtk.ScrolledWindow() + scroll.set_policy(gtk.POLICY_AUTOMATIC, + gtk.POLICY_AUTOMATIC) + scroll.add(self.parent_view) + table.attach(scroll,1,5,7,8) + + celltoggle = gtk.CellRendererToggle() + celltext = gtk.CellRendererText() + col0 = gtk.TreeViewColumn(_('Select'),celltoggle,active=0) + col1 = gtk.TreeViewColumn(_('Spouse'),celltext,text=1) + self.parent_view.append_column(col0) + self.parent_view.append_column(col1) + + self.parent_list.append(row=[True,'Joe Smith']) + box.add(table) + box.show_all() +# p.connect('next',self.build_options) + return p + + def build_parents_page(self,obj1,obj2): + """ + Build a page with the table of format radio buttons and + their descriptions. + """ + p = DruidPageStandard() + p.set_title(_('Select Parents')) + p.set_title_foreground(self.fg_color) + p.set_background(self.bg_color) + p.set_logo(self.logo) + + box = gtk.VBox() + box.set_spacing(12) + p.append_item("",box,"") + + f1_handle = self.p1.get_main_parents_family_handle() + f2_handle = self.p2.get_main_parents_family_handle() + + fname1 = "" + fname2 = "" + mname1 = "" + mname2 = "" + if f1_handle: + family1 = self.db.get_family_from_handle(f1_handle) + father1_handle = family1.get_father_handle() + if father1_handle: + father1 = self.db.get_person_from_handle(father1_handle) + fname1 = NameDisplay.displayer.display(father1) + mother1_handle = family1.get_mother_handle() + if mother1_handle: + mother1 = self.db.get_person_from_handle(mother1_handle) + mname1 = NameDisplay.displayer.display(mother1) + if f2_handle: + family2 = self.db.get_family_from_handle(f2_handle) + father2_handle = family2.get_father_handle() + if father2_handle: + father2 = self.db.get_person_from_handle(father2_handle) + fname2 = NameDisplay.displayer.display(father2) + mother2_handle = family2.get_mother_handle() + if mother2_handle: + mother2 = self.db.get_person_from_handle(mother2_handle) + mname2 = NameDisplay.displayer.display(mother2) + + f2 = self.db.get_family_from_handle(f1_handle) + + bstr1 = ", ".join([fname1,mname1]) + bstr2 = ", ".join([fname2,mname2]) + + self.family1 = gtk.RadioButton(None,bstr1) + self.family2 = gtk.RadioButton(self.family1,bstr2) + self.keepparents = gtk.CheckButton(_('Keep unselected parents in the parent list')) + + table = gtk.Table(8,2) + table.set_row_spacings(6) + table.set_col_spacings(6) + + label = gtk.Label('%s' % _('Parents')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,0,1,xoptions=gtk.EXPAND|gtk.FILL) + + label = gtk.Label('%s' % _('Options')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,3,4,xoptions=gtk.EXPAND|gtk.FILL) + + table.attach(self.family1,1,2,1,2) + table.attach(self.family2,1,2,2,3) + table.attach(self.keepparents,1,2,4,5) + + alt_parents = self.p1.get_parent_family_handle_list() + \ + self.p2.get_parent_family_handle_list() + + if len(alt_parents) > 0: + label = gtk.Label('%s' % + _('Select parent relationships')) + label.set_use_markup(True) + label.set_alignment(0.0,0.5) + table.attach(label,0,5,6,7,xoptions=gtk.EXPAND|gtk.FILL) + + self.parent_view = gtk.TreeView() + self.parent_list = gtk.ListStore(bool,str,str) + self.parent_view.set_model(self.parent_list) + scroll = gtk.ScrolledWindow() + scroll.set_policy(gtk.POLICY_AUTOMATIC, + gtk.POLICY_AUTOMATIC) + scroll.add(self.parent_view) + table.attach(scroll,1,5,7,8) + + celltoggle = gtk.CellRendererToggle() + celltoggle.set_property('activatable',True) + celltoggle.connect('toggled',self.parent_toggle, + (self.parent_list,0)) + celltext = gtk.CellRendererText() + col0 = gtk.TreeViewColumn(_('Select'),celltoggle,active=0) + col1 = gtk.TreeViewColumn(_('Father'),celltext,text=1) + col2 = gtk.TreeViewColumn(_('Mother'),celltext,text=2) + self.parent_view.append_column(col0) + self.parent_view.append_column(col1) + self.parent_view.append_column(col2) + + self.parent_list.append(row=[True, + 'Joe Smith','Mary Jones']) + box.add(table) + box.show_all() + if self.need_spouse: + p.connect('next',self.build_spouse_page) + return p + + def parent_toggle(self,celltoggle,path,data): + model, column = data + model[path][column] = not model[path][column] + return + + def build_info_page(self): + """ + Build initial druid page with the overall information about the process. + This is a static page, nothing fun here :-) + """ + p = DruidPageEdge(0) + p.set_title(_('Merge people')) + p.set_title_color(self.fg_color) + p.set_bg_color(self.bg_color) + p.set_logo(self.logo) + p.set_watermark(self.splash) + p.set_text(_('This document will help you through the ' + 'the process of merging two people.')) + return p + + def build_extra(self): + + fname = NameDisplay.displayer.display(self.p1) + mname = NameDisplay.displayer.display(self.p2) + + self.name1 = self.glade.get_widget('name1') + self.name2 = self.glade.get_widget('name2') + self.altnames = self.glade.get_widget('altnames') + + self.name1.set_label(fname) + self.name1.set_active(True) + self.name2.set_label(mname) + self.altnames.set_active(True) + + self.grampsid1 = self.glade.get_widget('grampsid1') + self.grampsid2 = self.glade.get_widget('grampsid2') + self.grampsid1.set_label(self.p1.get_gramps_id()) + self.grampsid2.set_label(self.p2.get_gramps_id()) + self.grampsid1.set_active(True) + + self.birth1 = self.glade.get_widget('birth1') + self.birth2 = self.glade.get_widget('birth2') + self.altbirth = self.glade.get_widget('altbirth') + + (birth1,bplace1) = self.get_event_info(self.p1, + self.p1.get_birth_handle()) + (birth2,bplace2) = self.get_event_info(self.p2, + self.p2.get_birth_handle()) + self.birth1.set_label(", ".join([birth1,bplace1])) + self.birth1.set_active(True) + self.birth1.set_label(", ".join([birth2,bplace2])) + + self.birth1 = self.glade.get_widget('birth1') + self.birth2 = self.glade.get_widget('birth2') + self.altbirth = self.glade.get_widget('altbirth') + + (death1,dplace1) = self.get_event_info(self.p1, + self.p1.get_death_handle()) + (death2,dplace2) = self.get_event_info(self.p2, + self.p2.get_death_handle()) + +# f1_handle = person1.get_main_parents_family_handle() +# f2_handle = person2.get_main_parents_family_handle() + +# name1 = NameDisplay.displayer.display(person1) +# name2 = NameDisplay.displayer.display(person2) + +# (death1,dplace1) = self.get_event_info(person1, +# person1.get_death_handle()) +# (birth1,bplace1) = self.get_event_info(person1, +# person1.get_birth_handle()) +# (death2,dplace2) = self.get_event_info(person2, +# person2.get_death_handle()) +# (birth2,bplace2) = self.get_event_info(person2, +# person2.get_birth_handle()) + +# if f2_handle and not f1_handle: +# self.glade.get_widget("bfather2").set_active(True) +# else: +# self.glade.get_widget("bfather1").set_active(True) + +# father1 = "" +# mother1 = "" +# if f1_handle: +# f1 = self.db.get_family_from_handle(f1_handle) +# father_id = f1.get_father_handle() +# mother_id = f1.get_mother_handle() +# if father_id: +# father1 = name_of(self.db.get_person_from_handle(father_id)) +# if mother_id: +# mother1 = name_of(self.db.get_person_from_handle(mother_id)) + +# father2 = "" +# mother2 = "" +# if f2_handle: +# f2 = self.db.get_family_from_handle(f2_handle) +# father_id = f2.get_father_handle() +# mother_id = f2.get_mother_handle() +# if father_id: +# father2 = name_of(self.db.get_person_from_handle(father_id)) +# if mother_id: +# mother2 = name_of(self.db.get_person_from_handle(mother_id)) + +# self.set_field(self.glade.get_widget("id1_text"), +# person1.get_gramps_id()) +# self.set_field(self.glade.get_widget("id2_text"), +# person2.get_gramps_id()) +# self.set_field(self.glade.get_widget("name1_text"),name1) +# self.set_field(self.glade.get_widget("name2_text"),name2) + +# self.bname1 = self.glade.get_widget("bname1") +# self.bname1.set_active(1) + +# self.set_field(self.glade.get_widget("birth1_text"),birth1) +# self.set_field(self.glade.get_widget("birth2_text"),birth2) +# self.set_field(self.glade.get_widget("bplace1_text"),bplace1) +# self.set_field(self.glade.get_widget("bplace2_text"),bplace2) + +# if ((not birth1 and not bplace1) and (birth2 or bplace2) or +# (not birth1 or not bplace1) and (birth2 and bplace2)): +# self.glade.get_widget('bbirth2').set_active(1) +# else: +# self.glade.get_widget('bbirth1').set_active(1) + +# if ((not death1 and not dplace1) and (death2 or dplace2) or +# (not death1 or not dplace1) and (death2 and dplace2)): +# self.glade.get_widget('death2').set_active(1) +# else: +# self.glade.get_widget('death1').set_active(1) + +# self.set_field(self.glade.get_widget("death1_text"),death1) +# self.set_field(self.glade.get_widget("dplace1_text"),dplace1) +# self.set_field(self.glade.get_widget("death2_text"),death2) +# self.set_field(self.glade.get_widget("dplace2_text"),dplace2) + +# self.set_field(self.glade.get_widget("father1"),father1) +# self.set_field(self.glade.get_widget("father2"),father2) +# self.set_field(self.glade.get_widget("mother1"),mother1) +# self.set_field(self.glade.get_widget("mother2"),mother2) + +# sp1_list = [('-',0,100)] +# self.sp1 = ListModel.ListModel(self.glade.get_widget('spouse1'), +# sp1_list) +# self.sp2 = ListModel.ListModel(self.glade.get_widget('spouse2'), +# sp1_list) + +# self.build_spouse_list(person1,self.sp1) +# self.build_spouse_list(person2,self.sp2) + +# if name1 != name2: +# self.altname.set_sensitive(True) +# self.altname.set_active(True) +# else: +# self.altname.set_sensitive(False) +# self.altname.set_active(False) + +# if birth1 and birth2 and birth1 != birth2: +# self.altbirth.set_active(True) +# if bplace1 and bplace2 or bplace1 != bplace2: +# self.altbirth.set_active(True) +# else: +# self.altbirth.set_active(False) + +# if death1 and death2 and death1 != death2: +# self.altdeath.set_active(True) +# if dplace1 and dplace2 or dplace1 != dplace2: +# self.altdeath.set_active(True) +# else: +# self.altdeath.set_active(False) + + def get_event_info(self,person,handle): + date = "" + place = "" + if handle: + event = self.db.get_event_from_handle(handle) + return (event.get_date(),self.place_name(event)) else: - self.altdeath.set_active(0) + return (u"",u"") def build_spouse_list(self,person,widget): @@ -230,15 +732,13 @@ class MergePeople: widget.set_text(value) def place_name(self,event): - place = event.get_place_handle() - if place: - return "%s (%s)" % (place.get_title(),place.get_handle()) + place_id = event.get_place_handle() + if place_id: + place = self.db.get_place_from_handle(place_id) + return "%s [%s]" % (place.get_title(),place.get_gramps_id()) else: return "" - def empty(self,junk): - pass - def on_merge_edit_clicked(self,obj): import EditPerson self.on_merge_clicked(obj) @@ -259,121 +759,154 @@ class MergePeople: one.add_source_reference(xsrc) def on_merge_clicked(self,obj): - lst = self.p1.get_alternate_names()[:] - for xdata in self.p2.get_alternate_names(): - for data in lst: - if data.are_equal(xdata): - self.copy_note(data,xdata) - self.copy_sources(data,xdata) - break - else: - self.p1.add_alternate_name(xdata) - lst = self.p1.get_attribute_list()[:] - for xdata in self.p2.get_attribute_list(): - for data in lst: - if data.get_type() == xdata.get_type() and \ - data.getValue() == xdata.get_value(): - self.copy_note(data,xdata) - self.copy_sources(data,xdata) - break - else: - self.p1.add_attribute(xdata) + trans = self.db.transaction_begin() + old_handle = self.p2.get_handle() + new_handle = self.p1.get_handle() + + new = RelLib.Person() - handle_lst = self.p1.get_event_list()[:] - lst = [] - for data_handle in handle_lst: - lst.append(self.db.get_event_from_handle(data_handle)) - for xdata_handle in self.p2.get_event_list(): - xdata = self.db.get_event_from_handle(xdata_handle) - for data in lst: - if data.are_equal(xdata): - self.copy_note(data,xdata) - self.copy_sources(data,xdata) - break - else: - self.p1.add_event_handle(xdata_handle) + # set internal handle + new.set_handle(new_handle) + + # set gender + new.set_gender(self.p1.get_gender()) - lst = self.p1.get_address_list() - for xdata in self.p2.get_address_list(): - for data in lst: - if data.are_equal(xdata): - self.copy_note(data,xdata) - self.copy_sources(data,xdata) - break - else: - self.p1.addAddress(xdata) - - lst = self.p1.get_url_list()[:] - for xdata in self.p2.get_url_list(): - for data in lst: - if data.are_equal(xdata): - break - else: - self.p1.add_url(xdata) - - self.id2 = self.glade.get_widget("id2") - old_id = self.p1.get_handle() - if self.id2.get_active(): - self.p1.set_handle(self.p2.get_handle()) - - if self.bname1.get_active(): - if self.altname.get_active(): - self.p1.add_alternate_name(self.p2.get_primary_name()) + # set GRAMPS ID + if self.glade.get_widget("gramps_btn1").get_active(): + new.set_gramps_id(self.p1.get_gramps_id()) else: - if self.altname.get_active(): - self.p1.add_alternate_name(self.p1.get_primary_name()) - self.p1.set_primary_name(self.p2.get_primary_name()) - - alt = self.glade.get_widget("altbirth").get_active() - if self.glade.get_widget("bbirth2").get_active(): - if alt: - event = self.p1.get_birth_handle() - event.set_name("Alternate Birth") - self.p1.add_event(event) - self.p1.set_birth(self.p2.get_birth_handle()) + new.set_gramps_id(self.p2.get_gramps_id()) + + # copy names + if self.bname.get_active(): + new.set_primary_name(self.p1.get_primary_name()) + new.add_alternate_name(self.p2.get_primary_name()) else: - if alt: - event = self.p2.get_birth_handle() - event.set_name("Alternate Birth") - self.p1.add_event(event) + new.set_primary_name(self.p2.get_primary_name()) + new.add_alternate_name(self.p1.get_primary_name()) - alt = self.glade.get_widget("altdeath").get_active() - if self.glade.get_widget("bbirth2").get_active(): - if alt: - event = self.p1.get_death_handle() - event.set_name("Alternate Death") - self.p1.add_event(event) - self.p1.set_death(self.p2.get_death_handle()) + # copy alternate names + for name in self.p1.get_alternate_names(): + new.add_alternate_name(name) + for name in self.p2.get_alternate_names(): + new.add_alternate_name(name) + + # copy birth + bhandle1 = self.p1.get_birth_handle() + birth1 = self.db.get_event_from_handle(bhandle1) + + bhandle2 = self.p2.get_birth_handle() + birth2 = self.db.get_event_from_handle(bhandle2) + + if bhandle1 and bhandle2 and (bhandle1 == bhandle2 or birth2.are_equal(birth1)): + new.set_birth_handle(bhandle1) else: - if alt: - event = self.p2.get_death_handle() - event.set_name("Alternate Death") - self.p1.add_event(event) + if self.glade.get_widget("bbirth1").get_active(): + new.set_birth_handle(bhandle1) + event = self.db.get_event_from_handle(bhandle1) + event.set_handle(None) + event.set_name('Alternate Birth') + self.add_event(event,trans) + new.add_event_handle(event.get_handle()) + else: + new.set_birth_handle(bhandle2) + event = self.db.get_event_from_handle(bhandle2) + event.set_handle(None) + event.set_name('Alternate Birth') + self.add_event(event,trans) + new.add_event_handle(event.get_handle()) + # copy death + dhandle1 = self.p1.get_death_handle() + death1 = self.db.get_event_from_handle(dhandle1) + + dhandle2 = self.p2.get_death_handle() + death2 = self.db.get_event_from_handle(dhandle2) + + if dhandle1 and dhandle2 and (dhandle1 == dhandle2 or death2.are_equal(death1)): + new.set_death_handle(dhandle1) + else: + if self.glade.get_widget("death1").get_active(): + new.set_death_handle(bhandle1) + event = self.db.get_event_from_handle(dhandle1) + event.set_handle(None) + event.set_name('Alternate Death') + self.add_event(event,trans) + new.add_event_handle(event.get_handle()) + else: + new.set_birth_handle(dhandle2) + event = self.db.get_event_from_handle(dhandle2) + event.set_handle(None) + event.set_name('Alternate Death') + self.add_event(event,trans) + new.add_event_handle(event.get_handle()) + + # copy events + data_list = self.p1.get_event_list() + for handle in self.p2.get_event_list(): + if handle not in data_list: + events.append(handle) + new.set_event_list(data_list) + + # copy attributes + new.set_attribute_list(self.p1.get_attribute_list() + self.p2.get_attribute_list()) + + # copy addresses + new.set_address_list(self.p1.get_address_list() + self.p2.get_address_list()) + + # copy urls + new.set_url_list(self.p1.get_url_list() + self.p2.get_url_list()) + + # privacy + new.set_privacy(self.p1.get_privacy() or self.p2.get_privacy()) + + # sources + new.set_source_reference_list(self.p1.get_source_references() + + self.p2.get_source_references()) + + # note + note1 = self.p1.get_note_object() + note2 = self.p2.get_note_object() + + if note1 and not note2: + new.set_note_object(note1) + elif not note1 and note2: + new.set_note_object(note2) + elif note1 and note2: + note1.append("\n" + note2.get()) + note1.set_format(note1.get_format() or note2.get_format()) + new.set_note_object(note1) + + ###################################################################### + if self.glade.get_widget("bfather2").get_active(): - orig_family = self.p1.get_main_parents_family_handle() - if orig_family: - orig_family.remove_child_handle(self.p1) - self.p1.remove_parent_family_handle(orig_family) + orig_family_handle = self.p1.get_main_parents_family_handle() + if orig_family_handle: + orig_family = self.db.get_family_from_handle(orig_family_handle) + orig_family.remove_child_handle(new_handle) + self.db.commit_family(orig_family,trans) - (source_family,mrel,frel) = self.p2.get_main_parents_family_handle() - self.p1.set_main_parent_family_handle(source_family) - - if source_family: - if self.p2 in source_family.get_child_handle_list(): - source_family.remove_child_handle(self.p2) - self.p2.remove_parent_family_handle(source_family) - if self.p1 not in source_family.get_child_handle_list(): - source_family.add_child_handle(self.p1) - self.p1.add_parent_family_handle(source_family.get_handle(),mrel,frel) + (src_handle,mrel,frel) = self.p2.get_main_parents_family_handle() + if src_handle: + source_family = self.db.get_family_from_handle(src_handle) + if old_handle in source_family.get_child_handle_list(): + source_family.remove_child_handle(old_handle) + self.p2.remove_parent_family_handle(src_handle) + if new_handle not in source_family.get_child_handle_list(): + source_family.add_child_handle(new_handle) + new.add_parent_family_handle(src_handle,mrel,frel) + self.db.commit_family(source_family,trans) + new.set_main_parent_family_handle(src_handle) else: - source_family = self.p2.get_main_parents_family_handle() - if source_family: + src_handle = self.p2.get_main_parents_family_handle() + if src_handle: + source_family = self.db.get_family_from_handle(src_handle) source_family.remove_child_handle(self.p2) self.p2.set_main_parent_family_handle(None) + self.db.commit_family(source_family,trans) - self.merge_families() + self.merge_families(trans) for photo in self.p2.get_media_list(): self.p1.add_media_reference(photo) @@ -389,16 +922,15 @@ class MergePeople: self.copy_sources(self.p1,self.p2) - try: - self.db.remove_person(self.p2.get_handle()) - self.db.personMap[self.p1.get_handle()] = self.p1 - except: - print "%s is not in the person map!" % (NameDisplay.displayer.display(self.p2)) + self.db.remove_person(self.p2.get_handle(),trans) + self.db.commit_person(self.p1,trans) + self.update(self.p1,self.p2,old_id) + + self.db.transaction_commit(trans,_("Merge Person")) Utils.destroy_passed_object(self.top) - def find_family(self,family_handle): - family = self.db.get_family_from_handle(family_handle) + def find_family(self,family): if self.p1.get_gender() == RelLib.Person.MALE: mother = family.get_mother_handle() father = self.p1.get_handle() @@ -408,32 +940,32 @@ class MergePeople: for myfamily_handle in self.db.get_family_handles(): myfamily = self.db.get_family_from_handle(myfamily_handle) - if myfamily.get_father_handle() == father and myfamily.get_mother_handle() == mother: - return myfamily_handle + if (myfamily.get_father_handle() == father and + myfamily.get_mother_handle() == mother): + return myfamily return None - def merge_family_pair(self,tgt_family,src_family): + def merge_family_pair(self,tgt_family,src_family,trans): # copy children from source to target - for child in src_family.get_child_handle_list(): - if child not in tgt_family.get_child_handle_list(): + for child_handle in src_family.get_child_handle_list(): + if child_handle not in tgt_family.get_child_handle_list(): + child = self.db.get_person_from_handle(child_handle) parents = child.get_parent_family_handle_list() tgt_family.add_child_handle(child) if child.get_main_parents_family_handle() == src_family: child.set_main_parent_family_handle(tgt_family) i = 0 for fam in parents[:]: - if fam[0] == src_family: + if fam[0] == src_family.get_handle(): parents[i] = (tgt_family,fam[1],fam[2]) - i = i + 1 + i += 1 + self.db.commit_person(child,trans) # merge family events - handle_lst = tgt_family.get_event_list()[:] - lst = [] - for data_handle in handle_lst: - lst.append(self.db.get_event_from_handle(data_handle)) + lst = tgt_family.get_event_list()[:] for xdata in src_family.get_event_list(): for data in lst: if data.are_equal(xdata): @@ -441,7 +973,7 @@ class MergePeople: self.copy_sources(data,xdata) break else: - tgt_family.add_event_handle(xdata_handle) + tgt_family.add_event(xdata) # merge family attributes @@ -473,23 +1005,20 @@ class MergePeople: for photo in src_family.get_media_list(): tgt_family.add_media_reference(photo) - def merge_families(self): + def merge_families(self,trans): family_num = 0 - mylist = self.p2.get_family_handle_list()[:] - for src_family_handle in mylist: - - family_num = family_num + 1 - - if not self.db.has_family_handle(src_family_handle): - continue - if src_family_handle in self.p1.get_family_handle_list(): - continue + for src_family_handle in self.p2.get_family_handle_list(): src_family = self.db.get_family_from_handle(src_family_handle) + family_num += 1 - tgt_family_handle = self.find_family(src_family_handle) - tgt_family = self.db.get_family_from_handle(tgt_family_handle) + if not src_family: + continue + if src_family in self.p1.get_family_handle_list(): + continue + + tgt_family = self.find_family(src_family) # # This is the case where a new family to be added to the @@ -498,18 +1027,19 @@ class MergePeople: # family (with the pre-merge identity of the p1) from # both the parents # - if tgt_family_handle in self.p1.get_family_handle_list(): + if tgt_family in self.p1.get_family_handle_list(): if tgt_family.get_father_handle() != None and \ - src_family_handle in tgt_family.get_family_handle_list(): - tgt_family.get_father_handle().remove_family_handle(src_family_handle) + src_family in tgt_family.get_family_handle_list(): + tgt_family.get_father_handle().remove_family_handle(src_family) if tgt_family.get_mother_handle() != None and \ src_family in tgt_family.get_mother_handle().get_family_handle_list(): tgt_family.get_mother_handle().remove_family_handle(src_family) - self.merge_family_pair(tgt_family,src_family) + self.merge_family_pair(tgt_family,src_family,trans) # delete the old source family - del self.db.get_family_handles()[src_family.get_handle()] + self.db.remove_family(src_family,trans) + self.db.commit_family(tgt_family,trans) continue @@ -525,20 +1055,26 @@ class MergePeople: # transfer child to new family, alter children to # point to the correct family - self.merge_family_pair(tgt_family,src_family) + self.merge_family_pair(tgt_family,src_family,trans) # change parents of the family to point to the new # family - - if src_family.get_father_handle(): - src_family.get_father_handle().remove_family_handle(src_family.get_handle()) - src_family.get_father_handle().add_family_handle(tgt_family.get_handle()) - if src_family.get_mother_handle(): - src_family.get_mother_handle().remove_family_handle(src_family.get_handle()) - src_family.get_mother_handle().add_family_handle(tgt_family.get_handle()) + father_handle = src_family.get_father_handle() + if father_handle: + father = self.db.get_father_from_handle(father_handle) + father.remove_family_handle(src_family.get_handle()) + father.add_family_handle(tgt_family.get_handle()) + self.db.commit_person(father,trans) - del self.db.get_family_handles()[src_family.get_handle()] + mother_handle = src_family.get_mother_handle() + if mother_handle: + mother = self.db.get_mother_from_handle(mother_handle) + mother.remove_family_handle(src_family.get_handle()) + mother.add_family_handle(tgt_family.get_handle()) + self.db.commit_person(mother,trans) + + self.db.remove_family(src_family.get_handle()) else: if src_family not in self.p1.get_family_handle_list(): self.p1.add_family_handle(src_family) @@ -546,36 +1082,41 @@ class MergePeople: src_family.set_father_handle(self.p1) else: src_family.set_mother_handle(self.p1) - self.remove_marriage(src_family,self.p2) + self.remove_marriage(src_family,self.p2,trans) # a little debugging here - - for fam_handle in self.db.get_family_handles(): - fam = self.db.get_family_from_handle(fam_handle) - if self.p2.get_handle() in fam.get_child_handle_list(): - fam.remove_child_handle(self.p2.get_handle()) - fam.add_child_handle(self.p1.get_handle()) - if self.p2.get_handle() == fam.get_father_handle(): - fam.set_father_handle(self.p1.get_handle()) - if self.p2.get_handle() == fam.get_mother_handle(): + + cursor = self.db.get_family_cursor() + data = cursor.first() + while data: + fam = RelLib.Family() + fam.unserialize(data[1]) + if self.p2 in fam.get_child_handle_list(): + fam.remove_child_handle(self.p2) + fam.add_child_handle(self.p1) + if self.p2 == fam.get_father_handle(): + fam.set_father_handle(self.p1) + if self.p2 == fam.get_mother_handle(): fam.set_mother_handle(self.p1) if fam.get_father_handle() == None and fam.get_mother_handle() == None: - self.delete_empty_family(fam_handle) + self.delete_empty_family(fam) + data = cursor.next() - def remove_marriage(self,family,person): + def remove_marriage(self,family,person,trans): if person: person.remove_family_handle(family) if family.get_father_handle() == None and family.get_mother_handle() == None: - self.delete_empty_family(family) + self.delete_empty_family(family,trans) - def delete_empty_family(self,family_handle): - family = self.db.get_family_from_handle(family_handle) - for child in family.get_child_handle_list(): + def delete_empty_family(self,family,trans): + for child_handle in family.get_child_handle_list(): + child = self.db.get_person_from_handle(child_handle) if child.get_main_parents_family_handle() == family_handle: child.set_main_parent_family_handle(None) else: child.remove_parent_family_handle(family_handle) - self.db.delete_family(family_handle) + self.db.commit_person(child,trans) + self.db.remove_family(family_handle,trans) def compare_people(p1,p2): @@ -775,8 +1316,8 @@ def name_match(name,name1): if name.get_first_name() == name1.get_first_name(): return 1 else: - list1 = string.split(name.get_first_name()) - list2 = string.split(name1.get_first_name()) + list1 = name.get_first_name().split() + list2 = name1.get_first_name().split() if len(list1) < len(list2): return list_reduce(list1,list2) @@ -886,7 +1427,7 @@ def ancestors_of(p1,lst): def name_of(p): if not p: return "" - return "%s (%s)" % (NameDisplay.displayer.display(p),p.get_gramps_id()) + return "%s [%s]" % (NameDisplay.displayer.display(p),p.get_gramps_id()) #------------------------------------------------------------------------- # @@ -978,8 +1519,7 @@ class MergePlaces: event.set_place_handle(self.p1) # loop through families, changing event references to P2 to P1 - for f_handle in self.db.get_family_handles(): - f = self.db.get_event_from_handle(f_handle) + for f in self.db.get_family_handle_map().values(): for event in f.get_event_list(): if event.get_place_handle() == self.p2: event.set_place_handle(self.p1) diff --git a/src/const.py.in b/src/const.py.in index b8bb55f94..d03de6510 100644 --- a/src/const.py.in +++ b/src/const.py.in @@ -114,6 +114,7 @@ dialogFile = "%s/gramps.glade" % rootDir srcselFile = "%s/gramps.glade" % rootDir findFile = "%s/find.glade" % rootDir mergeFile = "%s/mergedata.glade" % rootDir +merge2File = "%s/merge.glade" % rootDir filterFile = "%s/rule.glade" % rootDir errdialogsFile = "%s/gramps.glade" % rootDir