From 7bb5c75d6a22edcad1b7abfaf7ef820acb53faf5 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Wed, 16 Jan 2013 23:59:48 +0000 Subject: [PATCH] 6333: Display optional close button in gramplet bar tabs svn: r21140 --- gramps/gen/config.py | 1 + gramps/gui/configure.py | 13 +++ gramps/gui/displaystate.py | 1 + gramps/gui/widgets/grampletbar.py | 170 +++++++++++++++++++++-------- gramps/gui/widgets/grampletpane.py | 6 +- 5 files changed, 138 insertions(+), 53 deletions(-) diff --git a/gramps/gen/config.py b/gramps/gen/config.py index 43c868f48..63eab45ea 100644 --- a/gramps/gen/config.py +++ b/gramps/gen/config.py @@ -209,6 +209,7 @@ register('interface.filter', False) register('interface.filter-editor-width', 400) register('interface.filter-editor-height', 350) register('interface.fullscreen', False) +register('interface.grampletbar-close', False) register('interface.height', 500) register('interface.lds-height', 450) register('interface.lds-width', 600) diff --git a/gramps/gui/configure.py b/gramps/gui/configure.py index 406fe4e2c..86ca4e36a 100644 --- a/gramps/gui/configure.py +++ b/gramps/gui/configure.py @@ -893,6 +893,12 @@ class GrampsPreferences(ConfigureDialog): self.dbstate.db.name_formats = _nd.get_name_format(only_custom=True, only_active=False) + def cb_grampletbar_close(self, obj): + """ + Gramplet bar close button preference callback + """ + self.uistate.emit('grampletbar-close-changed') + def add_formats_panel(self, configdialog): row = 0 table = Gtk.Table(4, 4) @@ -1058,6 +1064,13 @@ class GrampsPreferences(ConfigureDialog): _("Show text in sidebar buttons (requires restart)"), row, 'interface.sidebar-text', stop=3) row += 1 + + # Gramplet bar close buttons: + self.add_checkbox(table, + _("Show close button in gramplet bar tabs"), + row, 'interface.grampletbar-close', stop=3, + extra_callback=self.cb_grampletbar_close) + row += 1 return _('Display'), table def add_text_panel(self, configdialog): diff --git a/gramps/gui/displaystate.py b/gramps/gui/displaystate.py index b6900b36c..8e3890e46 100644 --- a/gramps/gui/displaystate.py +++ b/gramps/gui/displaystate.py @@ -369,6 +369,7 @@ class DisplayState(Callback): 'filters-changed' : (str, ), 'filter-name-changed' : (str, UNITYPE, UNITYPE), 'nameformat-changed' : None, + 'grampletbar-close-changed' : None, } #nav_type to message diff --git a/gramps/gui/widgets/grampletbar.py b/gramps/gui/widgets/grampletbar.py index 2adf33cc6..41eba4299 100644 --- a/gramps/gui/widgets/grampletbar.py +++ b/gramps/gui/widgets/grampletbar.py @@ -54,6 +54,7 @@ from gi.repository import Gtk # #------------------------------------------------------------------------- from gramps.gen.const import URL_MANUAL_PAGE, VERSION_DIR +from gramps.gen.config import config from ..managedwindow import ManagedWindow from ..display import display_help, display_url from .grampletpane import (AVAILABLE_GRAMPLETS, @@ -94,15 +95,28 @@ class GrampletBar(Gtk.Notebook): self.defaults = defaults self.detached_gramplets = [] self.empty = False + self.close_buttons = [] self.set_group_name("grampletbar") self.set_show_border(False) self.set_scrollable(True) + + book_button = Gtk.Button() + box = Gtk.VBox() # Arrow is too small unless in a Vbox + arrow = Gtk.Arrow(Gtk.ArrowType.DOWN, Gtk.ShadowType.NONE) + arrow.show() + box.add(arrow) + box.show() + book_button.add(box) + book_button.set_relief(Gtk.ReliefStyle.NONE) + book_button.connect('clicked', self.__button_clicked) + book_button.show() + self.set_action_widget(book_button, Gtk.PackType.END) + self.connect('switch-page', self.__switch_page) self.connect('page-added', self.__page_added) self.connect('page-removed', self.__page_removed) self.connect('create-window', self.__create_window) - self.connect('button-press-event', self.__button_press) config_settings, opts_list = self.__load(defaults) @@ -123,6 +137,8 @@ class GrampletBar(Gtk.Notebook): self.show() self.set_current_page(config_settings[1]) + uistate.connect('grampletbar-close-changed', self.cb_close_changed) + def __load(self, defaults): """ Load the gramplets from the configuration file. @@ -333,21 +349,29 @@ class GrampletBar(Gtk.Notebook): def __create_tab_label(self, gramplet): """ - Create a tab label. + Create a tab label consisting of a label and a close button. """ - label = Gtk.Label() + tablabel = TabLabel(gramplet, self.__delete_clicked) + if hasattr(gramplet.pui, "has_data"): - if gramplet.pui.has_data: - label.set_text("%s" % gramplet.title) - else: - label.set_text(gramplet.title) + tablabel.set_has_data(gramplet.pui.has_data) else: # just a function; always show yes it has data - label.set_text("%s" % gramplet.title) - - label.set_use_markup(True) - label.set_tooltip_text(gramplet.tname) - label.show_all() - return label + tablabel.set_has_data(True) + + if config.get('interface.grampletbar-close'): + tablabel.use_close(True) + else: + tablabel.use_close(False) + + return tablabel + + def cb_close_changed(self): + """ + Close button preference changed. + """ + for gramplet in self.get_children(): + tablabel = self.get_tab_label(gramplet) + tablabel.use_close(config.get('interface.grampletbar-close')) def __delete_clicked(self, button, gramplet): """ @@ -421,47 +445,39 @@ class GrampletBar(Gtk.Notebook): gramplet.detached_window.close() gramplet.detached_window = None - def __button_press(self, widget, event): + def __button_clicked(self, button): """ - Called when a button is pressed in the tabs section of the GrampletBar. + Called when the drop-down button is clicked. """ - if is_right_click(event): - menu = Gtk.Menu() + menu = Gtk.Menu() - ag_menu = Gtk.MenuItem(label=_('Add a gramplet')) - nav_type = self.pageview.navigation_type() - skip = self.all_gramplets() - gramplet_list = GET_GRAMPLET_LIST(nav_type, skip) + ag_menu = Gtk.MenuItem(label=_('Add a gramplet')) + nav_type = self.pageview.navigation_type() + skip = self.all_gramplets() + gramplet_list = GET_GRAMPLET_LIST(nav_type, skip) + gramplet_list.sort() + self.__create_submenu(ag_menu, gramplet_list, self.__add_clicked) + ag_menu.show() + menu.append(ag_menu) + + if not (self.empty or config.get('interface.grampletbar-close')): + rg_menu = Gtk.MenuItem(label=_('Remove a gramplet')) + gramplet_list = [(gramplet.title, gramplet.gname) + for gramplet in self.get_children() + + self.detached_gramplets] gramplet_list.sort() - self.__create_submenu(ag_menu, gramplet_list, self.__add_clicked) - ag_menu.show() - menu.append(ag_menu) + self.__create_submenu(rg_menu, gramplet_list, + self.__remove_clicked) + rg_menu.show() + menu.append(rg_menu) - if not self.empty: - rg_menu = Gtk.MenuItem(label=_('Remove a gramplet')) - gramplet_list = [(gramplet.title, gramplet.gname) - for gramplet in self.get_children() + - self.detached_gramplets] - gramplet_list.sort() - self.__create_submenu(rg_menu, gramplet_list, - self.__remove_clicked) - rg_menu.show() - menu.append(rg_menu) + rd_menu = Gtk.MenuItem(label=_('Restore default gramplets')) + rd_menu.connect("activate", self.__restore_clicked) + rd_menu.show() + menu.append(rd_menu) - rd_menu = Gtk.MenuItem(label=_('Restore default gramplets')) - rd_menu.connect("activate", self.__restore_clicked) - rd_menu.show() - menu.append(rd_menu) - - menu.show_all() - #GTK3 does not show the popup, workaround: pass position function - menu.popup(None, None, - lambda menu, data: (event.get_root_coords()[0], - event.get_root_coords()[1], True), - None, event.button, event.time) - return True - - return False + menu.show_all() + menu.popup(None, None, cb_menu_position, button, 0, 0) def __create_submenu(self, main_menu, gramplet_list, callback_func): """ @@ -651,3 +667,61 @@ class DetachedWindow(ManagedWindow): self.gramplet.detached_window = None self.gramplet.reparent(self.grampletbar) ManagedWindow.close(self, *args) + +#------------------------------------------------------------------------- +# +# TabLabel class +# +#------------------------------------------------------------------------- +class TabLabel(Gtk.HBox): + """ + Create a tab label consisting of a label and a close button. + """ + def __init__(self, gramplet, callback): + Gtk.HBox.__init__(self) + + self.text = gramplet.title + self.set_spacing(4) + + self.label = Gtk.Label() + self.label.set_tooltip_text(gramplet.tname) + self.label.show() + + self.closebtn = Gtk.Button() + image = Gtk.Image() + image.set_from_stock(Gtk.STOCK_CLOSE, Gtk.IconSize.MENU) + self.closebtn.connect("clicked", callback, gramplet) + self.closebtn.set_image(image) + self.closebtn.set_relief(Gtk.ReliefStyle.NONE) + + self.pack_start(self.label, True, True, 0) + self.pack_end(self.closebtn, False, False, 0) + + def set_has_data(self, has_data): + """ + Set the label to indicate if the gramplet has data. + """ + if has_data: + self.label.set_text("%s" % self.text) + self.label.set_use_markup(True) + else: + self.label.set_text(self.text) + + def use_close(self, use_close): + """ + Display the cose button according to user preference. + """ + if use_close: + self.closebtn.show() + else: + self.closebtn.hide() + +def cb_menu_position(menu, button): + """ + Determine the position of the popup menu. + """ + ret_val, x_pos, y_pos = button.get_window().get_origin() + x_pos += button.get_allocation().x + y_pos += button.get_allocation().y + button.get_allocation().height + + return (x_pos, y_pos, False) diff --git a/gramps/gui/widgets/grampletpane.py b/gramps/gui/widgets/grampletpane.py index a4fa62549..92bc889b2 100644 --- a/gramps/gui/widgets/grampletpane.py +++ b/gramps/gui/widgets/grampletpane.py @@ -716,11 +716,7 @@ class GuiGramplet(object): if isinstance(self.pane, Gtk.Notebook): if self.pane.get_tab_label(self): label = self.pane.get_tab_label(self) - if value: - label.set_text("%s" % self.title) - label.set_use_markup(True) - else: - label.set_text(self.title) + label.set_has_data(value) class GridGramplet(GuiGramplet): """