PluginColorString.py

changeset 1
e1f013dc03bb
parent 0
78cb5b240094
child 4
40e7964a840d
equal deleted inserted replaced
0:78cb5b240094 1:e1f013dc03bb
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the 'Color String' tool plug-in.
8 """
9
10 from __future__ import unicode_literals
11
12 import os
13
14 from PyQt4.QtCore import QObject, QTranslator
15 from PyQt4.QtGui import QColor, QColorDialog, QMenu, QDialog
16
17 from E5Gui.E5Application import e5App
18 from E5Gui import E5MessageBox
19
20 # Start-Of-Header
21 name = "Color String Plug-in"
22 author = "Detlev Offenbach <detlev@die-offenbachs.de>"
23 autoactivate = True
24 deactivateable = True
25 version = "0.1.0"
26 className = "ColorStringPlugin"
27 packageName = "ColorString"
28 shortDescription = "Insert color as string"
29 longDescription = \
30 """This plug-in implements a tool to select a color via a""" \
31 """ color selection dialog and insert it as a hex string at the""" \
32 """ current cursor position. Selected text is used to initialize""" \
33 """ the dialog and is replaced with the new color."""
34 needsRestart = False
35 pyqtApi = 2
36 # End-Of-Header
37
38 error = ""
39
40
41 class ColorStringPlugin(QObject):
42 """
43 Class implementing the 'Color String' tool plug-in.
44 """
45 def __init__(self, ui):
46 """
47 Constructor
48
49 @param ui reference to the user interface object (UI.UserInterface)
50 """
51 QObject.__init__(self, ui)
52 self.__ui = ui
53
54 self.__translator = None
55 self.__loadTranslator()
56
57 self.__initMenu()
58
59 self.__editors = {}
60
61 def activate(self):
62 """
63 Public method to activate this plugin.
64
65 @return tuple of None and activation status (boolean)
66 """
67 global error
68 error = "" # clear previous error
69
70 self.__ui.showMenu.connect(self.__populateMenu)
71
72 e5App().getObject("ViewManager").editorOpenedEd.connect(
73 self.__editorOpened)
74 e5App().getObject("ViewManager").editorClosedEd.connect(
75 self.__editorClosed)
76
77 for editor in e5App().getObject("ViewManager").getOpenEditors():
78 self.__editorOpened(editor)
79
80 return None, True
81
82 def deactivate(self):
83 """
84 Public method to deactivate this plugin.
85 """
86 self.__ui.showMenu.disconnect(self.__populateMenu)
87
88 e5App().getObject("ViewManager").editorOpenedEd.disconnect(
89 self.__editorOpened)
90 e5App().getObject("ViewManager").editorClosedEd.disconnect(
91 self.__editorClosed)
92
93 for editor, acts in self.__editors.items():
94 menu = editor.getMenu("Tools")
95 if menu is not None:
96 for act in acts:
97 menu.removeAction(act)
98 self.__editors = {}
99
100 def __loadTranslator(self):
101 """
102 Private method to load the translation file.
103 """
104 if self.__ui is not None:
105 loc = self.__ui.getLocale()
106 if loc and loc != "C":
107 locale_dir = os.path.join(
108 os.path.dirname(__file__), "ColorString", "i18n")
109 translation = "colorstring_{0}".format(loc)
110 translator = QTranslator(None)
111 loaded = translator.load(translation, locale_dir)
112 if loaded:
113 self.__translator = translator
114 e5App().installTranslator(self.__translator)
115 else:
116 print("Warning: translation file '{0}' could not be"
117 " loaded.".format(translation))
118 print("Using default.")
119
120 def __initMenu(self):
121 """
122 Private method to initialize the menu.
123 """
124 self.__menu = QMenu("Color String")
125 self.__menu.addAction("Hex Color", self.__selectHexColor)
126 self.__menu.addAction("Color Name", self.__selectColorName)
127 self.__menu.setEnabled(False)
128
129 def __populateMenu(self, name, menu):
130 """
131 Private slot to populate the tools menu with our entry.
132
133 @param name name of the menu (string)
134 @param menu reference to the menu to be populated (QMenu)
135 """
136 if name != "Tools":
137 return
138
139 if not menu.isEmpty():
140 menu.addSeparator()
141 menu.addMenu(self.__menu)
142
143 def __editorOpened(self, editor):
144 """
145 Private slot called, when a new editor was opened.
146
147 @param editor reference to the new editor (QScintilla.Editor)
148 """
149 menu = editor.getMenu("Tools")
150 if menu is not None:
151 self.__editors[editor] = []
152 if not menu.isEmpty():
153 act = menu.addSeparator()
154 self.__editors[editor].append(act)
155 act = menu.addMenu(self.__menu)
156 self.__menu.setEnabled(True)
157 self.__editors[editor].append(act)
158
159 def __editorClosed(self, editor):
160 """
161 Private slot called, when an editor was closed.
162
163 @param editor reference to the editor (QScintilla.Editor)
164 """
165 try:
166 del self.__editors[editor]
167 if not self.__editors:
168 self.__menu.setEnabled(False)
169 except KeyError:
170 pass
171
172 def __isHexString(self, text):
173 """
174 Private method to check, if a given text is a hex string.
175
176 @param text text to check (string)
177 @return flag indicating a hex string (boolean)
178 """
179 isHex = True
180 for c in text:
181 isHex = isHex and c in "0123456789abcdefABCDEF"
182 return isHex
183
184 def __isValidColor(self, name):
185 """
186 Private method to check for a valid color name.
187
188 @param name color name to check (string)
189 @return flag indicating a valid color name (boolean)
190 """
191 try:
192 if self.__isHexString(name) and len(name) in [3, 6, 9, 12]:
193 return True
194 return QColor.isValidColor(name)
195 except AttributeError:
196 if name.startswith("#"):
197 if len(name) not in [4, 7, 10, 13]:
198 return False
199 hexCheckStr = name[1:]
200 return self.__isHexString(hexCheckStr)
201 else:
202 if self.__isHexString(name) and len(name) in [3, 6, 9, 12]:
203 return True
204 return name in QColor.colorNames()
205
206 def __selectHexColor(self):
207 """
208 Private slot implementing the hex color string selection.
209 """
210 editor = e5App().getObject("ViewManager").activeWindow()
211 if editor is None:
212 return
213
214 if editor.hasSelectedText():
215 currColor = editor.selectedText()
216 if not self.__isValidColor(currColor):
217 E5MessageBox.critical(
218 self.__ui,
219 self.trUtf8("Color String"),
220 self.trUtf8(
221 """<p>The selected string <b>{0}</b> is not a""" \
222 """ valid color string. Aborting!</p>""")
223 .format(currColor))
224 return
225
226 if currColor.startswith("#"):
227 withHash = True
228 elif self.__isHexString(currColor):
229 withHash = False
230 currColor = "#" + currColor
231 else:
232 withHash = True
233 initColor = QColor(currColor)
234 else:
235 withHash = True
236 currColor = ""
237 initColor = QColor()
238
239 color = QColorDialog.getColor(
240 initColor, self.__ui, self.tr("Color String"))
241 if color.isValid():
242 colorStr = color.name()
243 if not withHash:
244 colorStr = colorStr[1:]
245 editor.beginUndoAction()
246 if editor.hasSelectedText():
247 editor.replaceSelectedText(colorStr)
248 else:
249 line, index = editor.getCursorPosition()
250 editor.insert(colorStr)
251 editor.setCursorPosition(line, index + len(colorStr))
252 editor.endUndoAction()
253
254 def __selectColorName(self):
255 """
256 Private slot implementing the named color string selection.
257 """
258 editor = e5App().getObject("ViewManager").activeWindow()
259 if editor is None:
260 return
261
262 if editor.hasSelectedText():
263 currColor = editor.selectedText()
264 if currColor not in QColor.colorNames():
265 E5MessageBox.critical(
266 self.__ui,
267 self.trUtf8("Color String"),
268 self.trUtf8(
269 """<p>The selected string <b>{0}</b> is not a""" \
270 """ valid color name. Aborting!</p>""")
271 .format(currColor))
272 return
273 else:
274 currColor = ""
275
276 from ColorString.ColorSelectionDialog import ColorSelectionDialog
277 dlg = ColorSelectionDialog(currColor, self.__ui)
278 if dlg.exec_() == QDialog.Accepted:
279 colorStr = dlg.getColor()
280 editor.beginUndoAction()
281 if editor.hasSelectedText():
282 editor.replaceSelectedText(colorStr)
283 else:
284 line, index = editor.getCursorPosition()
285 editor.insert(colorStr)
286 editor.setCursorPosition(line, index + len(colorStr))
287 editor.endUndoAction()

eric ide

mercurial