%PDF- %PDF-
Direktori : /lib/rhythmbox/plugins/alternative-toolbar/ |
Current File : //lib/rhythmbox/plugins/alternative-toolbar/alttoolbar_plugins.py |
# -*- Mode: python; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; -*- # # Copyright (C) 2015 - 2020 David Mohammed <fossfreedom@ubuntu.com> # # 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 3, 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. import gettext import re import webbrowser from alttoolbar_preferences import CoverLocale from gi.repository import GLib from gi.repository import Gio from gi.repository import Gtk from gi.repository import Pango from gi.repository import Peas from gi.repository import PeasGtk class PluginListRow(Gtk.ListBoxRow): def __init__(self, plugin, switch_callback): super(PluginListRow, self).__init__() self.plugin = plugin self._refresh = False self._switch_callback = switch_callback label1 = Gtk.Label() escape = GLib.markup_escape_text(plugin.get_name()) label1.set_markup("<b>" + escape + "</b>") label1.set_ellipsize(Pango.EllipsizeMode.END) label1.props.halign = Gtk.Align.START label1.set_has_tooltip(True) label1.props.margin_top = 5 label1.connect('query-tooltip', self._display_tooltip) label2 = Gtk.Label(plugin.get_description()) label2.set_ellipsize(Pango.EllipsizeMode.END) label2.props.halign = Gtk.Align.START label2.set_has_tooltip(True) label2.connect('query-tooltip', self._display_tooltip) label2.props.margin_bottom = 5 switch = Gtk.Switch.new() self._switch = switch switch.props.valign = Gtk.Align.CENTER sensitive = False try: if plugin.is_available(): sensitive = True switch.set_active(plugin.is_loaded()) except: pass box = Gtk.Box() box.set_orientation(Gtk.Orientation.VERTICAL) box.pack_start(label1, True, False, 0) box.pack_start(label2, True, False, 1) outerbox = Gtk.Box() outerbox.set_orientation(Gtk.Orientation.HORIZONTAL) outerbox.pack_start(Gtk.Label(" "), False, False, 0) outerbox.pack_start(box, False, False, 1) outerbox.pack_end(switch, False, False, 3) self.add(outerbox) self.outerbox = outerbox if not sensitive: self.add_error() switch.connect('notify::active', self._switch_changed) def _display_tooltip(self, label, x, y, mode, tooltip): if label.get_layout().is_ellipsized(): tooltip.set_text(label.get_text()) return True return False def _switch_changed(self, switch, *args): if self._refresh: return False self._refresh = True def delay(*args): print("switch_changed") print(switch.get_active()) self._switch_callback(switch, self.plugin) self._refresh = False GLib.timeout_add(250, delay, None) def add_error(self): icon = Gio.ThemedIcon(name="dialog-error-symbolic") error_image = Gtk.Image() error_image.props.margin = 5 error_image.set_from_gicon(icon, Gtk.IconSize.BUTTON) error_image.show_all() error_image.set_has_tooltip(True) error_image.set_tooltip_text(_('The plugin cannot be enabled')) self.outerbox.pack_end(error_image, False, False, 4) self.set_sensitive(False) def refresh(self, *args): try: if not self.plugin.is_available(): self.add_error() if self._switch.get_active() == self.plugin.is_loaded(): return self._switch.set_active(self.plugin.is_loaded()) except: self.add_error() class PluginDialog(Gtk.Dialog): def __init__(self, parent_window, has_headerbar): if has_headerbar: super(PluginDialog, self).__init__(use_header_bar=True, parent=parent_window, flags=Gtk.DialogFlags.MODAL) else: super(PluginDialog, self).__init__(parent=parent_window, flags=Gtk.DialogFlags.MODAL) self._has_headerbar = has_headerbar self._parent_window = parent_window listbox = Gtk.ListBox.new() listbox.set_sort_func(self._listbox_sort, None) self._listbox = listbox self._items = {} self._peas = Peas.Engine.get_default() plugins = self._peas.get_plugin_list() self._peas.connect_after('unload-plugin', self._on_load_unload_plugin) self._peas.connect_after('load-plugin', self._on_load_unload_plugin) for plugin in plugins: if not plugin.is_builtin() and not plugin.is_hidden(): row = PluginListRow(plugin, self._switch_callback) self._items[plugin.get_module_name()] = row listbox.add(row) # locale stuff cl = CoverLocale() cl.switch_locale(cl.Locale.RB) def extract_text(str): # remove _ and (_A) type expressions translation = gettext.gettext(str) translation = re.sub('\(..\)', '', translation, flags=re.DOTALL) translation = translation.replace('_', '') return translation toolbar = Gtk.Toolbar.new() context = toolbar.get_style_context() context.add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR) item = Gtk.ToolItem.new() btn = Gtk.Button() icon = Gio.ThemedIcon(name="preferences-system-symbolic") image = Gtk.Image() image.props.margin = 3 btn.add(image) btn.set_tooltip_text(extract_text("_Preferences")) image.set_from_gicon(icon, Gtk.IconSize.BUTTON) box = Gtk.Box() box.pack_start(btn, False, False, 0) item.add(box) toolbar.insert(item, 0) btn.connect('clicked', self._preferences_button_clicked) self._preferences_button = btn minitoolbar_box = Gtk.ButtonBox() context = minitoolbar_box.get_style_context() context.add_class('linked') minitoolbar_box.set_layout(Gtk.ButtonBoxStyle.START) btn = Gtk.Button() icon = Gio.ThemedIcon(name="preferences-system-details-symbolic") image = Gtk.Image() image.props.margin = 3 btn.add(image) btn.set_tooltip_text(extract_text("_About")) image.set_from_gicon(icon, Gtk.IconSize.BUTTON) minitoolbar_box.add(btn) minitoolbar_box.child_set_property(btn, "non-homogeneous", True) btn.connect('clicked', self._info_button_clicked) self._info_button = btn btn = Gtk.Button() icon = Gio.ThemedIcon(name="help-contents-symbolic") image = Gtk.Image() image.props.margin = 3 btn.add(image) btn.set_tooltip_text(extract_text("_Help")) image.set_from_gicon(icon, Gtk.IconSize.BUTTON) minitoolbar_box.add(btn) minitoolbar_box.child_set_property(btn, "non-homogeneous", True) btn.connect('clicked', self._help_button_clicked) self._help_button = btn item = Gtk.SeparatorToolItem.new() item.props.draw = False toolbar.insert(item, 1) toolbar.child_set_property(item, "expand", True) item = Gtk.ToolItem.new() item.add(minitoolbar_box) toolbar.insert(item, 2) contentbox = Gtk.Box() contentbox.set_orientation(Gtk.Orientation.VERTICAL) scrollwindow = Gtk.ScrolledWindow.new(None, None) scrollwindow.add(listbox) scrollwindow.props.hexpand = True scrollwindow.props.vexpand = True contentbox.pack_start(scrollwindow, True, True, 0) contentbox.pack_start(toolbar, False, False, 1) self.props.title = _("Configure Plugins") if not self._has_headerbar: self.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) else: headerbar = self.get_header_bar() headerbar.set_show_close_button(True) contentbox.show_all() area = self.get_content_area() area.add(contentbox) listbox.connect('row-selected', self._listbox_row_selected) def _on_load_unload_plugin(self, engine, plugin): module_name = plugin.get_module_name() print(module_name) if module_name in self._items: self._items[module_name].refresh() def _listbox_sort(self, row1, row2, *args): return row1.plugin.get_name().lower() > row2.plugin.get_name().lower() def _switch_callback(self, switch, plugin): value = switch.get_active() if value and not plugin.is_loaded(): self._peas.load_plugin(plugin) if not value and plugin.is_loaded(): self._peas.unload_plugin(plugin) row = switch.get_parent().get_parent() self._listbox.select_row(row) self._listbox_row_selected(_, row) def _get_preference_widget(self, row): try: ext = self._peas.create_extension(row.plugin, PeasGtk.Configurable, None) widget = ext.create_configure_widget() cl = CoverLocale() cl.switch_locale(cl.Locale.RB) return widget except: pass return None def _listbox_row_selected(self, listbox, row): if row: has_preference = False widget = self._get_preference_widget(row) if widget: has_preference = True self._preferences_button.set_sensitive(has_preference) help_link = row.plugin.get_help_uri() if help_link: self._help_button.set_sensitive(True) else: self._help_button.set_sensitive(False) def _help_button_clicked(self, *args): row = self._listbox.get_selected_row() help_link = row.plugin.get_help_uri() webbrowser.open(help_link) def _info_button_clicked(self, *args): if self._has_headerbar: dlg = Gtk.Dialog(use_header_bar=True, flags=Gtk.DialogFlags.MODAL) dlg.get_header_bar().set_show_close_button(True) else: dlg = Gtk.Dialog(flags=Gtk.DialogFlags.MODAL) dlg.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) row = self._listbox.get_selected_row() title = row.plugin.get_name() version = row.plugin.get_version() dlg.props.title = _("About this plugin") area = dlg.get_content_area() widget = Gtk.Box() widget.set_orientation(Gtk.Orientation.VERTICAL) website = row.plugin.get_website() copyright = row.plugin.get_copyright() description = row.plugin.get_description() # authors = row.plugin.get_authors() help = row.plugin.get_help_uri() pos = 0 def get_label(label): label = Gtk.Label(label) label.set_line_wrap(True) label.set_justify(Gtk.Justification.CENTER) label.set_max_width_chars(60) return label label = Gtk.Label() escape = GLib.markup_escape_text(title) label.set_markup("<b>" + escape + "</b>") label.set_justify(Gtk.Justification.CENTER) label.props.margin_bottom = 5 widget.pack_start(label, False, False, pos) pos += 1 if version: label = get_label(_("Version: ") + version) label.props.margin_bottom = 5 widget.pack_start(label, False, False, pos) pos += 1 if description: label = get_label(description) label.props.margin_bottom = 5 widget.pack_start(label, False, False, pos) pos += 1 if copyright: label = get_label(copyright) label.props.margin_bottom = 5 widget.pack_start(label, False, False, pos) pos += 1 if title == _("Alternative Toolbar"): # special case for the this plugin grid = Gtk.Grid() grid.props.halign = Gtk.Align.CENTER label = Gtk.Label(_("Developer:")) label.props.halign = Gtk.Align.END grid.attach(label, 0, 0, 1, 1) link = Gtk.Label() link.props.halign = Gtk.Align.START m = " <a href=\"https://github.com/fossfreedom\">David " \ "Mohammed</a>" link.set_markup(m) grid.attach(link, 1, 0, 1, 1) label = Gtk.Label(_("Designer:")) label.props.halign = Gtk.Align.END grid.attach(label, 0, 1, 1, 1) link = Gtk.Label() link.props.halign = Gtk.Align.START m = " <a href=\"https://github.com/me4oslav\">Georgi " \ "Karavasilev</a>" link.set_markup(m) grid.attach(link, 1, 1, 1, 1) widget.pack_start(grid, False, False, pos) grid.props.margin_bottom = 5 pos += 1 box = Gtk.Box() box.set_homogeneous(True) def launch_browser(button, uri): webbrowser.open(uri) button = Gtk.Button(_("Help")) if help: button.connect('clicked', launch_browser, help) else: button.set_sensitive(False) box.pack_start(button, False, True, 0) button = Gtk.Button(_("Homepage")) if help: button.connect('clicked', launch_browser, website) else: button.set_sensitive(False) box.pack_start(Gtk.Label(""), False, True, 1) box.pack_start(Gtk.Label(""), False, True, 2) box.pack_start(button, False, True, 3) widget.pack_start(box, False, True, pos) # pos += 1 widget.show_all() frame = Gtk.Frame.new("") frame.props.margin = 8 frame.set_shadow_type(Gtk.ShadowType.NONE) frame.add(widget) frame.show_all() area.add(frame) dlg.set_resizable(False) dlg.run() dlg.destroy() def _preferences_button_clicked(self, *args): row = self._listbox.get_selected_row() widget = self._get_preference_widget(row) if not widget: return if self._has_headerbar: dlg = Gtk.Dialog(use_header_bar=True, flags=Gtk.DialogFlags.MODAL) dlg.get_header_bar().set_show_close_button(True) else: dlg = Gtk.Dialog(flags=Gtk.DialogFlags.MODAL) dlg.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE) dlg.props.title = row.plugin.get_name() area = dlg.get_content_area() area.add(widget) dlg.set_resizable(False) dlg.run() dlg.destroy()