def __init__(self, parent_widget): columns = [ { "key": "source", "type": GObject.TYPE_PYOBJECT }, { "key": "plugin_id", "type": str }, { "key": "toplevel", "type": bool }, { "key": "icon", "type": Gio.Icon }, { "key": "text", "type": str }, ] # setup plugin list table column_types = [c["type"] for c in columns] self.columns = [c["key"] for c in columns] self.store = Gtk.ListStore(*column_types) self.table = Gtk.TreeView.new_with_model(self.store) self.table.set_headers_visible(False) self.table.set_property("enable-search", False) #self.table.connect("cursor-changed", self.plugin_table_cursor_changed) self.table.get_selection().set_mode(Gtk.SelectionMode.NONE) checkcell = Gtk.CellRendererToggle() checkcol = Gtk.TreeViewColumn("item", checkcell) checkcol.add_attribute(checkcell, "active", self.columns.index("toplevel")) checkcell.connect("toggled", self.on_checktoplevel_enabled) icon_cell = Gtk.CellRendererPixbuf() icon_cell.set_property("height", LIST_ICON_SIZE) icon_cell.set_property("width", LIST_ICON_SIZE) icon_col = Gtk.TreeViewColumn("icon", icon_cell) icon_col.add_attribute(icon_cell, "gicon", self.columns.index("icon")) cell = Gtk.CellRendererText() col = Gtk.TreeViewColumn("item", cell) col.add_attribute(cell, "text", self.columns.index("text")) self.table.append_column(checkcol) self.table.append_column(icon_col) self.table.append_column(col) self._refresh() self.table.show() parent_widget.add(self.table) setctl = settings.GetSettingsController() setctl.connect("plugin-enabled-changed", self._refresh)
def _get_directory_sources(self): """ Return a tuple of S_sources, s_sources for directory sources directly included and for catalog inclusion respectively """ s_sources = [] S_sources = [] setctl = settings.GetSettingsController() source_config = setctl.get_config def dir_source(opt): return sources.DirectorySource(opt) def file_source(opt, depth=1): abs = os.path.abspath(os.path.expanduser(opt)) return sources.FileSource((abs, ), depth) for coll, direct in zip((s_sources, S_sources), (False, True)): for item in setctl.get_directories(direct): if not os.path.isdir(item): continue coll.append(dir_source(item)) dir_depth = source_config("DeepDirectories", "Depth") for item in source_config("DeepDirectories", "Catalog"): s_sources.append(file_source(item, dir_depth)) for item in source_config("DeepDirectories", "Direct"): S_sources.append(file_source(item, dir_depth)) return S_sources, s_sources
def get_items(self): setctl = settings.GetSettingsController() for info in plugins.get_plugin_info(): plugin_id = info["name"] if setctl.get_plugin_is_hidden(plugin_id): continue yield Plugin(info, info["localized_name"])
def _refresh_plugin_list(self, us_filter=None): "List plugins that pass text filter @us_filter or list all if None" self.store.clear() setctl = settings.GetSettingsController() if us_filter: self.plugin_list_timer.set_ms(300, self._show_focus_topmost_plugin) else: self.plugin_list_timer.invalidate() for info in self.plugin_info: plugin_id = info["name"] if setctl.get_plugin_is_hidden(plugin_id): continue enabled = setctl.get_plugin_enabled(plugin_id) name = info["localized_name"] folded_name = kupferstring.tofolded(name) desc = info["description"] text = "%s" % name if us_filter: name_score = relevance.score(name, us_filter) fold_name_score = relevance.score(folded_name, us_filter) desc_score = relevance.score(desc, us_filter) if not name_score and not fold_name_score and desc_score < 0.9: continue self.store.append((plugin_id, enabled, "kupfer-object", text))
def on_checkplugin_toggled(self, cell, path): checkcol = self.columns.index("enabled") plugin_id = self._id_for_table_path(path) it = self.store.get_iter(path) plugin_is_enabled = not self.store.get_value(it, checkcol) self.store.set_value(it, checkcol, plugin_is_enabled) setctl = settings.GetSettingsController() setctl.set_plugin_enabled(plugin_id, plugin_is_enabled)
def on_buttonkeybinding_clicked(self, widget): keystr = getkey_dialog.ask_for_key(keybindings.bind_key, screen=widget.get_screen()) if keystr: self.entrykeybinding.set_text(keystr) self.output_debug("Try set keybinding with", keystr) keybindings.bind_key(keystr) setctl = settings.GetSettingsController() setctl.set_keybinding(keystr)
def on_button_reset_keys_clicked(self, button): if self.ask_user_for_reset_keybinding(): setctl = settings.GetSettingsController() setctl.reset_keybindings() self._show_keybindings(setctl) # Unbind all before re-binding for keybind_id, target in self.KEYBINDING_TARGETS.items(): keybindings.bind_key(None, target) for keybind_id, target in self.KEYBINDING_TARGETS.items(): keystr = setctl.get_global_keybinding(keybind_id) keybindings.bind_key(keystr, target)
def _insert_sources(self, plugin_id, sources, initialize=True): if not sources: return sc = GetSourceController() setctl = settings.GetSettingsController() for src in sources: is_toplevel = setctl.get_source_is_toplevel(plugin_id, src) sc.add(plugin_id, (src, ), toplevel=is_toplevel, initialize=initialize) if initialize: self._reload_source_root()
def on_gkeybindings_row_activate(self, treeview, path, view_column): it = self.gkeybind_store.get_iter(path) keybind_id = self.gkeybind_store.get_value(it, 2) setctl = settings.GetSettingsController() curr_key = setctl.get_accelerator(keybind_id) keystr = getkey_dialog.ask_for_key(self._is_good_keystr, previous_key=curr_key, screen=treeview.get_screen()) if keystr is not None: setctl.set_accelerator(keybind_id, keystr) label = gtk.accelerator_get_label(*gtk.accelerator_parse(keystr)) self.gkeybind_store.set_value(it, 1, label)
def _load_all_plugins(self): """ Insert all plugin sources into the catalog """ from kupfer.core import plugins setctl = settings.GetSettingsController() for item in sorted(plugins.get_plugin_ids()): if not setctl.get_plugin_enabled(item): continue sources = self._load_plugin(item) self._insert_sources(item, sources, initialize=False)
def on_checktoplevel_enabled(self, cell, path): it = self.store.get_iter(path) checkcol = self.columns.index("toplevel") idcol = self.columns.index("plugin_id") srccol = self.columns.index("source") is_toplevel = not self.store.get_value(it, checkcol) plugin_id = self.store.get_value(it, idcol) src = self.store.get_value(it, srccol) sc = sources.GetSourceController() sc.set_toplevel(src, is_toplevel) setctl = settings.GetSettingsController() setctl.set_source_is_toplevel(plugin_id, src, is_toplevel) self.store.set_value(it, checkcol, is_toplevel)
def add_directory_model(self, d, store=False): have = list(os.path.normpath(row[0]) for row in self.dir_store) if d in have: self.output_debug("Ignoring duplicate directory: ", d) return else: have.append(d) d = os.path.expanduser(d) dispname = utils.get_display_path_for_bytestring(d) gicon = icons.get_gicon_for_file(d) self.dir_store.append((d, gicon, dispname)) if store: setctl = settings.GetSettingsController() setctl.set_directories(have)
def _import_hook_true(pathcomps): """@pathcomps path components to the import""" path = ".".join(pathcomps) fromlist = pathcomps[-1:] try: setctl = settings.GetSettingsController() if not setctl.get_plugin_enabled(pathcomps[-1]): raise NotEnabledError("%s is not enabled" % pathcomps[-1]) plugin = __import__(path, fromlist=fromlist) except ImportError, exc: # Try to find a fake plugin if it exists plugin = _import_plugin_fake(path, error=sys.exc_info()) if not plugin: raise pretty.print_error(__name__, "Could not import plugin '%s': %s" % (plugin.__name__, exc))
def callback(widget): setctl = settings.GetSettingsController() val_type = plugin_support.UserNamePassword backend_name = plugin_support.UserNamePassword.get_backend_name() if plugin_support.UserNamePassword.is_backend_encrypted(): information = _( "Using encrypted password storage: %s") % backend_name else: information = _("Using password storage: %s") % backend_name upass = setctl.get_plugin_config(plugin_id, key, val_type) \ or plugin_support.UserNamePassword() user_password = ask_user_credentials(upass.username, upass.password, information) if user_password: upass.username, upass.password = user_password setctl.set_plugin_config(plugin_id, key, upass, val_type)
def _load(self, sched): """Begin Data Controller work when we get application 'load' signal Load the data model from saved configuration and caches """ setctl = settings.GetSettingsController() setctl.connect("plugin-enabled-changed", self._plugin_enabled) setctl.connect("plugin-toplevel-changed", self._plugin_catalog_changed) self._load_all_plugins() D_s, d_s = self._get_directory_sources() sc = GetSourceController() sc.add(None, D_s, toplevel=True) sc.add(None, d_s, toplevel=False) sc.initialize() learn.load()
def initialize(self, plugin_name): """Init by reading from global settings and setting up callbacks""" setctl = settings.GetSettingsController() for key in self: value_type = self.setting_descriptions[key]["type"] value = setctl.get_plugin_config(plugin_name, key, value_type) if value is not None: self[key] = value elif _is_core_setting(key): default = self.setting_descriptions[key]["value"] setctl.set_plugin_config(plugin_name, key, default, value_type) setctl.connect("value-changed", self._value_changed, plugin_name) # register for unload notification if not plugin_name.startswith("core."): plugins.register_plugin_unimport_hook(plugin_name, self._disconnect_all, plugin_name)
def _refresh(self, *ignored): self.store.clear() setctl = settings.GetSettingsController() sc = sources.GetSourceController() srcs = sorted(sc.get_sources(), key=str) for src in srcs: name = str(src) plugin_id = sc.get_plugin_id_for_object(src) if not plugin_id or setctl.get_plugin_is_hidden(plugin_id): continue if not kobject_should_show(src): continue gicon = src.get_icon() toplevel = setctl.get_source_is_toplevel(plugin_id, src) self.store.append((src, plugin_id, toplevel, gicon, name))
def register_alternative(caller, category_key, id_, **kwargs): """ Register a new alternative for the category @category_key @caller: Must be the caller's plugin id (Plugin __name__ variable) @id_ is a string identifier for the object to register @kwargs are the keyed arguments for the alternative constructor Returns True with success """ caller = str(caller) category_key = str(category_key) id_ = str(id_) if category_key not in _available_alternatives: _plugin_configuration_error( caller, "Category '%s' does not exist" % category_key) return alt = _available_alternatives[category_key] id_ = caller + "." + id_ kw_set = set(kwargs) req_set = set(alt["required_keys"]) if not req_set.issubset(kw_set): _plugin_configuration_error( caller, "Configuration error for alternative '%s':" % category_key) _plugin_configuration_error(caller, "Missing keys: %s" % (req_set - kw_set)) return _alternatives[category_key][id_] = kwargs pretty.print_debug(__name__, "Registered alternative %s: %s" % (category_key, id_)) setctl = settings.GetSettingsController() setctl._update_alternatives(category_key, _alternatives[category_key], alt["filter"]) # register the alternative to be unloaded plugin_id = ".".join(caller.split(".")[2:]) if plugin_id and not plugin_id.startswith("core."): plugins.register_plugin_unimport_hook(plugin_id, _unregister_alternative, caller, category_key, id_) return True
def _update_alternative_combobox(self, category_key, combobox): """ Alternatives changed """ combobox_store = combobox.get_model() combobox_store.clear() setctl = settings.GetSettingsController() term_id = setctl.get_preferred_tool(category_key) # fill in the available alternatives alternatives = utils.locale_sort( setctl.get_valid_alternative_ids(category_key), key=lambda t: t[1]) term_iter = None for (id_, name) in alternatives: _it = combobox_store.append((name, id_)) if id_ == term_id: term_iter = _it # Update selection term_iter = term_iter or combobox_store.get_iter_first() combobox.set_sensitive(len(combobox_store) > 1) if term_iter: combobox.set_active_iter(term_iter)
def on_keybindings_row_activate(self, treeview, path, view_column): def bind_key_func(target): def bind_key(keystr): return keybindings.bind_key(keystr, target) return bind_key it = self.keybind_store.get_iter(path) keybind_id = self.keybind_store.get_value(it, 2) setctl = settings.GetSettingsController() curr_key = setctl.get_global_keybinding(keybind_id) bind_func = bind_key_func(self.KEYBINDING_TARGETS[keybind_id]) keystr = getkey_dialog.ask_for_key(bind_func, curr_key, screen=treeview.get_screen()) if keystr == '': keybindings.bind_key(None, self.KEYBINDING_TARGETS[keybind_id]) setctl.set_global_keybinding(keybind_id, keystr) self.keybind_store.set_value(it, 1, '') elif keystr is not None: setctl.set_global_keybinding(keybind_id, keystr) label = gtk.accelerator_get_label(*gtk.accelerator_parse(keystr)) self.keybind_store.set_value(it, 1, label)
def _unregister_alternative(caller, category_key, full_id_): """ Remove the alternative for category @category_key (this is done automatically at plugin unload) """ if category_key not in _available_alternatives: _plugin_configuration_error( caller, "Category '%s' does not exist" % category_key) return alt = _available_alternatives[category_key] id_ = full_id_ try: del _alternatives[category_key][id_] except KeyError: _plugin_configuration_error( caller, "Alternative '%s' does not exist" % (id_, )) return pretty.print_debug(__name__, "Unregistered alternative %s: %s" % (category_key, id_)) setctl = settings.GetSettingsController() setctl._update_alternatives(category_key, _alternatives[category_key], alt["filter"]) return True
def get_configured_terminal(): """ Return the configured Terminal object """ setctl = settings.GetSettingsController() return setctl.get_preferred_alternative('terminal')
def on_icons_small_size_changed(self, widget): setctl = settings.GetSettingsController() itr = widget.get_active_iter() if itr: val = widget.get_active_text() setctl.set_small_icon_size(val)
def on_icons_combobox_changed(self, widget): setctl = settings.GetSettingsController() itr = widget.get_active_iter() if itr: term_id = widget.get_model().get_value(itr, 1) setctl.set_preferred_tool('icon_renderer', term_id)
def on_radio_action_accel_ctrl(self, widget): if widget.get_active(): setctl = settings.GetSettingsController() setctl.set_action_accelerator_modifier('ctrl')
def on_checkusecommandkeys_toggled(self, widget): setctl = settings.GetSettingsController() setctl.set_use_command_keys(widget.get_active())
def on_button_reset_gkeys_clicked(self, button): if self.ask_user_for_reset_keybinding(): setctl = settings.GetSettingsController() setctl.reset_accelerators() self._show_gkeybindings(setctl)
def is_known_terminal_executable(exearg): setctl = settings.GetSettingsController() for id_, term in setctl.get_all_alternatives('terminal').items(): if exearg == term["argv"][0]: return True return False
def _setup_icon_renderer(sched): from kupfer.core import settings setctl = settings.GetSettingsController() setctl.connect("alternatives-changed::icon_renderer", _icon_render_change) setctl.connect("value-changed::tools.icon_renderer", _icon_render_change) _icon_render_change(setctl)
def __init__(self): """Load ui from data file""" builder = Gtk.Builder() builder.set_translation_domain(version.PACKAGE_NAME) ui_file = config.get_data_file("preferences.ui") if ui_file: builder.add_from_file(ui_file) else: self.window = None return self.window = builder.get_object("preferenceswindow") self.window.set_position(Gtk.WindowPosition.CENTER) self.window.connect("delete-event", self._close_window) self.pluglist_parent = builder.get_object("plugin_list_parent") self.dirlist_parent = builder.get_object("directory_list_parent") self.plugin_about_parent = builder.get_object("plugin_about_parent") self.preferences_notebook = builder.get_object("preferences_notebook") self.buttonremovedirectory = builder.get_object( "buttonremovedirectory") checkautostart = builder.get_object("checkautostart") checkstatusicon_gtk = builder.get_object("checkstatusicon_gtk") checkstatusicon_ai = builder.get_object("checkstatusicon_ai") combo_icons_large_size = builder.get_object("icons_large_size") combo_icons_small_size = builder.get_object("icons_small_size") checkusecommandkeys = builder.get_object("checkusecommandkeys") radio_actionaccelalt = builder.get_object("radio_actionaccelalt") radio_actionaccelctrl = builder.get_object("radio_actionaccelctrl") self.entry_plugins_filter = builder.get_object('entry_plugins_filter') self.keybindings_list_parent = builder.get_object( 'keybindings_list_parent') self.gkeybindings_list_parent = builder.get_object( 'gkeybindings_list_parent') source_list_parent = builder.get_object("source_list_parent") button_reset_keys = builder.get_object("button_reset_keys") self.sources_list_ctrl = SourceListController(source_list_parent) setctl = settings.GetSettingsController() checkautostart.set_active(self._get_should_autostart()) checkstatusicon_gtk.set_active(setctl.get_show_status_icon()) large_icon_size = setctl.get_config_int("Appearance", "icon_large_size") small_icon_size = setctl.get_config_int("Appearance", "icon_small_size") set_combobox(large_icon_size, combo_icons_large_size) set_combobox(small_icon_size, combo_icons_small_size) if supports_app_indicator(): checkstatusicon_ai.set_active(setctl.get_show_status_icon_ai()) else: checkstatusicon_ai.set_sensitive(False) label = checkstatusicon_gtk.get_label() checkstatusicon_gtk.set_label(label + " (GtkStatusIcon)") label = checkstatusicon_ai.get_label() checkstatusicon_ai.set_label(label + " (AppIndicator)") checkusecommandkeys.set_active(setctl.get_use_command_keys()) radio_actionaccelalt.set_active( setctl.get_action_accelerator_modifer() != 'ctrl') radio_actionaccelctrl.set_active( setctl.get_action_accelerator_modifer() == 'ctrl') # List store with columns (Name, ID) # Make alternative comboboxes terminal_combobox = builder.get_object("terminal_combobox") icons_combobox = builder.get_object("icons_combobox") def make_combobox_model(combobox): combobox_store = Gtk.ListStore(GObject.TYPE_STRING, GObject.TYPE_STRING) combobox.set_model(combobox_store) combobox_cell = Gtk.CellRendererText() combobox.pack_start(combobox_cell, True) combobox.add_attribute(combobox_cell, 'text', 0) make_combobox_model(terminal_combobox) make_combobox_model(icons_combobox) self._update_alternative_combobox('terminal', terminal_combobox) self._update_alternative_combobox('icon_renderer', icons_combobox) self.terminal_combobox = terminal_combobox self.icons_combobox = icons_combobox setctl.connect("alternatives-changed", self._on_alternatives_changed) # Plugin List columns = [ { "key": "plugin_id", "type": str }, { "key": "enabled", "type": bool }, { "key": "icon-name", "type": str }, { "key": "text", "type": str }, ] # setup plugin list table column_types = [c["type"] for c in columns] self.columns = [c["key"] for c in columns] self.store = Gtk.ListStore.new(column_types) self.table = Gtk.TreeView.new_with_model(self.store) self.table.set_headers_visible(False) self.table.set_property("enable-search", False) self.table.connect("cursor-changed", self.plugin_table_cursor_changed) self.table.get_selection().set_mode(Gtk.SelectionMode.BROWSE) checkcell = Gtk.CellRendererToggle() checkcol = Gtk.TreeViewColumn("item", checkcell) checkcol.add_attribute(checkcell, "active", self.columns.index("enabled")) checkcell.connect("toggled", self.on_checkplugin_toggled) icon_cell = Gtk.CellRendererPixbuf() icon_cell.set_property("height", LIST_ICON_SIZE) icon_cell.set_property("width", LIST_ICON_SIZE) icon_col = Gtk.TreeViewColumn("icon", icon_cell) icon_col.add_attribute(icon_cell, "icon-name", self.columns.index("icon-name")) cell = Gtk.CellRendererText() col = Gtk.TreeViewColumn("item", cell) col.add_attribute(cell, "text", self.columns.index("text")) self.table.append_column(checkcol) # hide icon for now #self.table.append_column(icon_col) self.table.append_column(col) self.plugin_list_timer = scheduler.Timer() self.plugin_info = utils.locale_sort( plugins.get_plugin_info(), key=lambda rec: rec["localized_name"]) self._refresh_plugin_list() self.output_debug("Standard Plugins: %d" % len(self.store)) self.table.show() self.pluglist_parent.add(self.table) # Directory List self.dir_store = Gtk.ListStore.new([str, Gio.Icon, str]) self.dir_table = Gtk.TreeView.new_with_model(self.dir_store) self.dir_table.set_headers_visible(False) self.dir_table.set_property("enable-search", False) self.dir_table.connect("cursor-changed", self.dir_table_cursor_changed) self.dir_table.get_selection().set_mode(Gtk.SelectionMode.BROWSE) icon_cell = Gtk.CellRendererPixbuf() icon_col = Gtk.TreeViewColumn("icon", icon_cell) icon_col.add_attribute(icon_cell, "gicon", 1) cell = Gtk.CellRendererText() col = Gtk.TreeViewColumn("name", cell) col.add_attribute(cell, "text", 2) cell.set_property("ellipsize", Pango.EllipsizeMode.END) self.dir_table.append_column(icon_col) self.dir_table.append_column(col) self.dir_table.show() self.dirlist_parent.add(self.dir_table) self.read_directory_settings() # global keybindings list self.keybind_table, self.keybind_store = _create_conf_keys_list() self.keybindings_list_parent.add(self.keybind_table) self.keybind_table.connect("row-activated", self.on_keybindings_row_activate) button_reset_keys.set_sensitive(keybindings.is_available()) self.keybind_table.set_sensitive(keybindings.is_available()) # kupfer interface (accelerators) keybindings list self.gkeybind_table, self.gkeybind_store = _create_conf_keys_list() self.gkeybindings_list_parent.add(self.gkeybind_table) self.gkeybind_table.connect("row-activated", self.on_gkeybindings_row_activate) # Requires GTK 3.22 try: self.gkeybindings_list_parent.set_propagate_natural_height(True) except AttributeError: pass self._show_keybindings(setctl) self._show_gkeybindings(setctl) # Connect to signals at the last point builder.connect_signals(self)