Simplify status bar and fix justification of filter status
svn: r22872
This commit is contained in:
parent
2d8b44db89
commit
c56996b635
@ -69,6 +69,7 @@ from gramps.gen.relationship import get_relationship_calculator
|
||||
from .glade import Glade
|
||||
from gramps.gen.utils.db import navigation_label
|
||||
from gramps.gen.constfunc import UNITYPE, cuni
|
||||
from .widgets.progressdialog import ProgressMonitor, GtkProgressDialog
|
||||
|
||||
DISABLED = -1
|
||||
|
||||
@ -389,30 +390,28 @@ class DisplayState(Callback):
|
||||
|
||||
BUSY_CURSOR = Gdk.Cursor.new(Gdk.CursorType.WATCH)
|
||||
|
||||
def __init__(self, window, status, progress, warnbtn, uimanager,
|
||||
progress_monitor, viewmanager=None):
|
||||
def __init__(self, window, status, uimanager, viewmanager=None):
|
||||
|
||||
self.busy = False
|
||||
self.cursor = None
|
||||
self.viewmanager = viewmanager
|
||||
self.uimanager = uimanager
|
||||
self.progress_monitor = progress_monitor
|
||||
self.progress_monitor = ProgressMonitor(GtkProgressDialog, ("", window))
|
||||
self.window = window
|
||||
Callback.__init__(self)
|
||||
self.status = status
|
||||
self.status_id = status.get_context_id('GRAMPS')
|
||||
self.progress = progress
|
||||
self.progress = status.get_progress_bar()
|
||||
self.history_lookup = {}
|
||||
self.gwm = GrampsWindowManager(uimanager)
|
||||
self.widget = None
|
||||
self.disprel_old = ''
|
||||
self.disprel_defpers = None
|
||||
self.disprel_active = None
|
||||
self.warnbtn = warnbtn
|
||||
self.last_bar = self.status.insert(min_width=35, ralign=True)
|
||||
self.set_relationship_class()
|
||||
|
||||
formatter = logging.Formatter('%(levelname)s %(name)s: %(message)s')
|
||||
warnbtn = status.get_warning_button()
|
||||
self.rhandler = WarnHandler(capacity=400, button=warnbtn)
|
||||
self.rhandler.setFormatter(formatter)
|
||||
self.rhandler.setLevel(logging.WARNING)
|
||||
@ -560,12 +559,10 @@ class DisplayState(Callback):
|
||||
#text = ((_("%(nav_type)s View") % {"nav_type": _(nav_type)}) +
|
||||
text = (self.viewmanager.active_page.get_title() +
|
||||
(": %d/%d" % (matched, total)))
|
||||
self.status.pop(1, self.last_bar)
|
||||
self.status.push(1, text, self.last_bar)
|
||||
self.status.set_filter(text)
|
||||
|
||||
def clear_filter_results(self):
|
||||
self.status.pop(1, self.last_bar)
|
||||
self.status.push(1, '', self.last_bar)
|
||||
self.status.clear_filter()
|
||||
|
||||
def modify_statusbar(self, dbstate, active=None):
|
||||
view = self.viewmanager.active_page
|
||||
@ -593,9 +590,12 @@ class DisplayState(Callback):
|
||||
self.status.push(self.status_id, name)
|
||||
process_pending_events()
|
||||
|
||||
def pulse_progressbar(self, value):
|
||||
def pulse_progressbar(self, value, text=None):
|
||||
self.progress.set_fraction(min(value/100.0, 1.0))
|
||||
self.progress.set_text("%d%%" % value)
|
||||
if text:
|
||||
self.progress.set_text("%s: %d%%" % (text, value))
|
||||
else:
|
||||
self.progress.set_text("%d%%" % value)
|
||||
process_pending_events()
|
||||
|
||||
def status_text(self, text):
|
||||
|
@ -90,7 +90,7 @@ from gramps.gen.config import config
|
||||
from gramps.gen.errors import WindowActiveError
|
||||
from .dialog import (ErrorDialog, WarningDialog, QuestionDialog2,
|
||||
InfoDialog)
|
||||
from . import widgets
|
||||
from .widgets import Statusbar
|
||||
from .undohistory import UndoHistory
|
||||
from gramps.gen.utils.file import (media_path_full, get_unicode_path_from_env_var,
|
||||
get_unicode_path_from_file_chooser)
|
||||
@ -615,6 +615,7 @@ class ViewManager(CLIManager):
|
||||
|
||||
self.window = Gtk.Window()
|
||||
self.window.set_icon_from_file(ICON)
|
||||
self.window.set_has_resize_grip(True)
|
||||
self.window.set_default_size(width, height)
|
||||
|
||||
vbox = Gtk.VBox()
|
||||
@ -640,15 +641,13 @@ class ViewManager(CLIManager):
|
||||
vbox.pack_start(self.menubar, False, True, 0)
|
||||
vbox.pack_start(self.toolbar, False, True, 0)
|
||||
vbox.add(hpane)
|
||||
vbox.pack_end(self.__setup_statusbar(), False, True, 0)
|
||||
self.statusbar = Statusbar()
|
||||
self.statusbar.show()
|
||||
vbox.pack_end(self.statusbar, False, True, 0)
|
||||
vbox.show()
|
||||
|
||||
self.progress_monitor = ProgressMonitor(
|
||||
GtkProgressDialog, ("", self.window))
|
||||
|
||||
self.uistate = DisplayState(
|
||||
self.window, self.statusbar, self.progress, self.warnbtn,
|
||||
self.uimanager, self.progress_monitor, self)
|
||||
self.uistate = DisplayState(self.window, self.statusbar,
|
||||
self.uimanager, self)
|
||||
|
||||
self.dbstate.connect('database-changed', self.uistate.db_changed)
|
||||
|
||||
@ -685,28 +684,6 @@ class ViewManager(CLIManager):
|
||||
# But we need to realize it here to have Gdk.window handy
|
||||
self.window.realize()
|
||||
|
||||
def __setup_statusbar(self):
|
||||
"""
|
||||
Create the statusbar that sits at the bottom of the window
|
||||
"""
|
||||
self.progress = Gtk.ProgressBar()
|
||||
self.progress.set_size_request(100, -1)
|
||||
self.progress.hide()
|
||||
|
||||
self.statusbar = widgets.Statusbar()
|
||||
self.statusbar.show()
|
||||
|
||||
self.warnbtn = widgets.WarnButton()
|
||||
|
||||
hbox2 = Gtk.HBox()
|
||||
hbox2.set_spacing(4)
|
||||
hbox2.set_border_width(2)
|
||||
hbox2.pack_start(self.progress, False, True, 0)
|
||||
hbox2.pack_start(self.warnbtn, False, True, 0)
|
||||
hbox2.pack_end(self.statusbar, True, True, 0)
|
||||
hbox2.show()
|
||||
return hbox2
|
||||
|
||||
def __setup_navigator(self):
|
||||
"""
|
||||
If we have enabled te sidebar, show it, and turn off the tabs. If
|
||||
@ -1583,20 +1560,20 @@ class ViewManager(CLIManager):
|
||||
if not yes_no:
|
||||
return
|
||||
self.uistate.set_busy_cursor(True)
|
||||
self.pulse_progressbar(0)
|
||||
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,
|
||||
User(error=ErrorDialog,
|
||||
callback=self.pulse_progressbar))
|
||||
callback=self.uistate.pulse_progressbar))
|
||||
writer.export()
|
||||
else:
|
||||
from gramps.plugins.export.exportxml import XmlWriter
|
||||
writer = XmlWriter(self.dbstate.db,
|
||||
User(error=ErrorDialog,
|
||||
callback=self.pulse_progressbar),
|
||||
callback=self.uistate.pulse_progressbar),
|
||||
strip_photos=0, compress=1)
|
||||
writer.write(filename)
|
||||
self.uistate.set_busy_cursor(False)
|
||||
@ -1608,15 +1585,6 @@ class ViewManager(CLIManager):
|
||||
self.uistate.push_message(self.dbstate, _("Backup aborted"))
|
||||
window.destroy()
|
||||
|
||||
def pulse_progressbar(self, value, text=None):
|
||||
self.progress.set_fraction(min(value/100.0, 1.0))
|
||||
if text:
|
||||
self.progress.set_text("%s: %d%%" % (text, value))
|
||||
else:
|
||||
self.progress.set_text("%d%%" % value)
|
||||
while Gtk.events_pending():
|
||||
Gtk.main_iteration()
|
||||
|
||||
def select_backup_path(self, widget, path_entry):
|
||||
"""
|
||||
Choose a backup folder. Make sure there is one highlighted in
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2007-2008 Zsolt Foldvari
|
||||
# Copyright (C) 2013 Nick Hall
|
||||
#
|
||||
# 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
|
||||
@ -20,8 +20,6 @@
|
||||
|
||||
# $Id$
|
||||
|
||||
__all__ = ["Statusbar"]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Standard python modules
|
||||
@ -35,9 +33,14 @@ _LOG = logging.getLogger(".widgets.statusbar")
|
||||
# GTK/Gnome modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Gtk
|
||||
from gi.repository import Pango
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from . import WarnButton
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -45,206 +48,60 @@ from gi.repository import Pango
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
class Statusbar(Gtk.HBox):
|
||||
"""Custom Statusbar with flexible number of "bars".
|
||||
|
||||
Statusbar can have any number of fields included, each identified
|
||||
by it's own bar id. It has by default one field with id = 0. This
|
||||
defult field is used when no bar id is given in the relevant (push, pop,
|
||||
etc.) methods, thus Statusbar behaves as a single Gtk.Statusbar.
|
||||
|
||||
To add a new field use the "insert" method. Using the received bar id
|
||||
one can push, pop and remove messages to/from this newly inserted field.
|
||||
|
||||
"""
|
||||
__gtype_name__ = 'Statusbar'
|
||||
|
||||
##__gsignals__ = {
|
||||
##'text-popped': ,
|
||||
##'text-pushed': ,
|
||||
##}
|
||||
|
||||
__gproperties__ = {
|
||||
'has-resize-grip': (GObject.TYPE_BOOLEAN,
|
||||
'Resize grip',
|
||||
'Whether resize grip is visible',
|
||||
True,
|
||||
GObject.PARAM_READWRITE),
|
||||
}
|
||||
|
||||
A status bar
|
||||
"""
|
||||
def __init__(self):
|
||||
GObject.GObject.__init__(self)
|
||||
# initialize property values
|
||||
self.__has_resize_grip = True
|
||||
# create the main statusbar with id #0
|
||||
main_bar = Gtk.Statusbar()
|
||||
main_bar.show()
|
||||
self.pack_start(main_bar, True, True, 0)
|
||||
self._bars = {0: main_bar}
|
||||
Gtk.HBox.__init__(self)
|
||||
self.set_spacing(4)
|
||||
self.set_border_width(2)
|
||||
|
||||
##TODO GTK3: statusbar no longer has resize grip methods, depracate this part
|
||||
## of Gramps Statusbar??
|
||||
## self._set_resize_grip()
|
||||
##
|
||||
## # Virtual methods
|
||||
##
|
||||
## def do_get_property(self, prop):
|
||||
## """Return the gproperty's value.
|
||||
## """
|
||||
## if prop.name == 'has-resize-grip':
|
||||
## return self.__has_resize_grip
|
||||
## else:
|
||||
## raise AttributeError, 'unknown property %s' % prop.name
|
||||
##
|
||||
## def do_set_property(self, prop, value):
|
||||
## """Set the property of writable properties.
|
||||
## """
|
||||
## if prop.name == 'has-resize-grip':
|
||||
## self.__has_resize_grip = value
|
||||
## self._set_resize_grip()
|
||||
## else:
|
||||
## raise AttributeError, 'unknown or read only property %s' % prop.name
|
||||
##
|
||||
## # Private
|
||||
##
|
||||
## def _set_resize_grip(self):
|
||||
## """Set the resize grip for the statusbar.
|
||||
##
|
||||
## Resize grip is disabled for all statusbars except the last one,
|
||||
## which is set according to the "has-resize-grip" propery.
|
||||
##
|
||||
## """
|
||||
## for bar in self.get_children():
|
||||
## bar.set_has_resize_grip(False)
|
||||
##
|
||||
## bar.set_has_resize_grip(self.get_property('has-resize-grip'))
|
||||
self.__progress = Gtk.ProgressBar()
|
||||
self.__progress.set_size_request(100, -1)
|
||||
self.__progress.hide()
|
||||
|
||||
def _get_next_id(self):
|
||||
"""Get next unused statusbar id.
|
||||
"""
|
||||
id = 1
|
||||
while id in self._bars:
|
||||
id = id + 1
|
||||
|
||||
return id
|
||||
self.__warnbtn = WarnButton()
|
||||
|
||||
# Public API
|
||||
|
||||
def insert(self, index=-1, min_width=None, ralign=False):
|
||||
"""Insert a new statusbar.
|
||||
|
||||
Create a new statusbar and insert it at the given index. Index starts
|
||||
from '0'. If index is negative the new statusbar is appended.
|
||||
The new bar_id is returned.
|
||||
|
||||
"""
|
||||
new_bar = Gtk.Statusbar()
|
||||
new_bar.show()
|
||||
self.pack_start(new_bar, True, True, 0)
|
||||
self.reorder_child(new_bar, index)
|
||||
##TODO GTK3: statusbar no longer has resize grip methods, depracate this part
|
||||
## of Gramps Statusbar??
|
||||
## self._set_resize_grip()
|
||||
|
||||
if ralign:
|
||||
frame = new_bar.get_children()[0]
|
||||
obj = frame.get_children()[0]
|
||||
# obj is HBox
|
||||
obj = obj.get_children()[0]
|
||||
##TODO GTK3: Check if following give expected alignment in statusbar
|
||||
obj.valign = Gtk.Align(value=Gtk.Align.CENTER)
|
||||
obj.halign = Gtk.Align(value=Gtk.Align.END)
|
||||
|
||||
new_bar_id = self._get_next_id()
|
||||
self._bars[new_bar_id] = new_bar
|
||||
|
||||
return new_bar_id
|
||||
|
||||
def get_context_id(self, context_description, bar_id=0):
|
||||
"""Return a new or existing context identifier.
|
||||
|
||||
The target statusbar is identified by bar_id created when statusbar
|
||||
was added.
|
||||
Existence of the bar_id is not checked as giving a wrong id is
|
||||
programming fault.
|
||||
|
||||
"""
|
||||
return self._bars[bar_id].get_context_id(context_description)
|
||||
self.__status = Gtk.Statusbar()
|
||||
self.__status.show()
|
||||
|
||||
def push(self, context_id, text, bar_id=0):
|
||||
"""Push message onto a statusbar's stack.
|
||||
|
||||
The target statusbar is identified by bar_id created when statusbar
|
||||
was added.
|
||||
Existence of the bar_id is not checked as giving a wrong id is
|
||||
programming fault.
|
||||
|
||||
"""
|
||||
# HACK: add an extra space so grip doesn't overlap
|
||||
return self._bars[bar_id].push(context_id, text + " ")
|
||||
self.__filter = Gtk.Label()
|
||||
self.__filter.set_alignment(1.0, 0.5)
|
||||
self.__filter.show()
|
||||
|
||||
def pop(self, context_id, bar_id=0):
|
||||
"""Remove the top message from a statusbar's stack.
|
||||
|
||||
The target statusbar is identified by bar_id created when statusbar
|
||||
was added.
|
||||
Existence of the bar_id is not checked as giving a wrong id is
|
||||
programming fault.
|
||||
|
||||
"""
|
||||
self._bars[bar_id].pop(context_id)
|
||||
self.pack_start(self.__warnbtn, False, True, 4)
|
||||
self.pack_start(self.__progress, False, True, 4)
|
||||
self.pack_start(self.__status, True, True, 4)
|
||||
self.pack_end(self.__filter, False, True, 4)
|
||||
|
||||
def remove(self, context_id, message_id, bar_id=0):
|
||||
"""Remove the message with the specified message_id.
|
||||
|
||||
Remove the message with the specified message_id and context_id
|
||||
from the statusbar's stack, which is identified by bar_id.
|
||||
Existence of the bar_id is not checked as giving a wrong id is
|
||||
programming fault.
|
||||
|
||||
"""
|
||||
self._bars[bar_id].remove(context_id, message_id)
|
||||
|
||||
def set_has_resize_grip(self, setting):
|
||||
"""Mirror Gtk.Statusbar functionaliy.
|
||||
"""
|
||||
self.set_property('has-resize-grip', setting)
|
||||
|
||||
def get_has_resize_grip(self):
|
||||
"""Mirror Gtk.Statusbar functionaliy.
|
||||
"""
|
||||
return self.get_property('has-resize-grip')
|
||||
def get_warning_button(self):
|
||||
"""Return the warning button widget."""
|
||||
return self.__warnbtn
|
||||
|
||||
def main(args):
|
||||
win = Gtk.Window()
|
||||
win.set_title('Statusbar test window')
|
||||
win.set_position(Gtk.WindowPosition.CENTER)
|
||||
def cb(window, event):
|
||||
Gtk.main_quit()
|
||||
win.connect('delete-event', cb)
|
||||
def get_progress_bar(self):
|
||||
"""Return the progress bar widget."""
|
||||
return self.__progress
|
||||
|
||||
vbox = Gtk.VBox()
|
||||
win.add(vbox)
|
||||
def get_context_id(self, context_description):
|
||||
"""Return a new or existing context identifier."""
|
||||
return self.__status.get_context_id(context_description)
|
||||
|
||||
statusbar = Statusbar()
|
||||
vbox.pack_end(statusbar, False, True, 0)
|
||||
|
||||
statusbar.push(1, "My statusbar")
|
||||
|
||||
my_statusbar = statusbar.insert()
|
||||
statusbar.push(1, "Testing width", my_statusbar)
|
||||
|
||||
yet_another_statusbar = statusbar.insert()
|
||||
statusbar.push(1, "A short one", yet_another_statusbar)
|
||||
def push(self, context_id, text):
|
||||
"""Push message onto a statusbar's stack."""
|
||||
return self.__status.push(context_id, text)
|
||||
|
||||
last_statusbar = statusbar.insert(ralign=True)
|
||||
statusbar.push(1, "The last statusbar",
|
||||
last_statusbar)
|
||||
|
||||
win.show_all()
|
||||
Gtk.main()
|
||||
def pop(self, context_id):
|
||||
"""Remove the top message from a statusbar's stack."""
|
||||
self.__status.pop(context_id)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
# fall back to root logger for testing
|
||||
log = logging
|
||||
sys.exit(main(sys.argv))
|
||||
def remove(self, context_id, message_id):
|
||||
"""Remove the message with the specified message_id."""
|
||||
self.__status.remove(context_id, message_id)
|
||||
|
||||
def set_filter(self, text):
|
||||
"""Set the filter status text."""
|
||||
self.__filter.set_text(text)
|
||||
|
||||
def clear_filter(self):
|
||||
"""Clear the filter status text."""
|
||||
self.__filter.set_text('')
|
||||
|
Loading…
Reference in New Issue
Block a user