PluginColorString.py

changeset 1
e1f013dc03bb
parent 0
78cb5b240094
child 4
40e7964a840d
--- a/PluginColorString.py	Fri Mar 21 17:58:43 2014 +0100
+++ b/PluginColorString.py	Sat Mar 22 15:36:57 2014 +0100
@@ -0,0 +1,287 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the 'Color String' tool plug-in.
+"""
+
+from __future__ import unicode_literals
+
+import os
+
+from PyQt4.QtCore import QObject, QTranslator
+from PyQt4.QtGui import QColor, QColorDialog, QMenu, QDialog
+
+from E5Gui.E5Application import e5App
+from E5Gui import E5MessageBox
+
+# Start-Of-Header
+name = "Color String Plug-in"
+author = "Detlev Offenbach <detlev@die-offenbachs.de>"
+autoactivate = True
+deactivateable = True
+version = "0.1.0"
+className = "ColorStringPlugin"
+packageName = "ColorString"
+shortDescription = "Insert color as string"
+longDescription = \
+    """This plug-in implements a tool to select a color via a""" \
+    """ color selection dialog and insert it as a hex string at the""" \
+    """ current cursor position. Selected text is used to initialize""" \
+    """ the dialog and is replaced with the new color."""
+needsRestart = False
+pyqtApi = 2
+# End-Of-Header
+
+error = ""
+
+
+class ColorStringPlugin(QObject):
+    """
+    Class implementing the 'Color String' tool plug-in.
+    """
+    def __init__(self, ui):
+        """
+        Constructor
+        
+        @param ui reference to the user interface object (UI.UserInterface)
+        """
+        QObject.__init__(self, ui)
+        self.__ui = ui
+        
+        self.__translator = None
+        self.__loadTranslator()
+        
+        self.__initMenu()
+        
+        self.__editors = {}
+    
+    def activate(self):
+        """
+        Public method to activate this plugin.
+        
+        @return tuple of None and activation status (boolean)
+        """
+        global error
+        error = ""     # clear previous error
+        
+        self.__ui.showMenu.connect(self.__populateMenu)
+        
+        e5App().getObject("ViewManager").editorOpenedEd.connect(
+            self.__editorOpened)
+        e5App().getObject("ViewManager").editorClosedEd.connect(
+            self.__editorClosed)
+        
+        for editor in e5App().getObject("ViewManager").getOpenEditors():
+            self.__editorOpened(editor)
+        
+        return None, True
+    
+    def deactivate(self):
+        """
+        Public method to deactivate this plugin.
+        """
+        self.__ui.showMenu.disconnect(self.__populateMenu)
+        
+        e5App().getObject("ViewManager").editorOpenedEd.disconnect(
+            self.__editorOpened)
+        e5App().getObject("ViewManager").editorClosedEd.disconnect(
+            self.__editorClosed)
+        
+        for editor, acts in self.__editors.items():
+            menu = editor.getMenu("Tools")
+            if menu is not None:
+                for act in acts:
+                    menu.removeAction(act)
+        self.__editors = {}
+    
+    def __loadTranslator(self):
+        """
+        Private method to load the translation file.
+        """
+        if self.__ui is not None:
+            loc = self.__ui.getLocale()
+            if loc and loc != "C":
+                locale_dir = os.path.join(
+                    os.path.dirname(__file__), "ColorString", "i18n")
+                translation = "colorstring_{0}".format(loc)
+                translator = QTranslator(None)
+                loaded = translator.load(translation, locale_dir)
+                if loaded:
+                    self.__translator = translator
+                    e5App().installTranslator(self.__translator)
+                else:
+                    print("Warning: translation file '{0}' could not be"
+                          " loaded.".format(translation))
+                    print("Using default.")
+    
+    def __initMenu(self):
+        """
+        Private method to initialize the menu.
+        """
+        self.__menu = QMenu("Color String")
+        self.__menu.addAction("Hex Color", self.__selectHexColor)
+        self.__menu.addAction("Color Name", self.__selectColorName)
+        self.__menu.setEnabled(False)
+    
+    def __populateMenu(self, name, menu):
+        """
+        Private slot to populate the tools menu with our entry.
+        
+        @param name name of the menu (string)
+        @param menu reference to the menu to be populated (QMenu)
+        """
+        if name != "Tools":
+            return
+        
+        if not menu.isEmpty():
+            menu.addSeparator()
+        menu.addMenu(self.__menu)
+    
+    def __editorOpened(self, editor):
+        """
+        Private slot called, when a new editor was opened.
+        
+        @param editor reference to the new editor (QScintilla.Editor)
+        """
+        menu = editor.getMenu("Tools")
+        if menu is not None:
+            self.__editors[editor] = []
+            if not menu.isEmpty():
+                act = menu.addSeparator()
+                self.__editors[editor].append(act)
+            act = menu.addMenu(self.__menu)
+            self.__menu.setEnabled(True)
+            self.__editors[editor].append(act)
+    
+    def __editorClosed(self, editor):
+        """
+        Private slot called, when an editor was closed.
+        
+        @param editor reference to the editor (QScintilla.Editor)
+        """
+        try:
+            del self.__editors[editor]
+            if not self.__editors:
+                self.__menu.setEnabled(False)
+        except KeyError:
+            pass
+    
+    def __isHexString(self, text):
+        """
+        Private method to check, if a given text is a hex string.
+        
+        @param text text to check (string)
+        @return flag indicating a hex string (boolean)
+        """
+        isHex = True
+        for c in text:
+            isHex = isHex and c in "0123456789abcdefABCDEF" 
+        return isHex
+    
+    def __isValidColor(self, name):
+        """
+        Private method to check for a valid color name.
+        
+        @param name color name to check (string)
+        @return flag indicating a valid color name (boolean)
+        """
+        try:
+            if self.__isHexString(name) and len(name) in [3, 6, 9, 12]:
+                return True
+            return QColor.isValidColor(name)
+        except AttributeError:
+            if name.startswith("#"):
+                if len(name) not in [4, 7, 10, 13]:
+                    return False
+                hexCheckStr = name[1:]
+                return self.__isHexString(hexCheckStr)
+            else:
+                if self.__isHexString(name) and len(name) in [3, 6, 9, 12]:
+                    return True
+                return name in QColor.colorNames()
+    
+    def __selectHexColor(self):
+        """
+        Private slot implementing the hex color string selection.
+        """
+        editor = e5App().getObject("ViewManager").activeWindow()
+        if editor is None:
+            return
+        
+        if editor.hasSelectedText():
+            currColor = editor.selectedText()
+            if not self.__isValidColor(currColor):
+                E5MessageBox.critical(
+                    self.__ui,
+                    self.trUtf8("Color String"),
+                    self.trUtf8(
+                        """<p>The selected string <b>{0}</b> is not a""" \
+                        """ valid color string. Aborting!</p>""")
+                    .format(currColor))
+                return
+            
+            if currColor.startswith("#"):
+                withHash = True
+            elif self.__isHexString(currColor):
+                withHash = False
+                currColor = "#" + currColor
+            else:
+                withHash = True
+            initColor = QColor(currColor)
+        else:
+            withHash = True
+            currColor = ""
+            initColor = QColor()
+        
+        color = QColorDialog.getColor(
+            initColor, self.__ui, self.tr("Color String"))
+        if color.isValid():
+            colorStr = color.name()
+            if not withHash:
+                colorStr = colorStr[1:]
+            editor.beginUndoAction()
+            if editor.hasSelectedText():
+                editor.replaceSelectedText(colorStr)
+            else:
+                line, index = editor.getCursorPosition()
+                editor.insert(colorStr)
+                editor.setCursorPosition(line, index + len(colorStr))
+            editor.endUndoAction()
+    
+    def __selectColorName(self):
+        """
+        Private slot implementing the named color string selection.
+        """
+        editor = e5App().getObject("ViewManager").activeWindow()
+        if editor is None:
+            return
+        
+        if editor.hasSelectedText():
+            currColor = editor.selectedText()
+            if currColor not in QColor.colorNames():
+                E5MessageBox.critical(
+                    self.__ui,
+                    self.trUtf8("Color String"),
+                    self.trUtf8(
+                        """<p>The selected string <b>{0}</b> is not a""" \
+                        """ valid color name. Aborting!</p>""")
+                    .format(currColor))
+                return
+        else:
+            currColor = ""
+        
+        from ColorString.ColorSelectionDialog import ColorSelectionDialog
+        dlg = ColorSelectionDialog(currColor, self.__ui)
+        if dlg.exec_() == QDialog.Accepted:
+            colorStr = dlg.getColor()
+            editor.beginUndoAction()
+            if editor.hasSelectedText():
+                editor.replaceSelectedText(colorStr)
+            else:
+                line, index = editor.getCursorPosition()
+                editor.insert(colorStr)
+                editor.setCursorPosition(line, index + len(colorStr))
+            editor.endUndoAction()

eric ide

mercurial