ProjectDjangoTagsMenu/DjangoTagsMenuHandler.py

Wed, 05 Feb 2014 19:13:12 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 05 Feb 2014 19:13:12 +0100
changeset 4
ba04ed0b14a1
parent 3
6d10c1249cb8
child 5
e2b08694e945
permissions
-rw-r--r--

Implemented template tags 'f' to 'i' (except 'if').

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

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

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

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

from E5Gui.E5Application import e5App

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"))
        
        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 %} " + selectedText + " {% endautoescape %}")
            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 " + data[0] + " %} " + selectedText +
                    " {% endblock %}")
                replace = True
        elif tag == "comment":
            templateText = (
                "{% comment %} " + selectedText + " {% endcomment %}")
            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 " + 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 ' + 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 "' + 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 " + data[0] + " %} " + selectedText +
                    " {% endfilter %}")
                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 " + data[0] +
                    ' "' + data[1] + '" %} ' + selectedText +
                    " {% endfilter %}")
                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 " + data[0] + " in " + data[1] +
                    " %} " + selectedText + " {% endfor %}")
                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 " + data[0] + " in " + data[1] + " %} " +
                    selectedText + " {% empty %} " + data[2] + " {% endfor %}")
                replace = True
        elif tag == "includevariable":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Include"),
                [self.tr("Enter variable name:")],
                ["variable"])
            if ok:
                templateText = ('{% include ' + data[0] + ' %} ')
        elif tag == "includefile":
            data, ok = DjangoTagInputDialog.getText(
                None,
                self.tr("Include"),
                [self.tr("Enter file name:")],
                ["other.html"])
            if ok:
                templateText = ('{% include "' + data[0] + '" %} ')
        
        ####################################################
        ## Fallback: return just the tag name             ##
        ####################################################
        
        else:
            templateText = tag
        
        return templateText, replace

eric ide

mercurial