From d1b65054a9d3d8540b77df4b46024bda023ad099 Mon Sep 17 00:00:00 2001 From: Benny Malengier Date: Fri, 30 Nov 2007 23:50:05 +0000 Subject: [PATCH] 2007-11-30 Benny Malengier * src/GrampsCfg.py: rel media path entry box * src/gen/db/base.py: methods for access * src/gen/db/dbdir.py: storage in BSDDB * src/GrampsDb/_GrampsDbWriteXML.py: write in header * src/GrampsDbUtils/_ReadXML.py: read relative path Start of adding relative media path to database svn: r9435 --- ChangeLog | 8 ++++ src/GrampsCfg.py | 57 +++++++++++++++++++++++- src/GrampsDb/_GrampsDbWriteXML.py | 10 +++++ src/GrampsDbUtils/_ReadXML.py | 74 ++++++++++++++++++++----------- src/gen/db/base.py | 11 +++++ src/gen/db/dbdir.py | 14 ++++++ 6 files changed, 147 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5c571199f..23b854195 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-11-30 Benny Malengier + * src/GrampsCfg.py: rel media path entry box + * src/gen/db/base.py: methods for access + * src/gen/db/dbdir.py: storage in BSDDB + * src/GrampsDb/_GrampsDbWriteXML.py: write in header + * src/GrampsDbUtils/_ReadXML.py: read relative path + Start of adding relative media path to database + 2007-11-29 Dougas S. Blank * src/Editors/_EditFamily.py: reverse surname guess for father diff --git a/src/GrampsCfg.py b/src/GrampsCfg.py index c3cc54814..5d7cbebba 100644 --- a/src/GrampsCfg.py +++ b/src/GrampsCfg.py @@ -43,6 +43,7 @@ import gtk import Config import DateHandler from BasicUtils import name_displayer as _nd +import Utils from gen.lib import Name import ManagedWindow from GrampsWidgets import * @@ -522,6 +523,10 @@ class GrampsPreferences(ManagedWindow.ManagedWindow): self.add_pos_int_entry(table, _('Number of generations for relationship determination'), 6, Config.GENERATION_DEPTH, self.update_gen_depth) + self.path_entry = gtk.Entry() + self.add_path_box(table, _('Base path for relative media paths'), + 7, self.path_entry, self.dbstate.db.get_mediapath(), + self.set_mediapath, self.select_mediapath) return table @@ -545,7 +550,31 @@ class GrampsPreferences(ManagedWindow.ManagedWindow): checkbox.set_active(Config.get(constant)) checkbox.connect('toggled', self.update_checkbox, constant) table.attach(checkbox, 1, 3, index, index+1, yoptions=0) - + + def add_path_box(self, table, label, index, entry, path, callback_label, + callback_sel): + ''' Add an entry to give in path and a select button to open a + dialog. + Changing entry calls callback_label + Clicking open button call callback_sel + ''' + lwidget = BasicLabel("%s: " %label) + hbox = gtk.HBox() + if path: + entry.set_text(path) + entry.connect('changed', callback_label) + btn = gtk.Button() + btn.connect('clicked', callback_sel) + image = gtk.Image() + image.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON) + image.show() + btn.add(image) + hbox.pack_start(entry, expand=True, fill=True) + hbox.pack_start(btn, expand=False, fill=False) + table.attach(lwidget, 1, 2, index, index+1, yoptions=0, + xoptions=gtk.FILL) + table.attach(hbox, 2, 3, index, index+1, yoptions=0) + def add_entry(self, table, label, index, constant): lwidget = BasicLabel("%s: " % label) entry = gtk.Entry() @@ -580,6 +609,32 @@ class GrampsPreferences(ManagedWindow.ManagedWindow): table.attach(color_hex_label, 2, 3, index, index+1, yoptions=0) return entry + def set_mediapath(self, *obj): + if self.path_entry.get_text().strip(): + self.dbstate.db.set_mediapath(self.path_entry.get_text()) + else: + self.dbstate.db.set_mediapath(None) + + def select_mediapath(self, *obj): + f = gtk.FileChooserDialog( + _("Select media directory"), + action=gtk.FILE_CHOOSER_ACTION_CREATE_FOLDER, + buttons=(gtk.STOCK_CANCEL, + gtk.RESPONSE_CANCEL, + gtk.STOCK_APPLY, + gtk.RESPONSE_OK)) + mpath = self.dbstate.db.get_mediapath() + if not mpath: + mpath = const.HOME_DIR + f.set_current_folder(os.path.dirname(mpath)) + + status = f.run() + if status == gtk.RESPONSE_OK: + val = Utils.get_unicode_path(f.get_filename()) + if val: + self.path_entry.set_text(val) + f.destroy() + def update_entry(self, obj, constant): Config.set(constant, unicode(obj.get_text())) diff --git a/src/GrampsDb/_GrampsDbWriteXML.py b/src/GrampsDb/_GrampsDbWriteXML.py index fefd051e0..3a7f509cf 100644 --- a/src/GrampsDb/_GrampsDbWriteXML.py +++ b/src/GrampsDb/_GrampsDbWriteXML.py @@ -264,6 +264,7 @@ class GrampsDbXmlWriter(UpdateCallback): self.write_line("resphone",owner.get_phone(),3) self.write_line("resemail",owner.get_email(),3) self.g.write(" \n") + self.write_metadata() self.g.write(" \n") # First write name formats: we need to know all formats @@ -342,11 +343,20 @@ class GrampsDbXmlWriter(UpdateCallback): # Data is written, now write bookmarks. self.write_bookmarks() + self.write_metadata() + self.g.write("\n") # self.status.end() # self.status = None + def write_metadata(self): + """ Method to write out metadata of the database + """ + mediapath= self.db.get_mediapath() + if mediapath is not None: + self.write_line("mediapath", mediapath, 2) + def write_bookmarks(self): bm_person_len = len(self.db.bookmarks.get()) bm_family_len = len(self.db.family_bookmarks.get()) diff --git a/src/GrampsDbUtils/_ReadXML.py b/src/GrampsDbUtils/_ReadXML.py index c681fe9a9..22bd21e7b 100644 --- a/src/GrampsDbUtils/_ReadXML.py +++ b/src/GrampsDbUtils/_ReadXML.py @@ -160,32 +160,35 @@ def importData(database, filename, callback=None, cl=0, use_trans=False): database.readonly = read_only - # copy all local images into .images directory - db_dir = os.path.abspath(os.path.dirname(database.get_save_path())) - db_base = os.path.basename(database.get_save_path()) - img_dir = os.path.join(db_dir, db_base) - first = not os.path.exists(img_dir) - - for m_id in database.get_media_object_handles(): - mobject = database.get_object_from_handle(m_id) - oldfile = mobject.get_path() - if oldfile and not os.path.isabs(oldfile): - if first: - os.mkdir(img_dir) - first = 0 - newfile = os.path.join(img_dir, oldfile) - - try: - oldfilename = os.path.join(basefile, oldfile) - shutil.copyfile(oldfilename, newfile) - try: - shutil.copystat(oldfilename, newfile) - except: - pass - mobject.set_path(newfile) - database.commit_media_object(mobject, None, change) - except (IOError, OSError), msg: - ErrorDialog(_('Could not copy file'), str(msg)) +## TODO - WITH MEDIA PATH, IS THIS STILL NEEDED? +## BETTER LEAVE ALL RELATIVE TO NEW RELATIVE PATH +## save_path is in .gramps/dbbase, no good place ! +## # copy all local images into .images directory +## db_dir = os.path.abspath(os.path.dirname(database.get_save_path())) +## db_base = os.path.basename(database.get_save_path()) +## img_dir = os.path.join(db_dir, db_base) +## first = not os.path.exists(img_dir) +## +## for m_id in database.get_media_object_handles(): +## mobject = database.get_object_from_handle(m_id) +## oldfile = mobject.get_path() +## if oldfile and not os.path.isabs(oldfile): +## if first: +## os.mkdir(img_dir) +## first = 0 +## newfile = os.path.join(img_dir, oldfile) +## +## try: +## oldfilename = os.path.join(basefile, oldfile) +## shutil.copyfile(oldfilename, newfile) +## try: +## shutil.copystat(oldfilename, newfile) +## except: +## pass +## mobject.set_path(newfile) +## database.commit_media_object(mobject, None, change) +## except (IOError, OSError), msg: +## ErrorDialog(_('Could not copy file'), str(msg)) #------------------------------------------------------------------------- # @@ -313,6 +316,8 @@ class GrampsParser(UpdateCallback): self.resphone = "" self.resemail = "" + self.mediapath = "" + self.pmap = {} self.fmap = {} self.smap = {} @@ -389,6 +394,7 @@ class GrampsParser(UpdateCallback): "gender" : (None, self.stop_gender), "header" : (None, None), "last" : (self.start_last, self.stop_last), + "mediapath" : (None, self.stop_mediapath), "mother" : (self.start_mother, None), "name" : (self.start_name, self.stop_name), "nick" : (None, self.stop_nick), @@ -660,6 +666,19 @@ class GrampsParser(UpdateCallback): 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: + oldpath = self.db.get_mediapath() + if not oldpath: + self.db.set_mediapath(self.mediapath) + 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." + ) % self.mediapath ) for key in self.func_map.keys(): del self.func_map[key] @@ -2045,6 +2064,9 @@ class GrampsParser(UpdateCallback): def stop_resemail(self, tag): self.resemail = tag + def stop_mediapath(self, tag): + self.mediapath = tag + def stop_ptag(self, tag): self.use_p = 1 if self.in_note: diff --git a/src/gen/db/base.py b/src/gen/db/base.py index 2b1a241ae..b9888a02f 100644 --- a/src/gen/db/base.py +++ b/src/gen/db/base.py @@ -2103,6 +2103,17 @@ class GrampsDbBase(GrampsDBCallback): media2 = self.media_map[str(second)][4] return locale.strcoll(media1, media2) + def set_mediapath(self, path): + """sets the default media path for database, path should be utf-8""" + if (self.metadata != None) and (not self.readonly): + self.metadata['mediapath'] = path + + def get_mediapath(self): + """returns the default media path of the database""" + if self.metadata != None: + return self.metadata.get('mediapath', None) + return None + def set_column_order(self, col_list, name): if (self.metadata != None) and (not self.readonly): self.metadata[name] = col_list diff --git a/src/gen/db/dbdir.py b/src/gen/db/dbdir.py index ad3c78a34..8c8177e28 100644 --- a/src/gen/db/dbdir.py +++ b/src/gen/db/dbdir.py @@ -406,6 +406,20 @@ class GrampsDBDir(GrampsDbBase, UpdateCallback): self.metadata.sync() return None + def set_mediapath(self, path): + """sets the default media path for database, path should be utf-8""" + if self.metadata and not self.readonly: + if self.UseTXN: + # Start transaction if needed + the_txn = self.env.txn_begin() + else: + the_txn = None + self.metadata.put('mediapath', path, txn=the_txn) + if self.UseTXN: + the_txn.commit() + else: + self.metadata.sync() + def set_column_order(self, col_list, name): if self.metadata and not self.readonly: if self.UseTXN: