PluginSelectionEncloser.py

branch
eric7
changeset 55
ccddc623f3c1
parent 53
ceb9ed8084db
child 56
2ca258eb5859
equal deleted inserted replaced
54:98441216a295 55:ccddc623f3c1
38 # End-Of-Header 38 # End-Of-Header
39 39
40 error = "" 40 error = ""
41 41
42 selectionEncloserPluginObject = None 42 selectionEncloserPluginObject = None
43 43
44 44
45 def createSelectionEncloserPage(configDlg): 45 def createSelectionEncloserPage(configDlg):
46 """ 46 """
47 Module function to create the Selection Encloser configuration page. 47 Module function to create the Selection Encloser configuration page.
48 48
49 @param configDlg reference to the configuration dialog 49 @param configDlg reference to the configuration dialog
50 @type ConfigurationWidget 50 @type ConfigurationWidget
51 @return reference to the configuration page 51 @return reference to the configuration page
52 @rtype SelectionEncloserPage 52 @rtype SelectionEncloserPage
53 """ 53 """
54 global selectionEncloserPluginObject 54 global selectionEncloserPluginObject
55 from SelectionEncloser.ConfigurationPage.SelectionEncloserPage import ( 55 from SelectionEncloser.ConfigurationPage.SelectionEncloserPage import (
56 SelectionEncloserPage 56 SelectionEncloserPage,
57 ) 57 )
58
58 return SelectionEncloserPage(selectionEncloserPluginObject) 59 return SelectionEncloserPage(selectionEncloserPluginObject)
59 60
60 61
61 def getConfigData(): 62 def getConfigData():
62 """ 63 """
63 Module function returning data as required by the configuration dialog. 64 Module function returning data as required by the configuration dialog.
64 65
65 @return dictionary containing the relevant data 66 @return dictionary containing the relevant data
66 @rtype dict 67 @rtype dict
67 """ 68 """
68 usesDarkPalette = ericApp().usesDarkPalette() 69 usesDarkPalette = ericApp().usesDarkPalette()
69 iconSuffix = "dark" if usesDarkPalette else "light" 70 iconSuffix = "dark" if usesDarkPalette else "light"
70 71
71 return { 72 return {
72 "selectionEncloserPage": [ 73 "selectionEncloserPage": [
73 QCoreApplication.translate("SelectionEncloserPlugin", 74 QCoreApplication.translate("SelectionEncloserPlugin", "Selection Encloser"),
74 "Selection Encloser"), 75 os.path.join(
75 os.path.join("SelectionEncloser", "icons", 76 "SelectionEncloser", "icons", "selectionEncloser-{0}".format(iconSuffix)
76 "selectionEncloser-{0}".format(iconSuffix)), 77 ),
77 createSelectionEncloserPage, None, None], 78 createSelectionEncloserPage,
79 None,
80 None,
81 ],
78 } 82 }
79 83
80 84
81 def prepareUninstall(): 85 def prepareUninstall():
82 """ 86 """
87 91
88 class SelectionEncloserPlugin(QObject): 92 class SelectionEncloserPlugin(QObject):
89 """ 93 """
90 Class implementing the Selection Encloser plugin. 94 Class implementing the Selection Encloser plugin.
91 """ 95 """
96
92 PreferencesKey = "SelectionEncloser" 97 PreferencesKey = "SelectionEncloser"
93 98
94 def __init__(self, ui): 99 def __init__(self, ui):
95 """ 100 """
96 Constructor 101 Constructor
97 102
98 @param ui reference to the user interface object 103 @param ui reference to the user interface object
99 @type UserInterface 104 @type UserInterface
100 """ 105 """
101 super().__init__(ui) 106 super().__init__(ui)
102 self.__ui = ui 107 self.__ui = ui
103 108
104 # menu is a list of lists; each list consists of a string for the 109 # menu is a list of lists; each list consists of a string for the
105 # submenu title and a list of submenu entries. Each submenu entry 110 # submenu title and a list of submenu entries. Each submenu entry
106 # consists of another list giving the title and the enclosing string 111 # consists of another list giving the title and the enclosing string
107 # or formatting string. 112 # or formatting string.
108 defaultMenu = [ 113 defaultMenu = [
109 [self.tr("Quotes"), [ 114 [
110 ['"', '"'], 115 self.tr("Quotes"),
111 ["'", "'"], 116 [['"', '"'], ["'", "'"], ['"""', '"""'], ["'''", "'''"]],
112 ['"""', '"""'], 117 ],
113 ["'''", "'''"] 118 [
114 ]], 119 self.tr("HTML"),
115 [self.tr("HTML"), [ 120 [
116 ['<h1>', '<h1>{0}</h1>'], 121 ["<h1>", "<h1>{0}</h1>"],
117 ['<h2>', '<h2>{0}</h2>'], 122 ["<h2>", "<h2>{0}</h2>"],
118 ['<h3>', '<h3>{0}</h3>'], 123 ["<h3>", "<h3>{0}</h3>"],
119 ['--Separator--', ''], 124 ["--Separator--", ""],
120 ['<p>', '<p>{0}</p>'], 125 ["<p>", "<p>{0}</p>"],
121 ['<div>', '<div>{0}</div>'], 126 ["<div>", "<div>{0}</div>"],
122 ['<span>', '<span>{0}</span>'], 127 ["<span>", "<span>{0}</span>"],
123 ]] 128 ],
129 ],
124 ] 130 ]
125 self.__defaults = { 131 self.__defaults = {
126 "MenuHierarchy": json.dumps(defaultMenu), 132 "MenuHierarchy": json.dumps(defaultMenu),
127 } 133 }
128 134
129 self.__translator = None 135 self.__translator = None
130 self.__loadTranslator() 136 self.__loadTranslator()
131 137
132 self.__initMenu() 138 self.__initMenu()
133 139
134 self.__editors = {} 140 self.__editors = {}
135 self.__mainActions = [] 141 self.__mainActions = []
136 142
137 def activate(self): 143 def activate(self):
138 """ 144 """
139 Public method to activate this plugin. 145 Public method to activate this plugin.
140 146
141 @return tuple of None and activation status 147 @return tuple of None and activation status
142 @rtype (None, bool) 148 @rtype (None, bool)
143 """ 149 """
144 global error 150 global error
145 error = "" # clear previous error 151 error = "" # clear previous error
146 152
147 global selectionEncloserPluginObject 153 global selectionEncloserPluginObject
148 selectionEncloserPluginObject = self 154 selectionEncloserPluginObject = self
149 155
150 self.__ui.showMenu.connect(self.__populateMenu) 156 self.__ui.showMenu.connect(self.__populateMenu)
151 157
152 menu = self.__ui.getMenu("plugin_tools") 158 menu = self.__ui.getMenu("plugin_tools")
153 if menu is not None: 159 if menu is not None:
154 if not menu.isEmpty(): 160 if not menu.isEmpty():
155 act = menu.addSeparator() 161 act = menu.addSeparator()
156 self.__mainActions.append(act) 162 self.__mainActions.append(act)
157 act = menu.addMenu(self.__menu) 163 act = menu.addMenu(self.__menu)
158 self.__mainActions.append(act) 164 self.__mainActions.append(act)
159 165
160 ericApp().getObject("ViewManager").editorOpenedEd.connect( 166 ericApp().getObject("ViewManager").editorOpenedEd.connect(self.__editorOpened)
161 self.__editorOpened) 167 ericApp().getObject("ViewManager").editorClosedEd.connect(self.__editorClosed)
162 ericApp().getObject("ViewManager").editorClosedEd.connect( 168
163 self.__editorClosed)
164
165 for editor in ericApp().getObject("ViewManager").getOpenEditors(): 169 for editor in ericApp().getObject("ViewManager").getOpenEditors():
166 self.__editorOpened(editor) 170 self.__editorOpened(editor)
167 171
168 return None, True 172 return None, True
169 173
170 def deactivate(self): 174 def deactivate(self):
171 """ 175 """
172 Public method to deactivate this plugin. 176 Public method to deactivate this plugin.
173 """ 177 """
174 self.__ui.showMenu.disconnect(self.__populateMenu) 178 self.__ui.showMenu.disconnect(self.__populateMenu)
175 179
176 menu = self.__ui.getMenu("plugin_tools") 180 menu = self.__ui.getMenu("plugin_tools")
177 if menu is not None: 181 if menu is not None:
178 for act in self.__mainActions: 182 for act in self.__mainActions:
179 menu.removeAction(act) 183 menu.removeAction(act)
180 self.__mainActions = [] 184 self.__mainActions = []
181 185
182 ericApp().getObject("ViewManager").editorOpenedEd.disconnect( 186 ericApp().getObject("ViewManager").editorOpenedEd.disconnect(
183 self.__editorOpened) 187 self.__editorOpened
188 )
184 ericApp().getObject("ViewManager").editorClosedEd.disconnect( 189 ericApp().getObject("ViewManager").editorClosedEd.disconnect(
185 self.__editorClosed) 190 self.__editorClosed
186 191 )
192
187 for editor, acts in self.__editors.items(): 193 for editor, acts in self.__editors.items():
188 editor.showMenu.disconnect(self.__editorShowMenu) 194 editor.showMenu.disconnect(self.__editorShowMenu)
189 menu = editor.getMenu("Tools") 195 menu = editor.getMenu("Tools")
190 if menu is not None: 196 if menu is not None:
191 for act in acts: 197 for act in acts:
192 menu.removeAction(act) 198 menu.removeAction(act)
193 self.__editors = {} 199 self.__editors = {}
194 200
195 def __loadTranslator(self): 201 def __loadTranslator(self):
196 """ 202 """
197 Private method to load the translation file. 203 Private method to load the translation file.
198 """ 204 """
199 if self.__ui is not None: 205 if self.__ui is not None:
200 loc = self.__ui.getLocale() 206 loc = self.__ui.getLocale()
201 if loc and loc != "C": 207 if loc and loc != "C":
202 locale_dir = os.path.join( 208 locale_dir = os.path.join(
203 os.path.dirname(__file__), "SelectionEncloser", "i18n") 209 os.path.dirname(__file__), "SelectionEncloser", "i18n"
210 )
204 translation = "selectionencloser_{0}".format(loc) 211 translation = "selectionencloser_{0}".format(loc)
205 translator = QTranslator(None) 212 translator = QTranslator(None)
206 loaded = translator.load(translation, locale_dir) 213 loaded = translator.load(translation, locale_dir)
207 if loaded: 214 if loaded:
208 self.__translator = translator 215 self.__translator = translator
209 ericApp().installTranslator(self.__translator) 216 ericApp().installTranslator(self.__translator)
210 else: 217 else:
211 print("Warning: translation file '{0}' could not be" 218 print(
212 " loaded.".format(translation)) 219 "Warning: translation file '{0}' could not be"
220 " loaded.".format(translation)
221 )
213 print("Using default.") 222 print("Using default.")
214 223
215 def getPreferences(self, key): 224 def getPreferences(self, key):
216 """ 225 """
217 Public method to retrieve the various settings. 226 Public method to retrieve the various settings.
218 227
219 @param key key of the value to get 228 @param key key of the value to get
220 @type str 229 @type str
221 @return value of the requested setting 230 @return value of the requested setting
222 @rtype Any 231 @rtype Any
223 """ 232 """
224 if key in ["MenuHierarchy"]: 233 if key in ["MenuHierarchy"]:
225 return json.loads( 234 return json.loads(
226 Preferences.Prefs.settings.value( 235 Preferences.Prefs.settings.value(
227 self.PreferencesKey + "/" + key, self.__defaults[key])) 236 self.PreferencesKey + "/" + key, self.__defaults[key]
237 )
238 )
228 else: 239 else:
229 return Preferences.Prefs.settings.value( 240 return Preferences.Prefs.settings.value(
230 self.PreferencesKey + "/" + key, self.__defaults[key]) 241 self.PreferencesKey + "/" + key, self.__defaults[key]
231 242 )
243
232 def setPreferences(self, key, value): 244 def setPreferences(self, key, value):
233 """ 245 """
234 Public method to store the various settings. 246 Public method to store the various settings.
235 247
236 @param key key of the setting to be set 248 @param key key of the setting to be set
237 @type str 249 @type str
238 @param value value to be set 250 @param value value to be set
239 @type Any 251 @type Any
240 """ 252 """
241 if key in ["MenuHierarchy"]: 253 if key in ["MenuHierarchy"]:
242 Preferences.Prefs.settings.setValue( 254 Preferences.Prefs.settings.setValue(
243 self.PreferencesKey + "/" + key, json.dumps(value)) 255 self.PreferencesKey + "/" + key, json.dumps(value)
256 )
244 else: 257 else:
245 Preferences.Prefs.settings.setValue( 258 Preferences.Prefs.settings.setValue(self.PreferencesKey + "/" + key, value)
246 self.PreferencesKey + "/" + key, value) 259
247
248 def __initMenu(self): 260 def __initMenu(self):
249 """ 261 """
250 Private method to initialize the menu. 262 Private method to initialize the menu.
251 """ 263 """
252 self.__menu = QMenu("Enclose Selection") 264 self.__menu = QMenu("Enclose Selection")
253 self.__menu.setEnabled(False) 265 self.__menu.setEnabled(False)
254 self.__menu.aboutToShow.connect(self.__showMenu) 266 self.__menu.aboutToShow.connect(self.__showMenu)
255 267
256 def __populateMenu(self, name, menu): 268 def __populateMenu(self, name, menu):
257 """ 269 """
258 Private slot to populate the tools menu with our entry. 270 Private slot to populate the tools menu with our entry.
259 271
260 @param name name of the menu 272 @param name name of the menu
261 @type str 273 @type str
262 @param menu reference to the menu to be populated 274 @param menu reference to the menu to be populated
263 @type QMenu 275 @type QMenu
264 """ 276 """
265 if name not in ["Tools", "PluginTools"]: 277 if name not in ["Tools", "PluginTools"]:
266 return 278 return
267 279
268 editor = ericApp().getObject("ViewManager").activeWindow() 280 editor = ericApp().getObject("ViewManager").activeWindow()
269 281
270 if name == "Tools": 282 if name == "Tools":
271 if not menu.isEmpty(): 283 if not menu.isEmpty():
272 menu.addSeparator() 284 menu.addSeparator()
273 act = menu.addMenu(self.__menu) 285 act = menu.addMenu(self.__menu)
274 act.setEnabled(editor is not None and editor.hasSelectedText()) 286 act.setEnabled(editor is not None and editor.hasSelectedText())
275 elif name == "PluginTools" and self.__mainActions: 287 elif name == "PluginTools" and self.__mainActions:
276 self.__menu.setEnabled(editor is not None and 288 self.__menu.setEnabled(editor is not None and editor.hasSelectedText())
277 editor.hasSelectedText()) 289
278
279 def __editorOpened(self, editor): 290 def __editorOpened(self, editor):
280 """ 291 """
281 Private slot called, when a new editor was opened. 292 Private slot called, when a new editor was opened.
282 293
283 @param editor reference to the new editor 294 @param editor reference to the new editor
284 @type Editor 295 @type Editor
285 """ 296 """
286 menu = editor.getMenu("Tools") 297 menu = editor.getMenu("Tools")
287 if menu is not None: 298 if menu is not None:
291 self.__editors[editor].append(act) 302 self.__editors[editor].append(act)
292 act = menu.addMenu(self.__menu) 303 act = menu.addMenu(self.__menu)
293 self.__menu.setEnabled(True) 304 self.__menu.setEnabled(True)
294 self.__editors[editor].append(act) 305 self.__editors[editor].append(act)
295 editor.showMenu.connect(self.__editorShowMenu) 306 editor.showMenu.connect(self.__editorShowMenu)
296 307
297 def __editorClosed(self, editor): 308 def __editorClosed(self, editor):
298 """ 309 """
299 Private slot called, when an editor was closed. 310 Private slot called, when an editor was closed.
300 311
301 @param editor reference to the editor 312 @param editor reference to the editor
302 @type Editor 313 @type Editor
303 """ 314 """
304 with contextlib.suppress(KeyError): 315 with contextlib.suppress(KeyError):
305 del self.__editors[editor] 316 del self.__editors[editor]
306 if not self.__editors: 317 if not self.__editors:
307 self.__menu.setEnabled(False) 318 self.__menu.setEnabled(False)
308 319
309 def __editorShowMenu(self, menuName, menu, editor): 320 def __editorShowMenu(self, menuName, menu, editor):
310 """ 321 """
311 Private slot called, when the the editor context menu or a submenu is 322 Private slot called, when the the editor context menu or a submenu is
312 about to be shown. 323 about to be shown.
313 324
314 @param menuName name of the menu to be shown 325 @param menuName name of the menu to be shown
315 @type str 326 @type str
316 @param menu reference to the menu 327 @param menu reference to the menu
317 @type QMenu 328 @type QMenu
318 @param editor reference to the editor 329 @param editor reference to the editor
325 if not menu.isEmpty(): 336 if not menu.isEmpty():
326 act = menu.addSeparator() 337 act = menu.addSeparator()
327 self.__editors[editor].append(act) 338 self.__editors[editor].append(act)
328 act = menu.addMenu(self.__menu) 339 act = menu.addMenu(self.__menu)
329 self.__editors[editor].append(act) 340 self.__editors[editor].append(act)
330 341
331 self.__menu.setEnabled(editor.selectedText() != '') 342 self.__menu.setEnabled(editor.selectedText() != "")
332 343
333 def __showMenu(self): 344 def __showMenu(self):
334 """ 345 """
335 Private slot to build the menu hierarchy. 346 Private slot to build the menu hierarchy.
336 """ 347 """
337 self.__menu.clear() 348 self.__menu.clear()
338 hierarchy = self.getPreferences("MenuHierarchy") 349 hierarchy = self.getPreferences("MenuHierarchy")
339 for menuTitle, entries in hierarchy: 350 for menuTitle, entries in hierarchy:
340 if menuTitle == '--Separator--': 351 if menuTitle == "--Separator--":
341 self.__menu.addSeparator() 352 self.__menu.addSeparator()
342 else: 353 else:
343 submenu = QMenu(menuTitle, self.__menu) 354 submenu = QMenu(menuTitle, self.__menu)
344 for title, encString in entries: 355 for title, encString in entries:
345 if title == '--Separator--': 356 if title == "--Separator--":
346 submenu.addSeparator() 357 submenu.addSeparator()
347 else: 358 else:
348 act = submenu.addAction(title) 359 act = submenu.addAction(title)
349 act.setData(encString) 360 act.setData(encString)
350 submenu.triggered.connect(self.__encloseSelection) 361 submenu.triggered.connect(self.__encloseSelection)
351 self.__menu.addMenu(submenu) 362 self.__menu.addMenu(submenu)
352 363
353 @pyqtSlot(QAction) 364 @pyqtSlot(QAction)
354 def __encloseSelection(self, act): 365 def __encloseSelection(self, act):
355 """ 366 """
356 Private slot to enclose the selection with the selected string. 367 Private slot to enclose the selection with the selected string.
357 368
358 @param act action that triggered 369 @param act action that triggered
359 @type QAction 370 @type QAction
360 """ 371 """
361 if act is None: 372 if act is None:
362 return 373 return
363 374
364 editor = ericApp().getObject("ViewManager").activeWindow() 375 editor = ericApp().getObject("ViewManager").activeWindow()
365 if editor is None: 376 if editor is None:
366 return 377 return
367 378
368 if not editor.hasSelectedText(): 379 if not editor.hasSelectedText():
369 return 380 return
370 381
371 encloseString = act.data() 382 encloseString = act.data()
372 if not encloseString: 383 if not encloseString:
373 return 384 return
374 385
375 if '%s' in encloseString: 386 if "%s" in encloseString:
376 newText = encloseString % editor.selectedText() 387 newText = encloseString % editor.selectedText()
377 elif '{0}' in encloseString or '{}' in encloseString: 388 elif "{0}" in encloseString or "{}" in encloseString:
378 # __IGNORE_WARNING_M613__ 389 # __IGNORE_WARNING_M613__
379 newText = encloseString.format(editor.selectedText()) 390 newText = encloseString.format(editor.selectedText())
380 else: 391 else:
381 newText = encloseString + editor.selectedText() + encloseString 392 newText = encloseString + editor.selectedText() + encloseString
382 editor.beginUndoAction() 393 editor.beginUndoAction()
383 editor.replaceSelectedText(newText) 394 editor.replaceSelectedText(newText)
384 editor.endUndoAction() 395 editor.endUndoAction()
385 396
397
386 # 398 #
387 # eflag: noqa = M801 399 # eflag: noqa = M801

eric ide

mercurial