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>
* src/plugins/Verify.py
links to wiki manual

View File

@ -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)

View File

@ -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]

View File

@ -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):
"""

View File

@ -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]

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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:

View File

@ -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>

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)