ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py

Thu, 06 Feb 2014 19:30:34 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 06 Feb 2014 19:30:34 +0100
changeset 6
5f1c0ebbdf5f
parent 5
e2b08694e945
child 7
8d928ad07c0a
permissions
-rw-r--r--

Fixed some code style issues.

# -*- coding: utf-8 -*-

# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the Django tags menu handler.
"""

import os

from PyQt4.QtCore import QObject
from PyQt4.QtGui import QMenu, QInputDialog

from E5Gui.E5Application import e5App
from E5Gui import E5FileDialog

from .DjangoTagInputDialog import DjangoTagInputDialog


class DjangoTagsMenuHandler(QObject):
    """
    Class implementing the Django tags menu handler.
    """
    def __init__(self, ui, parent=None):
        """
        Constructor
        
        @param ui reference to the user interface object (UI.UserInterface)
        @param parent reference to the parent object (QObject)
        """
        super(DjangoTagsMenuHandler, self).__init__(parent)
        self.__ui = ui
        
        self.__findDialog = None
    
    def closeAllWindows(self):
        """
        Public method to close all dialogs managed by the handler.
        """
        if self.__findDialog:
            self.__findDialog.close()
    
    def initMenus(self, mainMenu):
        """
        Public method to initialize the various menus.
        
        @param mainMenu reference to the main tags menu (QMenu)
        """
        mainMenu.addAction(self.tr("Django Template Tags Locator"),
                           self.__findTemplateTag)
        mainMenu.addSeparator()
        mainMenu.addMenu(self.__initTagsMenu())
    
    def __initTagsMenu(self):
        """
        Private method to initialize the tags menu.
        
        @return generated menu (QMenu)
        """
        menu = QMenu(self.tr("Tags"))
        menu.addAction(
            self.tr("autoescape - Auto Escape Characters"),
            lambda: self.__applyTemplate("autoescape"))
        menu.addSeparator()
        menu.addAction(
            self.tr("block - Named Block"),
            lambda: self.__applyTemplate("block"))
        menu.addSeparator()
        menu.addAction(
            self.tr("comment - Multiline Comment"),
            lambda: self.__applyTemplate("comment"))
        menu.addAction(
            self.tr("csrf_token - Cross Site Request Forgery Token"),
            lambda: self.__applyTemplate("csrf_token"))
        menu.addAction(
            self.tr("cycle - Cycle variables each time used"),
            lambda: self.__applyTemplate("cycle"))
        menu.addSeparator()
        menu.addAction(
            self.tr("debug - Output Debug Information"),
            lambda: self.__applyTemplate("debug"))
        menu.addSeparator()
        menu.addAction(
            self.tr("extends - Extend a template with variable contents"),
            lambda: self.__applyTemplate("extendsvariable"))
        menu.addAction(
            self.tr("extends - Extend a template with file"),
            lambda: self.__applyTemplate("extendsfile"))
        menu.addSeparator()
        menu.addAction(
            self.tr("filter - Filtered Block for one or more filters"),
            lambda: self.__applyTemplate("filter"))
        menu.addAction(
            self.tr("firstof - Outputs first argument variable that is True"),
            lambda: self.__applyTemplate("firstof"))
        menu.addAction(
            self.tr("for - For Loop"),
            lambda: self.__applyTemplate("for"))
        menu.addAction(
            self.tr("for...empty - For Loop with fallback for empty loop"),
            lambda: self.__applyTemplate("for...empty"))
        menu.addSeparator()
        # TODO: add 'if...' templates here
        menu.addAction(
            self.tr("include - Render template given by variable"),
            lambda: self.__applyTemplate("includevariable"))
        menu.addAction(
            self.tr("include - Render template given by file name"),
            lambda: self.__applyTemplate("includefile"))
        menu.addSeparator()
        menu.addAction(
            self.tr("load - Load a custom template tag set"),
            lambda: self.__applyTemplate("load"))
        menu.addSeparator()
        menu.addAction(
            self.tr("now - Display current date and time"),
            lambda: self.__applyTemplate("now"))
        menu.addSeparator()
        menu.addAction(
            self.tr("regroup - Regroup list of alike objects by a common"
                    " attribute"),
            lambda: self.__applyTemplate("regroup"))
        menu.addSeparator()
        menu.addAction(
            self.tr("spaceless - Remove whitespace between HTML tags"),
            lambda: self.__applyTemplate("spaceless"))
        menu.addAction(
            self.tr("ssi - Output contents of a given file into the page"),
            lambda: self.__applyTemplate("ssi"))
        menu.addAction(
            self.tr("ssi - Output contents of a given file into the page"
                    " (dialog selection)"),
            lambda: self.__applyTemplate("ssifile"))
        menu.addSeparator()
        menu.addAction(
            self.tr("templatetag - Output syntax characters used for"
                    " template"),
            lambda: self.__applyTemplate("templatetag"))
        menu.addSeparator()
        menu.addAction(
            self.tr("url - Return an absolute path reference"),
            lambda: self.__applyTemplate("url"))
        menu.addAction(
            self.tr("url...as - Return an absolute path reference"),
            lambda: self.__applyTemplate("urlas"))
        menu.addSeparator()
        menu.addAction(
            self.tr("verbatim - Output block contents without rendering"),
            lambda: self.__applyTemplate("verbatim"))
        menu.addSeparator()
        menu.addAction(
            self.tr("widthratio - Calculate width ratio"),
            lambda: self.__applyTemplate("verbatim"))
        menu.addAction(
            self.tr("with - Cache a complex variable under a simpler name"),
            lambda: self.__applyTemplate("verbatim"))
        
        self.__tagsMenu = menu
        return menu
    
    def __findTemplateTag(self):
        """
        Private slot to find a template tag and insert its text.
        """
        if self.__findDialog is None:
            from .FindTemplateTagDialog import FindTemplateTagDialog
            self.__findDialog = FindTemplateTagDialog()
            self.__findDialog.tag.connect(self.__applyTemplate)
        self.__findDialog.show()
        self.__findDialog.raise_()
        self.__findDialog.activateWindow()
    
    def __applyTemplate(self, tag):
        """
        Private slot to generate and insert the template text.
        
        @param tag name of the tag to insert (string)
        """
        editor = e5App().getObject("ViewManager").activeWindow()
        if editor is None:
            return
        
        templateText, replace = self.__generateTemplateText(
            tag, editor.selectedText())
        
        if templateText:
            editor.beginUndoAction()
            if replace:
                editor.replaceSelectedText(templateText)
            else:
                editor.insert(templateText)
            editor.endUndoAction()
    
    def __generateTemplateText(self, tag, selectedText):
        """
        Private slot to generate the template text.
        
        @param tag name of the tag to insert (string)
        @param selectedText selected text of the current editor (string)
        @return tuple of generated template text (string), a flag indicating
            to perform a replace operation (boolean)
        """
        # TODO: complete the tag generation logic
        replace = False         # safe value
        ok = True
        templateText = ""
        
        ####################################################
        ## Template Tags                                  ##
        ####################################################
        
        if tag == "autoescape":
            templateText = (
                "{{% autoescape on %}} {0} {{% endautoescape %}}".format(
                    selectedText))
            replace = True
        elif tag == "block":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Named Block"),
                [self.tr("Enter block name:")],
                ["block_name"])
            if ok:
                templateText = "{{% block {0} %}} {1} {{% endblock %}}".format(
                    data[0], selectedText)
                replace = True
        elif tag == "comment":
            templateText = "{{% comment %}} {0} {{% endcomment %}}".format(
                selectedText)
            replace = True
        elif tag == "csrf_token":
            templateText = "{% csrf_token %}"
        elif tag == "cycle":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Cycle Variables"),
                [self.tr("Enter items to cycle, space separated")],
                ["item1 item2 item3"])
            if ok:
                templateText = "{{% cycle {0} %}}".format(data[0])
        elif tag == "debug":
            templateText = "{% debug %}"
        elif tag == "extendsvariable":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Extends"),
                [self.tr("Enter variable name:")],
                ["variable"])
            if ok:
                templateText = "{{% extends {0} %}}".format(data[0])
        elif tag == "extendsfile":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Extends"),
                [self.tr("Enter parent file name:")],
                ["base.html"])
            if ok:
                templateText = '{{% extends "{0}" %}}'.format(data[0])
        elif tag == "filter":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Tag Filters"),
                [self.tr("Multiple filters with arguments, pipes separated:")],
                ["lower|safe"])
            if ok:
                templateText = (
                    "{{% filter {0} %}} {1} {{% endfilter %}}".format(
                        data[0], selectedText))
                replace = True
        elif tag == "firstof":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("First Of"),
                [self.tr("Enter multiple variables, space separated:"),
                 self.tr("Enter fallback value:")],
                ["var1 var2", "fallback_value"])
            if ok:
                templateText = (
                    '{{% filter force_escape %}}{{% firstof {0} "{1}" %}}'
                    ' {2} {{% endfilter %}}'.format(
                        data[0], data[1], selectedText))
                replace = True
        elif tag == "for":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("For Loop"),
                [self.tr("Enter variable to use for iteration:"),
                 self.tr("Enter sequence to iterate over:")],
                ["item", "values"])
            if ok:
                templateText = (
                    "{{% for {0} in {1} %}} {2} {{% endfor %}}".format(
                        data[0], data[1], selectedText))
                replace = True
        elif tag == "for...empty":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("For Loop"),
                [self.tr("Enter variable to use for iteration:"),
                 self.tr("Enter sequence to iterate over:"),
                 self.tr("Enter output to use if loop is empty:")],
                ["item", "values", '"Nothing."'])
            if ok:
                templateText = (
                    "{{% for {0} in {1} %}} {2} {{% empty %}} {3}"
                    " {{% endfor %}}".format(
                        data[0], data[1], selectedText, data[2]))
                replace = True
        elif tag == "includevariable":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Include"),
                [self.tr("Enter variable name:")],
                ["variable"])
            if ok:
                templateText = '{{% include {0} %}}'.format(data[0])
        elif tag == "includefile":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Include"),
                [self.tr("Enter file name:")],
                ["other.html"])
            if ok:
                templateText = '{{% include "{0}" %}}'.format(data[0])
        elif tag == "load":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Load"),
                [self.tr("Enter template tag set to load:")],
                ["foo bar"])
            if ok:
                templateText = '{{% load "{0}" %}}'.format(data[0])
        elif tag == "now":
            dateformat, ok = QInputDialog.getItem(
                None,
                self.tr("Now"),
                self.tr("Current date time format:"),
                ["DATETIME_FORMAT", "SHORT_DATETIME_FORMAT",
                 "SHORT_DATE_FORMAT", "DATE_FORMAT"],
                0, False)
            if ok:
                templateText = '{{% now "{0}" %}}'.format(dateformat)
        elif tag == "regroup":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Regroup List"),
                [self.tr("List Variable:"), self.tr("Common Attribute:"),
                 self.tr("Name of resulting list:")],
                ["cities", "country", "country_list"])
            if ok:
                templateText = '{{% regroup {0} by {1} as {2} %}}'.format(
                    data[0], data[1], data[2])
        elif tag == "spaceless":
            templateText = "{{% spaceless %}} {0} {{% endspaceless %}}".format(
                selectedText)
            replace = True
        elif tag == "ssi":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("SSI"),
                [self.tr("Full path to template:")],
                ["/tmp/ssi_template.html"])
            if ok:
                templateText = '{{% ssi "{0}" parsed %}}'.format(data[0])
        elif tag == "ssifile":
            ssi = E5FileDialog.getOpenFileName(
                None,
                self.tr("SSI"),
                os.path.expanduser("~"),
                self.tr("All Files (*)"))
            if ssi:
                templateText = '{{% ssi "{0}" parsed %}}'.format(ssi)
        elif tag == "templatetag":
            templatetag, ok = QInputDialog.getItem(
                None,
                self.tr("Template Tag"),
                self.tr("Argument:"),
                ["block", "variable", "brace", "comment"],
                0, False)
            if ok:
                templateText = (
                    '{{% templatetag open{0} %}} {1} {{% templatetag'
                    ' close{0} %}}'.format(templatetag, selectedText))
                replace = True
        elif tag == "url":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("URL"),
                [self.tr("View method name:"),
                 self.tr("Optional arguments (space separated):")],
                ["path.to.some_view", "var1 var2"])
            if ok:
                if data[1]:
                    data[1] = ' ' + data[1]
                templateText = '{{% url "{0}"{1} %}}'.format(
                    data[0], data[1])
        elif tag == "urlas":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("URL...as"),
                [self.tr("View method name:"),
                 self.tr("Optional arguments (space separated):"),
                 self.tr("URL name:")],
                ["path.to.some_view", "var1 var2", "url_name"])
            if ok:
                if data[1]:
                    data[1] = ' ' + data[1]
                templateText = '{{% url "{0}"{1} as {2} %}}'.format(
                    data[0], data[1], data[2])
        elif tag == "verbatim":
            templateText = "{{% verbatim %}} {0} {{% endverbatim %}}".format(
                selectedText)
            replace = True
        elif tag == "widthratio":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Width Ratio"),
                [self.tr("Variable:"),
                 self.tr("Maximum Value:"),
                 self.tr("Maximum Width:")],
                ["variable", "max_value", "max_width"])
            if ok:
                templateText = "{{% widthratio {0} {1} {2} %}}".format(
                    data[0], data[1], data[2])
        elif tag == "with":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Cache Variables"),
                [self.tr("Variables to cache as key=value (space separated):")
                 ],
                ["variable1=foo.bar variable2=bar.baz"])
            if ok:
                templateText = '{{% with {0} %}} {1} {{% endwith %}}'.format(
                    data[0], selectedText)
        
        ####################################################
        ## Fallback: return just the tag name             ##
        ####################################################
        
        else:
            templateText = tag
        
        return templateText, replace

eric ide

mercurial