Sun, 09 Feb 2014 18:21:45 +0100
Implemented the comments menu.
--- a/PluginDjangoTagsMenu.e4p Sat Feb 08 18:58:33 2014 +0100 +++ b/PluginDjangoTagsMenu.e4p Sun Feb 09 18:21:45 2014 +0100 @@ -21,11 +21,15 @@ <Source>ProjectDjangoTagsMenu/DjangoTagInputDialog.py</Source> <Source>ProjectDjangoTagsMenu/LoremTagInputDialog.py</Source> <Source>ProjectDjangoTagsMenu/IfTagInputDialog.py</Source> + <Source>ProjectDjangoTagsMenu/MultiLineInputDialog.py</Source> + <Source>ProjectDjangoTagsMenu/IeCommentDialog.py</Source> </Sources> <Forms> <Form>ProjectDjangoTagsMenu/FindTemplateTagDialog.ui</Form> <Form>ProjectDjangoTagsMenu/LoremTagInputDialog.ui</Form> <Form>ProjectDjangoTagsMenu/IfTagInputDialog.ui</Form> + <Form>ProjectDjangoTagsMenu/MultiLineInputDialog.ui</Form> + <Form>ProjectDjangoTagsMenu/IeCommentDialog.ui</Form> </Forms> <Translations/> <Resources/>
--- a/ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py Sat Feb 08 18:58:33 2014 +0100 +++ b/ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py Sun Feb 09 18:21:45 2014 +0100 @@ -8,15 +8,18 @@ """ import os +import datetime from PyQt4.QtCore import QObject -from PyQt4.QtGui import QMenu, QInputDialog, QDialog +from PyQt4.QtGui import QMenu, QInputDialog, QDialog, QApplication from E5Gui.E5Application import e5App -from E5Gui import E5FileDialog +from E5Gui import E5FileDialog, E5MessageBox from .DjangoTagInputDialog import DjangoTagInputDialog +import Utilities + class DjangoTagsMenuHandler(QObject): """ @@ -55,6 +58,10 @@ mainMenu.addMenu(self.__initHumanizeMenu()) mainMenu.addMenu(self.__initWebDesignMenu()) mainMenu.addMenu(self.__initStaticMenu()) + mainMenu.addMenu(self.__initCommentsMenu()) + # TODO: add internationalization tags/filters menu + # TODO: add localization tags/filters menu + # TODO: add timezone tags/filters menu def __initTagsMenu(self): """ @@ -180,7 +187,10 @@ @return generated menu (QMenu) """ - menu = QMenu(self.tr("Filters")) + # TODO: subdivide into even parts a-i,j-r,s-z + mainMenu = QMenu(self.tr("Filters")) + + menu = QMenu(self.tr("A-I"), mainMenu) menu.addAction( self.tr("add - Add variable or string"), lambda: self.__applyTemplate("add")) @@ -247,7 +257,9 @@ menu.addAction( self.tr("iriencode - Convert IRI to string"), lambda: self.__applyTemplate("iriencode")) - menu.addSeparator() + mainMenu.addMenu(menu) + + menu = QMenu(self.tr("J-R"), mainMenu) menu.addAction( self.tr("join - Join list"), lambda: self.__applyTemplate("join")) @@ -300,7 +312,9 @@ menu.addAction( self.tr("rjust - Right-align value"), lambda: self.__applyTemplate("rjust")) - menu.addSeparator() + mainMenu.addMenu(menu) + + menu = QMenu(self.tr("S-Z"), mainMenu) menu.addAction( self.tr("safe - Mark as not requiring HTML escaping "), lambda: self.__applyTemplate("safe")) @@ -370,9 +384,10 @@ menu.addAction( self.tr("yesno - Map True, False and None"), lambda: self.__applyTemplate("yesno")) + mainMenu.addMenu(menu) - self.__filtersMenu = menu - return menu + self.__filtersMenu = mainMenu + return mainMenu def __initHumanizeMenu(self): """ @@ -455,6 +470,52 @@ self.__staticMenu = menu return menu + def __initCommentsMenu(self): + """ + Private method to initialize the static menu. + + @return generated menu (QMenu) + """ + menu = QMenu(self.tr("Comment")) + menu.addAction( + self.tr("Single Line Comment Selected Text"), + lambda: self.__applyTemplate("singlelinecommentselect")) + menu.addAction( + self.tr("Multi Line Comment Selected Text"), + lambda: self.__applyTemplate("multilinecommentselect")) + menu.addSeparator() + menu.addAction( + self.tr("Single Line Comment from Input Dialog"), + lambda: self.__applyTemplate("singlelinecommentdialog")) + menu.addAction( + self.tr("Multi Line Comment from Input Dialog"), + lambda: self.__applyTemplate("multilinecommentdialog")) + menu.addSeparator() + menu.addAction( + self.tr("Single Line Comment from Clipboard"), + lambda: self.__applyTemplate("singlelinecommentclipboard")) + menu.addAction( + self.tr("Multi Line Comment from Clipboard"), + lambda: self.__applyTemplate("multilinecommentclipboard")) + menu.addSeparator() + menu.addAction( + self.tr("Multi Line Comment from File"), + lambda: self.__applyTemplate("multilinecommentfile")) + menu.addSeparator() + menu.addAction( + self.tr("Single Line Comment from Date Time Now"), + lambda: self.__applyTemplate("singlelinecommentdatetime")) + menu.addSeparator() + menu.addAction( + self.tr("HTML Comment Out Selected Text"), + lambda: self.__applyTemplate("htmlcomment")) + menu.addAction( + self.tr("MS IE Conditional Comment Selected Text"), + lambda: self.__applyTemplate("iecomment")) + + self.__commentsMenu = menu + return menu + def __findTemplateTag(self): """ Private slot to find a template tag and insert its text. @@ -1136,8 +1197,77 @@ elif tag == "get_media_prefix": templateText = '{% get_media_prefix %}' - # TODO: add comment functions - # TODO: add internationalization tags + #################################################### + ## Comments ## + #################################################### + + elif tag == "singlelinecommentselect": + templateText = '{{# {0} #}}'.format(selectedText) + replace = True + elif tag == "multilinecommentselect": + templateText = '{{% comment %}} {0} {{% endcomment }}'.format( + selectedText) + replace = True + elif tag == "singlelinecommentdialog": + data, ok = DjangoTagInputDialog.getText( + None, + self.tr("Single Line Comment"), + [self.tr("Enter comment:")], + [""]) + if ok: + templateText = '{{# {0} #}}'.format(data[0]) + elif tag == "multilinecommentdialog": + from .MultiLineInputDialog import MultiLineInputDialog + comment, ok = MultiLineInputDialog.getText( + None, self.tr("Multi Line Comment"), + self.tr("Enter comment:"), "") + if ok: + templateText = '{{% comment %}} {0} {{% endcomment }}'.format( + comment) + elif tag == "singlelinecommentclipboard": + templateText = '{{# {0} #}}'.format( + QApplication.clipboard().text().strip()) + elif tag == "multilinecommentclipboard": + templateText = '{{% comment %}} {0} {{% endcomment }}'.format( + QApplication.clipboard().text().strip()) + elif tag == "multilinecommentfile": + filename = E5FileDialog.getOpenFileName( + None, + self.tr("Comment File"), + Utilities.getHomeDir(), + self.tr("All Files (*)")) + if filename: + try: + f = open(filename, "r", encoding="utf-8") + comment = f.read() + f.close() + templateText = ( + '{{% comment %}} {0} {{% endcomment }}'.format( + comment)) + except (IOError, OSError) as err: + E5MessageBox.critical( + None, + self.tr("Comment File"), + self.tr("""<p>The file <b>{0}</b> could not be""" + """ read.</p><p>Reason: {1}</p>""").format( + str(err))) + elif tag == "singlelinecommentdatetime": + templateText = '{{# {0} by {1} #}}'.format( + datetime.datetime.now().isoformat().split(), + Utilities.getUserName()) + elif tag == "htmlcomment": + templateText = '<!-- {0} -->'.format(selectedText) + replace = True + elif tag == "iecomment": + from .IeCommentDialog import IeCommentDialog + tag, ok = IeCommentDialog.getTag(selectedText) + if ok: + templateText = '<!--{0}-->'.format(tag) + replace = True + + # TODO: add internationalization tags/filters + # TODO: add localization tags/filters + # TODO: add timezone tags/filters #################################################### ## Fallback: return just the tag name ## ####################################################
--- a/ProjectDjangoTagsMenu/FindTemplateTagDialog.py Sat Feb 08 18:58:33 2014 +0100 +++ b/ProjectDjangoTagsMenu/FindTemplateTagDialog.py Sun Feb 09 18:21:45 2014 +0100 @@ -66,13 +66,15 @@ 'get_media_prefix', # comments - # TODO: check tags against handler + 'singlelinecommentselect', 'multilinecommentselect', + 'singlelinecommentdialog', 'multilinecommentdialog', + 'singlelinecommentclipboard', 'multilinecommentclipboard', + 'multilinecommentfile', 'singlelinecommentdatetime', 'htmlcomment', 'iecomment', - 'singlelinecomment', 'multilinecomment', 'singlelinecommentpopup', - 'multilinecommentpopup', 'singlelinecommentclipboard', - 'multilinecommentclipboard', 'multilinecommentfile', - 'singlelinecommentdatetime'), - self) + + # internationalisation + # TODO: check tags against handler + ), self) self.__completer.setCompletionMode(QCompleter.PopupCompletion) self.__completer.setCaseSensitivity(False) self.tagEdit.setCompleter(self.__completer)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjangoTagsMenu/IeCommentDialog.py Sun Feb 09 18:21:45 2014 +0100 @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +""" +Module implementing a dialog to enter data for an IE comment. +""" + +from PyQt4.QtGui import QDialog + +from .Ui_IeCommentDialog import Ui_IeCommentDialog + + +class IeCommentDialog(QDialog, Ui_IeCommentDialog): + """ + Class implementing a dialog to enter data for an IE comment. + """ + def __init__(self, parent=None): + """ + Constructor + + @param parent reference to the parent widget (QWidget) + """ + super().__init__(parent) + self.setupUi(self) + + for condStr, condData in [("==", ""), ("<=", " lte"), ("<", " lt"), + (">", " gt"), (">=", " gte")]: + self.conditionalComboBox.addItem(condStr, condData) + + def getData(self): + """ + Public method to retrieve the entered data. + + @return tuple of condition (string) and version (integer) + """ + return (self.conditionalComboBox.itemData( + self.conditionalComboBox.currentIndex()), + self.versionSpinBox.value()) + + @staticmethod + def getTag(selectedText): + """ + Static method to get the formatted tag. + + @param selectedText selected text to embed (string) + @return formatted tag (string) and a flag indicating the acceptance + state (boolean) + """ + dlg = IeCommentDialog() + if dlg.exec_() == QDialog.Accepted: + condition, version = dlg.getData() + tag = '[if{0} IE {1}]> {2} <![endif]'.format( + condition, version, selectedText) + return tag, True + else: + return "", False
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjangoTagsMenu/IeCommentDialog.ui Sun Feb 09 18:21:45 2014 +0100 @@ -0,0 +1,150 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>IeCommentDialog</class> + <widget class="QDialog" name="IeCommentDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>295</width> + <height>114</height> + </rect> + </property> + <property name="windowTitle"> + <string>IE Comment</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Conditional Format:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QComboBox" name="conditionalComboBox"> + <property name="toolTip"> + <string>Select the conditional</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>MS IE Version:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QSpinBox" name="versionSpinBox"> + <property name="toolTip"> + <string>Enter the IE Version</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>5</number> + </property> + <property name="maximum"> + <number>12</number> + </property> + <property name="value"> + <number>7</number> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </item> + <item> + <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> + <tabstops> + <tabstop>conditionalComboBox</tabstop> + <tabstop>versionSpinBox</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>IeCommentDialog</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>IeCommentDialog</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>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjangoTagsMenu/MultiLineInputDialog.py Sun Feb 09 18:21:45 2014 +0100 @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog for the input of multi line text. +""" + +from PyQt4.QtGui import QDialog + +from .Ui_MultiLineInputDialog import Ui_MultiLineInputDialog + + +class MultiLineInputDialog(QDialog, Ui_MultiLineInputDialog): + """ + Class implementing a dialog for the input of multi line text. + """ + def __init__(self, label, default, parent=None): + """ + Constructor + + @param label label for the entry field (string) + @param default default value for the entry field (string) + @param parent reference to the parent widget (QWidget) + """ + super(MultiLineInputDialog, self).__init__(parent) + self.setupUi(self) + + def getData(self): + """ + Public method to retrieve the multi line text. + + @return multi line text (string) + """ + return self.multiLineEdit.toPlainText() + + @staticmethod + def getText(parent, title, label, default=""): + """ + Static method to create the dialog and return the multi line text. + + @param parent reference to the parent widget (QWidget) + @param title title of the dialog (string) + @param label label for the entry field (string) + @param default default value for the entry field (string) + @return multi line text (string) and a flag indicating the acceptance + state (boolean) + """ + dlg = MultiLineInputDialog(label, default, parent) + dlg.setWindowTitle(title) + if dlg.exec_() == QDialog.Accepted: + return dlg.getData(), True + else: + return "", False
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ProjectDjangoTagsMenu/MultiLineInputDialog.ui Sun Feb 09 18:21:45 2014 +0100 @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MultiLineInputDialog</class> + <widget class="QDialog" name="MultiLineInputDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>400</height> + </rect> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="entryLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QPlainTextEdit" name="multiLineEdit"/> + </item> + <item> + <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> + <tabstops> + <tabstop>multiLineEdit</tabstop> + <tabstop>buttonBox</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>MultiLineInputDialog</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>MultiLineInputDialog</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>