diff options
author | natural <natural> | 2006-12-28 13:30:24 +0000 |
---|---|---|
committer | natural <natural> | 2006-12-28 13:30:24 +0000 |
commit | 6353813802ba776b05241f07cb8fee9c90310c40 (patch) | |
tree | bbdb3641c28de20c9c6164748436d7411be468ff /kberylsettings/pluginframe.py | |
parent | c8ad4394c474f9f6854904f377ab28a38172b867 (diff) | |
download | kberylsettings-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.py | 349 |
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 |