gramps/gramps/gui/dialog.py
John Ralls c1dcd6f59e 7258: Remove all instances of sys.getfilesystemencoding()
This function reliably returns a useful value only on MacOS X. On Linux it's incorrectly determined by the
locale's encoding and on Windows it always returns 'mbcs' which is correct only on FAT file systems.
2014-04-20 17:05:51 -07:00

397 lines
14 KiB
Python

#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#-------------------------------------------------------------------------
#
# Standard python modules
#
#-------------------------------------------------------------------------
import sys
import logging
_LOG = logging.getLogger(".dialog")
#-------------------------------------------------------------------------
#
# GNOME/GTK+ modules
#
#-------------------------------------------------------------------------
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import GdkPixbuf
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import ICON
from gramps.gen.config import config
from gramps.gui.glade import Glade
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gramps.gen.constfunc import cuni
try:
ICON = GdkPixbuf.Pixbuf.new_from_file(ICON)
except:
ICON = None
class SaveDialog(object):
def __init__(self, msg1, msg2, task1, task2, parent=None):
self.xml = Glade(toplevel='savedialog')
self.top = self.xml.toplevel
self.top.set_icon(ICON)
self.top.set_title("%s - Gramps" % msg1)
self.dontask = self.xml.get_object('dontask')
self.task1 = task1
self.task2 = task2
label1 = self.xml.get_object('sd_label1')
label1.set_text('<span weight="bold" size="larger">%s</span>' % msg1)
label1.set_use_markup(True)
label2 = self.xml.get_object('sd_label2')
label2.set_text(msg2)
label2.set_use_markup(True)
if parent:
self.top.set_transient_for(parent)
self.top.show()
response = self.top.run()
if response == Gtk.ResponseType.NO:
self.task1()
elif response == Gtk.ResponseType.YES:
self.task2()
config.set('interface.dont-ask', self.dontask.get_active())
self.top.destroy()
class QuestionDialog(object):
def __init__(self, msg1, msg2, label, task, parent=None):
self.xml = Glade(toplevel='questiondialog')
self.top = self.xml.toplevel
self.top.set_icon(ICON)
self.top.set_title("%s - Gramps" % msg1)
label1 = self.xml.get_object('qd_label1')
label1.set_text('<span weight="bold" size="larger">%s</span>' % msg1)
label1.set_use_markup(True)
label2 = self.xml.get_object('qd_label2')
label2.set_text(msg2)
label2.set_use_markup(True)
self.xml.get_object('okbutton').set_label(label)
if parent:
self.top.set_transient_for(parent)
self.top.show()
response = self.top.run()
self.top.destroy()
if response == Gtk.ResponseType.ACCEPT:
task()
from gramps.gui.display import display_url
def on_activate_link(label, uri):
# see aboutdialog.py _show_url()
display_url(uri)
return True
class QuestionDialog2(object):
def __init__(self, msg1, msg2, label_msg1, label_msg2, parent=None):
self.xml = Glade(toplevel='questiondialog')
self.top = self.xml.toplevel
self.top.set_icon(ICON)
self.top.set_title("%s - Gramps" % msg1)
label1 = self.xml.get_object('qd_label1')
label1.set_text('<span weight="bold" size="larger">%s</span>' % msg1)
label1.set_use_markup(True)
label2 = self.xml.get_object('qd_label2')
# see https://github.com/emesene/emesene/issues/723
label2.connect('activate-link', on_activate_link)
label2.set_text(msg2)
label2.set_use_markup(True)
self.xml.get_object('okbutton').set_label(label_msg1)
self.xml.get_object('okbutton').set_use_underline(True)
self.xml.get_object('no').set_label(label_msg2)
self.xml.get_object('no').set_use_underline(True)
if parent:
self.top.set_transient_for(parent)
self.top.show()
def run(self):
response = self.top.run()
self.top.destroy()
return (response == Gtk.ResponseType.ACCEPT)
class OptionDialog(object):
def __init__(self, msg1, msg2, btnmsg1, task1, btnmsg2, task2, parent=None):
self.xml = Glade(toplevel='optiondialog')
self.top = self.xml.toplevel
self.top.set_icon(ICON)
self.top.set_title("%s - Gramps" % msg1)
label1 = self.xml.get_object('od_label1')
label1.set_text('<span weight="bold" size="larger">%s</span>' % msg1)
label1.set_use_markup(True)
label2 = self.xml.get_object('od_label2')
label2.set_text(msg2)
label2.set_use_markup(True)
self.xml.get_object('option1').set_label(btnmsg1)
self.xml.get_object('option2').set_label(btnmsg2)
if parent:
self.top.set_transient_for(parent)
self.top.show()
self.response = self.top.run()
if self.response == Gtk.ResponseType.NO:
if task1:
task1()
else:
if task2:
task2()
self.top.destroy()
def get_response(self):
return self.response
class ErrorDialog(Gtk.MessageDialog):
def __init__(self, msg1, msg2="", parent=None):
Gtk.MessageDialog.__init__(self, parent,
flags=Gtk.DialogFlags.MODAL,
type=Gtk.MessageType.ERROR,
buttons=Gtk.ButtonsType.CLOSE)
self.set_markup('<span weight="bold" size="larger">%s</span>' % str(msg1))
self.format_secondary_text(msg2)
self.set_icon(ICON)
self.set_title("%s - Gramps" % str(msg1))
self.show()
self.run()
self.destroy()
class RunDatabaseRepair(ErrorDialog):
def __init__(self, msg, parent=None):
ErrorDialog.__init__(
self,
_('Error detected in database'),
_('Gramps has detected an error in the database. This can '
'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') + msg, parent)
class DBErrorDialog(ErrorDialog):
def __init__(self, msg, parent=None):
ErrorDialog.__init__(
self,
_("Low level database corruption detected"),
_("Gramps has detected a problem in the underlying "
"Berkeley database. This can be repaired from "
"the Family Tree Manager. Select the database and "
'click on the Repair button') + '\n\n' + msg, parent)
class WarningDialog(Gtk.MessageDialog):
def __init__(self, msg1, msg2="", parent=None):
Gtk.MessageDialog.__init__(self, parent,
flags=Gtk.DialogFlags.MODAL,
type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.CLOSE)
self.set_markup('<span weight="bold" size="larger">%s</span>' % msg1)
self.format_secondary_markup(msg2)
# FIXME: Hyper-links in the secondary text display as underlined text,
# but clicking on the link fails with
# GtkWarning: Unable to show 'http://www.gramps-project.org/wiki/index.php?title=How_to_make_a_backup': Operation not supported
# self.connect('activate-link'... fails with
# <WarningDialog object at 0x4880300 (GtkMessageDialog at 0x5686010)>: unknown signal name: activate-link
self.set_icon(ICON)
self.set_title("%s - Gramps" % msg1)
self.show()
self.run()
self.destroy()
class OkDialog(Gtk.MessageDialog):
def __init__(self, msg1, msg2="", parent=None):
Gtk.MessageDialog.__init__(self, parent,
flags=Gtk.DialogFlags.MODAL,
type=Gtk.MessageType.INFO,
buttons=Gtk.ButtonsType.CLOSE)
self.set_markup('<span weight="bold" size="larger">%s</span>' % msg1)
self.format_secondary_text(msg2)
self.set_icon(ICON)
self.set_title("%s - Gramps" % msg1)
self.show()
self.run()
self.destroy()
class InfoDialog(object):
"""
Non modal dialog to show selectable info in a scrolled window
"""
def __init__(self, msg1, infotext, parent=None, monospaced=False):
self.xml = Glade(toplevel='infodialog')
self.top = self.xml.toplevel
self.top.set_icon(ICON)
self.top.set_title("%s - Gramps" % msg1)
label = self.xml.get_object('toplabel')
label.set_text('<span weight="bold" size="larger">%s</span>' % msg1)
label.set_use_markup(True)
infoview = self.xml.get_object('infoview')
infobuffer = Gtk.TextBuffer()
infobuffer.set_text(infotext)
if monospaced:
startiter, enditer = infobuffer.get_bounds()
tag = infobuffer.create_tag(family="Monospace")
infobuffer.apply_tag(tag, startiter, enditer)
infoview.set_buffer(infobuffer)
if parent:
self.top.set_transient_for(parent)
self.top.connect('response', self.destroy)
self.top.show()
def destroy(self, dialog, response_id):
#no matter how it finishes, destroy dialog
dialog.destroy()
class MissingMediaDialog(object):
def __init__(self, msg1, msg2, task1, task2, task3, parent=None):
self.xml = Glade(toplevel='missmediadialog')
self.top = self.xml.toplevel
self.top.set_icon(ICON)
self.top.set_title("%s - Gramps" % msg1)
self.task1 = task1
self.task2 = task2
self.task3 = task3
label1 = self.xml.get_object('label4')
label1.set_text('<span weight="bold" size="larger">%s</span>' % msg1)
label1.set_use_markup(True)
label2 = self.xml.get_object('label3')
label2.set_text(msg2)
label2.set_use_markup(True)
check_button = self.xml.get_object('use_always')
if parent:
self.top.set_transient_for(parent)
self.top.show()
self.top.connect('delete_event', self.warn)
response = Gtk.ResponseType.DELETE_EVENT
# Need some magic here, because an attempt to close the dialog
# with the X button not only emits the 'delete_event' signal
# but also exits with the RESPONSE_DELETE_EVENT
while response == Gtk.ResponseType.DELETE_EVENT:
response = self.top.run()
if response == 1:
self.task1()
elif response == 2:
self.task2()
elif response == 3:
self.task3()
if check_button.get_active():
self.default_action = response
else:
self.default_action = 0
self.top.destroy()
def warn(self, obj, obj2):
WarningDialog(
_("Attempt to force closing the dialog"),
_("Please do not force closing this important dialog.\n"
"Instead select one of the available options"),
self.top)
return True
class MessageHideDialog(object):
def __init__(self, title, message, key, parent=None):
self.xml = Glade(toplevel='hidedialog')
self.top = self.xml.toplevel
self.top.set_icon(ICON)
self.top.set_title("%s - Gramps" % title)
dont_show = self.xml.get_object('dont_show')
dont_show.set_active(config.get(key))
title_label = self.xml.get_object('title')
title_label.set_text(
'<span size="larger" weight="bold">%s</span>' % title)
title_label.set_use_markup(True)
self.xml.get_object('message').set_text(message)
dont_show.connect('toggled', self.update_checkbox, key)
self.top.run()
self.top.destroy()
def update_checkbox(self, obj, constant):
config.set(constant, obj.get_active())
config.save()
## Testing function of some of these dialogs
def main(args):
win = Gtk.Window()
win.set_title('Dialog test window')
win.set_position(Gtk.WindowPosition.CENTER)
def cb(window, event):
Gtk.main_quit()
win.connect('delete-event', cb)
def test_info(obj):
InfoDialog('The title', 'This is a lot of info\n to show to all!', parent=win)
vbox = Gtk.VBox()
win.add(vbox)
btn1 = Gtk.Button('Info dialog')
btn1.connect('clicked', test_info)
vbox.pack_start(btn1, True, True, 0)
win.show_all()
Gtk.main()
if __name__ == '__main__':
import sys
# fall back to root logger for testing
_LOG = logging
sys.exit(main(sys.argv))