PluginSplitMergeCamelCase.py

branch
eric7
changeset 54
a29b5f01c2fa
parent 52
8dcfbc830b52
child 55
dbc20f5da446
equal deleted inserted replaced
53:781a678e6c84 54:a29b5f01c2fa
41 41
42 class SplitMergeCamelCasePlugin(QObject): 42 class SplitMergeCamelCasePlugin(QObject):
43 """ 43 """
44 Class implementing the split, merge or convert camel case plug-in. 44 Class implementing the split, merge or convert camel case plug-in.
45 """ 45 """
46
46 def __init__(self, ui): 47 def __init__(self, ui):
47 """ 48 """
48 Constructor 49 Constructor
49 50
50 @param ui reference to the user interface object 51 @param ui reference to the user interface object
51 @type UserInterface 52 @type UserInterface
52 """ 53 """
53 super().__init__(ui) 54 super().__init__(ui)
54 self.__ui = ui 55 self.__ui = ui
55 56
56 self.__translator = None 57 self.__translator = None
57 self.__loadTranslator() 58 self.__loadTranslator()
58 59
59 self.__initMenu() 60 self.__initMenu()
60 61
61 self.__editors = {} 62 self.__editors = {}
62 self.__mainActions = [] 63 self.__mainActions = []
63 64
64 def activate(self): 65 def activate(self):
65 """ 66 """
66 Public method to activate this plugin. 67 Public method to activate this plugin.
67 68
68 @return tuple of None and activation status 69 @return tuple of None and activation status
69 @rtype tuple of (None, bool) 70 @rtype tuple of (None, bool)
70 """ 71 """
71 global error 72 global error
72 error = "" # clear previous error 73 error = "" # clear previous error
73 74
74 self.__ui.showMenu.connect(self.__populateMenu) 75 self.__ui.showMenu.connect(self.__populateMenu)
75 76
76 menu = self.__ui.getMenu("plugin_tools") 77 menu = self.__ui.getMenu("plugin_tools")
77 if menu is not None: 78 if menu is not None:
78 if not menu.isEmpty(): 79 if not menu.isEmpty():
79 act = menu.addSeparator() 80 act = menu.addSeparator()
80 self.__mainActions.append(act) 81 self.__mainActions.append(act)
81 act = menu.addMenu(self.__menu) 82 act = menu.addMenu(self.__menu)
82 self.__mainActions.append(act) 83 self.__mainActions.append(act)
83 84
84 ericApp().getObject("ViewManager").editorOpenedEd.connect( 85 ericApp().getObject("ViewManager").editorOpenedEd.connect(self.__editorOpened)
85 self.__editorOpened) 86 ericApp().getObject("ViewManager").editorClosedEd.connect(self.__editorClosed)
86 ericApp().getObject("ViewManager").editorClosedEd.connect( 87
87 self.__editorClosed)
88
89 for editor in ericApp().getObject("ViewManager").getOpenEditors(): 88 for editor in ericApp().getObject("ViewManager").getOpenEditors():
90 self.__editorOpened(editor) 89 self.__editorOpened(editor)
91 90
92 return None, True 91 return None, True
93 92
94 def deactivate(self): 93 def deactivate(self):
95 """ 94 """
96 Public method to deactivate this plugin. 95 Public method to deactivate this plugin.
97 """ 96 """
98 self.__ui.showMenu.disconnect(self.__populateMenu) 97 self.__ui.showMenu.disconnect(self.__populateMenu)
99 98
100 menu = self.__ui.getMenu("plugin_tools") 99 menu = self.__ui.getMenu("plugin_tools")
101 if menu is not None: 100 if menu is not None:
102 for act in self.__mainActions: 101 for act in self.__mainActions:
103 menu.removeAction(act) 102 menu.removeAction(act)
104 self.__mainActions = [] 103 self.__mainActions = []
105 104
106 ericApp().getObject("ViewManager").editorOpenedEd.disconnect( 105 ericApp().getObject("ViewManager").editorOpenedEd.disconnect(
107 self.__editorOpened) 106 self.__editorOpened
107 )
108 ericApp().getObject("ViewManager").editorClosedEd.disconnect( 108 ericApp().getObject("ViewManager").editorClosedEd.disconnect(
109 self.__editorClosed) 109 self.__editorClosed
110 110 )
111
111 for editor, acts in self.__editors.items(): 112 for editor, acts in self.__editors.items():
112 editor.showMenu.disconnect(self.__editorShowMenu) 113 editor.showMenu.disconnect(self.__editorShowMenu)
113 menu = editor.getMenu("Tools") 114 menu = editor.getMenu("Tools")
114 if menu is not None: 115 if menu is not None:
115 for act in acts: 116 for act in acts:
116 menu.removeAction(act) 117 menu.removeAction(act)
117 self.__editors = {} 118 self.__editors = {}
118 119
119 def __loadTranslator(self): 120 def __loadTranslator(self):
120 """ 121 """
121 Private method to load the translation file. 122 Private method to load the translation file.
122 """ 123 """
123 if self.__ui is not None: 124 if self.__ui is not None:
124 loc = self.__ui.getLocale() 125 loc = self.__ui.getLocale()
125 if loc and loc != "C": 126 if loc and loc != "C":
126 locale_dir = os.path.join( 127 locale_dir = os.path.join(
127 os.path.dirname(__file__), "SplitMergeCamelCase", "i18n") 128 os.path.dirname(__file__), "SplitMergeCamelCase", "i18n"
129 )
128 translation = "splitmergecamelcase_{0}".format(loc) 130 translation = "splitmergecamelcase_{0}".format(loc)
129 translator = QTranslator(None) 131 translator = QTranslator(None)
130 loaded = translator.load(translation, locale_dir) 132 loaded = translator.load(translation, locale_dir)
131 if loaded: 133 if loaded:
132 self.__translator = translator 134 self.__translator = translator
133 ericApp().installTranslator(self.__translator) 135 ericApp().installTranslator(self.__translator)
134 else: 136 else:
135 print("Warning: translation file '{0}' could not be" 137 print(
136 " loaded.".format(translation)) 138 "Warning: translation file '{0}' could not be"
139 " loaded.".format(translation)
140 )
137 print("Using default.") 141 print("Using default.")
138 142
139 def __initMenu(self): 143 def __initMenu(self):
140 """ 144 """
141 Private method to initialize the camel case handling menu. 145 Private method to initialize the camel case handling menu.
142 """ 146 """
143 self.__menu = QMenu(self.tr("Camel/Snake Case Handling")) 147 self.__menu = QMenu(self.tr("Camel/Snake Case Handling"))
144 self.__menu.addAction( 148 self.__menu.addAction(self.tr("Split from Camel Case"), self.__splitCamelCase)
145 self.tr("Split from Camel Case"), 149 self.__menu.addAction(self.tr("Merge to Camel Case"), self.__mergeCamelCase)
146 self.__splitCamelCase)
147 self.__menu.addAction(
148 self.tr("Merge to Camel Case"),
149 self.__mergeCamelCase)
150 self.__menu.addAction( 150 self.__menu.addAction(
151 self.tr("Merge to Camel Case (upper case first)"), 151 self.tr("Merge to Camel Case (upper case first)"),
152 self.__mergeCamelCaseUppercaseFirst) 152 self.__mergeCamelCaseUppercaseFirst,
153 )
154 self.__menu.addSeparator()
155 self.__menu.addAction(self.tr("Split from Snake Case"), self.__splitSnakeCase)
156 self.__menu.addAction(self.tr("Merge to Snake Case"), self.__mergeSnakeCase)
153 self.__menu.addSeparator() 157 self.__menu.addSeparator()
154 self.__menu.addAction( 158 self.__menu.addAction(
155 self.tr("Split from Snake Case"), 159 self.tr("Camel Case to Snake Case"), self.__camelCaseToSnakeCase
156 self.__splitSnakeCase) 160 )
157 self.__menu.addAction( 161 self.__menu.addAction(
158 self.tr("Merge to Snake Case"), 162 self.tr("Snake Case to Camel Case"), self.__snakeCaseToCamelCase
159 self.__mergeSnakeCase) 163 )
160 self.__menu.addSeparator()
161 self.__menu.addAction(
162 self.tr("Camel Case to Snake Case"),
163 self.__camelCaseToSnakeCase)
164 self.__menu.addAction(
165 self.tr("Snake Case to Camel Case"),
166 self.__snakeCaseToCamelCase)
167 self.__menu.addAction( 164 self.__menu.addAction(
168 self.tr("Snake Case to Camel Case (upper case first)"), 165 self.tr("Snake Case to Camel Case (upper case first)"),
169 self.__snakeCaseToCamelCaseUppercaseFirst) 166 self.__snakeCaseToCamelCaseUppercaseFirst,
170 167 )
168
171 def __populateMenu(self, name, menu): 169 def __populateMenu(self, name, menu):
172 """ 170 """
173 Private slot to populate the tools menu with our entries. 171 Private slot to populate the tools menu with our entries.
174 172
175 @param name name of the menu 173 @param name name of the menu
176 @type str 174 @type str
177 @param menu reference to the menu to be populated 175 @param menu reference to the menu to be populated
178 @type QMenu 176 @type QMenu
179 """ 177 """
180 if name not in ["Tools", "PluginTools"]: 178 if name not in ["Tools", "PluginTools"]:
181 return 179 return
182 180
183 editor = ericApp().getObject("ViewManager").activeWindow() 181 editor = ericApp().getObject("ViewManager").activeWindow()
184 182
185 if name == "Tools": 183 if name == "Tools":
186 if not menu.isEmpty(): 184 if not menu.isEmpty():
187 menu.addSeparator() 185 menu.addSeparator()
188 act = menu.addMenu(self.__menu) 186 act = menu.addMenu(self.__menu)
189 act.setEnabled(editor is not None and editor.hasSelectedText()) 187 act.setEnabled(editor is not None and editor.hasSelectedText())
190 elif name == "PluginTools" and self.__mainActions: 188 elif name == "PluginTools" and self.__mainActions:
191 self.__menu.setEnabled(editor is not None and 189 self.__menu.setEnabled(editor is not None and editor.hasSelectedText())
192 editor.hasSelectedText()) 190
193
194 def __editorOpened(self, editor): 191 def __editorOpened(self, editor):
195 """ 192 """
196 Private slot called, when a new editor was opened. 193 Private slot called, when a new editor was opened.
197 194
198 @param editor reference to the new editor 195 @param editor reference to the new editor
199 @type Editor 196 @type Editor
200 """ 197 """
201 menu = editor.getMenu("Tools") 198 menu = editor.getMenu("Tools")
202 if menu is not None: 199 if menu is not None:
205 act = menu.addSeparator() 202 act = menu.addSeparator()
206 self.__editors[editor].append(act) 203 self.__editors[editor].append(act)
207 act = menu.addMenu(self.__menu) 204 act = menu.addMenu(self.__menu)
208 self.__editors[editor].append(act) 205 self.__editors[editor].append(act)
209 editor.showMenu.connect(self.__editorShowMenu) 206 editor.showMenu.connect(self.__editorShowMenu)
210 207
211 def __editorClosed(self, editor): 208 def __editorClosed(self, editor):
212 """ 209 """
213 Private slot called, when an editor was closed. 210 Private slot called, when an editor was closed.
214 211
215 @param editor reference to the editor 212 @param editor reference to the editor
216 @type Editor 213 @type Editor
217 """ 214 """
218 with contextlib.suppress(KeyError): 215 with contextlib.suppress(KeyError):
219 del self.__editors[editor] 216 del self.__editors[editor]
220 217
221 def __editorShowMenu(self, menuName, menu, editor): 218 def __editorShowMenu(self, menuName, menu, editor):
222 """ 219 """
223 Private slot called, when the the editor context menu or a submenu is 220 Private slot called, when the the editor context menu or a submenu is
224 about to be shown. 221 about to be shown.
225 222
226 @param menuName name of the menu to be shown 223 @param menuName name of the menu to be shown
227 @type str 224 @type str
228 @param menu reference to the menu 225 @param menu reference to the menu
229 @type QMenu 226 @type QMenu
230 @param editor reference to the editor 227 @param editor reference to the editor
237 if not menu.isEmpty(): 234 if not menu.isEmpty():
238 act = menu.addSeparator() 235 act = menu.addSeparator()
239 self.__editors[editor].append(act) 236 self.__editors[editor].append(act)
240 act = menu.addMenu(self.__menu) 237 act = menu.addMenu(self.__menu)
241 self.__editors[editor].append(act) 238 self.__editors[editor].append(act)
242 239
243 self.__menu.setEnabled(editor.hasSelectedText()) 240 self.__menu.setEnabled(editor.hasSelectedText())
244 241
245 def __applyChange(self, newText, editor): 242 def __applyChange(self, newText, editor):
246 """ 243 """
247 Private method to change the selected text. 244 Private method to change the selected text.
248 245
249 @param newText new (converted) text 246 @param newText new (converted) text
250 @type str 247 @type str
251 @param editor reference to the editor to apply the text 248 @param editor reference to the editor to apply the text
252 change to 249 change to
253 @type Editor 250 @type Editor
254 """ 251 """
255 editor.beginUndoAction() 252 editor.beginUndoAction()
256 editor.replaceSelectedText(newText) 253 editor.replaceSelectedText(newText)
257 editor.endUndoAction() 254 editor.endUndoAction()
258 255
259 def __splitCamelCase(self): 256 def __splitCamelCase(self):
260 """ 257 """
261 Private slot to split the selected camel case text. 258 Private slot to split the selected camel case text.
262 """ 259 """
263 editor = ericApp().getObject("ViewManager").activeWindow() 260 editor = ericApp().getObject("ViewManager").activeWindow()
264 if editor is None: 261 if editor is None:
265 return 262 return
266 263
267 text = editor.selectedText() 264 text = editor.selectedText()
268 if text: 265 if text:
269 newText = re.sub(r"([A-Z])", r" \1", text).lstrip(" ") 266 newText = re.sub(r"([A-Z])", r" \1", text).lstrip(" ")
270 if newText != text: 267 if newText != text:
271 self.__applyChange(newText, editor) 268 self.__applyChange(newText, editor)
272 269
273 def __mergeCamelCase(self, uppercaseFirst=False): 270 def __mergeCamelCase(self, uppercaseFirst=False):
274 """ 271 """
275 Private slot to merge the selected text to camel case. 272 Private slot to merge the selected text to camel case.
276 273
277 @param uppercaseFirst flag indicating to upper case the 274 @param uppercaseFirst flag indicating to upper case the
278 first character 275 first character
279 @type bool 276 @type bool
280 """ 277 """
281 editor = ericApp().getObject("ViewManager").activeWindow() 278 editor = ericApp().getObject("ViewManager").activeWindow()
282 if editor is None: 279 if editor is None:
283 return 280 return
284 281
285 text = editor.selectedText() 282 text = editor.selectedText()
286 if text: 283 if text:
287 newText = "".join(w[0].upper() + w[1:] for w in text.split()) 284 newText = "".join(w[0].upper() + w[1:] for w in text.split())
288 if not uppercaseFirst: 285 if not uppercaseFirst:
289 newText = newText[0].lower() + newText[1:] 286 newText = newText[0].lower() + newText[1:]
290 if newText != text: 287 if newText != text:
291 self.__applyChange(newText, editor) 288 self.__applyChange(newText, editor)
292 289
293 def __mergeCamelCaseUppercaseFirst(self): 290 def __mergeCamelCaseUppercaseFirst(self):
294 """ 291 """
295 Private slot to merge the selected text to camel case upper casing 292 Private slot to merge the selected text to camel case upper casing
296 the first character. 293 the first character.
297 """ 294 """
298 self.__mergeCamelCase(True) 295 self.__mergeCamelCase(True)
299 296
300 def __splitSnakeCase(self): 297 def __splitSnakeCase(self):
301 """ 298 """
302 Private slot to split the selected snake case text. 299 Private slot to split the selected snake case text.
303 """ 300 """
304 editor = ericApp().getObject("ViewManager").activeWindow() 301 editor = ericApp().getObject("ViewManager").activeWindow()
305 if editor is None: 302 if editor is None:
306 return 303 return
307 304
308 text = editor.selectedText() 305 text = editor.selectedText()
309 if text: 306 if text:
310 newText = text.replace("_", " ").lstrip(" ") 307 newText = text.replace("_", " ").lstrip(" ")
311 if newText != text: 308 if newText != text:
312 self.__applyChange(newText, editor) 309 self.__applyChange(newText, editor)
313 310
314 def __mergeSnakeCase(self): 311 def __mergeSnakeCase(self):
315 """ 312 """
316 Private slot to merge the selected text to snake case. 313 Private slot to merge the selected text to snake case.
317 """ 314 """
318 editor = ericApp().getObject("ViewManager").activeWindow() 315 editor = ericApp().getObject("ViewManager").activeWindow()
319 if editor is None: 316 if editor is None:
320 return 317 return
321 318
322 text = editor.selectedText() 319 text = editor.selectedText()
323 if text: 320 if text:
324 newText = "_".join(w.lower() for w in text.split()) 321 newText = "_".join(w.lower() for w in text.split())
325 if newText != text: 322 if newText != text:
326 self.__applyChange(newText, editor) 323 self.__applyChange(newText, editor)
327 324
328 def __camelCaseToSnakeCase(self): 325 def __camelCaseToSnakeCase(self):
329 """ 326 """
330 Private slot to convert camel case text to underscore separated text. 327 Private slot to convert camel case text to underscore separated text.
331 """ 328 """
332 editor = ericApp().getObject("ViewManager").activeWindow() 329 editor = ericApp().getObject("ViewManager").activeWindow()
333 if editor is None: 330 if editor is None:
334 return 331 return
335 332
336 text = editor.selectedText() 333 text = editor.selectedText()
337 if text: 334 if text:
338 newText = re.sub(r"([A-Z])", r"_\1", text).lower().lstrip("_") 335 newText = re.sub(r"([A-Z])", r"_\1", text).lower().lstrip("_")
339 if text.startswith("__"): 336 if text.startswith("__"):
340 newText = "__" + newText 337 newText = "__" + newText
341 elif text.startswith("_"): 338 elif text.startswith("_"):
342 newText = "_" + newText 339 newText = "_" + newText
343 if newText != text: 340 if newText != text:
344 self.__applyChange(newText, editor) 341 self.__applyChange(newText, editor)
345 342
346 def __snakeCaseToCamelCase(self, uppercaseFirst=False): 343 def __snakeCaseToCamelCase(self, uppercaseFirst=False):
347 """ 344 """
348 Private slot to convert underscore separated text to camel case. 345 Private slot to convert underscore separated text to camel case.
349 346
350 @param uppercaseFirst flag indicating to upper case the 347 @param uppercaseFirst flag indicating to upper case the
351 first character 348 first character
352 @type bool 349 @type bool
353 """ 350 """
354 editor = ericApp().getObject("ViewManager").activeWindow() 351 editor = ericApp().getObject("ViewManager").activeWindow()
355 if editor is None: 352 if editor is None:
356 return 353 return
357 354
358 text = editor.selectedText() 355 text = editor.selectedText()
359 if text: 356 if text:
360 newText = "".join(s.capitalize() for s in text.split("_")) 357 newText = "".join(s.capitalize() for s in text.split("_"))
361 if not uppercaseFirst: 358 if not uppercaseFirst:
362 newText = newText[0].lower() + newText[1:] 359 newText = newText[0].lower() + newText[1:]
364 newText = "__" + newText 361 newText = "__" + newText
365 elif text.startswith("_"): 362 elif text.startswith("_"):
366 newText = "_" + newText 363 newText = "_" + newText
367 if newText != text: 364 if newText != text:
368 self.__applyChange(newText, editor) 365 self.__applyChange(newText, editor)
369 366
370 def __snakeCaseToCamelCaseUppercaseFirst(self): 367 def __snakeCaseToCamelCaseUppercaseFirst(self):
371 """ 368 """
372 Private slot to convert underscore separated text to camel case 369 Private slot to convert underscore separated text to camel case
373 upper casing the first character. 370 upper casing the first character.
374 """ 371 """
375 self.__snakeCaseToCamelCase(True) 372 self.__snakeCaseToCamelCase(True)
376 373
374
377 # 375 #
378 # eflag: noqa = M801 376 # eflag: noqa = M801

eric ide

mercurial