diff --git a/gramps2/ChangeLog b/gramps2/ChangeLog index a7b38be0d..ad602237f 100644 --- a/gramps2/ChangeLog +++ b/gramps2/ChangeLog @@ -1,3 +1,21 @@ +2004-08-23 Don Allingham + * src/Utils.py: produce less line noise when generating + handles + * src/WriteGedcom.py: save CHAN records + * src/WriteXML.py: save handles and time stamps + * src/GrampsDbBase.py: make the find_xxx_from_handle functions + consistent and correct (handle ids correctly) + * src/DisplayModels.py: add last change column + * src/PeopleModel.py: add last change column + * src/PeopleView.py: add last change column + * src/MediaView.py: add last change column + * src/SourceView.py: add last change column + * src/EditPerson.py: display last change timestamps + * src/EditPlace.py: display last change timestamps + * src/Marriage.py: display last change timestamps + * src/ReadXML.py: set last change time + * src/gramps.glade: updates for last change display + 2004-08-23 Alex Roitman * src/RelLib.py: (probably_alive): Fixed typo (bug #1014223). * src/NameEdit.py: Proper use of ComboBoxEntry widgets (#1014238). diff --git a/gramps2/src/DisplayModels.py b/gramps2/src/DisplayModels.py index 5583e19da..fd746e5f6 100644 --- a/gramps2/src/DisplayModels.py +++ b/gramps2/src/DisplayModels.py @@ -18,6 +18,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +import time + #------------------------------------------------------------------------- # # GNOME/GTK modules @@ -130,16 +132,13 @@ class SourceModel(BaseModel): self.column_author, self.column_abbrev, self.column_pubinfo, - self.column_handle, + self.column_change, ] BaseModel.__init__(self,db) def column_title(self,data): return unicode(data[2]) - def column_handle(self,data): - return unicode(data[0]) - def column_author(self,data): return unicode(data[3]) @@ -152,6 +151,9 @@ class SourceModel(BaseModel): def column_pubinfo(self,data): return unicode(data[5]) + def column_change(self,data): + return unicode(time.asctime(time.localtime(data[8]))) + #------------------------------------------------------------------------- # # PlaceModel @@ -172,16 +174,17 @@ class PlaceModel(BaseModel): self.column_country, self.column_longitude, self.column_latitude, + self.column_change, self.column_handle, ] BaseModel.__init__(self,db) - def column_name(self,data): - return unicode(data[2]) - def column_handle(self,data): return unicode(data[0]) + def column_name(self,data): + return unicode(data[2]) + def column_longitude(self,data): return unicode(data[3]) @@ -221,6 +224,9 @@ class PlaceModel(BaseModel): except: return u'' + def column_change(self,data): + return unicode(time.asctime(time.localtime(data[11]))) + #------------------------------------------------------------------------- # # MediaModel @@ -237,6 +243,8 @@ class MediaModel(BaseModel): self.column_id, self.column_mime, self.column_path, + self.column_change, + self.column_handle, ] BaseModel.__init__(self,db) @@ -251,3 +259,9 @@ class MediaModel(BaseModel): def column_id(self,data): return unicode(data[1]) + + def column_handle(self,data): + return unicode(data[0]) + + def column_change(self,data): + return unicode(time.asctime(time.localtime(data[8]))) diff --git a/gramps2/src/EditPerson.py b/gramps2/src/EditPerson.py index f8d0a460f..525759f69 100644 --- a/gramps2/src/EditPerson.py +++ b/gramps2/src/EditPerson.py @@ -25,8 +25,8 @@ # Standard python modules # #------------------------------------------------------------------------- -import string import pickle +import time #------------------------------------------------------------------------- # @@ -209,6 +209,7 @@ class EditPerson: self.inet_label = self.get_widget("inet_label") self.gallery_label = self.get_widget("gallery_label") self.lds_tab = self.get_widget("lds_tab") + self.get_widget("changed").set_text(person.get_change_display()) self.orig_birth = self.db.get_event_from_handle(person.get_birth_handle()) self.orig_death = self.db.get_event_from_handle(person.get_death_handle()) @@ -458,7 +459,7 @@ class EditPerson: self.window.destroy() def add_itself_to_winsmenu(self): - self.parent.child_windows[self.orig_id] = self + self.parent.child_windows[self.orig_handle] = self win_menu_label = GrampsCfg.get_nameof()(self.person) if not win_menu_label.strip(): win_menu_label = _("New Person") @@ -473,7 +474,7 @@ class EditPerson: self.winsmenu.append(self.menu_item) def remove_itself_from_winsmenu(self): - del self.parent.child_windows[self.orig_id] + del self.parent.child_windows[self.orig_handle] self.menu_item.destroy() self.winsmenu.destroy() self.win_menu_item.destroy() @@ -1126,8 +1127,8 @@ class EditPerson: if self.lds_not_loaded == 0 and self.check_lds(): changed = 1 - bplace = unicode(string.strip(self.bplace.get_text())) - dplace = unicode(string.strip(self.dplace.get_text())) + bplace = unicode(self.bplace.get_text().strip()) + dplace = unicode(self.dplace.get_text().strip()) if self.pdmap.has_key(bplace): self.birth.set_place_handle(self.pdmap[bplace]) @@ -1620,7 +1621,7 @@ class EditPerson: self.close() def get_place(self,field,makenew=0): - text = unicode(string.strip(field.get_text())) + text = unicode(field.get_text().strip()) if text: if self.pdmap.has_key(text): return self.pdmap[text] diff --git a/gramps2/src/EditPlace.py b/gramps2/src/EditPlace.py index 13aebc5a0..5570d60fd 100644 --- a/gramps2/src/EditPlace.py +++ b/gramps2/src/EditPlace.py @@ -114,6 +114,8 @@ class EditPlace: self.web_edit = self.top_window.get_widget("web_edit") self.web_description = self.top_window.get_widget("url_des") + self.top_window.get_widget('changed').set_text(place.get_change_display()) + # event display self.web_model = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING) self.build_columns(self.web_list, [(_('Path'),150), (_('Description'),150)]) diff --git a/gramps2/src/GrampsBSDDB.py b/gramps2/src/GrampsBSDDB.py index a61d1318e..9cc9ff511 100644 --- a/gramps2/src/GrampsBSDDB.py +++ b/gramps2/src/GrampsBSDDB.py @@ -21,6 +21,7 @@ # $Id$ import os +import time from RelLib import * from GrampsDbBase import * @@ -83,12 +84,27 @@ class GrampsBSDDB(GrampsDbBase): self.fid_trans.set_flags(db.DB_DUP) self.fid_trans.open(name, "fidtrans", db.DB_HASH, flags=db.DB_CREATE) + self.pid_trans = db.DB(self.env) + self.pid_trans.set_flags(db.DB_DUP) + self.pid_trans.open(name, "pidtrans", db.DB_HASH, flags=db.DB_CREATE) + + self.sid_trans = db.DB(self.env) + self.sid_trans.set_flags(db.DB_DUP) + self.sid_trans.open(name, "sidtrans", db.DB_HASH, flags=db.DB_CREATE) + + self.oid_trans = db.DB(self.env) + self.oid_trans.set_flags(db.DB_DUP) + self.oid_trans.open(name, "oidtrans", db.DB_HASH, flags=db.DB_CREATE) + self.eventnames = db.DB(self.env) self.eventnames.set_flags(db.DB_DUP) self.eventnames.open(name, "eventnames", db.DB_HASH, flags=db.DB_CREATE) - self.person_map.associate(self.surnames, find_surname, db.DB_CREATE) - self.person_map.associate(self.id_trans, find_idmap, db.DB_CREATE) - self.person_map.associate(self.fid_trans, find_fidmap, db.DB_CREATE) + self.person_map.associate(self.surnames, find_surname, db.DB_CREATE) + self.person_map.associate(self.id_trans, find_idmap, db.DB_CREATE) + self.family_map.associate(self.fid_trans, find_idmap, db.DB_CREATE) + self.place_map.associate(self.pid_trans, find_idmap, db.DB_CREATE) + self.media_map.associate(self.oid_trans, find_idmap, db.DB_CREATE) + self.source_map.associate(self.sid_trans, find_idmap, db.DB_CREATE) self.event_map.associate(self.eventnames, find_eventname, db.DB_CREATE) self.undodb = db.DB() @@ -115,6 +131,9 @@ class GrampsBSDDB(GrampsDbBase): self.eventnames.close() self.id_trans.close() self.fid_trans.close() + self.oid_trans.close() + self.sid_trans.close() + self.pid_trans.close() self.env.close() self.undodb.close() @@ -189,8 +208,8 @@ class GrampsBSDDB(GrampsDbBase): return None def get_family_from_gramps_id(self,val): - """finds a Person in the database from the passed gramps' ID. - If no such Person exists, a new Person is added to the database.""" + """finds a Family in the database from the passed gramps' ID. + If no such Family exists, a new Person is added to the database.""" data = self.fid_trans.get(str(val)) if data: @@ -199,3 +218,39 @@ class GrampsBSDDB(GrampsDbBase): return family else: return None + + def get_place_from_gramps_id(self,val): + """finds a Place in the database from the passed gramps' ID. + If no such Place exists, a new Person is added to the database.""" + + data = self.pid_trans.get(str(val)) + if data: + place = Place() + place.unserialize(cPickle.loads(data)) + return place + else: + return None + + def get_source_from_gramps_id(self,val): + """finds a Source in the database from the passed gramps' ID. + If no such Source exists, a new Person is added to the database.""" + + data = self.sid_trans.get(str(val)) + if data: + source = Source() + source.unserialize(cPickle.loads(data)) + return source + else: + return None + + def get_object_from_gramps_id(self,val): + """finds a MediaObject in the database from the passed gramps' ID. + If no such MediaObject exists, a new Person is added to the database.""" + + data = self.oid_trans.get(str(val)) + if data: + obj = MediaObject() + obj.unserialize(cPickle.loads(data)) + return obj + else: + return None diff --git a/gramps2/src/GrampsDbBase.py b/gramps2/src/GrampsDbBase.py index 25eb36565..10ab62ba9 100644 --- a/gramps2/src/GrampsDbBase.py +++ b/gramps2/src/GrampsDbBase.py @@ -32,6 +32,7 @@ from this class. #------------------------------------------------------------------------- from RelLib import * import cPickle +import time from gettext import gettext as _ #------------------------------------------------------------------------- @@ -79,7 +80,11 @@ class GrampsDbBase: self.open = 0 self.genderStats = GenderStats() - self.id_trans = None + self.id_trans = None + self.fid_trans = None + self.pid_trans = None + self.sid_trans = None + self.oid_trans = None self.env = None self.person_map = None self.family_map = None @@ -121,66 +126,91 @@ class GrampsDbBase: """ return self.person_map != None - def commit_person(self,person,transaction): + def commit_person(self,person,transaction,change_time=None): """ Commits the specified Person to the database, storing the changes as part of the transaction. """ + + if change_time: + person.change = int(change_time) + else: + person.change = int(time.time()) handle = str(person.get_handle()) if transaction != None: old_data = self.person_map.get(handle) transaction.add(PERSON_KEY,handle,old_data) self.person_map[handle] = person.serialize() - def commit_media_object(self,obj,transaction): + def commit_media_object(self,obj,transaction,change_time=None): """ Commits the specified MediaObject to the database, storing the changes as part of the transaction. """ + if change_time: + obj.change = int(change_time) + else: + obj.change = int(time.time()) handle = str(obj.get_handle()) if transaction != None: old_data = self.media_map.get(handle) transaction.add(MEDIA_KEY,handle,old_data) self.media_map[handle] = obj.serialize() - def commit_source(self,source,transaction): + def commit_source(self,source,transaction,change_time=None): """ Commits the specified Source to the database, storing the changes as part of the transaction. """ + if change_time: + source.change = int(change_time) + else: + source.change = int(time.time()) handle = str(source.get_handle()) if transaction != None: old_data = self.source_map.get(handle) transaction.add(SOURCE_KEY,handle,old_data) self.source_map[handle] = source.serialize() - def commit_place(self,place,transaction): + def commit_place(self,place,transaction,change_time=None): """ Commits the specified Place to the database, storing the changes as part of the transaction. """ + if change_time: + place.change = int(change_time) + else: + place.change = int(time.time()) handle = str(place.get_handle()) if transaction != None: old_data = self.place_map.get(handle) transaction.add(PLACE_KEY,handle,old_data) self.place_map[handle] = place.serialize() - def commit_event(self,event,transaction): + def commit_event(self,event,transaction,change_time=None): """ Commits the specified Event to the database, storing the changes as part of the transaction. """ + if change_time: + event.change = int(change_time) + else: + event.change = int(time.time()) handle = str(event.get_handle()) if transaction != None: old_data = self.event_map.get(handle) transaction.add(EVENT_KEY,handle,old_data) self.event_map[handle] = event.serialize() - def commit_family(self,family,transaction): + def commit_family(self,family,transaction,change_time=None): """ Commits the specified Family to the database, storing the changes as part of the transaction. """ + if change_time: + family.change = int(change_time) + else: + family.change = int(time.time()) handle = str(family.get_handle()) if transaction != None: old_data = self.family_map.get(handle) @@ -205,7 +235,7 @@ class GrampsDbBase: off the person ID prefix. """ index = self.pprefix % self.lmap_index - while self.id_trans.get(str(index)): + while self.pid_trans.get(str(index)): self.lmap_index += 1 index = self.pprefix % self.lmap_index self.lmap_index += 1 @@ -217,9 +247,6 @@ class GrampsDbBase: off the person ID prefix. """ index = self.eprefix % self.emap_index - while self.id_trans.get(str(index)): - self.emap_index += 1 - index = self.eprefix % self.emap_index self.emap_index += 1 return index @@ -229,7 +256,7 @@ class GrampsDbBase: off the person ID prefix. """ index = self.oprefix % self.omap_index - while self.id_trans.get(str(index)): + while self.oid_trans.get(str(index)): self.omap_index += 1 index = self.oprefix % self.omap_index self.omap_index += 1 @@ -241,10 +268,10 @@ class GrampsDbBase: off the person ID prefix. """ index = self.sprefix % self.smap_index - while self.source_map.get(str(index)): + while self.sid_trans.get(str(index)): self.smap_index += 1 index = self.sprefix % self.smap_index - self.fmap_index += 1 + self.smap_index += 1 return index def find_next_family_gramps_id(self): @@ -253,7 +280,7 @@ class GrampsDbBase: off the person ID prefix. """ index = self.fprefix % self.fmap_index - while self.family_map.get(str(index)): + while self.fid_trans.get(str(index)): self.fmap_index += 1 index = self.fprefix % self.fmap_index self.fmap_index += 1 @@ -350,11 +377,7 @@ class GrampsDbBase: source.unserialize(self.source_map.get(str(val))) else: source.set_handle(val) - source.set_gramps_id(val) - if transaction != None: - transaction.add(SOURCE_KEY,val,None) - self.source_map[str(val)] = source.serialize() - self.smap_index = self.smap_index + 1 + self.add_source(source,transaction) return source def find_event_from_handle(self,val,transaction): @@ -368,10 +391,7 @@ class GrampsDbBase: event.unserialize(data) else: event.set_handle(val) - if transaction: - transaction.add(EVENT_KEY,val,None) - self.event_map[str(val)] = event.serialize() - self.emap_index = self.emap_index + 1 + self.add_event(event,transaction) return event def find_object_from_handle(self,handle,transaction): @@ -392,16 +412,12 @@ class GrampsDbBase: Finds a Place in the database from the passed GRAMPS ID. If no such Place exists, a new Place is added to the database. """ - data = self.place_map.get(str(handle)) place = Place() - if not data: - place.set_handle(handle) - if transaction != None: - transaction.add(PLACE_KEY,handle,None) - self.place_map[str(handle)] = place.serialize() - self.lmap_index = self.lmap_index + 1 + if self.place_map.get(str(handle)): + place.unserialize(self.place_map.get(str(handle))) else: - place.unserialize(data) + place.set_handle(handle) + self.add_place(place,transaction) return place def find_family_from_handle(self,val,transaction): @@ -409,15 +425,11 @@ class GrampsDbBase: If no such Family exists, a new Family is added to the database.""" family = Family() - data = self.family_map.get(str(val)) - if data: - family.unserialize(data) + if self.family_map.get(str(val)): + family.unserialize(self.family_map.get(str(val))) else: family.set_handle(val) - if transaction: - transaction.add(FAMILY_KEY,val,None) - self.family_map[str(val)] = family.serialize() - self.fmap_index = self.fmap_index + 1 + self.add_family(family,transaction) return family def get_person_from_gramps_id(self,val): @@ -427,13 +439,7 @@ class GrampsDbBase: Needs to be overridden by the derrived class. """ - data = self.id_trans.get(str(val)) - if data: - person = Person() - person.unserialize(cPickle.loads(data)) - return person - else: - return None + assert(False,"Needs to be overridden in the derived class") def get_family_from_gramps_id(self,val): """ @@ -991,7 +997,7 @@ class GrampsDbBase: Returns the Person display common information stored in the database's metadata. """ - default = [(1,1),(1,2),(1,3),(0,4),(1,5),(0,6),(0,7)] + default = [(1,1),(1,2),(1,3),(0,4),(1,5),(0,6),(0,7),(0,8)] if self.metadata == None: return default else: @@ -1006,7 +1012,7 @@ class GrampsDbBase: Returns the Place display common information stored in the database's metadata. """ - default = [(1,1),(1,2),(0,3),(1,4),(0,5),(1,6),(0,7),(0,8)] + default = [(1,1),(1,2),(0,3),(1,4),(0,5),(1,6),(0,7),(0,8),(0,9)] if self.metadata == None: return default else: @@ -1021,7 +1027,7 @@ class GrampsDbBase: Returns the Source display common information stored in the database's metadata. """ - default = [(1,1),(1,2),(1,3),(0,4)] + default = [(1,1),(1,2),(1,3),(0,4),(0,5)] if self.metadata == None: return default else: @@ -1036,11 +1042,11 @@ class GrampsDbBase: Returns the MediaObject display common information stored in the database's metadata. """ - default = [(1,1),(1,2),(1,3)] + default = [(1,1),(1,2),(1,3),(0,4)] if self.metadata == None: return default else: - cols = self.metadata.get('meda_columns',default) + cols = self.metadata.get('media_columns',default) if len(cols) != len(default): return cols + default[len(cols):] else: diff --git a/gramps2/src/Marriage.py b/gramps2/src/Marriage.py index 3e4d58be2..0e6a9cbeb 100644 --- a/gramps2/src/Marriage.py +++ b/gramps2/src/Marriage.py @@ -186,6 +186,8 @@ class Marriage: self.alist = family.get_attribute_list()[:] self.lists_changed = 0 + self.get_widget('changed').set_text(family.get_change_display()) + # set initial data self.gallery.load_images() diff --git a/gramps2/src/MediaView.py b/gramps2/src/MediaView.py index e339b3633..bede9771b 100644 --- a/gramps2/src/MediaView.py +++ b/gramps2/src/MediaView.py @@ -64,6 +64,7 @@ column_names = [ _('ID'), _('Type'), _('Path'), + _('Last Changed'), ] #------------------------------------------------------------------------- diff --git a/gramps2/src/PeopleModel.py b/gramps2/src/PeopleModel.py index ebfca3806..f0c692813 100644 --- a/gramps2/src/PeopleModel.py +++ b/gramps2/src/PeopleModel.py @@ -26,6 +26,7 @@ # #------------------------------------------------------------------------- from gettext import gettext as _ +import time #------------------------------------------------------------------------- # @@ -50,7 +51,7 @@ import accent # #------------------------------------------------------------------------- COLUMN_NAME = 0 -COLUMN_VIEW = 6 +COLUMN_VIEW = 9 COLUMN_BOLD = COLUMN_VIEW + 1 COLUMN_INT_ID = COLUMN_BOLD + 1 @@ -61,6 +62,7 @@ _NAME_COL = 3 _DEATH_COL = 6 _BIRTH_COL = 7 _FAMILY_COL= 9 +_CHANGE_COL= 21 #------------------------------------------------------------------------- # @@ -85,6 +87,7 @@ class PeopleModel(gtk.GenericTreeModel): self.column_death_day, self.column_death_place, self.column_spouse, + self.column_change, self.sort_name, ] @@ -290,6 +293,9 @@ class PeopleModel(gtk.GenericTreeModel): def column_id(self,data): return data[_ID_COL] + def column_change(self,data): + return time.asctime(time.localtime(data[_CHANGE_COL])) + def column_gender(self,data): return _GENDER[data[_GENDER_COL]] diff --git a/gramps2/src/PeopleView.py b/gramps2/src/PeopleView.py index c8c442f59..dcb61ba23 100644 --- a/gramps2/src/PeopleView.py +++ b/gramps2/src/PeopleView.py @@ -55,6 +55,7 @@ column_names = [ _('Death Date'), _('Death Place'), _('Spouse'), + _('Last Change'), ] #------------------------------------------------------------------------- @@ -92,7 +93,8 @@ class PeopleView: for column in self.columns: self.person_tree.remove_column(column) - column = gtk.TreeViewColumn(_('Name'), self.renderer,text=0,weight=PeopleModel.COLUMN_BOLD) + column = gtk.TreeViewColumn(_('Name'), self.renderer,text=0, + weight=PeopleModel.COLUMN_BOLD) column.set_resizable(gtk.TRUE) column.set_min_width(225) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) diff --git a/gramps2/src/PlaceView.py b/gramps2/src/PlaceView.py index b91867246..b1a3f7450 100644 --- a/gramps2/src/PlaceView.py +++ b/gramps2/src/PlaceView.py @@ -58,6 +58,7 @@ column_names = [ _('Country'), _('Longitude'), _('Latitude'), + _('Last Changed'), ] _HANDLE_COL = len(column_names) @@ -237,6 +238,7 @@ class PlaceView: EditPlace.EditPlace(self.parent, place, self.update_display) def blist(self,store,path,iter,list): + print iter, _HANDLE_COL handle = self.parent.db.get_place_from_handle(store.get_value(iter,_HANDLE_COL)) list.append(handle) diff --git a/gramps2/src/ReadXML.py b/gramps2/src/ReadXML.py index f8bb96df3..c6e683963 100644 --- a/gramps2/src/ReadXML.py +++ b/gramps2/src/ReadXML.py @@ -30,8 +30,8 @@ import os import gtk import shutil import xml.parsers.expat -import Utils from gettext import gettext as _ +import time #------------------------------------------------------------------------- # @@ -44,6 +44,7 @@ import Date import GrampsMime import RelLib import const +import Utils #------------------------------------------------------------------------- # @@ -75,7 +76,8 @@ def importData(database, filename, callback=None,cl=0): database.pmap = {} database.fmap = {} - parser = GrampsParser(database,callback,basefile) + change = os.path.getmtime(filename) + parser = GrampsParser(database,callback,basefile,change) if gzip_ok: use_gzip = 1 @@ -168,7 +170,7 @@ def importData(database, filename, callback=None,cl=0): except: pass mobject.set_path(newfile) - database.commit_media_object(mobject,None) + database.commit_media_object(mobject,None,self.change) except: pass @@ -271,7 +273,7 @@ def fix_spaces(text_list): #------------------------------------------------------------------------- class GrampsParser: - def __init__(self,database,callback,base): + def __init__(self,database,callback,base,change): self.stext_list = [] self.scomments_list = [] self.note_list = [] @@ -279,6 +281,10 @@ class GrampsParser: self.conf = 2 self.gid2id = {} self.gid2fid = {} + self.gid2pid = {} + self.gid2oid = {} + self.gid2sid = {} + self.change = change self.ord = None self.objref = None @@ -324,6 +330,7 @@ class GrampsParser: self.event = None self.name = None self.tempDefault = None + self.home = None self.owner = RelLib.Researcher() self.func_list = [None]*50 self.func_index = 0 @@ -331,6 +338,10 @@ class GrampsParser: self.witness_comment = "" self.idswap = {} self.fidswap = {} + self.sidswap = {} + self.pidswap = {} + self.oidswap = {} + self.eidswap = {} self.func_map = { "address" : (self.start_address, self.stop_address), @@ -441,6 +452,45 @@ class GrampsParser: self.gid2fid[gramps_id] = intid return family + def find_place_by_gramps_id(self,gramps_id): + intid = self.gid2pid.get(gramps_id) + if intid: + place = self.db.get_place_from_handle(intid) + else: + intid = Utils.create_id() + place = RelLib.Place() + place.set_handle(intid) + place.set_gramps_id(gramps_id) + self.db.add_place(place,self.trans) + self.gid2pid[gramps_id] = intid + return place + + def find_source_by_gramps_id(self,gramps_id): + intid = self.gid2sid.get(gramps_id) + if intid: + source = self.db.get_source_from_handle(intid) + else: + intid = Utils.create_id() + source = RelLib.Source() + source.set_handle(intid) + source.set_gramps_id(gramps_id) + self.db.add_source(source,self.trans) + self.gid2sid[gramps_id] = intid + return source + + def find_object_by_gramps_id(self,gramps_id): + intid = self.gid2oid.get(gramps_id) + if intid: + obj = self.db.get_object_from_handle(intid) + else: + intid = Utils.create_id() + obj = RelLib.MediaObject() + obj.set_handle(intid) + obj.set_gramps_id(gramps_id) + self.db.add_object(obj,self.trans) + self.gid2oid[gramps_id] = intid + return obj + def map_gid(self,id): if not self.idswap.get(id): if self.db.get_person_from_gramps_id(id): @@ -457,6 +507,30 @@ class GrampsParser: self.fidswap[id] = id return self.fidswap[id] + def map_pid(self,id): + if not self.pidswap.get(id): + if self.db.get_place_from_gramps_id(id): + self.pidswap[id] = self.db.find_next_place_gramps_id() + else: + self.pidswap[id] = id + return self.pidswap[id] + + def map_sid(self,id): + if not self.sidswap.get(id): + if self.db.get_source_from_gramps_id(id): + self.sidswap[id] = self.db.find_next_source_gramps_id() + else: + self.sidswap[id] = id + return self.sidswap[id] + + def map_oid(self,id): + if not self.oidswap.get(id): + if self.db.get_object_from_gramps_id(id): + self.oidswap[id] = self.db.find_next_object_gramps_id() + else: + self.oidswap[id] = id + return self.oidswap[id] + def parse(self,file): self.trans = self.db.transaction_begin() p = xml.parsers.expat.ParserCreate() @@ -466,6 +540,9 @@ class GrampsParser: p.ParseFile(file) self.db.set_researcher(self.owner) + if self.home != None: + person = self.db.find_person_from_handle(self.home,self.trans) + self.db.set_default_person_handle(person.get_handle()) if self.tempDefault != None: id = self.map_gid(self.tempDefault) person = self.find_person_by_gramps_id(id) @@ -500,14 +577,27 @@ class GrampsParser: self.ord.set_status(int(attrs['val'])) def start_sealed_to(self,attrs): - id = self.map_fid(attrs['ref']) - self.ord.set_family_handle(self.find_family_by_gramps_id(id)) + try: + family = self.db.find_family_from_handle(attrs['hlink'],self.trans) + except KeyError: + id = self.map_fid(attrs['ref']) + family = self.find_family_by_gramps_id(id) + self.ord.set_family_handle(family.get_handle()) def start_place(self,attrs): - self.placeobj = self.db.find_place_from_handle(attrs['ref'],self.trans) + try: + self.placeobj = self.db.find_place_from_handle(attrs['hlink'],self.trans) + except KeyError: + id = self.map_pid(attrs['ref']) + self.placeobj = self.find_place_by_gramps_id(id) def start_placeobj(self,attrs): - self.placeobj = self.db.find_place_from_handle(attrs['id'],self.trans) + id = self.map_pid(attrs['id']) + try: + self.placeobj = self.db.find_place_from_handle(attrs['handle'],self.trans) + self.placeobj.set_gramps_id(id) + except KeyError: + self.placeobj = self.find_place_by_gramps_id(id) title = attrs['title'] if title == "": title = attrs['id'] @@ -601,8 +691,11 @@ class GrampsParser: self.address.private = int(attrs["priv"]) def start_bmark(self,attrs): - id = self.map_gid(attrs["ref"]) - person = self.find_person_by_gramps_id(id) + try: + person = self.db.find_person_from_handle(attrs['hlink'],self.trans) + except KeyError: + id = self.map_gid(attrs["ref"]) + person = self.find_person_by_gramps_id(id) self.db.bookmarks.append(person.get_handle()) def start_person(self,attrs): @@ -611,27 +704,42 @@ class GrampsParser: self.count = self.count + 1 new_id = self.map_gid(attrs['id']) - self.person = self.find_person_by_gramps_id(new_id) + try: + self.person = self.db.find_person_from_handle(attrs['handle'],self.trans) + self.person.set_gramps_id(new_id) + except KeyError: + self.person = self.find_person_by_gramps_id(new_id) - if attrs.has_key("complete"): + try: self.person.set_complete_flag(int(attrs['complete'])) - else: + except KeyError: self.person.set_complete_flag(0) def start_people(self,attrs): + if attrs.has_key('home'): + self.home = attrs['home'] if attrs.has_key("default"): self.tempDefault = attrs["default"] def start_father(self,attrs): - person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) + try: + person = self.db.find_person_from_handle(attrs['hlink'],self.trans) + except KeyError: + person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) self.family.set_father_handle(person.get_handle()) def start_mother(self,attrs): - person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) + try: + person = self.db.find_person_from_handle(attrs['hlink'],self.trans) + except KeyError: + person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) self.family.set_mother_handle(person.get_handle()) def start_child(self,attrs): - person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) + try: + person = self.db.find_person_from_handle(attrs['hlink'],self.trans) + except KeyError: + person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) self.family.add_child_handle(person.get_handle()) def start_url(self,attrs): @@ -659,7 +767,12 @@ class GrampsParser: if self.callback != None and self.count % self.increment == 0: self.callback(float(self.count)/float(self.entries)) self.count = self.count + 1 - self.family = self.find_family_by_gramps_id(self.map_fid(attrs["id"])) + id = self.map_fid(attrs["id"]) + try: + self.family = self.db.find_family_from_handle(attrs["handle"],self.trans) + self.family.set_gramps_id(id) + except KeyError: + self.family = self.find_family_by_gramps_id(id) if attrs.has_key("type"): self.family.set_relationship(_FAMILY_TRANS.get(attrs["type"], @@ -670,7 +783,11 @@ class GrampsParser: self.family.set_complete_flag(0) def start_childof(self,attrs): - family = self.find_family_by_gramps_id(self.map_fid(attrs["ref"])) + try: + family = self.db.find_family_from_handle(attrs["hlink"],self.trans) + except KeyError: + family = self.find_family_by_gramps_id(self.map_fid(attrs["ref"])) + if attrs.has_key("mrel"): mrel = attrs["mrel"] else: @@ -682,7 +799,10 @@ class GrampsParser: self.person.add_parent_family_handle(family.get_handle(),mrel,frel) def start_parentin(self,attrs): - family = self.find_family_by_gramps_id(self.map_fid(attrs["ref"])) + try: + family = self.db.find_family_from_handle(attrs['hlink'],self.trans) + except KeyError: + family = self.find_family_by_gramps_id(self.map_fid(attrs["ref"])) self.person.add_family_handle(family.get_handle()) def start_name(self,attrs): @@ -709,7 +829,11 @@ class GrampsParser: def start_sourceref(self,attrs): self.source_ref = RelLib.SourceRef() - source = self.db.find_source_from_handle(attrs["ref"],self.trans) + try: + source = self.db.find_source_from_handle(attrs["hlink"],self.trans) + except KeyError: + source = self.find_source_by_gramps_id(self.map_sid(attrs["ref"])) + if attrs.has_key("conf"): self.source_ref.confidence = int(attrs["conf"]) else: @@ -739,11 +863,20 @@ class GrampsParser: self.person.add_source_reference(self.source_ref) def start_source(self,attrs): - self.source = self.db.find_source_from_handle(attrs["id"],self.trans) + id = self.map_sid(attrs["id"]) + try: + self.source = self.db.find_source_from_handle(attrs["handle"],self.trans) + self.source.set_gramps_id(id) + except KeyError: + self.source = self.find_source_by_gramps_id(id) def start_objref(self,attrs): self.objref = RelLib.MediaRef() - obj = self.db.find_object_from_handle(attrs['ref'],self.trans) + try: + obj = self.db.find_object_from_handle(attrs['hlink'],self.trans) + except KeyError: + obj = self.find_object_by_gramps_id(self.map_oid(attrs['ref'])) + id = obj.get_handle() self.objref.set_reference_handle(id) @@ -761,8 +894,12 @@ class GrampsParser: self.placeobj.add_media_reference(self.objref) def start_object(self,attrs): - self.object = self.db.find_object_from_handle(attrs['id'],self.trans) - self.object.set_gramps_id(attrs['id']) + id = self.map_oid(attrs['id']) + try: + self.object = self.db.find_object_from_handle(attrs['handle'],self.trans) + self.object.set_gramps_id(id) + except KeyError: + self.object = self.find_object_by_gramps_id(id) self.object.set_mime_type(attrs['mime']) self.object.set_description(attrs['description']) src = attrs["src"] @@ -773,7 +910,7 @@ class GrampsParser: pass def stop_object(self,*tag): - self.db.commit_media_object(self.object,self.trans) + self.db.commit_media_object(self.object,self.trans,self.change) self.object = None def stop_objref(self,*tag): @@ -919,11 +1056,11 @@ class GrampsParser: if self.placeobj.get_title() == "": loc = self.placeobj.get_main_location() self.placeobj.set_title(build_place_title(loc)) - self.db.commit_place(self.placeobj,self.trans) + self.db.commit_place(self.placeobj,self.trans,self.change) self.placeobj = None def stop_family(self,*tag): - self.db.commit_family(self.family,self.trans) + self.db.commit_family(self.family,self.trans,self.change) self.family = None def stop_event(self,*tag): @@ -938,7 +1075,7 @@ class GrampsParser: self.person.set_death_handle(self.event.get_handle()) else: self.person.add_event_handle(self.event.get_handle()) - self.db.commit_event(self.event,self.trans) + self.db.commit_event(self.event,self.trans,self.change) self.event = None def stop_name(self,tag): @@ -965,7 +1102,7 @@ class GrampsParser: self.ord.set_place_handle(self.placeobj.get_handle()) else: self.event.set_place_handle(self.placeobj.get_handle()) - self.db.commit_place(self.placeobj,self.trans) + self.db.commit_place(self.placeobj,self.trans,self.change) self.placeobj = None def stop_date(self,tag): @@ -982,7 +1119,7 @@ class GrampsParser: self.family = None def stop_person(self,*tag): - self.db.commit_person(self.person,self.trans) + self.db.commit_person(self.person,self.trans,self.change) self.person = None def stop_description(self,tag): @@ -1007,7 +1144,7 @@ class GrampsParser: self.source_ref = None def stop_source(self,*tag): - self.db.commit_source(self.source,self.trans) + self.db.commit_source(self.source,self.trans,self.change) self.source = None def stop_sauthor(self,tag): diff --git a/gramps2/src/RelLib.py b/gramps2/src/RelLib.py index 08a191d42..ee4e54d6b 100644 --- a/gramps2/src/RelLib.py +++ b/gramps2/src/RelLib.py @@ -33,6 +33,7 @@ __version__ = "$Revision$" from re import compile import os import os.path +import time import types import accent from gettext import gettext as _ @@ -82,9 +83,20 @@ class PrimaryObject: if source: self.gramps_id = source.gramps_id self.handle = source.handle + self.change = source.change else: self.gramps_id = None self.handle = None + self.change = 0 + + def get_change_time(self): + return self.change + + def get_change_display(self): + if self.change: + return time.asctime(time.localtime(self.change)) + else: + return '' def set_handle(self,handle): """Sets the database handle for the primary object""" @@ -242,7 +254,7 @@ class Person(PrimaryObject,SourceNote): self.family_list, self.parent_family_list, self.media_list, self.address_list, self.attribute_list, self.urls, self.lds_bapt, self.lds_endow, self.lds_seal, - self.complete, self.source_list, self.note) + self.complete, self.source_list, self.note, self.change) def unserialize(self,data): """ @@ -254,7 +266,8 @@ class Person(PrimaryObject,SourceNote): self.birth_handle, self.event_list, self.family_list, self.parent_family_list, self.media_list, self.address_list, self.attribute_list, self.urls, self.lds_bapt, self.lds_endow, - self.lds_seal, self.complete, self.source_list, self.note) = data + self.lds_seal, self.complete, self.source_list, self.note, + self.change) = data def set_complete_flag(self,val): """ @@ -666,7 +679,8 @@ class Family(PrimaryObject,SourceNote): return (self.handle, self.gramps_id, self.father_handle, self.mother_handle, self.child_list, self.type, self.event_list, self.media_list, self.attribute_list, self.lds_seal, - self.complete, self.source_list, self.note) + self.complete, self.source_list, self.note, + self.change) def unserialize(self, data): """ @@ -676,7 +690,7 @@ class Family(PrimaryObject,SourceNote): (self.handle, self.gramps_id, self.father_handle, self.mother_handle, self.child_list, self.type, self.event_list, self.media_list, self.attribute_list, self.lds_seal, - self.complete, self.source_list, self.note) = data + self.complete, self.source_list, self.note, self.change) = data def set_complete_flag(self,val): self.complete = val @@ -826,7 +840,8 @@ class Event(PrimaryObject,DataObj): """ return (self.handle, self.gramps_id, self.name, self.date, self.description, self.place, self.cause, self.private, - self.source_list, self.note, self.witness, self.media_list) + self.source_list, self.note, self.witness, self.media_list, + self.change) def unserialize(self,data): """ @@ -835,7 +850,7 @@ class Event(PrimaryObject,DataObj): """ (self.handle, self.gramps_id, self.name, self.date, self.description, self.place, self.cause, self.private, self.source_list, - self.note, self.witness, self.media_list) = data + self.note, self.witness, self.media_list, self.change) = data def add_media_reference(self,media_id): """Adds a MediaObject object to the Event object's image list""" @@ -1037,16 +1052,16 @@ class Place(PrimaryObject,SourceNote): """ return (self.handle, self.gramps_id, self.title, self.long, self.lat, self.main_loc, self.alt_loc, self.urls, self.media_list, - self.source_list, self.note) + self.source_list, self.note, self.change) def unserialize(self,data): """ Converts the data held in a tuple created by the serialize method back into the data in an Event structure. """ - (self.handle, self.gramps_id, self.title, self.long, self.lat, self.main_loc, - self.alt_loc, self.urls, self.media_list, self.source_list, - self.note) = data + (self.handle, self.gramps_id, self.title, self.long, self.lat, + self.main_loc, self.alt_loc, self.urls, self.media_list, + self.source_list, self.note, self.change) = data def get_url_list(self): """Return the list of URLs""" @@ -1173,7 +1188,8 @@ class MediaObject(PrimaryObject,SourceNote): a form that it can use. """ return (self.handle, self.gramps_id, self.path, self.mime, - self.desc, self.attrlist, self.source_list, self.note) + self.desc, self.attrlist, self.source_list, self.note, + self.change) def unserialize(self,data): """ @@ -1181,7 +1197,7 @@ class MediaObject(PrimaryObject,SourceNote): back into the data in an Event structure. """ (self.handle, self.gramps_id, self.path, self.mime, self.desc, - self.attrlist, self.source_list, self.note) = data + self.attrlist, self.source_list, self.note, self.change) = data def set_mime_type(self,type): self.mime = type @@ -1233,7 +1249,8 @@ class Source(PrimaryObject): def serialize(self): return (self.handle, self.gramps_id, self.title, self.author, - self.pubinfo, self.note, self.media_list, self.abbrev) + self.pubinfo, self.note, self.media_list, self.abbrev, + self.change) def unserialize(self,data): """ @@ -1241,10 +1258,12 @@ class Source(PrimaryObject): back into the data in an Event structure. """ (self.handle, self.gramps_id, self.title, self.author, - self.pubinfo, self.note, self.media_list, self.abbrev) = data + self.pubinfo, self.note, self.media_list, self.abbrev, + self.change) = data def get_display_info(self): - return [self.title,self.gramps_id,self.author,self.title.upper(),self.author.upper()] + return [self.title,self.gramps_id,self.author, + self.title.upper(),self.author.upper()] def add_media_reference(self,media_id): """Adds a MediaObject object to the Source instance's image list""" diff --git a/gramps2/src/SourceView.py b/gramps2/src/SourceView.py index 508f4a7b5..432be3ba8 100644 --- a/gramps2/src/SourceView.py +++ b/gramps2/src/SourceView.py @@ -1,4 +1,4 @@ -# + # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2001-2004 Donald N. Allingham @@ -58,6 +58,7 @@ column_names = [ _('Author'), _('Abbreviation'), _('Publication Information'), + _('Last Changed'), ] #------------------------------------------------------------------------- diff --git a/gramps2/src/StartupDialog.py b/gramps2/src/StartupDialog.py index 64416b7ed..502d81cc7 100644 --- a/gramps2/src/StartupDialog.py +++ b/gramps2/src/StartupDialog.py @@ -154,7 +154,7 @@ class StartupDialog: box.show_all() name = GrampsCfg.get_researcher_name() - if name.strip() == "": + if not name or name.strip() == "": import pwd import os diff --git a/gramps2/src/Utils.py b/gramps2/src/Utils.py index cae776995..1128464bb 100644 --- a/gramps2/src/Utils.py +++ b/gramps2/src/Utils.py @@ -542,8 +542,12 @@ def create_id(): rand.randint(0,0x7fffffff), rand.randint(0,0x7fffffff)]: while val != 0: - s += chr(val%57+65) - val = int(val/57) + rem = val % 36 + if rem <= 9: + s += chr(48+rem) + else: + s += chr(rem+55) + val = int(val/36) return s #------------------------------------------------------------------------- diff --git a/gramps2/src/WriteGedcom.py b/gramps2/src/WriteGedcom.py index 29534a713..f6881b6a3 100644 --- a/gramps2/src/WriteGedcom.py +++ b/gramps2/src/WriteGedcom.py @@ -814,6 +814,8 @@ class GedcomWriter: self.writeln('2 _STAT %s' % f[2]) break + self.write_change(1,family.get_change_time()) + # index = index + 1 # if index % 100 == 0 and not self.cl: # self.fbar.set_fraction(index/nump) @@ -844,6 +846,8 @@ class GedcomWriter: if source.get_note(): self.write_long_text("NOTE",1,self.cnvtxt(source.get_note())) index = index + 1 + self.write_change(1,source.get_change_time()) + # if index % 100 == 0 and not self.cl: # self.sbar.set_fraction(index/nump) # while(gtk.events_pending()): @@ -1069,6 +1073,19 @@ class GedcomWriter: if person.get_note(): self.write_long_text("NOTE",1,self.cnvtxt(person.get_note())) + self.write_change(1,person.get_change_time()) + + + def write_change(self,level,timeval): + tval = time.localtime(timeval) + self.writeln('%d CHAN' % level) + time_val = time.localtime(timeval) + self.writeln('%d DATE %d %s %d' % (level + 1,time_val[2], + _month[time_val[1]],time_val[0])) + self.writeln('%d TIME %02d:%02d:%02d' % (level + 2,time_val[3], + time_val[4],time_val[5])) + + def write_long_text(self,tag,level,note): if self.conc == GedcomInfo.CONC_OK: self.write_conc_ok(tag,level,note) diff --git a/gramps2/src/WriteXML.py b/gramps2/src/WriteXML.py index 19ea374a8..14ee3d149 100644 --- a/gramps2/src/WriteXML.py +++ b/gramps2/src/WriteXML.py @@ -236,7 +236,7 @@ class XmlWriter: self.g.write(" \n") keys = self.db.get_person_handles(sort_handles=False) @@ -307,12 +307,12 @@ class XmlWriter: else: frel='' parent_family = self.db.get_family_from_handle (alt[0]) - self.g.write(" \n" % \ - (parent_family.get_gramps_id (), mrel, frel)) + self.g.write(" \n" % \ + (parent_family.get_handle(), mrel, frel)) for family_handle in person.get_family_handle_list(): family = self.db.get_family_from_handle (family_handle) - self.write_ref("parentin",family.get_gramps_id (),3) + self.write_ref("parentin",family.get_handle(),3) self.write_note("note",person.get_note_object(),3) for s in person.get_source_references(): @@ -341,10 +341,10 @@ class XmlWriter: fhandle = family.get_father_handle() mhandle = family.get_mother_handle() if fhandle: - fid = self.db.get_person_from_handle (fhandle).get_gramps_id () + fid = self.db.get_person_from_handle (fhandle).get_handle() self.write_ref("father",fid,3) if mhandle: - mid = self.db.get_person_from_handle (mhandle).get_gramps_id () + mid = self.db.get_person_from_handle (mhandle).get_handle() self.write_ref("mother",mid,3) for event_handle in family.get_event_list(): event = self.db.get_event_from_handle(event_handle) @@ -356,7 +356,7 @@ class XmlWriter: if len(family.get_child_handle_list()) > 0: for person_handle in family.get_child_handle_list(): person = self.db.get_person_from_handle (person_handle) - self.write_ref("child",person.get_gramps_id (),3) + self.write_ref("child",person.get_handle(),3) self.write_attribute_list(family.get_attribute_list()) self.write_note("note",family.get_note_object(),3) for s in family.get_source_references(): @@ -373,7 +373,8 @@ class XmlWriter: if self.callback and count % delta == 0: self.callback(float(count)/float(total)) count = count + 1 - self.g.write(" \n") + self.g.write(" \n" % + (source.get_gramps_id(), source.get_handle(), source.get_change_time())) self.write_force_line("stitle",source.get_title(),3) self.write_line("sauthor",source.get_author(),3) self.write_line("spubinfo",source.get_publication_info(),3) @@ -417,7 +418,7 @@ class XmlWriter: if len(self.db.get_bookmarks()) > 0: self.g.write(" \n") for person_handle in self.db.get_bookmarks(): - self.g.write(' \n' % person_handle) + self.g.write(' \n' % person_handle) self.g.write(" \n") self.g.write("\n") @@ -517,8 +518,8 @@ class XmlWriter: if ord.get_status() != 0: self.g.write('%s\n' % (sp2,ord.get_status())) if ord.get_family_handle(): - self.g.write('%s\n' % \ - (sp2,self.fix(ord.get_family_handle().get_gramps_id()))) + self.g.write('%s\n' % \ + (sp2,self.fix(ord.get_family_handle().get_handle()))) if ord.get_note() != "": self.write_note("note",ord.get_note_object(),index+1) for s in ord.get_source_references(): @@ -535,12 +536,12 @@ class XmlWriter: q = source_ref.get_confidence_level() self.g.write(" " * index) if p == "" and c == "" and t == "" and d.is_empty() and q == 2: - self.g.write('\n' % source.get_gramps_id()) + self.g.write('\n' % source.get_handle()) else: if q == 2: - self.g.write('\n' % source.get_gramps_id()) + self.g.write('\n' % source.get_handle()) else: - self.g.write('\n' % (source.get_gramps_id(),q)) + self.g.write('\n' % (source.get_handle(),q)) self.write_line("spage",p,index+1) self.write_text("scomments",c,index+1) self.write_text("stext",t,index+1) @@ -549,11 +550,13 @@ class XmlWriter: def write_ref(self,label,gid,index=1): if gid: - self.g.write('%s<%s ref="%s"/>\n' % (" "*index,label,gid)) + self.g.write('%s<%s hlink="%s"/>\n' % (" "*index,label,gid)) def write_id(self,label,person,index=1): if person: - self.g.write('%s<%s id="%s"' % (" "*index,label,person.get_gramps_id())) + self.g.write('%s<%s id="%s" handle="%s" change="%d"' % + (" "*index,label,person.get_gramps_id(),person.get_handle(), + person.get_change_time())) comp = person.get_complete_flag() if comp: self.g.write(' complete="1"') @@ -564,7 +567,8 @@ class XmlWriter: rel = family.get_relationship() comp = family.get_complete_flag() sp = " " * index - self.g.write('%s 0 or note: self.g.write('>\n') @@ -777,7 +782,7 @@ class XmlWriter: self.g.write(" \n") def write_object(self,obj): - handle = obj.get_gramps_id() + id = obj.get_gramps_id() mime_type = obj.get_mime_type() path = obj.get_path() if self.strip_photos: @@ -787,7 +792,8 @@ class XmlWriter: if len(path) >= l: if self.fileroot == path[0:l]: path = path[l+1:] - self.g.write(' 12 True - 15 - 12 + 17 + 11 False 6 12 @@ -8600,8 +8600,8 @@ Other - 7 - 12 + 6 + 11 0 8 fill @@ -8624,8 +8624,8 @@ Other 0 - 7 - 12 + 6 + 11 9 10 fill @@ -8649,8 +8649,8 @@ Other gid - 8 - 9 + 7 + 8 10 11 fill @@ -8671,8 +8671,8 @@ Other False - 9 - 12 + 8 + 11 10 11 @@ -8719,8 +8719,8 @@ Other 0 - 7 - 12 + 6 + 11 12 13 fill @@ -8747,8 +8747,8 @@ Other - 8 - 9 + 7 + 8 13 14 fill @@ -8772,8 +8772,8 @@ Other death_place - 8 - 9 + 7 + 8 14 15 fill @@ -8794,8 +8794,8 @@ Other False - 9 - 10 + 8 + 9 13 14 @@ -8811,8 +8811,8 @@ Other 0 - 10 - 11 + 9 + 10 13 14 fill @@ -8833,8 +8833,8 @@ Other - 11 - 12 + 10 + 11 13 14 fill @@ -8897,8 +8897,8 @@ Other False - 9 - 12 + 8 + 11 14 15 @@ -8918,6 +8918,91 @@ Other fill + + + + 6 + True + True + Information i_s complete + True + GTK_RELIEF_NORMAL + True + False + False + True + + + 0 + 5 + 16 + 17 + fill + + + + + + + True + False + 0 + + + + True + Last changed: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 0 + False + False + + + + + + + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + + + 0 + True + True + + + + + 6 + 11 + 16 + 17 + fill + fill + + 0 @@ -8928,29 +9013,6 @@ Other fill - - - - 6 - True - True - Information i_s complete - True - GTK_RELIEF_NORMAL - True - False - False - True - - - 0 - 1 - 1 - 2 - shrink - - - 0 @@ -13030,6 +13092,69 @@ Other + + + True + + + + 1 + 2 + 0 + 1 + fill + fill + + + + + + True + Last Changed: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 0 + 1 + 2 + 3 + fill + + + + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 1 + 2 + 2 + 3 + fill + + + + True @@ -13045,27 +13170,12 @@ Other 1 2 - 2 - 3 + 3 + 4 fill - - - - True - - - - 1 - 2 - 0 - 1 - fill - fill - - 5 @@ -14860,7 +14970,7 @@ Other 6 True - 11 + 12 4 False 6 @@ -15375,6 +15485,54 @@ Other + + + + True + Last Changed: + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 1 + 2 + 11 + 12 + fill + + + + + + + True + + False + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + + + 2 + 4 + 11 + 12 + fill + + + False