* src/GrampsDb/_GrampsBSDDB.py (load_from): Add method.

* src/GrampsDb/_GrampsXMLDB.py (load_from): Add method.
	* src/GrampsDb/_GrampsGEDDB.py (load_from): Add method.
	* src/GrampsDb/_GrampsDbBase.py (load_from): Add method.
	* src/GrampsDb/_WriteGrdb.py: Use db_copy.
	* src/GrampsDb/_DbUtils.py (db_copy): Add function.
	* src/ViewManager.py: Save as support.
	* src/DataViews/_MapView.py (enable_debug): Set to False to be
	able to see the output besides MapView.



svn: r6604
This commit is contained in:
Alex Roitman 2006-05-10 05:52:55 +00:00
parent 626185cff8
commit 40f355e17d
9 changed files with 281 additions and 88 deletions

View File

@ -8,6 +8,16 @@
the session
2006-05-09 Alex Roitman <shura@gramps-project.org>
* src/GrampsDb/_GrampsBSDDB.py (load_from): Add method.
* src/GrampsDb/_GrampsXMLDB.py (load_from): Add method.
* src/GrampsDb/_GrampsGEDDB.py (load_from): Add method.
* src/GrampsDb/_GrampsDbBase.py (load_from): Add method.
* src/GrampsDb/_WriteGrdb.py: Use db_copy.
* src/GrampsDb/_DbUtils.py (db_copy): Add function.
* src/ViewManager.py: Save as support.
* src/DataViews/_MapView.py (enable_debug): Set to False to be
able to see the output besides MapView.
* src/plugins/FamilyGroup.py: Use triple quotes.
* src/Exporter.py (Exporter.native_export): Use callback.
* src/Utils.py (get_new_filename): Add path separator.

View File

@ -78,7 +78,7 @@ glob_loc_data = [ # (Name, longitude, latitude)
("Mannheim-Neckarau",8.48,49.45),
("Gorxheimertal",8.73,49.53)]
enable_debug = True
enable_debug = False
# Draws a map image and tries to allocate space in the correct aspect ratio

View File

@ -143,3 +143,95 @@ def add_child_to_family(db, family, child,
if need_commit:
db.transaction_commit(trans, _('Add child to family') )
def db_copy(from_db,to_db,callback):
if '__call__' in dir(callback): # callback is really callable
update = update_real
# Prepare length for the callback
person_len = from_db.get_number_of_people()
family_len = from_db.get_number_of_families()
event_len = from_db.get_number_of_events()
source_len = from_db.get_number_of_sources()
place_len = from_db.get_number_of_places()
repo_len = from_db.get_number_of_repositories()
obj_len = from_db.get_number_of_media_objects()
total = person_len + family_len + event_len + place_len + \
source_len + obj_len + repo_len
else:
update = update_empty
total = 0
primary_tables = {
'Person': {'cursor_func': from_db.get_person_cursor,
'table': to_db.person_map },
'Family': {'cursor_func': from_db.get_family_cursor,
'table': to_db.family_map },
'Event': {'cursor_func': from_db.get_event_cursor,
'table': to_db.event_map },
'Place': {'cursor_func': from_db.get_place_cursor,
'table': to_db.place_map },
'Source': {'cursor_func': from_db.get_source_cursor,
'table': to_db.source_map },
'MediaObject': {'cursor_func': from_db.get_media_cursor,
'table': to_db.media_map },
'Repository': {'cursor_func': from_db.get_repository_cursor,
'table': to_db.repository_map },
}
if to_db.__class__.__name__ == 'GrampsBSDDB':
if to_db.UseTXN:
add_data = add_data_txn
else:
add_data = add_data_notxn
else:
add_data = add_data_dict
oldval = 0
count = 0
for table_name in primary_tables.keys():
cursor_func = primary_tables[table_name]['cursor_func']
table = primary_tables[table_name]['table']
cursor = cursor_func()
item = cursor.first()
while item:
(handle,data) = item
add_data(to_db,table,handle,data)
item = cursor.next()
count,oldval = update(callback,count,oldval,total)
update(callback,count,oldval,total)
cursor.close()
# The metadata is always transactionless,
# and the table is small, so using key iteration is OK here.
for handle in from_db.metadata.keys():
data = from_db.metadata.get(handle)
to_db.metadata[handle] = data
def add_data_txn(db,table,handle,data):
the_txn = db.env.txn_begin()
table.put(handle,data,txn=the_txn)
the_txn.commit()
def add_data_notxn(db,table,handle,data):
table.put(handle,data)
def add_data_dict(db,table,handle,data):
table[handle] = data
def update_empty(callback,count,oldval,total):
pass
def update_real(callback,count,oldval,total):
count += 1
newval = int(100.0*count/total)
if newval != oldval:
callback(newval)
oldval = newval
return count,oldval

View File

@ -53,6 +53,7 @@ except NameError:
#-------------------------------------------------------------------------
from RelLib import *
from _GrampsDbBase import *
from _DbUtils import db_copy
import const
_MINVERSION = 5
@ -316,15 +317,14 @@ class GrampsBSDDB(GrampsDbBase):
else:
env_flags = db.DB_CREATE|db.DB_PRIVATE|\
db.DB_INIT_MPOOL|db.DB_INIT_LOG
env_name = self.brief_name
env_name = os.path.expanduser('~')
self.env.open(env_name,env_flags)
if self.UseTXN:
self.env.txn_checkpoint()
callback(25)
self.metadata =self.open_table(self.full_name,"meta",no_txn=True)
self.metadata = self.open_table(self.full_name,"meta",no_txn=True)
self.family_map = self.open_table(self.full_name, "family")
self.place_map = self.open_table(self.full_name, "places")
@ -386,6 +386,11 @@ class GrampsBSDDB(GrampsDbBase):
return 1
def load_from(self, other_database, filename, callback):
self.load(filename,callback)
db_copy(other_database,self,callback)
return 1
def connect_secondary(self):
"""
This method connects or creates secondary index tables.

View File

@ -356,6 +356,14 @@ class GrampsDbBase(GrampsDBCallback):
"""
assert False, "Needs to be overridden in the derived class"
def load_from(self, other_database, filename, callback):
"""
Loads data from the other database into itself.
The filename is the name of the file for the newly created database.
The method needs to be overridden in the derived class.
"""
assert False, "Needs to be overridden in the derived class"
def close(self):
"""
Closes the specified database. The method needs to be overridden

View File

@ -30,6 +30,7 @@ from _GrampsInMemDB import *
import _ReadGedcom as ReadGedcom
import _WriteGedcom as WriteGedcom
from _DbUtils import db_copy
#-------------------------------------------------------------------------
#
@ -56,6 +57,17 @@ class GrampsGEDDB(GrampsInMemDB):
self.db_is_open = True
return 1
def load_from(self, other_database, filename, callback):
db_copy(other_database,self,callback)
GrampsInMemDB.load(self,filename,callback)
self.bookmarks = self.metadata.get('bookmarks')
if self.bookmarks == None:
self.bookmarks = []
self.db_is_open = True
writer = WriteGedcom.GedcomWriter(self,self.get_default_person())
writer.export_data(self.full_name)
return 1
def close(self):
if not self.db_is_open:
return

View File

@ -30,6 +30,7 @@ from _GrampsInMemDB import *
import _ReadXML as ReadXML
import _WriteXML as WriteXML
from _DbUtils import db_copy
#-------------------------------------------------------------------------
#
@ -58,6 +59,17 @@ class GrampsXMLDB(GrampsInMemDB):
self.db_is_open = True
return 1
def load_from(self, other_database, filename, callback):
self.id_trans = {}
db_copy(other_database,self,callback)
GrampsInMemDB.load(self,filename,callback)
self.bookmarks = self.metadata.get('bookmarks')
if self.bookmarks == None:
self.bookmarks = []
self.db_is_open = True
WriteXML.quick_write(self,self.full_name)
return 1
def close(self):
if not self.db_is_open:
return

View File

@ -37,6 +37,7 @@ from gettext import gettext as _
#-------------------------------------------------------------------------
from _GrampsBSDDB import GrampsBSDDB
from QuestionDialog import ErrorDialog
from _DbUtils import db_copy
#-------------------------------------------------------------------------
#
@ -44,25 +45,7 @@ from QuestionDialog import ErrorDialog
#
#-------------------------------------------------------------------------
def exportData(database, filename, person=None, callback=None, cl=False):
if '__call__' in dir(callback): # callback is really callable
update = update_real
# Prepare length for the callback
person_len = database.get_number_of_people()
family_len = database.get_number_of_families()
event_len = database.get_number_of_events()
source_len = database.get_number_of_sources()
place_len = database.get_number_of_places()
repo_len = database.get_number_of_repositories()
obj_len = database.get_number_of_media_objects()
total = person_len + family_len + event_len + place_len + \
source_len + obj_len + repo_len
else:
update = update_empty
total = 0
filename = os.path.normpath(filename)
new_database = GrampsBSDDB()
try:
@ -75,69 +58,6 @@ def exportData(database, filename, person=None, callback=None, cl=False):
return
# copy all data from new_database to database
# Need different adders depending on whether the new db is transactional
if new_database.UseTXN:
add_data = add_data_txn
else:
add_data = add_data_notxn
primary_tables = {
'Person': {'cursor_func': database.get_person_cursor,
'new_table': new_database.person_map },
'Family': {'cursor_func': database.get_family_cursor,
'new_table': new_database.family_map },
'Event': {'cursor_func': database.get_event_cursor,
'new_table': new_database.event_map },
'Place': {'cursor_func': database.get_place_cursor,
'new_table': new_database.place_map },
'Source': {'cursor_func': database.get_source_cursor,
'new_table': new_database.source_map },
'MediaObject': {'cursor_func': database.get_media_cursor,
'new_table': new_database.media_map },
'Repository': {'cursor_func': database.get_repository_cursor,
'new_table': new_database.repository_map },
}
count = 0
oldval = 0
for table_name in primary_tables.keys():
cursor_func = primary_tables[table_name]['cursor_func']
new_table = primary_tables[table_name]['new_table']
cursor = cursor_func()
item = cursor.first()
while item:
(handle,data) = item
add_data(new_database,new_table,handle,data)
item = cursor.next()
count,oldval = update(callback,count,oldval,total)
cursor.close()
# The metadata is always transactionless,
# and the table is small, so using key iteration is OK here.
for handle in database.metadata.keys():
new_database.metadata.put(handle,database.metadata.get(handle))
db_copy(database,new_database,callback)
new_database.close()
def add_data_txn(db,table,handle,data):
the_txn = db.env.txn_begin()
table.put(handle,data,txn=the_txn)
the_txn.commit()
def add_data_notxn(db,table,handle,data):
table.put(handle,data)
def update_empty(callback,count,oldval,total):
pass
def update_real(callback,count,oldval,total):
count += 1
newval = int(100.0*count/total)
if newval != oldval:
callback(newval)
oldval = newval
return count,oldval

View File

@ -329,7 +329,8 @@ class ViewManager:
]
self._action_action_list = [
('SaveAs', gtk.STOCK_SAVE_AS, _('_Save As')),
('SaveAs', gtk.STOCK_SAVE_AS, _('_Save As'),"<control><shift>s",
None, self.save_as_activate),
('Export', gtk.STOCK_SAVE_AS, _('_Export'), "<control>e", None,
self.export_data),
('Abandon', gtk.STOCK_REVERT_TO_SAVED,
@ -755,6 +756,79 @@ class ViewManager:
choose.destroy()
return False
def save_as_activate(self,obj):
choose = gtk.FileChooserDialog(
_('GRAMPS: Create GRAMPS database'),
self.uistate.window,
gtk.FILE_CHOOSER_ACTION_SAVE,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OPEN, gtk.RESPONSE_OK))
# Always add automatic (macth all files) filter
add_all_files_filter(choose)
add_gramps_files_filter(choose)
add_grdb_filter(choose)
add_xml_filter(choose)
add_gedcom_filter(choose)
format_list = [const.app_gramps,const.app_gramps_xml,const.app_gedcom]
(box, type_selector) = format_maker(format_list)
choose.set_extra_widget(box)
# Suggested folder: try last open file, import, then last export,
# then home.
default_dir = os.path.split(Config.get(Config.RECENT_FILE))[0] \
+ os.path.sep
if len(default_dir)<=1:
default_dir = Config.get(Config.RECENT_IMPORT_DIR)
if len(default_dir)<=1:
default_dir = Config.get(Config.RECENT_EXPORT_DIR)
if len(default_dir)<=1:
default_dir = '~/'
new_filename = Utils.get_new_filename('grdb', default_dir)
choose.set_current_folder(default_dir)
choose.set_current_name(os.path.split(new_filename)[1])
response = choose.run()
if response == gtk.RESPONSE_OK:
filename = choose.get_filename()
if filename == None:
choose.destroy()
return False
filetype = type_selector.get_value()
if filetype == 'auto':
try:
the_file = open(filename,'wb')
the_file.close()
filetype = Mime.get_type(filename)
os.remove(filename)
except RuntimeError, msg:
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
str(msg))
return False
# First we try our best formats
if filetype not in (const.app_gramps,
const.app_gramps_xml,
const.app_gedcom):
QuestionDialog.ErrorDialog(
_("Could not open file: %s") % filename,
_("Unknown type: %s") % filetype
)
return False
choose.destroy()
try:
return self.open_saved_as(filename,filetype)
except:
log.error("Failed to save as", exc_info=True)
return False
else:
choose.destroy()
return False
def new_activate(self, obj):
choose = gtk.FileChooserDialog(
@ -1159,6 +1233,66 @@ class ViewManager:
self.progress.hide()
self.window.window.set_cursor(None)
def open_saved_as(self, filename, filetype):
(the_path, the_file) = os.path.split(filename)
Config.set(Config.RECENT_IMPORT_DIR,the_path)
dbclass = GrampsDb.gramps_db_factory(filetype)
success = self.do_save_as(filename,dbclass)
self.state.signal_change()
self.change_page(None, None)
if success:
# Add the file to the recent items
RecentFiles.recent_files(filename, filetype)
self.recent_manager.build()
self.actiongroup.set_visible(True)
self.uistate.clear_history()
return success
def do_save_as(self,filename,dbclass):
# FIXME: error checking on filename here
self.state.emit('database-changed', (GrampsDb.GrampsDbBase(), ))
try:
if self._do_copy(filename,dbclass):
if filename[-1] == '/':
filename = filename[:-1]
name = os.path.basename(filename)
msg = "%s - GRAMPS" % name
self.uistate.window.set_title(msg)
else:
Config.set(Config.RECENT_FILE,"")
QuestionDialog.ErrorDialog(
_('Cannot save a copy of the database'),
_('The database copy could not be saved.'))
return False
except (IOError,OSError), msg:
QuestionDialog.ErrorDialog(_('Cannot save database'), str(msg))
return False
except (db.DBAccessError, db.DBError), msg:
QuestionDialog.ErrorDialog(
_('Cannot save database'),
_('%s could not be saved.' % filename) + '\n' + msg[1])
return False
except Exception:
log.error("Failed to open database.", exc_info=True)
return False
self.file_loaded = True
self.actiongroup.set_visible(True)
return True
def _do_copy(self,filename,dbclass):
self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
self.progress.show()
new_database = dbclass()
if not new_database.load_from(self.state.db,filename,
self.uistate.pulse_progressbar):
return False
self.progress.hide()
self.state.db.close()
self.state.change_database(new_database)
return self.post_load(filename,self.uistate.pulse_progressbar)
def build_tools_menu(self):
self.toolactions = gtk.ActionGroup('ToolWindow')
(ui, actions) = self.build_plugin_menu('ToolsMenu',