diff --git a/gramps/src/EditPerson.py b/gramps/src/EditPerson.py index 34f390d85..33da954f4 100644 --- a/gramps/src/EditPerson.py +++ b/gramps/src/EditPerson.py @@ -49,6 +49,7 @@ import Date from RelLib import * import ImageSelect import sort +import AutoComp from intl import gettext _ = gettext @@ -231,7 +232,8 @@ class EditPerson: self.window.editable_enters(self.ddate); self.window.editable_enters(self.dplace); - utils.attach_surnames(self.get_widget("lastNameList")) + if Config.autocomp: + AutoComp.AutoComp(self.surname_field,const.surnames) self.gid.set_text(person.getId()) self.gid.set_editable(Config.id_edit) diff --git a/gramps/src/Find.py b/gramps/src/Find.py index 90212a3f8..b5fc17927 100644 --- a/gramps/src/Find.py +++ b/gramps/src/Find.py @@ -29,6 +29,7 @@ import const import utils import string import gtk +import AutoComp class Find: """Opens find person dialog for gramps""" @@ -51,14 +52,13 @@ class Find: self.top = self.xml.get_widget("find") self.entry = self.xml.get_widget("entry") + + self.nlist = [] + for n in plist: + self.nlist.append(n.getPrimaryName().getName()) + if Config.autocomp: - self.nlist = [("","")] - for n in plist: - n1 = n.getPrimaryName().getName() - n2 = string.lower(n1) - self.nlist.append((n2,n1)) - self.nlist.sort() - self.entry.connect("insert-text",self.insert_text) + AutoComp.AutoComp(self.entry,self.nlist) self.next = self.xml.get_widget("next") self.top.editable_enters(self.entry) @@ -139,83 +139,3 @@ class Find: """Callback for dialog box that causes the previous person to be found""" self.find_prev() - #------------------------------------------------------------------------- - # - # Sets up a delayed (0.005 sec) handler for text completion. Text - # completion cannot be handled directly in this routine because, for - # some reason, the select_region() function doesn't work when called - # from signal handlers. Go figure. - # - # Thanks to iain@nodata.demon.co.uk (in mail from 1999) for the idea - # to use a timer to get away from the problems with signal handlers - # and the select_region function. - # - #------------------------------------------------------------------------- - def insert_text(self,entry,new_text,new_text_len,i_dont_care): - # One time setup to clear selected region when user moves on - if (not entry.get_data("signal_set")): - entry.set_data("signal_set",1) - entry.signal_connect("focus_out_event", self.lost_focus, entry) - - # Nuke the current timer if the user types fast enough - timer = entry.get_data("timer"); - if (timer): - gtk.timeout_remove(timer) - - # Setup a callback timer so we can operate outside of a signal handler - timer = gtk.timeout_add(5, self.timer_callback, entry) - entry.set_data("timer", timer); - - #------------------------------------------------------------------------- - # - # The entry box entry field lost focus. Go clear any selection. Why - # this form of a select_region() call works in a signal handler and - # the other form doesn't is a mystery. - # - #------------------------------------------------------------------------- - def lost_focus(self,entry,a,b): - entry.select_region(0, 0) - - #------------------------------------------------------------------------- - # - # The workhorse routine of file completion. This routine grabs the - # current text of the entry box, and grubs through the list item - # looking for any case insensitive matches. This routine relies on - # public knowledge of the GtkEntry data structure, not on any private - # data. - # - # These three completion routines have only one gramps specific hook, - # and can be easily ported to any program. - # - #------------------------------------------------------------------------- - def timer_callback(self,entry): - # Clear any timer - timer = entry.get_data("timer"); - if (timer): - gtk.timeout_remove(timer) - - # Get the user's text - typed = entry.get_text() - if (not typed): - return - typed_lc = string.lower(typed) - - # Walk the GtkList in the entry box - for nl,n in self.nlist: - if (not nl): - continue - - # If equal, no need to add any text - if (typed_lc == nl): - return - - # If typed text is a substring of the label text, then fill in - # the entry field with the full text (and correcting - # capitalization), and then select all the characters that - # don't match. With the user's enxt keystroke these will be - # replaced if they are incorrect. - if (string.find(nl,typed_lc) == 0): - entry.set_text(n) - entry.set_position(len(typed)) - entry.select_region(len(typed), -1) - return diff --git a/gramps/src/WriteXML.py b/gramps/src/WriteXML.py index 05ca35d69..f797261af 100644 --- a/gramps/src/WriteXML.py +++ b/gramps/src/WriteXML.py @@ -17,25 +17,622 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +""" +Contains the interface to allow a database to get written using +GRAMPS' XML file format. +""" -from RelLib import * -import const - +#------------------------------------------------------------------------- +# +# load standard python libraries +# +#------------------------------------------------------------------------- import string -import Config import time import shutil import os -from Date import SingleDate +#------------------------------------------------------------------------- +# +# load GRAMPS libraries +# +#------------------------------------------------------------------------- +import const +import Config +from RelLib import * +from Date import SingleDate +from intl import gettext +_ = gettext + +#------------------------------------------------------------------------- +# +# Attempt to load the GZIP library. Some version of python do not seem +# to be compiled with this available. +# +#------------------------------------------------------------------------- try: import gzip - gzip_ok = 1 + _gzip_ok = 1 except: - gzip_ok = 0 + _gzip_ok = 0 -fileroot = "" -strip_photo = 0 +#------------------------------------------------------------------------- +# +# +# +#------------------------------------------------------------------------- +def exportData(database, filename, callback): + if os.path.isfile(filename): + shutil.copy(filename, filename + ".bak") + + compress = Config.uncompress ==0 and _gzip_ok == 1 + + try: + g = XmlWriter(database,callback,0,compress) + g.write(filename) + except: + from gnome.ui import GnomeErrorDialog + import traceback + + traceback.print_exc() + + fname = os.path.expanduser("~/gramps.err") + errfile = open(fname,"w") + traceback.print_exc(file=errfile) + errfile.close() + + GnomeErrorDialog(_("Failure writing %s, original file restored") % filename) + shutil.copy(filename + ".bak", filename) + +#------------------------------------------------------------------------- +# +# +# +#------------------------------------------------------------------------- +def quick_write(database, filename,callback=None): + g = XmlWriter(database,callback,0,1) + g.write(filename) + +#------------------------------------------------------------------------- +# +# +# +#------------------------------------------------------------------------- +class XmlWriter: + """ + Writes a database to the XML file. + """ + + def __init__(self,db,callback,strip_photos,compress=1): + """ + Initializes, but nots not write, and XML file. + + db - database to write + callback - function to provide progress indication + strip_photos - remove full paths off of media object paths + compress - attempt to compress the database + """ + self.compress = compress + self.db = db + self.callback = callback + self.strip_photos = strip_photos + + def write(self,filename): + """ + Write the database to the specfied file. + """ + self.fileroot = os.path.dirname(filename) + if self.compress: + try: + self.g = gzip.open(filename,"wb") + except: + self.g = open(filename,"w") + else: + self.g = open(filename,"w") + + self.write_xml_data() + self.g.close() + + def write_xml_data(self): + + date = string.split(time.ctime(time.time())) + owner = self.db.getResearcher() + personList = self.db.getPersonMap().values() + personList.sort(sortById) + familyList = self.db.getFamilyMap().values() + familyList.sort(sortById) + sourceList = self.db.getSourceMap().values() + placeList = self.db.getPlaceMap().values() + placeList.sort(sortById) + objList = self.db.getObjectMap().values() + objList.sort(sortById) + + total = len(personList) + len(familyList) + + self.g.write('\n') + self.g.write('\n') + self.g.write("\n") + self.g.write("
\n") + self.g.write(" \n" % len(self.db.getFamilyMap().values())) + self.g.write(" \n") + self.write_line("resname",owner.getName(),3) + self.write_line("resaddr",owner.getAddress(),3) + self.write_line("rescity",owner.getCity(),3) + self.write_line("resstate",owner.getState(),3) + self.write_line("rescountry",owner.getCountry(),3) + self.write_line("respostal",owner.getPostalCode(),3) + self.write_line("resphone",owner.getPhone(),3) + self.write_line("resemail",owner.getEmail(),3) + self.g.write(" \n") + self.g.write("
\n") + + if len(personList) > 0: + self.g.write(" \n") + + total = len(personList) + len(familyList) + delta = max(int(total/50),1) + + count = 0 + for person in personList: + if self.callback and count % delta == 0: + self.callback(float(count)/float(total)) + count = count + 1 + + self.write_id("person",person,2) + if person.getGender() == Person.male: + self.write_line("gender","M",3) + elif person.getGender() == Person.female: + self.write_line("gender","F",3) + else: + self.write_line("gender","U",3) + self.dump_name("name",person.getPrimaryName(),3) + for name in person.getAlternateNames(): + self.dump_name("aka",name,3) + + self.write_line("uid",person.getPafUid(),3) + self.write_line("nick",person.getNickName(),3) + pos = person.getPosition() + if pos != None: + self.g.write(' \n'% pos) + self.dump_my_event("Birth",person.getBirth(),3) + self.dump_my_event("Death",person.getDeath(),3) + for event in person.getEventList(): + self.dump_event(event,3) + + self.dump_ordinance("baptism",person.getLdsBaptism(),3) + self.dump_ordinance("endowment",person.getLdsEndowment(),3) + self.dump_ordinance("sealed_to_parents",person.getLdsSeal(),3) + + self.write_photo_list(person.getPhotoList()) + + if len(person.getAddressList()) > 0: + for address in person.getAddressList(): + self.g.write(' \n' % conf_priv(address)) + self.write_date(address.getDateObj(),4) + self.write_line("street",address.getStreet(),4) + self.write_line("city",address.getCity(),4) + self.write_line("state",address.getState(),4) + self.write_line("country",address.getCountry(),4) + self.write_line("postal",address.getPostal(),4) + if address.getNote() != "": + self.write_note("note",address.getNote(),4) + for s in address.getSourceRefList(): + self.dump_source_ref(s,4) + self.g.write(' \n') + + self.write_attribute_list(person.getAttributeList()) + self.write_url_list(person.getUrlList()) + + self.write_ref("childof",person.getMainFamily(),3) + for alt in person.getAltFamilyList(): + if alt[1] != "": + mrel=' mrel="%s"' % alt[1] + else: + mrel='' + if alt[2] != "": + frel=' frel="%s"' % alt[2] + else: + frel='' + self.g.write(" \n" % \ + (alt[0].getId(), mrel, frel)) + + for family in person.getFamilyList(): + self.write_ref("parentin",family,3) + + self.write_note("note",person.getNote(),3) + + self.g.write(" \n") + self.g.write(" \n") + + if len(familyList) > 0: + self.g.write(" \n") + + for family in familyList: + if self.callback and count % delta == 0: + self.callback(float(count)/float(total)) + count = count + 1 + + self.write_family_id(family,2) + self.write_ref("father",family.getFather(),3) + self.write_ref("mother",family.getMother(),3) + pos = family.getPosition() + if pos != None: + self.g.write(' \n'% pos) + + for event in family.getEventList(): + self.dump_event(event,3) + self.dump_ordinance("sealed_to_spouse",family.getLdsSeal(),3) + + self.write_photo_list(family.getPhotoList()) + + if len(family.getChildList()) > 0: + for person in family.getChildList(): + self.write_ref("child",person,3) + self.write_attribute_list(family.getAttributeList()) + self.write_note("note",family.getNote(),3) + self.g.write(" \n") + self.g.write(" \n") + + if len(sourceList) > 0: + self.g.write(" \n") + for source in sourceList: + self.g.write(" \n") + self.write_force_line("stitle",source.getTitle(),3) + self.write_line("sauthor",source.getAuthor(),3) + self.write_line("spubinfo",source.getPubInfo(),3) + self.write_line("scallno",source.getCallNumber(),3) + if source.getNote() != "": + self.write_note("note",source.getNote(),3) + self.write_photo_list(source.getPhotoList()) + self.g.write(" \n") + self.g.write(" \n") + + if len(placeList) > 0: + self.g.write(" \n") + for place in placeList: + self.write_place_obj(place) + self.g.write(" \n") + + if len(objList) > 0: + self.g.write(" \n") + for object in objList: + self.write_object(object) + self.g.write(" \n") + + if len(self.db.getBookmarks()) > 0: + self.g.write(" \n") + for person in self.db.getBookmarks(): + self.g.write(' \n' % person.getId()) + self.g.write(" \n") + + self.g.write("
\n") + + def fix(self,line): + l = string.strip(line) + l = string.replace(l,'&','&') + l = string.replace(l,'>','>') + l = string.replace(l,'<','<') + return string.replace(l,'"','"') + + def write_note(self,val,note,indent=0): + if not note: + return + if indent != 0: + self.g.write(" " * indent) + + self.g.write("<%s>" % val) + self.g.write(self.fix(string.rstrip(note))) + self.g.write("\n" % val) + + def dump_event(self,event,index=1): + if event: + self.dump_my_event(event.getName(),event,index) + + def dump_my_event(self,name,event,index=1): + if not event: + return + + date = event.getDateObj() + place = event.getPlace() + description = event.getDescription() + cause = event.getCause() + if (not name or name == "Birth" or name == "Death") and \ + date.isEmpty() and not place and not description: + return + + sp = " " * index + self.g.write('%s\n' % (sp,self.fix(name),conf_priv(event))) + self.write_date(event.getDateObj(),index+1) + self.write_ref("place",place,index+1) + self.write_line("cause",cause,index+1) + self.write_line("description",description,index+1) + if event.getNote(): + self.write_note("note",event.getNote(),index+1) + + for s in event.getSourceRefList(): + self.dump_source_ref(s,index+1) + self.g.write("%s\n" % sp) + + def dump_ordinance(self,name,ord,index=1): + if not ord: + return + + sp = " " * index + sp2 = " " * (index+1) + self.g.write('%s\n' % (sp,self.fix(name))) + dateobj = ord.getDateObj() + if dateobj != None and not dateobj.isEmpty(): + self.write_date(dateobj,index+1) + if ord.getTemple(): + self.g.write('%s\n' % (sp2,self.fix(ord.getTemple()))) + self.write_ref("place",ord.getPlace(),index+1) + if ord.getStatus() != 0: + self.g.write('%s\n' % (sp2,ord.getStatus())) + if ord.getFamily(): + self.g.write('%s\n' % (sp2,self.fix(ord.getFamily().getId()))) + if ord.getNote() != "": + self.write_note("note",ord.getNote(),index+1) + for s in ord.getSourceRefList(): + self.dump_source_ref(s,index+1) + self.g.write('%s\n' % sp) + + def dump_source_ref(self,source_ref,index=1): + source = source_ref.getBase() + if source: + p = source_ref.getPage() + c = source_ref.getComments() + t = source_ref.getText() + d = source_ref.getDate() + q = source_ref.getConfidence() + self.g.write(" " * index) + if p == "" and c == "" and t == "" and d.isEmpty() and q == 2: + self.g.write('\n' % source.getId()) + else: + if q == 2: + self.g.write('\n' % source.getId()) + else: + self.g.write('\n' % (source.getId(),q)) + self.write_line("spage",p,index+1) + self.write_note("scomments",c,index+1) + self.write_note("stext",t,index+1) + self.write_date(d,index+1) + self.g.write("%s\n" % (" " * index)) + + def write_ref(self,label,person,index=1): + if person: + self.g.write('%s<%s ref="%s"/>\n' % (" "*index,label,person.getId())) + + def write_id(self,label,person,index=1): + if person: + self.g.write('%s<%s id="%s">\n' % (" "*index,label,person.getId())) + + def write_family_id(self,family,index=1): + if family: + rel = family.getRelationship() + sp = " " * index + self.g.write('%s\n' % rel) + else: + self.g.write('>\n') + + def write_line(self,label,value,indent=1): + if value: + self.g.write('%s<%s>%s\n' % (' '*indent,label,self.fix(value),label)) + + def write_date(self,date,indent=1): + sp = ' '*indent + if date.isEmpty(): + return + + cal = date.get_calendar() + if cal != 0: + calstr = ' calendar="%s"' % self.fix(str(cal)) + else: + calstr = '' + + if date.isRange(): + d1 = date.get_start_date().getIsoDate() + d2 = date.get_stop_date().getIsoDate() + self.g.write('%s\n' % (sp,d1,d2,calstr)) + elif date.isValid(): + d1 = date.get_start_date() + mode = d1.getModeVal() + dstr = d1.getIsoDate() + + if mode == SingleDate.before: + pref = ' type="before"' + elif mode == SingleDate.after: + pref = ' type="after"' + elif mode == SingleDate.about: + pref = ' type="about"' + else: + pref = "" + + self.g.write('%s\n' % (sp,dstr,pref,calstr)) + else: + self.g.write('%s\n' %(sp,date.getText())) + + def write_force_line(self,label,value,indent=1): + if value != None: + self.g.write('%s<%s>%s\n' % (' '*indent,label,self.fix(value),label)) + + def dump_name(self,label,name,index=1): + sp = " "*index + self.g.write('%s<%s%s>\n' % (sp,label,conf_priv(name))) + self.write_line("first",name.getFirstName(),index+1) + self.write_line("last",name.getSurname(),index+1) + self.write_line("suffix",name.getSuffix(),index+1) + self.write_line("title",name.getTitle(),index+1) + if name.getNote() != "": + self.write_note("note",name.getNote(),index+1) + for s in name.getSourceRefList(): + self.dump_source_ref(s,index+1) + + self.g.write('%s\n' % (sp,label)) + + def append_value(self,orig,val): + if orig: + return "%s, %s" % (orig,val) + else: + return val + + def build_place_title(self,loc): + "Builds a title from a location" + city = self.fix(loc.get_city()) + parish = self.fix(loc.get_parish()) + state = self.fix(loc.get_state()) + country = self.fix(loc.get_country()) + county = self.fix(loc.get_county()) + + value = "" + + if city: + value = city + if parish: + value = self.append_value(value,parish) + if county: + value = self.append_value(value,county) + if state: + value = self.append_value(value,state) + if country: + value = self.append_value(value,country) + return value + + def dump_location(self,loc): + "Writes the location information to the output file" + city = self.fix(loc.get_city()) + parish = self.fix(loc.get_parish()) + state = self.fix(loc.get_state()) + country = self.fix(loc.get_country()) + county = self.fix(loc.get_county()) + + if not city and not state and not parish and not county and not country: + return + + self.g.write(' \n') + + def write_attribute_list(self, list, indent=3): + sp = ' ' * indent + for attr in list: + self.g.write('%s\n') + else: + self.g.write('>\n') + for s in attr.getSourceRefList(): + self.dump_source_ref(s,indent+1) + self.write_note("note",attr.getNote(),4) + self.g.write('%s\n' % sp) + + def write_photo_list(self,list,indent=3): + sp = ' '*indent + for photo in list: + mobj = photo.getReference() + self.g.write('%s\n") + else: + self.g.write(">\n") + self.write_attribute_list(proplist,indent+1) + self.write_note("note",photo.getNote(),indent+1) + self.g.write('%s\n' % sp) + + def write_url_list(self,list): + for url in list: + self.g.write(' \n') + + def write_place_obj(self,place): + title = self.fix(place.get_title()) + long = self.fix(place.get_longitude()) + lat = self.fix(place.get_latitude()) + id = place.getId() + main_loc = place.get_main_location() + llen = len(place.get_alternate_locations()) + len(place.getUrlList()) + \ + len(place.getPhotoList()) + len(place.getSourceRefList()) + + ml_empty = main_loc.is_empty() + note = place.getNote() + + if title == "": + title = self.fix(self.build_place_title(place.get_main_location())) + + self.g.write(' 0 or note: + self.g.write('>\n') + else: + self.g.write('/>\n') + return + + if long or lat: + self.g.write(' \n' % (long,lat)) + + self.dump_location(main_loc) + for loc in place.get_alternate_locations(): + self.dump_location(loc) + self.write_photo_list(place.getPhotoList()) + self.write_url_list(place.getUrlList()) + if note != "": + self.write_note("note",note,3) + for s in place.getSourceRefList(): + self.dump_source_ref(s,3) + self.g.write(" \n") + + def write_object(self,object): + id = object.getId() + type = object.getMimeType() + path = object.getPath() + if self.strip_photos: + path = os.path.basename(path) + else: + l = len(self.fileroot) + if len(path) >= l: + if self.fileroot == path[0:l]: + path = path[l+1:] + self.g.write(' \n') + else: + self.g.write('>\n') + self.write_attribute_list(alist) + if note != "": + self.write_note("note",note,3) + for s in slist: + self.dump_source_ref(s,3) + self.g.write(" \n") #------------------------------------------------------------------------- # @@ -51,42 +648,6 @@ def sortById(first,second): else: return fid != sid -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def fix(line): - l = string.strip(line) - l = string.replace(l,'&','&') - l = string.replace(l,'>','>') - l = string.replace(l,'<','<') - return string.replace(l,'"','"') - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def write_note(g,val,note,indent=0): - if not note: - return - if indent != 0: - g.write(" " * indent) - - g.write("<" + val + ">") - g.write(fix(string.rstrip(note))) - g.write("\n") - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def dump_event(g,event,index=1): - if event: - dump_my_event(g,event.getName(),event,index) - #------------------------------------------------------------------------- # # @@ -97,587 +658,3 @@ def conf_priv(obj): return ' priv="%d"' % obj.getPrivacy() else: return '' - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def dump_my_event(g,name,event,index=1): - if not event: - return - - date = event.getDateObj() - place = event.getPlace() - description = event.getDescription() - cause = event.getCause() - if (not name or name == "Birth" or name == "Death") and \ - date.isEmpty() and not place and not description: - return - - sp = " " * index - g.write('%s\n' % (sp,fix(name),conf_priv(event))) - write_date(g,event.getDateObj(),index+1) - write_ref(g,"place",place,index+1) - write_line(g,"cause",cause,index+1) - write_line(g,"description",description,index+1) - if event.getNote() != "": - write_note(g,"note",event.getNote(),index+1) - - for s in event.getSourceRefList(): - dump_source_ref(g,s,index+1) - g.write("%s\n" % sp) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def dump_ordinance(g,name,ord,index=1): - if not ord: - return - - sp = " " * index - sp2 = " " * (index+1) - g.write('%s\n' % (sp,fix(name))) - dateobj = ord.getDateObj() - if dateobj != None and not dateobj.isEmpty(): - write_date(g,dateobj,index+1) - if ord.getTemple(): - g.write('%s\n' % (sp2,fix(ord.getTemple()))) - write_ref(g,"place",ord.getPlace(),index+1) - if ord.getStatus() != 0: - g.write('%s\n' % (sp2,ord.getStatus())) - if ord.getFamily(): - g.write('%s\n' % (sp2,fix(ord.getFamily().getId()))) - if ord.getNote() != "": - write_note(g,"note",ord.getNote(),index+1) - for s in ord.getSourceRefList(): - dump_source_ref(g,s,index+1) - g.write('%s\n' % sp) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def dump_source_ref(g,source_ref,index=1): - source = source_ref.getBase() - if source: - p = source_ref.getPage() - c = source_ref.getComments() - t = source_ref.getText() - d = source_ref.getDate() - q = source_ref.getConfidence() - g.write(" " * index) - if p == "" and c == "" and t == "" and d.isEmpty() and q == 2: - g.write('\n' % source.getId()) - else: - if q == 2: - g.write('\n' % source.getId()) - else: - g.write('\n' % (source.getId(),q)) - write_line(g,"spage",p,index+1) - write_note(g,"scomments",c,index+1) - write_note(g,"stext",t,index+1) - write_date(g,d,index+1) - g.write("%s\n" % (" " * index)) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def write_ref(g,label,person,index=1): - if person: - g.write('%s<%s ref="%s"/>\n' % (" "*index,label,person.getId())) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def write_id(g,label,person,index=1): - if person: - g.write('%s<%s id="%s">\n' % (" "*index,label,person.getId())) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def write_family_id(g,family,index=1): - if family: - rel = family.getRelationship() - sp = " " * index - if rel != "": - g.write('%s\n' % (sp,family.getId(),rel)) - else: - g.write('%s\n' % (sp,family.getId())) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def write_line(g,label,value,indent=1): - if value: - g.write('%s<%s>%s\n' % (' '*indent,label,fix(value),label)) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def write_date(g,date,indent=1): - sp = ' '*indent - if date.isEmpty(): - return - - cal = date.get_calendar() - if cal != 0: - calstr = ' calendar="%s"' % fix(str(cal)) - else: - calstr = '' - - if date.isRange(): - d1 = date.get_start_date().getIsoDate() - d2 = date.get_stop_date().getIsoDate() - g.write('%s\n' % (sp,d1,d2,calstr)) - elif date.isValid(): - d1 = date.get_start_date() - mode = d1.getModeVal() - dstr = d1.getIsoDate() - - if mode == SingleDate.before: - pref = ' type="before"' - elif mode == SingleDate.after: - pref = ' type="after"' - elif mode == SingleDate.about: - pref = ' type="about"' - else: - pref = "" - - g.write('%s\n' % (sp,dstr,pref,calstr)) - else: - g.write('%s\n' %(sp,date.getText())) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def write_force_line(g,label,value,indent=1): - if value != None: - g.write('%s<%s>%s\n' % (' '*indent,label,fix(value),label)) - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- -def dump_name(g,label,name,index=1): - sp = " "*index - g.write('%s<%s%s>\n' % (sp,label,conf_priv(name))) - write_line(g,"first",name.getFirstName(),index+1) - write_line(g,"last",name.getSurname(),index+1) - write_line(g,"suffix",name.getSuffix(),index+1) - write_line(g,"title",name.getTitle(),index+1) - if name.getNote() != "": - write_note(g,"note",name.getNote(),index+1) - for s in name.getSourceRefList(): - dump_source_ref(g,s,index+1) - - g.write('%s\n' % (sp,label)) - - -def append_value(orig,val): - if orig: - return "%s, %s" % (orig,val) - else: - return val - -def build_place_title(loc): - "Builds a title from a location" - city = fix(loc.get_city()) - parish = fix(loc.get_parish()) - state = fix(loc.get_state()) - country = fix(loc.get_country()) - county = fix(loc.get_county()) - - value = "" - - if city: - value = city - if parish: - value = append_value(value,parish) - if county: - value = append_value(value,county) - if state: - value = append_value(value,state) - if country: - value = append_value(value,country) - return value - -def dump_location(g,loc): - "Writes the location information to the output file" - city = fix(loc.get_city()) - parish = fix(loc.get_parish()) - state = fix(loc.get_state()) - country = fix(loc.get_country()) - county = fix(loc.get_county()) - - if not city and not state and not parish and not county and not country: - return - - g.write(' \n') - - -def write_attribute_list(g, list, indent=3): - sp = ' ' * indent - for attr in list: - g.write('%s\n') - else: - g.write('>\n') - for s in attr.getSourceRefList(): - dump_source_ref(g,s,indent+1) - write_note(g,"note",attr.getNote(),4) - g.write('%s\n' % sp) - -def write_photo_list(g,list,indent=3): - sp = ' '*indent - for photo in list: - mobj = photo.getReference() - g.write('%s\n") - else: - g.write(">\n") - write_attribute_list(g,proplist,indent+1) - write_note(g,"note",photo.getNote(),indent+1) - g.write('%s\n' % sp) - -def write_url_list(g, list): - for url in list: - g.write(' \n') - -def write_place_obj(g,place): - title = fix(place.get_title()) - long = place.get_longitude() - lat = place.get_latitude() - id = place.getId() - main_loc = place.get_main_location() - llen = len(place.get_alternate_locations()) + len(place.getUrlList()) + \ - len(place.getPhotoList()) + len(place.getSourceRefList()) - - ml_empty = main_loc.is_empty() - note = place.getNote() - - if title == "": - title = fix(build_place_title(place.get_main_location())) - - g.write(' 0 or note: - g.write('>\n') - else: - g.write('/>\n') - return - - if long or lat: - g.write(' \n' % (fix(long),fix(lat))) - - dump_location(g,main_loc) - for loc in place.get_alternate_locations(): - dump_location(g,loc) - write_photo_list(g,place.getPhotoList()) - write_url_list(g, place.getUrlList()) - if note != "": - write_note(g,"note",note,3) - for s in place.getSourceRefList(): - dump_source_ref(g,s,3) - g.write(" \n") - -def write_object(g,object): - id = object.getId() - type = object.getMimeType() - path = object.getPath() - if strip_photo: - path = os.path.basename(path) - else: - l = len(fileroot) - if len(path) >= l: - if fileroot == path[0:l]: - path = path[l+1:] - g.write(' \n') - else: - g.write('>\n') - write_attribute_list(g,alist) - if note != "": - write_note(g,"note",note,3) - for s in slist: - dump_source_ref(g,s,3) - g.write(" \n") - -#------------------------------------------------------------------------- -# -# -# -#------------------------------------------------------------------------- - -def exportData(database, filename, callback): - global fileroot - - fileroot = os.path.dirname(filename) - if os.path.isfile(filename): - shutil.copy(filename, filename + ".bak") - - if Config.uncompress ==0 and gzip_ok == 1: - try: - g = gzip.open(filename,"wb") - except: - g = open(filename,"w") - else: - g = open(filename,"w") - - try: - write_xml_data(database, g, callback, 0) - g.close() - except: - from gnome.ui import GnomeErrorDialog - import traceback - from intl import gettext - _ = gettext - - traceback.print_exc() - - fname = os.path.expanduser("~/gramps.err") - errfile = open(fname,"w") - traceback.print_exc(file=errfile) - errfile.close() - - GnomeErrorDialog(_("Failure writing %s, original file restored") % filename) - shutil.copy(filename + ".bak", filename) - -def quick_write(database, filename,callback=None): - global fileroot - - fileroot = os.path.dirname(filename) - g = gzip.open(filename,"wb") - write_xml_data(database, g, callback, 0) - g.close() - -def write_xml_data(database, g, callback, sp): - - global strip_photo - - strip_photo = sp - - date = string.split(time.ctime(time.time())) - owner = database.getResearcher() - personList = database.getPersonMap().values() - personList.sort(sortById) - familyList = database.getFamilyMap().values() - familyList.sort(sortById) - sourceList = database.getSourceMap().values() - placeList = database.getPlaceMap().values() - placeList.sort(sortById) - objList = database.getObjectMap().values() - objList.sort(sortById) - - total = len(personList) + len(familyList) - - g.write('\n') - g.write('\n') - g.write("\n") - g.write("
\n") - g.write(" \n" % len(database.getFamilyMap().values())) - g.write(" \n") - write_line(g,"resname",owner.getName(),3) - write_line(g,"resaddr",owner.getAddress(),3) - write_line(g,"rescity",owner.getCity(),3) - write_line(g,"resstate",owner.getState(),3) - write_line(g,"rescountry",owner.getCountry(),3) - write_line(g,"respostal",owner.getPostalCode(),3) - write_line(g,"resphone",owner.getPhone(),3) - write_line(g,"resemail",owner.getEmail(),3) - g.write(" \n") - g.write("
\n") - - if len(personList) > 0: - g.write(" \n") - - total = len(personList) + len(familyList) - delta = max(int(total/50),1) - - count = 0 - for person in personList: - if callback and count % delta == 0: - callback(float(count)/float(total)) - count = count + 1 - - write_id(g,"person",person,2) - if person.getGender() == Person.male: - write_line(g,"gender","M",3) - elif person.getGender() == Person.female: - write_line(g,"gender","F",3) - else: - write_line(g,"gender","U",3) - dump_name(g,"name",person.getPrimaryName(),3) - for name in person.getAlternateNames(): - dump_name(g,"aka",name,3) - - write_line(g,"uid",person.getPafUid(),3) - write_line(g,"nick",person.getNickName(),3) - pos = person.getPosition() - if pos != None: - g.write(' \n'% pos) - dump_my_event(g,"Birth",person.getBirth(),3) - dump_my_event(g,"Death",person.getDeath(),3) - for event in person.getEventList(): - dump_event(g,event,3) - - dump_ordinance(g,"baptism",person.getLdsBaptism(),3) - dump_ordinance(g,"endowment",person.getLdsEndowment(),3) - dump_ordinance(g,"sealed_to_parents",person.getLdsSeal(),3) - - write_photo_list(g,person.getPhotoList()) - - if len(person.getAddressList()) > 0: - for address in person.getAddressList(): - g.write(' \n' % conf_priv(address)) - write_date(g,address.getDateObj(),4) - write_line(g,"street",address.getStreet(),4) - write_line(g,"city",address.getCity(),4) - write_line(g,"state",address.getState(),4) - write_line(g,"country",address.getCountry(),4) - write_line(g,"postal",address.getPostal(),4) - if address.getNote() != "": - write_note(g,"note",address.getNote(),4) - for s in address.getSourceRefList(): - dump_source_ref(g,s,4) - g.write(' \n') - - write_attribute_list(g,person.getAttributeList()) - write_url_list(g,person.getUrlList()) - - write_ref(g,"childof",person.getMainFamily(),3) - for alt in person.getAltFamilyList(): - if alt[1] != "": - mrel=' mrel="%s"' % alt[1] - else: - mrel='' - if alt[2] != "": - frel=' frel="%s"' % alt[2] - else: - frel='' - g.write(" \n" % \ - (alt[0].getId(), mrel, frel)) - - for family in person.getFamilyList(): - write_ref(g,"parentin",family,3) - - write_note(g,"note",person.getNote(),3) - - g.write(" \n") - g.write(" \n") - - if len(familyList) > 0: - g.write(" \n") - - for family in familyList: - if callback and count % delta == 0: - callback(float(count)/float(total)) - count = count + 1 - - write_family_id(g,family,2) - write_ref(g,"father",family.getFather(),3) - write_ref(g,"mother",family.getMother(),3) - pos = family.getPosition() - if pos != None: - g.write(' \n'% pos) - - for event in family.getEventList(): - dump_event(g,event,3) - dump_ordinance(g,"sealed_to_spouse",family.getLdsSeal(),3) - - write_photo_list(g,family.getPhotoList()) - - if len(family.getChildList()) > 0: - for person in family.getChildList(): - write_ref(g,"child",person,3) - write_attribute_list(g,family.getAttributeList()) - write_note(g,"note",family.getNote(),3) - g.write("
\n") - g.write(" \n") - - if len(sourceList) > 0: - g.write(" \n") - for source in sourceList: - g.write(" \n") - write_force_line(g,"stitle",source.getTitle(),3) - write_line(g,"sauthor",source.getAuthor(),3) - write_line(g,"spubinfo",source.getPubInfo(),3) - write_line(g,"scallno",source.getCallNumber(),3) - if source.getNote() != "": - write_note(g,"note",source.getNote(),3) - write_photo_list(g,source.getPhotoList()) - g.write(" \n") - g.write(" \n") - - if len(placeList) > 0: - g.write(" \n") - for place in placeList: - write_place_obj(g,place) - g.write(" \n") - - if len(objList) > 0: - g.write(" \n") - for object in objList: - write_object(g,object) - g.write(" \n") - - if len(database.getBookmarks()) > 0: - g.write(" \n") - for person in database.getBookmarks(): - g.write(' \n' % person.getId()) - g.write(" \n") - - g.write("\n") - diff --git a/gramps/src/gramps.glade b/gramps/src/gramps.glade index 58b6ba8b2..5acad731b 100644 --- a/gramps/src/gramps.glade +++ b/gramps/src/gramps.glade @@ -2185,29 +2185,117 @@ - GtkLabel + GtkHBox CList:title - glabel13 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 + hbox70 + True + 0 + + + GtkHBox + hbox71 + False + 0 + + 0 + False + False + + + + GtkLabel + CList:title + label294 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkArrow + cIDSort + 10 + 10 + False + GTK_ARROW_DOWN + GTK_SHADOW_OUT + 0.5 + 0.5 + 0 + 0 + + 5 + False + True + + + - GtkLabel + GtkHBox CList:title - label14 - - GTK_JUSTIFY_CENTER - False - 0.5 - 0.5 - 0 - 0 + hbox72 + True + 0 + + + GtkHBox + hbox73 + False + 0 + + 0 + False + False + + + + GtkLabel + CList:title + label295 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + + + GtkArrow + cGenderSort + 10 + 10 + False + GTK_ARROW_DOWN + GTK_SHADOW_OUT + 0.5 + 0.5 + 0 + 0 + + 5 + False + True + + + diff --git a/gramps/src/gramps_main.py b/gramps/src/gramps_main.py index cc90764f2..df1458397 100755 --- a/gramps/src/gramps_main.py +++ b/gramps/src/gramps_main.py @@ -118,11 +118,14 @@ DataFilter = Filter.Filter("") c_birth_order = 0 c_name = 1 c_id = 2 +c_gender = 3 c_birth_date = 4 c_details = 6 c_sort_column = c_birth_order c_sort_direct = GTK.SORT_ASCENDING cNameArrow = None +cGenderArrow = None +cIDArrow = None cDateArrow = None #------------------------------------------------------------------------- @@ -843,7 +846,7 @@ def set_sort_arrow(column,direct): else: arrow.set(GTK.ARROW_UP,2) -def change_sort(column): +def change_sort(column,change=1): global sort_direct global sort_column @@ -855,22 +858,24 @@ def change_sort(column): a.hide() arrow.show() - if sort_column == column: - if sort_direct == GTK.SORT_DESCENDING: - sort_direct = GTK.SORT_ASCENDING - arrow.set(GTK.ARROW_DOWN,2) - else: - sort_direct = GTK.SORT_DESCENDING - arrow.set(GTK.ARROW_UP,2) - else: - sort_direct = GTK.SORT_ASCENDING - arrow.set(GTK.ARROW_DOWN,2) - sort_column = column - person_list.set_sort_column(col_map[column]) person_list.set_sort_type(sort_direct) sort_person_list() + + if change: + if sort_column == column: + if sort_direct == GTK.SORT_DESCENDING: + sort_direct = GTK.SORT_ASCENDING + arrow.set(GTK.ARROW_DOWN,2) + else: + sort_direct = GTK.SORT_DESCENDING + arrow.set(GTK.ARROW_UP,2) + else: + sort_direct = GTK.SORT_ASCENDING + arrow.set(GTK.ARROW_DOWN,2) + sort_column = column + if id2col.has_key(active_person): row = person_list.find_row_from_data(id2col[active_person]) person_list.moveto(row) @@ -997,9 +1002,13 @@ def on_child_list_select_row(obj,row,b,c): #------------------------------------------------------------------------- def on_child_list_click_column(clist,column): if column == c_name: - child_change_sort(clist,c_name,gtop.get_widget("cNameSort")) + child_change_sort(clist,c_name,cNameArrow) + elif column == c_gender: + child_change_sort(clist,c_gender,cGenderArrow) + elif column == c_id: + child_change_sort(clist,c_id,cIDArrow) elif (column == c_birth_order) or (column == c_birth_date): - child_change_sort(clist,c_birth_order,gtop.get_widget("cDateSort")) + child_change_sort(clist,c_birth_order,cDateArrow) else: return @@ -1019,6 +1028,8 @@ def child_change_sort(clist,column,arrow): cNameArrow.hide() cDateArrow.hide() + cIDArrow.hide() + cGenderArrow.hide() arrow.show() if c_sort_column == column: @@ -1034,7 +1045,6 @@ def child_change_sort(clist,column,arrow): clist.set_sort_type(c_sort_direct) clist.set_sort_column(c_sort_column) clist.set_reorderable(c_sort_column == c_birth_order) - def sort_child_list(clist): clist.freeze() @@ -1982,7 +1992,7 @@ def main(arg): global person_list global topWindow, preview, merge_button global nameArrow, dateArrow, deathArrow, idArrow, genderArrow - global cNameArrow, cDateArrow, toolbar + global cNameArrow, cDateArrow, cIDArrow, cGenderArrow, toolbar global sort_column, sort_direct gtk.rc_parse(const.gtkrcFile) @@ -2027,6 +2037,8 @@ def main(arg): media_view = MediaView(database,gtop,update_display) cNameArrow = gtop.get_widget("cNameSort") + cGenderArrow= gtop.get_widget("cGenderSort") + cIDArrow = gtop.get_widget("cIDSort") cDateArrow = gtop.get_widget("cDateSort") person_list.set_column_visibility(5,0) person_list.set_column_visibility(6,0) @@ -2040,8 +2052,9 @@ def main(arg): topWindow.set_icon(gtk.GtkPixmap(topWindow,const.icon)) person_list.column_titles_active() + + change_sort(sort_column,sort_direct==GTK.SORT_DESCENDING) set_sort_arrow(sort_column,sort_direct) - change_sort(sort_column) gtop.signal_autoconnect({ "delete_event" : delete_event, diff --git a/gramps/src/plugins/DetAncestralReport.py b/gramps/src/plugins/DetAncestralReport.py index f4a11675f..38bc67fd0 100644 --- a/gramps/src/plugins/DetAncestralReport.py +++ b/gramps/src/plugins/DetAncestralReport.py @@ -94,7 +94,7 @@ class DetAncestorReport(Report): self.doc.start_paragraph("ChildList") t= child.getPrimaryName().getRegularName() #print "getBirth()", child.getBirth().__dict__ - if child.getBirth().getDate() != "" and \ + if child.getBirth().getDate() != "" or \ child.getBirth().getPlaceName() != "": #print child.getBirth().getPlace().__dict__ t= t+ _(" Born: ")+child.getBirth().getDate() + \ @@ -339,7 +339,7 @@ class DetAncestorReport(Report): elif fulldate == "" and place != "": t= _(" %s married %s in %s." % (heshe, spouse, place)) elif fulldate != "" and place == "": - t= _(" %s married %s on %s" % (heshe, spouse, fulldate)) + t= _(" %s married %s on %s." % (heshe, spouse, fulldate)) else: t= _(" %s married %s on %s in %s." % \ (heshe, spouse, fulldate, place)) else: @@ -348,7 +348,7 @@ class DetAncestorReport(Report): elif fulldate == "" and place != "": t= _(" %s married in %s." % (heshe, place)) elif fulldate != "" and place == "": - t= _(" %s married on %s" % (heshe, fulldate)) + t= _(" %s married on %s." % (heshe, fulldate)) else: t= _(" %s married on %s in %s." % \ (heshe, fulldate, place)) @@ -700,11 +700,11 @@ class reportOptions: if birth.getDayValid() and death.getDayValid(): if birth.getMonth() == death.getMonth() and birth.getDay() > death.getDay(): self.age= self.age -1 - self.units= "month" if self.age == 0: self.age= death.getMonth() - birth.getMonth() # calc age in months if birth.getDay() > death.getDay(): self.age= self.age - 1 + self.units= "month" if self.age == 0: self.age= death.getDay() + 31 - birth.getDay() # calc age in days self.units= "day"