[kupfer] preferences: Allow configuring toplevel sources
- From: Ulrik Sverdrup <usverdrup src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [kupfer] preferences: Allow configuring toplevel sources
- Date: Sun, 9 May 2010 15:56:13 +0000 (UTC)
commit e73c5a094dcc81593db2bbe17e4418ab37301666
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date: Sun May 9 16:25:25 2010 +0100
preferences: Allow configuring toplevel sources
Add preferences configuration to decide which sources export their
objects to the top level.
data/preferences.ui | 100 ++++++++++++++++++++++++++++++++-------
kupfer/core/data.py | 1 +
kupfer/core/sources.py | 8 +++
kupfer/ui/preferences.py | 117 ++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 201 insertions(+), 25 deletions(-)
---
diff --git a/data/preferences.ui b/data/preferences.ui
index 5ef7da2..342741a 100644
--- a/data/preferences.ui
+++ b/data/preferences.ui
@@ -370,12 +370,12 @@
</packing>
</child>
<child type="tab">
- <object class="GtkLabel" id="label2">
+ <object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="label" translatable="yes">Keyboard</property>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
@@ -418,21 +418,77 @@
<property name="position">1</property>
</packing>
</child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="plugin_about_parent">
+ <property name="width_request">320</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">never</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Plugins</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkVBox" id="vbox6">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkLabel" id="labelplugininstructions">
+ <object class="GtkAlignment" id="alignment3">
<property name="visible">True</property>
- <property name="label" translatable="yes"><i>Plugins may not be unloaded at runtime</i></property>
- <property name="use_markup">True</property>
- <property name="wrap">True</property>
- <property name="width_chars">30</property>
+ <property name="top_padding">6</property>
+ <property name="left_padding">6</property>
+ <child>
+ <object class="GtkLabel" id="labelplugininstructions1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Tick the box next to a source to make sure its objects are exported to the top level of the catalog. An unticked source's contents are only available by locating its subcatalog and entering it.
+
+Note: Kupfer is an integrator, not an indexer itself. Kupfer is not designed to carry a catalog larger than a couple of thousand objects, and may become slow if overly large subcatalogs are included in the top level.</property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ <property name="width_chars">30</property>
+ </object>
+ </child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
- <property name="position">2</property>
+ <property name="position">0</property>
</packing>
</child>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="expand">False</property>
@@ -440,29 +496,39 @@
</packing>
</child>
<child>
- <object class="GtkScrolledWindow" id="plugin_about_parent">
- <property name="width_request">320</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">never</property>
+ <object class="GtkVBox" id="source_list_container">
+ <property name="height_request">350</property>
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
<child>
- <placeholder/>
+ <object class="GtkScrolledWindow" id="source_list_parent">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
</child>
</object>
<packing>
- <property name="expand">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
- <property name="position">2</property>
+ <property name="position">3</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
- <property name="label" translatable="yes">Plugins</property>
+ <property name="label" translatable="yes">Catalog</property>
</object>
<packing>
<property name="position">2</property>
diff --git a/kupfer/core/data.py b/kupfer/core/data.py
index c384034..c4ee1e2 100644
--- a/kupfer/core/data.py
+++ b/kupfer/core/data.py
@@ -485,6 +485,7 @@ class DataController (gobject.GObject, pretty.OutputMixin):
"""Load data from persistent store"""
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()
diff --git a/kupfer/core/sources.py b/kupfer/core/sources.py
index 6f5ffff..8471e91 100644
--- a/kupfer/core/sources.py
+++ b/kupfer/core/sources.py
@@ -274,6 +274,14 @@ class SourceController (pretty.OutputMixin):
if plugin_id:
self._register_plugin_objects(plugin_id, *sources)
+ def set_toplevel(self, src, toplevel):
+ assert src in self.sources, "Source is not tracked in SourceController"
+ self._invalidate_root()
+ if toplevel:
+ self.toplevel_sources.add(src)
+ else:
+ self.toplevel_sources.discard(src)
+
def _register_plugin_objects(self, plugin_id, *objects):
"Register a plugin id mapping for @objects"
for obj in objects:
diff --git a/kupfer/ui/preferences.py b/kupfer/ui/preferences.py
index d743e28..a12797c 100644
--- a/kupfer/ui/preferences.py
+++ b/kupfer/ui/preferences.py
@@ -11,11 +11,17 @@ from xdg import DesktopEntry as desktop
from kupfer import config, pretty, utils, icons, version
from kupfer import scheduler, kupferstring
-from kupfer.core import settings, plugins, relevance
+from kupfer.core import settings, plugins, relevance, sources
from kupfer.ui import keybindings
from kupfer.ui.credentials_dialog import ask_user_credentials
from kupfer.ui import getkey_dialog
+# index in GtkNotebook
+PLUGIN_LIST_PAGE = 2
+
+# List icon pixel size
+LIST_ICON_SIZE = 18
+
# A major HACK
# http://tadeboro.blogspot.com/2009/05/wrapping-adn-resizing-gtklabel.html
def _cb_allocate(label, allocation, maxwid):
@@ -30,6 +36,18 @@ def wrapped_label(text=None, maxwid=-1):
label.connect("size-allocate", _cb_allocate, maxwid)
return label
+def kobject_should_show(obj):
+ try:
+ leaf_repr = obj.get_leaf_repr()
+ except AttributeError:
+ pass
+ else:
+ if leaf_repr is None:
+ return True
+ if hasattr(leaf_repr, "is_valid") and not leaf_repr.is_valid():
+ return False
+ return True
+
class PreferencesWindowController (pretty.OutputMixin):
KEYBINDING_NAMES = {
@@ -89,6 +107,8 @@ class PreferencesWindowController (pretty.OutputMixin):
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")
+ self.sources_list_ctrl = SourceListController(source_list_parent)
setctl = settings.GetSettingsController()
checkautostart.set_active(self._get_should_autostart())
@@ -120,8 +140,8 @@ class PreferencesWindowController (pretty.OutputMixin):
checkcell.connect("toggled", self.on_checkplugin_toggled)
icon_cell = gtk.CellRendererPixbuf()
- icon_cell.set_property("height", 18)
- icon_cell.set_property("width", 18)
+ 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",
@@ -485,14 +505,14 @@ class PreferencesWindowController (pretty.OutputMixin):
hbox.pack_start(label, False)
objvbox.pack_start(hbox)
# Display information for application content-sources.
+ if not kobject_should_show(obj):
+ continue
try:
leaf_repr = obj.get_leaf_repr()
except AttributeError:
continue
if leaf_repr is None:
continue
- if hasattr(leaf_repr, "is_valid") and not leaf_repr.is_valid():
- continue
hbox = gtk.HBox()
hbox.set_property("spacing", 3)
gicon = leaf_repr.get_icon()
@@ -732,9 +752,7 @@ class PreferencesWindowController (pretty.OutputMixin):
table_path = self._table_path_for_id(plugin_id)
self.table.set_cursor(table_path)
self.table.scroll_to_cell(table_path)
- # FIXME: Revisit if we add new pages to the GtkNotebook
- self.preferences_notebook.next_page()
- self.preferences_notebook.next_page()
+ self.preferences_notebook.set_current_page(PLUGIN_LIST_PAGE)
self.window.present()
def hide(self):
@@ -780,3 +798,86 @@ def GetPreferencesWindowController():
if _preferences_window is None:
_preferences_window = PreferencesWindowController()
return _preferences_window
+
+class SourceListController (object):
+ 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": "markup", "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(self.store)
+ self.table.set_headers_visible(False)
+ self.table.set_property("enable-search", False)
+ self.table.set_rules_hint(True)
+ #self.table.connect("cursor-changed", self.plugin_table_cursor_changed)
+ self.table.get_selection().set_mode(gtk.SELECTION_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, "markup", self.columns.index("markup"))
+
+ 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 _refresh(self, *ignored):
+ self.store.clear()
+ setctl = settings.GetSettingsController()
+ sc = sources.GetSourceController()
+ srcs = sorted(sc.get_sources(), key=unicode)
+
+ for src in srcs:
+ name = unicode(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 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)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]