From c56996b6351062831e4ff4631bfb146ae6eab321 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 15 Aug 2013 22:08:23 +0000 Subject: [PATCH] Simplify status bar and fix justification of filter status svn: r22872 --- gramps/gui/displaystate.py | 24 ++-- gramps/gui/viewmanager.py | 52 ++----- gramps/gui/widgets/statusbar.py | 247 +++++++------------------------- 3 files changed, 74 insertions(+), 249 deletions(-) diff --git a/gramps/gui/displaystate.py b/gramps/gui/displaystate.py index 0a100d218..493e8b458 100644 --- a/gramps/gui/displaystate.py +++ b/gramps/gui/displaystate.py @@ -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): diff --git a/gramps/gui/viewmanager.py b/gramps/gui/viewmanager.py index a9d5dbccf..0f46b29a9 100644 --- a/gramps/gui/viewmanager.py +++ b/gramps/gui/viewmanager.py @@ -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 diff --git a/gramps/gui/widgets/statusbar.py b/gramps/gui/widgets/statusbar.py index f89bdaf9a..16461d083 100644 --- a/gramps/gui/widgets/statusbar.py +++ b/gramps/gui/widgets/statusbar.py @@ -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('')