summaryrefslogtreecommitdiff
path: root/kberylsettings
diff options
context:
space:
mode:
authornatural <natural>2006-12-19 13:03:14 +0000
committernatural <natural>2006-12-19 13:03:14 +0000
commite87833f32ea631dab7391484f0f89bedf669b80c (patch)
tree2a66917ce2bad8f7d6619ebbccf0d37598f12f22 /kberylsettings
parent99b44818d60794aae11dca5f67722ab32c98f137 (diff)
downloadkberylsettings-e87833f32ea631dab7391484f0f89bedf669b80c.tar.gz
kberylsettings-e87833f32ea631dab7391484f0f89bedf669b80c.tar.bz2
Support for basic setting saves. Other refactorings and fixes.
Diffstat (limited to 'kberylsettings')
-rw-r--r--kberylsettings/beryl.py12
-rw-r--r--kberylsettings/contentframe.py87
-rw-r--r--kberylsettings/lib.py11
-rw-r--r--kberylsettings/main.py33
-rw-r--r--kberylsettings/plugindialog.py10
-rw-r--r--kberylsettings/pluginframe.py8
-rw-r--r--kberylsettings/settingframe.py158
-rw-r--r--kberylsettings/settingwidget.py361
8 files changed, 488 insertions, 192 deletions
diff --git a/kberylsettings/beryl.py b/kberylsettings/beryl.py
index ba8a791..8814b68 100644
--- a/kberylsettings/beryl.py
+++ b/kberylsettings/beryl.py
@@ -83,13 +83,18 @@ class Context(QObject):
general = property(getGeneral)
def write(self):
- """ saves the beryl context and messages the extension to
- reload the new settings.
+ """ saves the beryl context
@return None
"""
self.emit(Signals.statusMessage, ('Saving Beryl settings....', ))
self.context.write()
+
+ def reload(self):
+ """ messages the extension to reload the new settings
+
+ @return None
+ """
berylsettings.send_reload()
self.emit(Signals.statusMessage, ('Beryl settings reloaded.', ))
@@ -205,6 +210,9 @@ class Setting:
def __getattr__(self, value):
return getattr(self.setting, value)
+ def set(self, value):
+ self.setting.Value = value
+
def icon(cls, value, size):
name = cls.iconNameMap.get(str(value), cls.iconNameMap['Bool'])
return icon(name, size=size)
diff --git a/kberylsettings/contentframe.py b/kberylsettings/contentframe.py
index 72155b3..4e43628 100644
--- a/kberylsettings/contentframe.py
+++ b/kberylsettings/contentframe.py
@@ -5,11 +5,11 @@
"""
from os.path import abspath
-from qt import Qt, QFrame, QLabel, QHBoxLayout, QScrollView, QVBoxLayout
-from kdecore import KIcon, KIconLoader
-from kdeui import KStdGuiItem, KPushButton
+from qt import Qt, QFrame, QLabel, QHBoxLayout, QScrollView, QVBoxLayout, QStringList
+from kdecore import KIcon
+from kdeui import KStdGuiItem, KPushButton, KMessageBox
-from kberylsettings.lib import App, Signals, buildPart
+from kberylsettings.lib import App, Signals, buildPart, iconLoader
from kberylsettings.settingframe import SettingFrame
from kberylsettings.widget import Frame, WidgetStack
@@ -23,7 +23,7 @@ class ContentFrame(WidgetStack):
def __init__(self, parent):
WidgetStack.__init__(self, parent)
- self.loader = KIconLoader(self.__class__.__name__)
+ self.loader = iconLoader()
self.buildAboutPage()
self.buildSettingsPage()
self.buildConnections()
@@ -51,10 +51,7 @@ class ContentFrame(WidgetStack):
layout.addWidget(self.pluginIconLabel)
layout.addWidget(self.pluginNameLabel, 100)
- self.settingsMain = QFrame(self)
- self.settingsMain.settingsWidgets = []
- layout = QVBoxLayout(self.settingsMain)
-
+ self.settingsMain = SettingsMainFrame(self)
self.settingsScroller = ContentScroll(self.settingsPage, self.settingsMain)
if not App.debug:
self.settingsScroller.setFrameShape(Frame.NoFrame)
@@ -68,10 +65,14 @@ class ContentFrame(WidgetStack):
return button
self.helpButton = contentButton('help')
+ self.helpButton.setEnabled(False)
self.defaultsButton = contentButton('defaults')
+ self.defaultsButton.setEnabled(False)
layout.addStretch(100)
self.applyButton = contentButton('apply')
+ #self.applyButton.setEnabled(False)
self.resetButton = contentButton('reset')
+ self.resetButton.setEnabled(False)
self.addWidget(self.settingsPage, self.settingsPageId)
def buildConnections(self):
@@ -79,9 +80,13 @@ class ContentFrame(WidgetStack):
@return None
"""
- self.connect(self.helpButton, Signals.clicked, self.settingHelp)
- self.connect(self.defaultsButton, Signals.clicked, self.settingDefaults)
- self.connect(self.applyButton, Signals.clicked, self.settingApply)
+ connect = self.connect
+ connect(self.helpButton, Signals.clicked, self.settingHelp)
+ connect(self.defaultsButton, Signals.clicked, self.settingDefaults)
+ connect(self.applyButton, Signals.clicked, self.settingApply)
+ root = self.topLevelWidget()
+ connect(self, Signals.berylSettingChanged, root.onSettingChanged)
+ connect(self, Signals.statusMessage, root.showMessage)
def showAbout(self, plugin):
""" displays the About Plugin page with information from the plugin
@@ -109,27 +114,16 @@ class ContentFrame(WidgetStack):
@param arg setting name or setting section name
@return None
"""
- self.settingsMain.hide()
- for widget in self.settingsMain.settingsWidgets:
- widget.close()
- layout = self.settingsMain.layout()
- layout.deleteAllItems()
+ ico = plugin.icon(KIcon.SizeLarge, self.loader)
+ self.pluginIconLabel.setPixmap(ico)
if arg in plugin.settings:
settings = plugin.settings[arg]
extra = ' - %s' % (arg, )
else:
settings = [arg, ]
extra = ''
- ico = plugin.icon(KIcon.SizeLarge, self.loader)
- self.pluginIconLabel.setPixmap(ico)
self.pluginNameLabel.setText('<b>%s%s</b>' % (plugin.ShortDesc, extra))
- for setting in settings:
- frame = SettingFrame(self.settingsMain, setting)
- self.settingsMain.settingsWidgets.append(frame)
- layout.addWidget(frame, 0, Qt.AlignTop)
- frame.show()
- layout.addStretch(100)
- self.settingsMain.show()
+ self.settingsMain.addSettings(plugin, settings)
self.raiseWidget(self.settingsPageId)
def settingHelp(self):
@@ -146,6 +140,47 @@ class ContentFrame(WidgetStack):
""" not implemented
"""
+ frame = self.settingsPage
+ widgets = frame.queryList('BaseSettingWidget')
+ exceptions = []
+ for widget in widgets:
+ try:
+ widget.setting.set(widget.value())
+ print '****', widget.setting.ShortDesc, widget.setting.Value
+
+ except (Exception, ), exc:
+ exceptions.append((widget.plugin.Name, widget.setting.Name, exc))
+ if exceptions:
+ exclist = QStringList()
+ for exc in exceptions:
+ exclist.append('Plugin:%s Setting:%s Exception:%s' % exc)
+ ## KMessageBox.errorList isn't available!
+ KMessageBox.informationList(None, 'Exceptions Saving Settings',
+ exclist)
+ self.emit(Signals.statusMessage, ('Saving settings...', ))
+ self.emit(Signals.berylSettingChanged, ())
+
+class SettingsMainFrame(QFrame):
+ def __init__(self, parent):
+ QFrame.__init__(self, parent)
+ self.settingFrames = []
+ layout = QVBoxLayout(self)
+
+ def addSettings(self, plugin, settings):
+ self.clearFrames()
+ layout = self.layout()
+ for setting in settings:
+ frame = SettingFrame(self, plugin, setting)
+ self.settingFrames.append(frame)
+ layout.addWidget(frame, 0, Qt.AlignTop)
+ frame.show()
+ layout.addStretch(100)
+
+ def clearFrames(self):
+ for widget in self.settingFrames:
+ widget.close(True)
+ self.layout().deleteAllItems()
+ self.settingFrames = []
class ContentScroll(QScrollView):
diff --git a/kberylsettings/lib.py b/kberylsettings/lib.py
index 8a2d795..33c0ca0 100644
--- a/kberylsettings/lib.py
+++ b/kberylsettings/lib.py
@@ -57,6 +57,13 @@ class Slots:
close = SLOT('close()')
+def iconLoader():
+ """ returns the global icon loader
+
+ @return KIconLoader instance
+ """
+ return KGlobal.instance().iconLoader()
+
def icon(name, group=KIcon.NoGroup, size=KIcon.SizeSmall):
""" loads pixmap by name
@@ -73,7 +80,7 @@ def icon(name, group=KIcon.NoGroup, size=KIcon.SizeSmall):
return iconCache[(name, size)]
except (KeyError, ):
pass
- ico = KGlobal.instance().iconLoader().loadIcon(name, group)
+ ico = iconLoader().loadIcon(name, group)
img = ico.convertToImage()
pix = iconCache[(name, size)] = QPixmap()
pix.convertFromImage(img.smoothScale(size, size, QImage.ScaleMin))
@@ -88,7 +95,7 @@ def iconSet(name, group=KIcon.NoGroup, size=KIcon.SizeSmall):
@param size KIcon size
@return icon as QIconSet instance
"""
- return KGlobal.instance().iconLoader().loadIconSet(name, group, size)
+ return iconLoader().loadIconSet(name, group, size)
def action(text, label, icon, accel, tip, collection, pluggable):
diff --git a/kberylsettings/main.py b/kberylsettings/main.py
index 4b928ce..a0161fd 100644
--- a/kberylsettings/main.py
+++ b/kberylsettings/main.py
@@ -8,6 +8,7 @@ from sys import argv
from qt import Qt, QWidget, QHBoxLayout, QLabel
from kdecore import KApplication, KCmdLineArgs, KIcon, KGlobal, KWin, i18n
from kdeui import KMainWindow, KStdGuiItem, KLineEdit
+from kfile import KFileDialog
from kberylsettings.about import about
from kberylsettings.beryl import Context
@@ -37,7 +38,6 @@ class KBerylSetttings(KMainWindow):
@return None
"""
- self.loader = KGlobal.iconLoader()
self.mainSplitter = Splitter(self, Qt.Horizontal)
self.leftFrame = Frame(self.mainSplitter)
self.rightFrame = Frame(self.mainSplitter)
@@ -76,6 +76,8 @@ class KBerylSetttings(KMainWindow):
connect(self.pluginList, Signals.showSettings, self.contentFrame.showSettings)
connect(self.inputSearch, Signals.textChanged, self.pluginList.showSearch)
connect(self.clearSearch, Signals.clicked, self.onClearSearch)
+ connect(self.importAction, Signals.activated, self.onImport)
+ connect(self.exportAction, Signals.activated, self.onExport)
statusBar = self.statusBar()
actions = self.actionCollection()
actions.setHighlightingEnabled(True)
@@ -127,9 +129,9 @@ class KBerylSetttings(KMainWindow):
"""
pop = Popup(self)
actions = self.actionCollection()
- self.importAction = action('import', 'Import', '', 'Import settings',
+ self.importAction = action('import', 'Import...', '', 'Import settings',
'Import profile', actions, pop)
- self.exportAction = action('export', 'Export', '', 'Export current settings',
+ self.exportAction = action('export', 'Export...', '', 'Export current settings',
'Export profile', actions, pop)
pop.insertSeparator()
self.quitAction = stdAction(self, 'quit', Slots.close, actions, pop)
@@ -208,6 +210,14 @@ class KBerylSetttings(KMainWindow):
self.emit(Signals.viewModeChanged, (self.viewMode, ))
def onContextChanged(self):
+ """ writes the beryl context and sends a reload message
+
+ @return None
+ """
+ self.context.write()
+ self.context.reload()
+
+ def onSettingChanged(self):
""" writes the beryl context
@return None
@@ -259,6 +269,17 @@ class KBerylSetttings(KMainWindow):
for mode, menuid in self.modePopupIds.items():
self.modePopup.setItemChecked(menuid, mode==value)
+ def onImport(self):
+ filename = KFileDialog.getOpenFileName('::kberylsettings')
+ if filename:
+ print 'importing file...', filename
+
+ def onExport(self):
+ filename = KFileDialog.getSaveFileName('::kberylsettings')
+ if filename:
+ print 'exporting file...', filename
+
+
def showMessage(self, text):
self.statusBar().message(text, 3000)
@@ -270,9 +291,9 @@ def iconSizes():
"""
def sizeOk(attr):
return attr.startswith('Size') and attr != 'SizeSmallMedium'
- names = [a for a in dir(KIcon) if sizeOk(a)]
- sizes = [getattr(KIcon, a) for a in names]
- names = [l.replace('Size', '') for l in names]
+ names = [name for name in dir(KIcon) if sizeOk(name)]
+ sizes = [getattr(KIcon, name) for name in names]
+ names = [name.replace('Size', '') for name in names]
sizenames = zip(sizes, names)
sizenames.sort()
return sizenames
diff --git a/kberylsettings/plugindialog.py b/kberylsettings/plugindialog.py
index dc97831..3b981fe 100644
--- a/kberylsettings/plugindialog.py
+++ b/kberylsettings/plugindialog.py
@@ -7,8 +7,8 @@ from qt import QCheckListItem, QLabel
from kdecore import i18n
from kdeui import KDialogBase, KListView, KMessageBox
-from kberylsettings.lib import Signals
-
+from kberylsettings.lib import Signals, iconLoader
+### try to use KActionSelector
class PluginList(KListView):
""" PluginList -> list view for the select plugins dialog
@@ -19,16 +19,16 @@ class PluginList(KListView):
self.addColumn(i18n('Plugin'))
self.addColumn(i18n('Description'))
- def addPlugins(self, context, loader):
+ def addPlugins(self, context):
""" creates list view items from plugins in context
@param context berylsetting Context instance
- @param loader KIconLoader instance
@return mapping of plugin names and their enabled state
"""
stateMap = {}
active = context.active
count = textlen = 0
+ loader = iconLoader()
for p in context.plugins:
item = QCheckListItem(self, p.ShortDesc, QCheckListItem.CheckBox)
item.setEnabled(not p.isGeneral)
@@ -70,7 +70,7 @@ class PluginDialog(KDialogBase):
self.label = QLabel('Enable or disable plugins below.', main)
self.listView = PluginList(main)
self.connect(self.listView, Signals.itemClicked, self.changePlugin)
- self.pluginMap = self.listView.addPlugins(context, parent.loader)
+ self.pluginMap = self.listView.addPlugins(context)
def changePlugin(self, item):
""" handle a possible change to the plugins checkbox
diff --git a/kberylsettings/pluginframe.py b/kberylsettings/pluginframe.py
index e3116e8..5eacb2c 100644
--- a/kberylsettings/pluginframe.py
+++ b/kberylsettings/pluginframe.py
@@ -7,10 +7,10 @@ and search view.
from re import sub
from qt import QLabel, QListViewItem
-from kdecore import KIconLoader, i18n
+from kdecore import i18n
from kberylsettings.beryl import Setting
-from kberylsettings.lib import Signals, icon
+from kberylsettings.lib import Signals, icon, iconLoader
from kberylsettings.widget import Frame, ListView, ValueListViewItem, \
WidgetStack
@@ -74,7 +74,7 @@ class SearchView(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.index = {}
- self.loader = KIconLoader(self.__class__.__name__)
+ self.loader = iconLoader()
self.keywordLabel = QLabel(i18n('Keywords:'), self)
self.keywordsList = ListView(self)
configList(self.keywordsList)
@@ -165,7 +165,7 @@ class PluginView(ListView):
def __init__(self, parent):
ListView.__init__(self, parent)
configList(self)
- self.loader = KIconLoader(self.__class__.__name__)
+ self.loader = iconLoader()
self.connect(self, Signals.itemSelected, self.onSelected)
def addPlugins(self):
diff --git a/kberylsettings/settingframe.py b/kberylsettings/settingframe.py
index 7ead0a3..c84ae75 100644
--- a/kberylsettings/settingframe.py
+++ b/kberylsettings/settingframe.py
@@ -4,166 +4,30 @@
berylsettings.Setting instances.
"""
-from qt import Qt, QFrame, QHBoxLayout, QSizePolicy, QLabel, QVBoxLayout, \
- QCheckBox, QColor, qRgba, QToolTip
+from qt import Qt, QFrame, QHBoxLayout, QSizePolicy, QToolTip
-from kdecore import KShortcut, KKey
-from kdeui import KIntNumInput, KDoubleNumInput, KComboBox, KLineEdit, \
- KKeyButton, KColorButton
-
-from kberylsettings.lib import App, Signals, iconSet
+from kberylsettings.lib import App, iconSet
+from kberylsettings.settingwidget import settingWidgetBuilder
from kberylsettings.widget import SmallPushButton
-def numberInput(cls):
- """ returns closure to display indicated class
-
- @param cls KIntNumInput or KDoubleNumInput
- @return function for displaying cls
- """
- def builder(self):
- layout = QVBoxLayout()
- try:
- minv, maxv, stepv = self.setting.Restrictions
- except (ValueError, ):
- minv, maxv = self.setting.Restrictions
- stepv = 1
- curv = self.setting.Value
- self.input = cls(curv, self)
- self.input.setRange(minv, maxv, stepv, True)
- layout.addWidget(self.label)
- layout.addWidget(self.input)
- return layout
- return builder
-
-
class SettingFrame(QFrame):
""" SettingFrame -> displays editing widgets for a single Setting instance.
"""
- def __init__(self, parent, setting):
+ def __init__(self, parent, plugin, setting):
+ print '****', plugin.Name, setting.Name
+
QFrame.__init__(self, parent)
layout = QHBoxLayout(self, 3, 3)
- self.setting = setting
- if App.debug:
- self.setFrameStyle(QFrame.Box|QFrame.Plain)
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,
QSizePolicy.Minimum))
- self.buildWidgets()
-
- def buildWidgets(self):
- """ builds widgets on this instance
-
- @return None
- """
- layout = self.layout()
- self.label = QLabel(self.setting.label, self)
self.infoButton = SmallPushButton(iconSet('help'), '', self)
- tooltip = QToolTip.add(self.infoButton, self.setting.LongDesc or '')
self.resetButton = SmallPushButton(iconSet('reload'), '', self)
+ self.settingWidget = settingWidgetBuilder(self, plugin, setting)
+ tooltip = QToolTip.add(self.infoButton, setting.LongDesc or '')
layout.addWidget(self.infoButton, 0, Qt.AlignLeft|Qt.AlignVCenter)
layout.addWidget(self.resetButton, 0, Qt.AlignLeft|Qt.AlignVCenter)
- builder = getattr(self, 'build%s' % self.setting.Type, self.buildUnknown)
- if builder:
- nextlayout = builder()
- layout.addLayout(nextlayout, 100)
-
- buildInt = numberInput(KIntNumInput)
- buildFloat = numberInput(KDoubleNumInput)
-
- def buildBool(self):
- """ builds widget for a boolean setting
-
- @return layout instance
- """
- layout = QHBoxLayout()
- self.cb = QCheckBox(self)
- self.cb.setChecked(self.setting.Value)
- layout.addWidget(self.cb)
- layout.addWidget(self.label, 100)
- return layout
-
- def buildString(self):
- """ builds widget for a string setting
-
- @return layout instance
- """
- layout = QVBoxLayout()
- try:
- s = self.setting.Value
- except (IndexError, ):
- s = ''
- #print '%s: %s: %s' % (self.setting.Name, s, self.setting.Restrictions)
-
- if self.setting.Restrictions:
- other = self.combo = KComboBox(False, self)
- for r in self.setting.Restrictions:
- self.combo.insertItem(r)
- if s == r:
- self.combo.setCurrentItem(self.combo.count()-1)
- else:
- other = self.line = KLineEdit(s, self)
-
- layout.addWidget(self.label)
- layout.addWidget(other)
- return layout
-
- def buildColor(self):
- """ builds widget for a color setting
-
- @return layout instance
- """
- layout = QHBoxLayout()
- self.color = QColor(qRgba(*[a/256 for a in self.setting.Value]))
- self.colorButton = KColorButton(self)
- self.colorButton.setColor(self.color)
- layout.addWidget(self.label, 100)
- layout.addWidget(self.colorButton)
- return layout
-
- def buildUnknown(self):
- """ builds widget for an unknown setting
-
- @return layout instance
- """
- layout = QHBoxLayout()
- text = '%s (Unknown Type %s)' % (self.setting.ShortDesc, self.setting.Type, )
- self.label.setText(text)
- layout.addWidget(self.label)
- #print '***', self.setting.Value
- #print '***', self.setting.Restrictions
- return layout
-
- ##
- ## binding restrictions, e.g.: [1, 1, 0, 1]
- ## [cansetkey, cansetbutton, cansetedgemask, cansetbell]
- ##
- ## binding values: [keystr, buttonstr, bell, edgelist]
- ##
-
- def buildBinding(self):
- """ builds widget for a binding setting
-
- @return layout instance
- """
- layout = QHBoxLayout()
- self.line = KLineEdit('%s || %s' % (self.setting.Value, self.setting.Restrictions, ), self)
- self.keybutton = KKeyButton(self)
- self.keybutton.setShortcut(KShortcut(toKKey(self.setting.Value[0])))
- self.keybutton.setText(self.setting.Value[0])
- layout.addWidget(self.label)
- layout.addWidget(self.line)
- layout.addWidget(self.keybutton)
- return layout
-
-
-def toKKey(v):
- """ creates a KKey instance from a key setting
-
- @param v key setting as string
- @return KKey instance
- """
- v = v.replace("Control", "ctrl")
- v = v.replace('<', '')
- v = v.replace('>', '+')
- return KKey(v)
+ layout.addWidget(self.settingWidget, 10)
+ if App.debug:
+ self.setFrameStyle(QFrame.Box|QFrame.Plain)
diff --git a/kberylsettings/settingwidget.py b/kberylsettings/settingwidget.py
new file mode 100644
index 0000000..f6de843
--- /dev/null
+++ b/kberylsettings/settingwidget.py
@@ -0,0 +1,361 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+""" kberylsettings.settingwidget -> defines widgets for displaying and
+editing berylsettings.Setting instances.
+
+"""
+from re import match
+
+from kdecore import KShortcut, KKey, i18n
+from kdeui import KIntNumInput, KDoubleNumInput, KComboBox, KLineEdit, \
+ KKeyButton, KColorButton
+from kfile import KURLRequester, KURLComboBox, KURLComboRequester
+from qt import QCheckBox, QFrame, QLabel, QObject, QWidget, QHBoxLayout, \
+ QVBoxLayout, QGridLayout, QColor, qRgba
+from sip import wrappertype
+
+
+##
+# grown with BaseSettingWidget subclass definitions by the metaclass
+# below.
+settingWidgetTypes = []
+
+
+class MetaSettingWidget(wrappertype):
+ """ Small metaclass to gather subclasses of BaseSettingWidget as
+ they're created. Also turns any 'inspect' attribute into a
+ classmethod. Lazy * 2.
+ """
+ def __init__(cls, name, bases, ns):
+ super(MetaSettingWidget, cls).__init__(name, bases, ns)
+ if name != 'BaseSettingWidget' and cls not in settingWidgetTypes:
+ settingWidgetTypes.append(cls)
+ try:
+ setattr(cls, 'inspect', classmethod(ns['inspect']))
+ except (KeyError, ):
+ pass
+
+
+class BaseSettingWidget(QWidget):
+ """ Base class for setting widgets.
+
+ Setting Widget classes inherit this class to participate in
+ automatic discovery. They also recieve a default implementation
+ for 'inspect', which is quite handy.
+ """
+ ##
+ # specifies the metaclass for this class and it's derived classes.
+ __metaclass__ = MetaSettingWidget
+
+ def __init__(self, parent, plugin, setting):
+ QWidget.__init__(self, parent)
+ self.plugin = plugin
+ self.setting = setting
+
+ ##
+ # subclasses can redefine this attribute to make use of the
+ # default inspect method.
+ inspectTypes = ()
+
+ def inspect(cls, plugin, setting):
+ """ determines if this class can be used to display plugin setting
+
+ The default implementation here checks for inclusion of the
+ setting.Type in the inspectTypes sequence.
+
+ @param cls class object
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return truth value if this type can build a widget for
+ specified plugin and setting, false value otherwise.
+ """
+ return setting.Type in cls.inspectTypes
+
+ ##
+ # subclasses can change this to adjust the behavior of the
+ # commonSetup method below.
+ layoutType = QVBoxLayout
+
+ def commonSetup(self, setting, stretch=0):
+ """ create a layout object and a label for the setting
+
+ @param setting berylsetting Setting instance
+ @return QLayout instance with QLabel added
+ """
+ layout = self.layoutType(self)
+ label = self.label = QLabel(setting.label, self)
+ layout.addWidget(label, stretch)
+ return layout
+
+
+class NamedSettingWidget(BaseSettingWidget):
+ """ Setting widget for specific named settings.
+
+ Method names are in the form 'pluginname_settingname'.
+ """
+ def __init__(self, parent, plugin, setting):
+ BaseSettingWidget.__init__(self, parent, plugin, setting)
+ meth = self.inspect(plugin, setting)
+ meth(self, parent, plugin, setting)
+
+ def inspect(cls, plugin, setting):
+ """ matches plugin and setting names to local method names
+
+ @param cls class object
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return unbound method if found on class, None otherwise
+ """
+ name = '%s_%s' % (plugin.Name, setting.Name, )
+ return getattr(cls, name, None)
+
+ iconCorners = list(enumerate(('BottomRight', 'BottomLeft', 'TopRight',
+ 'TopLeft', 'Center')))
+
+ def switcher_icon_corner(self, parent, plugin, setting):
+ """ creates a combo box for the Switcher Icon Corner setting
+
+ @param parent ignored
+ @param plugin ignored
+ @param setting better be a icon_corner setting instance
+ @return None
+ """
+ layout = self.commonSetup(setting)
+ self.view = view = KComboBox(self)
+ layout.addWidget(view)
+ for index, text in self.iconCorners:
+ view.insertItem(text, index)
+
+ def value(self):
+ try:
+ return self.view.currentItem()
+ except (AttributeError, ):
+ raise
+
+class MatchNamedSettingWidget(BaseSettingWidget):
+ """ Setting widget for settings with matching names.
+
+ """
+ lookups = (
+ #((plugin name re, setting name re), method name)
+ (('.*', '.*_file'), 'fileSelector'),
+ (('.*', 'skydome_image'), 'fileSelector'),
+ (('.*', 'default_icon'), 'fileSelector'),
+ (('.*', '(.*_)?window_types'), 'wmTypeSelector'),
+ (('.*', 'images_(.*)'), 'filesSelector'),
+ )
+
+ def __init__(self, parent, plugin, setting):
+ BaseSettingWidget.__init__(self, parent, plugin, setting)
+ meth = self.inspect(plugin, setting)
+ meth(self, parent, plugin, setting)
+
+ def inspect(cls, plugin, setting):
+ """ matches plugin and setting names to local method names
+
+ @param cls class object
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return unbound method if found on class, None otherwise
+ """
+ for (plugpat, setpat), callname in cls.lookups:
+ if match(plugpat, plugin.Name) and match(setpat, setting.Name):
+ return getattr(cls, callname, None)
+
+ def fileSelector(self, parent, plugin, setting):
+ layout = self.commonSetup(setting)
+ self.view = KURLRequester(setting.Value, self)
+ layout.addWidget(self.view)
+
+ def filesSelector(self, parent, plugin, setting):
+ layout = self.commonSetup(setting)
+ #self.files = KURLComboBox(KURLComboBox.Files, self)
+ self.files = KURLComboRequester(self)
+
+ layout.addWidget(self.files)
+
+ def wmTypeSelector(self, parent, plugin, setting):
+ types = setting.Restrictions
+ current = setting.Value
+ grid = QGridLayout(len(types)/3, 3)
+ items = range(len(types))
+ for row, indexes in enumerate([items[i:i+3] for i in items[::3]]):
+ for col, index in enumerate(indexes):
+ typ = types[index]
+ cb = QCheckBox(typ, self)
+ cb.setChecked(typ in current)
+ grid.addWidget(cb, row, col)
+ layout = self.commonSetup(setting)
+ layout.addLayout(grid)
+
+ def value(self):
+ try:
+ return str(self.view.url())
+ except (AttributeError, ):
+ def fix(o):
+ return str(o.text()).replace('&', '')
+ return [fix(check) for check in self.queryList('QCheckBox')
+ if check.isChecked()]
+
+
+class ColorSettingWidget(BaseSettingWidget):
+ """ Setting widget for colors.
+
+ """
+ inspectTypes = ('Color', )
+ layoutType = QHBoxLayout
+
+ def __init__(self, parent, plugin, setting):
+ BaseSettingWidget.__init__(self, parent, plugin, setting)
+ layout = self.commonSetup(setting, 100)
+ self.color = QColor(qRgba(*[a/256 for a in setting.Value]))
+ self.colorButton = KColorButton(self)
+ self.colorButton.setColor(self.color)
+ layout.addWidget(self.colorButton)
+
+
+class BoolSettingWidget(BaseSettingWidget):
+ """ Setting widget for true/false values.
+
+ """
+ inspectTypes = ('Bool', )
+
+ def __init__(self, parent, plugin, setting):
+ BaseSettingWidget.__init__(self, parent, plugin, setting)
+ layout = QHBoxLayout(self)
+ self.cb = QCheckBox(self)
+ self.cb.setChecked(setting.Value)
+ layout.addWidget(self.cb)
+ label = QLabel(setting.ShortDesc, self)
+ layout.addWidget(label, 100)
+
+ def value(self):
+ return self.cb.isChecked()
+
+
+class NumericSettingWidget(BaseSettingWidget):
+ """ Setting widget for numeric ranges. Integers and floats supported.
+
+ """
+ inspectTypes = {
+ 'Int' : KIntNumInput,
+ 'Float' : KDoubleNumInput,
+ }
+
+ def __init__(self, parent, plugin, setting):
+ BaseSettingWidget.__init__(self, parent, plugin, setting)
+ try:
+ minvalue, maxvalue, stepvalue = setting.Restrictions
+ except (ValueError, ):
+ minvalue, maxvalue = setting.Restrictions
+ stepvalue = 1
+ current = setting.Value
+ self.input = self.inspectTypes[setting.Type](current, self)
+ self.input.setRange(minvalue, maxvalue, stepvalue, True)
+ layout = self.commonSetup(setting)
+ layout.addWidget(self.input)
+
+ def value(self):
+ return self.input.value()
+
+
+class StringSettingWidget(BaseSettingWidget):
+ """ Setting widget for strings.
+
+ """
+ inspectTypes = ('String', )
+
+ def __init__(self, parent, plugin, setting):
+ BaseSettingWidget.__init__(self, parent, plugin, setting)
+ layout = self.commonSetup(setting)
+ try:
+ s = setting.Value
+ except (IndexError, ): # some berylsettings bug???
+ s = ''
+ if setting.Restrictions:
+ other = self.combo = KComboBox(False, self)
+ for r in setting.Restrictions:
+ other.insertItem(r)
+ if s == r:
+ other.setCurrentItem(other.count()-1)
+ else:
+ other = self.line = KLineEdit(s, self)
+ layout.addWidget(other)
+
+ def value(self):
+ try:
+ return str(self.line.text())
+ except (AttributeError, ):
+ return str(self.combo.currentText())
+
+class BindingSettingWidget(BaseSettingWidget):
+ """ Setting widget for keyboard/mouse/edge bindings.
+
+ """
+ inspectTypes = ('Binding', )
+ layoutType = QHBoxLayout
+
+ def __init__(self, parent, plugin, setting):
+ BaseSettingWidget.__init__(self, parent, plugin, setting)
+ layout = self.commonSetup(setting)
+ self.line = KLineEdit('%s || %s' % (setting.Value, setting.Restrictions, ), self)
+ self.keybutton = KKeyButton(self)
+ self.keybutton.setShortcut(KShortcut(toKKey(setting.Value[0])))
+ self.keybutton.setText(setting.Value[0])
+ layout.addWidget(self.line)
+ layout.addWidget(self.keybutton)
+
+
+class UnknownSettingWidget(BaseSettingWidget):
+ """ Setting widget for unknown values.
+
+ Because this class is defined last, it's caught by the metaclass
+ last and therefore put into the list of types at the end.
+ Whenever a setting object cannot be otherwise matched to a
+ SettingWidget, this class will be called.
+ """
+ layoutType = QHBoxLayout
+
+ def __init__(self, parent, plugin, setting):
+ BaseSettingWidget.__init__(self, parent, plugin, setting)
+ layout = self.commonSetup(setting)
+ text = '%s (Unknown Type %s)' % (setting.ShortDesc, setting.Type, )
+ self.label.setText(text)
+
+ def inspect(cls, plugin, setting):
+ """ matches plugin and setting names to local method names
+
+ @param cls class object
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return True
+ """
+ return True
+
+ def value(self):
+ raise RuntimeError('Cannot get value of unknown setting.')
+
+
+def settingWidgetBuilder(parent, plugin, setting):
+ """ client interface to this module.
+
+ @param parent parent of setting widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return new widget suitable for display and edit of setting
+ """
+ for typ in settingWidgetTypes:
+ if typ.inspect(plugin, setting):
+ return typ(parent, plugin, setting)
+
+
+def toKKey(v):
+ """ creates a KKey instance from a key setting
+
+ @param v key setting as string
+ @return KKey instance
+ """
+ v = v.replace("Control", "ctrl")
+ v = v.replace('<', '')
+ v = v.replace('>', '+')
+ return KKey(v)