PluginSelectionEncloser.py

changeset 1
a9f6842a18f6
parent 0
96fac1d8181f
child 3
b26df0282953
equal deleted inserted replaced
0:96fac1d8181f 1:a9f6842a18f6
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2014 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the Selection Encloser plug-in.
8 """
9
10 from __future__ import unicode_literals # __IGNORE_WARNING__
11
12 import os
13 import json
14
15 from PyQt4.QtCore import QObject, QTranslator, QCoreApplication
16 from PyQt4.QtGui import QAction, QMenu
17
18 from E5Gui.E5Application import e5App
19
20 import Preferences
21
22 # Start-Of-Header
23 name = "Selection Encloser Plug-in"
24 author = "Detlev Offenbach <detlev@die-offenbachs.de>"
25 autoactivate = True
26 deactivateable = True
27 version = "0.1.0"
28 className = "SelectionEncloserPlugin"
29 packageName = "SelectionEncloser"
30 shortDescription = "Enclose the selection with a string."
31 longDescription = \
32 """This plug-in implements a tool to enclose the selection of""" \
33 """ the current editor with a string. The enclosing string is""" \
34 """ selectable via a configurable menu hierarchy."""
35 needsRestart = False
36 pyqtApi = 2
37 python2Compatible = True
38 # End-Of-Header
39
40 error = ""
41
42 selectionEncloserPluginObject = None
43
44
45 def createSelectionEncloserPage(configDlg):
46 """
47 Module function to create the Selection Encloser configuration page.
48
49 @param configDlg reference to the configuration dialog
50 @return reference to the configuration page
51 """
52 global selectionEncloserPluginObject
53 from SelectionEncloser.ConfigurationPage.SelectionEncloserPage import \
54 SelectionEncloserPage
55 page = SelectionEncloserPage(selectionEncloserPluginObject)
56 return page
57
58
59 def getConfigData():
60 """
61 Module function returning data as required by the configuration dialog.
62
63 @return dictionary containing the relevant data
64 """
65 if e5App().getObject("UserInterface").versionIsNewer('5.2.99', '20121012'):
66 return {
67 "selectionEncloserPage": [
68 QCoreApplication.translate("SelectionEncloserPlugin",
69 "Selection Encloser"),
70 os.path.join("SelectionEncloser", "icons",
71 "selectionEncloser.png"),
72 createSelectionEncloserPage, None, None],
73 }
74 else:
75 return {}
76
77
78 def prepareUninstall():
79 """
80 Module function to prepare for an uninstallation.
81 """
82 Preferences.Prefs.settings.remove(SelectionEncloserPlugin.PreferencesKey)
83
84
85 class SelectionEncloserPlugin(QObject):
86 """
87 Class implementing the Selection Encloser plugin.
88 """
89 PreferencesKey = "SelectionEncloser"
90
91 def __init__(self, ui):
92 """
93 Constructor
94
95 @param ui reference to the user interface object (UI.UserInterface)
96 """
97 QObject.__init__(self, ui)
98 self.__ui = ui
99
100 # menu is a list of lists; each list consists of a string for the
101 # submenu title and a list of submenu entries. The title of the submenu
102 # entry is the enclosing string.
103 defaultMenu = [
104 [self.tr("Quotes"), ['"', "'", '"""', "'''"]],
105 ]
106 self.__defaults = {
107 "MenuHierarchy": json.dumps(defaultMenu),
108 }
109
110 self.__translator = None
111 self.__loadTranslator()
112
113 self.__initMenu()
114
115 self.__editors = {}
116
117 def activate(self):
118 """
119 Public method to activate this plugin.
120
121 @return tuple of None and activation status (boolean)
122 """
123 global error
124 error = "" # clear previous error
125
126 global selectionEncloserPluginObject
127 selectionEncloserPluginObject = self
128
129 self.__ui.showMenu.connect(self.__populateMenu)
130
131 e5App().getObject("ViewManager").editorOpenedEd.connect(
132 self.__editorOpened)
133 e5App().getObject("ViewManager").editorClosedEd.connect(
134 self.__editorClosed)
135
136 for editor in e5App().getObject("ViewManager").getOpenEditors():
137 self.__editorOpened(editor)
138
139 return None, True
140
141 def deactivate(self):
142 """
143 Public method to deactivate this plugin.
144 """
145 self.__ui.showMenu.disconnect(self.__populateMenu)
146
147 e5App().getObject("ViewManager").editorOpenedEd.disconnect(
148 self.__editorOpened)
149 e5App().getObject("ViewManager").editorClosedEd.disconnect(
150 self.__editorClosed)
151
152 for editor, acts in self.__editors.items():
153 menu = editor.getMenu("Tools")
154 if menu is not None:
155 for act in acts:
156 menu.removeAction(act)
157 self.__editors = {}
158
159 def __loadTranslator(self):
160 """
161 Private method to load the translation file.
162 """
163 if self.__ui is not None:
164 loc = self.__ui.getLocale()
165 if loc and loc != "C":
166 locale_dir = os.path.join(
167 os.path.dirname(__file__), "SelectionEncloser", "i18n")
168 translation = "selectionencloser_{0}".format(loc)
169 translator = QTranslator(None)
170 loaded = translator.load(translation, locale_dir)
171 if loaded:
172 self.__translator = translator
173 e5App().installTranslator(self.__translator)
174 else:
175 print("Warning: translation file '{0}' could not be"
176 " loaded.".format(translation))
177 print("Using default.")
178
179 def getPreferences(self, key):
180 """
181 Public method to retrieve the various settings.
182
183 @param key the key of the value to get (string)
184 @return the requested setting
185 """
186 if key in ["MenuHierarchy"]:
187 return json.loads(
188 Preferences.Prefs.settings.value(
189 self.PreferencesKey + "/" + key, self.__defaults[key]))
190 else:
191 return Preferences.Prefs.settings.value(
192 self.PreferencesKey + "/" + key, self.__defaults[key])
193
194 def setPreferences(self, key, value):
195 """
196 Public method to store the various settings.
197
198 @param key the key of the setting to be set (string)
199 @param value the value to be set
200 """
201 if key in ["MenuHierarchy"]:
202 Preferences.Prefs.settings.setValue(
203 self.PreferencesKey + "/" + key, json.dumps(value))
204 else:
205 Preferences.Prefs.settings.setValue(
206 self.PreferencesKey + "/" + key, value)
207
208 def __initMenu(self):
209 """
210 Private method to initialize the menu.
211 """
212 self.__menu = QMenu("Enclose Selection")
213 self.__menu.setEnabled(False)
214 self.__menu.aboutToShow.connect(self.__showMenu)
215
216 def __populateMenu(self, name, menu):
217 """
218 Private slot to populate the tools menu with our entry.
219
220 @param name name of the menu (string)
221 @param menu reference to the menu to be populated (QMenu)
222 """
223 if name != "Tools":
224 return
225
226 editor = e5App().getObject("ViewManager").activeWindow()
227
228 if not menu.isEmpty():
229 menu.addSeparator()
230
231 act = menu.addMenu(self.__menu)
232 act.setEnabled(editor is not None and editor.hasSelectedText())
233
234 def __editorOpened(self, editor):
235 """
236 Private slot called, when a new editor was opened.
237
238 @param editor reference to the new editor (QScintilla.Editor)
239 """
240 menu = editor.getMenu("Tools")
241 if menu is not None:
242 self.__editors[editor] = []
243 if not menu.isEmpty():
244 act = menu.addSeparator()
245 self.__editors[editor].append(act)
246 act = menu.addMenu(self.__menu)
247 self.__menu.setEnabled(True)
248 self.__editors[editor].append(act)
249 editor.showMenu.connect(self.__editorShowMenu)
250
251 def __editorClosed(self, editor):
252 """
253 Private slot called, when an editor was closed.
254
255 @param editor reference to the editor (QScintilla.Editor)
256 """
257 try:
258 del self.__editors[editor]
259 if not self.__editors:
260 self.__menu.setEnabled(False)
261 except KeyError:
262 pass
263
264 def __editorShowMenu(self, menuName, menu, editor):
265 """
266 Private slot called, when the the editor context menu or a submenu is
267 about to be shown.
268
269 @param menuName name of the menu to be shown (string)
270 @param menu reference to the menu (QMenu)
271 @param editor reference to the editor
272 """
273 if menuName == "Tools":
274 for act in self.__editors[editor]:
275 if not act.isSeparator():
276 act.setEnabled(editor.hasSelectedText())
277
278 def __showMenu(self):
279 """
280 Private slot to build the menu hierarchy.
281 """
282 self.__menu.clear()
283 hierarchy = self.getPreferences("MenuHierarchy")
284 for menuTitle, entries in hierarchy:
285 submenu = QMenu(menuTitle, self.__menu)
286 for entry in entries:
287 act = submenu.addAction(entry, self.__encloseSelection)
288 act.setData(entry)
289 self.__menu.addMenu(submenu)
290
291 def __encloseSelection(self):
292 """
293 Private slot to enclose the selection with the selected string.
294 """
295 act = self.sender()
296 if act is None or not isinstance(act, QAction):
297 return
298
299 editor = e5App().getObject("ViewManager").activeWindow()
300 if editor is None:
301 return
302
303 if not editor.hasSelectedText():
304 return
305
306 string = act.data()
307 if not string:
308 return
309
310 newText = string + editor.selectedText() + string
311 editor.beginUndoAction()
312 editor.replaceSelectedText(newText)
313 editor.endUndoAction()

eric ide

mercurial