# # 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 # "Export to GEDCOM" from RelLib import * import os import string import time import const import utils import intl _ = intl.gettext from gtk import * from gnome.ui import * from libglade import * import const from latin_ansel import latin_to_ansel from latin_utf8 import latin_to_utf8 cnvtxt = latin_to_ansel topDialog = None db = None people_list = [] family_list = [] source_list = [] #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def entire_database(): global people_list global family_list global source_list people_list = db.getPersonMap().values() family_list = db.getFamilyMap().values() source_list = db.getSourceMap().values() #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def active_person_descendants(): global people_list global family_list global source_list people_list = [] family_list = [] source_list = [] descend(active_person) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def active_person_ancestors_and_descendants(): global people_list global family_list global source_list people_list = [] family_list = [] source_list = [] descend(active_person) ancestors(active_person) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def active_person_ancestors(): global people_list global family_list global source_list people_list = [] family_list = [] source_list = [] ancestors(active_person) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def interconnected(): global people_list global family_list global source_list people_list = [] family_list = [] source_list = [] walk(active_person) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def descend(person): if person == None or person in people_list: return people_list.append(person) add_persons_sources(person) for family in person.getFamilyList(): add_familys_sources(family) family_list.append(family) father = family.getFather() mother = family.getMother() if father != None and father not in people_list: people_list.append(father) add_persons_sources(father) if mother != None and mother not in people_list: people_list.append(mother) add_persons_sources(mother) for child in family.getChildList(): descend(child) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def ancestors(person): if person == None or person in people_list: return people_list.append(person) add_persons_sources(person) family = person.getMainFamily() if family == None or family in family_list: return add_familys_sources(family) family_list.append(family) ancestors(family.getMother()) ancestors(family.getFather()) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def walk(person): if person == None or person in people_list: return people_list.append(person) add_persons_sources(person) families = person.getFamilyList() families.append(person.getMainFamily()) for f in person.getAltFamilyList(): families.append(f[0]) for family in families: if family == None or family in family_list: continue add_familys_sources(family) family_list.append(family) walk(family.getFather()) walk(family.getMother()) for child in family.getChildList(): walk(child) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def add_persons_sources(person): elist = person.getEventList()[:] elist.append(person.getBirth()) elist.append(person.getDeath()) for event in elist: if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and sbase not in source_list: source_list.append(sbase) for event in person.getAddressList(): if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and sbase not in source_list: source_list.append(sbase) for event in person.getAttibuteList: if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and sbase not in source_list: source_list.append(sbase) for name in person.getNameList + [ person.getPrimaryName() ]: if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and sbase not in source_list: source_list.append(sbase) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def add_familys_sources(family): for event in family.getEventList(): if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and sbase not in source_list: source_list.append(sbase) for attr in family.getAttributeList(): if private and event.getPrivacy(): continue for source_ref in event.getSourceRefList(): sbase = source_ref.getBase() if sbase != None and sbase not in source_list: source_list.append(sbase) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def sortById(first,second): fid = first.getId() sid = second.getId() if fid == sid: return 0 elif fid < sid: return -1 else: return 1 #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def write_long_text(g,tag,level,note): prefix = "%d %s" % (level,tag) textlines = string.split(note,'\n') if len(note) == 0: g.write("%s\n" % prefix) else: for line in textlines: while len(line) > 0: if len(line) > 70: g.write("%s %s\n" % (prefix,line[0:70])) line = line[70:] else: g.write("%s %s\n" % (prefix,line)) line = "" if len(line) > 0: prefix = "%d CONC" % (level + 1) else: prefix = "%d CONT" % (level + 1) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def dump_event_stats(g,event): if event.getSaveDate() != "": g.write("2 DATE %s\n" % cnvtxt(event.getSaveDate())) if event.getPlaceName() != "": g.write("2 PLAC %s\n" % cnvtxt(event.getPlaceName())) if event.getCause() != "": g.write("2 CAUS %s\n" % cnvtxt(event.getCause())) if event.getNote() != "": write_long_text(g,"NOTE",2,event.getNote()) for srcref in event.getSourceRefList(): write_source_ref(g,2,srcref) def fmtline(text,limit,level): new_text = [] text = cnvtxt(text) while len(text) > limit: new_text.append(text[0:limit-1]) text = text[limit:] if len(text) > 0: new_text.append(text) app = "\n%d CONC " % (level+1) return string.join(new_text,app) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def probably_alive(person): if person == None: return 1 if restrict == 0: return 0 death = person.getDeath() birth = person.getBirth() if death.getDate() != "": return 0 if birth.getDate() != "": year = birth.getDateObj().getYear() time_struct = time.localtime(time.time()) current_year = time_struct[0] if year != -1 and current_year - year > 110: return 0 return 1 #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def write_person_name(g,name,nick): firstName = cnvtxt(name.getFirstName()) surName = cnvtxt(name.getSurname()) suffix = cnvtxt(name.getSuffix()) title = cnvtxt(name.getTitle()) if suffix == "": g.write("1 NAME %s /%s/\n" % (firstName,surName)) else: g.write("1 NAME %s /%s/, %s\n" % (firstName,surName, suffix)) if name.getFirstName() != "": g.write("2 GIVN %s\n" % firstName) if name.getSurname() != "": g.write("2 SURN %s\n" % surName) if name.getSuffix() != "": g.write("2 NSFX %s\n" % suffix) if name.getTitle() != "": g.write("2 TITL %s\n" % title) if nick != "": g.write('2 NICK %s\n' % nick) if name.getNote() != "": write_long_text(g,"NOTE",2,name.getNote()) for srcref in name.getSourceRefList(): write_source_ref(g,2,srcref) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def write_source_ref(g,level,ref): if ref.getBase() == None: return g.write("%d SOUR @S%s@\n" % (level,ref.getBase().getId())) if ref.getPage() != "": g.write("%d PAGE %s\n" % (level+1,ref.getPage())) ref_text = ref.getText() if ref_text != "" or ref.getDate().getDate() != "": g.write('%d DATA\n' % (level+1)) if ref_text != "": write_long_text(g,"TEXT",level+1,ref_text) if ref.getDate().getDate(): g.write("%d DATE %s\n" % (level+1,ref.getDate().getSaveDate())) if ref.getComments() != "": write_long_text(g,"NOTE",level+1,ref.getComments()) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def write_person(g,person): g.write("0 @I%s@ INDI\n" % person.getId()) write_person_name(g,person.getPrimaryName(),person.getNickName()) for name in person.getAlternateNames(): write_person_name(g,name,"") if person.getGender() == Person.male: g.write("1 SEX M\n") else: g.write("1 SEX F\n") if not probably_alive(person): birth = person.getBirth() if not (private and birth.getPrivacy()): if birth.getSaveDate() != "" or birth.getPlaceName() != "": g.write("1 BIRT\n") dump_event_stats(g,birth) death = person.getDeath() if not (private and death.getPrivacy()): if death.getSaveDate() != "" or death.getPlaceName() != "": g.write("1 DEAT\n") dump_event_stats(g,death) uid = person.getPafUid() if uid != "": g.write("1 _UID %s\n" % uid) for event in person.getEventList(): if private and event.getPrivacy(): continue name = event.getName() if const.personalConstantEvents.has_key(name): val = const.personalConstantEvents[name] else: val = "" if val != "" : g.write("1 %s %s\n" % (cnvtxt(val),cnvtxt(event.getDescription()))) else: g.write("1 EVEN %s\n" % cnvtxt(event.getDescription())) g.write("2 TYPE %s\n" % cnvtxt(event.getName())) dump_event_stats(g,event) for attr in person.getAttributeList(): if private and attr.getPrivacy(): continue name = attr.getType() if const.personalConstantAttributes.has_key(name): val = const.personalConstantAttributes[name] else: val = "" if val != "" : g.write("1 %s\n" % val) else: g.write("1 EVEN\n") g.write("2 TYPE %s\n" % cnvtxt(name)) g.write("2 PLAC %s\n" % cnvtxt(attr.getValue())) if attr.getNote() != "": write_long_text(g,"NOTE",2,attr.getNote()) for srcref in attr.getSourceRefList(): write_source_ref(g,2,srclist) for addr in person.getAddressList(): if private and addr.getPrivacy(): continue write_long_text(g,"RESI",1,addr.getStreet()) if addr.getCity() != "": g.write("2 CITY %s\n" % addr.getCity()) if addr.getState() != "": g.write("2 STAE %s\n" % addr.getState()) if addr.getPostal() != "": g.write("2 POST %s\n" % addr.getPostal()) if addr.getCountry() != "": g.write("2 CTRY %s\n" % addr.getCountry()) if addr.getNote() != "": write_long_text(g,"NOTE",2,addr.getNote()) for srcref in addr.getSourceRefList(): write_source_ref(g,2,srcref) family = person.getMainFamily() if family != None and family in family_list: g.write("1 FAMC @F%s@\n" % family.getId()) g.write("2 PEDI birth\n") for family in person.getAltFamilyList(): g.write("1 FAMC @F%s@\n" % family[0].getId()) if string.lower(family[1]) == "adopted": g.write("2 PEDI adopted\n") for family in person.getFamilyList(): if family != None and family in family_list: g.write("1 FAMS @F%s@\n" % family.getId()) for url in person.getUrlList(): g.write('1 OBJE\n') g.write('2 FORM URL\n') if url.get_description() != "": g.write('2 TITL %s\n' % url.get_description()) if url.get_path() != "": g.write('2 FILE %s\n' % url.get_path()) if person.getNote() != "": write_long_text(g,"NOTE",1,person.getNote()) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def exportData(database, filename, pbar, fbar, sbar): g = open(filename,"w") date = string.split(time.ctime(time.time())) g.write("0 HEAD\n") g.write("1 SOUR GRAMPS\n") g.write("2 VERS " + const.version + "\n") g.write("2 NAME Gramps\n") g.write("1 DEST GRAMPS\n") g.write("1 DATE %s %s %s\n" % (date[2],string.upper(date[1]),date[4])) if cnvtxt == latin_to_ansel: g.write("1 CHAR ANSEL\n"); else: g.write("1 CHAR UNICODE\n"); g.write("1 SUBM @SUBM@\n") g.write("1 FILE %s\n" % filename) g.write("1 GEDC\n") g.write("2 VERS 5.5\n") g.write("0 @SUBM@ SUBM\n") owner = database.getResearcher() if owner.getName() != "": g.write("1 NAME " + cnvtxt(owner.getName()) +"\n") if owner.getAddress() != "": g.write("1 ADDR " + cnvtxt(owner.getAddress()) + "\n") if owner.getCity() != "": g.write("2 CITY " + cnvtxt(owner.getCity()) + "\n") if owner.getState() != "": g.write("2 STAE " + cnvtxt(owner.getState()) + "\n") if owner.getPostalCode() != "": g.write("2 POST " + cnvtxt(owner.getPostalCode()) + "\n") if owner.getCountry() != "": g.write("2 CTRY " + cnvtxt(owner.getCountry()) + "\n") if owner.getPhone() != "": g.write("1 PHON " + cnvtxt(owner.getPhone()) + "\n") people_list.sort(sortById) nump = float(len(people_list)) index = 0.0 for person in people_list: write_person(g,person) index = index + 1 pbar.set_value((100*index)/nump) while(events_pending()): mainiteration() pbar.set_value(100.0) nump = float(len(family_list)) index = 0.0 for family in family_list: g.write("0 @F%s@ FAM\n" % family.getId()) person = family.getFather() if person != None: g.write("1 HUSB @I%s@\n" % person.getId()) person = family.getMother() if person != None: g.write("1 WIFE @I%s@\n" % person.getId()) father = family.getFather() mother = family.getMother() if not probably_alive(father) or not probably_alive(mother): for event in family.getEventList(): if private and event.getPrivacy(): continue name = event.getName() if const.familyConstantEvents.has_key(name): val = const.familyConstantEvents[name] else: val = "" if val != "": g.write("1 %s\n" % const.familyConstantEvents[name]) else: g.write("1 EVEN\n") g.write("2 TYPE %s\n" % cnvtxt(name)) dump_event_stats(g,event) for person in family.getChildList(): g.write("1 CHIL @I%s@\n" % person.getId()) index = index + 1 fbar.set_value((100*index)/nump) while(events_pending()): mainiteration() fbar.set_value(100.0) nump = float(len(source_list)) index = 0.0 for source in source_list: g.write("0 @S%s@ SOUR\n" % source.getId()) if source.getTitle() != "": g.write("1 TITL %s\n" % fmtline(source.getTitle(),248,1)) if source.getAuthor() != "": g.write("1 AUTH %s\n" % cnvtxt(source.getAuthor())) if source.getPubInfo() != "": g.write("1 PUBL %s\n" % cnvtxt(source.getPubInfo())) if source.getTitle() != "": g.write("1 ABBR %s\n" % cnvtxt(source.getTitle())) if source.getCallNumber() != "": g.write("1 CALN %s\n" % cnvtxt(source.getCallNumber())) if source.getNote() != "": write_long_text(g,"NOTE",1,source.getNote()) index = index + 1 sbar.set_value((100*index)/nump) while(events_pending()): mainiteration() sbar.set_value(100.0) g.write("0 TRLR\n") g.close() #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def gedcom_date(date): if date.range == 1: s1 = ged_subdate(date.get_start_date()) s2 = ged_subdate(date.get_stop_date()) return "BET %s AND %s" % (s1,s2) elif date.range == -1: return "(%s)" % date.text else: return ged_subdate(self.start) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def ged_subdate(date): if date.month == -1 and date.day == -1 and date.year == -1 : return "" elif date.day == -1: if date.month == -1: retval = str(date.year) elif date.year == -1: retval = "(%s)" % SingleDate.emname[date.month] else: retval = "%s %d" % (SingleDate.emname[date.month],date.year) elif date.month == -1: retval = str(date.year) else: month = SingleDate.emname[date.month] if date.year == -1: retval = "(%d %s)" % (date.day,month) else: retval = "%d %s %d" % (date.day,month,date.year) if date.mode == SingleDate.about: retval = "ABT %s" % retval if date.mode == SingleDate.before: retval = "BEF %s" % retval elif date.mode == SingleDate.after: retval = "AFT %s" % retval return retval #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def on_ok_clicked(obj): global db global topDialog global restrict global private global cnvtxt restrict = topDialog.get_widget("restrict").get_active() private = topDialog.get_widget("private").get_active() filter_obj = topDialog.get_widget("filter").get_menu().get_active() filter = filter_obj.get_data("filter") if topDialog.get_widget("ansel").get_active(): cnvtxt = latin_to_ansel else: cnvtxt = latin_to_utf8 name = topDialog.get_widget("filename").get_text() filter() utils.destroy_passed_object(obj) base = os.path.dirname(__file__) glade_file = base + os.sep + "gedcomexport.glade" progress = GladeXML(glade_file,"exportprogress") progress.signal_autoconnect({"on_close_clicked":utils.destroy_passed_object}) fbar = progress.get_widget("fbar") pbar = progress.get_widget("pbar") sbar = progress.get_widget("sbar") closebtn = progress.get_widget("close") closebtn.connect("clicked",utils.destroy_passed_object) closebtn.set_sensitive(0) exportData(db,name,pbar,fbar,sbar) closebtn.set_sensitive(1) #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- def writeData(database,person): global db global topDialog global active_person db = database active_person = person base = os.path.dirname(__file__) glade_file = base + os.sep + "gedcomexport.glade" dic = { "destroy_passed_object" : utils.destroy_passed_object, "on_ok_clicked" : on_ok_clicked } topDialog = GladeXML(glade_file,"gedcomExport") topDialog.signal_autoconnect(dic) filter_obj = topDialog.get_widget("filter") myMenu = GtkMenu() menuitem = GtkMenuItem(_("Entire Database")) myMenu.append(menuitem) menuitem.set_data("filter",entire_database) menuitem.show() name = active_person.getPrimaryName().getRegularName() menuitem = GtkMenuItem(_("Ancestors of %s") % name) myMenu.append(menuitem) menuitem.set_data("filter",active_person_ancestors) menuitem.show() menuitem = GtkMenuItem(_("Descendants of %s") % name) myMenu.append(menuitem) menuitem.set_data("filter",active_person_descendants) menuitem.show() menuitem = GtkMenuItem(_("Ancestors and Descendants of %s") % name) myMenu.append(menuitem) menuitem.set_data("filter",active_person_ancestors_and_descendants) menuitem.show() menuitem = GtkMenuItem(_("People somehow connected to %s") % name) myMenu.append(menuitem) menuitem.set_data("filter",interconnected) menuitem.show() filter_obj.set_menu(myMenu) topDialog.get_widget("gedcomExport").show() #------------------------------------------------------------------------- # # # #------------------------------------------------------------------------- from Plugins import register_export register_export(writeData,_("Export to GEDCOM"))