summaryrefslogtreecommitdiff
path: root/kberylsettings/pluginframe.py
diff options
context:
space:
mode:
authornatural <natural>2006-12-28 13:30:24 +0000
committernatural <natural>2006-12-28 13:30:24 +0000
commit6353813802ba776b05241f07cb8fee9c90310c40 (patch)
treebbdb3641c28de20c9c6164748436d7411be468ff /kberylsettings/pluginframe.py
parentc8ad4394c474f9f6854904f377ab28a38172b867 (diff)
downloadkberylsettings-6353813802ba776b05241f07cb8fee9c90310c40.tar.gz
kberylsettings-6353813802ba776b05241f07cb8fee9c90310c40.tar.bz2
Support for plugin categories.
Fixed scroll view layouts. Many other bug fixes and enhancements.
Diffstat (limited to 'kberylsettings/pluginframe.py')
-rw-r--r--kberylsettings/pluginframe.py349
1 files changed, 203 insertions, 146 deletions
diff --git a/kberylsettings/pluginframe.py b/kberylsettings/pluginframe.py
index a867fee..d7e4e79 100644
--- a/kberylsettings/pluginframe.py
+++ b/kberylsettings/pluginframe.py
@@ -1,70 +1,55 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-""" kberylsettings.pluginframe -> defines the left side plugin views.
+""" kberylsettings.pluginframe -> defines the left side plugin views
and search view.
"""
from re import sub
-from qt import QLabel, QListViewItem
+from qt import QLabel
from kdecore import KIcon, i18n
from kberylsettings.beryl import Setting
from kberylsettings.lib import Signals, icon, iconLoader
-from kberylsettings.widget import Frame, ListView, ValueListViewItem, \
- WidgetStack
+from kberylsettings.widget import BasicListView, Frame, ValueListViewItem, \
+ WidgetStack
class PluginFrame(WidgetStack):
- """ PluginFrame -> stack with Icon View, Tree View, and Search widget.
+ """ PluginFrame -> stack with various plugin views and search widget.
"""
- iconPageId, treePageId, searchPageId = range(3)
-
+ iconPageId, treePageId, searchPageId, categoryPageId = pageIds = range(4)
+ modePages = (
+ (iconPageId, '&Icon View'),
+ (treePageId, '&Tree View'),
+ ## search does not have a mode menu
+ ## entry selectable by the user.
+ (categoryPageId, '&Category View')
+ )
+
def __init__(self, parent):
WidgetStack.__init__(self, parent)
- self.buildWidgets()
- self.buildConnections()
-
- def buildWidgets(self):
- """ builds widgets on this instance
-
- @return None
- """
- self.iconView = PluginIconView(self)
- self.treeView = PluginTreeView(self)
- self.searchView = SearchView(self)
- self.addWidget(self.iconView, self.iconPageId)
- self.addWidget(self.treeView, self.treePageId)
- self.addWidget(self.searchView, self.searchPageId)
-
- def buildConnections(self):
- """ build the connections for this instance
-
- @return None
- """
- root = self.topLevelWidget()
+ pages = (IconView(self), TreeView(self), SearchView(self),
+ CategoryView(self))
+ addWidget = self.addWidget
+ for pageId, page in zip(self.pageIds, pages):
+ addWidget(page, pageId)
connect = self.connect
+ root = self.topLevelWidget()
connect(root, Signals.viewModeChanged, self.raiseWidget)
- connect(root, Signals.iconSizeChanged, self.iconView.onIconSize)
- connect(root, Signals.berylContextChanged, self.searchView.rebuildIndex)
- connect(self.searchView, Signals.pluginAbout, root, Signals.pluginAbout)
- connect(self.searchView, Signals.showSettings, Signals.showSettings)
- for view in (self.iconView, self.treeView):
- connect(view, Signals.showSettings, Signals.showSettings)
- connect(view, Signals.berylSettingChanged, root.onContextChanged)
- connect(view, Signals.pluginAbout, root, Signals.pluginAbout)
- connect(view, Signals.statusMessage, root.showMessage)
- connect(root, Signals.berylContextChanged, view.onBerylContext)
- connect(root, Signals.berylPluginEnabled, view.enablePluginItem)
-
- def showSearch(self, value):
- """ displays the search page and tickles it with the search value
-
- @return None
- """
- self.raiseWidget(self.searchPageId)
- self.searchView.showKeywords(value)
+ for page in pages:
+ connect(page, Signals.berylSettingChanged, root.onContextChanged)
+ connect(page, Signals.showAbout, root, Signals.showAbout)
+ connect(page, Signals.showSettings, root, Signals.showSettings)
+ connect(page, Signals.showGroups, root, Signals.showGroups)
+ connect(page, Signals.statusMessage, root.showMessage)
+ try:
+ connect(root, Signals.berylContextChanged, page.onBerylContext)
+ connect(root, Signals.berylPluginEnabled, page.enablePluginItem)
+ connect(root, Signals.selectPrevious, page.selectPluginItem)
+ except (AttributeError, ):
+ pass
class SearchView(Frame):
@@ -76,14 +61,15 @@ class SearchView(Frame):
self.index = {}
self.loader = iconLoader()
self.keywordLabel = QLabel(i18n('Keywords:'), self)
- self.keywordsList = ListView(self)
- configList(self.keywordsList)
+ self.keywordsList = keywordsList = BasicListView(self)
self.resultsLabel = QLabel(i18n('Results:'), self)
- self.resultsList = ListView(self)
- configList(self.resultsList)
- self.connect(self.keywordsList, Signals.itemSelected, self.showResults)
- self.connect(self.resultsList, Signals.itemSelected, self.emitResult)
-
+ self.resultsList = resultsList = BasicListView(self)
+ connect = self.connect
+ connect(keywordsList, Signals.itemSelected, self.showResults)
+ connect(resultsList, Signals.itemSelected, self.emitResult)
+ root = self.topLevelWidget()
+ connect(root, Signals.searchInput, self.showKeywords)
+ connect(root, Signals.berylContextChanged, self.rebuildIndex)
def rebuildIndex(self, context):
""" reconstructs the search 'index' given a berylsetting context
@@ -96,7 +82,8 @@ class SearchView(Frame):
"""
index = self.index
index.clear()
- for p in context.plugins:
+ itemKeywords = self.itemKeywords
+ for p in context.plugins[::-1]:
for key in itemKeywords(p):
seq = index.setdefault(key, [])
seq.append((p, None))
@@ -105,6 +92,17 @@ class SearchView(Frame):
seq = index.setdefault(key, [])
seq.append((p, s))
+ def itemKeywords(self, obj):
+ """ creates a list of keywords for the given berylsettings object
+
+ @param obj berylsettings Plugin or Setting instance
+ @return list of keywords
+ """
+ values = [obj.ShortDesc, obj.LongDesc, ] + \
+ obj.ShortDesc.split() + \
+ obj.LongDesc.split()
+ return [sub('\W|_', ' ', v) for v in values]
+
def showKeywords(self, text):
""" displays keywords from the index that match the given text
@@ -153,28 +151,34 @@ class SearchView(Frame):
"""
plugin, setting = item.value
if setting is None:
- self.emit(Signals.pluginAbout, (plugin, ))
+ self.emit(Signals.showAbout, (plugin, ))
else:
self.emit(Signals.showSettings, (plugin, Setting(setting), ))
-class PluginView(ListView):
- """ PluginView -> mixin for shared view functionality
+class BasicPluginView(BasicListView):
+ """ BasicPluginView -> mixin for shared view functionality
"""
def __init__(self, parent):
- ListView.__init__(self, parent)
- configList(self)
+ BasicListView.__init__(self, parent)
self.loader = iconLoader()
- self.connect(self, Signals.itemSelected, self.onSelected)
+ self.connect(self, Signals.itemClicked, self.onItemClick)
- def addPlugins(self):
+ def selectPluginItem(self, plugin, setting):
+ match = (plugin, setting)
+ for item in self:
+ if item.value == match:
+ self.setCurrentItem(item)
+ return
+
+ def addItems(self):
""" adds list view items for every plugin in context
@return None
"""
active = self.context.active
- for plugin in self.context.plugins:
+ for plugin in self.context.plugins[::-1]:
self.listItem(plugin, active)
def listItem(self, plugin, active):
@@ -184,13 +188,17 @@ class PluginView(ListView):
@param active sequence of active plugin names
@return QListViewItem instance
"""
- item = self.findItem(plugin.ShortDesc, 0)
+ item = None
+ for i in self:
+ p, s = i.value
+ if p and p.Name == plugin.Name and s is None:
+ item = i
+ break
if not item:
- item = QListViewItem(self, plugin.ShortDesc)
- item.setVisible(True)
+ item = ValueListViewItem(self, plugin.ShortDesc, (None, None))
+ item.value = (plugin, None)
item.setVisible(plugin.Name in active)
item.setPixmap(0, plugin.icon(self.iconSize, self.loader))
- item.setText(0, plugin.ShortDesc)
return item
def onBerylContext(self, context):
@@ -200,7 +208,7 @@ class PluginView(ListView):
@return None
"""
self.context = context
- self.addPlugins()
+ self.addItems()
def enablePluginItem(self, plugin, enable):
""" toggle the enabled state of a plugin list view item
@@ -208,19 +216,22 @@ class PluginView(ListView):
@param index position of plugin within plugins list
@return None
"""
- for item in [i for i in self if i.text(0)==plugin.ShortDesc]:
- item.setVisible(enable)
+ for item in self:
+ p, s = item.value
+ if p == plugin and s is None:
+ item.setVisible(enable)
-class PluginIconView(PluginView):
- """ PluginIconView -> icon list view of plugins
+class IconView(BasicPluginView):
+ """ IconView -> icon list view of plugins
"""
- iconSize = 32
+ iconSize = KIcon.SizeMedium
def __init__(self, parent):
- PluginView.__init__(self, parent)
- self.selectedPlugin = None
+ BasicPluginView.__init__(self, parent)
+ root = self.topLevelWidget()
+ self.connect(root, Signals.iconSizeChanged, self.onIconSize)
def onIconSize(self, size):
""" update the icon size
@@ -230,71 +241,80 @@ class PluginIconView(PluginView):
"""
self.iconSize = size
for item in self:
- plugin = self.context.plugin(item.text(0))
+ plugin, setting = item.value
if plugin:
item.setPixmap(0, plugin.icon(size, self.loader))
else:
- item.setPixmap(0, Setting.icon(item.text(0), size))
+ item.setPixmap(0, Setting.icon(setting, size))
- def onSelected(self, item):
+ def onItemClick(self, item):
""" emit a signal if a plugin item is selected
@param item QListViewItem instance
@return None
"""
- plugin = self.context.plugin(item.text(0))
- text = item.text(0)
- if plugin:
- self.navToSettings(plugin)
- self.emit(Signals.pluginAbout, (plugin, ))
+ if not item:
+ return
+ plugin, setting = item.value
+ if plugin and not setting:
+ self.showSettingItems(plugin)
+ self.emit(Signals.showAbout, (plugin, ))
elif item == self.firstChild():
- for item in self:
- plugin = self.context.plugin(item.text(0))
- if plugin:
- item.setVisible(True)
- else:
- item.setVisible(False)
+ self.showPlugins()
else:
- args = (self.selectedPlugin, str(text), )
- self.emit(Signals.showSettings, args)
+ self.emit(Signals.showSettings, (plugin, setting))
- def navToSettings(self, plugin):
- """ needs to be renamed and reworked
-
- """
- self.emit(Signals.statusMessage, ('%s.navToSettings(%r)' % (self.__class__.__name__, plugin), ))
- self.selectedPlugin = plugin
- groups = plugin.settings
- keys = groups.keys()
- keys.sort()
- for key in keys:
- label = key #Setting.label(key)
- sub = self.findItem(label, 0)
- if not sub:
- sub = QListViewItem(self, self.lastItem(), label, )
- sub.setPixmap(0, Setting.icon(key, self.iconSize))
+ def showPlugins(self):
+ active = self.context.active
+ for item in self:
+ plugin, setting = item.value
+ if plugin and plugin.Name in active and not setting:
+ item.setVisible(True)
+ else:
+ item.setVisible(False)
- back = self.findItem(i18n('Back'), 0)
- if not back:
- back = QListViewItem(self, i18n('Back'))
+ def backItem(self):
+ back = self.findItem(i18n('Back'), 0)
+ if back is None:
+ back = ValueListViewItem(self, i18n('Back'), (None, None))
back.setPixmap(0, icon('back', size=self.iconSize))
+ return back
+
+ def showSettingItems(self, plugin):
+ keys = plugin.settings.keys()
+ keys.sort()
+ back = self.backItem()
+ back.setVisible(True)
+
+ settings = []
for item in self:
- plugin = self.context.plugin(item.text(0))
- if plugin or (item.text(0) not in keys and item != back):
+ p, s = item.value
+ if p and s:
+ if s in keys:
+ item.setVisible(True)
+ item.value = (plugin, s)
+ settings.append(s)
+ else:
+ item.setVisible(False)
+ elif p and not s:
item.setVisible(False)
- else:
- item.setVisible(True)
+
+ for key in keys[::-1]:
+ if key not in settings:
+ sub = ValueListViewItem(self, key, (plugin, key))
+ sub.setPixmap(0, Setting.icon(key, self.iconSize))
+ sub.moveItem(back)
-class PluginTreeView(PluginView):
- """ PluginTreeView -> tree list view of plugins
+class TreeView(BasicPluginView):
+ """ TreeView -> tree list view of plugins
"""
- iconSize = 16
+ iconSize = KIcon.SizeSmall
def __init__(self, parent):
- PluginView.__init__(self, parent)
+ BasicPluginView.__init__(self, parent)
self.setRootIsDecorated(True)
def listItem(self, plugin, active):
@@ -305,56 +325,93 @@ class PluginTreeView(PluginView):
@param size icon size
@return QListViewItem instance with children
"""
- item = PluginView.listItem(self, plugin, active)
+ item = BasicPluginView.listItem(self, plugin, active)
groups = plugin.settings
keys = groups.keys()
keys.sort()
-
child = item.firstChild()
while child:
item.takeItem(child)
child = item.firstChild()
-
for key in keys:
- sub = QListViewItem(item, key)
+ sub = ValueListViewItem(item, key, (plugin, key))
sub.setPixmap(0, Setting.icon(key, self.iconSize))
return item
- def onSelected(self, item):
+ def onItemClick(self, item):
""" emit a signal if a plugin item is selected
@param item QListViewItem instance
@return None
"""
- plugin = self.context.plugin(item.text(0))
- if plugin:
- self.emit(Signals.pluginAbout, (plugin, ))
+ if not item:
+ return
+ plugin, setting = item.value
+ if plugin and setting:
+ self.emit(Signals.showSettings, (plugin, setting))
else:
- plugin = self.context.plugin(item.parent().text(0))
- name = str(item.text(0))
- self.emit(Signals.showSettings, (plugin, name))
+ self.emit(Signals.showAbout, (plugin, ))
-def configList(obj):
- """ configures a ListView with a single column, no sorting, hidden
- header and no horizontal scrollbar.
+class CategoryView(BasicPluginView):
+ """ CategoryView -> tree list view of plugins by category
- @param obj KListView or QListView instance
- @return None
"""
- obj.addColumn('')
- obj.setSorting(-1)
- obj.header().hide()
- obj.setHScrollBarMode(obj.AlwaysOff)
+ iconSize = KIcon.SizeMedium
+ def __init__(self, parent):
+ BasicPluginView.__init__(self, parent)
+ self.setRootIsDecorated(True)
-def itemKeywords(obj):
- """ creates a list of keywords for the given berylsettings object
+ def onItemClick(self, item):
+ """ emit appropriate signal when plugin or category selected
- @param obj berylsettings Plugin or Setting instance
- @return list of keywords
- """
- values = [obj.ShortDesc, obj.LongDesc, ] + \
- obj.ShortDesc.split() + \
- obj.LongDesc.split()
- return [sub('\W|_', ' ', v) for v in values]
+ @param item QListViewItem instance
+ @return None
+ """
+ if not item:
+ return
+ plugin, setting = item.value
+ if plugin:
+ self.emit(Signals.showGroups, (plugin, ))
+
+ def addItems(self):
+ """ adds list view items for each category and plugin in context
+
+ @return None
+ """
+ active = self.context.active
+ for category in self.context.categories[::-1]:
+ plugins = [p for p in category.plugins[::-1] if p.Name in active]
+ catitem = self.categoryItem(category)
+ catitem.setVisible(bool(plugins))
+ for plugin in plugins:
+ if plugin.Name in active:
+ self.pluginItem(plugin, catitem)
+
+ def categoryItem(self, category):
+ """ create a list view item for a category
+
+ @param category
+ @return QListViewItem instance
+ """
+ desc = category.ShortDesc
+ item = self.findItem(desc, 0)
+ if not item:
+ item = ValueListViewItem(self, desc, (None, None))
+ item.setPixmap(0, category.icon(self.iconSize, self.loader))
+ return item
+
+ def pluginItem(self, plugin, parent):
+ """ create a list view item for a plugin
+
+ @param category
+ @return QListViewItem instance
+ """
+ for item in [i for i in self if i.parent() == parent]:
+ if item.value[0].Name == plugin.Name:
+ item.value = (plugin, None)
+ return item
+ item = ValueListViewItem(parent, plugin.ShortDesc, (plugin, None))
+ item.setPixmap(0, plugin.icon(self.iconSize, self.loader))
+ return item