2008-02-28 Benny Malengier <benny.malengier@gramps-project.org>

* src/ViewManager.py: allow for info dialog after import
	* src/gen/db/base.py: find returns if new object or not
	* src/gen/db/dbdir.py: find returns if new object or not
	* src/plugins/ImportGeneWeb.py: allow multiple mime types
	* src/plugins/ImportvCard.py: allow multiple mime types
	* src/plugins/ReadGrdb.py: allow multiple mime types
	* src/plugins/ReadPkg.py: allow multiple mime types
	* src/plugins/ImportCSV.py: allow multiple mime types
	* src/DbManager.py: use family tree string, not database
	* src/glade/gramps.glade: add info dialog
	* src/QuestionDialog.py: add info dialog, clean up set transient errors
	* src/GrampsDbUtils/_GrampsDbWriteXML.py: improve comment
	* src/GrampsDbUtils/_ReadXML.py: fix change dates problems, fix 
	 creation of empty objects in bookmarks, add info dialog, clean up
	 relative media import, remove unneeded parameters
	* src/GrampsDbUtils/_GrampsDbWRFactories.py: 
	* src/GrampsDbUtils/_GrampsBSDDB.py: allow multiple mime types
	* src/DbLoader.py: fix up import filters and some mime type issues



svn: r10138
This commit is contained in:
Benny Malengier 2008-02-28 22:32:40 +00:00
parent fefa36ad4e
commit b1561e5f78
17 changed files with 575 additions and 143 deletions

View File

@ -1,3 +1,23 @@
2008-02-28 Benny Malengier <benny.malengier@gramps-project.org>
* src/ViewManager.py: allow for info dialog after import
* src/gen/db/base.py: find returns if new object or not
* src/gen/db/dbdir.py: find returns if new object or not
* src/plugins/ImportGeneWeb.py: allow multiple mime types
* src/plugins/ImportvCard.py: allow multiple mime types
* src/plugins/ReadGrdb.py: allow multiple mime types
* src/plugins/ReadPkg.py: allow multiple mime types
* src/plugins/ImportCSV.py: allow multiple mime types
* src/DbManager.py: use family tree string, not database
* src/glade/gramps.glade: add info dialog
* src/QuestionDialog.py: add info dialog, clean up set transient errors
* src/GrampsDbUtils/_GrampsDbWriteXML.py: improve comment
* src/GrampsDbUtils/_ReadXML.py: fix change dates problems, fix
creation of empty objects in bookmarks, add info dialog, clean up
relative media import, remove unneeded parameters
* src/GrampsDbUtils/_GrampsDbWRFactories.py:
* src/GrampsDbUtils/_GrampsBSDDB.py: allow multiple mime types
* src/DbLoader.py: fix up import filters and some mime type issues
2008-02-28 Frederik De Richter <frederik.de.richter@pandora.be> 2008-02-28 Frederik De Richter <frederik.de.richter@pandora.be>
* src/plugins/Verify.py * src/plugins/Verify.py
links to wiki manual links to wiki manual

View File

@ -69,10 +69,12 @@ import Errors
# Constants # Constants
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
#connection between main mime type, name, and list of alternative mime types
_KNOWN_FORMATS = { _KNOWN_FORMATS = {
const.APP_GRAMPS : _('GRAMPS (grdb)'), const.APP_GRAMPS : [_('GRAMPS (grdb)'), []],
const.APP_GRAMPS_XML : _('GRAMPS XML'), const.APP_GRAMPS_XML : [_('GRAMPS XML'), []],
const.APP_GEDCOM : _('GEDCOM'), const.APP_GEDCOM : [_('GEDCOM'), []],
} }
OPEN_FORMATS = [const.APP_GRAMPS_XML, const.APP_GEDCOM] OPEN_FORMATS = [const.APP_GRAMPS_XML, const.APP_GEDCOM]
@ -86,6 +88,7 @@ class DbLoader:
def __init__(self, dbstate, uistate): def __init__(self, dbstate, uistate):
self.dbstate = dbstate self.dbstate = dbstate
self.uistate = uistate self.uistate = uistate
self.import_info = None
def import_file(self): def import_file(self):
# First thing first: import is a batch transaction # First thing first: import is a batch transaction
@ -112,24 +115,24 @@ class DbLoader:
choose_db_dialog.set_local_only(False) choose_db_dialog.set_local_only(False)
# Always add automatic (match all files) filter # Always add automatic (match all files) filter
add_all_files_filter(choose_db_dialog) add_all_files_filter(choose_db_dialog) # *
add_grdb_filter(choose_db_dialog) #add_grdb_filter(choose_db_dialog) # .grdb no longer native!
add_xml_filter(choose_db_dialog) add_xml_filter(choose_db_dialog) # .gramps
add_gedcom_filter(choose_db_dialog) add_gedcom_filter(choose_db_dialog) # .ged
format_list = OPEN_FORMATS[:] format_list = OPEN_FORMATS[:]
# Add more data type selections if opening existing db # Add more data type selections if opening existing db
for data in import_list: for data in import_list:
mime_filter = data[1] mime_filter = data[1]
mime_type = data[2] mime_types = data[2]
native_format = data[3] native_format = data[3]
format_name = data[4] format_name = data[4]
if not native_format: if not native_format:
choose_db_dialog.add_filter(mime_filter) choose_db_dialog.add_filter(mime_filter)
format_list.append(mime_type) format_list.append(mime_types[0])
_KNOWN_FORMATS[mime_type] = format_name _KNOWN_FORMATS[mime_types[0]] = [format_name, mime_types[1:]]
(box, type_selector) = format_maker(format_list) (box, type_selector) = format_maker(format_list)
choose_db_dialog.set_extra_widget(box) choose_db_dialog.set_extra_widget(box)
@ -166,17 +169,17 @@ class DbLoader:
continue continue
# First we try our best formats # First we try our best formats
if filetype in OPEN_FORMATS: if filetype in OPEN_FORMATS or filetype in _KNOWN_FORMATS:
importer = GrampsDbUtils.gramps_db_reader_factory(filetype) importer = GrampsDbUtils.gramps_db_reader_factory(filetype)
self.do_import(choose_db_dialog, importer, filename) self.do_import(choose_db_dialog, importer, filename)
return True return True
# Then we try all the known plugins
(the_path, the_file) = os.path.split(filename) (the_path, the_file) = os.path.split(filename)
Config.set(Config.RECENT_IMPORT_DIR, the_path) Config.set(Config.RECENT_IMPORT_DIR, the_path)
for (importData, mime_filter, mime_type, native_format, # Then we try all the known plugins
for (importData, mime_filter, mime_types, native_format,
format_name) in import_list: format_name) in import_list:
if filetype == mime_type or the_file == mime_type: if filetype in mime_types:
self.do_import(choose_db_dialog, importData, filename) self.do_import(choose_db_dialog, importData, filename)
return True return True
@ -281,12 +284,16 @@ class DbLoader:
def do_import(self, dialog, importer, filename): def do_import(self, dialog, importer, filename):
self.import_info = None
dialog.destroy() dialog.destroy()
self.uistate.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH)) self.uistate.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
self.uistate.progress.show() self.uistate.progress.show()
try: try:
importer(self.dbstate.db, filename, self.uistate.pulse_progressbar) #an importer can return an object with info, object.info_text()
#returns that info. Otherwise None is set to import_info
self.import_info = importer(self.dbstate.db, filename,
self.uistate.pulse_progressbar)
dirname = os.path.dirname(filename) + os.path.sep dirname = os.path.dirname(filename) + os.path.sep
Config.set(Config.RECENT_IMPORT_DIR, dirname) Config.set(Config.RECENT_IMPORT_DIR, dirname)
except UnicodeError, msg: except UnicodeError, msg:
@ -297,6 +304,16 @@ class DbLoader:
"encoding, and import again") + "\n\n %s" % msg) "encoding, and import again") + "\n\n %s" % msg)
except Exception: except Exception:
_LOG.error("Failed to import database.", exc_info=True) _LOG.error("Failed to import database.", exc_info=True)
def import_info_text(self):
"""
On import the importer can construct an info object about the import.
If so, this method will return this text, otherwise the empty string
is returned
"""
if self.import_info is None:
return u""
return self.import_info.info_text()
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -348,7 +365,7 @@ def add_grdb_filter(chooser):
Add a GRDB filter to the file chooser dialog. Add a GRDB filter to the file chooser dialog.
""" """
mime_filter = gtk.FileFilter() mime_filter = gtk.FileFilter()
mime_filter.set_name(_('GRAMPS databases')) mime_filter.set_name(_('GRAMPS 2.x databases'))
mime_filter.add_mime_type(const.APP_GRAMPS) mime_filter.add_mime_type(const.APP_GRAMPS)
chooser.add_filter(mime_filter) chooser.add_filter(mime_filter)
@ -409,7 +426,7 @@ def format_maker(formats):
format_list = [ ('auto', _('Automatically detected')) ] format_list = [ ('auto', _('Automatically detected')) ]
for format in formats: for format in formats:
if _KNOWN_FORMATS.has_key(format): if _KNOWN_FORMATS.has_key(format):
format_list.append( (format, _KNOWN_FORMATS[format]) ) format_list.append( (format, _KNOWN_FORMATS[format][0]) )
type_selector = GrampsFormatWidget() type_selector = GrampsFormatWidget()
type_selector.set(format_list) type_selector.set(format_list)

View File

@ -684,9 +684,9 @@ class DbManager(CLIDbManager):
if len(path) == 1: if len(path) == 1:
QuestionDialog( QuestionDialog(
_("Remove the '%s' database?") % self.data_to_delete[0], _("Remove the '%s' family tree?") % self.data_to_delete[0],
_("Removing this database will permanently destroy the data."), _("Removing this family tree will permanently destroy the data."),
_("Remove database"), _("Remove family tree"),
self.__really_delete_db) self.__really_delete_db)
else: else:
rev = self.data_to_delete[0] rev = self.data_to_delete[0]

View File

@ -1475,13 +1475,17 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
def find_from_handle(self, hndl, transaction, class_type, dmap, add_func): def find_from_handle(self, hndl, transaction, class_type, dmap, add_func):
obj = class_type() obj = class_type()
hndl = str(hndl) hndl = str(hndl)
new = True
if dmap.has_key(hndl): if dmap.has_key(hndl):
data = dmap.get(hndl, txn=self.txn) data = dmap.get(hndl, txn=self.txn)
obj.unserialize(data) obj.unserialize(data)
#references create object with id None before object is really made
if obj.gramps_id is not None:
new = False
else: else:
obj.set_handle(hndl) obj.set_handle(hndl)
add_func(obj, transaction) add_func(obj, transaction)
return obj return obj, new
def transaction_begin(self, msg="", batch=False, no_magic=False): def transaction_begin(self, msg="", batch=False, no_magic=False):
""" """

View File

@ -66,7 +66,7 @@ def gramps_db_reader_factory(db_type):
#see if registered importer #see if registered importer
found = False found = False
for data in import_list: for data in import_list:
if db_type == data[2]: if db_type in data[2]:
print "Found import plugin for %s" % data[4] print "Found import plugin for %s" % data[4]
found = True found = True
md = data[0] md = data[0]

View File

@ -103,8 +103,8 @@ class GrampsDbXmlWriter(UpdateCallback):
db - database to write db - database to write
strip_photos - remove paths off of media object paths strip_photos - remove paths off of media object paths
> 0: do not touch the paths > 0: do not touch the paths
> 1: remove everything expect the filename > 1: remove everything expect the filename (eg gpkg)
> 2: remove leading slash > 2: remove leading slash (quick write)
compress - attempt to compress the database compress - attempt to compress the database
""" """
UpdateCallback.__init__(self, callback) UpdateCallback.__init__(self, callback)

View File

@ -89,7 +89,7 @@ def importData(database, filename, callback=None, cl=0, use_trans=False):
database.fmap = {} database.fmap = {}
change = os.path.getmtime(filename) change = os.path.getmtime(filename)
parser = GrampsParser(database, callback, basefile, change, filename) parser = GrampsParser(database, callback, change)
linecounter = LineParser(filename) linecounter = LineParser(filename)
line_cnt = linecounter.get_count() line_cnt = linecounter.get_count()
@ -109,7 +109,7 @@ def importData(database, filename, callback=None, cl=0, use_trans=False):
try: try:
xml_file.seek(0) xml_file.seek(0)
parser.parse(xml_file, use_trans, line_cnt, person_cnt) info = parser.parse(xml_file, use_trans, line_cnt, person_cnt)
except IOError, msg: except IOError, msg:
if cl: if cl:
print "Error reading %s" % filename print "Error reading %s" % filename
@ -135,6 +135,8 @@ def importData(database, filename, callback=None, cl=0, use_trans=False):
xml_file.close() xml_file.close()
database.readonly = read_only database.readonly = read_only
return info
## TODO - WITH MEDIA PATH, IS THIS STILL NEEDED? ## TODO - WITH MEDIA PATH, IS THIS STILL NEEDED?
## BETTER LEAVE ALL RELATIVE TO NEW RELATIVE PATH ## BETTER LEAVE ALL RELATIVE TO NEW RELATIVE PATH
@ -183,6 +185,108 @@ def fix_spaces(text_list):
# #
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class ImportInfo:
"""
Class object that can hold information about the import
"""
keyorder = [PERSON_KEY, FAMILY_KEY, SOURCE_KEY, EVENT_KEY, MEDIA_KEY,
PLACE_KEY, REPOSITORY_KEY, NOTE_KEY]
key2data = {
PERSON_KEY : 0,
FAMILY_KEY : 1,
SOURCE_KEY: 2,
EVENT_KEY: 3,
MEDIA_KEY: 4,
PLACE_KEY: 5,
REPOSITORY_KEY: 6,
NOTE_KEY: 7
}
def __init__(self):
"""
Init of the import class.
This creates the datastructures to hold info
"""
self.data_mergeoverwrite = [{},{},{},{},{},{},{},{}]
self.data_newobject = [0,0,0,0,0,0,0,0]
self.data_relpath = False
def add(self, category, key, obj):
"""
Add info of a certain category. Key is one of the predefined keys,
while obj is an object of which information will be extracted
"""
if category == 'merge-overwrite':
self.data_mergeoverwrite[self.key2data[key]][obj.handle] = \
self._extract_mergeinfo(key, obj)
elif category == 'new-object':
self.data_newobject[self.key2data[key]] += 1
elif category == 'relative-path':
self.data_relpath = True
def _extract_mergeinfo(self, key, obj):
"""
Extract info from obj about 'merge-overwrite', Key is one of the
predefined keys.
"""
if key == PERSON_KEY:
return _(" %(id)s - %(text)s\n") % {'id': obj.gramps_id,
'text' : name_displayer.display(obj)
}
elif key == FAMILY_KEY :
return _(" Family %(id)s\n") % {'id': obj.gramps_id}
elif key ==SOURCE_KEY:
return _(" Source %(id)s\n") % {'id': obj.gramps_id}
elif key == EVENT_KEY:
return _(" Event %(id)s\n") % {'id': obj.gramps_id}
elif key == MEDIA_KEY:
return _(" Media Object %(id)s\n") % {'id': obj.gramps_id}
elif key == PLACE_KEY:
return _(" Place %(id)s\n") % {'id': obj.gramps_id}
elif key == REPOSITORY_KEY:
return _(" Repository %(id)s\n") % {'id': obj.gramps_id}
elif key == NOTE_KEY:
return _(" Note %(id)s\n") % {'id': obj.gramps_id}
def info_text(self):
"""
Construct an info message from the data in the class.
"""
key2string = {
PERSON_KEY : _(' People: %d\n'),
FAMILY_KEY : _(' Families: %d\n'),
SOURCE_KEY : _(' Sources: %d\n'),
EVENT_KEY : _(' Events: %d\n'),
MEDIA_KEY : _(' Media Objects: %d\n'),
PLACE_KEY : _(' Places: %d\n'),
REPOSITORY_KEY : _(' Repositories: %d\n'),
NOTE_KEY : _(' Notes: %d\n'),
}
txt = _("Number of new objects imported:\n")
for key in self.keyorder:
txt += key2string[key] % self.data_newobject[self.key2data[key]]
merged = False
for key in self.keyorder:
if self.data_mergeoverwrite[self.key2data[key]]:
merged = True
break
if merged:
txt += _("\n\nObjects merged-overwritten on import:\n")
for key in self.keyorder:
datakey = self.key2data[key]
for handle in self.data_mergeoverwrite[datakey].keys():
txt += self.data_mergeoverwrite[datakey][handle]
if self.data_relpath:
txt += _("\nMedia objects with relative paths have been\n"
"imported. These paths are considered relative to\n"
"the media directory you can set in the preferences,\n"
"or, if not set, relative to the user directory.\n"
)
return txt
class LineParser: class LineParser:
def __init__(self, filename): def __init__(self, filename):
@ -231,9 +335,8 @@ class LineParser:
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
class GrampsParser(UpdateCallback): class GrampsParser(UpdateCallback):
def __init__(self, database, callback, base, change, filename): def __init__(self, database, callback, change):
UpdateCallback.__init__(self, callback) UpdateCallback.__init__(self, callback)
self.filename = filename
self.stext_list = [] self.stext_list = []
self.scomments_list = [] self.scomments_list = []
self.note_list = [] self.note_list = []
@ -251,6 +354,8 @@ class GrampsParser(UpdateCallback):
self.change = change self.change = change
self.dp = DateHandler.parser self.dp = DateHandler.parser
self.place_names = sets.Set() self.place_names = sets.Set()
self.info = ImportInfo()
self.all_abs = True
cursor = database.get_place_cursor() cursor = database.get_place_cursor()
data = cursor.next() data = cursor.next()
while data: while data:
@ -271,7 +376,6 @@ class GrampsParser(UpdateCallback):
self.in_scomments = 0 self.in_scomments = 0
self.in_witness = False self.in_witness = False
self.db = database self.db = database
self.base = base
self.photo = None self.photo = None
self.person = None self.person = None
self.family = None self.family = None
@ -311,7 +415,6 @@ class GrampsParser(UpdateCallback):
self.childref = None self.childref = None
self.personref = None self.personref = None
self.name = None self.name = None
self.tempDefault = None
self.home = None self.home = None
self.owner = gen.lib.Researcher() self.owner = gen.lib.Researcher()
self.func_list = [None]*50 self.func_list = [None]*50
@ -434,120 +537,132 @@ class GrampsParser(UpdateCallback):
def find_person_by_gramps_id(self, gramps_id): def find_person_by_gramps_id(self, gramps_id):
intid = self.gid2id.get(gramps_id) intid = self.gid2id.get(gramps_id)
new = True
if intid: if intid:
person = self.db.get_person_from_handle(intid) person = self.db.get_person_from_handle(intid)
new = False
else: else:
intid = Utils.create_id() intid = Utils.create_id()
person = gen.lib.Person() person = gen.lib.Person()
person.set_handle(intid) person.set_handle(intid)
person.set_gramps_id(gramps_id) person.set_gramps_id(gramps_id)
self.db.add_person(person, self.trans) self.db.add_person(person, self.trans)
#set correct change time
self.db.commit_person(person, self.trans, self.change)
self.gid2id[gramps_id] = intid self.gid2id[gramps_id] = intid
return person return person, new
def find_family_by_gramps_id(self, gramps_id): def find_family_by_gramps_id(self, gramps_id):
intid = self.gid2fid.get(gramps_id) intid = self.gid2fid.get(gramps_id)
new = True
if intid: if intid:
family = self.db.get_family_from_handle(intid) family = self.db.get_family_from_handle(intid)
new = False
else: else:
intid = Utils.create_id() intid = Utils.create_id()
family = gen.lib.Family() family = gen.lib.Family()
family.set_handle(intid) family.set_handle(intid)
family.set_gramps_id(gramps_id) family.set_gramps_id(gramps_id)
self.db.add_family(family, self.trans) self.db.add_family(family, self.trans)
self.db.commit_family(family, self.trans, self.change)
self.gid2fid[gramps_id] = intid self.gid2fid[gramps_id] = intid
return family return family, new
def find_event_by_gramps_id(self, gramps_id): def find_event_by_gramps_id(self, gramps_id):
intid = self.gid2eid.get(gramps_id) intid = self.gid2eid.get(gramps_id)
new = True
if intid: if intid:
event = self.db.get_event_from_handle(intid) event = self.db.get_event_from_handle(intid)
new = False
else: else:
intid = Utils.create_id() intid = Utils.create_id()
event = gen.lib.Event() event = gen.lib.Event()
event.set_handle(intid) event.set_handle(intid)
event.set_gramps_id(gramps_id) event.set_gramps_id(gramps_id)
self.db.add_event(event, self.trans) self.db.add_event(event, self.trans)
self.db.commit_event(event, self.trans, self.change)
self.gid2eid[gramps_id] = intid self.gid2eid[gramps_id] = intid
return event return event, new
def find_place_by_gramps_id(self, gramps_id): def find_place_by_gramps_id(self, gramps_id):
intid = self.gid2pid.get(gramps_id) intid = self.gid2pid.get(gramps_id)
new = True
if intid: if intid:
place = self.db.get_place_from_handle(intid) place = self.db.get_place_from_handle(intid)
new = False
else: else:
intid = Utils.create_id() intid = Utils.create_id()
place = gen.lib.Place() place = gen.lib.Place()
place.set_handle(intid) place.set_handle(intid)
place.set_gramps_id(gramps_id) place.set_gramps_id(gramps_id)
self.db.add_place(place, self.trans) self.db.add_place(place, self.trans)
self.db.commit_place(place, self.trans, self.change)
self.gid2pid[gramps_id] = intid self.gid2pid[gramps_id] = intid
return place return place, new
def find_source_by_gramps_id(self, gramps_id): def find_source_by_gramps_id(self, gramps_id):
intid = self.gid2sid.get(gramps_id) intid = self.gid2sid.get(gramps_id)
new = True
if intid: if intid:
source = self.db.get_source_from_handle(intid) source = self.db.get_source_from_handle(intid)
new = False
else: else:
intid = Utils.create_id() intid = Utils.create_id()
source = gen.lib.Source() source = gen.lib.Source()
source.set_handle(intid) source.set_handle(intid)
source.set_gramps_id(gramps_id) source.set_gramps_id(gramps_id)
self.db.add_source(source, self.trans) self.db.add_source(source, self.trans)
self.db.commit_source(source, self.trans, self.change)
self.gid2sid[gramps_id] = intid self.gid2sid[gramps_id] = intid
return source return source, new
def find_object_by_gramps_id(self, gramps_id): def find_object_by_gramps_id(self, gramps_id):
intid = self.gid2oid.get(gramps_id) intid = self.gid2oid.get(gramps_id)
new = True
if intid: if intid:
obj = self.db.get_object_from_handle(intid) obj = self.db.get_object_from_handle(intid)
new = False
else: else:
intid = Utils.create_id() intid = Utils.create_id()
obj = gen.lib.MediaObject() obj = gen.lib.MediaObject()
obj.set_handle(intid) obj.set_handle(intid)
obj.set_gramps_id(gramps_id) obj.set_gramps_id(gramps_id)
self.db.add_object(obj, self.trans) self.db.add_object(obj, self.trans)
self.db.commit_media_object(obj, self.trans, self.change)
self.gid2oid[gramps_id] = intid self.gid2oid[gramps_id] = intid
return obj return obj, new
def find_repository_by_gramps_id(self, gramps_id): def find_repository_by_gramps_id(self, gramps_id):
intid = self.gid2rid.get(gramps_id) intid = self.gid2rid.get(gramps_id)
new = True
if intid: if intid:
repo = self.db.get_repository_from_handle(intid) repo = self.db.get_repository_from_handle(intid)
new = False
else: else:
intid = Utils.create_id() intid = Utils.create_id()
repo = gen.lib.Repository() repo = gen.lib.Repository()
repo.set_handle(intid) repo.set_handle(intid)
repo.set_gramps_id(gramps_id) repo.set_gramps_id(gramps_id)
self.db.add_repository(repo, self.trans) self.db.add_repository(repo, self.trans)
self.db.commit_repository(repo, self.trans, self.change)
self.gid2rid[gramps_id] = intid self.gid2rid[gramps_id] = intid
return repo return repo, new
def find_note_by_gramps_id(self, gramps_id): def find_note_by_gramps_id(self, gramps_id):
intid = self.gid2nid.get(gramps_id) intid = self.gid2nid.get(gramps_id)
new = True
if intid: if intid:
note = self.db.get_note_from_handle(intid) note = self.db.get_note_from_handle(intid)
new = False
else: else:
intid = Utils.create_id() intid = Utils.create_id()
note = gen.lib.Note() note = gen.lib.Note()
note.set_handle(intid) note.set_handle(intid)
note.set_gramps_id(gramps_id) note.set_gramps_id(gramps_id)
self.db.add_note(note, self.trans) self.db.add_note(note, self.trans)
self.db.commit_note(note, self.trans, self.change)
self.gid2nid[gramps_id] = intid self.gid2nid[gramps_id] = intid
return note return note, new
def find_repo_by_gramps_id(self, gramps_id):
intid = self.gid2rid.get(gramps_id)
if intid:
repo = self.db.get_repository_from_handle(intid)
else:
intid = Utils.create_id()
repo = gen.lib.Repository()
repo.set_handle(intid)
repo.set_gramps_id(gramps_id)
self.db.add_repository(repo, self.trans)
self.gid2rid[gramps_id] = intid
return repo
def map_gid(self, gramps_id): def map_gid(self, gramps_id):
if not self.idswap.get(gramps_id): if not self.idswap.get(gramps_id):
@ -637,13 +752,9 @@ class GrampsParser(UpdateCallback):
self.db.set_researcher(self.owner) self.db.set_researcher(self.owner)
if self.home != None: if self.home != None:
person = self.db.find_person_from_handle(self.home, self.trans) person = self.db.get_person_from_handle(self.home)
self.db.set_default_person_handle(person.handle) self.db.set_default_person_handle(person.handle)
if self.tempDefault != None:
gramps_id = self.map_gid(self.tempDefault)
person = self.find_person_by_gramps_id(gramps_id)
if person:
self.db.set_default_person_handle(person.handle)
#set media path, this should really do some parsing to convert eg #set media path, this should really do some parsing to convert eg
# windows path to unix ? # windows path to unix ?
if self.mediapath: if self.mediapath:
@ -653,9 +764,10 @@ class GrampsParser(UpdateCallback):
elif not oldpath == self.mediapath: elif not oldpath == self.mediapath:
ErrorDialog(_("Could not change media path"), ErrorDialog(_("Could not change media path"),
_("The opened file has media path %s, which conflicts with" _("The opened file has media path %s, which conflicts with"
" the media path of the database. Copy the files with " " the media path of the family tree you import into. "
"non absolute path to new position or change the media " "The original media path has been retained. Copy the "
"path of the database in the Preferences." "files to a correct directory or change the media "
"path in the Preferences."
) % self.mediapath ) ) % self.mediapath )
for key in self.func_map.keys(): for key in self.func_map.keys():
@ -666,6 +778,7 @@ class GrampsParser(UpdateCallback):
self.db.transaction_commit(self.trans, _("GRAMPS XML import")) self.db.transaction_commit(self.trans, _("GRAMPS XML import"))
self.db.enable_signals() self.db.enable_signals()
self.db.request_rebuild() self.db.request_rebuild()
return self.info
def start_lds_ord(self, attrs): def start_lds_ord(self, attrs):
self.ord = gen.lib.LdsOrd() self.ord = gen.lib.LdsOrd()
@ -710,7 +823,7 @@ class GrampsParser(UpdateCallback):
except KeyError: except KeyError:
#legacy, before hlink there was ref #legacy, before hlink there was ref
gramps_id = self.map_pid(attrs['ref']) gramps_id = self.map_pid(attrs['ref'])
place = self.find_place_by_gramps_id(gramps_id) place, new = self.find_place_by_gramps_id(gramps_id)
handle = place.handle handle = place.handle
if self.ord: if self.ord:
@ -723,13 +836,20 @@ class GrampsParser(UpdateCallback):
def start_placeobj(self, attrs): def start_placeobj(self, attrs):
gramps_id = self.map_pid(attrs['id']) gramps_id = self.map_pid(attrs['id'])
try: try:
self.placeobj = self.db.find_place_from_handle( self.placeobj, new = self.db.find_place_from_handle(
attrs['handle'].replace('_', ''), self.trans) attrs['handle'].replace('_', ''), self.trans)
self.placeobj.set_gramps_id(gramps_id) self.placeobj.set_gramps_id(gramps_id)
except KeyError: except KeyError:
self.placeobj = self.find_place_by_gramps_id(gramps_id) self.placeobj, new = self.find_place_by_gramps_id(gramps_id)
self.placeobj.private = bool(attrs.get("priv")) self.placeobj.private = bool(attrs.get("priv"))
if new:
#keep change time from xml file
self.placeobj.change = int(attrs.get('change',self.change))
self.info.add('new-object', PLACE_KEY, self.placeobj)
else:
self.placeobj.change = self.change
self.info.add('merge-overwrite', PLACE_KEY, self.placeobj)
# GRAMPS LEGACY: title in the placeobj tag # GRAMPS LEGACY: title in the placeobj tag
self.placeobj.title = attrs.get('title', '') self.placeobj.title = attrs.get('title', '')
@ -766,15 +886,19 @@ class GrampsParser(UpdateCallback):
note.type.set(gen.lib.NoteType.EVENT) note.type.set(gen.lib.NoteType.EVENT)
note.private = self.event.private note.private = self.event.private
self.db.add_note(note, self.trans) self.db.add_note(note, self.trans)
#set correct change time
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.event.add_note(note.handle) self.event.add_note(note.handle)
return return
try: try:
handle = attrs['hlink'].replace('_', '') handle = attrs['hlink'].replace('_', '')
person = self.db.find_person_from_handle(handle, self.trans) person, new = self.db.find_person_from_handle(handle, self.trans)
except KeyError: except KeyError:
if attrs.has_key('ref'): if attrs.has_key('ref'):
person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) person, new = self.find_person_by_gramps_id(
self.map_gid(attrs["ref"]))
else: else:
person = None person = None
@ -800,17 +924,27 @@ class GrampsParser(UpdateCallback):
self.event.type = gen.lib.EventType() self.event.type = gen.lib.EventType()
self.event.type.set_from_xml_str(attrs['type']) self.event.type.set_from_xml_str(attrs['type'])
self.db.add_event(self.event, self.trans) self.db.add_event(self.event, self.trans)
#set correct change time
self.db.commit_event(self.event, self.trans, self.change)
self.info.add('new-object', EVENT_KEY, self.event)
else: else:
# This is new event, with ID and handle already existing # This is new event, with ID and handle already existing
self.update(self.p.CurrentLineNumber) self.update(self.p.CurrentLineNumber)
gramps_id = self.map_eid(attrs["id"]) gramps_id = self.map_eid(attrs["id"])
try: try:
self.event = self.db.find_event_from_handle( self.event, new = self.db.find_event_from_handle(
attrs['handle'].replace('_', ''), self.trans) attrs['handle'].replace('_', ''), self.trans)
self.event.gramps_id = gramps_id self.event.gramps_id = gramps_id
except KeyError: except KeyError:
self.event = self.find_event_by_gramps_id(gramps_id) self.event, new = self.find_event_by_gramps_id(gramps_id)
self.event.private = bool(attrs.get("priv")) self.event.private = bool(attrs.get("priv"))
if new:
#keep change time from xml file
self.event.change = int(attrs.get('change',self.change))
self.info.add('new-object', EVENT_KEY, self.event)
else:
self.event.change = self.change
self.info.add('merge-overwrite', EVENT_KEY, self.event)
def start_eventref(self, attrs): def start_eventref(self, attrs):
self.eventref = gen.lib.EventRef() self.eventref = gen.lib.EventRef()
@ -877,7 +1011,7 @@ class GrampsParser(UpdateCallback):
self.db.check_person_from_handle(handle, self.trans) self.db.check_person_from_handle(handle, self.trans)
except KeyError: except KeyError:
gramps_id = self.map_gid(attrs["ref"]) gramps_id = self.map_gid(attrs["ref"])
person = self.find_person_by_gramps_id(gramps_id) person, new = self.find_person_by_gramps_id(gramps_id)
handle = person.handle handle = person.handle
self.db.bookmarks.append(handle) self.db.bookmarks.append(handle)
return return
@ -888,35 +1022,35 @@ class GrampsParser(UpdateCallback):
# Make sure those are filtered out. # Make sure those are filtered out.
# Bookmarks are at end, so all handle must exist before we do bookmrks # Bookmarks are at end, so all handle must exist before we do bookmrks
if target == 'person': if target == 'person':
if (self.db.find_person_from_handle(handle,self.trans) is not None if (self.db.get_person_from_handle(handle) is not None
and handle not in self.db.bookmarks.get() ): and handle not in self.db.bookmarks.get() ):
self.db.bookmarks.append(handle) self.db.bookmarks.append(handle)
elif target == 'family': elif target == 'family':
if (self.db.find_family_from_handle(handle,self.trans) is not None if (self.db.get_family_from_handle(handle) is not None
and handle not in self.db.family_bookmarks.get() ): and handle not in self.db.family_bookmarks.get() ):
self.db.family_bookmarks.append(handle) self.db.family_bookmarks.append(handle)
elif target == 'event': elif target == 'event':
if (self.db.find_event_from_handle(handle,self.trans) is not None if (self.db.get_event_from_handle(handle) is not None
and handle not in self.db.event_bookmarks.get() ): and handle not in self.db.event_bookmarks.get() ):
self.db.event_bookmarks.append(handle) self.db.event_bookmarks.append(handle)
elif target == 'source': elif target == 'source':
if (self.db.find_source_from_handle(handle,self.trans) is not None if (self.db.get_source_from_handle(handle) is not None
and handle not in self.db.source_bookmarks.get() ): and handle not in self.db.source_bookmarks.get() ):
self.db.source_bookmarks.append(handle) self.db.source_bookmarks.append(handle)
elif target == 'place': elif target == 'place':
if (self.db.find_place_from_handle(handle,self.trans) is not None if (self.db.get_place_from_handle(handle) is not None
and handle not in self.db.place_bookmarks.get() ): and handle not in self.db.place_bookmarks.get() ):
self.db.place_bookmarks.append(handle) self.db.place_bookmarks.append(handle)
elif target == 'media': elif target == 'media':
if (self.db.find_object_from_handle(handle,self.trans) is not None if (self.db.get_object_from_handle(handle) is not None
and handle not in self.db.media_bookmarks.get() ): and handle not in self.db.media_bookmarks.get() ):
self.db.media_bookmarks.append(handle) self.db.media_bookmarks.append(handle)
elif target == 'repository': elif target == 'repository':
if (self.db.find_repository_from_handle(handle,self.trans) if (self.db.get_repository_from_handle(handle)
is not None and handle not in self.db.repo_bookmarks.get()): is not None and handle not in self.db.repo_bookmarks.get()):
self.db.repo_bookmarks.append(handle) self.db.repo_bookmarks.append(handle)
elif target == 'note': elif target == 'note':
if (self.db.find_note_from_handle(handle, self.trans) is not None if (self.db.get_note_from_handle(handle) is not None
and handle not in self.db.note_bookmarks.get() ): and handle not in self.db.note_bookmarks.get() ):
self.db.note_bookmarks.append(handle) self.db.note_bookmarks.append(handle)
@ -949,13 +1083,20 @@ class GrampsParser(UpdateCallback):
self.update(self.p.CurrentLineNumber) self.update(self.p.CurrentLineNumber)
new_id = self.map_gid(attrs['id']) new_id = self.map_gid(attrs['id'])
try: try:
self.person = self.db.find_person_from_handle( self.person, new = self.db.find_person_from_handle(
attrs['handle'].replace('_', ''), self.trans) attrs['handle'].replace('_', ''), self.trans)
self.person.set_gramps_id(new_id) self.person.set_gramps_id(new_id)
except KeyError: except KeyError:
self.person = self.find_person_by_gramps_id(new_id) self.person, new = self.find_person_by_gramps_id(new_id)
self.person.private = bool(attrs.get("priv")) self.person.private = bool(attrs.get("priv"))
if new:
#keep change time from xml file
self.person.change = int(attrs.get('change',self.change))
self.info.add('new-object', PERSON_KEY, self.person)
else:
self.person.change = self.change
self.info.add('merge-overwrite', PERSON_KEY, self.person)
# Old and new markers: complete=1 and marker=word both have to work # Old and new markers: complete=1 and marker=word both have to work
if attrs.get('complete'): # this is only true for complete=1 if attrs.get('complete'): # this is only true for complete=1
self.person.marker.set(gen.lib.MarkerType.COMPLETE) self.person.marker.set(gen.lib.MarkerType.COMPLETE)
@ -972,7 +1113,7 @@ class GrampsParser(UpdateCallback):
#all persons exist before father tag is encountered #all persons exist before father tag is encountered
self.db.check_person_from_handle(handle, self.trans) self.db.check_person_from_handle(handle, self.trans)
except KeyError: except KeyError:
person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) person, new = self.find_person_by_gramps_id(self.map_gid(attrs["ref"]))
handle = person.handle handle = person.handle
self.family.set_father_handle(handle) self.family.set_father_handle(handle)
@ -982,16 +1123,17 @@ class GrampsParser(UpdateCallback):
#all persons exist before mother tag is encountered #all persons exist before mother tag is encountered
self.db.check_person_from_handle(handle, self.trans) self.db.check_person_from_handle(handle, self.trans)
except KeyError: except KeyError:
person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) person, new = self.find_person_by_gramps_id(self.map_gid(attrs["ref"]))
handle = person.handle handle = person.handle
self.family.set_mother_handle(handle) self.family.set_mother_handle(handle)
def start_child(self, attrs): def start_child(self, attrs):
try: try:
handle = attrs['hlink'].replace('_', '') handle = attrs['hlink'].replace('_', '')
#all persons exist before child tag is encountered
self.db.check_person_from_handle(handle, self.trans) self.db.check_person_from_handle(handle, self.trans)
except KeyError: except KeyError:
person = self.find_person_by_gramps_id(self.map_gid(attrs["ref"])) person, new = self.find_person_by_gramps_id(self.map_gid(attrs["ref"]))
handle = person.handle handle = person.handle
# Here we are handling the old XML, in which # Here we are handling the old XML, in which
@ -1003,7 +1145,7 @@ class GrampsParser(UpdateCallback):
def start_childref(self, attrs): def start_childref(self, attrs):
# Here we are handling the new XML, in which frel and mrel # Here we are handling the new XML, in which frel and mrel
# belong to the "child" tag under family. # belong to the "childref" tag under family.
self.childref = gen.lib.ChildRef() self.childref = gen.lib.ChildRef()
self.childref.ref = attrs['hlink'].replace('_', '') self.childref.ref = attrs['hlink'].replace('_', '')
self.childref.private = bool(attrs.get('priv')) self.childref.private = bool(attrs.get('priv'))
@ -1047,13 +1189,20 @@ class GrampsParser(UpdateCallback):
self.update(self.p.CurrentLineNumber) self.update(self.p.CurrentLineNumber)
gramps_id = self.map_fid(attrs["id"]) gramps_id = self.map_fid(attrs["id"])
try: try:
self.family = self.db.find_family_from_handle( self.family, new = self.db.find_family_from_handle(
attrs['handle'].replace('_', ''), self.trans) attrs['handle'].replace('_', ''), self.trans)
self.family.set_gramps_id(gramps_id) self.family.set_gramps_id(gramps_id)
except KeyError: except KeyError:
self.family = self.find_family_by_gramps_id(gramps_id) self.family, new = self.find_family_by_gramps_id(gramps_id)
self.family.private = bool(attrs.get("priv")) self.family.private = bool(attrs.get("priv"))
if new:
#keep change time from xml file
self.family.change = int(attrs.get('change',self.change))
self.info.add('new-object', FAMILY_KEY, self.family)
else:
self.family.change = self.change
self.info.add('merge-overwrite', FAMILY_KEY, self.family)
# GRAMPS LEGACY: the type now belongs to <rel> tag # GRAMPS LEGACY: the type now belongs to <rel> tag
# Here we need to support old format of <family type="Married"> # Here we need to support old format of <family type="Married">
@ -1076,12 +1225,13 @@ class GrampsParser(UpdateCallback):
self.object.desc = attrs['description'] self.object.desc = attrs['description']
else: else:
self.object.desc = "" self.object.desc = ""
drive, src = os.path.splitdrive(attrs["src"]) #keep value of path, no longer make absolute paths on import
src = attrs["src"]
if src: if src:
if not drive and not os.path.isabs(src):
fullpath = os.path.abspath(self.filename)
src = os.path.join(os.path.dirname(fullpath), src)
self.object.path = src self.object.path = src
if self.all_abs and not os.path.isabs(src):
self.all_abs = False
self.info.add('relative-path', None, None)
def start_childof(self, attrs): def start_childof(self, attrs):
try: try:
@ -1089,7 +1239,7 @@ class GrampsParser(UpdateCallback):
self.db.check_family_from_handle(handle, self.trans, self.db.check_family_from_handle(handle, self.trans,
set_gid = False) set_gid = False)
except KeyError: except KeyError:
family = self.find_family_by_gramps_id(self.map_fid(attrs["ref"])) family, new = self.find_family_by_gramps_id(self.map_fid(attrs["ref"]))
handle = family.handle handle = family.handle
# Here we are handling the old XML, in which # Here we are handling the old XML, in which
@ -1116,7 +1266,7 @@ class GrampsParser(UpdateCallback):
self.db.check_family_from_handle(handle, self.trans, self.db.check_family_from_handle(handle, self.trans,
set_gid = False) set_gid = False)
except KeyError: except KeyError:
family = self.find_family_by_gramps_id(self.map_fid(attrs["ref"])) family, new = self.find_family_by_gramps_id(self.map_fid(attrs["ref"]))
handle = family.handle handle = family.handle
self.person.add_family_handle(handle) self.person.add_family_handle(handle)
@ -1174,12 +1324,19 @@ class GrampsParser(UpdateCallback):
self.update(self.p.CurrentLineNumber) self.update(self.p.CurrentLineNumber)
gramps_id = self.map_nid(attrs["id"]) gramps_id = self.map_nid(attrs["id"])
try: try:
self.note = self.db.find_note_from_handle( self.note, new = self.db.find_note_from_handle(
attrs['handle'].replace('_', ''), self.trans) attrs['handle'].replace('_', ''), self.trans)
self.note.gramps_id = gramps_id self.note.gramps_id = gramps_id
except KeyError: except KeyError:
self.note = self.find_note_by_gramps_id(gramps_id) self.note, new = self.find_note_by_gramps_id(gramps_id)
self.note.private = bool(attrs.get("priv")) self.note.private = bool(attrs.get("priv"))
if new:
#keep change time from xml file
self.note.change = int(attrs.get('change',self.change))
self.info.add('new-object', NOTE_KEY, self.note)
else:
self.note.change = self.change
self.info.add('merge-overwrite', NOTE_KEY, self.note)
self.note.format = int(attrs.get('format', gen.lib.Note.FLOWED)) self.note.format = int(attrs.get('format', gen.lib.Note.FLOWED))
self.note.type.set_from_xml_str(attrs['type']) self.note.type.set_from_xml_str(attrs['type'])
else: else:
@ -1246,6 +1403,9 @@ class GrampsParser(UpdateCallback):
self.note.private = self.reporef.private self.note.private = self.reporef.private
self.db.add_note(self.note, self.trans) self.db.add_note(self.note, self.trans)
#set correct change time
self.db.commit_note(self.note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, self.note)
def start_noteref(self, attrs): def start_noteref(self, attrs):
handle = attrs['hlink'].replace('_', '') handle = attrs['hlink'].replace('_', '')
@ -1296,7 +1456,7 @@ class GrampsParser(UpdateCallback):
self.db.check_source_from_handle(handle, self.trans, self.db.check_source_from_handle(handle, self.trans,
set_gid = False) set_gid = False)
except KeyError: except KeyError:
source = self.find_source_by_gramps_id(self.map_sid(attrs["ref"])) source, new = self.find_source_by_gramps_id(self.map_sid(attrs["ref"]))
handle = source.handle handle = source.handle
self.source_ref.ref = handle self.source_ref.ref = handle
@ -1334,12 +1494,19 @@ class GrampsParser(UpdateCallback):
self.update(self.p.CurrentLineNumber) self.update(self.p.CurrentLineNumber)
gramps_id = self.map_sid(attrs["id"]) #avoid double id's on import gramps_id = self.map_sid(attrs["id"]) #avoid double id's on import
try: try:
self.source = self.db.find_source_from_handle( self.source, new = self.db.find_source_from_handle(
attrs['handle'].replace('_', ''), self.trans) attrs['handle'].replace('_', ''), self.trans)
self.source.set_gramps_id(gramps_id) self.source.set_gramps_id(gramps_id)
except KeyError: except KeyError:
self.source = self.find_source_by_gramps_id(gramps_id) self.source, new = self.find_source_by_gramps_id(gramps_id)
self.source.private = bool(attrs.get("priv")) self.source.private = bool(attrs.get("priv"))
if new:
#keep change time from xml file
self.source.change = int(attrs.get('change',self.change))
self.info.add('new-object', SOURCE_KEY, self.source)
else:
self.source.change = self.change
self.info.add('merge-overwrite', SOURCE_KEY, self.source)
def start_reporef(self, attrs): def start_reporef(self, attrs):
self.reporef = gen.lib.RepoRef() self.reporef = gen.lib.RepoRef()
@ -1348,7 +1515,7 @@ class GrampsParser(UpdateCallback):
self.db.check_repository_from_handle(handle, self.trans, self.db.check_repository_from_handle(handle, self.trans,
set_gid = False) set_gid = False)
except KeyError: except KeyError:
repo = self.find_repo_by_gramps_id(self.map_rid(attrs['ref'])) repo, new = self.find_repository_by_gramps_id(self.map_rid(attrs['ref']))
handle = repo.handle handle = repo.handle
self.reporef.ref = handle self.reporef.ref = handle
@ -1366,7 +1533,7 @@ class GrampsParser(UpdateCallback):
self.db.check_object_from_handle(handle, self.trans, self.db.check_object_from_handle(handle, self.trans,
set_gid = False) set_gid = False)
except KeyError: except KeyError:
obj = self.find_object_by_gramps_id(self.map_oid(attrs['ref'])) obj, new = self.find_object_by_gramps_id(self.map_oid(attrs['ref']))
handle = obj.handle handle = obj.handle
self.objref.ref = handle self.objref.ref = handle
@ -1392,35 +1559,47 @@ class GrampsParser(UpdateCallback):
def start_object(self, attrs): def start_object(self, attrs):
gramps_id = self.map_oid(attrs['id']) gramps_id = self.map_oid(attrs['id'])
try: try:
self.object = self.db.find_object_from_handle( self.object, new = self.db.find_object_from_handle(
attrs['handle'].replace('_', ''), self.trans) attrs['handle'].replace('_', ''), self.trans)
self.object.set_gramps_id(gramps_id) self.object.set_gramps_id(gramps_id)
except KeyError: except KeyError:
self.object = self.find_object_by_gramps_id(gramps_id) self.object, new = self.find_object_by_gramps_id(gramps_id)
self.object.private = bool(attrs.get("priv"))
if new:
#keep change time from xml file
self.object.change = int(attrs.get('change',self.change))
self.info.add('new-object', MEDIA_KEY, self.object)
else:
self.object.change = self.change
self.info.add('merge-overwrite', MEDIA_KEY, self.object)
# GRAMPS LEGACY: src, mime, and description attributes # GRAMPS LEGACY: src, mime, and description attributes
# now belong to the <file> tag. Here we are supporting # now belong to the <file> tag. Here we are supporting
# the old format of <object src="blah"...> # the old format of <object src="blah"...>
self.object.mime = attrs.get('mime', '') self.object.mime = attrs.get('mime', '')
self.object.desc = attrs.get('description', '') self.object.desc = attrs.get('description', '')
self.object.private = bool(attrs.get("priv"))
src = attrs.get("src", '') src = attrs.get("src", '')
if src: if src:
if not os.path.isabs(src):
fullpath = os.path.abspath(self.filename)
src = os.path.join(os.path.dirname(fullpath), src)
self.object.path = src self.object.path = src
def start_repo(self, attrs): def start_repo(self, attrs):
gramps_id = self.map_rid(attrs['id']) gramps_id = self.map_rid(attrs['id'])
try: try:
self.repo = self.db.find_repository_from_handle( self.repo, new = self.db.find_repository_from_handle(
attrs['handle'].replace('_', ''), self.trans) attrs['handle'].replace('_', ''), self.trans)
self.repo.set_gramps_id(gramps_id) self.repo.set_gramps_id(gramps_id)
except KeyError: except KeyError:
self.repo = self.find_repository_by_gramps_id(gramps_id) self.repo, new = self.find_repository_by_gramps_id(gramps_id)
self.repo.private = bool(attrs.get("priv")) self.repo.private = bool(attrs.get("priv"))
if new:
#keep change time from xml file
self.repo.change = int(attrs.get('change',self.change))
self.info.add('new-object', REPOSITORY_KEY, self.repo)
else:
self.repo.change = self.change
self.info.add('merge-overwrite', REPOSITORY_KEY, self.repo)
def stop_people(self, *tag): def stop_people(self, *tag):
pass pass
@ -1429,14 +1608,16 @@ class GrampsParser(UpdateCallback):
self.update(self.p.CurrentLineNumber) self.update(self.p.CurrentLineNumber)
def stop_object(self, *tag): def stop_object(self, *tag):
self.db.commit_media_object(self.object, self.trans, self.change) self.db.commit_media_object(self.object, self.trans,
self.object.get_change_time())
self.object = None self.object = None
def stop_objref(self, *tag): def stop_objref(self, *tag):
self.objref = None self.objref = None
def stop_repo(self, *tag): def stop_repo(self, *tag):
self.db.commit_repository(self.repo, self.trans, self.change) self.db.commit_repository(self.repo, self.trans,
self.repo.get_change_time())
self.repo = None self.repo = None
def stop_reporef(self, *tag): def stop_reporef(self, *tag):
@ -1455,17 +1636,17 @@ class GrampsParser(UpdateCallback):
self.photo.set_privacy(int(attrs[key])) self.photo.set_privacy(int(attrs[key]))
elif key == "src": elif key == "src":
src = attrs["src"] src = attrs["src"]
if not os.path.isabs(src): self.photo.set_path(src)
self.photo.set_path(os.path.join(self.base, src))
else:
self.photo.set_path(src)
else: else:
attr = gen.lib.Attribute() attr = gen.lib.Attribute()
attr.set_type(key) attr.set_type(key)
attr.set_value(attrs[key]) attr.set_value(attrs[key])
self.photo.add_attribute(attr) self.photo.add_attribute(attr)
self.photo.set_mime_type(Mime.get_type(self.photo.get_path())) self.photo.set_mime_type(Mime.get_type(self.photo.get_path()))
self.db.add_object(self.photo) self.db.add_object(self.photo, self.trans)
#set correct change time
self.db.commit_media_object(self.photo, self.trans, self.change)
self.info.add('new-object', MEDIA_KEY, self.photo)
if self.family: if self.family:
self.family.add_media_reference(self.pref) self.family.add_media_reference(self.pref)
elif self.source: elif self.source:
@ -1677,6 +1858,9 @@ class GrampsParser(UpdateCallback):
note.type.set(gen.lib.NoteType.EVENT) note.type.set(gen.lib.NoteType.EVENT)
note.private = self.event.private note.private = self.event.private
self.db.add_note(note, self.trans) self.db.add_note(note, self.trans)
#set correct change time
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.event.add_note(note.handle) self.event.add_note(note.handle)
self.in_witness = False self.in_witness = False
@ -1710,11 +1894,13 @@ class GrampsParser(UpdateCallback):
# if self.placeobj.title in self.place_names: # if self.placeobj.title in self.place_names:
# self.placeobj.title += " [%s]" % self.placeobj.gramps_id # self.placeobj.title += " [%s]" % self.placeobj.gramps_id
self.db.commit_place(self.placeobj, self.trans, self.change) self.db.commit_place(self.placeobj, self.trans,
self.placeobj.get_change_time())
self.placeobj = None self.placeobj = None
def stop_family(self, *tag): def stop_family(self, *tag):
self.db.commit_family(self.family, self.trans, self.change) self.db.commit_family(self.family, self.trans,
self.family.get_change_time())
self.family = None self.family = None
def stop_type(self, tag): def stop_type(self, tag):
@ -1771,7 +1957,8 @@ class GrampsParser(UpdateCallback):
text = u'' text = u''
self.event.set_description(text) self.event.set_description(text)
self.db.commit_event(self.event, self.trans, self.change) self.db.commit_event(self.event, self.trans,
self.event.get_change_time())
self.event = None self.event = None
def stop_name(self, tag): def stop_name(self, tag):
@ -1783,6 +1970,9 @@ class GrampsParser(UpdateCallback):
note.type.set(gen.lib.NoteType.EVENT) note.type.set(gen.lib.NoteType.EVENT)
note.private = self.event.private note.private = self.event.private
self.db.add_note(note, self.trans) self.db.add_note(note, self.trans)
#set correct change time
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.event.add_note(note.handle) self.event.add_note(note.handle)
elif self.alt_name: elif self.alt_name:
# former aka tag -- alternate name # former aka tag -- alternate name
@ -1801,7 +1991,7 @@ class GrampsParser(UpdateCallback):
def stop_ref(self, tag): def stop_ref(self, tag):
# Parse witnesses created by older gramps # Parse witnesses created by older gramps
person = self.find_person_by_gramps_id(self.map_gid(tag)) person, new = self.find_person_by_gramps_id(self.map_gid(tag))
# Add an EventRef from that person # Add an EventRef from that person
# to this event using ROLE_WITNESS role # to this event using ROLE_WITNESS role
event_ref = gen.lib.EventRef() event_ref = gen.lib.EventRef()
@ -1855,7 +2045,8 @@ class GrampsParser(UpdateCallback):
self.family = None self.family = None
def stop_person(self, *tag): def stop_person(self, *tag):
self.db.commit_person(self.person, self.trans, self.change) self.db.commit_person(self.person, self.trans,
self.person.get_change_time())
self.person = None self.person = None
def stop_description(self, tag): def stop_description(self, tag):
@ -1884,7 +2075,8 @@ class GrampsParser(UpdateCallback):
self.source_ref = None self.source_ref = None
def stop_source(self, *tag): def stop_source(self, *tag):
self.db.commit_source(self.source, self.trans, self.change) self.db.commit_source(self.source, self.trans,
self.source.get_change_time())
self.source = None self.source = None
def stop_sauthor(self, tag): def stop_sauthor(self, tag):
@ -1936,7 +2128,10 @@ class GrampsParser(UpdateCallback):
note.private = self.source_ref.private note.private = self.source_ref.private
note.set(text) note.set(text)
note.type.set(gen.lib.NoteType.SOURCE_TEXT) note.type.set(gen.lib.NoteType.SOURCE_TEXT)
self.db.add_note(note, self.trans) self.db.add_note(note, self.trans)
#set correct change time
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.source_ref.add_note(note.handle) self.source_ref.add_note(note.handle)
def stop_scomments(self, tag): def stop_scomments(self, tag):
@ -1951,6 +2146,9 @@ class GrampsParser(UpdateCallback):
note.set(text) note.set(text)
note.type.set(gen.lib.NoteType.SOURCEREF) note.type.set(gen.lib.NoteType.SOURCEREF)
self.db.add_note(note, self.trans) self.db.add_note(note, self.trans)
#set correct change time
self.db.commit_note(note, self.trans, self.change)
self.info.add('new-object', NOTE_KEY, note)
self.source_ref.add_note(note.handle) self.source_ref.add_note(note.handle)
def stop_last(self, tag): def stop_last(self, tag):
@ -2020,7 +2218,7 @@ class GrampsParser(UpdateCallback):
elif self.reporef: elif self.reporef:
self.reporef.add_note(self.note.handle) self.reporef.add_note(self.note.handle)
self.db.commit_note(self.note, self.trans, self.change) self.db.commit_note(self.note, self.trans, self.note.get_change_time())
self.note = None self.note = None
def stop_research(self, tag): def stop_research(self, tag):

View File

@ -67,9 +67,9 @@ class SaveDialog:
label2 = self.xml.get_widget('label2') label2 = self.xml.get_widget('label2')
label2.set_text(msg2) label2.set_text(msg2)
label2.set_use_markup(True) label2.set_use_markup(True)
self.top.show()
if parent: if parent:
self.top.set_transient_for(parent) self.top.set_transient_for(parent)
self.top.show()
response = self.top.run() response = self.top.run()
if response == gtk.RESPONSE_NO: if response == gtk.RESPONSE_NO:
self.task1() self.task1()
@ -96,9 +96,9 @@ class QuestionDialog:
self.xml.get_widget('okbutton').set_label(label) self.xml.get_widget('okbutton').set_label(label)
self.top.show()
if parent: if parent:
self.top.set_transient_for(parent) self.top.set_transient_for(parent)
self.top.show()
response = self.top.run() response = self.top.run()
self.top.destroy() self.top.destroy()
if response == gtk.RESPONSE_ACCEPT: if response == gtk.RESPONSE_ACCEPT:
@ -123,9 +123,10 @@ class QuestionDialog2:
self.xml.get_widget('okbutton').set_use_underline(True) self.xml.get_widget('okbutton').set_use_underline(True)
self.xml.get_widget('no').set_label(label_msg2) self.xml.get_widget('no').set_label(label_msg2)
self.xml.get_widget('no').set_use_underline(True) self.xml.get_widget('no').set_use_underline(True)
self.top.show()
if parent: if parent:
self.top.set_transient_for(parent) self.top.set_transient_for(parent)
self.top.show()
def run(self): def run(self):
response = self.top.run() response = self.top.run()
@ -149,9 +150,9 @@ class OptionDialog:
self.xml.get_widget('option1').set_label(btnmsg1) self.xml.get_widget('option1').set_label(btnmsg1)
self.xml.get_widget('option2').set_label(btnmsg2) self.xml.get_widget('option2').set_label(btnmsg2)
self.top.show()
if parent: if parent:
self.top.set_transient_for(parent) self.top.set_transient_for(parent)
self.top.show()
self.response = self.top.run() self.response = self.top.run()
if self.response == gtk.RESPONSE_NO: if self.response == gtk.RESPONSE_NO:
if task1: if task1:
@ -188,7 +189,7 @@ class RunDatabaseRepair(ErrorDialog):
'usually be resolved by running the "Check and Repair Database" ' 'usually be resolved by running the "Check and Repair Database" '
'tool.\n\nIf this problem continues to exist after running this ' 'tool.\n\nIf this problem continues to exist after running this '
'tool, please file a bug report at ' 'tool, please file a bug report at '
'http://bugs.gramps-project.org\n\n') + str(msg)) 'http://bugs.gramps-project.org\n\n') + str(msg), parent)
class DBErrorDialog(ErrorDialog): class DBErrorDialog(ErrorDialog):
def __init__(self, msg, parent=None): def __init__(self, msg, parent=None):
@ -198,7 +199,7 @@ class DBErrorDialog(ErrorDialog):
_("GRAMPS has detected a problem in the underlying " _("GRAMPS has detected a problem in the underlying "
"Berkeley database. This can be repaired by from " "Berkeley database. This can be repaired by from "
"the Family Tree Manager. Select the database and " "the Family Tree Manager. Select the database and "
'click on the Repair button') + '\n\n' + str(msg)) 'click on the Repair button') + '\n\n' + str(msg), parent)
class WarningDialog(gtk.MessageDialog): class WarningDialog(gtk.MessageDialog):
def __init__(self,msg1,msg2="",parent=None): def __init__(self,msg1,msg2="",parent=None):
@ -230,6 +231,35 @@ class OkDialog(gtk.MessageDialog):
self.run() self.run()
self.destroy() self.destroy()
class InfoDialog:
"""
Dialog to show selectable info in a scrolled window
"""
def __init__(self, msg1, infotext, parent=None):
self.xml = glade.XML(const.GLADE_FILE, "infodialog", "gramps")
self.top = self.xml.get_widget('infodialog')
self.top.set_icon(ICON)
self.top.set_title("%s - GRAMPS" % msg1)
label = self.xml.get_widget('toplabel')
label.set_text('<span weight="bold" size="larger">%s</span>' % msg1)
label.set_use_markup(True)
infoview = self.xml.get_widget('infoview')
infobuffer = gtk.TextBuffer()
infobuffer.set_text(infotext)
infoview.set_buffer(infobuffer)
if parent:
self.top.set_transient_for(parent)
self.top.show()
self.response = self.top.run()
#no matter how it finishes, destroy dialog
self.top.destroy()
def get_response(self):
return self.response
class MissingMediaDialog: class MissingMediaDialog:
def __init__(self,msg1,msg2,task1,task2,task3,parent=None): def __init__(self,msg1,msg2,task1,task2,task3,parent=None):
self.xml = glade.XML(const.GLADE_FILE,"missmediadialog","gramps") self.xml = glade.XML(const.GLADE_FILE,"missmediadialog","gramps")
@ -251,9 +281,9 @@ class MissingMediaDialog:
check_button = self.xml.get_widget('use_always') check_button = self.xml.get_widget('use_always')
self.top.show()
if parent: if parent:
self.top.set_transient_for(parent) self.top.set_transient_for(parent)
self.top.show()
self.top.connect('delete_event',self.warn) self.top.connect('delete_event',self.warn)
response = gtk.RESPONSE_DELETE_EVENT response = gtk.RESPONSE_DELETE_EVENT

View File

@ -64,7 +64,8 @@ import const
import Config import Config
import GrampsCfg import GrampsCfg
import Errors import Errors
from QuestionDialog import ErrorDialog, WarningDialog, QuestionDialog2 from QuestionDialog import (ErrorDialog, WarningDialog, QuestionDialog2,
InfoDialog)
import PageView import PageView
import Navigation import Navigation
import RecentFiles import RecentFiles
@ -91,11 +92,6 @@ gtk.about_dialog_set_url_hook(show_url, None)
# Constants # Constants
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
_KNOWN_FORMATS = {
const.APP_GRAMPS : _('GRAMPS (grdb)'),
const.APP_GRAMPS_XML : _('GRAMPS XML'),
const.APP_GEDCOM : _('GEDCOM'),
}
UIDEFAULT = '''<ui> UIDEFAULT = '''<ui>
<menubar name="MenuBar"> <menubar name="MenuBar">
@ -1039,6 +1035,9 @@ class ViewManager:
""" """
if self.state.db.is_open(): if self.state.db.is_open():
self.db_loader.import_file() self.db_loader.import_file()
infotxt = self.db_loader.import_info_text()
if infotxt:
InfoDialog(_('Import Statistics'), infotxt, self.window)
self.__post_load() self.__post_load()
def open_activate(self, path): def open_activate(self, path):

View File

@ -816,12 +816,16 @@ class GrampsDbBase(Callback):
add_func): add_func):
obj = class_type() obj = class_type()
handle = str(handle) handle = str(handle)
new = True
if dmap.has_key(handle): if dmap.has_key(handle):
obj.unserialize(dmap.get(handle)) obj.unserialize(dmap.get(handle))
#references create object with id None before object is really made
if obj.gramps_id is not None:
new = False
else: else:
obj.set_handle(handle) obj.set_handle(handle)
add_func(obj, transaction) add_func(obj, transaction)
return obj return obj, new
def __check_from_handle(self, handle, transaction, class_type, dmap, def __check_from_handle(self, handle, transaction, class_type, dmap,
add_func, set_gid=True): add_func, set_gid=True):

View File

@ -1585,13 +1585,17 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback):
def find_from_handle(self, handle, transaction, class_type, dmap, add_func): def find_from_handle(self, handle, transaction, class_type, dmap, add_func):
obj = class_type() obj = class_type()
handle = str(handle) handle = str(handle)
new = True
if dmap.has_key(handle): if dmap.has_key(handle):
data = dmap.get(handle, txn=self.txn) data = dmap.get(handle, txn=self.txn)
obj.unserialize(data) obj.unserialize(data)
#references create object with id None before object is really made
if obj.gramps_id is not None:
new = False
else: else:
obj.set_handle(handle) obj.set_handle(handle)
add_func(obj, transaction) add_func(obj, transaction)
return obj return obj, new
def transaction_begin(self, msg="", batch=False, no_magic=False): def transaction_begin(self, msg="", batch=False, no_magic=False):
try: try:

View File

@ -16454,4 +16454,159 @@ Very High</property>
</child> </child>
</widget> </widget>
<widget class="GtkDialog" id="infodialog">
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="focus_on_map">True</property>
<property name="urgency_hint">False</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="vbox142">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="hbuttonbox49">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="button182">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-ok</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table81">
<property name="border_width">12</property>
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="homogeneous">False</property>
<property name="row_spacing">0</property>
<property name="column_spacing">0</property>
<child>
<widget class="GtkImage" id="image2723">
<property name="visible">True</property>
<property name="stock">gtk-dialog-info</property>
<property name="icon_size">6</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="toplabel">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">6</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">expand|shrink|fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow89">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="GtkTextView" id="infoview">
<property name="width_request">308</property>
<property name="height_request">210</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="overwrite">False</property>
<property name="accepts_tab">True</property>
<property name="justification">GTK_JUSTIFY_LEFT</property>
<property name="wrap_mode">GTK_WRAP_NONE</property>
<property name="cursor_visible">True</property>
<property name="pixels_above_lines">0</property>
<property name="pixels_below_lines">0</property>
<property name="pixels_inside_wrap">0</property>
<property name="left_margin">0</property>
<property name="right_margin">0</property>
<property name="indent">0</property>
<property name="text" translatable="yes"></property>
</widget>
</child>
</widget>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface> </glade-interface>

View File

@ -787,6 +787,7 @@ _mime_type_rfc_4180 = "text/csv" # CSV Document See rfc4180 for mime type
_filter = gtk.FileFilter() _filter = gtk.FileFilter()
_filter.set_name(_('CSV spreadsheet files')) _filter.set_name(_('CSV spreadsheet files'))
_filter.add_mime_type(_mime_type) _filter.add_mime_type(_mime_type)
_filter.add_mime_type(_mime_type_rfc_4180)
_format_name = _('CSV Spreadheet') _format_name = _('CSV Spreadheet')
register_import(importData, _filter, _mime_type, 0, _format_name) register_import(importData, _filter, [_mime_type, _mime_type_rfc_4180],
register_import(importData, _filter, _mime_type_rfc_4180, 0, _format_name) 0, _format_name)

View File

@ -934,4 +934,4 @@ _filter.set_name(_('GeneWeb files'))
_filter.add_mime_type(_mime_type) _filter.add_mime_type(_mime_type)
_format_name = _('GeneWeb') _format_name = _('GeneWeb')
register_import(importData,_filter,_mime_type,0,_format_name) register_import(importData, _filter, [_mime_type], 0, _format_name)

View File

@ -220,9 +220,9 @@ class VCardParser:
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
_mime_type = const.APP_VCARD _mime_type = const.APP_VCARD
_filter = gtk.FileFilter()
_filter.set_name(_('vCard files'))
for mime in _mime_type: for mime in _mime_type:
_filter = gtk.FileFilter()
_filter.set_name(_('vCard files'))
_filter.add_mime_type(mime) _filter.add_mime_type(mime)
register_import(importData,_filter,mime,1) register_import(importData, _filter, _mime_type, 1)

View File

@ -326,4 +326,4 @@ _filter.set_name(_('GRAMPS 2.x database'))
_filter.add_mime_type(_mime_type) _filter.add_mime_type(_mime_type)
_format_name = _('GRAMPS 2.x database') _format_name = _('GRAMPS 2.x database')
register_import(importData, _filter, _mime_type, 0, _format_name) register_import(importData, _filter, [_mime_type], 0, _format_name)

View File

@ -124,4 +124,4 @@ _filter.set_name(_('GRAMPS packages'))
_filter.add_mime_type(_mime_type) _filter.add_mime_type(_mime_type)
_format_name = _('GRAMPS package') _format_name = _('GRAMPS package')
register_import(impData, _filter, _mime_type, 0, _format_name) register_import(impData, _filter, [_mime_type], 0, _format_name)