summaryrefslogtreecommitdiff
path: root/kberylsettings
diff options
context:
space:
mode:
authornatural <natural>2006-12-23 13:15:14 +0000
committernatural <natural>2006-12-23 13:15:14 +0000
commit218899acc534b1d8d8896ecf5cbbda8c676732be (patch)
tree54fb6d8cf11ed7374f3e535d27e1cc4a9d70bfa5 /kberylsettings
parenta4fcfeb8b855e88d8e662c562dfbd6c9370793a1 (diff)
downloadkberylsettings-218899acc534b1d8d8896ecf5cbbda8c676732be.tar.gz
kberylsettings-218899acc534b1d8d8896ecf5cbbda8c676732be.tar.bz2
Updated setting widget construction and splitter handling.
Diffstat (limited to 'kberylsettings')
-rw-r--r--kberylsettings/contentframe.py75
-rw-r--r--kberylsettings/main.py20
-rw-r--r--kberylsettings/settingframe.py12
-rw-r--r--kberylsettings/settingwidget.py428
-rw-r--r--kberylsettings/widget.py19
5 files changed, 395 insertions, 159 deletions
diff --git a/kberylsettings/contentframe.py b/kberylsettings/contentframe.py
index 9880925..e0f53d8 100644
--- a/kberylsettings/contentframe.py
+++ b/kberylsettings/contentframe.py
@@ -5,9 +5,9 @@
"""
from os.path import abspath
-from qt import Qt, QFrame, QLabel, QHBoxLayout, QScrollView, QVBoxLayout, QStringList
+from qt import Qt, QFrame, QLabel, QHBoxLayout, QScrollView, QVBoxLayout, QStringList, QSizePolicy, QSize
from kdecore import KIcon
-from kdeui import KStdGuiItem, KPushButton, KMessageBox
+from kdeui import KStdGuiItem, KPushButton, KMessageBox, KSeparator
from kberylsettings.lib import App, Signals, buildPart, iconLoader
from kberylsettings.settingframe import SettingFrame
@@ -34,45 +34,51 @@ class ContentFrame(WidgetStack):
@return None
"""
self.aboutPage = Frame(self, margin=6, spacing=10)
+ self.addWidget(self.aboutPage, self.aboutPageId)
self.infoHtml = buildPart(self.aboutPage, 'text/html',
"Type == 'Service'", True)
- self.addWidget(self.aboutPage, self.aboutPageId)
+
def buildSettingsPage(self):
""" builds page for displaying one or more settings
@return None
"""
- self.settingsPage = Frame(self, margin=6, spacing=10)
- self.pluginHeader = QFrame(self.settingsPage)
- self.pluginIconLabel = QLabel(self.pluginHeader)
- self.pluginNameLabel = QLabel(self.pluginHeader)
- layout = QHBoxLayout(self.pluginHeader)
- layout.addWidget(self.pluginIconLabel)
- layout.addWidget(self.pluginNameLabel, 100)
-
- self.settingsMain = SettingsMainFrame(self)
- self.settingsScroller = ContentScroll(self.settingsPage, self.settingsMain)
- if not App.debug:
- self.settingsScroller.setFrameShape(Frame.NoFrame)
- self.settingsFooter = QFrame(self.settingsPage)
- layout = QHBoxLayout(self.settingsFooter)
+
+ self.settingsPage = page = Frame(self, 6, 10)
+ self.addWidget(page, self.settingsPageId)
+
+ self.pluginHeader = header = QFrame(page)
+ self.pluginIconLabel = QLabel(header)
+ self.pluginNameLabel = QLabel(header)
+
+ headerLayout = QHBoxLayout(header)
+ headerLayout.addWidget(self.pluginIconLabel, 1)
+ headerLayout.addWidget(self.pluginNameLabel, 10)
+ self.settingsMain = main = SettingsMainFrame(page)
+ ## ugly hack that took me 6 hours (!!) to find
+ self.any = Frame(page)
+ self.settingsScroller = scroller = ContentScroll(self.any, main)
+
+ sep = KSeparator(KSeparator.Horizontal, page)
+ self.settingsFooter = footer = QFrame(page)
+ footerLayout = QHBoxLayout(footer)
+
def contentButton(name):
gui = getattr(KStdGuiItem, name)()
button = KPushButton(gui.iconSet(), gui.text(), self.settingsFooter)
- layout.addWidget(button)
+ footerLayout.addWidget(button)
return button
self.helpButton = contentButton('help')
self.defaultsButton = contentButton('defaults')
- layout.addStretch(100)
+ footerLayout.addStretch(100)
self.applyButton = contentButton('apply')
self.applyButton.setEnabled(False)
self.resetButton = contentButton('reset')
- self.resetButton.setEnabled(False)
- self.addWidget(self.settingsPage, self.settingsPageId)
-
+ self.resetButton.setEnabled(False)
+
def buildConnections(self):
""" build the connections for this instance
@@ -112,6 +118,7 @@ class ContentFrame(WidgetStack):
self.infoHtml.write(htmlsrc % locals())
self.infoHtml.end()
self.raiseWidget(self.aboutPageId)
+
def showSettings(self, plugin, arg):
""" displays the settings page with individual setting frames
@@ -120,6 +127,7 @@ class ContentFrame(WidgetStack):
@param arg setting name or setting section name
@return None
"""
+ p = self.parent()
ico = plugin.icon(KIcon.SizeLarge, self.loader)
self.pluginIconLabel.setPixmap(ico)
if arg in plugin.settings:
@@ -131,8 +139,8 @@ class ContentFrame(WidgetStack):
self.pluginNameLabel.setText('<b>%s%s</b>' % (plugin.ShortDesc, extra))
self.settingsMain.addSettings(plugin, settings)
self.applyButton.setEnabled(False)
- self.resetButton.setEnabled(False)
- self.raiseWidget(self.settingsPageId)
+ self.resetButton.setEnabled(False)
+ self.raiseWidget(self.settingsPageId)
def settingHelp(self):
""" not implemented
@@ -182,24 +190,28 @@ class ContentFrame(WidgetStack):
self.emit(Signals.statusMessage, ('Saving settings...', ))
self.emit(Signals.berylSettingChanged, ())
+
class SettingsMainFrame(QFrame):
def __init__(self, parent):
QFrame.__init__(self, parent)
+ self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.settingFrames = []
- layout = QVBoxLayout(self)
+ layout = QVBoxLayout(self, 20)
def addSettings(self, plugin, settings):
self.clearFrames()
layout = self.layout()
+ changed = Signals.somethingChanged
for setting in settings:
frame = SettingFrame(self, plugin, setting)
self.settingFrames.append(frame)
layout.addWidget(frame, 0, Qt.AlignTop)
+ self.connect(frame, changed, self, changed)
+ layout.addStretch(100)
+ for frame in self.settingFrames:
frame.show()
- self.connect(frame, Signals.somethingChanged,
- self, Signals.somethingChanged)
- layout.addStretch(100)
-
+ self.updateGeometry()
+
def clearFrames(self):
for widget in self.settingFrames:
widget.close(True)
@@ -207,11 +219,14 @@ class SettingsMainFrame(QFrame):
self.settingFrames = []
+
class ContentScroll(QScrollView):
""" ContentScroll -> a scroll view fitted to a single child
"""
def __init__(self, parent, child):
QScrollView.__init__(self, parent)
- self.addChild(child)
self.setResizePolicy(QScrollView.AutoOneFit)
+ #self.setVScrollBarMode(self.AlwaysOn)
+ self.setFrameShape(self.Box)
+ self.addChild(child)
diff --git a/kberylsettings/main.py b/kberylsettings/main.py
index 10c2752..ab827cd 100644
--- a/kberylsettings/main.py
+++ b/kberylsettings/main.py
@@ -8,7 +8,7 @@ from sys import argv
from kdecore import KApplication, KCmdLineArgs, KIcon, KGlobal, KWin, i18n
from kdeui import KMainWindow, KStdGuiItem, KLineEdit, KSystemTray
from kfile import KFileDialog
-from qt import Qt, QWidget, QHBoxLayout, QLabel
+from qt import Qt, QWidget, QHBoxLayout, QLabel, QImage
from kberylsettings.about import about
from kberylsettings.beryl import Context
@@ -42,9 +42,12 @@ class KBerylSettings(KMainWindow):
"""
actions = self.actionCollection()
actions.setHighlightingEnabled(True)
- self.mainSplitter = Splitter(self, Qt.Horizontal)
- self.leftFrame = Frame(self.mainSplitter)
- self.rightFrame = Frame(self.mainSplitter)
+
+ self.mainSplitter = splitter = Splitter(self, Qt.Horizontal)
+ self.leftFrame = left = Frame(splitter)
+ self.contentFrame = ContentFrame(splitter)
+ #splitter.setResizeMode(self.contentFrame, splitter.FollowSizeHint)
+
self.searchWidget = search = QWidget(self.leftFrame)
searchLayout = QHBoxLayout(search, 6, 6)
searchLayout.setAutoAdd(True)
@@ -52,9 +55,8 @@ class KBerylSettings(KMainWindow):
self.clearSearch = SmallPushButton(clear.iconSet(), '', search)
self.labelSearch = QLabel(i18n('Search: '), search)
self.inputSearch = KLineEdit(search)
- self.pluginList = PluginFrame(self.leftFrame)
- self.setCentralWidget(self.mainSplitter)
- self.contentFrame = ContentFrame(self.rightFrame)
+ self.pluginList = PluginFrame(left)
+ self.setCentralWidget(splitter)
statusBar = self.statusBar()
def buildMenus(self):
@@ -115,12 +117,13 @@ class KBerylSettings(KMainWindow):
self.emit(Signals.berylContextChanged, (context, ))
connect = self.connect
connect(context, Signals.statusMessage, self.showMessage)
+ self.setIcon(icon(self.iconFile(), size=KIcon.SizeSmall))
KWin.setIcons(self.winId(),
icon(self.iconFile(), size=KIcon.SizeLarge),
icon(self.iconFile(), size=KIcon.SizeSmall))
config = self.config('mainwindow')
self.restoreWindowSize(config)
- self.mainSplitter.setSizes([self.width()*0.35, self.width()*0.65])
+ self.mainSplitter.setSizes([self.width()*0.25, self.width()*0.75])
config = self.config('mainview')
self.emit(Signals.iconSizeChanged,
(config.readNumEntry('iconsize', self.iconSize), ))
@@ -344,6 +347,7 @@ def main():
@return None
"""
aboutdata = about()
+ aboutdata.setProgramLogo(QImage(App.basedir + '/pixmaps/kberylsettings.png'))
KCmdLineArgs.init(argv, aboutdata)
app = KApplication()
obj = KBerylSettings()
diff --git a/kberylsettings/settingframe.py b/kberylsettings/settingframe.py
index c888f4c..261f8c1 100644
--- a/kberylsettings/settingframe.py
+++ b/kberylsettings/settingframe.py
@@ -4,7 +4,7 @@
berylsettings.Setting instances.
"""
-from qt import Qt, QFrame, QHBoxLayout, QSizePolicy, QToolTip
+from qt import Qt, QFrame, QHBoxLayout, QSizePolicy, QToolTip, QVBoxLayout
from kberylsettings.lib import App, Signals, iconSet
from kberylsettings.settingwidget import settingWidget
@@ -16,10 +16,9 @@ class SettingFrame(QFrame):
"""
def __init__(self, parent, plugin, setting):
- print '****', plugin.Name, setting.Name
-
QFrame.__init__(self, parent)
- layout = QHBoxLayout(self, 3, 3)
+ vlayout = QVBoxLayout(self)
+ layout = QHBoxLayout(vlayout, 3)
self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,
QSizePolicy.Minimum))
self.infoButton = SmallPushButton(iconSet('help'), '', self)
@@ -31,11 +30,10 @@ class SettingFrame(QFrame):
else:
align = Qt.AlignLeft | Qt.AlignTop
- tooltip = QToolTip.add(self.infoButton, setting.LongDesc or '')
+ tooltip = QToolTip.add(self.infoButton, setting.LongDesc)
layout.addWidget(self.infoButton, 0, align)
layout.addWidget(self.resetButton, 0, align)
layout.addWidget(self.settingWidget, 10)
+ vlayout.addSpacing(10)
self.connect(self.settingWidget, Signals.somethingChanged,
self, Signals.somethingChanged)
- if App.debug:
- self.setFrameStyle(QFrame.Box|QFrame.Plain)
diff --git a/kberylsettings/settingwidget.py b/kberylsettings/settingwidget.py
index b954ea3..fc3507d 100644
--- a/kberylsettings/settingwidget.py
+++ b/kberylsettings/settingwidget.py
@@ -6,19 +6,24 @@ editing berylsettings.Setting instances.
"""
from re import match
-from kdecore import KShortcut, KKey, i18n
+from kdecore import i18n
from kdeui import KIntNumInput, KDoubleNumInput, KComboBox, KLineEdit, \
- KKeyButton, KColorButton, KEditListBox
+ KColorButton, KEditListBox, KPushButton
from kfile import KURLRequester, KURLComboBox, KURLComboRequester
from qt import QCheckBox, QFrame, QLabel, QObject, QWidget, QHBoxLayout, \
- QVBoxLayout, QGridLayout, QColor, qRgba, Qt, QGroupBox
+ QVBoxLayout, QGridLayout, QColor, qRgba, Qt, QGroupBox, QCheckListItem, \
+ QSizePolicy, QSpacerItem
from sip import wrappertype
from kberylsettings.lib import Signals
+from kberylsettings.widget import ShortListView
def settingWidget(parent, plugin, setting):
- """ client interface to this module.
+ """ create display and edit widgets for setting
+
+ This is the client interface to this module; no other methods or
+ classes are needed.
@param parent parent of setting widget
@param plugin berylsettings Plugin instance
@@ -26,13 +31,14 @@ def settingWidget(parent, plugin, setting):
@return new widget suitable for display and edit of setting
"""
for typ in SettingWidgetDetector.types:
- if typ.inspect(plugin, setting):
+ if typ.query(plugin, setting):
return typ(parent, plugin, setting)
class SettingWidgetDetector(wrappertype):
""" Small metaclass to gather subclasses of SettingWidgetBase as
they're created.
+
"""
types = []
@@ -43,7 +49,7 @@ class SettingWidgetDetector(wrappertype):
types.append(cls)
-class SettingWidgetBase(QWidget):
+class SettingWidgetBase(QFrame):
""" Base class for setting widgets.
Subclasses must define a 'build' method to construct their
@@ -53,38 +59,37 @@ class SettingWidgetBase(QWidget):
The last two items may be None.
- Additionally, subclasses must define (or set at runtime) methods
- named 'value' and 'reset'. The 'value' method will be called to
- retrieve the new value for the setting, and the 'reset' method
- will be called to reset the widget to its initial value.
-
Setting Widget classes inherit this class to participate in
automatic discovery. They also recieve a default implementation
- for 'inspect', which is quite handy.
+ for 'query', which is quite handy.
"""
__metaclass__ = SettingWidgetDetector
def __init__(self, parent, plugin, setting):
- QWidget.__init__(self, parent)
+ QFrame.__init__(self, parent)
self.plugin = plugin
self.setting = setting
try:
self.initial = setting.Value
except (IndexError, ):
self.initial = ''
- primaryWidget, changeSignal, self.value, self.reset = \
- self.build(parent, plugin, setting)
- if self.reset:
+ self.primaryWidget, self.changeSignal, self.value, self.reset = \
+ self.build(parent, plugin, setting)
+ try:
self.reset()
- if changeSignal:
- self.connect(primaryWidget, changeSignal,
+ except (ValueError, ):
+ pass
+ if self.changeSignal:
+ self.connect(self.primaryWidget, self.changeSignal,
self, Signals.somethingChanged)
- def commonSetup(self, setting, stretch=1, layoutType=QVBoxLayout):
+ def labeledLayout(self, setting, stretch=1, layoutType=QVBoxLayout):
""" create a layout object and a label for the setting
@param setting berylsetting Setting instance
- @return QLayout instance with QLabel added
+ @keyparam stretch=1 label layout stretch factor
+ @keyparam layoutType=QVBoxLayout layout type
+ @return layoutType instance with QLabel added
"""
layout = layoutType(self)
label = self.label = QLabel(setting.label, self)
@@ -93,15 +98,15 @@ class SettingWidgetBase(QWidget):
##
# subclasses can redefine this attribute to make use of the
- # default inspect method below.
- inspectTypes = ()
+ # default query method below.
+ queryTypes = ()
- def inspect(cls, plugin, setting):
+ def query(cls, plugin, setting):
""" determines if this class can be used to display plugin setting
The default implementation checks for inclusion of the
- setting.Type in the inspectTypes sequence. Subclasses can
- override inspectTypes, or override this method completely.
+ setting.Type in the queryTypes sequence. Subclasses can
+ override queryTypes, or override this method completely.
@param cls class object
@param plugin berylsettings Plugin instance
@@ -109,8 +114,8 @@ class SettingWidgetBase(QWidget):
@return truth value if this type can build a widget for
specified plugin and setting, false value otherwise.
"""
- return setting.Type in cls.inspectTypes
- inspect = classmethod(inspect)
+ return setting.Type in cls.queryTypes
+ query = classmethod(query)
## MARKER
@@ -134,6 +139,8 @@ class SettingWidgetBase(QWidget):
return self.combo.currentItem()
def comboIndexReset(self):
+ ## this method does not clear the combo,
+ ## it only sets the current item.
self.combo.setCurrentItem(self.setting.Value)
def inputValue(self):
@@ -150,12 +157,12 @@ class SettingWidgetBase(QWidget):
def checkBoxesValue(self):
boxes = self.queryList('QCheckBox')
- return [cbText(box) for box in boxes if box.isChecked()]
+ return [self.cbText(box) for box in boxes if box.isChecked()]
def checkBoxesReset(self):
initial = self.initial
for cb in self.queryList('QCheckBox'):
- cb.setChecked(cbText(cb) in initial)
+ cb.setChecked(self.cbText(cb) in initial)
def listEditorValue(self):
box = self.listEditor.listBox()
@@ -173,16 +180,28 @@ class SettingWidgetBase(QWidget):
self.requester.clear()
self.requester.setURL(self.initial)
+ def cbText(self, widget):
+ return str(widget.text()).replace('&', '')
+
class NamedSettingWidget(SettingWidgetBase):
""" Setting widget for specific named settings.
Method names are in the form 'pluginname_settingname'.
"""
+ iconCorners = 'BottomRight', 'BottomLeft', 'TopRight', 'TopLeft', 'Center'
+
def build(self, parent, plugin, setting):
- return self.inspect(plugin, setting)(self, parent, plugin, setting)
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
+ return self.query(plugin, setting)(self, parent, plugin, setting)
- def inspect(cls, plugin, setting):
+ def query(cls, plugin, setting):
""" matches plugin and setting names to local method names
@param cls class object
@@ -192,9 +211,7 @@ class NamedSettingWidget(SettingWidgetBase):
"""
name = '%s_%s' % (plugin.Name, setting.Name, )
return getattr(cls, name, None)
- inspect = classmethod(inspect)
-
- iconCorners = 'BottomRight', 'BottomLeft', 'TopRight', 'TopLeft', 'Center'
+ query = classmethod(query)
def switcher_icon_corner(self, parent, plugin, setting):
""" creates a combo box for the Switcher Icon Corner setting
@@ -207,8 +224,7 @@ class NamedSettingWidget(SettingWidgetBase):
self.combo = KComboBox(self)
for index, text in enumerate(self.iconCorners):
self.combo.insertItem(text, index)
- #self.combo.setCurrentItem(setting.Value)
- layout = self.commonSetup(setting)
+ layout = self.labeledLayout(setting)
layout.addWidget(self.combo, 2)
return (self.combo, Signals.activatedIndex,
self.comboIndex, self.comboIndexReset)
@@ -228,10 +244,17 @@ class MatchNamedSettingWidget(SettingWidgetBase):
)
def build(self, parent, plugin, setting):
- meth = self.inspect(plugin, setting)
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
+ meth = self.query(plugin, setting)
return meth(self, parent, plugin, setting)
- def inspect(cls, plugin, setting):
+ def query(cls, plugin, setting):
""" matches plugin and setting names to local method names
@param cls class object
@@ -242,11 +265,11 @@ class MatchNamedSettingWidget(SettingWidgetBase):
for (plugpat, setpat), callname in cls.lookups:
if match(plugpat, plugin.Name) and match(setpat, setting.Name):
return getattr(cls, callname, None)
- inspect = classmethod(inspect)
+ query = classmethod(query)
def fileSelector(self, parent, plugin, setting):
self.requester = KURLRequester(self)
- layout = self.commonSetup(setting)
+ layout = self.labeledLayout(setting)
layout.addWidget(self.requester, 2)
return (self.requester, Signals.textChanged,
self.requesterValue, self.requesterReset)
@@ -261,25 +284,31 @@ class MatchNamedSettingWidget(SettingWidgetBase):
self.listEditorValue, self.listEditorReset)
def wmTypeSelector(self, parent, plugin, setting):
- types = setting.Restrictions
- current = setting.Value
- group = LocalGroupBox(3, Qt.Horizontal, setting.ShortDesc, self)
- items = range(len(types))
- for typ in types:
- cb = QCheckBox(typ, group)
- self.connect(cb, Signals.clicked, self, Signals.somethingChanged)
+ self.group = LocalGroupBox(3, Qt.Horizontal, setting.ShortDesc, self)
+ for text in setting.Restrictions:
+ checkBox = QCheckBox(text, self.group)
+ self.connect(checkBox, Signals.clicked,
+ self, Signals.somethingChanged)
layout = QVBoxLayout(self)
- layout.addWidget(group, 2)
- return (self, None, self.checkBoxesValue, self.checkBoxesReset)
+ layout.addWidget(self.group, 2)
+ ## return signal None because we've already connected the checkboxes
+ return (self.group, None, self.checkBoxesValue, self.checkBoxesReset)
class BoolSettingWidget(SettingWidgetBase):
""" Setting widget for true/false values.
"""
- inspectTypes = 'Bool'
+ queryTypes = ('Bool', )
def build(self, parent, plugin, setting):
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
layout = QHBoxLayout(self)
self.checkBox = QCheckBox(self)
layout.addWidget(self.checkBox)
@@ -289,17 +318,26 @@ class BoolSettingWidget(SettingWidgetBase):
self.checkBoxValue, self.checkBoxReset)
+## TODO: add slider for opacity
+## TODO: add reset and value functions
class ColorSettingWidget(SettingWidgetBase):
""" Setting widget for colors.
"""
- inspectTypes = 'Color'
+ queryTypes = ('Color', )
def build(self, parent, plugin, setting):
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
self.color = QColor(qRgba(*[a/256 for a in setting.Value]))
self.colorButton = KColorButton(self)
self.colorButton.setColor(self.color)
- layout = self.commonSetup(setting, 100, QHBoxLayout)
+ layout = self.labeledLayout(setting, 100, QHBoxLayout)
layout.addWidget(self.colorButton)
return (self.colorButton, Signals.colorChanged, None, None)
@@ -308,7 +346,7 @@ class NumericSettingWidget(SettingWidgetBase):
""" Setting widget for numeric ranges. Integers and floats supported.
"""
- inspectTypes = {
+ queryTypes = {
'Int' : KIntNumInput,
'Float' : KDoubleNumInput,
}
@@ -319,14 +357,21 @@ class NumericSettingWidget(SettingWidgetBase):
}
def build(self, parent, plugin, setting):
- self.input = self.inspectTypes[setting.Type](self)
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
+ self.input = self.queryTypes[setting.Type](self)
try:
minvalue, maxvalue, stepvalue = setting.Restrictions
except (ValueError, ):
minvalue, maxvalue = setting.Restrictions
stepvalue = 1
self.input.setRange(minvalue, maxvalue, stepvalue, True)
- layout = self.commonSetup(setting, layoutType=QHBoxLayout)
+ layout = self.labeledLayout(setting, layoutType=QHBoxLayout)
layout.addWidget(self.input, 2)
return (self.input, self.changeSignals[setting.Type],
self.inputValue, self.inputReset)
@@ -336,9 +381,16 @@ class StringSettingWidget(SettingWidgetBase):
""" Setting widget for strings.
"""
- inspectTypes = 'String'
+ queryTypes = ('String', )
def build(self, parent, plugin, setting):
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
if setting.Restrictions:
self.combo = KComboBox(self)
res = (self.combo, Signals.activatedIndex,
@@ -347,7 +399,7 @@ class StringSettingWidget(SettingWidgetBase):
self.line = KLineEdit(self)
res = (self.line, Signals.textChanged,
self.lineText, self.lineTextReset)
- layout = self.commonSetup(setting, layoutType=QHBoxLayout)
+ layout = self.labeledLayout(setting, layoutType=QHBoxLayout)
layout.addWidget(res[0], 2)
return res
@@ -356,9 +408,16 @@ class StringListSettingWidget(SettingWidgetBase):
""" Setting widget for lists of strings.
"""
- inspectTypes = 'List of String'
+ queryTypes = ('List of String', )
def build(self, parent, plugin, setting):
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
self.listEditor = KEditListBox(setting.ShortDesc, self)
layout = QVBoxLayout(self)
layout.addWidget(self.listEditor, 2)
@@ -366,52 +425,202 @@ class StringListSettingWidget(SettingWidgetBase):
self.listEditorValue, self.listEditorReset)
-## binding restrictions, e.g.: [1, 1, 0, 1]
-## [cansetkey, cansetbutton, cansetedgemask, cansetbell]
-##
-## binding values: [keystr, buttonstr, bell, edgelist]
-"""
-print p.Settings[0]
-initiate setting
+class BindingSettingWidget(SettingWidgetBase):
+ """ Setting widget for keyboard/pointer/edge bindings.
-in [77]: s = p.Settings[0]
+ restrictions example:
+ [1, 1, 0, 1]
+ decoded:
+ [can set key, can set button, can set bell, can set edge]
-in [78]: s
-out[78]: <berylsettings.Setting object at 0xb54d962c>
+ value example:
+ ('<Alt>F2', 'Disabled', False, [])
+ decoded:
+ [key string, button string, bell enabled, edge list]
-in [79]: s.Value
-out[79]: ('<Alt>F7', '<Alt>Button1', False, [])
+ """
+ queryTypes = ('Binding', )
-in [80]: s.Type
-out[80]: 'Binding'
-"""
+ edges = (
+ 'Left', 'Right', 'Top', 'Bottom',
+ 'Top-Left', 'Top-Right',
+ 'Bottom-Left', 'Bottom-Right',
+ )
-class BindingSettingWidget(SettingWidgetBase):
- """ Setting widget for keyboard/mouse/edge bindings.
+ modifiers = (
+ 'Shift', 'Control', 'Alt', 'Super', 'Hyper', 'Meta', 'Mode',
+ 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5',
+ )
- """
- inspectTypes = 'Binding'
+ pointerButtons = (
+ '1 (primary)',
+ '2 (middle)',
+ '3 (secondary)',
+ '4 (often wheel up)',
+ '5 (often wheel down)',
+ '6 (if available)',
+ '7 (if available)',
+ '8 (if available)',
+ '9 (if available)',
+ )
- keyMods = ('Shift', 'Control', 'Alt', 'Super', 'Hyper',
- 'Meta', 'Mode', 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5')
+ idxKey, idxPointer, idxBell, idxEdge = range(4)
def build(self, parent, plugin, setting):
- layout = self.commonSetup(setting, layoutType=QHBoxLayout)
- 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, 3)
- layout.addWidget(self.keybutton, 2)
- return (self.keybutton, Signals.clicked, None, None)
-
- catsetkey, cansetbutton, cansetedge, cansetbell = setting.Restrictions
- keystr, buttonstr, bell, edgeseq = setting.Value
- group = LocalGroupBox(3, Qt.Horizontal, setting.ShortDesc, self)
- if cansetkey:
- pass
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
+ self.controls = [None, None, None, None]
+ self.label = QLabel(setting.ShortDesc, self)
+ layout = QGridLayout(self, 4, 3, 0, 10)
+ layout.addMultiCellWidget(self.label, 0, 0, 0, 3, Qt.AlignTop|Qt.AlignLeft)
+ restrictions = setting.Restrictions
+ if restrictions[self.idxKey]:
+ self.controls[self.idxKey] = control = \
+ self.bindingWidget('Key', self.idxKey)
+ layout.addLayout(control.headerLayout, 1, 0)
+ layout.addWidget(control.modifierList, 2, 0)
+
+ if restrictions[self.idxPointer]:
+ self.controls[self.idxPointer] = control = \
+ self.bindingWidget('Pointer Button', self.idxPointer)
+ layout.addLayout(control.headerLayout, 1, 1)
+ layout.addWidget(control.modifierList, 2, 1)
+
+ if restrictions[self.idxEdge]:
+ self.controls[self.idxEdge] = control = \
+ self.edgeBindingWidget('Edge')
+ layout.addWidget(control.typeLabel, 1, 2)
+ layout.addWidget(control.edgeList, 2, 2)
+ else:
+ layout.addItem(self.spacer(), 1, 2)
+ layout.addItem(self.spacer(), 2, 2)
+
+ return (None, None, self.bindingValue, self.bindingReset)
+
+
+ def bindingValue(self):
+ raise RuntimeError('Cannot fetch binding value')
+
+
+ def bindingReset(self):
+ value = self.initial
+ def reset(index):
+ enabled = value[index] != 'Disabled'
+ control = self.controls[index]
+
+ def valuenomod():
+ return value[index].split('>')[-1]
+
+ try:
+ control.keyLine.setText(enabled and valuenomod() or '')
+ except (AttributeError, ):
+ pass
+
+ try:
+ buttonList = control.buttonList
+ except (AttributeError, ):
+ pass
+ else:
+ buttonList.clear()
+ for text in self.pointerButtons:
+ buttonList.insertItem(text)
+ if enabled:
+ try:
+ buttonNo = valuenomod().replace('Button', '')
+ buttonList.setCurrentItem(int(buttonNo) - 1)
+ except (Exception, ), exc:
+ pass
+
+ def resetView(v, s):
+ v.clear()
+ for t in s[::-1]:
+ i = QCheckListItem(v, t, QCheckListItem.CheckBox)
+ i.setState(t in value[index] and i.On or i.Off)
+
+ try:
+ resetView(control.modifierList, self.modifiers)
+ except (AttributeError, ):
+ pass
+
+ try:
+ resetView(control.edgeList, self.edges)
+ except (AttributeError, ):
+ pass
+
+ try:
+ checkBox = control.enableCheck
+ checkBox.setChecked(enabled)
+ checkBox.emit(Signals.toggled, (enabled,))
+ except (AttributeError, ):
+ pass
+
+ ## use the closure
+ restrictions = self.setting.Restrictions
+ for key in (self.idxKey, self.idxPointer, self.idxEdge):
+ if restrictions[key]:
+ reset(key)
+
+ def bindingWidget(self, text, which):
+ connect = self.connect
+ ctl = self.control()
+ toggled = Signals.toggled
+ someChange = Signals.somethingChanged
+
+ ctl.headerLayout = headerLayout = QVBoxLayout()
+ ctl.enableCheck = enableCheck = QCheckBox(i18n('Enable'), self)
+ headerLayout.addWidget(enableCheck)
+
+ ctl.lineLayout = lineLayout = QHBoxLayout(headerLayout)
+ connect(enableCheck, Signals.clicked, self, someChange)
+ ctl.typeLabel = typeLabel = QLabel(text, self)
+ lineLayout.addWidget(typeLabel)
+ connect(enableCheck, toggled, typeLabel.setEnabled)
+
+ if which == self.idxKey:
+ ctl.keyLine = keyLine = KLineEdit(self)
+ lineLayout.addWidget(keyLine)
+ ctl.keyButton = keyButton = KPushButton(i18n('Grab'), self)
+ lineLayout.addWidget(keyButton)
+ connect(keyLine, Signals.textChanged, self, someChange)
+ connect(enableCheck, toggled, keyLine.setEnabled)
+ connect(enableCheck, toggled, keyButton.setEnabled)
+ elif which == self.idxPointer:
+ ctl.buttonList = buttonList = KComboBox(self)
+ lineLayout.addWidget(buttonList)
+ connect(buttonList, Signals.activatedIndex, self, someChange)
+ connect(enableCheck, toggled, buttonList.setEnabled)
+
+ ctl.modifierList = ShortListView(self, i18n('Modifiers'), 5)
+ connect(ctl.modifierList, Signals.itemSelected, self, someChange)
+ connect(enableCheck, toggled, ctl.modifierList.setEnabled)
+ return ctl
+
+ def edgeBindingWidget(self, text):
+ connect = self.connect
+ ctl = self.control()
+ ctl.typeLabel = QLabel(text, self)
+ ctl.edgeList = edgeList = ShortListView(self, i18n('Edges'), 5)
+ connect(edgeList, Signals.itemSelected, self, Signals.somethingChanged)
+ return ctl
+
+ class control(object):
+ """ add attributes to instances of this handy-and-empty class
+
+ """
+
+ def spacer(self):
+ """ creates and returns a new QSpacerItem
+
+ @return QSpacerItem instance
+ """
+ return QSpacerItem(1, 1, QSizePolicy.Expanding, QSizePolicy.Expanding)
class UnknownSettingWidget(SettingWidgetBase):
@@ -424,12 +633,19 @@ class UnknownSettingWidget(SettingWidgetBase):
"""
def build(self, parent, plugin, setting):
- layout = self.commonSetup(setting, layoutType=QHBoxLayout)
+ """ create widget(s) for setting display and edit
+
+ @param parent parent object of this widget
+ @param plugin berylsettings Plugin instance
+ @param setting berylsettings Setting instance
+ @return four-item tuple of (widget, signal, valuemethod, resetmethod)
+ """
+ layout = self.labeledLayout(setting, layoutType=QHBoxLayout)
text = '%s (Unknown Type %s)' % (setting.ShortDesc, setting.Type, )
self.label.setText(text)
return (self.label, Signals.clicked, None, None)
- def inspect(cls, plugin, setting):
+ def query(cls, plugin, setting):
""" matches plugin and setting names to local method names
@param cls class object
@@ -438,23 +654,7 @@ class UnknownSettingWidget(SettingWidgetBase):
@return True
"""
return True
- inspect = classmethod(inspect)
-
-
-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)
-
-
-def cbText(o):
- return str(o.text()).replace('&', '')
+ query = classmethod(query)
class LocalGroupBox(QGroupBox):
@@ -463,3 +663,7 @@ class LocalGroupBox(QGroupBox):
self.setFlat(True)
self.setInsideMargin(margin)
self.setInsideSpacing(spacing)
+
+ def addSpaces(self, count, size=0):
+ for i in range(count):
+ self.addSpace(size)
diff --git a/kberylsettings/widget.py b/kberylsettings/widget.py
index 246c29d..f86a73a 100644
--- a/kberylsettings/widget.py
+++ b/kberylsettings/widget.py
@@ -12,11 +12,11 @@ class Frame(QFrame):
""" Frame -> QFrame with QVBoxLayout
"""
- def __init__(self, parent, margin=0, spacing=-1):
+ def __init__(self, parent, margin=0, spacing=-1, autoAdd=True):
QFrame.__init__(self, parent)
layout = QVBoxLayout(self, margin, spacing)
layout.setAlignment(Qt.AlignTop | Qt.AlignLeft)
- layout.setAutoAdd(True)
+ layout.setAutoAdd(autoAdd)
class Popup(KPopupMenu):
@@ -35,6 +35,7 @@ class Splitter(QSplitter):
def __init__(self, parent, style):
QSplitter.__init__(self, style, parent)
self.setOpaqueResize(True)
+ self.setChildrenCollapsible(False)
class SmallPushButton(KPushButton):
@@ -61,6 +62,7 @@ class ListView(KListView):
"""
def __init__(self, parent):
KListView.__init__(self, parent)
+ self.setSorting(-1)
def __iter__(self):
""" iterate over QListView items
@@ -74,6 +76,19 @@ class ListView(KListView):
item = it.current()
+class ShortListView(ListView):
+ def __init__(self, parent, text, lines):
+ ListView.__init__(self, parent)
+ self.addColumn(text)
+ self.setResizeMode(self.LastColumn)
+ self.setHeightLines(lines)
+
+ def setHeightLines(self, num):
+ height = self.fontMetrics().lineSpacing() * num
+ height += self.header().height()
+ self.setMaximumHeight(height)
+
+
class WidgetStack(QWidgetStack):
""" WidgetStack -> QWidgetStack with QVBoxLayout