Mon, 21 Apr 2014 15:25:27 +0200
Finished implementing the functionality.
--- a/PluginSelectionEncloser.py Fri Apr 18 19:46:40 2014 +0200 +++ b/PluginSelectionEncloser.py Mon Apr 21 15:25:27 2014 +0200 @@ -98,10 +98,24 @@ self.__ui = ui # menu is a list of lists; each list consists of a string for the - # submenu title and a list of submenu entries. The title of the submenu - # entry is the enclosing string. + # submenu title and a list of submenu entries. Each submenu entry + # consists of another list giving the title and the enclosing string + # or formatting string. defaultMenu = [ - [self.tr("Quotes"), ['"', "'", '"""', "'''"]], + [self.tr("Quotes"), [ + ['"', '"'], + ["'", "'"], + ['"""', '"""'], + ["'''", "'''"] + ]], + [self.tr("HTML"), [ + ['<h1>', '<h1>{0}</h1>'], + ['<h2>', '<h2>{0}</h2>'], + ['<h3>', '<h3>{0}</h3>'], + ['<p>', '<p>{0}</p>'], + ['<div>', '<div>{0}</div>'], + ['<span>', '<span>{0}</span>'], + ]] ] self.__defaults = { "MenuHierarchy": json.dumps(defaultMenu), @@ -283,9 +297,9 @@ hierarchy = self.getPreferences("MenuHierarchy") for menuTitle, entries in hierarchy: submenu = QMenu(menuTitle, self.__menu) - for entry in entries: - act = submenu.addAction(entry, self.__encloseSelection) - act.setData(entry) + for title, encString in entries: + act = submenu.addAction(title, self.__encloseSelection) + act.setData(encString) self.__menu.addMenu(submenu) def __encloseSelection(self): @@ -307,7 +321,12 @@ if not string: return - newText = string + editor.selectedText() + string + if '%s' in string: + newText = string % editor.selectedText() + elif '{0}' in string: + newText = string.format(editor.selectedText()) + else: + newText = string + editor.selectedText() + string editor.beginUndoAction() editor.replaceSelectedText(newText) editor.endUndoAction()
--- a/SelectionEncloser.e4p Fri Apr 18 19:46:40 2014 +0200 +++ b/SelectionEncloser.e4p Mon Apr 21 15:25:27 2014 +0200 @@ -19,9 +19,11 @@ <Source>SelectionEncloser/__init__.py</Source> <Source>SelectionEncloser/ConfigurationPage/__init__.py</Source> <Source>SelectionEncloser/ConfigurationPage/SelectionEncloserPage.py</Source> + <Source>SelectionEncloser/ConfigurationPage/SelectionEncloserEditDialog.py</Source> </Sources> <Forms> <Form>SelectionEncloser/ConfigurationPage/SelectionEncloserPage.ui</Form> + <Form>SelectionEncloser/ConfigurationPage/SelectionEncloserEditDialog.ui</Form> </Forms> <Translations/> <Resources/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SelectionEncloser/ConfigurationPage/SelectionEncloserEditDialog.py Mon Apr 21 15:25:27 2014 +0200 @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to edit an enclosing menu entry. +""" + +from __future__ import unicode_literals # __IGNORE_WARNING__ + +from PyQt4.QtCore import pyqtSlot +from PyQt4.QtGui import QDialog, QDialogButtonBox + +from .Ui_SelectionEncloserEditDialog import Ui_SelectionEncloserEditDialog + + +class SelectionEncloserEditDialog(QDialog, Ui_SelectionEncloserEditDialog): + """ + Class implementing a dialog to edit an enclosing menu entry. + """ + def __init__(self, title="", string="", parent=None): + """ + Constructor + + @param title menu entry title (string) + @param string enclosing string or string format expression (string) + @param parent reference to the parent widget (QWidget) + """ + super().__init__(parent) + self.setupUi(self) + + self.titleEdit.setText(title) + self.stringEdit.setText(string) + + msh = self.minimumSizeHint() + self.resize(max(self.size().width(), msh.width()), msh.height()) + + self.__updateOkButton() + + def __updateOkButton(self): + """ + Private slot to set the status of the OK button. + """ + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled( + bool(self.titleEdit.text()) and bool(self.stringEdit.text())) + + @pyqtSlot(str) + def on_titleEdit_textChanged(self, txt): + """ + Private slot to react on changes of the title. + + @param txt title text (string) + """ + self.__updateOkButton() + + @pyqtSlot(str) + def on_stringEdit_textChanged(self, txt): + """ + Private slot to react on changes of the string. + + @param txt enclosing string (string) + """ + self.__updateOkButton() + + def getData(self): + """ + Public method to get the dialog data. + + @return tuple with menu entry title (string) and enclosing string + or string format expression (string) + """ + return self.titleEdit.text(), self.stringEdit.text()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SelectionEncloser/ConfigurationPage/SelectionEncloserEditDialog.ui Mon Apr 21 15:25:27 2014 +0200 @@ -0,0 +1,102 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>SelectionEncloserEditDialog</class> + <widget class="QDialog" name="SelectionEncloserEditDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>500</width> + <height>130</height> + </rect> + </property> + <property name="windowTitle"> + <string>Menu Entry</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Title:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="titleEdit"> + <property name="toolTip"> + <string>Enter the menu entry title</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>String:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="stringEdit"> + <property name="toolTip"> + <string>Enter the enclosing string or string format expression</string> + </property> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string><b>Note</b>: '%s' or '{0}' is replace by the selected text</string> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>SelectionEncloserEditDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>SelectionEncloserEditDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- a/SelectionEncloser/ConfigurationPage/SelectionEncloserPage.py Fri Apr 18 19:46:40 2014 +0200 +++ b/SelectionEncloser/ConfigurationPage/SelectionEncloserPage.py Mon Apr 21 15:25:27 2014 +0200 @@ -1,5 +1,8 @@ # -*- coding: utf-8 -*- +# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# + """ Module implementing Selection Encloser configuration page. """ @@ -9,7 +12,7 @@ import os from PyQt4.QtCore import pyqtSlot, Qt -from PyQt4.QtGui import QTreeWidgetItem, QInputDialog, QLineEdit +from PyQt4.QtGui import QTreeWidgetItem, QInputDialog, QLineEdit, QDialog from Preferences.ConfigurationPages.ConfigurationPageBase import \ ConfigurationPageBase @@ -32,6 +35,8 @@ self.setupUi(self) self.setObjectName("SelectionEncloserPage") + self.editButton.setIcon(UI.PixmapCache.getIcon( + os.path.join("SelectionEncloser", "icons", "edit.png"))) self.addButton.setIcon(UI.PixmapCache.getIcon("plus.png")) self.deleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) self.upButton.setIcon(UI.PixmapCache.getIcon("1uparrow.png")) @@ -39,6 +44,7 @@ self.addMenuButton.setIcon(UI.PixmapCache.getIcon( os.path.join("SelectionEncloser", "icons", "topAdd.png"))) + self.editButton.setEnabled(False) self.addButton.setEnabled(False) self.deleteButton.setEnabled(False) self.upButton.setEnabled(False) @@ -50,10 +56,9 @@ hierarchy = self.__plugin.getPreferences("MenuHierarchy") for menuTitle, entries in hierarchy: top = QTreeWidgetItem(self.menuTree, [menuTitle]) - top.setFlags(top.flags() | Qt.ItemIsEditable) - for entry in entries: - itm = QTreeWidgetItem(top, [entry]) - itm.setFlags(itm.flags() | Qt.ItemIsEditable) + for title, encString in entries: + itm = QTreeWidgetItem(top, [title]) + itm.setData(0, Qt.UserRole, encString) top.setExpanded(True) def save(self): @@ -66,7 +71,7 @@ topEntry = [topItem.text(0), []] for index in range(topItem.childCount()): itm = topItem.child(index) - topEntry[1].append(itm.text(0)) + topEntry[1].append([itm.text(0), itm.data(0, Qt.UserRole)]) hierarchy.append(topEntry) self.__plugin.setPreferences("MenuHierarchy", hierarchy) @@ -82,7 +87,6 @@ QLineEdit.Normal) if ok and menuTitle: top = QTreeWidgetItem(self.menuTree, [menuTitle]) - top.setFlags(top.flags() | Qt.ItemIsEditable) top.setExpanded(True) @pyqtSlot() @@ -90,14 +94,12 @@ """ Private slot to add a menu entry. """ - entry, ok = QInputDialog.getText( - self, - self.tr("Menu Entry"), - self.tr("Enter menu entry text:"), - QLineEdit.Normal) - if ok and entry: - itm = QTreeWidgetItem(self.menuTree.selectedItems()[0], [entry]) - itm.setFlags(itm.flags() | Qt.ItemIsEditable) + from .SelectionEncloserEditDialog import SelectionEncloserEditDialog + dlg = SelectionEncloserEditDialog(parent=self) + if dlg.exec_() == QDialog.Accepted: + title, encString = dlg.getData() + itm = QTreeWidgetItem(self.menuTree.selectedItems()[0], [title]) + itm.setData(0, Qt.UserRole, encString) @pyqtSlot() def on_deleteButton_clicked(self): @@ -117,18 +119,65 @@ @pyqtSlot() def on_upButton_clicked(self): """ - Slot documentation goes here. + Private slot to move an entry up. """ - # TODO: not implemented yet - raise NotImplementedError + self.__moveSelectedEntry(True) @pyqtSlot() def on_downButton_clicked(self): """ + Private slot to move an entry down. + """ + self.__moveSelectedEntry(False) + + def __moveSelectedEntry(self, moveUp): + """ + Private method to move the selected entry up or down. + """ + itm = self.menuTree.selectedItems()[0] + parent = itm.parent() + if parent is None: + # top level item + index = self.menuTree.indexOfTopLevelItem(itm) + newIndex = index - 1 if moveUp else index + 1 + self.menuTree.takeTopLevelItem(index) + self.menuTree.insertTopLevelItem(newIndex, itm) + itm.setExpanded(True) + else: + # sub item + index = parent.indexOfChild(itm) + newIndex = index - 1 if moveUp else index + 1 + parent.takeChild(index) + parent.insertChild(newIndex, itm) + for sitm in self.menuTree.selectedItems(): + sitm.setSelected(False) + itm.setSelected(True) + + @pyqtSlot() + def on_editButton_clicked(self): + """ Slot documentation goes here. """ - # TODO: not implemented yet - raise NotImplementedError + itm = self.menuTree.selectedItems()[0] + parent = itm.parent() + if parent is None: + menuTitle, ok = QInputDialog.getText( + self, + self.tr("Menu Entry"), + self.tr("Enter menu entry text:"), + QLineEdit.Normal, + itm.text(0)) + if ok and menuTitle: + itm.setText(0, menuTitle) + else: + from .SelectionEncloserEditDialog import \ + SelectionEncloserEditDialog + dlg = SelectionEncloserEditDialog( + itm.text(0), itm.data(0, Qt.UserRole), self) + if dlg.exec_() == QDialog.Accepted: + title, encString = dlg.getData() + itm.setText(0, title) + itm.setData(0, Qt.UserRole, encString) @pyqtSlot() def on_menuTree_itemSelectionChanged(self): @@ -140,6 +189,7 @@ self.deleteButton.setEnabled(False) self.upButton.setEnabled(False) self.downButton.setEnabled(False) + self.editButton.setEnabled(False) else: addEnable = True upEnable = True @@ -165,3 +215,4 @@ self.deleteButton.setEnabled(True) self.upButton.setEnabled(upEnable) self.downButton.setEnabled(downEnable) + self.editButton.setEnabled(True)
--- a/SelectionEncloser/ConfigurationPage/SelectionEncloserPage.ui Fri Apr 18 19:46:40 2014 +0200 +++ b/SelectionEncloser/ConfigurationPage/SelectionEncloserPage.ui Mon Apr 21 15:25:27 2014 +0200 @@ -40,7 +40,7 @@ </item> <item> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0" rowspan="6"> + <item row="0" column="0" rowspan="7"> <widget class="QTreeWidget" name="menuTree"> <property name="alternatingRowColors"> <bool>true</bool> @@ -56,41 +56,48 @@ </widget> </item> <item row="0" column="1"> + <widget class="QToolButton" name="editButton"> + <property name="toolTip"> + <string>Press to edit the selected entry</string> + </property> + </widget> + </item> + <item row="1" column="1"> <widget class="QToolButton" name="addMenuButton"> <property name="toolTip"> <string>Press to add a new top level menu item</string> </property> </widget> </item> - <item row="1" column="1"> + <item row="2" column="1"> <widget class="QToolButton" name="addButton"> <property name="toolTip"> <string>Press to add a new menu item</string> </property> </widget> </item> - <item row="2" column="1"> + <item row="3" column="1"> <widget class="QToolButton" name="deleteButton"> <property name="toolTip"> <string>Press to delete the selected item</string> </property> </widget> </item> - <item row="3" column="1"> + <item row="4" column="1"> <widget class="QToolButton" name="upButton"> <property name="toolTip"> <string>Press to move the selected entry up</string> </property> </widget> </item> - <item row="4" column="1"> + <item row="5" column="1"> <widget class="QToolButton" name="downButton"> <property name="toolTip"> <string>Press to move the selected entry down</string> </property> </widget> </item> - <item row="5" column="1"> + <item row="6" column="1"> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -109,6 +116,7 @@ </widget> <tabstops> <tabstop>menuTree</tabstop> + <tabstop>editButton</tabstop> <tabstop>addMenuButton</tabstop> <tabstop>addButton</tabstop> <tabstop>deleteButton</tabstop>