Thread: SF.net SVN: fclient:[947] trunk/fclient/fclient/impl/lib/qt4ex
Status: Pre-Alpha
Brought to you by:
jurner
From: <jU...@us...> - 2008-08-21 11:08:54
|
Revision: 947 http://fclient.svn.sourceforge.net/fclient/?rev=947&view=rev Author: jUrner Date: 2008-08-21 11:09:03 +0000 (Thu, 21 Aug 2008) Log Message: ----------- add bookmarks dialog Added Paths: ----------- trunk/fclient/fclient/impl/lib/qt4ex/dlgbookmarks.py trunk/fclient/fclient/impl/lib/qt4ex/tpls/Ui_DlgBookmarks.py Added: trunk/fclient/fclient/impl/lib/qt4ex/dlgbookmarks.py =================================================================== --- trunk/fclient/fclient/impl/lib/qt4ex/dlgbookmarks.py (rev 0) +++ trunk/fclient/fclient/impl/lib/qt4ex/dlgbookmarks.py 2008-08-21 11:09:03 UTC (rev 947) @@ -0,0 +1,366 @@ +#******************************************************************************************** +#TODO: +# +# x. QTreeWidget does not clear selections when items are collapsed. so selected items will +# always be set to visible even if they where collapsed by the user before saving bookmarks +# x. clients may want to adjust label texts +# x. clients may want to adjust "target" edit box to a custom thingy +# +# x. fresh from boilerplate. not tested +# +#******************************************************************************************* +"""bookmarks dialog""" +from __future__ import absolute_import +if __name__ == '__main__': # see --> http://bugs.python.org/issue1510172 . works only current dir and below + import os; __path__ = [os.path.dirname(__file__)] + +from PyQt4 import QtCore, QtGui + +from xml.etree import cElementTree as ET + +from . import treewidgetwrap +from .tpls.Ui_DlgBookmarks import Ui_DlgBookmarks +#********************************************************************* +# +#********************************************************************* +class Actions(object): + + def __init__(self, parent): + + self.newBookmark = QtGui.QAction(parent) + parent.connect(self.newBookmark, QtCore.SIGNAL('triggered()'), parent.onNewBookmark) + self.newFolder = QtGui.QAction(parent) + parent.connect(self.newFolder, QtCore.SIGNAL('triggered()'), parent.onNewFolder) + self.deleteItem = QtGui.QAction(parent) + parent.connect(self.deleteItem, QtCore.SIGNAL('triggered()'), parent.onDeleteItem) + self.deleteItem.setEnabled(False) + + def retranslateUi(self, parent): + self.newBookmark.setText(parent.trUtf8('New bookmark')) + self.newFolder.setText(parent.trUtf8('New folder')) + self.deleteItem.setText(parent.trUtf8('Remove')) + + +class EventFilter(QtCore.QObject): + """event filter for the dialog""" + + def eventFilter(self, obj, event): + # filter return pressed on dlg subwidgets if desired + if event.type() == event.KeyPress: + if event.key() == QtCore.Qt.Key_Return: + dlg = self.parent() + if dlg.swallowReturnPressed(): + return True + return False + +#********************************************************************* +# +#********************************************************************* +class DlgBookmarks(QtGui.QDialog, Ui_DlgBookmarks): + + IdTree = 'tree' + IdEdName = 'edName' + IdEdTarget = 'edTarget' + + + ItemTypeFolder = 0 + ItemTypeItem = 1 + + def __init__(self, parent=None, rootElem=None): + QtGui.QDialog.__init__(self, parent) + + self.isCreated = False + self.dlgActions = Actions(self) + self.setupUi(self) + self.installEventFilter(EventFilter(self)) + + # setup tree + tree = self.controlById(self.IdTree) + tree.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + self.connect(tree, QtCore.SIGNAL('customContextMenuRequested(const QPoint &)'), self.onTreeCustomContextMenu) + self.connect(tree, QtCore.SIGNAL('currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)'), self.onTreeCurrentItemChanged) + + # setup edit boxes + edName = self.controlById(self.IdEdName) + self.connect(edName, QtCore.SIGNAL('returnPressed()'), self.onEdNameReturnPressed) + edName.setEnabled(False) + + edTarget = self.controlById(self.IdEdTarget) + self.connect(edTarget, QtCore.SIGNAL('returnPressed()'), self.onEdTargetReturnPressed) + edTarget.setEnabled(False) + + # init bookmarks if desired + #TODO: move to a better place to speed up dlg show + if rootElem is not None: + self.restoreBookmarks(rootElem) + + ################## + ## private methods + ################## + def _addBookmark(self, parent, name=None, target=None): + item= QtGui.QTreeWidgetItem(parent, self.ItemTypeItem) + item.setText(0, self.nameForNewItem(self.ItemTypeItem) if name is None else name) + item.setText(1, QtCore.QString('') if target is None else target) + item.setIcon(0, self.iconForItem(self.ItemTypeItem, QtCore.QString(''))) + item.setFlags(item.flags() & ~(QtCore.Qt.ItemIsDropEnabled | QtCore.Qt.ItemIsEditable)) + return item + + def _addFolder(self, parent, name=None): + item= QtGui.QTreeWidgetItem(parent, self.ItemTypeFolder) + item.setText(0, self.nameForNewItem(self.ItemTypeFolder) if name is None else name) + item.setIcon(0, self.iconForItem(self.ItemTypeFolder, QtCore.QString(''))) + item.setFlags(item.flags() & ~QtCore.Qt.ItemIsEditable) + return item + + ################## + ## methods + ################## + def retranslateUi(self, this): + Ui_DlgBookmarks.retranslateUi(self, this) + self.dlgActions.retranslateUi(self) + tree = self.controlById(self.IdTree) + tree.setHeaderLabels([ + self.trUtf8('Name'), + self.trUtf8('Target'), + ]) + + def controlById(self, idControl): + return getattr(self, idControl) + + def itemIsFolder(self, item): + tree = self.controlById(self.IdTree) + if item == tree.invisibleRootItem() or item.type() == self.ItemTypeFolder: + return True + return False + + def saveBookmarks(self): + """saves the bookmarks + @return: (ElementTree.Element) root + """ + tree = self.controlById(self.IdTree) + enum = treewidgetwrap.walkItem(tree.invisibleRootItem()) + rootItem = enum.next() + rootElem = ET.Element('bookmarks', columnWidthName=str(tree.columnWidth(0))) + stack = [(rootElem, rootItem), ] + + selectedItems = tree.selectedItems() + selectedItem = selectedItems[0] if selectedItems else None + + for item in enum: + if item.type() == self.ItemTypeFolder: + # clear parents from stack + parent = item.parent() + if parent is None: + parent = rootItem + while parent != stack[-1][1]: + stack.pop() + elem = ET.SubElement(stack[-1][0], 'folder', expanded=str(item.isExpanded()), selected=str(item is selectedItem)) + stack.append((elem, item)) + elemName = ET.SubElement(elem, 'name') + elemName.text = unicode(item.text(0)) + else: + elem = ET.SubElement(stack[-1][0], 'bookmark', selected=str(item is selectedItem)) + elemName = ET.SubElement(elem, 'name') + elemName.text = unicode(item.text(0)) + elemTarget = ET.SubElement(elem, 'target') + elemTarget.text = unicode(item.text(1)) + + return ET.ElementTree(rootElem) + + + #TODO: in depth error checks + def restoreBookmarks(self, rootElem): + """sets the bookmarks of the dialog + @param rootElem: (ElementTree.Element) root + @return: (bool) True if errors occured, False otherwise + """ + tree = self.controlById(self.IdTree) + tree.clear() + rootItem = tree.invisibleRootItem() + enum = rootElem.getiterator() + rootElem = enum.next() + parentMap = dict((c, p) for p in rootElem.getiterator() for c in p) + ok = True + stack = [(rootElem, rootItem), ] + selectedItem = None + + if rootElem.tag != 'bookmarks': + ok = False + else: + + # restore properties... + columnWidthName = rootElem.get('columnWidthName', None) + try: + tree.setColumnWidth(0, int(columnWidthName)) + except ValueError: + pass + + # restore elems.. + for elem in enum: + if elem.tag == 'folder': + # clear parents from stack + parent= parentMap[elem] + while parent != stack[-1][0]: + stack.pop() + name = elem.find('name') + if name is None: + ok = False + continue + item = self._addFolder(stack[-1][1], name.text) + stack.append((elem, item)) + if elem.get('expanded', 'False').lower() == 'true': + item.setExpanded(True) + selectedItem = item if elem.get('selected', 'False').lower() == 'true' else selectedItem + + elif elem.tag == 'bookmark': + name = elem.find('name') + if name is None: + ok = False + continue + target = elem.find('target') + if target is None: + ok = False + continue + item = self._addBookmark(stack[-1][1], name.text, target.text) + selectedItem = item if elem.get('selected', 'False').lower() == 'true' else selectedItem + + if selectedItem is not None: + tree.scrollToItem(selectedItem) + tree.setCurrentItem(selectedItem) + return ok + + ####################### + ## overwrite to customize the dialog + ####################### + def nameForNewItem(self, itemType): + """should return the default name for a new item + @param itemType: (ItemType*) one of the ItemType* consts + @return: (QString) + """ + if itemType == self.ItemTypeFolder: + return self.trUtf8('New folder') + return self.trUtf8('Unnamed') + + + def iconForItem(self, itemType, itemTarget): + """"should return the icon associated to an item + @param itemType: (ItemType*) one of the ItemType* consts + @param itemTarget: (QString) the target the item points to + @return (QIcon) + """ + return QtGui.QIcon() + + + def swallowReturnPressed(self): + """called to check if return pressed on a subwidget should be swallowed or not + @return: (bool) True if so, False otherwise + @note: use this to swallow for example return presses in edit boxes to not end the dialog + """ + return self.controlById(self.IdEdName).hasFocus() or self.controlById(self.IdEdTarget).hasFocus() + + ###################### + ## event handlers + ###################### + def onDeleteItem(self): + tree = self.controlById(self.IdTree) + item = tree.currentItem() + if item is not None: + parent = item.parent() + if parent is None: + parent = tree.invisibleRootItem() + parent.takeChild(parent.indexOfChild(item)) + + def onEdNameReturnPressed(self): + ed = self.controlById(self.IdEdName) + tree = self.controlById(self.IdTree) + item = tree.currentItem() + if item is not None: + item.setText(0, ed.text()) + + def onEdTargetReturnPressed(self): + ed = self.controlById(self.IdEdTarget) + tree = self.controlById(self.IdTree) + item = tree.currentItem() + if item is not None: + item.setText(1, ed.text()) + item.setIcon(0, self.iconForItem(self.ItemTypeItem, QtCore.QString(''))) + + + def onNewBookmark(self): + tree = self.controlById(self.IdTree) + parent = tree.currentItem() + if parent is None: + parent = tree.invisibleRootItem() + item = self._addBookmark(parent) + tree.scrollToItem(item) + tree.setCurrentItem(item) + + def onNewFolder(self): + tree = self.controlById(self.IdTree) + parent = tree.currentItem() + if parent is None: + parent = tree.invisibleRootItem() + + item = self._addFolder(parent) + tree.scrollToItem(item) + tree.setCurrentItem(item) + + + def onTreeCustomContextMenu(self, pt): + tree = self.controlById(self.IdTree) + pt = tree.viewport().mapToGlobal(pt) + + menu = QtGui.QMenu(self) + + menu.addAction(self.dlgActions.newBookmark) + menu.addAction(self.dlgActions.newFolder) + menu.addSeparator() + menu.addAction(self.dlgActions.deleteItem) + + menu.exec_(pt) + + + def onTreeCurrentItemChanged(self, current, prev): + edName = self.controlById(self.IdEdName) + edTarget = self.controlById(self.IdEdTarget) + tree = self.controlById(self.IdTree) + + itemIsFolder = True if current is None else self.itemIsFolder(current) + + edName.setEnabled(not current is None) + edTarget.setEnabled(not current is None and not itemIsFolder) + edName.setText('' if current is None else current.text(0)) + edTarget.setText('' if current is None else current.text(1)) + + self.dlgActions.newBookmark.setEnabled(itemIsFolder) + self.dlgActions.newFolder.setEnabled(itemIsFolder) + self.dlgActions.deleteItem.setEnabled(not current is None) + +#********************************************************************* +# +#********************************************************************* + +if __name__ == '__main__': + import sys, os + + # try to restore saved bookmarks + rootElem = None + fpath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'bookmarks.xml') + try: + tree = ET.parse(fpath) + except IOError: + pass + else: + rootElem = tree.getroot() + + # show dialog + app = QtGui.QApplication(sys.argv) + w = DlgBookmarks(None, rootElem=rootElem) + w.show() + res = app.exec_() + + # save bookmarks + rootElem = w.saveBookmarks() + rootElem.write(fpath, encoding='utf-8') + + sys.exit(res) \ No newline at end of file Added: trunk/fclient/fclient/impl/lib/qt4ex/tpls/Ui_DlgBookmarks.py =================================================================== --- trunk/fclient/fclient/impl/lib/qt4ex/tpls/Ui_DlgBookmarks.py (rev 0) +++ trunk/fclient/fclient/impl/lib/qt4ex/tpls/Ui_DlgBookmarks.py 2008-08-21 11:09:03 UTC (rev 947) @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file '/home/me/src/fclient/trunk/fclient/fclient/impl/lib/qt4ex/tpls/DlgBookmarks.ui' +# +# Created: Thu Aug 21 13:07:31 2008 +# by: PyQt4 UI code generator 4.4.2 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +class Ui_DlgBookmarks(object): + def setupUi(self, DlgBookmarks): + DlgBookmarks.setObjectName("DlgBookmarks") + DlgBookmarks.resize(400,567) + self.gridLayout = QtGui.QGridLayout(DlgBookmarks) + self.gridLayout.setObjectName("gridLayout") + self.labelHeader = QtGui.QLabel(DlgBookmarks) + self.labelHeader.setObjectName("labelHeader") + self.gridLayout.addWidget(self.labelHeader,0,0,1,1) + self.tree = QtGui.QTreeWidget(DlgBookmarks) + self.tree.setDragEnabled(True) + self.tree.setDragDropMode(QtGui.QAbstractItemView.InternalMove) + self.tree.setColumnCount(2) + self.tree.setObjectName("tree") + self.gridLayout.addWidget(self.tree,1,0,1,1) + self.horizontalLayout = QtGui.QHBoxLayout() + self.horizontalLayout.setObjectName("horizontalLayout") + self.verticalLayout = QtGui.QVBoxLayout() + self.verticalLayout.setObjectName("verticalLayout") + self.label = QtGui.QLabel(DlgBookmarks) + self.label.setObjectName("label") + self.verticalLayout.addWidget(self.label) + self.label_2 = QtGui.QLabel(DlgBookmarks) + self.label_2.setObjectName("label_2") + self.verticalLayout.addWidget(self.label_2) + self.horizontalLayout.addLayout(self.verticalLayout) + self.verticalLayout_2 = QtGui.QVBoxLayout() + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.edName = QtGui.QLineEdit(DlgBookmarks) + self.edName.setObjectName("edName") + self.verticalLayout_2.addWidget(self.edName) + self.edTarget = QtGui.QLineEdit(DlgBookmarks) + self.edTarget.setObjectName("edTarget") + self.verticalLayout_2.addWidget(self.edTarget) + self.horizontalLayout.addLayout(self.verticalLayout_2) + self.gridLayout.addLayout(self.horizontalLayout,2,0,1,1) + self.line = QtGui.QFrame(DlgBookmarks) + self.line.setFrameShape(QtGui.QFrame.HLine) + self.line.setFrameShadow(QtGui.QFrame.Sunken) + self.line.setObjectName("line") + self.gridLayout.addWidget(self.line,3,0,1,1) + self.buttonBox = QtGui.QDialogButtonBox(DlgBookmarks) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName("buttonBox") + self.gridLayout.addWidget(self.buttonBox,4,0,1,1) + + self.retranslateUi(DlgBookmarks) + QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),DlgBookmarks.accept) + QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),DlgBookmarks.reject) + QtCore.QMetaObject.connectSlotsByName(DlgBookmarks) + + def retranslateUi(self, DlgBookmarks): + DlgBookmarks.setWindowTitle(QtGui.QApplication.translate("DlgBookmarks", "Edit bookmarks..", None, QtGui.QApplication.UnicodeUTF8)) + self.labelHeader.setText(QtGui.QApplication.translate("DlgBookmarks", "Edit bookmarks", None, QtGui.QApplication.UnicodeUTF8)) + self.tree.headerItem().setText(0,QtGui.QApplication.translate("DlgBookmarks", "1", None, QtGui.QApplication.UnicodeUTF8)) + self.tree.headerItem().setText(1,QtGui.QApplication.translate("DlgBookmarks", "2", None, QtGui.QApplication.UnicodeUTF8)) + self.label.setText(QtGui.QApplication.translate("DlgBookmarks", "Name:", None, QtGui.QApplication.UnicodeUTF8)) + self.label_2.setText(QtGui.QApplication.translate("DlgBookmarks", "Target:", None, QtGui.QApplication.UnicodeUTF8)) + + +if __name__ == "__main__": + import sys + app = QtGui.QApplication(sys.argv) + DlgBookmarks = QtGui.QDialog() + ui = Ui_DlgBookmarks() + ui.setupUi(DlgBookmarks) + DlgBookmarks.show() + sys.exit(app.exec_()) + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |