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:
parent
fefa36ad4e
commit
b1561e5f78
20
ChangeLog
20
ChangeLog
@ -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>
|
||||
* src/plugins/Verify.py
|
||||
links to wiki manual
|
||||
|
@ -69,10 +69,12 @@ import Errors
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
#connection between main mime type, name, and list of alternative mime types
|
||||
_KNOWN_FORMATS = {
|
||||
const.APP_GRAMPS : _('GRAMPS (grdb)'),
|
||||
const.APP_GRAMPS_XML : _('GRAMPS XML'),
|
||||
const.APP_GEDCOM : _('GEDCOM'),
|
||||
const.APP_GRAMPS : [_('GRAMPS (grdb)'), []],
|
||||
const.APP_GRAMPS_XML : [_('GRAMPS XML'), []],
|
||||
const.APP_GEDCOM : [_('GEDCOM'), []],
|
||||
}
|
||||
|
||||
OPEN_FORMATS = [const.APP_GRAMPS_XML, const.APP_GEDCOM]
|
||||
@ -86,6 +88,7 @@ class DbLoader:
|
||||
def __init__(self, dbstate, uistate):
|
||||
self.dbstate = dbstate
|
||||
self.uistate = uistate
|
||||
self.import_info = None
|
||||
|
||||
def import_file(self):
|
||||
# First thing first: import is a batch transaction
|
||||
@ -112,24 +115,24 @@ class DbLoader:
|
||||
choose_db_dialog.set_local_only(False)
|
||||
|
||||
# Always add automatic (match all files) filter
|
||||
add_all_files_filter(choose_db_dialog)
|
||||
add_grdb_filter(choose_db_dialog)
|
||||
add_xml_filter(choose_db_dialog)
|
||||
add_gedcom_filter(choose_db_dialog)
|
||||
add_all_files_filter(choose_db_dialog) # *
|
||||
#add_grdb_filter(choose_db_dialog) # .grdb no longer native!
|
||||
add_xml_filter(choose_db_dialog) # .gramps
|
||||
add_gedcom_filter(choose_db_dialog) # .ged
|
||||
|
||||
format_list = OPEN_FORMATS[:]
|
||||
|
||||
# Add more data type selections if opening existing db
|
||||
for data in import_list:
|
||||
mime_filter = data[1]
|
||||
mime_type = data[2]
|
||||
mime_types = data[2]
|
||||
native_format = data[3]
|
||||
format_name = data[4]
|
||||
|
||||
if not native_format:
|
||||
choose_db_dialog.add_filter(mime_filter)
|
||||
format_list.append(mime_type)
|
||||
_KNOWN_FORMATS[mime_type] = format_name
|
||||
format_list.append(mime_types[0])
|
||||
_KNOWN_FORMATS[mime_types[0]] = [format_name, mime_types[1:]]
|
||||
|
||||
(box, type_selector) = format_maker(format_list)
|
||||
choose_db_dialog.set_extra_widget(box)
|
||||
@ -166,17 +169,17 @@ class DbLoader:
|
||||
continue
|
||||
|
||||
# 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)
|
||||
self.do_import(choose_db_dialog, importer, filename)
|
||||
return True
|
||||
|
||||
# Then we try all the known plugins
|
||||
(the_path, the_file) = os.path.split(filename)
|
||||
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:
|
||||
if filetype == mime_type or the_file == mime_type:
|
||||
if filetype in mime_types:
|
||||
self.do_import(choose_db_dialog, importData, filename)
|
||||
return True
|
||||
|
||||
@ -281,12 +284,16 @@ class DbLoader:
|
||||
|
||||
|
||||
def do_import(self, dialog, importer, filename):
|
||||
self.import_info = None
|
||||
dialog.destroy()
|
||||
self.uistate.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
|
||||
self.uistate.progress.show()
|
||||
|
||||
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
|
||||
Config.set(Config.RECENT_IMPORT_DIR, dirname)
|
||||
except UnicodeError, msg:
|
||||
@ -297,6 +304,16 @@ class DbLoader:
|
||||
"encoding, and import again") + "\n\n %s" % msg)
|
||||
except Exception:
|
||||
_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.
|
||||
"""
|
||||
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)
|
||||
chooser.add_filter(mime_filter)
|
||||
|
||||
@ -409,7 +426,7 @@ def format_maker(formats):
|
||||
format_list = [ ('auto', _('Automatically detected')) ]
|
||||
for format in formats:
|
||||
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.set(format_list)
|
||||
|
@ -684,9 +684,9 @@ class DbManager(CLIDbManager):
|
||||
|
||||
if len(path) == 1:
|
||||
QuestionDialog(
|
||||
_("Remove the '%s' database?") % self.data_to_delete[0],
|
||||
_("Removing this database will permanently destroy the data."),
|
||||
_("Remove database"),
|
||||
_("Remove the '%s' family tree?") % self.data_to_delete[0],
|
||||
_("Removing this family tree will permanently destroy the data."),
|
||||
_("Remove family tree"),
|
||||
self.__really_delete_db)
|
||||
else:
|
||||
rev = self.data_to_delete[0]
|
||||
|
@ -1475,13 +1475,17 @@ class GrampsBSDDB(GrampsDbBase, UpdateCallback):
|
||||
def find_from_handle(self, hndl, transaction, class_type, dmap, add_func):
|
||||
obj = class_type()
|
||||
hndl = str(hndl)
|
||||
new = True
|
||||
if dmap.has_key(hndl):
|
||||
data = dmap.get(hndl, txn=self.txn)
|
||||
obj.unserialize(data)
|
||||
#references create object with id None before object is really made
|
||||
if obj.gramps_id is not None:
|
||||
new = False
|
||||
else:
|
||||
obj.set_handle(hndl)
|
||||
add_func(obj, transaction)
|
||||
return obj
|
||||
return obj, new
|
||||
|
||||
def transaction_begin(self, msg="", batch=False, no_magic=False):
|
||||
"""
|
||||
|
@ -66,7 +66,7 @@ def gramps_db_reader_factory(db_type):
|
||||
#see if registered importer
|
||||
found = False
|
||||
for data in import_list:
|
||||
if db_type == data[2]:
|
||||
if db_type in data[2]:
|
||||
print "Found import plugin for %s" % data[4]
|
||||
found = True
|
||||
md = data[0]
|
||||
|
@ -103,8 +103,8 @@ class GrampsDbXmlWriter(UpdateCallback):
|
||||
db - database to write
|
||||
strip_photos - remove paths off of media object paths
|
||||
> 0: do not touch the paths
|
||||
> 1: remove everything expect the filename
|
||||
> 2: remove leading slash
|
||||
> 1: remove everything expect the filename (eg gpkg)
|
||||
> 2: remove leading slash (quick write)
|
||||
compress - attempt to compress the database
|
||||
"""
|
||||
UpdateCallback.__init__(self, callback)
|
||||
|
@ -89,7 +89,7 @@ def importData(database, filename, callback=None, cl=0, use_trans=False):
|
||||
database.fmap = {}
|
||||
|
||||
change = os.path.getmtime(filename)
|
||||
parser = GrampsParser(database, callback, basefile, change, filename)
|
||||
parser = GrampsParser(database, callback, change)
|
||||
|
||||
linecounter = LineParser(filename)
|
||||
line_cnt = linecounter.get_count()
|
||||
@ -109,7 +109,7 @@ def importData(database, filename, callback=None, cl=0, use_trans=False):
|
||||
|
||||
try:
|
||||
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:
|
||||
if cl:
|
||||
print "Error reading %s" % filename
|
||||
@ -135,6 +135,8 @@ def importData(database, filename, callback=None, cl=0, use_trans=False):
|
||||
xml_file.close()
|
||||
|
||||
database.readonly = read_only
|
||||
|
||||
return info
|
||||
|
||||
## TODO - WITH MEDIA PATH, IS THIS STILL NEEDED?
|
||||
## 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:
|
||||
def __init__(self, filename):
|
||||
|
||||
@ -231,9 +335,8 @@ class LineParser:
|
||||
#-------------------------------------------------------------------------
|
||||
class GrampsParser(UpdateCallback):
|
||||
|
||||
def __init__(self, database, callback, base, change, filename):
|
||||
def __init__(self, database, callback, change):
|
||||
UpdateCallback.__init__(self, callback)
|
||||
self.filename = filename
|
||||
self.stext_list = []
|
||||
self.scomments_list = []
|
||||
self.note_list = []
|
||||
@ -251,6 +354,8 @@ class GrampsParser(UpdateCallback):
|
||||
self.change = change
|
||||
self.dp = DateHandler.parser
|
||||
self.place_names = sets.Set()
|
||||
self.info = ImportInfo()
|
||||
self.all_abs = True
|
||||
cursor = database.get_place_cursor()
|
||||
data = cursor.next()
|
||||
while data:
|
||||
@ -271,7 +376,6 @@ class GrampsParser(UpdateCallback):
|
||||
self.in_scomments = 0
|
||||
self.in_witness = False
|
||||
self.db = database
|
||||
self.base = base
|
||||
self.photo = None
|
||||
self.person = None
|
||||
self.family = None
|
||||
@ -311,7 +415,6 @@ class GrampsParser(UpdateCallback):
|
||||
self.childref = None
|
||||
self.personref = None
|
||||
self.name = None
|
||||
self.tempDefault = None
|
||||
self.home = None
|
||||
self.owner = gen.lib.Researcher()
|
||||
self.func_list = [None]*50
|
||||
@ -434,120 +537,132 @@ class GrampsParser(UpdateCallback):
|
||||
|
||||
def find_person_by_gramps_id(self, gramps_id):
|
||||
intid = self.gid2id.get(gramps_id)
|
||||
new = True
|
||||
if intid:
|
||||
person = self.db.get_person_from_handle(intid)
|
||||
new = False
|
||||
else:
|
||||
intid = Utils.create_id()
|
||||
person = gen.lib.Person()
|
||||
person.set_handle(intid)
|
||||
person.set_gramps_id(gramps_id)
|
||||
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
|
||||
return person
|
||||
return person, new
|
||||
|
||||
def find_family_by_gramps_id(self, gramps_id):
|
||||
intid = self.gid2fid.get(gramps_id)
|
||||
new = True
|
||||
if intid:
|
||||
family = self.db.get_family_from_handle(intid)
|
||||
new = False
|
||||
else:
|
||||
intid = Utils.create_id()
|
||||
family = gen.lib.Family()
|
||||
family.set_handle(intid)
|
||||
family.set_gramps_id(gramps_id)
|
||||
self.db.add_family(family, self.trans)
|
||||
self.db.commit_family(family, self.trans, self.change)
|
||||
self.gid2fid[gramps_id] = intid
|
||||
return family
|
||||
return family, new
|
||||
|
||||
def find_event_by_gramps_id(self, gramps_id):
|
||||
intid = self.gid2eid.get(gramps_id)
|
||||
new = True
|
||||
if intid:
|
||||
event = self.db.get_event_from_handle(intid)
|
||||
new = False
|
||||
else:
|
||||
intid = Utils.create_id()
|
||||
event = gen.lib.Event()
|
||||
event.set_handle(intid)
|
||||
event.set_gramps_id(gramps_id)
|
||||
self.db.add_event(event, self.trans)
|
||||
self.db.commit_event(event, self.trans, self.change)
|
||||
self.gid2eid[gramps_id] = intid
|
||||
return event
|
||||
return event, new
|
||||
|
||||
def find_place_by_gramps_id(self, gramps_id):
|
||||
intid = self.gid2pid.get(gramps_id)
|
||||
new = True
|
||||
if intid:
|
||||
place = self.db.get_place_from_handle(intid)
|
||||
new = False
|
||||
else:
|
||||
intid = Utils.create_id()
|
||||
place = gen.lib.Place()
|
||||
place.set_handle(intid)
|
||||
place.set_gramps_id(gramps_id)
|
||||
self.db.add_place(place, self.trans)
|
||||
self.db.commit_place(place, self.trans, self.change)
|
||||
self.gid2pid[gramps_id] = intid
|
||||
return place
|
||||
return place, new
|
||||
|
||||
def find_source_by_gramps_id(self, gramps_id):
|
||||
intid = self.gid2sid.get(gramps_id)
|
||||
new = True
|
||||
if intid:
|
||||
source = self.db.get_source_from_handle(intid)
|
||||
new = False
|
||||
else:
|
||||
intid = Utils.create_id()
|
||||
source = gen.lib.Source()
|
||||
source.set_handle(intid)
|
||||
source.set_gramps_id(gramps_id)
|
||||
self.db.add_source(source, self.trans)
|
||||
self.db.commit_source(source, self.trans, self.change)
|
||||
self.gid2sid[gramps_id] = intid
|
||||
return source
|
||||
return source, new
|
||||
|
||||
def find_object_by_gramps_id(self, gramps_id):
|
||||
intid = self.gid2oid.get(gramps_id)
|
||||
new = True
|
||||
if intid:
|
||||
obj = self.db.get_object_from_handle(intid)
|
||||
new = False
|
||||
else:
|
||||
intid = Utils.create_id()
|
||||
obj = gen.lib.MediaObject()
|
||||
obj.set_handle(intid)
|
||||
obj.set_gramps_id(gramps_id)
|
||||
self.db.add_object(obj, self.trans)
|
||||
self.db.commit_media_object(obj, self.trans, self.change)
|
||||
self.gid2oid[gramps_id] = intid
|
||||
return obj
|
||||
return obj, new
|
||||
|
||||
def find_repository_by_gramps_id(self, gramps_id):
|
||||
intid = self.gid2rid.get(gramps_id)
|
||||
new = True
|
||||
if intid:
|
||||
repo = self.db.get_repository_from_handle(intid)
|
||||
new = False
|
||||
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.db.commit_repository(repo, self.trans, self.change)
|
||||
self.gid2rid[gramps_id] = intid
|
||||
return repo
|
||||
return repo, new
|
||||
|
||||
def find_note_by_gramps_id(self, gramps_id):
|
||||
intid = self.gid2nid.get(gramps_id)
|
||||
new = True
|
||||
if intid:
|
||||
note = self.db.get_note_from_handle(intid)
|
||||
new = False
|
||||
else:
|
||||
intid = Utils.create_id()
|
||||
note = gen.lib.Note()
|
||||
note.set_handle(intid)
|
||||
note.set_gramps_id(gramps_id)
|
||||
self.db.add_note(note, self.trans)
|
||||
self.db.commit_note(note, self.trans, self.change)
|
||||
self.gid2nid[gramps_id] = intid
|
||||
return note
|
||||
|
||||
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
|
||||
return note, new
|
||||
|
||||
def map_gid(self, gramps_id):
|
||||
if not self.idswap.get(gramps_id):
|
||||
@ -637,13 +752,9 @@ class GrampsParser(UpdateCallback):
|
||||
|
||||
self.db.set_researcher(self.owner)
|
||||
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)
|
||||
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
|
||||
# windows path to unix ?
|
||||
if self.mediapath:
|
||||
@ -653,9 +764,10 @@ class GrampsParser(UpdateCallback):
|
||||
elif not oldpath == self.mediapath:
|
||||
ErrorDialog(_("Could not change media path"),
|
||||
_("The opened file has media path %s, which conflicts with"
|
||||
" the media path of the database. Copy the files with "
|
||||
"non absolute path to new position or change the media "
|
||||
"path of the database in the Preferences."
|
||||
" the media path of the family tree you import into. "
|
||||
"The original media path has been retained. Copy the "
|
||||
"files to a correct directory or change the media "
|
||||
"path in the Preferences."
|
||||
) % self.mediapath )
|
||||
|
||||
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.enable_signals()
|
||||
self.db.request_rebuild()
|
||||
return self.info
|
||||
|
||||
def start_lds_ord(self, attrs):
|
||||
self.ord = gen.lib.LdsOrd()
|
||||
@ -710,7 +823,7 @@ class GrampsParser(UpdateCallback):
|
||||
except KeyError:
|
||||
#legacy, before hlink there was 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
|
||||
|
||||
if self.ord:
|
||||
@ -723,13 +836,20 @@ class GrampsParser(UpdateCallback):
|
||||
def start_placeobj(self, attrs):
|
||||
gramps_id = self.map_pid(attrs['id'])
|
||||
try:
|
||||
self.placeobj = self.db.find_place_from_handle(
|
||||
self.placeobj, new = self.db.find_place_from_handle(
|
||||
attrs['handle'].replace('_', ''), self.trans)
|
||||
self.placeobj.set_gramps_id(gramps_id)
|
||||
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"))
|
||||
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
|
||||
self.placeobj.title = attrs.get('title', '')
|
||||
@ -766,15 +886,19 @@ class GrampsParser(UpdateCallback):
|
||||
note.type.set(gen.lib.NoteType.EVENT)
|
||||
note.private = self.event.private
|
||||
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)
|
||||
return
|
||||
|
||||
try:
|
||||
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:
|
||||
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:
|
||||
person = None
|
||||
|
||||
@ -800,17 +924,27 @@ class GrampsParser(UpdateCallback):
|
||||
self.event.type = gen.lib.EventType()
|
||||
self.event.type.set_from_xml_str(attrs['type'])
|
||||
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:
|
||||
# This is new event, with ID and handle already existing
|
||||
self.update(self.p.CurrentLineNumber)
|
||||
gramps_id = self.map_eid(attrs["id"])
|
||||
try:
|
||||
self.event = self.db.find_event_from_handle(
|
||||
self.event, new = self.db.find_event_from_handle(
|
||||
attrs['handle'].replace('_', ''), self.trans)
|
||||
self.event.gramps_id = gramps_id
|
||||
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"))
|
||||
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):
|
||||
self.eventref = gen.lib.EventRef()
|
||||
@ -877,7 +1011,7 @@ class GrampsParser(UpdateCallback):
|
||||
self.db.check_person_from_handle(handle, self.trans)
|
||||
except KeyError:
|
||||
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
|
||||
self.db.bookmarks.append(handle)
|
||||
return
|
||||
@ -888,35 +1022,35 @@ class GrampsParser(UpdateCallback):
|
||||
# Make sure those are filtered out.
|
||||
# Bookmarks are at end, so all handle must exist before we do bookmrks
|
||||
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() ):
|
||||
self.db.bookmarks.append(handle)
|
||||
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() ):
|
||||
self.db.family_bookmarks.append(handle)
|
||||
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() ):
|
||||
self.db.event_bookmarks.append(handle)
|
||||
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() ):
|
||||
self.db.source_bookmarks.append(handle)
|
||||
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() ):
|
||||
self.db.place_bookmarks.append(handle)
|
||||
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() ):
|
||||
self.db.media_bookmarks.append(handle)
|
||||
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()):
|
||||
self.db.repo_bookmarks.append(handle)
|
||||
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() ):
|
||||
self.db.note_bookmarks.append(handle)
|
||||
|
||||
@ -949,13 +1083,20 @@ class GrampsParser(UpdateCallback):
|
||||
self.update(self.p.CurrentLineNumber)
|
||||
new_id = self.map_gid(attrs['id'])
|
||||
try:
|
||||
self.person = self.db.find_person_from_handle(
|
||||
self.person, new = self.db.find_person_from_handle(
|
||||
attrs['handle'].replace('_', ''), self.trans)
|
||||
self.person.set_gramps_id(new_id)
|
||||
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"))
|
||||
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
|
||||
if attrs.get('complete'): # this is only true for complete=1
|
||||
self.person.marker.set(gen.lib.MarkerType.COMPLETE)
|
||||
@ -972,7 +1113,7 @@ class GrampsParser(UpdateCallback):
|
||||
#all persons exist before father tag is encountered
|
||||
self.db.check_person_from_handle(handle, self.trans)
|
||||
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
|
||||
self.family.set_father_handle(handle)
|
||||
|
||||
@ -982,16 +1123,17 @@ class GrampsParser(UpdateCallback):
|
||||
#all persons exist before mother tag is encountered
|
||||
self.db.check_person_from_handle(handle, self.trans)
|
||||
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
|
||||
self.family.set_mother_handle(handle)
|
||||
|
||||
def start_child(self, attrs):
|
||||
try:
|
||||
handle = attrs['hlink'].replace('_', '')
|
||||
#all persons exist before child tag is encountered
|
||||
self.db.check_person_from_handle(handle, self.trans)
|
||||
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
|
||||
|
||||
# Here we are handling the old XML, in which
|
||||
@ -1003,7 +1145,7 @@ class GrampsParser(UpdateCallback):
|
||||
|
||||
def start_childref(self, attrs):
|
||||
# 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.ref = attrs['hlink'].replace('_', '')
|
||||
self.childref.private = bool(attrs.get('priv'))
|
||||
@ -1047,13 +1189,20 @@ class GrampsParser(UpdateCallback):
|
||||
self.update(self.p.CurrentLineNumber)
|
||||
gramps_id = self.map_fid(attrs["id"])
|
||||
try:
|
||||
self.family = self.db.find_family_from_handle(
|
||||
self.family, new = self.db.find_family_from_handle(
|
||||
attrs['handle'].replace('_', ''), self.trans)
|
||||
self.family.set_gramps_id(gramps_id)
|
||||
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"))
|
||||
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
|
||||
# Here we need to support old format of <family type="Married">
|
||||
@ -1076,12 +1225,13 @@ class GrampsParser(UpdateCallback):
|
||||
self.object.desc = attrs['description']
|
||||
else:
|
||||
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 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
|
||||
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):
|
||||
try:
|
||||
@ -1089,7 +1239,7 @@ class GrampsParser(UpdateCallback):
|
||||
self.db.check_family_from_handle(handle, self.trans,
|
||||
set_gid = False)
|
||||
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
|
||||
|
||||
# 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,
|
||||
set_gid = False)
|
||||
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
|
||||
self.person.add_family_handle(handle)
|
||||
|
||||
@ -1174,12 +1324,19 @@ class GrampsParser(UpdateCallback):
|
||||
self.update(self.p.CurrentLineNumber)
|
||||
gramps_id = self.map_nid(attrs["id"])
|
||||
try:
|
||||
self.note = self.db.find_note_from_handle(
|
||||
self.note, new = self.db.find_note_from_handle(
|
||||
attrs['handle'].replace('_', ''), self.trans)
|
||||
self.note.gramps_id = gramps_id
|
||||
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"))
|
||||
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.type.set_from_xml_str(attrs['type'])
|
||||
else:
|
||||
@ -1246,6 +1403,9 @@ class GrampsParser(UpdateCallback):
|
||||
self.note.private = self.reporef.private
|
||||
|
||||
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):
|
||||
handle = attrs['hlink'].replace('_', '')
|
||||
@ -1296,7 +1456,7 @@ class GrampsParser(UpdateCallback):
|
||||
self.db.check_source_from_handle(handle, self.trans,
|
||||
set_gid = False)
|
||||
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
|
||||
|
||||
self.source_ref.ref = handle
|
||||
@ -1334,12 +1494,19 @@ class GrampsParser(UpdateCallback):
|
||||
self.update(self.p.CurrentLineNumber)
|
||||
gramps_id = self.map_sid(attrs["id"]) #avoid double id's on import
|
||||
try:
|
||||
self.source = self.db.find_source_from_handle(
|
||||
self.source, new = self.db.find_source_from_handle(
|
||||
attrs['handle'].replace('_', ''), self.trans)
|
||||
self.source.set_gramps_id(gramps_id)
|
||||
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"))
|
||||
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):
|
||||
self.reporef = gen.lib.RepoRef()
|
||||
@ -1348,7 +1515,7 @@ class GrampsParser(UpdateCallback):
|
||||
self.db.check_repository_from_handle(handle, self.trans,
|
||||
set_gid = False)
|
||||
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
|
||||
|
||||
self.reporef.ref = handle
|
||||
@ -1366,7 +1533,7 @@ class GrampsParser(UpdateCallback):
|
||||
self.db.check_object_from_handle(handle, self.trans,
|
||||
set_gid = False)
|
||||
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
|
||||
|
||||
self.objref.ref = handle
|
||||
@ -1392,35 +1559,47 @@ class GrampsParser(UpdateCallback):
|
||||
def start_object(self, attrs):
|
||||
gramps_id = self.map_oid(attrs['id'])
|
||||
try:
|
||||
self.object = self.db.find_object_from_handle(
|
||||
self.object, new = self.db.find_object_from_handle(
|
||||
attrs['handle'].replace('_', ''), self.trans)
|
||||
self.object.set_gramps_id(gramps_id)
|
||||
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
|
||||
# now belong to the <file> tag. Here we are supporting
|
||||
# the old format of <object src="blah"...>
|
||||
self.object.mime = attrs.get('mime', '')
|
||||
self.object.desc = attrs.get('description', '')
|
||||
self.object.private = bool(attrs.get("priv"))
|
||||
src = attrs.get("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
|
||||
|
||||
def start_repo(self, attrs):
|
||||
gramps_id = self.map_rid(attrs['id'])
|
||||
try:
|
||||
self.repo = self.db.find_repository_from_handle(
|
||||
self.repo, new = self.db.find_repository_from_handle(
|
||||
attrs['handle'].replace('_', ''), self.trans)
|
||||
self.repo.set_gramps_id(gramps_id)
|
||||
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"))
|
||||
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):
|
||||
pass
|
||||
@ -1429,14 +1608,16 @@ class GrampsParser(UpdateCallback):
|
||||
self.update(self.p.CurrentLineNumber)
|
||||
|
||||
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
|
||||
|
||||
def stop_objref(self, *tag):
|
||||
self.objref = None
|
||||
|
||||
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
|
||||
|
||||
def stop_reporef(self, *tag):
|
||||
@ -1455,17 +1636,17 @@ class GrampsParser(UpdateCallback):
|
||||
self.photo.set_privacy(int(attrs[key]))
|
||||
elif key == "src":
|
||||
src = attrs["src"]
|
||||
if not os.path.isabs(src):
|
||||
self.photo.set_path(os.path.join(self.base, src))
|
||||
else:
|
||||
self.photo.set_path(src)
|
||||
self.photo.set_path(src)
|
||||
else:
|
||||
attr = gen.lib.Attribute()
|
||||
attr.set_type(key)
|
||||
attr.set_value(attrs[key])
|
||||
self.photo.add_attribute(attr)
|
||||
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:
|
||||
self.family.add_media_reference(self.pref)
|
||||
elif self.source:
|
||||
@ -1677,6 +1858,9 @@ class GrampsParser(UpdateCallback):
|
||||
note.type.set(gen.lib.NoteType.EVENT)
|
||||
note.private = self.event.private
|
||||
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.in_witness = False
|
||||
|
||||
@ -1710,11 +1894,13 @@ class GrampsParser(UpdateCallback):
|
||||
# if self.placeobj.title in self.place_names:
|
||||
# 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
|
||||
|
||||
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
|
||||
|
||||
def stop_type(self, tag):
|
||||
@ -1771,7 +1957,8 @@ class GrampsParser(UpdateCallback):
|
||||
text = u''
|
||||
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
|
||||
|
||||
def stop_name(self, tag):
|
||||
@ -1783,6 +1970,9 @@ class GrampsParser(UpdateCallback):
|
||||
note.type.set(gen.lib.NoteType.EVENT)
|
||||
note.private = self.event.private
|
||||
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)
|
||||
elif self.alt_name:
|
||||
# former aka tag -- alternate name
|
||||
@ -1801,7 +1991,7 @@ class GrampsParser(UpdateCallback):
|
||||
|
||||
def stop_ref(self, tag):
|
||||
# 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
|
||||
# to this event using ROLE_WITNESS role
|
||||
event_ref = gen.lib.EventRef()
|
||||
@ -1855,7 +2045,8 @@ class GrampsParser(UpdateCallback):
|
||||
self.family = None
|
||||
|
||||
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
|
||||
|
||||
def stop_description(self, tag):
|
||||
@ -1884,7 +2075,8 @@ class GrampsParser(UpdateCallback):
|
||||
self.source_ref = None
|
||||
|
||||
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
|
||||
|
||||
def stop_sauthor(self, tag):
|
||||
@ -1936,7 +2128,10 @@ class GrampsParser(UpdateCallback):
|
||||
note.private = self.source_ref.private
|
||||
note.set(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)
|
||||
|
||||
def stop_scomments(self, tag):
|
||||
@ -1951,6 +2146,9 @@ class GrampsParser(UpdateCallback):
|
||||
note.set(text)
|
||||
note.type.set(gen.lib.NoteType.SOURCEREF)
|
||||
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)
|
||||
|
||||
def stop_last(self, tag):
|
||||
@ -2020,7 +2218,7 @@ class GrampsParser(UpdateCallback):
|
||||
elif self.reporef:
|
||||
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
|
||||
|
||||
def stop_research(self, tag):
|
||||
|
@ -67,9 +67,9 @@ class SaveDialog:
|
||||
label2 = self.xml.get_widget('label2')
|
||||
label2.set_text(msg2)
|
||||
label2.set_use_markup(True)
|
||||
self.top.show()
|
||||
if parent:
|
||||
self.top.set_transient_for(parent)
|
||||
self.top.show()
|
||||
response = self.top.run()
|
||||
if response == gtk.RESPONSE_NO:
|
||||
self.task1()
|
||||
@ -96,9 +96,9 @@ class QuestionDialog:
|
||||
|
||||
self.xml.get_widget('okbutton').set_label(label)
|
||||
|
||||
self.top.show()
|
||||
if parent:
|
||||
self.top.set_transient_for(parent)
|
||||
self.top.show()
|
||||
response = self.top.run()
|
||||
self.top.destroy()
|
||||
if response == gtk.RESPONSE_ACCEPT:
|
||||
@ -123,9 +123,10 @@ class QuestionDialog2:
|
||||
self.xml.get_widget('okbutton').set_use_underline(True)
|
||||
self.xml.get_widget('no').set_label(label_msg2)
|
||||
self.xml.get_widget('no').set_use_underline(True)
|
||||
self.top.show()
|
||||
|
||||
if parent:
|
||||
self.top.set_transient_for(parent)
|
||||
self.top.show()
|
||||
|
||||
def run(self):
|
||||
response = self.top.run()
|
||||
@ -149,9 +150,9 @@ class OptionDialog:
|
||||
|
||||
self.xml.get_widget('option1').set_label(btnmsg1)
|
||||
self.xml.get_widget('option2').set_label(btnmsg2)
|
||||
self.top.show()
|
||||
if parent:
|
||||
self.top.set_transient_for(parent)
|
||||
self.top.show()
|
||||
self.response = self.top.run()
|
||||
if self.response == gtk.RESPONSE_NO:
|
||||
if task1:
|
||||
@ -188,7 +189,7 @@ class RunDatabaseRepair(ErrorDialog):
|
||||
'usually be resolved by running the "Check and Repair Database" '
|
||||
'tool.\n\nIf this problem continues to exist after running this '
|
||||
'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):
|
||||
def __init__(self, msg, parent=None):
|
||||
@ -198,7 +199,7 @@ class DBErrorDialog(ErrorDialog):
|
||||
_("GRAMPS has detected a problem in the underlying "
|
||||
"Berkeley database. This can be repaired by from "
|
||||
"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):
|
||||
def __init__(self,msg1,msg2="",parent=None):
|
||||
@ -230,6 +231,35 @@ class OkDialog(gtk.MessageDialog):
|
||||
self.run()
|
||||
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:
|
||||
def __init__(self,msg1,msg2,task1,task2,task3,parent=None):
|
||||
self.xml = glade.XML(const.GLADE_FILE,"missmediadialog","gramps")
|
||||
@ -251,9 +281,9 @@ class MissingMediaDialog:
|
||||
|
||||
check_button = self.xml.get_widget('use_always')
|
||||
|
||||
self.top.show()
|
||||
if parent:
|
||||
self.top.set_transient_for(parent)
|
||||
self.top.show()
|
||||
self.top.connect('delete_event',self.warn)
|
||||
response = gtk.RESPONSE_DELETE_EVENT
|
||||
|
||||
|
@ -64,7 +64,8 @@ import const
|
||||
import Config
|
||||
import GrampsCfg
|
||||
import Errors
|
||||
from QuestionDialog import ErrorDialog, WarningDialog, QuestionDialog2
|
||||
from QuestionDialog import (ErrorDialog, WarningDialog, QuestionDialog2,
|
||||
InfoDialog)
|
||||
import PageView
|
||||
import Navigation
|
||||
import RecentFiles
|
||||
@ -91,11 +92,6 @@ gtk.about_dialog_set_url_hook(show_url, None)
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
_KNOWN_FORMATS = {
|
||||
const.APP_GRAMPS : _('GRAMPS (grdb)'),
|
||||
const.APP_GRAMPS_XML : _('GRAMPS XML'),
|
||||
const.APP_GEDCOM : _('GEDCOM'),
|
||||
}
|
||||
|
||||
UIDEFAULT = '''<ui>
|
||||
<menubar name="MenuBar">
|
||||
@ -1039,6 +1035,9 @@ class ViewManager:
|
||||
"""
|
||||
if self.state.db.is_open():
|
||||
self.db_loader.import_file()
|
||||
infotxt = self.db_loader.import_info_text()
|
||||
if infotxt:
|
||||
InfoDialog(_('Import Statistics'), infotxt, self.window)
|
||||
self.__post_load()
|
||||
|
||||
def open_activate(self, path):
|
||||
|
@ -816,12 +816,16 @@ class GrampsDbBase(Callback):
|
||||
add_func):
|
||||
obj = class_type()
|
||||
handle = str(handle)
|
||||
new = True
|
||||
if dmap.has_key(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:
|
||||
obj.set_handle(handle)
|
||||
add_func(obj, transaction)
|
||||
return obj
|
||||
return obj, new
|
||||
|
||||
def __check_from_handle(self, handle, transaction, class_type, dmap,
|
||||
add_func, set_gid=True):
|
||||
|
@ -1585,13 +1585,17 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback):
|
||||
def find_from_handle(self, handle, transaction, class_type, dmap, add_func):
|
||||
obj = class_type()
|
||||
handle = str(handle)
|
||||
new = True
|
||||
if dmap.has_key(handle):
|
||||
data = dmap.get(handle, txn=self.txn)
|
||||
obj.unserialize(data)
|
||||
#references create object with id None before object is really made
|
||||
if obj.gramps_id is not None:
|
||||
new = False
|
||||
else:
|
||||
obj.set_handle(handle)
|
||||
add_func(obj, transaction)
|
||||
return obj
|
||||
return obj, new
|
||||
|
||||
def transaction_begin(self, msg="", batch=False, no_magic=False):
|
||||
try:
|
||||
|
@ -16454,4 +16454,159 @@ Very High</property>
|
||||
</child>
|
||||
</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>
|
||||
|
@ -787,6 +787,7 @@ _mime_type_rfc_4180 = "text/csv" # CSV Document See rfc4180 for mime type
|
||||
_filter = gtk.FileFilter()
|
||||
_filter.set_name(_('CSV spreadsheet files'))
|
||||
_filter.add_mime_type(_mime_type)
|
||||
_filter.add_mime_type(_mime_type_rfc_4180)
|
||||
_format_name = _('CSV Spreadheet')
|
||||
register_import(importData, _filter, _mime_type, 0, _format_name)
|
||||
register_import(importData, _filter, _mime_type_rfc_4180, 0, _format_name)
|
||||
register_import(importData, _filter, [_mime_type, _mime_type_rfc_4180],
|
||||
0, _format_name)
|
||||
|
@ -934,4 +934,4 @@ _filter.set_name(_('GeneWeb files'))
|
||||
_filter.add_mime_type(_mime_type)
|
||||
_format_name = _('GeneWeb')
|
||||
|
||||
register_import(importData,_filter,_mime_type,0,_format_name)
|
||||
register_import(importData, _filter, [_mime_type], 0, _format_name)
|
||||
|
@ -220,9 +220,9 @@ class VCardParser:
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
_mime_type = const.APP_VCARD
|
||||
_filter = gtk.FileFilter()
|
||||
_filter.set_name(_('vCard files'))
|
||||
for mime in _mime_type:
|
||||
_filter = gtk.FileFilter()
|
||||
_filter.set_name(_('vCard files'))
|
||||
_filter.add_mime_type(mime)
|
||||
|
||||
register_import(importData,_filter,mime,1)
|
||||
register_import(importData, _filter, _mime_type, 1)
|
||||
|
@ -326,4 +326,4 @@ _filter.set_name(_('GRAMPS 2.x database'))
|
||||
_filter.add_mime_type(_mime_type)
|
||||
_format_name = _('GRAMPS 2.x database')
|
||||
|
||||
register_import(importData, _filter, _mime_type, 0, _format_name)
|
||||
register_import(importData, _filter, [_mime_type], 0, _format_name)
|
||||
|
@ -124,4 +124,4 @@ _filter.set_name(_('GRAMPS packages'))
|
||||
_filter.add_mime_type(_mime_type)
|
||||
_format_name = _('GRAMPS package')
|
||||
|
||||
register_import(impData, _filter, _mime_type, 0, _format_name)
|
||||
register_import(impData, _filter, [_mime_type], 0, _format_name)
|
||||
|
Loading…
x
Reference in New Issue
Block a user