8868: Make XML backup dialog size persist [part 2]
This commit is contained in:
@@ -92,6 +92,7 @@ from .navigator import Navigator
|
|||||||
from .views.tags import Tags
|
from .views.tags import Tags
|
||||||
from .actiongroup import ActionGroup
|
from .actiongroup import ActionGroup
|
||||||
from gramps.gen.db.exceptions import DbWriteFailure
|
from gramps.gen.db.exceptions import DbWriteFailure
|
||||||
|
from .managedwindow import ManagedWindow
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@@ -1291,184 +1292,6 @@ class ViewManager(CLIManager):
|
|||||||
except WindowActiveError:
|
except WindowActiveError:
|
||||||
return
|
return
|
||||||
|
|
||||||
from .managedwindow import ManagedWindow # only temporarily down here, inline
|
|
||||||
class QuickBackup(ManagedWindow): # class temporarily inline, for a better diff
|
|
||||||
|
|
||||||
def __init__(self, dbstate, uistate, user):
|
|
||||||
"""
|
|
||||||
Make a quick XML back with or without media.
|
|
||||||
"""
|
|
||||||
self.dbstate = dbstate
|
|
||||||
self.user = user
|
|
||||||
|
|
||||||
ManagedWindow.__init__(self, uistate, [], self.__class__)
|
|
||||||
window = Gtk.Dialog('',
|
|
||||||
self.uistate.window,
|
|
||||||
Gtk.DialogFlags.DESTROY_WITH_PARENT, None)
|
|
||||||
self.set_window(window, None, _("Gramps XML Backup"))
|
|
||||||
self.setup_configs('interface.quick-backup', 500, 150)
|
|
||||||
ok_button = window.add_button(_('_OK'),
|
|
||||||
Gtk.ResponseType.APPLY)
|
|
||||||
close_button = window.add_button(_('_Close'),
|
|
||||||
Gtk.ResponseType.CLOSE)
|
|
||||||
vbox = window.get_content_area()
|
|
||||||
hbox = Gtk.Box()
|
|
||||||
label = Gtk.Label(label=_("Path:"))
|
|
||||||
label.set_justify(Gtk.Justification.LEFT)
|
|
||||||
label.set_size_request(90, -1)
|
|
||||||
label.set_halign(Gtk.Align.START)
|
|
||||||
hbox.pack_start(label, False, True, 0)
|
|
||||||
path_entry = Gtk.Entry()
|
|
||||||
text = config.get('paths.quick-backup-directory')
|
|
||||||
path_entry.set_text(text)
|
|
||||||
hbox.pack_start(path_entry, True, True, 0)
|
|
||||||
file_entry = Gtk.Entry()
|
|
||||||
button = Gtk.Button()
|
|
||||||
button.connect("clicked",
|
|
||||||
lambda widget:
|
|
||||||
self.select_backup_path(widget, path_entry))
|
|
||||||
image = Gtk.Image()
|
|
||||||
image.set_from_icon_name('document-open', Gtk.IconSize.BUTTON)
|
|
||||||
image.show()
|
|
||||||
button.add(image)
|
|
||||||
hbox.pack_end(button, False, True, 0)
|
|
||||||
vbox.pack_start(hbox, False, True, 0)
|
|
||||||
hbox = Gtk.Box()
|
|
||||||
label = Gtk.Label(label=_("File:"))
|
|
||||||
label.set_justify(Gtk.Justification.LEFT)
|
|
||||||
label.set_size_request(90, -1)
|
|
||||||
label.set_halign(Gtk.Align.START)
|
|
||||||
hbox.pack_start(label, False, True, 0)
|
|
||||||
struct_time = time.localtime()
|
|
||||||
file_entry.set_text(
|
|
||||||
config.get('paths.quick-backup-filename'
|
|
||||||
) % {"filename": self.dbstate.db.get_dbname(),
|
|
||||||
"year": struct_time.tm_year,
|
|
||||||
"month": struct_time.tm_mon,
|
|
||||||
"day": struct_time.tm_mday,
|
|
||||||
"hour": struct_time.tm_hour,
|
|
||||||
"minutes": struct_time.tm_min,
|
|
||||||
"seconds": struct_time.tm_sec,
|
|
||||||
"extension": "gpkg"})
|
|
||||||
hbox.pack_end(file_entry, True, True, 0)
|
|
||||||
vbox.pack_start(hbox, False, True, 0)
|
|
||||||
hbox = Gtk.Box()
|
|
||||||
fbytes = 0
|
|
||||||
mbytes = "0"
|
|
||||||
for media in self.dbstate.db.iter_media():
|
|
||||||
fullname = media_path_full(self.dbstate.db, media.get_path())
|
|
||||||
try:
|
|
||||||
fbytes += posixpath.getsize(fullname)
|
|
||||||
length = len(str(fbytes))
|
|
||||||
if fbytes <= 999999:
|
|
||||||
mbytes = "< 1"
|
|
||||||
else:
|
|
||||||
mbytes = str(fbytes)[:(length-6)]
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
label = Gtk.Label(label=_("Media:"))
|
|
||||||
label.set_justify(Gtk.Justification.LEFT)
|
|
||||||
label.set_size_request(90, -1)
|
|
||||||
label.set_halign(Gtk.Align.START)
|
|
||||||
hbox.pack_start(label, False, True, 0)
|
|
||||||
include = Gtk.RadioButton.new_with_mnemonic_from_widget(
|
|
||||||
None, "%s (%s %s)" % (_("Include"),
|
|
||||||
mbytes, _("Megabyte|MB")))
|
|
||||||
exclude = Gtk.RadioButton.new_with_mnemonic_from_widget(include,
|
|
||||||
_("Exclude"))
|
|
||||||
include.connect("toggled", lambda widget: self.media_toggle(widget,
|
|
||||||
file_entry))
|
|
||||||
include_mode = config.get('preferences.quick-backup-include-mode')
|
|
||||||
if include_mode:
|
|
||||||
include.set_active(True)
|
|
||||||
else:
|
|
||||||
exclude.set_active(True)
|
|
||||||
hbox.pack_start(include, False, True, 0)
|
|
||||||
hbox.pack_end(exclude, False, True, 0)
|
|
||||||
vbox.pack_start(hbox, False, True, 0)
|
|
||||||
self.show()
|
|
||||||
dbackup = window.run()
|
|
||||||
if dbackup == Gtk.ResponseType.APPLY:
|
|
||||||
# if file exists, ask if overwrite; else abort
|
|
||||||
basefile = file_entry.get_text()
|
|
||||||
basefile = basefile.replace("/", r"-")
|
|
||||||
filename = os.path.join(path_entry.get_text(), basefile)
|
|
||||||
if os.path.exists(filename):
|
|
||||||
question = QuestionDialog2(
|
|
||||||
_("Backup file already exists! Overwrite?"),
|
|
||||||
_("The file '%s' exists.") % filename,
|
|
||||||
_("Proceed and overwrite"),
|
|
||||||
_("Cancel the backup"),
|
|
||||||
parent=self.window)
|
|
||||||
yes_no = question.run()
|
|
||||||
if not yes_no:
|
|
||||||
self.close()
|
|
||||||
return
|
|
||||||
position = self.window.get_position() # crock
|
|
||||||
window.hide()
|
|
||||||
self.window.move(position[0], position[1])
|
|
||||||
self.uistate.set_busy_cursor(True)
|
|
||||||
self.uistate.pulse_progressbar(0)
|
|
||||||
self.uistate.progress.show()
|
|
||||||
self.uistate.push_message(self.dbstate, _("Making backup..."))
|
|
||||||
if include.get_active():
|
|
||||||
from gramps.plugins.export.exportpkg import PackageWriter
|
|
||||||
writer = PackageWriter(self.dbstate.db, filename, self.user)
|
|
||||||
writer.export()
|
|
||||||
else:
|
|
||||||
from gramps.plugins.export.exportxml import XmlWriter
|
|
||||||
writer = XmlWriter(self.dbstate.db, self.user,
|
|
||||||
strip_photos=0, compress=1)
|
|
||||||
writer.write(filename)
|
|
||||||
self.uistate.set_busy_cursor(False)
|
|
||||||
self.uistate.progress.hide()
|
|
||||||
self.uistate.push_message(self.dbstate,
|
|
||||||
_("Backup saved to '%s'") % filename)
|
|
||||||
config.set('paths.quick-backup-directory', path_entry.get_text())
|
|
||||||
else:
|
|
||||||
self.uistate.push_message(self.dbstate, _("Backup aborted"))
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def select_backup_path(self, widget, path_entry):
|
|
||||||
"""
|
|
||||||
Choose a backup folder. Make sure there is one highlighted in
|
|
||||||
right pane, otherwise FileChooserDialog will hang.
|
|
||||||
"""
|
|
||||||
fdialog = Gtk.FileChooserDialog(
|
|
||||||
title=_("Select backup directory"),
|
|
||||||
parent=self.window,
|
|
||||||
action=Gtk.FileChooserAction.SELECT_FOLDER,
|
|
||||||
buttons=(_('_Cancel'),
|
|
||||||
Gtk.ResponseType.CANCEL,
|
|
||||||
_('_Apply'),
|
|
||||||
Gtk.ResponseType.OK))
|
|
||||||
mpath = path_entry.get_text()
|
|
||||||
if not mpath:
|
|
||||||
mpath = HOME_DIR
|
|
||||||
fdialog.set_current_folder(os.path.dirname(mpath))
|
|
||||||
fdialog.set_filename(os.path.join(mpath, "."))
|
|
||||||
status = fdialog.run()
|
|
||||||
if status == Gtk.ResponseType.OK:
|
|
||||||
filename = fdialog.get_filename()
|
|
||||||
if filename:
|
|
||||||
path_entry.set_text(filename)
|
|
||||||
fdialog.destroy()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def media_toggle(self, widget, file_entry):
|
|
||||||
"""
|
|
||||||
Toggles media include values in the quick backup dialog.
|
|
||||||
"""
|
|
||||||
include = widget.get_active()
|
|
||||||
config.set('preferences.quick-backup-include-mode', include)
|
|
||||||
extension = "gpkg" if include else "gramps"
|
|
||||||
filename = file_entry.get_text()
|
|
||||||
if "." in filename:
|
|
||||||
base, ext = filename.rsplit(".", 1)
|
|
||||||
file_entry.set_text("%s.%s" % (base, extension))
|
|
||||||
else:
|
|
||||||
file_entry.set_text("%s.%s" % (filename, extension))
|
|
||||||
|
|
||||||
def autobackup(self):
|
def autobackup(self):
|
||||||
"""
|
"""
|
||||||
Backup the current family tree.
|
Backup the current family tree.
|
||||||
@@ -1850,3 +1673,180 @@ def views_to_show(views, use_last=True):
|
|||||||
current_cat = 0
|
current_cat = 0
|
||||||
current_cat_view = 0
|
current_cat_view = 0
|
||||||
return current_cat, current_cat_view, default_cat_views
|
return current_cat, current_cat_view, default_cat_views
|
||||||
|
|
||||||
|
class QuickBackup(ManagedWindow): # TODO move this class into its own module
|
||||||
|
|
||||||
|
def __init__(self, dbstate, uistate, user):
|
||||||
|
"""
|
||||||
|
Make a quick XML back with or without media.
|
||||||
|
"""
|
||||||
|
self.dbstate = dbstate
|
||||||
|
self.user = user
|
||||||
|
|
||||||
|
ManagedWindow.__init__(self, uistate, [], self.__class__)
|
||||||
|
window = Gtk.Dialog('',
|
||||||
|
self.uistate.window,
|
||||||
|
Gtk.DialogFlags.DESTROY_WITH_PARENT, None)
|
||||||
|
self.set_window(window, None, _("Gramps XML Backup"))
|
||||||
|
self.setup_configs('interface.quick-backup', 500, 150)
|
||||||
|
close_button = window.add_button(_('_Close'),
|
||||||
|
Gtk.ResponseType.CLOSE)
|
||||||
|
ok_button = window.add_button(_('_OK'),
|
||||||
|
Gtk.ResponseType.APPLY)
|
||||||
|
vbox = window.get_content_area()
|
||||||
|
hbox = Gtk.Box()
|
||||||
|
label = Gtk.Label(label=_("Path:"))
|
||||||
|
label.set_justify(Gtk.Justification.LEFT)
|
||||||
|
label.set_size_request(90, -1)
|
||||||
|
label.set_halign(Gtk.Align.START)
|
||||||
|
hbox.pack_start(label, False, True, 0)
|
||||||
|
path_entry = Gtk.Entry()
|
||||||
|
text = config.get('paths.quick-backup-directory')
|
||||||
|
path_entry.set_text(text)
|
||||||
|
hbox.pack_start(path_entry, True, True, 0)
|
||||||
|
file_entry = Gtk.Entry()
|
||||||
|
button = Gtk.Button()
|
||||||
|
button.connect("clicked",
|
||||||
|
lambda widget:
|
||||||
|
self.select_backup_path(widget, path_entry))
|
||||||
|
image = Gtk.Image()
|
||||||
|
image.set_from_icon_name('document-open', Gtk.IconSize.BUTTON)
|
||||||
|
image.show()
|
||||||
|
button.add(image)
|
||||||
|
hbox.pack_end(button, False, True, 0)
|
||||||
|
vbox.pack_start(hbox, False, True, 0)
|
||||||
|
hbox = Gtk.Box()
|
||||||
|
label = Gtk.Label(label=_("File:"))
|
||||||
|
label.set_justify(Gtk.Justification.LEFT)
|
||||||
|
label.set_size_request(90, -1)
|
||||||
|
label.set_halign(Gtk.Align.START)
|
||||||
|
hbox.pack_start(label, False, True, 0)
|
||||||
|
struct_time = time.localtime()
|
||||||
|
file_entry.set_text(
|
||||||
|
config.get('paths.quick-backup-filename'
|
||||||
|
) % {"filename": self.dbstate.db.get_dbname(),
|
||||||
|
"year": struct_time.tm_year,
|
||||||
|
"month": struct_time.tm_mon,
|
||||||
|
"day": struct_time.tm_mday,
|
||||||
|
"hour": struct_time.tm_hour,
|
||||||
|
"minutes": struct_time.tm_min,
|
||||||
|
"seconds": struct_time.tm_sec,
|
||||||
|
"extension": "gpkg"})
|
||||||
|
hbox.pack_end(file_entry, True, True, 0)
|
||||||
|
vbox.pack_start(hbox, False, True, 0)
|
||||||
|
hbox = Gtk.Box()
|
||||||
|
fbytes = 0
|
||||||
|
mbytes = "0"
|
||||||
|
for media in self.dbstate.db.iter_media():
|
||||||
|
fullname = media_path_full(self.dbstate.db, media.get_path())
|
||||||
|
try:
|
||||||
|
fbytes += posixpath.getsize(fullname)
|
||||||
|
length = len(str(fbytes))
|
||||||
|
if fbytes <= 999999:
|
||||||
|
mbytes = "< 1"
|
||||||
|
else:
|
||||||
|
mbytes = str(fbytes)[:(length-6)]
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
label = Gtk.Label(label=_("Media:"))
|
||||||
|
label.set_justify(Gtk.Justification.LEFT)
|
||||||
|
label.set_size_request(90, -1)
|
||||||
|
label.set_halign(Gtk.Align.START)
|
||||||
|
hbox.pack_start(label, False, True, 0)
|
||||||
|
include = Gtk.RadioButton.new_with_mnemonic_from_widget(
|
||||||
|
None, "%s (%s %s)" % (_("Include"),
|
||||||
|
mbytes, _("Megabyte|MB")))
|
||||||
|
exclude = Gtk.RadioButton.new_with_mnemonic_from_widget(include,
|
||||||
|
_("Exclude"))
|
||||||
|
include.connect("toggled", lambda widget: self.media_toggle(widget,
|
||||||
|
file_entry))
|
||||||
|
include_mode = config.get('preferences.quick-backup-include-mode')
|
||||||
|
if include_mode:
|
||||||
|
include.set_active(True)
|
||||||
|
else:
|
||||||
|
exclude.set_active(True)
|
||||||
|
hbox.pack_start(include, False, True, 0)
|
||||||
|
hbox.pack_end(exclude, False, True, 0)
|
||||||
|
vbox.pack_start(hbox, False, True, 0)
|
||||||
|
self.show()
|
||||||
|
dbackup = window.run()
|
||||||
|
if dbackup == Gtk.ResponseType.APPLY:
|
||||||
|
# if file exists, ask if overwrite; else abort
|
||||||
|
basefile = file_entry.get_text()
|
||||||
|
basefile = basefile.replace("/", r"-")
|
||||||
|
filename = os.path.join(path_entry.get_text(), basefile)
|
||||||
|
if os.path.exists(filename):
|
||||||
|
question = QuestionDialog2(
|
||||||
|
_("Backup file already exists! Overwrite?"),
|
||||||
|
_("The file '%s' exists.") % filename,
|
||||||
|
_("Proceed and overwrite"),
|
||||||
|
_("Cancel the backup"),
|
||||||
|
parent=self.window)
|
||||||
|
yes_no = question.run()
|
||||||
|
if not yes_no:
|
||||||
|
self.close()
|
||||||
|
return
|
||||||
|
position = self.window.get_position() # crock
|
||||||
|
window.hide()
|
||||||
|
self.window.move(position[0], position[1])
|
||||||
|
self.uistate.set_busy_cursor(True)
|
||||||
|
self.uistate.pulse_progressbar(0)
|
||||||
|
self.uistate.progress.show()
|
||||||
|
self.uistate.push_message(self.dbstate, _("Making backup..."))
|
||||||
|
if include.get_active():
|
||||||
|
from gramps.plugins.export.exportpkg import PackageWriter
|
||||||
|
writer = PackageWriter(self.dbstate.db, filename, self.user)
|
||||||
|
writer.export()
|
||||||
|
else:
|
||||||
|
from gramps.plugins.export.exportxml import XmlWriter
|
||||||
|
writer = XmlWriter(self.dbstate.db, self.user,
|
||||||
|
strip_photos=0, compress=1)
|
||||||
|
writer.write(filename)
|
||||||
|
self.uistate.set_busy_cursor(False)
|
||||||
|
self.uistate.progress.hide()
|
||||||
|
self.uistate.push_message(self.dbstate,
|
||||||
|
_("Backup saved to '%s'") % filename)
|
||||||
|
config.set('paths.quick-backup-directory', path_entry.get_text())
|
||||||
|
else:
|
||||||
|
self.uistate.push_message(self.dbstate, _("Backup aborted"))
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def select_backup_path(self, widget, path_entry):
|
||||||
|
"""
|
||||||
|
Choose a backup folder. Make sure there is one highlighted in
|
||||||
|
right pane, otherwise FileChooserDialog will hang.
|
||||||
|
"""
|
||||||
|
fdialog = Gtk.FileChooserDialog(
|
||||||
|
title=_("Select backup directory"),
|
||||||
|
parent=self.window,
|
||||||
|
action=Gtk.FileChooserAction.SELECT_FOLDER,
|
||||||
|
buttons=(_('_Cancel'),
|
||||||
|
Gtk.ResponseType.CANCEL,
|
||||||
|
_('_Apply'),
|
||||||
|
Gtk.ResponseType.OK))
|
||||||
|
mpath = path_entry.get_text()
|
||||||
|
if not mpath:
|
||||||
|
mpath = HOME_DIR
|
||||||
|
fdialog.set_current_folder(os.path.dirname(mpath))
|
||||||
|
fdialog.set_filename(os.path.join(mpath, "."))
|
||||||
|
status = fdialog.run()
|
||||||
|
if status == Gtk.ResponseType.OK:
|
||||||
|
filename = fdialog.get_filename()
|
||||||
|
if filename:
|
||||||
|
path_entry.set_text(filename)
|
||||||
|
fdialog.destroy()
|
||||||
|
return True
|
||||||
|
|
||||||
|
def media_toggle(self, widget, file_entry):
|
||||||
|
"""
|
||||||
|
Toggles media include values in the quick backup dialog.
|
||||||
|
"""
|
||||||
|
include = widget.get_active()
|
||||||
|
config.set('preferences.quick-backup-include-mode', include)
|
||||||
|
extension = "gpkg" if include else "gramps"
|
||||||
|
filename = file_entry.get_text()
|
||||||
|
if "." in filename:
|
||||||
|
base, ext = filename.rsplit(".", 1)
|
||||||
|
file_entry.set_text("%s.%s" % (base, extension))
|
||||||
|
else:
|
||||||
|
file_entry.set_text("%s.%s" % (filename, extension))
|
||||||
|
Reference in New Issue
Block a user