diff options
Diffstat (limited to 'examples/pykde-sampler/sampler.py')
-rwxr-xr-x | examples/pykde-sampler/sampler.py | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/examples/pykde-sampler/sampler.py b/examples/pykde-sampler/sampler.py new file mode 100755 index 0000000..bacf634 --- /dev/null +++ b/examples/pykde-sampler/sampler.py @@ -0,0 +1,423 @@ +#!/usr/bin/env python +""" The PyKDE application sampler + +This module defines the top-level widgets for displaying the sampler +application. + + +""" +import inspect +import os +import sys + +from qt import SIGNAL, SLOT, PYSIGNAL, Qt +from qt import QVBoxLayout, QLabel, QPixmap, QSplitter, QFrame, QDialog +from qt import QSizePolicy, QHBoxLayout, QSpacerItem, QPushButton + +from kdecore import i18n, KAboutData, KApplication, KCmdLineArgs, KGlobal +from kdecore import KGlobalSettings, KWin, KWinModule, KURL, KIcon + +from kdeui import KComboBox, KListView, KListViewItem, KTabWidget, KTextEdit +from kdeui import KMainWindow, KPushButton, KSplashScreen, KStdAction +from kdeui import KKeyDialog, KEditToolbar + +from kio import KTrader +from kparts import createReadOnlyPart, createReadWritePart +from khtml import KHTMLPart + +import about +import lib + + +try: + __file__ +except (NameError, ): + __file__ = sys.argv[0] + + +sigDoubleClicked = SIGNAL('doubleClicked(QListViewItem *)') +sigViewItemSelected = SIGNAL('selectionChanged(QListViewItem *)') +sigSampleSelected = PYSIGNAL('sample selected') + +blank = KURL('about:blank') + + +def appConfig(group=None): + """ appConfig(group=None) -> returns the application KConfig + + """ + config = KGlobal.instance().config() + if group is not None: + config.setGroup(group) + return config + + +def getIcon(name, group=KIcon.NoGroup, size=KIcon.SizeSmall): + """ returns a kde icon by name + + """ + return KGlobal.instance().iconLoader().loadIcon(name, group, size) + + +def getIconSet(name, group=KIcon.NoGroup, size=KIcon.SizeSmall): + """ returns a kde icon set by name + + """ + return KGlobal.instance().iconLoader().loadIconSet(name, group, size) + + +def buildPart(parent, query, constraint, writable=False): + """ builds the first available offered part on the parent + + """ + offers = KTrader.self().query(query, constraint) + for ptr in offers: + if writable: + builder = createReadWritePart + else: + builder = createReadOnlyPart + part = builder(ptr.library(), parent, ptr.name()) + if part: + break + return part + + + +class CommonFrame(QFrame): + """ provides a modicum of reuse + + """ + def __init__(self, parent): + QFrame.__init__(self, parent) + layout = QVBoxLayout(self) + layout.setAutoAdd(True) + layout.setAlignment(Qt.AlignCenter | Qt.AlignVCenter) + + +class SamplerFrame(CommonFrame): + """ frame type that swaps out old widgets for new when told to do so + + """ + def __init__(self, parent): + CommonFrame.__init__(self, parent) + self.widget = None + + def setWidget(self, widget): + self.layout().deleteAllItems() + previous = self.widget + if previous: + previous.close() + delattr(self, 'widget') + self.widget = widget + + def showSample(self, item, module): + try: + frameType = module.builder() + except (AttributeError, ): + print 'No sample callable defined in %s' % (module.name(), ) + else: + frame = frameType(self) + self.setWidget(frame) + frame.show() + + +class SourceFrame(CommonFrame): + """ frame with part for displaying python source + + """ + def __init__(self, parent): + CommonFrame.__init__(self, parent) + query = '' + self.part = buildPart(self, 'application/x-python', query, False) + + def showModuleSource(self, item, module): + if not self.part: + print 'No part available for displaying python source.' + return + try: + modulefile = inspect.getabsfile(module.module) + except: + return + self.part.openURL(blank) + if os.path.splitext(modulefile)[-1] == '.py': + self.part.openURL(KURL('file://%s' % modulefile)) + + +class WebFrame(CommonFrame): + """ frame with part for viewing web pages + + """ + docBase = 'http://www.riverbankcomputing.com/Docs/PyKDE3/classref/' + + def __init__(self, parent): + CommonFrame.__init__(self, parent) + self.part = part = buildPart(self, 'text/html', "Type == 'Service'") + #part.connect(part, SIGNAL('khtmlMousePressEvent(a)'), self.onURL) + + def onURL(self, a): + print '****', a + + def showDocs(self, item, module): + try: + mod, cls = module.module.docParts + except (AttributeError, ): + url = blank + else: + url = KURL(self.docUrl(mod, cls)) + self.part.openURL(url) + + + def docUrl(self, module, klass): + """ docUrl(name) -> return a doc url given a name from the kde libs + + """ + return '%s/%s/%s.html' % (self.docBase, module, klass, ) + + +class OutputFrame(KTextEdit): + """ text widget that acts (just enough) like a file + + """ + def __init__(self, parent, filehandle): + KTextEdit.__init__(self, parent) + self.filehandle = filehandle + self.setReadOnly(True) + self.setFont(KGlobalSettings.fixedFont()) + + + def write(self, text): + self.insert(text) + + + def clear(self): + self.setText('') + + + def __getattr__(self, name): + return getattr(self.filehandle, name) + + +class SamplerListView(KListView): + """ the main list view of samples + + """ + def __init__(self, parent): + KListView.__init__(self, parent) + self.addColumn(i18n('Sample')) + self.setRootIsDecorated(True) + + modules = lib.listmodules() + modules.sort(lambda a, b: cmp(a[0], b[0])) + + modmap = dict(modules) + modules = [(name.split('.'), name, mod) for name, mod in modules] + roots, cache = {}, {} + + for names, modname, module in modules: + topname, subnames = names[0], names[1:] + item = roots.get(topname, None) + if item is None: + roots[topname] = item = KListViewItem(self, module.labelText()) + item.module = module + item.setPixmap(0, getIcon(module.icon())) + + bname = '' + subitem = item + for subname in subnames: + bname = '%s.%s' % (bname, subname, ) + item = cache.get(bname, None) + if item is None: + subitem = cache[bname] = \ + KListViewItem(subitem, module.labelText()) + subitem.module = module + subitem.setPixmap(0, getIcon(module.icon())) + subitem = item + + for root in roots.values(): + self.setOpen(root, True) + + +class SamplerMainWindow(KMainWindow): + """ the main window + + """ + def __init__(self, *args): + KMainWindow.__init__(self, *args) + self.hSplitter = hSplit = QSplitter(Qt.Horizontal, self) + self.samplesList = samplesList = SamplerListView(hSplit) + self.vSplitter = vSplit = QSplitter(Qt.Vertical, hSplit) + self.setCentralWidget(hSplit) + self.setIcon(getIcon('kmail')) + + hSplit.setOpaqueResize(True) + vSplit.setOpaqueResize(True) + + self.contentTabs = cTabs = KTabWidget(vSplit) + self.outputTabs = oTabs = KTabWidget(vSplit) + + self.sampleFrame = SamplerFrame(cTabs) + self.sourceFrame = SourceFrame(cTabs) + self.webFrame = WebFrame(cTabs) + + cTabs.insertTab(self.sampleFrame, getIconSet('exec'), i18n('Sample')) + cTabs.insertTab(self.sourceFrame, getIconSet('source'), i18n('Source')) + cTabs.insertTab(self.webFrame, getIconSet('help'), i18n('Docs')) + + sys.stdout = self.stdoutFrame = OutputFrame(oTabs, sys.stdout) + sys.stderr = self.stderrFrame = OutputFrame(oTabs, sys.stderr) + + termIcons = getIconSet('terminal') + oTabs.insertTab(self.stdoutFrame, termIcons, i18n('stdout')) + oTabs.insertTab(self.stderrFrame, termIcons, i18n('stderr')) + + self.resize(640, 480) + height, width = self.height(), self.width() + hSplit.setSizes([width * 0.35, width * 0.65]) + vSplit.setSizes([height * 0.80, height * 0.20]) + + self.xmlRcFileName = os.path.abspath(os.path.join(os.path.dirname(__file__), 'sampler.rc')) + self.setXMLFile(self.xmlRcFileName) + config = appConfig() + actions = self.actionCollection() + actions.readShortcutSettings("", config) + self.quitAction = KStdAction.quit(self.close, actions) + + self.toggleMenubarAction = \ + KStdAction.showMenubar(self.showMenubar, actions) + self.toggleToolbarAction = \ + KStdAction.showToolbar(self.showToolbar, actions) + self.toggleStatusbarAction = \ + KStdAction.showStatusbar(self.showStatusbar, actions) + self.configureKeysAction = \ + KStdAction.keyBindings(self.showConfigureKeys, actions) + self.configureToolbarAction = \ + KStdAction.configureToolbars(self.showConfigureToolbars, actions) + self.configureAppAction = \ + KStdAction.preferences(self.showConfiguration, actions) + + connect = self.connect + connect(samplesList, sigViewItemSelected, self.sampleSelected) + connect(self, sigSampleSelected, self.reloadModule) + connect(self, sigSampleSelected, self.sourceFrame.showModuleSource) + connect(self, sigSampleSelected, self.sampleFrame.showSample) + connect(self, sigSampleSelected, self.webFrame.showDocs) + + self.restoreWindowSize(config) + self.createGUI(self.xmlRcFileName, 0) + self.sourceFrame.part.openURL(KURL('file://%s' % os.path.abspath(__file__))) + + + def showConfiguration(self): + """ showConfiguration() -> display the config dialog + + """ + return + ## not yet implemented + dlg = configdialog.ConfigurationDialog(self) + for obj in (self.stderrFrame, self.stdoutFrame, self.pythonShell): + call = getattr(obj, 'configChanged', None) + if call: + self.connect(dlg, util.sigConfigChanged, call) + dlg.show() + + + def senderCheckShow(self, widget): + """ senderCheckShow(widget) -> show or hide widget if sender is checked + + """ + if self.sender().isChecked(): + widget.show() + else: + widget.hide() + + + def showMenubar(self): + """ showMenuBar() -> toggle the menu bar + + """ + self.senderCheckShow(self.menuBar()) + + + def showToolbar(self): + """ showToolbar() -> toggle the tool bar + + """ + self.senderCheckShow(self.toolBar()) + + + def showStatusbar(self): + """ showStatusbar() -> toggle the status bar + + """ + self.senderCheckShow(self.statusBar()) + + + def showConfigureKeys(self): + """ showConfigureKeys() -> show the shortcut keys dialog + + """ + ret = KKeyDialog.configure(self.actionCollection(), self) + print ret + if ret == QDialog.Accepted: + actions = self.actionCollection() + actions.writeShortcutSettings(None, appConfig()) + + + def showConfigureToolbars(self): + """ showConfigureToolbars() -> broken + + """ + dlg = KEditToolbar(self.actionCollection(), self.xmlRcFileName) + self.connect(dlg, SIGNAL('newToolbarConfig()'), self.rebuildGui) + #connect(self, sigSampleSelected, self.sourceFrame.showModuleSource) + + dlg.exec_loop() + + + def rebuildGui(self): + """ rebuildGui() -> recreate the gui and refresh the palette + + """ + self.createGUI(self.xmlRcFileName, 0) + for widget in (self.toolBar(), self.menuBar(), ): + widget.setPalette(self.palette()) + + + def sampleSelected(self): + """ sampleSelected() -> emit the current item and its module + + """ + self.stdoutFrame.clear() + self.stderrFrame.clear() + item = self.sender().currentItem() + self.emit(sigSampleSelected, (item, item.module)) + + + def setSplashPixmap(self, pixmap): + """ setSplashPixmap(pixmap) -> assimilate the splash screen pixmap + + """ + target = self.sampleFrame + label = QLabel(target) + label.setPixmap(pixmap) + target.setWidget(label) + + + def reloadModule(self, item, module): + print >> sys.__stdout__, 'reload: ', reload(module.module) + + +if __name__ == '__main__': + aboutdata = about.about() + KCmdLineArgs.init(sys.argv, aboutdata) + app = KApplication() + + splashpix = QPixmap(os.path.join(lib.samplerpath, 'aboutkde.png')) + splash = KSplashScreen(splashpix) + splash.resize(splashpix.size()) + splash.show() + mainWindow = SamplerMainWindow() + mainWindow.setSplashPixmap(splashpix) + mainWindow.show() + splash.finish(mainWindow) + app.exec_loop() |