diff --git a/ChangeLog b/ChangeLog index e2def9193..5c813927a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2004-07-31 Don Allingham + * src/AddSpouse.py: fix gender selection + * src/DbPrompter.py: support other DB formats + * src/GrampsBSDDB.py: BSDDB format, derived from GrampsDbBase + * src/GrampsDbBase.py: base class for database classes + * src/GrampsGEDDB.py: GEDCOM format, derived from GrampsDbBase + * src/GrampsXMLDB.py: XML format, derived from GrampsDbBase + * src/PeopleModel.py: handle rebuilds better + * src/RelLib.py: use try_to_find_person_from_handle + * src/WriteXML.py: use gramps ids instead of handles + * src/const.py.in: handle family relations correctly + * src/gramps_main.py: remove prefix settings + * src/data/gnome-mime-application-x-gramps-xml.png: new icon + * src/data/gramps.applications: support for x-gramps-xml + * src/data/gramps.keys: support for x-gramps-xml + * src/data/gramps.mime: support for x-gramps-xml + * src/data/gramps.schemas: added event format + * src/data/gramps.xml: support for x-gramps-xml + * src/plugins/ReadGedcom.py: start of GEDDB support + * src/plugins/WriteGedcom.py: start of GEDDB support + 2004-07-30 Don Allingham * src/const.py.in: fix relationship types diff --git a/example/gramps/data.gramps b/example/gramps/data.gramps index 65d86ea43..ee302713f 100644 Binary files a/example/gramps/data.gramps and b/example/gramps/data.gramps differ diff --git a/src/AddSpouse.py b/src/AddSpouse.py index 14066bd18..db57c2a50 100644 --- a/src/AddSpouse.py +++ b/src/AddSpouse.py @@ -342,8 +342,7 @@ class AddSpouse: return 1 def set_gender(self): - family_type = const.family_relations[value][0] - if text == const.FAMILY_CIVIL_UNION: + if self.rel_type.get_active() == const.FAMILY_CIVIL_UNION: if self.gender == RelLib.Person.male: self.sgender = RelLib.Person.female else: diff --git a/src/DbPrompter.py b/src/DbPrompter.py index 00456a12d..127b87ec5 100644 --- a/src/DbPrompter.py +++ b/src/DbPrompter.py @@ -48,6 +48,9 @@ import Utils import const import QuestionDialog import Plugins +import GrampsBSDDB +import GrampsXMLDB +import GrampsGEDDB #------------------------------------------------------------------------- # @@ -144,8 +147,21 @@ class ExistingDbPrompter: if response == gtk.RESPONSE_OK: filename = choose.get_filename() filetype = gnome.vfs.get_mime_type(filename) + print filetype + if filetype == 'application/x-gramps': choose.destroy() + self.parent.db = GrampsBSDDB.GrampsBSDDB() + self.parent.read_file(filename) + return 1 + if filetype == 'application/x-gramps-xml' or filetype == 'text/xml' or filetype == 'application/x-gzip': + choose.destroy() + self.parent.db = GrampsXMLDB.GrampsXMLDB() + self.parent.read_file(filename) + return 1 + if filetype == 'application/x-gedcom': + choose.destroy() + self.parent.db = GrampsGEDDB.GrampsGEDDB() self.parent.read_file(filename) return 1 (junk,the_file) = os.path.split(filename) diff --git a/src/GrampsBSDDB.py b/src/GrampsBSDDB.py index 8e22f8372..ee3e94452 100644 --- a/src/GrampsBSDDB.py +++ b/src/GrampsBSDDB.py @@ -20,61 +20,33 @@ # $Id$ +import os + from RelLib import * +from GrampsDbBase import * +from bsddb import dbshelve, db -_UNDO_SIZE = 1000 +def find_surname(key,data): + return str(data[3].get_surname()) -#------------------------------------------------------------------------- -# -# ID regular expression -# -#------------------------------------------------------------------------- -_id_reg = compile("%\d+d") +def find_idmap(key,data): + return str(data[1]) + +def find_eventname(key,data): + return str(data[1]) #------------------------------------------------------------------------- # # GrampsBSDDB # #------------------------------------------------------------------------- -class GrampsBSDDB: +class GrampsBSDDB(GrampsDbBase): """GRAMPS database object. This object is a base class for other objects.""" def __init__(self): """creates a new GrampsDB""" - - self.iprefix = "I%04d" - self.sprefix = "S%04d" - self.oprefix = "O%04d" - self.pprefix = "P%04d" - self.fprefix = "F%04d" - self.eprefix = "E%04d" - self.open = 0 - self.new() - self.added_files = [] - self.genderStats = GenderStats() - - self.env = None - self.person_map = None - self.family_map = None - self.place_map = None - self.source_map = None - self.media_map = None - self.event_map = None - self.surnames = None - self.eventnames = None - self.metadata = None - self.undolabel = None - self.redolabel = None - self.undodb = None - - def set_undo_label(self,label): - self.undolabel = label - self.undolabel.set_sensitive(0) - - def set_redo_label(self,label): - self.redolabel = label - self.redolabel.set_sensitive(0) + GrampsDbBase.__init__(self) def load(self,name,callback): if self.person_map: @@ -119,32 +91,6 @@ class GrampsBSDDB: self.bookmarks = [] return 1 - def find_next_gramps_id(self): - index = self.iprefix % self.pmap_index - while self.id_trans.get(str(index)): - self.pmap_index += 1 - index = self.iprefix % self.pmap_index - self.pmap_index += 1 - return index - - def get_people_view_maps(self): - if self.metadata: - return (self.metadata.get('tp_iter'), - self.metadata.get('tp_path'), - self.metadata.get('p_iter'), - self.metadata.get('p_path'), - self.metadata.get('sname')) - else: - return (None,None,None,None,None) - - def set_people_view_maps(self,maps): - if self.metadata: - self.metadata['tp_iter'] = maps[0] - self.metadata['tp_path'] = maps[1] - self.metadata['p_iter'] = maps[2] - self.metadata['p_path'] = maps[3] - self.metadata['sname'] = maps[4] - def close(self): self.person_map.close() self.family_map.close() @@ -175,248 +121,6 @@ class GrampsBSDDB: self.env = None self.metadata = None - def is_open(self): - return self.person_map != None - - def get_added_media_objects(self): - return self.added_files - - def clear_added_media_objects(self): - self.added_files = [] - - def get_number_of_people(self): - return len(self.person_map) - - def get_person_keys(self): - if self.person_map: - return self.person_map.keys() - else: - return [] - - def get_family_keys(self): - if self.family_map: - return self.family_map.keys() - else: - return [] - - def sort_by_name(self,f,s): - n1 = self.person_map.get(f)[2].sname - n2 = self.person_map.get(s)[2].sname - return cmp(n1,n2) - - def sort_person_keys(self): - if self.person_map: - keys = self.person_map.keys() - keys.sort(self.sort_by_name) - return keys - else: - return [] - - def get_person_display(self,key): - data = self.person_map.get(key) - - if data[2] == Person.male: - gender = const.male - elif data[2] == Person.female: - gender = const.female - else: - gender = const.unknown - - return [ data[3].get_name(), - data[1], - gender, - data[7], - data[6], - data[3].get_sort_name(), - data[7], - data[6], - GrampsCfg.get_display_surname()(data[3])] - - def commit_person(self,person,transaction): - handle = person.get_handle() - if transaction != None: - old_data = self.person_map.get(handle) - transaction.add(PERSON_KEY,handle,old_data) - self.person_map.put(handle,person.serialize()) - - def commit_media_object(self,object,transaction): - handle = str(object.get_handle()) - if transaction != None: - old_data = self.media_map.get(handle) - transaction.add(MEDIA_KEY,handle,old_data) - self.media_map.put(str(object.get_handle()),object.serialize()) - - def commit_source(self,source,transaction): - 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.put(str(source.get_handle()),source.serialize()) - - def commit_place(self,place,transaction): - 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.put(str(place.get_handle()),place.serialize()) - - def commit_event(self,event,transaction): - 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.put(str(event.get_handle()),event.serialize()) - - def commit_family(self,family,transaction): - handle = str(family.get_handle()) - if transaction != None: - old_data = self.family_map.get(handle) - transaction.add(FAMILY_KEY,handle,old_data) - self.family_map.put(str(family.get_handle()),family.serialize()) - - def set_iprefix(self,val): - if val: - if _id_reg.search(val): - self.iprefix = val - else: - self.iprefix = val + "%d" - else: - self.iprefix = "I%04d" - - def set_sprefix(self,val): - if val: - if _id_reg.search(val): - self.sprefix = val - else: - self.sprefix = val + "%d" - else: - self.sprefix = "S%04d" - - def set_oprefix(self,val): - if val: - if _id_reg.search(val): - self.oprefix = val - else: - self.oprefix = val + "%d" - else: - self.oprefix = "O%04d" - - def set_pprefix(self,val): - if val: - if _id_reg.search(val): - self.pprefix = val - else: - self.pprefix = val + "%d" - else: - self.pprefix = "P%04d" - - def set_fprefix(self,val): - if val: - if _id_reg.search(val): - self.fprefix = val - else: - self.fprefix = val + "%d" - else: - self.fprefix = "F%04d" - - def set_eprefix(self,val): - if val: - if _id_reg.search(val): - self.eprefix = val - else: - self.eprefix = val + "%d" - else: - self.eprefix = "E%04d" - - def new(self): - """initializes the GrampsDB to empty values""" - - self.undoindex = -1 - self.translist = [None] * _UNDO_SIZE - self.smap_index = 0 - self.emap_index = 0 - self.pmap_index = 0 - self.fmap_index = 0 - self.lmap_index = 0 - self.omap_index = 0 - self.default = None - self.owner = Researcher() - self.bookmarks = [] - self.path = "" - self.place2title = {} - self.genderStats = GenderStats() - - def start_transaction(self,msg=""): - return Transaction(msg,self.undodb) - - def add_transaction(self,transaction,msg): - if not len(transaction): - return - transaction.set_description(msg) - self.undoindex += 1 - if self.undoindex == _UNDO_SIZE: - self.translist = transaction[0:-1] + [ transaction ] - else: - self.translist[self.undoindex] = transaction - - if self.undolabel: - self.undolabel.set_sensitive(1) - label = self.undolabel.get_children()[0] - label.set_text(_("_Undo %s") % transaction.get_description()) - label.set_use_underline(1) - - def undo(self): - if self.undoindex == -1: - return - transaction = self.translist[self.undoindex] - - self.undoindex -= 1 - subitems = transaction.get_recnos() - subitems.reverse() - for record_id in subitems: - (key, handle, data) = transaction.get_record(record_id) - if key == PERSON_KEY: - if data == None: - del self.person_map[handle] - else: - self.person_map.put(handle,data) - elif key == FAMILY_KEY: - if data == None: - del self.family_map[handle] - else: - self.family_map.put(handle,data) - elif key == SOURCE_KEY: - if data == None: - del self.source_map[handle] - else: - self.source_map.put(handle,data) - elif key == EVENT_KEY: - if data == None: - del self.event_map[handle] - else: - self.event_map.put(handle,data) - elif key == PLACE_KEY: - if data == None: - del self.place_map[handle] - else: - self.place_map.put(handle,data) - elif key == MEDIA_KEY: - if data == None: - del self.media_map[handle] - else: - self.media_map.put(handle,data) - - if self.undolabel: - label = self.undolabel.get_children()[0] - if self.undoindex == -1: - label.set_text(_("_Undo")) - self.undolabel.set_sensitive(0) - else: - transaction = self.translist[self.undoindex] - label.set_text(_("_Undo %s") % transaction.get_description()) - self.undolabel.set_sensitive(1) - label.set_use_underline(1) - def get_surnames(self): names = self.surnames.keys() a = {} @@ -435,111 +139,6 @@ class GrampsBSDDB: vals.sort() return vals - def get_bookmarks(self): - """returns the list of Person instances in the bookmarks""" - return self.bookmarks - - def clean_bookmarks(self): - """cleans up the bookmark list, removing empty slots""" - new_bookmarks = [] - for person_handle in self.bookmarks: - new_bookmarks.append(person_handle) - self.bookmarks = new_bookmarks - - def set_researcher(self,owner): - """sets the information about the owner of the database""" - self.owner.set(owner.get_name(),owner.get_address(),owner.get_city(), - owner.get_state(),owner.get_country(), - owner.get_postal_code(),owner.get_phone(),owner.get_email()) - - def get_researcher(self): - """returns the Researcher instance, providing information about - the owner of the database""" - return self.owner - - def set_default_person(self,person): - """sets the default Person to the passed instance""" -# if (self.default): -# self.default.set_ancestor(0) - self.metadata['default'] = person.get_handle() -# if person: -# self.default.set_ancestor(1) - - def set_default_person_handle(self,handle): - """sets the default Person to the passed instance""" - self.metadata['default'] = handle - - def get_default_person(self): - """returns the default Person of the database""" - if self.metadata and self.metadata.has_key('default'): - person = Person() - handle = self.metadata['default'] - data = self.person_map.get(handle) - person.unserialize(data) - return person - return None - - def get_person(self,handle): - """returns a Person from a GRAMPS's ID""" - p = Person() - data = self.person_map.get(handle) - p.unserialize(data) - return p - - def get_place_handle_map(self): - """returns a map of gramps's IDs to Place instances""" - return self.place_map - - def set_place_handle_map(self,map): - """sets the map of gramps's IDs to Place instances""" - self.place_map = map - - def get_family_handle(self,handle): - """returns a map of gramps's IDs to Family instances""" - return self.family_map.get(str(handle)) - - def get_save_path(self): - """returns the save path of the file, or "" if one does not exist""" - return self.path - - def set_save_path(self,path): - """sets the save path for the database""" - self.path = path - - def get_person_event_types(self): - """returns a list of all Event types assocated with Person - instances in the database""" - return [] - - def get_person_attribute_types(self): - """returns a list of all Attribute types assocated with Person - instances in the database""" - return [] - - def get_family_attribute_types(self): - """returns a list of all Attribute types assocated with Family - instances in the database""" - return [] - - def get_family_event_types(self): - """returns a list of all Event types assocated with Family - instances in the database""" - return [] - - def get_media_attribute_types(self): - """returns a list of all Attribute types assocated with Media - instances in the database""" - return [] - - def get_place_handles(self): - """returns a list of Place instances""" - return self.place_map.keys() - - def get_family_relation_types(self): - """returns a list of all relationship types assocated with Family - instances in the database""" - return [] - def remove_person_handle(self,handle,transaction): # self.genderStats.uncount_person (self.person_map[handle]) if transaction != None: @@ -559,722 +158,3 @@ class GrampsBSDDB: transaction.add(EVENT_KEY,handle,old_data) self.event_map.delete(str(handle)) - def add_person_as(self,person,trans): - if trans != None: - trans.add(PERSON_KEY, person.get_handle(),None) - self.person_map.put(person.get_handle(),person.serialize()) -# self.genderStats.count_person (person, self) - return person.get_handle() - - def add_person(self,person,trans): - """adds a Person to the database, assigning a gramps' ID""" - person.set_gramps_id(self.find_next_gramps_id()) - person.set_handle(Utils.create_id()) - if trans != None: - trans.add(PERSON_KEY, person.get_handle(),None) - self.person_map.put(person.get_handle(),person.serialize()) - self.genderStats.count_person (person, self) - return person.get_handle() - - def has_person_handle(self,val): - return self.person_map.get(val) - - def has_family_handle(self,val): - return self.family_map.get(str(val)) - - def try_to_find_person_from_handle(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.""" - - data = self.person_map.get(val) - if data: - person = Person() - person.unserialize(data) - return person - else: - return None - - def try_to_find_person_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.""" - - data = self.id_trans.get(str(val)) - if data: - person = Person() - person.unserialize(cPickle.loads(data)) - return person - else: - return None - - def find_person_from_gramps_id(self,val,trans): - """finds a Person in the database from the passed gramps' ID. - If no such Person exists, a new Person is added to the database.""" - - person = Person() - data = self.id_trans.get(str(val)) - if data: - person.unserialize(cPickle.loads(data)) - else: - intid = Utils.create_id() - person.set_handle(intid) - person.set_gramps_id(val) - self.add_person_as(person,trans) - return person - - def find_person_from_handle(self,val,trans): - """finds a Person in the database from the passed gramps' ID. - If no such Person exists, a new Person is added to the database.""" - - person = Person() - data = self.person_map.get(val) - if data: - person.unserialize(data) - else: - person.set_handle(val) - if trans != None: - trans.add(PERSON_KEY, val, None) - self.person_map.put(val, person.serialize()) -# self.genderStats.count_person (person, self) - return person - - def add_person_no_map(self,person,handle,trans): - """adds a Person to the database if the gramps' ID is known""" - - person.set_handle(handle) - if trans != None: - trans.add(PERSON_KEY, handle, None) - self.person_map.set(handle,person.serialize()) -# self.genderStats.count_person (person, self) - return handle - - def add_source(self,source,trans): - """adds a Source instance to the database, assigning it a gramps' - ID number""" - - index = self.sprefix % self.smap_index - while self.source_map.get(str(index)): - self.smap_index = self.smap_index + 1 - index = self.sprefix % self.smap_index - source.set_handle(index) - if trans != None: - trans.add(SOURCE_KEY,index,None) - self.source_map.put(str(index),source.serialize()) - self.smap_index = self.smap_index + 1 - return index - - def add_event(self,event,trans): - """adds a Event instance to the database, assigning it a gramps' - ID number""" - index = self.eprefix % self.emap_index - while self.event_map.get(str(index)): - self.emap_index += 1 - index = self.eprefix % self.emap_index - event.set_handle(index) - if trans != None: - trans.add(EVENT_KEY,index,None) - self.event_map.put(str(index),event.serialize()) - self.emap_index += 1 - return index - - def add_source_no_map(self,source,index,trans): - """adds a Source to the database if the gramps' ID is known""" - source.set_handle(index) - if trans != None: - trans.add(SOURCE_KEY,index,None) - self.source_map.put(str(index),source.serialize()) - self.smap_index = self.smap_index + 1 - return index - - def add_event_no_map(self,event,index,trans): - """adds a Source to the database if the gramps' ID is known""" - event.set_handle(index) - if trans != None: - trans.add(EVENT_KEY,index,None) - self.event_map.put(str(index),event.serialize()) - self.emap_index += 1 - return index - - def find_source(self,handle,map,trans): - """finds a Source in the database using the handle and map - variables to translate between the external ID and gramps' - internal ID. If no such Source exists, a new Source instance - is created. - - handle - external ID number - map - map build by find_source of external to gramp's IDs""" - - if map.has_key(handle): - data = self.source_map.get(str(map[handle])) - source = Source() - source.unserialize(data) - else: - source = Source() - map[handle] = self.add_source(source,trans) - return source - - def find_event(self,handle,map,trans): - """finds a Event in the database using the handle and map - variables to translate between the external ID and gramps' - internal ID. If no such Event exists, a new Event instance - is created. - - handle - external ID number - map - map build by find_source of external to gramp's IDs""" - - event = Event() - if map.has_key(handle): - data = self.event_map.get(str(map[handle])) - event.unserialize(data) - else: - map[handle] = self.add_event(event,trans) - return event - - def try_to_find_source_from_handle(self,val): - """finds a Source in the database from the passed gramps' ID. - If no such Source exists, None is returned.""" - - data = self.source_map.get(str(val)) - if data: - source = Source() - source.unserialize(data) - return source - else: - return None - - def find_source_from_handle(self,val,trans): - """finds a Source in the database from the passed gramps' ID. - If no such Source exists, a new Source is added to the database.""" - - source = Source() - if self.source_map.get(str(val)): - source.unserialize(self.source_map.get(str(val))) - else: - self.add_source_no_map(source,val,trans) - return source - - def find_event_from_handle(self,val): - """finds a Family in the database from the passed gramps' ID. - If no such Family exists, a new Family is added to the database.""" - data = self.event_map.get(str(val)) - if data: - event = Event() - event.unserialize(data) - return event - else: - return None - - def add_object(self,object,trans): - """adds an Object instance to the database, assigning it a gramps' - ID number""" - - index = self.oprefix % self.omap_index - while self.media_map.get(str(index)): - self.omap_index = self.omap_index + 1 - index = self.oprefix % self.omap_index - object.set_handle(index) - if trans != None: - trans.add(MEDIA_KEY,index,None) - self.media_map.put(str(index),object.serialize()) - self.omap_index = self.omap_index + 1 - self.added_files.append(object) - - return index - - def find_object_no_conflicts(self,handle,map,trans): - """finds an Object in the database using the handle and map - variables to translate between the external ID and gramps' - internal ID. If no such Object exists, a new Object instance - is created. - - handle - external ID number - map - map build by find_object of external to gramp's IDs""" - - handle = str(handle) - object = MediaObject() - if map.has_key(handle): - object.unserialize(self.media_map.get(str(map[handle]))) - else: - if self.media_map.get(str(handle)): - map[handle] = self.add_object(object,trans) - else: - map[handle] = self.add_object_no_map(object,handle,trans) - return object - - def add_object_no_map(self,object,index,trans): - """adds an Object to the database if the gramps' ID is known""" - index = str(index) - object.set_handle(index) - if trans != None: - trans.add(MEDIA_KEY,index,None) - self.media_map.put(str(index),object.serialize()) - self.omap_index = self.omap_index + 1 - self.added_files.append(object) - return index - - def try_to_find_object_from_handle(self,handle): - """finds an Object in the database from the passed gramps' ID. - If no such Object exists, None is returned.""" - - data = self.media_map.get(str(handle)) - if data: - mobject = MediaObject() - mobject.unserialize(data) - return mobject - else: - return None - - def find_object_from_handle(self,handle,trans): - """finds an Object in the database from the passed gramps' ID. - If no such Object exists, a new Object is added to the database.""" - - object = MediaObject() - if self.media_map.get(str(handle)): - object.unserialize(self.media_map.get(str(handle))) - else: - self.add_object_no_map(object,handle,trans) - return object - - def has_object_handle(self,handle): - """finds an Object in the database from the passed gramps' ID. - If no such Source exists, a new Source is added to the database.""" - - return self.media_map.get(str(handle)) != None - - def add_place(self,place,trans): - """adds a Place instance to the database, assigning it a gramps' - ID number""" - - index = self.pprefix % self.lmap_index - while self.place_map.get(str(index)): - self.lmap_index = self.lmap_index + 1 - index = self.pprefix % self.lmap_index - place.set_handle(index) - if trans != None: - trans.add(PLACE_KEY,index,None) - self.place_map.put(str(index),place.serialize()) - self.lmap_index = self.lmap_index + 1 - return index - - def remove_object(self,handle,transaction): - if transaction != None: - old_data = self.media_map.get(str(handle)) - transaction.add(MEDIA_KEY,handle,old_data) - self.media_map.delete(str(handle)) - - def remove_place(self,handle,transaction): - if transaction != None: - old_data = self.place_map.get(str(handle)) - transaction.add(PLACE_KEY,handle,old_data) - self.place_map.delete(str(handle)) - - def add_place_as(self,place,trans): - if trans != None: - trans.add(PLACE_KEY,place.get_handle(),None) - self.place_map.put(str(place.get_handle()),place.serialize()) - return place.get_handle() - - def find_place_no_conflicts(self,handle,map,trans): - """finds a Place in the database using the handle and map - variables to translate between the external ID and gramps' - internal ID. If no such Place exists, a new Place instance - is created. - - handle - external ID number - map - map build by findPlace of external to gramp's IDs""" - - if map.has_key(str(handle)): - place = Place() - data = self.place_map[str(map[handle])] - place.unserialize(data) - else: - place = Place() - if self.place_map.has_key(str(handle)): - map[handle] = self.add_place(place,trans) - else: - place.set_handle(str(handle)) - map[str(handle)] = self.add_place_as(place,trans) - self.place_map.put(str(handle),place.serialize()) - return place - - def add_place_no_map(self,place,index,trans): - """adds a Place to the database if the gramps' ID is known""" - - index = str(index) - place.set_handle(index) - if trans != None: - trans.add(PLACE_KEY,index,None) - self.place_map.put(str(index), place.serialize()) - self.lmap_index = self.lmap_index + 1 - return index - - def find_place_from_handle(self,handle,trans): - """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.handle = handle - if trans != None: - trans.add(PLACE_KEY,handle,None) - self.place_map.put(str(handle),place.serialize()) - self.lmap_index = self.lmap_index + 1 - else: - place.unserialize(data) - return place - - def try_to_find_place_from_handle(self,handle): - """finds a Place in the database from the passed gramps' ID. - If no such Place exists, None is returned.""" - - data = self.place_map.get(str(handle)) - - if data: - place = Place() - place.unserialize(data) - return place - else: - return None - - def sortbyplace(self,f,s): - return cmp(self.placesortmap[f], self.placesortmap[s]) - - def sortbysource(self,f,s): - fp = self.source_map[f][1].upper() - sp = self.source_map[s][1].upper() - return cmp(fp,sp) - - def sortbymedia(self,f,s): - fp = self.media_map[f][3].upper() - sp = self.media_map[s][3].upper() - return cmp(fp,sp) - - def sort_place_keys(self): - if self.place_map: - self.placesortmap = {} - for key in self.place_map.keys(): - self.placesortmap[key] = self.place_map[key][1].upper() - keys = self.placesortmap.keys() - keys.sort(self.sortbyplace) - del self.placesortmap - return keys - return [] - - def sort_media_keys(self): - if self.media_map: - keys = self.media_map.keys() - keys.sort(self.sortbymedia) - return keys - else: - return [] - - def sort_source_keys(self): - if self.source_map: - keys = self.source_map.keys() - keys.sort(self.sortbysource) - return keys - else: - return [] - - def get_place_handle_keys(self): - if self.place_map: - return self.place_map.keys() - else: - return [] - - def get_place_handle(self,key): - place = Place() - place.unserialize(self.place_map.get(str(key))) - return place - - def get_place_display(self,key): - # fix this up better - place = Place() - place.unserialize(self.place_map[str(key)]) - return place.get_display_info() - - def get_source_keys(self): - if self.source_map: - return self.source_map.keys() - return [] - - def get_object_keys(self): - if self.media_map: - return self.media_map.keys() - return [] - - def get_event_keys(self): - if self.event_map: - return self.event_map.keys() - return [] - - def sortbysource(self,f,s): - f1 = self.source_map[f][1].upper() - s1 = self.source_map[s][1].upper() - return cmp(f1,s1) - - def set_source_keys(self): - keys = self.source_map.keys() - if type(keys) == type([]): - keys.sort(self.sortbyplace) - return keys - - def get_source_display(self,key): - source = Source() - source.unserialize(self.source_map.get(str(key))) - return source.get_display_info() - - def get_source(self,key): - source = Source() - source.unserialize(self.source_map[key]) - return source - - def build_source_display(self,nkey,okey=None): - pass - - def new_family(self,trans): - """adds a Family to the database, assigning a gramps' ID""" - - index = self.fprefix % self.fmap_index - while self.family_map.get(str(index)): - self.fmap_index = self.fmap_index + 1 - index = self.fprefix % self.fmap_index - self.fmap_index = self.fmap_index + 1 - family = Family() - family.set_handle(unicode(index)) - if trans != None: - trans.add(FAMILY_KEY, index, None) - self.family_map.put(str(index),family.serialize()) - return family - - def new_family_no_map(self,handle,trans): - """finds a Family in the database from the passed gramps' ID. - If no such Family exists, a new Family is added to the database.""" - - family = Family() - family.set_handle(handle) - if trans != None: - trans.add(FAMILY_KEY, handle, None) - self.family_map.put(str(handle),family.serialize()) - self.fmap_index = self.fmap_index + 1 - return family - - def find_family_with_map(self,handle,map,trans): - """finds a Family in the database using the handle and map - variables to translate between the external ID and gramps' - internal ID. If no such Family exists, a new Family instance - is created. - - handle - external ID number - map - map build by find_family_with_map of external to gramp's IDs""" - - if map.has_key(handle): - family = Family() - data = self.family_map.get(str(map[handle])) - family.unserialize(data) - else: - family = self.new_family(trans) - map[handle] = family.get_handle() - return family - - def find_family_no_map(self,val,trans): - """finds a Family in the database from the passed gramps' ID. - 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) - else: - family.handle = val - if trans: - trans.add(FAMILY_KEY,val,None) - self.family_map.put(str(val),family.serialize()) - self.fmap_index = self.fmap_index + 1 - return family - - def find_family_from_handle(self,val): - """finds a Family in the database from the passed gramps' ID. - If no such Family exists, a new Family is added to the database.""" - data = self.family_map.get(str(val)) - if data: - family = Family() - family.unserialize(data) - return family - else: - return None - - def delete_family(self,family_handle,trans): - """deletes the Family instance from the database""" - if self.family_map.get(str(family_handle)): - if trans != None: - old_data = self.family_map.get(str(family_handle)) - trans.add(FAMILY_KEY,family_handle,old_data) - self.family_map.delete(str(family_handle)) - - def find_family_no_conflicts(self,handle,map,trans): - """finds a Family in the database using the handle and map - variables to translate between the external ID and gramps' - internal ID. If no such Family exists, a new Family instance - is created. - - handle - external ID number - map - map build by findFamily of external to gramp's IDs""" - - if map.has_key(str(handle)): - family = Family() - family.unserialize(self.family_map.get(str(map[str(handle)]))) - else: - if self.family_map.has_key(str(handle)): - family = self.new_family(trans) - else: - family = self.new_family_no_map(str(handle),trans) - map[handle] = family.get_handle() - return family - - def find_source_no_conflicts(self,handle,map,trans): - """finds a Source in the database using the handle and map - variables to translate between the external ID and gramps' - internal ID. If no such Source exists, a new Source instance - is created. - - handle - external ID number - map - map build by findSource of external to gramp's IDs""" - - source = Source() - if map.has_key(handle): - source.unserialize(self.source_map.get(str(map[handle]))) - else: - if self.source_map.get(str(handle)): - map[handle] = self.add_source(source,trans) - else: - map[handle] = self.add_source(source,trans) - return source - - def set_column_order(self,list): - if self.metadata != None: - self.metadata['columns'] = list - - def set_place_column_order(self,list): - if self.metadata != None: - self.metadata['place_columns'] = list - - def set_source_column_order(self,list): - if self.metadata != None: - self.metadata['source_columns'] = list - - def set_media_column_order(self,list): - if self.metadata != None: - self.metadata['media_columns'] = list - - def get_column_order(self): - default = [(1,1),(1,2),(1,3),(0,4),(1,5),(0,6),(0,7)] - if self.metadata == None: - return default - else: - cols = self.metadata.get('columns',default) - if len(cols) != len(default): - return cols + default[len(cols):] - else: - return cols - - def get_place_column_order(self): - default = [(1,1),(1,2),(0,3),(1,4),(0,5),(1,6),(0,7),(0,8)] - if self.metadata == None: - return default - else: - cols = self.metadata.get('place_columns',default) - if len(cols) != len(default): - return cols + default[len(cols):] - else: - return cols - - def get_source_column_order(self): - default = [(1,1),(1,2),(1,3),(0,4)] - if self.metadata == None: - return default - else: - cols = self.metadata.get('source_columns',default) - if len(cols) != len(default): - return cols + default[len(cols):] - else: - return cols - - def get_media_column_order(self): - default = [(1,1),(1,2),(1,3)] - if self.metadata == None: - return default - else: - cols = self.metadata.get('meda_columns',default) - if len(cols) != len(default): - return cols + default[len(cols):] - else: - return cols -#------------------------------------------------------------------------- -# -# Transaction -# -#------------------------------------------------------------------------- -class Transaction: - - def __init__(self,msg,db): - self.db = db - self.first = None - self.last = None - - def get_description(self): - return self.msg - - def set_description(self,msg): - self.msg = msg - - def add(self, type, handle, data): - self.last = self.db.append(cPickle.dumps((type,handle,data),1)) - if self.first == None: - self.first = self.last - - def get_recnos(self): - return range (self.first, self.last+1) - - def get_record(self,id): - return cPickle.loads(self.db[id]) - - def __len__(self): - if self.last and self.first: - return self.last - self.first + 1 - return 0 - - def display(self): - for record in self.get_recnos(): - (key,handle,val) = self.get_record(record) - if key == PERSON_KEY: - if val: - print "PERSON %s change" % handle - else: - print "PERSON %s remove" % handle - elif key == FAMILY_KEY: - if val: - print "FAMILY %s change" % handle - else: - print "FAMILY %s remove" % handle - elif key == EVENT_KEY: - if val: - print "EVENT %s change" % handle - else: - print "EVENT %s remove" % handle - elif key == SOURCE_KEY: - if val: - print "SOURCE %s change" % handle - else: - print "SOURCE %s remove" % handle - elif key == MEDIA_KEY: - if val: - print "MEDIA %s change" % handle - else: - print "MEDIA %s remove" % handle - elif key == PLACE_KEY: - if val: - print "PLACE %s change" % handle - else: - print "PLACE %s remove" % handle - diff --git a/src/GrampsCfg.py b/src/GrampsCfg.py index f90edb33e..070ec6185 100644 --- a/src/GrampsCfg.py +++ b/src/GrampsCfg.py @@ -268,6 +268,9 @@ def save_usetips(val): def get_iprefix(): return get_string("/apps/gramps/preferences/iprefix") +def get_eprefix(): + return get_string("/apps/gramps/preferences/iprefix") + def save_iprefix(val): set_string_as_id_prefix("/apps/gramps/preferences/iprefix",val) @@ -283,6 +286,9 @@ def get_sprefix(): def save_sprefix(val): set_string_as_id_prefix("/apps/gramps/preferences/sprefix",val) +def save_eprefix(val): + set_string_as_id_prefix("/apps/gramps/preferences/eprefix",val) + def get_pprefix(): return get_string("/apps/gramps/preferences/pprefix") diff --git a/src/GrampsDbBase.py b/src/GrampsDbBase.py new file mode 100644 index 000000000..9cc2eae7f --- /dev/null +++ b/src/GrampsDbBase.py @@ -0,0 +1,1186 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2004 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 +# + +# $Id$ + +from RelLib import * +import cPickle + +_UNDO_SIZE = 1000 + +#------------------------------------------------------------------------- +# +# ID regular expression +# +#------------------------------------------------------------------------- +_id_reg = compile("%\d+d") + +#------------------------------------------------------------------------- +# +# GrampsDbBase +# +#------------------------------------------------------------------------- +class GrampsDbBase: + """GRAMPS database object. This object is a base class for other + objects.""" + + def __init__(self): + """creates a new GrampsDB""" + + self.set_iprefix(GrampsCfg.get_iprefix()) + self.set_oprefix(GrampsCfg.get_oprefix()) + self.set_fprefix(GrampsCfg.get_fprefix()) + self.set_sprefix(GrampsCfg.get_sprefix()) + self.set_pprefix(GrampsCfg.get_pprefix()) + self.set_eprefix(GrampsCfg.get_eprefix()) + self.open = 0 + self.new() + self.added_files = [] + self.genderStats = GenderStats() + + self.env = None + self.person_map = None + self.family_map = None + self.place_map = None + self.source_map = None + self.media_map = None + self.event_map = None + self.eventnames = None + self.metadata = None + self.undolabel = None + self.redolabel = None + self.modified = 0 + + def set_undo_label(self,label): + self.undolabel = label + self.undolabel.set_sensitive(0) + + def set_redo_label(self,label): + self.redolabel = label + self.redolabel.set_sensitive(0) + + def load(self,name,callback): + assert(0,"Needs to be overridden in the derived class") + + def find_next_gramps_id(self): + index = self.iprefix % self.pmap_index + while self.id_trans.get(str(index)): + self.pmap_index += 1 + index = self.iprefix % self.pmap_index + self.pmap_index += 1 + return index + + def get_people_view_maps(self): + if self.metadata: + return (self.metadata.get('tp_iter'), + self.metadata.get('tp_path'), + self.metadata.get('p_iter'), + self.metadata.get('p_path'), + self.metadata.get('sname')) + else: + return (None,None,None,None,None) + + def set_people_view_maps(self,maps): + if self.metadata: + self.metadata['tp_iter'] = maps[0] + self.metadata['tp_path'] = maps[1] + self.metadata['p_iter'] = maps[2] + self.metadata['p_path'] = maps[3] + self.metadata['sname'] = maps[4] + + def close(self): + assert(0,"Needs to be overridden in the derived class") + + def is_open(self): + return self.person_map != None + + def get_added_media_objects(self): + return self.added_files + + def clear_added_media_objects(self): + self.added_files = [] + + def get_number_of_people(self): + return len(self.person_map) + + def get_person_keys(self): + if self.person_map: + return self.person_map.keys() + else: + return [] + + def get_family_keys(self): + if self.family_map: + return self.family_map.keys() + else: + return [] + + def sort_by_name(self,f,s): + n1 = self.person_map.get(f)[2].sname + n2 = self.person_map.get(s)[2].sname + return cmp(n1,n2) + + def sort_person_keys(self): + if self.person_map: + keys = self.person_map.keys() + keys.sort(self.sort_by_name) + return keys + else: + return [] + + def get_person_display(self,key): + data = self.person_map.get(key) + + if data[2] == Person.male: + gender = const.male + elif data[2] == Person.female: + gender = const.female + else: + gender = const.unknown + + return [ data[3].get_name(), + data[1], + gender, + data[7], + data[6], + data[3].get_sort_name(), + data[7], + data[6], + GrampsCfg.get_display_surname()(data[3])] + + def commit_person(self,person,transaction): + handle = 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,object,transaction): + handle = str(object.get_handle()) + if transaction != None: + old_data = self.media_map.get(handle) + transaction.add(MEDIA_KEY,handle,old_data) + self.media_map[str(object.get_handle())] = object.serialize() + + def commit_source(self,source,transaction): + 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[str(source.get_handle())] = source.serialize() + + def commit_place(self,place,transaction): + 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[str(place.get_handle())] = place.serialize() + + def commit_event(self,event,transaction): + 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[str(event.get_handle())] = event.serialize() + + def commit_family(self,family,transaction): + handle = str(family.get_handle()) + if transaction != None: + old_data = self.family_map.get(handle) + transaction.add(FAMILY_KEY,handle,old_data) + self.family_map[str(family.get_handle())] = family.serialize() + + def set_iprefix(self,val): + if val: + if _id_reg.search(val): + self.iprefix = val + else: + self.iprefix = val + "%d" + else: + self.iprefix = "I%04d" + + def set_sprefix(self,val): + if val: + if _id_reg.search(val): + self.sprefix = val + else: + self.sprefix = val + "%d" + else: + self.sprefix = "S%04d" + + def set_oprefix(self,val): + if val: + if _id_reg.search(val): + self.oprefix = val + else: + self.oprefix = val + "%d" + else: + self.oprefix = "O%04d" + + def set_pprefix(self,val): + if val: + if _id_reg.search(val): + self.pprefix = val + else: + self.pprefix = val + "%d" + else: + self.pprefix = "P%04d" + + def set_fprefix(self,val): + if val: + if _id_reg.search(val): + self.fprefix = val + else: + self.fprefix = val + "%d" + else: + self.fprefix = "F%04d" + + def set_eprefix(self,val): + if val: + if _id_reg.search(val): + self.eprefix = val + else: + self.eprefix = val + "%d" + else: + self.eprefix = "E%04d" + + def new(self): + """initializes the GrampsDB to empty values""" + + self.undoindex = -1 + self.translist = [None] * _UNDO_SIZE + self.smap_index = 0 + self.emap_index = 0 + self.pmap_index = 0 + self.fmap_index = 0 + self.lmap_index = 0 + self.omap_index = 0 + self.default = None + self.owner = Researcher() + self.bookmarks = [] + self.path = "" + self.place2title = {} + self.genderStats = GenderStats() + + def start_transaction(self,msg=""): + return Transaction(msg,self.undodb) + + def add_transaction(self,transaction,msg): + if not len(transaction): + return + transaction.set_description(msg) + self.undoindex += 1 + if self.undoindex == _UNDO_SIZE: + self.translist = transaction[0:-1] + [ transaction ] + else: + self.translist[self.undoindex] = transaction + + if self.undolabel: + self.undolabel.set_sensitive(1) + label = self.undolabel.get_children()[0] + label.set_text(_("_Undo %s") % transaction.get_description()) + label.set_use_underline(1) + + def undo(self): + if self.undoindex == -1: + return + transaction = self.translist[self.undoindex] + + self.undoindex -= 1 + subitems = transaction.get_recnos() + subitems.reverse() + for record_id in subitems: + (key, handle, data) = transaction.get_record(record_id) + if key == PERSON_KEY: + if data == None: + del self.person_map[handle] + else: + self.person_map[handle] = data + elif key == FAMILY_KEY: + if data == None: + del self.family_map[handle] + else: + self.family_map[handle] = data + elif key == SOURCE_KEY: + if data == None: + del self.source_map[handle] + else: + self.source_map[handle] = data + elif key == EVENT_KEY: + if data == None: + del self.event_map[handle] + else: + self.event_map[handle] = data + elif key == PLACE_KEY: + if data == None: + del self.place_map[handle] + else: + self.place_map[handle] = data + elif key == MEDIA_KEY: + if data == None: + del self.media_map[handle] + else: + self.media_map[handle] = data + + if self.undolabel: + label = self.undolabel.get_children()[0] + if self.undoindex == -1: + label.set_text(_("_Undo")) + self.undolabel.set_sensitive(0) + else: + transaction = self.translist[self.undoindex] + label.set_text(_("_Undo %s") % transaction.get_description()) + self.undolabel.set_sensitive(1) + label.set_use_underline(1) + + def get_surnames(self): + assert(0,"Needs to be overridden in the derived class") + + def get_eventnames(self): + assert(0,"Needs to be overridden in the derived class") + + def get_bookmarks(self): + """returns the list of Person instances in the bookmarks""" + return self.bookmarks + + def clean_bookmarks(self): + """cleans up the bookmark list, removing empty slots""" + new_bookmarks = [] + for person_handle in self.bookmarks: + new_bookmarks.append(person_handle) + self.bookmarks = new_bookmarks + + def set_researcher(self,owner): + """sets the information about the owner of the database""" + self.owner.set(owner.get_name(),owner.get_address(),owner.get_city(), + owner.get_state(),owner.get_country(), + owner.get_postal_code(),owner.get_phone(),owner.get_email()) + + def get_researcher(self): + """returns the Researcher instance, providing information about + the owner of the database""" + return self.owner + + def set_default_person(self,person): + """sets the default Person to the passed instance""" +# if (self.default): +# self.default.set_ancestor(0) + self.metadata['default'] = person.get_handle() +# if person: +# self.default.set_ancestor(1) + + def set_default_person_handle(self,handle): + """sets the default Person to the passed instance""" + self.metadata['default'] = handle + + def get_default_person(self): + """returns the default Person of the database""" + if self.metadata and self.metadata.has_key('default'): + person = Person() + handle = self.metadata['default'] + data = self.person_map.get(handle) + person.unserialize(data) + return person + return None + + def get_person(self,handle): + """returns a Person from a GRAMPS's ID""" + p = Person() + data = self.person_map.get(handle) + p.unserialize(data) + return p + + def get_place_handle_map(self): + """returns a map of gramps's IDs to Place instances""" + return self.place_map + + def set_place_handle_map(self,map): + """sets the map of gramps's IDs to Place instances""" + self.place_map = map + + def get_family_handle(self,handle): + """returns a map of gramps's IDs to Family instances""" + return self.family_map.get(str(handle)) + + def get_save_path(self): + """returns the save path of the file, or "" if one does not exist""" + return self.path + + def set_save_path(self,path): + """sets the save path for the database""" + self.path = path + + def get_person_event_types(self): + """returns a list of all Event types assocated with Person + instances in the database""" + return [] + + def get_person_attribute_types(self): + """returns a list of all Attribute types assocated with Person + instances in the database""" + return [] + + def get_family_attribute_types(self): + """returns a list of all Attribute types assocated with Family + instances in the database""" + return [] + + def get_family_event_types(self): + """returns a list of all Event types assocated with Family + instances in the database""" + return [] + + def get_media_attribute_types(self): + """returns a list of all Attribute types assocated with Media + instances in the database""" + return [] + + def get_place_handles(self): + """returns a list of Place instances""" + return self.place_map.keys() + + def get_family_relation_types(self): + """returns a list of all relationship types assocated with Family + instances in the database""" + return [] + + def remove_person_handle(self,handle,transaction): + assert(0,"Needs to be overridden in the derived class") + + def remove_source_handle(self,handle,transaction): + assert(0,"Needs to be overridden in the derived class") + + def remove_event_handle(self,handle,transaction): + assert(0,"Needs to be overridden in the derived class") + + def add_person_as(self,person,trans): + if trans != None: + trans.add(PERSON_KEY, person.get_handle(),None) + self.person_map[person.get_handle()] = person.serialize() +# self.genderStats.count_person (person, self) + return person.get_handle() + + def add_person(self,person,trans): + """adds a Person to the database, assigning a gramps' ID""" + person.set_gramps_id(self.find_next_gramps_id()) + person.set_handle(Utils.create_id()) + if trans != None: + trans.add(PERSON_KEY, person.get_handle(),None) + self.person_map[person.get_handle()] = person.serialize() + self.genderStats.count_person (person, self) + return person.get_handle() + + def has_person_handle(self,val): + return self.person_map.get(val) + + def has_family_handle(self,val): + return self.family_map.get(str(val)) + + def try_to_find_person_from_handle(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.""" + + data = self.person_map.get(val) + if data: + person = Person() + person.unserialize(data) + return person + else: + return None + + def try_to_find_person_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.""" + + data = self.id_trans.get(str(val)) + if data: + person = Person() + person.unserialize(cPickle.loads(data)) + return person + else: + return None + + def find_person_from_gramps_id(self,val,trans): + """finds a Person in the database from the passed gramps' ID. + If no such Person exists, a new Person is added to the database.""" + + person = Person() + data = self.id_trans.get(str(val)) + if data: + person.unserialize(cPickle.loads(data)) + else: + intid = Utils.create_id() + person.set_handle(intid) + person.set_gramps_id(val) + self.add_person_as(person,trans) + return person + + def find_person_from_handle(self,val,trans): + """finds a Person in the database from the passed gramps' ID. + If no such Person exists, a new Person is added to the database.""" + + person = Person() + data = self.person_map.get(val) + if data: + person.unserialize(data) + else: + person.set_handle(val) + if trans != None: + trans.add(PERSON_KEY, val, None) + self.person_map[val] = person.serialize() +# self.genderStats.count_person (person, self) + return person + + def add_person_no_map(self,person,handle,trans): + """adds a Person to the database if the gramps' ID is known""" + + person.set_handle(handle) + if trans != None: + trans.add(PERSON_KEY, handle, None) + self.person_map.set(handle,person.serialize()) +# self.genderStats.count_person (person, self) + return handle + + def add_source(self,source,trans): + """adds a Source instance to the database, assigning it a gramps' + ID number""" + + index = self.sprefix % self.smap_index + while self.source_map.get(str(index)): + self.smap_index = self.smap_index + 1 + index = self.sprefix % self.smap_index + source.set_handle(index) + if trans != None: + trans.add(SOURCE_KEY,index,None) + self.source_map[str(index)] = source.serialize() + self.smap_index = self.smap_index + 1 + return index + + def add_event(self,event,trans): + """adds a Event instance to the database, assigning it a gramps' + ID number""" + index = self.eprefix % self.emap_index + while self.event_map.get(str(index)): + self.emap_index += 1 + index = self.eprefix % self.emap_index + event.set_handle(index) + if trans != None: + trans.add(EVENT_KEY,index,None) + self.event_map[str(index)] = event.serialize() + self.emap_index += 1 + return index + + def add_source_no_map(self,source,index,trans): + """adds a Source to the database if the gramps' ID is known""" + source.set_handle(index) + if trans != None: + trans.add(SOURCE_KEY,index,None) + self.source_map[str(index)] = source.serialize() + self.smap_index = self.smap_index + 1 + return index + + def add_event_no_map(self,event,index,trans): + """adds a Source to the database if the gramps' ID is known""" + event.set_handle(index) + if trans != None: + trans.add(EVENT_KEY,index,None) + self.event_map[str(index)] = event.serialize() + self.emap_index += 1 + return index + + def find_source(self,handle,map,trans): + """finds a Source in the database using the handle and map + variables to translate between the external ID and gramps' + internal ID. If no such Source exists, a new Source instance + is created. + + handle - external ID number + map - map build by find_source of external to gramp's IDs""" + + if map.has_key(handle): + data = self.source_map.get(str(map[handle])) + source = Source() + source.unserialize(data) + else: + source = Source() + map[handle] = self.add_source(source,trans) + return source + + def find_event(self,handle,map,trans): + """finds a Event in the database using the handle and map + variables to translate between the external ID and gramps' + internal ID. If no such Event exists, a new Event instance + is created. + + handle - external ID number + map - map build by find_source of external to gramp's IDs""" + + event = Event() + if map.has_key(handle): + data = self.event_map.get(str(map[handle])) + event.unserialize(data) + else: + map[handle] = self.add_event(event,trans) + return event + + def try_to_find_source_from_handle(self,val): + """finds a Source in the database from the passed gramps' ID. + If no such Source exists, None is returned.""" + + data = self.source_map.get(str(val)) + if data: + source = Source() + source.unserialize(data) + return source + else: + return None + + def find_source_from_handle(self,val,trans): + """finds a Source in the database from the passed gramps' ID. + If no such Source exists, a new Source is added to the database.""" + + source = Source() + if self.source_map.get(str(val)): + source.unserialize(self.source_map.get(str(val))) + else: + self.add_source_no_map(source,val,trans) + return source + + def find_event_from_handle(self,val): + """finds a Family in the database from the passed gramps' ID. + If no such Family exists, a new Family is added to the database.""" + data = self.event_map.get(str(val)) + if data: + event = Event() + event.unserialize(data) + return event + else: + return None + + def add_object(self,object,trans): + """adds an Object instance to the database, assigning it a gramps' + ID number""" + + index = self.oprefix % self.omap_index + while self.media_map.get(str(index)): + self.omap_index = self.omap_index + 1 + index = self.oprefix % self.omap_index + object.set_handle(index) + if trans != None: + trans.add(MEDIA_KEY,index,None) + self.media_map[str(index)] = object.serialize() + self.omap_index = self.omap_index + 1 + self.added_files.append(object) + + return index + + def find_object_no_conflicts(self,handle,map,trans): + """finds an Object in the database using the handle and map + variables to translate between the external ID and gramps' + internal ID. If no such Object exists, a new Object instance + is created. + + handle - external ID number + map - map build by find_object of external to gramp's IDs""" + + handle = str(handle) + object = MediaObject() + if map.has_key(handle): + object.unserialize(self.media_map.get(str(map[handle]))) + else: + if self.media_map.get(str(handle)): + map[handle] = self.add_object(object,trans) + else: + map[handle] = self.add_object_no_map(object,handle,trans) + return object + + def add_object_no_map(self,object,index,trans): + """adds an Object to the database if the gramps' ID is known""" + index = str(index) + object.set_handle(index) + if trans != None: + trans.add(MEDIA_KEY,index,None) + self.media_map[str(index)] = object.serialize() + self.omap_index = self.omap_index + 1 + self.added_files.append(object) + return index + + def try_to_find_object_from_handle(self,handle): + """finds an Object in the database from the passed gramps' ID. + If no such Object exists, None is returned.""" + + data = self.media_map.get(str(handle)) + if data: + mobject = MediaObject() + mobject.unserialize(data) + return mobject + else: + return None + + def find_object_from_handle(self,handle,trans): + """finds an Object in the database from the passed gramps' ID. + If no such Object exists, a new Object is added to the database.""" + + object = MediaObject() + if self.media_map.get(str(handle)): + object.unserialize(self.media_map.get(str(handle))) + else: + self.add_object_no_map(object,handle,trans) + return object + + def has_object_handle(self,handle): + """finds an Object in the database from the passed gramps' ID. + If no such Source exists, a new Source is added to the database.""" + + return self.media_map.get(str(handle)) != None + + def add_place(self,place,trans): + """adds a Place instance to the database, assigning it a gramps' + ID number""" + + index = self.pprefix % self.lmap_index + while self.place_map.get(str(index)): + self.lmap_index = self.lmap_index + 1 + index = self.pprefix % self.lmap_index + place.set_handle(index) + if trans != None: + trans.add(PLACE_KEY,index,None) + self.place_map[str(index)] = place.serialize() + self.lmap_index = self.lmap_index + 1 + return index + + def remove_object(self,handle,transaction): + assert(0,"Needs to be overridden in the derived class") + + def remove_place(self,handle,transaction): + assert(0,"Needs to be overridden in the derived class") + + def add_place_as(self,place,trans): + if trans != None: + trans.add(PLACE_KEY,place.get_handle(),None) + self.place_map[str(place.get_handle())] = place.serialize() + return place.get_handle() + + def find_place_no_conflicts(self,handle,map,trans): + """finds a Place in the database using the handle and map + variables to translate between the external ID and gramps' + internal ID. If no such Place exists, a new Place instance + is created. + + handle - external ID number + map - map build by findPlace of external to gramp's IDs""" + + if map.has_key(str(handle)): + place = Place() + data = self.place_map[str(map[handle])] + place.unserialize(data) + else: + place = Place() + if self.place_map.has_key(str(handle)): + map[handle] = self.add_place(place,trans) + else: + place.set_handle(str(handle)) + map[str(handle)] = self.add_place_as(place,trans) + self.place_map[str(handle)] = place.serialize() + return place + + def add_place_no_map(self,place,index,trans): + """adds a Place to the database if the gramps' ID is known""" + + index = str(index) + place.set_handle(index) + if trans != None: + trans.add(PLACE_KEY,index,None) + self.place_map[str(index)] = place.serialize() + self.lmap_index = self.lmap_index + 1 + return index + + def find_place_from_handle(self,handle,trans): + """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.handle = handle + if trans != None: + trans.add(PLACE_KEY,handle,None) + self.place_map[str(handle)] = place.serialize() + self.lmap_index = self.lmap_index + 1 + else: + place.unserialize(data) + return place + + def try_to_find_place_from_handle(self,handle): + """finds a Place in the database from the passed gramps' ID. + If no such Place exists, None is returned.""" + + data = self.place_map.get(str(handle)) + + if data: + place = Place() + place.unserialize(data) + return place + else: + return None + + def sortbyplace(self,f,s): + return cmp(self.placesortmap[f], self.placesortmap[s]) + + def sortbysource(self,f,s): + fp = self.source_map[f][1].upper() + sp = self.source_map[s][1].upper() + return cmp(fp,sp) + + def sortbymedia(self,f,s): + fp = self.media_map[f][3].upper() + sp = self.media_map[s][3].upper() + return cmp(fp,sp) + + def sort_place_keys(self): + if self.place_map: + self.placesortmap = {} + for key in self.place_map.keys(): + self.placesortmap[key] = self.place_map[key][1].upper() + keys = self.placesortmap.keys() + keys.sort(self.sortbyplace) + del self.placesortmap + return keys + return [] + + def sort_media_keys(self): + if self.media_map: + keys = self.media_map.keys() + keys.sort(self.sortbymedia) + return keys + else: + return [] + + def sort_source_keys(self): + if self.source_map: + keys = self.source_map.keys() + keys.sort(self.sortbysource) + return keys + else: + return [] + + def get_place_handle_keys(self): + if self.place_map: + return self.place_map.keys() + else: + return [] + + def get_place_handle(self,key): + place = Place() + place.unserialize(self.place_map.get(str(key))) + return place + + def get_place_display(self,key): + # fix this up better + place = Place() + place.unserialize(self.place_map[str(key)]) + return place.get_display_info() + + def get_source_keys(self): + if self.source_map: + return self.source_map.keys() + return [] + + def get_object_keys(self): + if self.media_map: + return self.media_map.keys() + return [] + + def get_event_keys(self): + if self.event_map: + return self.event_map.keys() + return [] + + def sortbysource(self,f,s): + f1 = self.source_map[f][1].upper() + s1 = self.source_map[s][1].upper() + return cmp(f1,s1) + + def set_source_keys(self): + keys = self.source_map.keys() + if type(keys) == type([]): + keys.sort(self.sortbyplace) + return keys + + def get_source_display(self,key): + source = Source() + source.unserialize(self.source_map.get(str(key))) + return source.get_display_info() + + def get_source(self,key): + source = Source() + source.unserialize(self.source_map[key]) + return source + + def build_source_display(self,nkey,okey=None): + pass + + def new_family(self,trans): + """adds a Family to the database, assigning a gramps' ID""" + + index = self.fprefix % self.fmap_index + while self.family_map.get(str(index)): + self.fmap_index = self.fmap_index + 1 + index = self.fprefix % self.fmap_index + self.fmap_index = self.fmap_index + 1 + family = Family() + family.set_handle(unicode(index)) + if trans != None: + trans.add(FAMILY_KEY, index, None) + self.family_map[str(index)] = family.serialize() + return family + + def new_family_no_map(self,handle,trans): + """finds a Family in the database from the passed gramps' ID. + If no such Family exists, a new Family is added to the database.""" + + family = Family() + family.set_handle(handle) + if trans != None: + trans.add(FAMILY_KEY, handle, None) + self.family_map[str(handle)] = family.serialize() + self.fmap_index = self.fmap_index + 1 + return family + + def find_family_with_map(self,handle,map,trans): + """finds a Family in the database using the handle and map + variables to translate between the external ID and gramps' + internal ID. If no such Family exists, a new Family instance + is created. + + handle - external ID number + map - map build by find_family_with_map of external to gramp's IDs""" + + if map.has_key(handle): + family = Family() + data = self.family_map.get(str(map[handle])) + family.unserialize(data) + else: + family = self.new_family(trans) + map[handle] = family.get_handle() + return family + + def find_family_no_map(self,val,trans): + """finds a Family in the database from the passed gramps' ID. + 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) + else: + family.handle = val + if trans: + trans.add(FAMILY_KEY,val,None) + self.family_map[str(val)] = family.serialize() + self.fmap_index = self.fmap_index + 1 + return family + + def find_family_from_handle(self,val): + """finds a Family in the database from the passed gramps' ID. + If no such Family exists, a new Family is added to the database.""" + data = self.family_map.get(str(val)) + if data: + family = Family() + family.unserialize(data) + return family + else: + return None + + def delete_family(self,family_handle,trans): + """deletes the Family instance from the database""" + if self.family_map.get(str(family_handle)): + if trans != None: + old_data = self.family_map.get(str(family_handle)) + trans.add(FAMILY_KEY,family_handle,old_data) + del self.family_map[str(family_handle)] + + def find_family_no_conflicts(self,handle,map,trans): + """finds a Family in the database using the handle and map + variables to translate between the external ID and gramps' + internal ID. If no such Family exists, a new Family instance + is created. + + handle - external ID number + map - map build by findFamily of external to gramp's IDs""" + + if map.has_key(str(handle)): + family = Family() + family.unserialize(self.family_map.get(str(map[str(handle)]))) + else: + if self.family_map.has_key(str(handle)): + family = self.new_family(trans) + else: + family = self.new_family_no_map(str(handle),trans) + map[handle] = family.get_handle() + return family + + def find_source_no_conflicts(self,handle,map,trans): + """finds a Source in the database using the handle and map + variables to translate between the external ID and gramps' + internal ID. If no such Source exists, a new Source instance + is created. + + handle - external ID number + map - map build by findSource of external to gramp's IDs""" + + source = Source() + if map.has_key(handle): + source.unserialize(self.source_map.get(str(map[handle]))) + else: + if self.source_map.get(str(handle)): + map[handle] = self.add_source(source,trans) + else: + map[handle] = self.add_source(source,trans) + return source + + def set_column_order(self,list): + if self.metadata != None: + self.metadata['columns'] = list + + def set_place_column_order(self,list): + if self.metadata != None: + self.metadata['place_columns'] = list + + def set_source_column_order(self,list): + if self.metadata != None: + self.metadata['source_columns'] = list + + def set_media_column_order(self,list): + if self.metadata != None: + self.metadata['media_columns'] = list + + def get_column_order(self): + default = [(1,1),(1,2),(1,3),(0,4),(1,5),(0,6),(0,7)] + if self.metadata == None: + return default + else: + cols = self.metadata.get('columns',default) + if len(cols) != len(default): + return cols + default[len(cols):] + else: + return cols + + def get_place_column_order(self): + default = [(1,1),(1,2),(0,3),(1,4),(0,5),(1,6),(0,7),(0,8)] + if self.metadata == None: + return default + else: + cols = self.metadata.get('place_columns',default) + if len(cols) != len(default): + return cols + default[len(cols):] + else: + return cols + + def get_source_column_order(self): + default = [(1,1),(1,2),(1,3),(0,4)] + if self.metadata == None: + return default + else: + cols = self.metadata.get('source_columns',default) + if len(cols) != len(default): + return cols + default[len(cols):] + else: + return cols + + def get_media_column_order(self): + default = [(1,1),(1,2),(1,3)] + if self.metadata == None: + return default + else: + cols = self.metadata.get('meda_columns',default) + if len(cols) != len(default): + return cols + default[len(cols):] + else: + return cols +#------------------------------------------------------------------------- +# +# Transaction +# +#------------------------------------------------------------------------- +class Transaction: + + def __init__(self,msg,db): + print db + self.db = db + self.first = None + self.last = None + + def get_description(self): + return self.msg + + def set_description(self,msg): + self.msg = msg + + def add(self, type, handle, data): + self.last = self.db.append(cPickle.dumps((type,handle,data),1)) + if self.first == None: + self.first = self.last + + def get_recnos(self): + return range (self.first, self.last+1) + + def get_record(self,id): + return cPickle.loads(self.db[id]) + + def __len__(self): + if self.last and self.first: + return self.last - self.first + 1 + return 0 + + def display(self): + for record in self.get_recnos(): + (key,handle,val) = self.get_record(record) + if key == PERSON_KEY: + if val: + print "PERSON %s change" % handle + else: + print "PERSON %s remove" % handle + elif key == FAMILY_KEY: + if val: + print "FAMILY %s change" % handle + else: + print "FAMILY %s remove" % handle + elif key == EVENT_KEY: + if val: + print "EVENT %s change" % handle + else: + print "EVENT %s remove" % handle + elif key == SOURCE_KEY: + if val: + print "SOURCE %s change" % handle + else: + print "SOURCE %s remove" % handle + elif key == MEDIA_KEY: + if val: + print "MEDIA %s change" % handle + else: + print "MEDIA %s remove" % handle + elif key == PLACE_KEY: + if val: + print "PLACE %s change" % handle + else: + print "PLACE %s remove" % handle + diff --git a/src/GrampsGEDDB.py b/src/GrampsGEDDB.py new file mode 100644 index 000000000..d0f0a4dc0 --- /dev/null +++ b/src/GrampsGEDDB.py @@ -0,0 +1,102 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2004 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 +# + +# $Id$ + +from RelLib import * +from GrampsDbBase import * + +import ReadGedcom +import WriteGedcom + +#------------------------------------------------------------------------- +# +# GrampsGEDDB +# +#------------------------------------------------------------------------- +class GrampsGEDDB(GrampsDbBase): + """GRAMPS database object. This object is a base class for other + objects.""" + + def __init__(self): + """creates a new GrampsDB""" + GrampsDbBase.__init__(self) + + def load(self,name,callback): + self.person_map = {} + self.family_map = {} + self.place_map = {} + self.source_map = {} + self.media_map = {} + self.event_map = {} + self.metadata = {} + self.filename = name + self.id_trans = {} + self.eventnames = {} + self.undodb = [] + + ReadGedcom.importData(self,name) + + self.bookmarks = self.metadata.get('bookmarks') + if self.bookmarks == None: + self.bookmarks = [] + return 1 + + def close(self): + writer = WriteGedcom.GedcomWriter(self,self.get_default_person()) + writer.export_data(self.filename) + + def get_surnames(self): + a = {} + for person_id in self.get_person_keys(): + p = self.try_to_find_person_from_handle(person_id) + a[p.get_primary_name().get_surname()] = 1 + vals = a.keys() + vals.sort() + return vals + + def get_eventnames(self): + names = self.eventnames.keys() + a = {} + for name in names: + a[unicode(name)] = 1 + vals = a.keys() + vals.sort() + return vals + + def remove_person_handle(self,handle,transaction): +# self.genderStats.uncount_person (self.person_map[handle]) + if transaction != None: + old_data = self.person_map.get(handle) + transaction.add(PERSON_KEY,handle,old_data) + del self.person_map[handle] + + def remove_source_handle(self,handle,transaction): + if transaction != None: + old_data = self.source_map.get(str(handle)) + transaction.add(SOURCE_KEY,handle,old_data) + del self.source_map[str(handle)] + + def remove_event_handle(self,handle,transaction): + if transaction != None: + old_data = self.event_map.get(str(handle)) + transaction.add(EVENT_KEY,handle,old_data) + del self.event_map[str(handle)] + diff --git a/src/GrampsXMLDB.py b/src/GrampsXMLDB.py new file mode 100644 index 000000000..d42c8d041 --- /dev/null +++ b/src/GrampsXMLDB.py @@ -0,0 +1,110 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2000-2004 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 +# + +# $Id$ + +from RelLib import * +from GrampsDbBase import * + +import ReadXML +import WriteXML + +_UNDO_SIZE = 1000 + +#------------------------------------------------------------------------- +# +# ID regular expression +# +#------------------------------------------------------------------------- +_id_reg = compile("%\d+d") + +#------------------------------------------------------------------------- +# +# GrampsXMLDB +# +#------------------------------------------------------------------------- +class GrampsXMLDB(GrampsDbBase): + """GRAMPS database object. This object is a base class for other + objects.""" + + def __init__(self): + """creates a new GrampsDB""" + GrampsDbBase.__init__(self) + + def load(self,name,callback): + self.person_map = {} + self.family_map = {} + self.place_map = {} + self.source_map = {} + self.media_map = {} + self.event_map = {} + self.metadata = {} + self.filename = name + self.id_trans = {} + self.eventnames = {} + self.undodb = [] + + ReadXML.importData(self,name) + + self.bookmarks = self.metadata.get('bookmarks') + if self.bookmarks == None: + self.bookmarks = [] + return 1 + + def close(self): + WriteXML.quick_write(self,self.filename) + + def get_surnames(self): + a = {} + for person_id in self.get_person_keys(): + p = self.try_to_find_person_from_handle(person_id) + a[p.get_primary_name().get_surname()] = 1 + vals = a.keys() + vals.sort() + return vals + + def get_eventnames(self): + names = self.eventnames.keys() + a = {} + for name in names: + a[unicode(name)] = 1 + vals = a.keys() + vals.sort() + return vals + + def remove_person_handle(self,handle,transaction): +# self.genderStats.uncount_person (self.person_map[handle]) + if transaction != None: + old_data = self.person_map.get(handle) + transaction.add(PERSON_KEY,handle,old_data) + del self.person_map[handle] + + def remove_source_handle(self,handle,transaction): + if transaction != None: + old_data = self.source_map.get(str(handle)) + transaction.add(SOURCE_KEY,handle,old_data) + del self.source_map[str(handle)] + + def remove_event_handle(self,handle,transaction): + if transaction != None: + old_data = self.event_map.get(str(handle)) + transaction.add(EVENT_KEY,handle,old_data) + del self.event_map[str(handle)] + diff --git a/src/PeopleModel.py b/src/PeopleModel.py index 9f08a5497..7dc0077f3 100644 --- a/src/PeopleModel.py +++ b/src/PeopleModel.py @@ -89,7 +89,7 @@ class PeopleModel(gtk.GenericTreeModel): ] maps = self.db.get_people_view_maps() - if maps[0] != None: + if maps[0] != None and len(maps[0]) != 0: self.top_iter2path = maps[0] self.top_path2iter = maps[1] self.iter2path = maps[2] @@ -137,7 +137,7 @@ class PeopleModel(gtk.GenericTreeModel): return for person_handle in self.db.get_person_keys(): - + person = self.db.try_to_find_person_from_handle(person_handle) surname = unicode(person.get_primary_name().get_surname()) diff --git a/src/ReadXML.py b/src/ReadXML.py index 17f13a8cd..f239bc27e 100644 --- a/src/ReadXML.py +++ b/src/ReadXML.py @@ -447,7 +447,7 @@ class GrampsParser: self.db.set_researcher(self.owner) if self.tempDefault != None: id = self.tempDefault - person = self.db.find_person_from_gramps_id(id,self.trans) + person = self.find_person_by_gramps_id(id) if person: self.db.set_default_person_handle(person.get_handle()) @@ -602,15 +602,15 @@ class GrampsParser: self.tempDefault = attrs["default"] def start_father(self,attrs): - person = self.db.find_person_from_gramps_id(self.map_gid(attrs["ref"]),self.trans) + 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.db.find_person_from_gramps_id(self.map_gid(attrs["ref"]),self.trans) + 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.db.find_person_from_gramps_id(self.map_gid(attrs["ref"]),self.trans) + 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): diff --git a/src/RelLib.py b/src/RelLib.py index b126c9d8f..cec9bbbbd 100644 --- a/src/RelLib.py +++ b/src/RelLib.py @@ -1505,7 +1505,7 @@ class Person(SourceNote): for family_handle in person.get_family_handle_list(): family = db.find_family_from_handle(family_handle) for child_handle in family.get_child_handle_list(): - child = db.find_person_from_handle(child_handle) + child = db.try_to_find_person_from_handle(child_handle) if child.birth_handle: child_birth = db.find_event_from_handle(child.birth_handle) if child_birth.get_date() != "": @@ -1538,7 +1538,7 @@ class Person(SourceNote): if not parent_id: continue - parent = db.find_person_from_handle(parent_id) + parent = db.try_to_find_person_from_handle(parent_id) if parent.birth_handle: parent_birth = db.find_event_from_handle(parent.birth_handle) if parent_birth.get_date(): @@ -1570,7 +1570,7 @@ class Person(SourceNote): continue if spouse_id == self.handle: continue - spouse = db.find_person_from_handle(spouse_id) + spouse = db.try_to_find_person_from_handle(spouse_id) if spouse.birth_handle: spouse_birth = db.find_event_from_handle(spouse.birth_handle) if spouse_birth.get_date() != "": @@ -2309,13 +2309,3 @@ class GenderStats: return Person.unknown -from bsddb import dbshelve, db - -def find_surname(key,data): - return str(data[3].get_surname()) - -def find_idmap(key,data): - return str(data[1]) - -def find_eventname(key,data): - return str(data[1]) diff --git a/src/WriteXML.py b/src/WriteXML.py index f7302923e..182e05b1b 100644 --- a/src/WriteXML.py +++ b/src/WriteXML.py @@ -236,7 +236,7 @@ class XmlWriter: self.g.write(" \n") keys = self.db.get_person_keys() @@ -498,7 +498,7 @@ 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_handle()))) + self.g.write('%s\n' % (sp2,self.fix(ord.get_family_handle().get_gramps_id()))) if ord.get_note() != "": self.write_note("note",ord.get_note_object(),index+1) for s in ord.get_source_references(): @@ -533,7 +533,7 @@ class XmlWriter: def write_id(self,label,person,index=1): if person: - self.g.write('%s<%s id="%s"' % (" "*index,label,person.get_handle())) + self.g.write('%s<%s id="%s"' % (" "*index,label,person.get_gramps_id())) comp = person.get_complete() if comp: self.g.write(' complete="1"') @@ -792,8 +792,8 @@ class XmlWriter: # #------------------------------------------------------------------------- def sortById(first,second): - fid = first.get_handle() - sid = second.get_handle() + fid = first.get_gramps_id() + sid = second.get_gramps_id() if fid < sid: return -1 diff --git a/src/const.py.in b/src/const.py.in index 92e91fb4e..7fe0bab7e 100644 --- a/src/const.py.in +++ b/src/const.py.in @@ -483,7 +483,10 @@ def display_frel(st): return family_relations.find_value(st) def save_frel(st): - return family_relations.find_key(st) + try: + return family_relations[st][0] + except: + return _("Unknown") #------------------------------------------------------------------------- # diff --git a/src/data/Makefile.am b/src/data/Makefile.am index 33a60d2bf..b2f63605a 100644 --- a/src/data/Makefile.am +++ b/src/data/Makefile.am @@ -9,6 +9,7 @@ dist_pkgdata_DATA = \ gnome-mime-application-x-gramps.png \ gnome-mime-application-x-gedcom.png \ gnome-mime-application-x-gramps-package.png \ + gnome-mime-application-x-gramps-xml.png \ gramps.applications \ gramps.desktop \ gramps.svg \ diff --git a/src/data/gnome-mime-application-x-gramps-xml.png b/src/data/gnome-mime-application-x-gramps-xml.png new file mode 100644 index 000000000..63bef300f Binary files /dev/null and b/src/data/gnome-mime-application-x-gramps-xml.png differ diff --git a/src/data/gramps.applications b/src/data/gramps.applications index 8f5ba8c0c..98192823b 100644 --- a/src/data/gramps.applications +++ b/src/data/gramps.applications @@ -4,4 +4,4 @@ gramps can_open_multiple_files=false expects_uris=false requires_terminal=false - mime_types=application/x-gramps,application/x-gedcom,application/x-gramps-package + mime_types=application/x-gramps,application/x-gedcom,application/x-gramps-package,application/x-gramps-xml diff --git a/src/data/gramps.keys b/src/data/gramps.keys index 5c93b8dcc..f70a05bd7 100644 --- a/src/data/gramps.keys +++ b/src/data/gramps.keys @@ -20,6 +20,17 @@ application/x-gramps-package: icon-filename=/usr/share/gramps/gramps.png open=gramps %f +application/x-gramps-xml: + description=GRAMPS XML database + default_action_type=application + short_list_application_ids=gramps + short_list_application_ids_for_novice_user_level=gramps + short_list_application_ids_for_intermediate_user_level=gramps + short_list_application_ids_for_advanced_user_level=gramps + category=Documents/Genealogy + icon-filename=/usr/share/gramps/gramps.png + open=gramps %f + application/x-gedcom: description=GEDCOM default_action_type=application diff --git a/src/data/gramps.mime b/src/data/gramps.mime index 7494685fa..073597b54 100644 --- a/src/data/gramps.mime +++ b/src/data/gramps.mime @@ -1,6 +1,9 @@ application/x-gramps ext: grdb +application/x-gramps-xml + ext: gramps + application/x-gramps-package ext: gpkg diff --git a/src/data/gramps.schemas b/src/data/gramps.schemas index 8cf0db346..dfa29a04c 100644 --- a/src/data/gramps.schemas +++ b/src/data/gramps.schemas @@ -107,6 +107,19 @@ + + /schemas/apps/gramps/preferences/eprefix + /apps/gramps/preferences/eprefix + gramps + string + E%04d + + Default event GRAMPS ID pattern + The new GRAMPS IDs for the events are generated according + to this format string. + + + /schemas/apps/gramps/preferences/iprefix /apps/gramps/preferences/iprefix diff --git a/src/data/gramps.xml b/src/data/gramps.xml index 8525f11ff..e29914ebc 100644 --- a/src/data/gramps.xml +++ b/src/data/gramps.xml @@ -12,4 +12,8 @@ GRAMPS package + + GRAMPS XML database + + diff --git a/src/gramps_main.py b/src/gramps_main.py index 88e2d5d4f..bdde0950a 100755 --- a/src/gramps_main.py +++ b/src/gramps_main.py @@ -53,6 +53,7 @@ import gtk.gdk #------------------------------------------------------------------------- import RelLib import GrampsBSDDB +import GrampsXMLDB import PedView import MediaView import PlaceView @@ -130,11 +131,6 @@ class Gramps: self.hindex = -1 self.db = GrampsBSDDB.GrampsBSDDB() - self.db.set_iprefix(GrampsCfg.get_iprefix()) - self.db.set_oprefix(GrampsCfg.get_oprefix()) - self.db.set_fprefix(GrampsCfg.get_fprefix()) - self.db.set_sprefix(GrampsCfg.get_sprefix()) - self.db.set_pprefix(GrampsCfg.get_pprefix()) GrampsCfg.loadConfig() diff --git a/src/plugins/ReadGedcom.py b/src/plugins/ReadGedcom.py index 3950baa6c..b26e46c50 100644 --- a/src/plugins/ReadGedcom.py +++ b/src/plugins/ReadGedcom.py @@ -129,6 +129,8 @@ def importData(database, filename, cb=None): # add some checking here glade_file = "%s/gedcomimport.glade" % os.path.dirname(__file__) + if not os.path.isfile(glade_file): + glade_file = "plugins/gedcomimport.glade" statusTop = gtk.glade.XML(glade_file,"status","gramps") statusWindow = statusTop.get_widget("status") @@ -219,6 +221,7 @@ class GedcomParser: self.broken_conc = 0 self.is_ftw = 0 self.idswap = {} + self.gid2id = {} self.f = open(file,"rU") self.filename = file @@ -514,7 +517,7 @@ class GedcomParser: self.indi_count = self.indi_count + 1 id = matches[1] id = id[1:-1] - self.person = self.find_or_create_person(id) + self.person = self.find_or_create_person(self.map_gid(id)) self.added[self.person.get_handle()] = 1 self.parse_individual() self.db.commit_person(self.person, self.trans) @@ -545,14 +548,23 @@ class GedcomParser: if self.idswap.get(id): return self.idswap[id] else: - if self.db.idtrans.get(str(id)): + if self.db.id_trans.get(str(id)): self.idswap[id] = self.db.find_next_gid() else: self.idswap[id] = id return self.idswap[id] - def find_or_create_person(self,id): - person = self.db.find_person_from_gramps_id(self.map_gid(id),self.trans) + def find_or_create_person(self,gramps_id): + person = RelLib.Person() + intid = self.gid2id.get(gramps_id) + if self.db.person_map.has_key(intid): + person.unserialize(self.db.person_map.get(intid)) + else: + intid = Utils.create_id() + person.set_handle(intid) + person.set_gramps_id(gramps_id) + self.db.add_person_as(person,self.trans) + self.gid2id[gramps_id] = intid return person def parse_cause(self,event,level): @@ -620,12 +632,12 @@ class GedcomParser: return elif matches[1] == "HUSB": id = matches[2] - person = self.find_or_create_person(id[1:-1]) + person = self.find_or_create_person(self.map_gid(id[1:-1])) self.family.set_father_handle(person.get_handle()) self.ignore_sub_junk(2) elif matches[1] == "WIFE": id = matches[2] - person = self.find_or_create_person(id[1:-1]) + person = self.find_or_create_person(self.map_gid(id[1:-1])) self.family.set_mother_handle(person.get_handle()) self.ignore_sub_junk(2) elif matches[1] == "SLGS": @@ -639,7 +651,7 @@ class GedcomParser: elif matches[1] == "CHIL": mrel,frel = self.parse_ftw_relations(2) id = matches[2] - child = self.find_or_create_person(id[1:-1]) + child = self.find_or_create_person(self.map_gid(id[1:-1])) self.family.add_child_handle(child.get_handle()) for f in child.get_parent_family_handle_list(): @@ -1734,7 +1746,7 @@ class GedcomParser: new_key = prefix % val new_pmax = max(new_pmax,val) - person = self.db.find_person_from_handle(pid,self.trans) + person = self.db.try_to_find_person_from_handle(pid,self.trans) # new ID is not used if not self.db.has_person_handle(new_key): @@ -1743,7 +1755,7 @@ class GedcomParser: person.set_gramps_id(new_key) self.db.add_person(person,self.trans) else: - tp = self.db.find_person_from_handle(new_key,self.trans) + tp = self.db.try_to_find_person_from_handle(new_key,self.trans) # same person, just change it if person == tp: self.db.remove_person_handle(pid,self.trans) diff --git a/src/plugins/WriteGedcom.py b/src/plugins/WriteGedcom.py index 054d21277..8def35f8a 100644 --- a/src/plugins/WriteGedcom.py +++ b/src/plugins/WriteGedcom.py @@ -374,6 +374,9 @@ class GedcomWriterOptionBox: self.adopt = GedcomInfo.ADOPT_EVENT glade_file = "%s/gedcomexport.glade" % os.path.dirname(__file__) + if not os.path.isfile(glade_file): + glade_file = "plugins/gedcomexport.glade" + self.topDialog = gtk.glade.XML(glade_file,"gedcomExport","gramps") self.topDialog.signal_autoconnect({ "gnu_free" : self.gnu_free,