src/eric7/Templates/TemplateViewer.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
11 import os 11 import os
12 import pathlib 12 import pathlib
13 import re 13 import re
14 14
15 from PyQt6.QtCore import QFile, QIODevice, Qt, QCoreApplication 15 from PyQt6.QtCore import QFile, QIODevice, Qt, QCoreApplication
16 from PyQt6.QtWidgets import ( 16 from PyQt6.QtWidgets import QTreeWidget, QDialog, QApplication, QMenu, QTreeWidgetItem
17 QTreeWidget, QDialog, QApplication, QMenu, QTreeWidgetItem
18 )
19 17
20 from EricWidgets.EricApplication import ericApp 18 from EricWidgets.EricApplication import ericApp
21 from EricWidgets import EricMessageBox, EricFileDialog 19 from EricWidgets import EricMessageBox, EricFileDialog
22 20
23 import Preferences 21 import Preferences
30 28
31 class TemplateGroup(QTreeWidgetItem): 29 class TemplateGroup(QTreeWidgetItem):
32 """ 30 """
33 Class implementing a template group. 31 Class implementing a template group.
34 """ 32 """
33
35 def __init__(self, parent, name, language="All"): 34 def __init__(self, parent, name, language="All"):
36 """ 35 """
37 Constructor 36 Constructor
38 37
39 @param parent parent widget of the template group (QWidget) 38 @param parent parent widget of the template group (QWidget)
40 @param name name of the group (string) 39 @param name name of the group (string)
41 @param language programming language for the group (string) 40 @param language programming language for the group (string)
42 """ 41 """
43 self.name = name 42 self.name = name
44 self.language = language 43 self.language = language
45 self.entries = {} 44 self.entries = {}
46 45
47 super().__init__(parent, [name]) 46 super().__init__(parent, [name])
48 47
49 if Preferences.getTemplates("ShowTooltip"): 48 if Preferences.getTemplates("ShowTooltip"):
50 self.setToolTip(0, language) 49 self.setToolTip(0, language)
51 50
52 def setName(self, name): 51 def setName(self, name):
53 """ 52 """
54 Public method to update the name of the group. 53 Public method to update the name of the group.
55 54
56 @param name name of the group (string) 55 @param name name of the group (string)
57 """ 56 """
58 self.name = name 57 self.name = name
59 self.setText(0, name) 58 self.setText(0, name)
60 59
61 def getName(self): 60 def getName(self):
62 """ 61 """
63 Public method to get the name of the group. 62 Public method to get the name of the group.
64 63
65 @return name of the group (string) 64 @return name of the group (string)
66 """ 65 """
67 return self.name 66 return self.name
68 67
69 def setLanguage(self, language): 68 def setLanguage(self, language):
70 """ 69 """
71 Public method to update the name of the group. 70 Public method to update the name of the group.
72 71
73 @param language programming language for the group (string) 72 @param language programming language for the group (string)
74 """ 73 """
75 self.language = language 74 self.language = language
76 if Preferences.getTemplates("ShowTooltip"): 75 if Preferences.getTemplates("ShowTooltip"):
77 self.setToolTip(0, language) 76 self.setToolTip(0, language)
78 77
79 def getLanguage(self): 78 def getLanguage(self):
80 """ 79 """
81 Public method to get the name of the group. 80 Public method to get the name of the group.
82 81
83 @return language of the group (string) 82 @return language of the group (string)
84 """ 83 """
85 return self.language 84 return self.language
86 85
87 def addEntry(self, name, description, template, quiet=False): 86 def addEntry(self, name, description, template, quiet=False):
88 """ 87 """
89 Public method to add a template entry to this group. 88 Public method to add a template entry to this group.
90 89
91 @param name name of the entry (string) 90 @param name name of the entry (string)
92 @param description description of the entry to add (string) 91 @param description description of the entry to add (string)
93 @param template template text of the entry (string) 92 @param template template text of the entry (string)
94 @param quiet flag indicating quiet operation (boolean) 93 @param quiet flag indicating quiet operation (boolean)
95 """ 94 """
96 if name in self.entries: 95 if name in self.entries:
97 if not quiet: 96 if not quiet:
98 EricMessageBox.critical( 97 EricMessageBox.critical(
99 None, 98 None,
100 QCoreApplication.translate("TemplateGroup", 99 QCoreApplication.translate("TemplateGroup", "Add Template"),
101 "Add Template"),
102 QCoreApplication.translate( 100 QCoreApplication.translate(
103 "TemplateGroup", 101 "TemplateGroup",
104 """<p>The group <b>{0}</b> already contains a""" 102 """<p>The group <b>{0}</b> already contains a"""
105 """ template named <b>{1}</b>.</p>""") 103 """ template named <b>{1}</b>.</p>""",
106 .format(self.name, name)) 104 ).format(self.name, name),
105 )
107 return 106 return
108 107
109 self.entries[name] = TemplateEntry(self, name, description, template) 108 self.entries[name] = TemplateEntry(self, name, description, template)
110 109
111 if ( 110 if Preferences.getTemplates("AutoOpenGroups") and not self.isExpanded():
112 Preferences.getTemplates("AutoOpenGroups") and
113 not self.isExpanded()
114 ):
115 self.setExpanded(True) 111 self.setExpanded(True)
116 112
117 def removeEntry(self, name): 113 def removeEntry(self, name):
118 """ 114 """
119 Public method to remove a template entry from this group. 115 Public method to remove a template entry from this group.
120 116
121 @param name name of the entry to be removed (string) 117 @param name name of the entry to be removed (string)
122 """ 118 """
123 if name in self.entries: 119 if name in self.entries:
124 index = self.indexOfChild(self.entries[name]) 120 index = self.indexOfChild(self.entries[name])
125 self.takeChild(index) 121 self.takeChild(index)
126 del self.entries[name] 122 del self.entries[name]
127 123
128 if ( 124 if (
129 len(self.entries) == 0 and 125 len(self.entries) == 0
130 Preferences.getTemplates("AutoOpenGroups") and 126 and Preferences.getTemplates("AutoOpenGroups")
131 self.isExpanded() 127 and self.isExpanded()
132 ): 128 ):
133 self.setExpanded(False) 129 self.setExpanded(False)
134 130
135 def removeAllEntries(self): 131 def removeAllEntries(self):
136 """ 132 """
137 Public method to remove all template entries of this group. 133 Public method to remove all template entries of this group.
138 """ 134 """
139 for name in list(self.entries.keys())[:]: 135 for name in list(self.entries.keys())[:]:
140 self.removeEntry(name) 136 self.removeEntry(name)
141 137
142 def hasEntry(self, name): 138 def hasEntry(self, name):
143 """ 139 """
144 Public method to check, if the group has an entry with the given name. 140 Public method to check, if the group has an entry with the given name.
145 141
146 @param name name of the entry to check for (string) 142 @param name name of the entry to check for (string)
147 @return flag indicating existence (boolean) 143 @return flag indicating existence (boolean)
148 """ 144 """
149 return name in self.entries 145 return name in self.entries
150 146
151 def getEntry(self, name): 147 def getEntry(self, name):
152 """ 148 """
153 Public method to get an entry. 149 Public method to get an entry.
154 150
155 @param name name of the entry to retrieve (string) 151 @param name name of the entry to retrieve (string)
156 @return reference to the entry (TemplateEntry) 152 @return reference to the entry (TemplateEntry)
157 """ 153 """
158 try: 154 try:
159 return self.entries[name] 155 return self.entries[name]
162 158
163 def getEntryNames(self, beginning): 159 def getEntryNames(self, beginning):
164 """ 160 """
165 Public method to get the names of all entries, who's name starts with 161 Public method to get the names of all entries, who's name starts with
166 the given string. 162 the given string.
167 163
168 @param beginning string denoting the beginning of the template name 164 @param beginning string denoting the beginning of the template name
169 (string) 165 (string)
170 @return list of entry names found (list of strings) 166 @return list of entry names found (list of strings)
171 """ 167 """
172 names = [] 168 names = []
173 for name in self.entries: 169 for name in self.entries:
174 if name.startswith(beginning): 170 if name.startswith(beginning):
175 names.append(name) 171 names.append(name)
176 172
177 return names 173 return names
178 174
179 def getAllEntries(self): 175 def getAllEntries(self):
180 """ 176 """
181 Public method to retrieve all entries. 177 Public method to retrieve all entries.
182 178
183 @return list of all entries (list of TemplateEntry) 179 @return list of all entries (list of TemplateEntry)
184 """ 180 """
185 return list(self.entries.values()) 181 return list(self.entries.values())
186 182
187 183
188 class TemplateEntry(QTreeWidgetItem): 184 class TemplateEntry(QTreeWidgetItem):
189 """ 185 """
190 Class immplementing a template entry. 186 Class immplementing a template entry.
191 """ 187 """
188
192 def __init__(self, parent, name, description, templateText): 189 def __init__(self, parent, name, description, templateText):
193 """ 190 """
194 Constructor 191 Constructor
195 192
196 @param parent parent widget of the template entry (QWidget) 193 @param parent parent widget of the template entry (QWidget)
197 @param name name of the entry (string) 194 @param name name of the entry (string)
198 @param description descriptive text for the template (string) 195 @param description descriptive text for the template (string)
199 @param templateText text of the template entry (string) 196 @param templateText text of the template entry (string)
200 """ 197 """
201 self.name = name 198 self.name = name
202 self.description = description 199 self.description = description
203 self.template = templateText 200 self.template = templateText
204 self.__extractVariables() 201 self.__extractVariables()
205 202
206 super().__init__(parent, [self.__displayText()]) 203 super().__init__(parent, [self.__displayText()])
207 if Preferences.getTemplates("ShowTooltip"): 204 if Preferences.getTemplates("ShowTooltip"):
208 self.setToolTip(0, self.template) 205 self.setToolTip(0, self.template)
209 206
210 def __displayText(self): 207 def __displayText(self):
211 """ 208 """
212 Private method to generate the display text. 209 Private method to generate the display text.
213 210
214 @return display text (string) 211 @return display text (string)
215 """ 212 """
216 txt = ( 213 txt = (
217 "{0} - {1}".format(self.name, self.description) 214 "{0} - {1}".format(self.name, self.description)
218 if self.description else 215 if self.description
219 self.name 216 else self.name
220 ) 217 )
221 return txt 218 return txt
222 219
223 def setName(self, name): 220 def setName(self, name):
224 """ 221 """
225 Public method to update the name of the entry. 222 Public method to update the name of the entry.
226 223
227 @param name name of the entry (string) 224 @param name name of the entry (string)
228 """ 225 """
229 self.name = name 226 self.name = name
230 self.setText(0, self.__displayText()) 227 self.setText(0, self.__displayText())
231 228
232 def getName(self): 229 def getName(self):
233 """ 230 """
234 Public method to get the name of the entry. 231 Public method to get the name of the entry.
235 232
236 @return name of the entry (string) 233 @return name of the entry (string)
237 """ 234 """
238 return self.name 235 return self.name
239 236
240 def setDescription(self, description): 237 def setDescription(self, description):
241 """ 238 """
242 Public method to update the description of the entry. 239 Public method to update the description of the entry.
243 240
244 @param description description of the entry (string) 241 @param description description of the entry (string)
245 """ 242 """
246 self.description = description 243 self.description = description
247 self.setText(0, self.__displayText()) 244 self.setText(0, self.__displayText())
248 245
249 def getDescription(self): 246 def getDescription(self):
250 """ 247 """
251 Public method to get the description of the entry. 248 Public method to get the description of the entry.
252 249
253 @return description of the entry (string) 250 @return description of the entry (string)
254 """ 251 """
255 return self.description 252 return self.description
256 253
257 def getGroupName(self): 254 def getGroupName(self):
258 """ 255 """
259 Public method to get the name of the group this entry belongs to. 256 Public method to get the name of the group this entry belongs to.
260 257
261 @return name of the group containing this entry (string) 258 @return name of the group containing this entry (string)
262 """ 259 """
263 return self.parent().getName() 260 return self.parent().getName()
264 261
265 def setTemplateText(self, templateText): 262 def setTemplateText(self, templateText):
266 """ 263 """
267 Public method to update the template text. 264 Public method to update the template text.
268 265
269 @param templateText text of the template entry (string) 266 @param templateText text of the template entry (string)
270 """ 267 """
271 self.template = templateText 268 self.template = templateText
272 self.__extractVariables() 269 self.__extractVariables()
273 if Preferences.getTemplates("ShowTooltip"): 270 if Preferences.getTemplates("ShowTooltip"):
274 self.setToolTip(0, self.template) 271 self.setToolTip(0, self.template)
275 272
276 def getTemplateText(self): 273 def getTemplateText(self):
277 """ 274 """
278 Public method to get the template text. 275 Public method to get the template text.
279 276
280 @return the template text (string) 277 @return the template text (string)
281 """ 278 """
282 return self.template 279 return self.template
283 280
284 def getExpandedText(self, varDict, indent): 281 def getExpandedText(self, varDict, indent):
285 """ 282 """
286 Public method to get the template text with all variables expanded. 283 Public method to get the template text with all variables expanded.
287 284
288 @param varDict dictionary containing the texts of each variable 285 @param varDict dictionary containing the texts of each variable
289 with the variable name as key. 286 with the variable name as key.
290 @param indent indentation of the line receiving he expanded 287 @param indent indentation of the line receiving he expanded
291 template text (string) 288 template text (string)
292 @return a tuple of the expanded template text (string), the 289 @return a tuple of the expanded template text (string), the
294 """ 291 """
295 txt = self.template 292 txt = self.template
296 for var, val in list(varDict.items()): 293 for var, val in list(varDict.items()):
297 txt = ( 294 txt = (
298 self.__expandFormattedVariable(var, val, txt) 295 self.__expandFormattedVariable(var, val, txt)
299 if var in self.formatedVariables else 296 if var in self.formatedVariables
300 txt.replace(var, val) 297 else txt.replace(var, val)
301 ) 298 )
302 sepchar = Preferences.getTemplates("SeparatorChar") 299 sepchar = Preferences.getTemplates("SeparatorChar")
303 txt = txt.replace("{0}{1}".format(sepchar, sepchar), sepchar) 300 txt = txt.replace("{0}{1}".format(sepchar, sepchar), sepchar)
304 prefix = "{0}{1}".format(os.linesep, indent) 301 prefix = "{0}{1}".format(os.linesep, indent)
305 trailingEol = txt.endswith(os.linesep) 302 trailingEol = txt.endswith(os.linesep)
314 return txt, lineCount, lineLen 311 return txt, lineCount, lineLen
315 312
316 def __expandFormattedVariable(self, var, val, txt): 313 def __expandFormattedVariable(self, var, val, txt):
317 """ 314 """
318 Private method to expand a template variable with special formatting. 315 Private method to expand a template variable with special formatting.
319 316
320 @param var template variable name (string) 317 @param var template variable name (string)
321 @param val value of the template variable (string) 318 @param val value of the template variable (string)
322 @param txt template text (string) 319 @param txt template text (string)
323 @return expanded and formatted variable (string) 320 @return expanded and formatted variable (string)
324 """ 321 """
325 t = "" 322 t = ""
326 for line in txt.splitlines(): 323 for line in txt.splitlines():
327 ind = line.find(var) 324 ind = line.find(var)
328 if ind >= 0: 325 if ind >= 0:
329 variableFormat = var[1:-1].split(':', 1)[1] 326 variableFormat = var[1:-1].split(":", 1)[1]
330 if variableFormat == 'rl': 327 if variableFormat == "rl":
331 prefix = line[:ind] 328 prefix = line[:ind]
332 postfix = line[ind + len(var):] 329 postfix = line[ind + len(var) :]
333 for v in val.splitlines(): 330 for v in val.splitlines():
334 t = "{0}{1}{2}{3}{4}".format( 331 t = "{0}{1}{2}{3}{4}".format(t, os.linesep, prefix, v, postfix)
335 t, os.linesep, prefix, v, postfix) 332 elif variableFormat == "ml":
336 elif variableFormat == 'ml':
337 indent = line.replace(line.lstrip(), "") 333 indent = line.replace(line.lstrip(), "")
338 prefix = line[:ind] 334 prefix = line[:ind]
339 postfix = line[ind + len(var):] 335 postfix = line[ind + len(var) :]
340 for count, v in enumerate(val.splitlines()): 336 for count, v in enumerate(val.splitlines()):
341 t = ( 337 t = (
342 "{0}{1}{2}{3}".format(t, os.linesep, indent, v) 338 "{0}{1}{2}{3}".format(t, os.linesep, indent, v)
343 if count else 339 if count
344 "{0}{1}{2}{3}".format(t, os.linesep, prefix, v) 340 else "{0}{1}{2}{3}".format(t, os.linesep, prefix, v)
345 ) 341 )
346 t = "{0}{1}".format(t, postfix) 342 t = "{0}{1}".format(t, postfix)
347 else: 343 else:
348 t = "{0}{1}{2}".format(t, os.linesep, line) 344 t = "{0}{1}{2}".format(t, os.linesep, line)
349 else: 345 else:
351 return "".join(t.splitlines(1)[1:]) 347 return "".join(t.splitlines(1)[1:])
352 348
353 def getVariables(self): 349 def getVariables(self):
354 """ 350 """
355 Public method to get the list of variables. 351 Public method to get the list of variables.
356 352
357 @return list of variables (list of strings) 353 @return list of variables (list of strings)
358 """ 354 """
359 return self.variables 355 return self.variables
360 356
361 def __extractVariables(self): 357 def __extractVariables(self):
362 """ 358 """
363 Private method to retrieve the list of variables. 359 Private method to retrieve the list of variables.
364 """ 360 """
365 sepchar = Preferences.getTemplates("SeparatorChar") 361 sepchar = Preferences.getTemplates("SeparatorChar")
366 variablesPattern = re.compile( 362 variablesPattern = re.compile(
367 r"""\{0}[a-zA-Z][a-zA-Z0-9_]*(?::(?:ml|rl))?\{1}""".format( 363 r"""\{0}[a-zA-Z][a-zA-Z0-9_]*(?::(?:ml|rl))?\{1}""".format(sepchar, sepchar)
368 sepchar, sepchar)
369 ) 364 )
370 variables = variablesPattern.findall(self.template) 365 variables = variablesPattern.findall(self.template)
371 self.variables = [] 366 self.variables = []
372 self.formatedVariables = [] 367 self.formatedVariables = []
373 for var in variables: 368 for var in variables:
374 if var not in self.variables: 369 if var not in self.variables:
375 self.variables.append(var) 370 self.variables.append(var)
376 if var.find(':') >= 0 and var not in self.formatedVariables: 371 if var.find(":") >= 0 and var not in self.formatedVariables:
377 self.formatedVariables.append(var) 372 self.formatedVariables.append(var)
378 373
379 374
380 class TemplateViewer(QTreeWidget): 375 class TemplateViewer(QTreeWidget):
381 """ 376 """
382 Class implementing the template viewer. 377 Class implementing the template viewer.
383 """ 378 """
379
384 def __init__(self, parent, viewmanager): 380 def __init__(self, parent, viewmanager):
385 """ 381 """
386 Constructor 382 Constructor
387 383
388 @param parent the parent (QWidget) 384 @param parent the parent (QWidget)
389 @param viewmanager reference to the viewmanager object 385 @param viewmanager reference to the viewmanager object
390 """ 386 """
391 super().__init__(parent) 387 super().__init__(parent)
392 388
393 self.viewmanager = viewmanager 389 self.viewmanager = viewmanager
394 self.groups = {} 390 self.groups = {}
395 391
396 self.setHeaderLabels(["Template"]) 392 self.setHeaderLabels(["Template"])
397 self.header().hide() 393 self.header().hide()
398 self.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder) 394 self.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
399 self.setRootIsDecorated(True) 395 self.setRootIsDecorated(True)
400 self.setAlternatingRowColors(True) 396 self.setAlternatingRowColors(True)
401 397
402 self.__menu = QMenu(self) 398 self.__menu = QMenu(self)
403 self.applyAct = self.__menu.addAction( 399 self.applyAct = self.__menu.addAction(
404 self.tr("Apply"), self.__templateItemActivated) 400 self.tr("Apply"), self.__templateItemActivated
401 )
405 self.__menu.addSeparator() 402 self.__menu.addSeparator()
406 self.__menu.addAction(self.tr("Add entry..."), self.__addEntry) 403 self.__menu.addAction(self.tr("Add entry..."), self.__addEntry)
407 self.__menu.addAction(self.tr("Add group..."), self.__addGroup) 404 self.__menu.addAction(self.tr("Add group..."), self.__addGroup)
408 self.__menu.addAction(self.tr("Edit..."), self.__edit) 405 self.__menu.addAction(self.tr("Edit..."), self.__edit)
409 self.__menu.addAction(self.tr("Remove"), self.__remove) 406 self.__menu.addAction(self.tr("Remove"), self.__remove)
411 self.saveAct = self.__menu.addAction(self.tr("Save"), self.save) 408 self.saveAct = self.__menu.addAction(self.tr("Save"), self.save)
412 self.__menu.addAction(self.tr("Import..."), self.__import) 409 self.__menu.addAction(self.tr("Import..."), self.__import)
413 self.__menu.addAction(self.tr("Export..."), self.__export) 410 self.__menu.addAction(self.tr("Export..."), self.__export)
414 self.__menu.addAction(self.tr("Reload"), self.__reload) 411 self.__menu.addAction(self.tr("Reload"), self.__reload)
415 self.__menu.addSeparator() 412 self.__menu.addSeparator()
416 self.__menu.addAction( 413 self.__menu.addAction(self.tr("Help about Templates..."), self.__showHelp)
417 self.tr("Help about Templates..."), self.__showHelp)
418 self.__menu.addSeparator() 414 self.__menu.addSeparator()
419 self.__menu.addAction(self.tr("Configure..."), self.__configure) 415 self.__menu.addAction(self.tr("Configure..."), self.__configure)
420 416
421 self.__backMenu = QMenu(self) 417 self.__backMenu = QMenu(self)
422 self.__backMenu.addAction(self.tr("Add group..."), self.__addGroup) 418 self.__backMenu.addAction(self.tr("Add group..."), self.__addGroup)
423 self.__backMenu.addSeparator() 419 self.__backMenu.addSeparator()
424 self.bmSaveAct = self.__backMenu.addAction(self.tr("Save"), self.save) 420 self.bmSaveAct = self.__backMenu.addAction(self.tr("Save"), self.save)
425 self.__backMenu.addAction(self.tr("Import..."), self.__import) 421 self.__backMenu.addAction(self.tr("Import..."), self.__import)
426 self.bmExportAct = self.__backMenu.addAction( 422 self.bmExportAct = self.__backMenu.addAction(
427 self.tr("Export..."), self.__export) 423 self.tr("Export..."), self.__export
424 )
428 self.__backMenu.addAction(self.tr("Reload"), self.__reload) 425 self.__backMenu.addAction(self.tr("Reload"), self.__reload)
429 self.__backMenu.addSeparator() 426 self.__backMenu.addSeparator()
430 self.__backMenu.addAction( 427 self.__backMenu.addAction(self.tr("Help about Templates..."), self.__showHelp)
431 self.tr("Help about Templates..."), self.__showHelp)
432 self.__backMenu.addSeparator() 428 self.__backMenu.addSeparator()
433 self.__backMenu.addAction( 429 self.__backMenu.addAction(self.tr("Configure..."), self.__configure)
434 self.tr("Configure..."), self.__configure) 430
435
436 self.__activating = False 431 self.__activating = False
437 self.__dirty = False 432 self.__dirty = False
438 433
439 self.__templatesFile = TemplatesFile(self) 434 self.__templatesFile = TemplatesFile(self)
440 435
441 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) 436 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
442 self.customContextMenuRequested.connect(self.__showContextMenu) 437 self.customContextMenuRequested.connect(self.__showContextMenu)
443 self.itemActivated.connect(self.__templateItemActivated) 438 self.itemActivated.connect(self.__templateItemActivated)
444 439
445 self.setWindowIcon(UI.PixmapCache.getIcon("eric")) 440 self.setWindowIcon(UI.PixmapCache.getIcon("eric"))
446 441
447 def __resort(self): 442 def __resort(self):
448 """ 443 """
449 Private method to resort the tree. 444 Private method to resort the tree.
450 """ 445 """
451 self.sortItems(self.sortColumn(), self.header().sortIndicatorOrder()) 446 self.sortItems(self.sortColumn(), self.header().sortIndicatorOrder())
452 447
453 def __templateItemActivated(self, itm=None, col=0): 448 def __templateItemActivated(self, itm=None, col=0):
454 """ 449 """
455 Private slot to handle the activation of an item. 450 Private slot to handle the activation of an item.
456 451
457 @param itm reference to the activated item (QTreeWidgetItem) 452 @param itm reference to the activated item (QTreeWidgetItem)
458 @param col column the item was activated in (integer) 453 @param col column the item was activated in (integer)
459 """ 454 """
460 if not self.__activating: 455 if not self.__activating:
461 self.__activating = True 456 self.__activating = True
462 itm = self.currentItem() 457 itm = self.currentItem()
463 if isinstance(itm, TemplateEntry): 458 if isinstance(itm, TemplateEntry):
464 self.applyTemplate(itm) 459 self.applyTemplate(itm)
465 self.__activating = False 460 self.__activating = False
466 461
467 def __showContextMenu(self, coord): 462 def __showContextMenu(self, coord):
468 """ 463 """
469 Private slot to show the context menu of the list. 464 Private slot to show the context menu of the list.
470 465
471 @param coord the position of the mouse pointer (QPoint) 466 @param coord the position of the mouse pointer (QPoint)
472 """ 467 """
473 itm = self.itemAt(coord) 468 itm = self.itemAt(coord)
474 coord = self.mapToGlobal(coord) 469 coord = self.mapToGlobal(coord)
475 if itm is None: 470 if itm is None:
476 self.bmSaveAct.setEnabled(self.__dirty) 471 self.bmSaveAct.setEnabled(self.__dirty)
477 self.bmExportAct.setEnabled(self.topLevelItemCount() != 0) 472 self.bmExportAct.setEnabled(self.topLevelItemCount() != 0)
478 self.__backMenu.popup(coord) 473 self.__backMenu.popup(coord)
479 else: 474 else:
480 self.applyAct.setEnabled( 475 self.applyAct.setEnabled(
481 self.viewmanager.activeWindow() is not None and 476 self.viewmanager.activeWindow() is not None
482 isinstance(itm, TemplateEntry)) 477 and isinstance(itm, TemplateEntry)
478 )
483 self.saveAct.setEnabled(self.__dirty) 479 self.saveAct.setEnabled(self.__dirty)
484 self.__menu.popup(coord) 480 self.__menu.popup(coord)
485 481
486 def __addEntry(self): 482 def __addEntry(self):
487 """ 483 """
488 Private slot to handle the Add Entry context menu action. 484 Private slot to handle the Add Entry context menu action.
489 """ 485 """
490 itm = self.currentItem() 486 itm = self.currentItem()
491 groupName = ( 487 groupName = (
492 itm.getName() 488 itm.getName() if isinstance(itm, TemplateGroup) else itm.getGroupName()
493 if isinstance(itm, TemplateGroup) else
494 itm.getGroupName()
495 ) 489 )
496 490
497 from .TemplatePropertiesDialog import TemplatePropertiesDialog 491 from .TemplatePropertiesDialog import TemplatePropertiesDialog
492
498 dlg = TemplatePropertiesDialog(self) 493 dlg = TemplatePropertiesDialog(self)
499 dlg.setSelectedGroup(groupName) 494 dlg.setSelectedGroup(groupName)
500 if dlg.exec() == QDialog.DialogCode.Accepted: 495 if dlg.exec() == QDialog.DialogCode.Accepted:
501 name, description, groupName, template = dlg.getData() 496 name, description, groupName, template = dlg.getData()
502 self.addEntry(groupName, name, description, template) 497 self.addEntry(groupName, name, description, template)
503 self.__dirty = True 498 self.__dirty = True
504 499
505 def __addGroup(self): 500 def __addGroup(self):
506 """ 501 """
507 Private slot to handle the Add Group context menu action. 502 Private slot to handle the Add Group context menu action.
508 """ 503 """
509 from .TemplatePropertiesDialog import TemplatePropertiesDialog 504 from .TemplatePropertiesDialog import TemplatePropertiesDialog
505
510 dlg = TemplatePropertiesDialog(self, True) 506 dlg = TemplatePropertiesDialog(self, True)
511 if dlg.exec() == QDialog.DialogCode.Accepted: 507 if dlg.exec() == QDialog.DialogCode.Accepted:
512 name, language = dlg.getData() 508 name, language = dlg.getData()
513 self.addGroup(name, language) 509 self.addGroup(name, language)
514 self.__dirty = True 510 self.__dirty = True
515 511
516 def __edit(self): 512 def __edit(self):
517 """ 513 """
518 Private slot to handle the Edit context menu action. 514 Private slot to handle the Edit context menu action.
519 """ 515 """
520 itm = self.currentItem() 516 itm = self.currentItem()
521 editGroup = not isinstance(itm, TemplateEntry) 517 editGroup = not isinstance(itm, TemplateEntry)
522 518
523 from .TemplatePropertiesDialog import TemplatePropertiesDialog 519 from .TemplatePropertiesDialog import TemplatePropertiesDialog
520
524 dlg = TemplatePropertiesDialog(self, editGroup, itm) 521 dlg = TemplatePropertiesDialog(self, editGroup, itm)
525 if dlg.exec() == QDialog.DialogCode.Accepted: 522 if dlg.exec() == QDialog.DialogCode.Accepted:
526 if editGroup: 523 if editGroup:
527 name, language = dlg.getData() 524 name, language = dlg.getData()
528 self.changeGroup(itm.getName(), name, language) 525 self.changeGroup(itm.getName(), name, language)
529 else: 526 else:
530 name, description, groupName, template = dlg.getData() 527 name, description, groupName, template = dlg.getData()
531 self.changeEntry(itm, name, groupName, description, template) 528 self.changeEntry(itm, name, groupName, description, template)
532 self.__dirty = True 529 self.__dirty = True
533 530
534 def __remove(self): 531 def __remove(self):
535 """ 532 """
536 Private slot to handle the Remove context menu action. 533 Private slot to handle the Remove context menu action.
537 """ 534 """
538 itm = self.currentItem() 535 itm = self.currentItem()
539 res = EricMessageBox.yesNo( 536 res = EricMessageBox.yesNo(
540 self, 537 self,
541 self.tr("Remove Template"), 538 self.tr("Remove Template"),
542 self.tr("""<p>Do you really want to remove <b>{0}</b>?</p>""") 539 self.tr("""<p>Do you really want to remove <b>{0}</b>?</p>""").format(
543 .format(itm.getName())) 540 itm.getName()
541 ),
542 )
544 if not res: 543 if not res:
545 return 544 return
546 545
547 if isinstance(itm, TemplateGroup): 546 if isinstance(itm, TemplateGroup):
548 self.removeGroup(itm) 547 self.removeGroup(itm)
565 """ 564 """
566 fn = EricFileDialog.getOpenFileName( 565 fn = EricFileDialog.getOpenFileName(
567 self, 566 self,
568 self.tr("Import Templates"), 567 self.tr("Import Templates"),
569 "", 568 "",
570 self.tr("Templates Files (*.ecj);;" 569 self.tr(
571 "XML Templates Files (*.e4c);;" 570 "Templates Files (*.ecj);;"
572 "All Files (*)")) 571 "XML Templates Files (*.e4c);;"
573 572 "All Files (*)"
573 ),
574 )
575
574 if fn: 576 if fn:
575 self.readTemplates(fn) 577 self.readTemplates(fn)
576 self.__dirty = True 578 self.__dirty = True
577 579
578 def __export(self): 580 def __export(self):
581 """ 583 """
582 fn, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 584 fn, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
583 self, 585 self,
584 self.tr("Export Templates"), 586 self.tr("Export Templates"),
585 "", 587 "",
586 self.tr("Templates Files (*.ecj);;" 588 self.tr("Templates Files (*.ecj);;" "All Files (*)"),
587 "All Files (*)"),
588 "", 589 "",
589 EricFileDialog.DontConfirmOverwrite) 590 EricFileDialog.DontConfirmOverwrite,
590 591 )
592
591 if fn: 593 if fn:
592 fpath = pathlib.Path(fn) 594 fpath = pathlib.Path(fn)
593 if not fpath.suffix: 595 if not fpath.suffix:
594 ex = selectedFilter.split("(*")[1].split(")")[0] 596 ex = selectedFilter.split("(*")[1].split(")")[0]
595 if ex: 597 if ex:
596 fpath = fpath.with_suffix(ex) 598 fpath = fpath.with_suffix(ex)
597 if fpath.exists(): 599 if fpath.exists():
598 ok = EricMessageBox.yesNo( 600 ok = EricMessageBox.yesNo(
599 self, 601 self,
600 self.tr("Export Templates"), 602 self.tr("Export Templates"),
601 self.tr("""<p>The templates file <b>{0}</b> exists""" 603 self.tr(
602 """ already. Overwrite it?</p>""").format(fpath)) 604 """<p>The templates file <b>{0}</b> exists"""
605 """ already. Overwrite it?</p>"""
606 ).format(fpath),
607 )
603 else: 608 else:
604 ok = True 609 ok = True
605 610
606 if ok: 611 if ok:
607 self.writeTemplates(str(fpath)) 612 self.writeTemplates(str(fpath))
608 613
609 def __reload(self): 614 def __reload(self):
610 """ 615 """
611 Private slot to reload the templates. 616 Private slot to reload the templates.
612 """ 617 """
613 if self.__dirty: 618 if self.__dirty:
614 res = EricMessageBox.yesNo( 619 res = EricMessageBox.yesNo(
615 self, 620 self,
616 self.tr("Reload Templates"), 621 self.tr("Reload Templates"),
617 self.tr( 622 self.tr(
618 """The templates contain unsaved changes. Shall these""" 623 """The templates contain unsaved changes. Shall these"""
619 """ changes be discarded?"""), 624 """ changes be discarded?"""
620 icon=EricMessageBox.Warning) 625 ),
626 icon=EricMessageBox.Warning,
627 )
621 if not res: 628 if not res:
622 return 629 return
623 630
624 self.clear() 631 self.clear()
625 self.groups = {} 632 self.groups = {}
626 633
627 self.readTemplates() 634 self.readTemplates()
628 635
629 def __showHelp(self): 636 def __showHelp(self):
630 """ 637 """
631 Private method to show some help. 638 Private method to show some help.
632 """ 639 """
633 EricMessageBox.information( 640 EricMessageBox.information(
640 """ In order to add template entries, at least one group""" 647 """ In order to add template entries, at least one group"""
641 """ has to be defined.</p>""" 648 """ has to be defined.</p>"""
642 """<p><b>Template entries</b> are the actual templates.""" 649 """<p><b>Template entries</b> are the actual templates."""
643 """ They are grouped by the template groups. Help about""" 650 """ They are grouped by the template groups. Help about"""
644 """ how to define them is available in the template edit""" 651 """ how to define them is available in the template edit"""
645 """ dialog.</p>""")) 652 """ dialog.</p>"""
653 ),
654 )
646 655
647 def __getPredefinedVars(self): 656 def __getPredefinedVars(self):
648 """ 657 """
649 Private method to return predefined variables. 658 Private method to return predefined variables.
650 659
651 @return dictionary of predefined variables and their values 660 @return dictionary of predefined variables and their values
652 """ 661 """
653 project = ericApp().getObject("Project") 662 project = ericApp().getObject("Project")
654 editor = self.viewmanager.activeWindow() 663 editor = self.viewmanager.activeWindow()
655 now = datetime.datetime.now() 664 now = datetime.datetime.now()
656 sepchar = Preferences.getTemplates("SeparatorChar") 665 sepchar = Preferences.getTemplates("SeparatorChar")
657 keyfmt = sepchar + "{0}" + sepchar 666 keyfmt = sepchar + "{0}" + sepchar
658 varValues = { 667 varValues = {
659 keyfmt.format('date'): now.date().isoformat(), 668 keyfmt.format("date"): now.date().isoformat(),
660 keyfmt.format('year'): str(now.date().year), 669 keyfmt.format("year"): str(now.date().year),
661 keyfmt.format('time'): now.time().strftime("%H:%M:%S"), 670 keyfmt.format("time"): now.time().strftime("%H:%M:%S"),
662 } 671 }
663 672
664 if project.name: 673 if project.name:
665 varValues[keyfmt.format('project_name')] = project.name 674 varValues[keyfmt.format("project_name")] = project.name
666 675
667 if project.ppath: 676 if project.ppath:
668 varValues[keyfmt.format('project_path')] = project.ppath 677 varValues[keyfmt.format("project_path")] = project.ppath
669 678
670 path_name = editor.getFileName() 679 path_name = editor.getFileName()
671 if path_name: 680 if path_name:
672 dir_name, file_name = os.path.split(path_name) 681 dir_name, file_name = os.path.split(path_name)
673 base_name, ext = os.path.splitext(file_name) 682 base_name, ext = os.path.splitext(file_name)
674 if ext: 683 if ext:
675 ext = ext[1:] 684 ext = ext[1:]
676 path_name_rel = project.getRelativePath(path_name) 685 path_name_rel = project.getRelativePath(path_name)
677 dir_name_rel = project.getRelativePath(dir_name) 686 dir_name_rel = project.getRelativePath(dir_name)
678 varValues.update({ 687 varValues.update(
679 keyfmt.format('path_name'): path_name, 688 {
680 keyfmt.format('path_name_rel'): path_name_rel, 689 keyfmt.format("path_name"): path_name,
681 keyfmt.format('dir_name'): dir_name, 690 keyfmt.format("path_name_rel"): path_name_rel,
682 keyfmt.format('dir_name_rel'): dir_name_rel, 691 keyfmt.format("dir_name"): dir_name,
683 keyfmt.format('file_name'): file_name, 692 keyfmt.format("dir_name_rel"): dir_name_rel,
684 keyfmt.format('base_name'): base_name, 693 keyfmt.format("file_name"): file_name,
685 keyfmt.format('ext'): ext 694 keyfmt.format("base_name"): base_name,
686 }) 695 keyfmt.format("ext"): ext,
687 696 }
688 varValues[keyfmt.format('clipboard:ml')] = ( 697 )
689 QApplication.clipboard().text() 698
690 ) 699 varValues[keyfmt.format("clipboard:ml")] = QApplication.clipboard().text()
691 varValues[keyfmt.format('clipboard')] = QApplication.clipboard().text() 700 varValues[keyfmt.format("clipboard")] = QApplication.clipboard().text()
692 701
693 if editor.hasSelectedText(): 702 if editor.hasSelectedText():
694 varValues[keyfmt.format('cur_select:ml')] = editor.selectedText() 703 varValues[keyfmt.format("cur_select:ml")] = editor.selectedText()
695 varValues[keyfmt.format('cur_select')] = editor.selectedText() 704 varValues[keyfmt.format("cur_select")] = editor.selectedText()
696 else: 705 else:
697 varValues[keyfmt.format('cur_select:ml')] = os.linesep 706 varValues[keyfmt.format("cur_select:ml")] = os.linesep
698 varValues[keyfmt.format('cur_select')] = "" 707 varValues[keyfmt.format("cur_select")] = ""
699 708
700 varValues[keyfmt.format('insertion')] = "i_n_s_e_r_t_i_o_n" 709 varValues[keyfmt.format("insertion")] = "i_n_s_e_r_t_i_o_n"
701 710
702 varValues[keyfmt.format('select_start')] = "s_e_l_e_c_t_s_t_a_r_t" 711 varValues[keyfmt.format("select_start")] = "s_e_l_e_c_t_s_t_a_r_t"
703 varValues[keyfmt.format('select_end')] = "s_e_l_e_c_t_e_n_d" 712 varValues[keyfmt.format("select_end")] = "s_e_l_e_c_t_e_n_d"
704 713
705 return varValues 714 return varValues
706 715
707 def applyTemplate(self, itm): 716 def applyTemplate(self, itm):
708 """ 717 """
709 Public method to apply the template. 718 Public method to apply the template.
710 719
711 @param itm reference to the template item to apply (TemplateEntry) 720 @param itm reference to the template item to apply (TemplateEntry)
712 """ 721 """
713 editor = self.viewmanager.activeWindow() 722 editor = self.viewmanager.activeWindow()
714 if editor is None: 723 if editor is None:
715 return 724 return
716 725
717 ok = False 726 ok = False
718 variables = itm.getVariables() 727 variables = itm.getVariables()
719 varValues = self.__getPredefinedVars() 728 varValues = self.__getPredefinedVars()
720 729
721 # Remove predefined variables from list so user doesn't have to fill 730 # Remove predefined variables from list so user doesn't have to fill
722 # these values out in the dialog. 731 # these values out in the dialog.
723 for v in list(varValues.keys()): 732 for v in list(varValues.keys()):
724 if v in variables: 733 if v in variables:
725 variables.remove(v) 734 variables.remove(v)
726 735
727 if variables: 736 if variables:
728 if Preferences.getTemplates("SingleDialog"): 737 if Preferences.getTemplates("SingleDialog"):
729 from .TemplateMultipleVariablesDialog import ( 738 from .TemplateMultipleVariablesDialog import (
730 TemplateMultipleVariablesDialog 739 TemplateMultipleVariablesDialog,
731 ) 740 )
741
732 dlg = TemplateMultipleVariablesDialog(variables, self) 742 dlg = TemplateMultipleVariablesDialog(variables, self)
733 if dlg.exec() == QDialog.DialogCode.Accepted: 743 if dlg.exec() == QDialog.DialogCode.Accepted:
734 varValues.update(dlg.getVariables()) 744 varValues.update(dlg.getVariables())
735 ok = True 745 ok = True
736 else: 746 else:
737 from .TemplateSingleVariableDialog import ( 747 from .TemplateSingleVariableDialog import TemplateSingleVariableDialog
738 TemplateSingleVariableDialog 748
739 )
740 for var in variables: 749 for var in variables:
741 dlg = TemplateSingleVariableDialog(var, self) 750 dlg = TemplateSingleVariableDialog(var, self)
742 if dlg.exec() == QDialog.DialogCode.Accepted: 751 if dlg.exec() == QDialog.DialogCode.Accepted:
743 varValues[var] = dlg.getVariable() 752 varValues[var] = dlg.getVariable()
744 else: 753 else:
745 return 754 return
746 del dlg 755 del dlg
747 ok = True 756 ok = True
748 else: 757 else:
749 ok = True 758 ok = True
750 759
751 if ok: 760 if ok:
752 line = editor.text( 761 line = editor.text(editor.getCursorPosition()[0]).replace(os.linesep, "")
753 editor.getCursorPosition()[0]).replace(os.linesep, "")
754 indent = line.replace(line.lstrip(), "") 762 indent = line.replace(line.lstrip(), "")
755 txt, lines, count = itm.getExpandedText(varValues, indent) 763 txt, lines, count = itm.getExpandedText(varValues, indent)
756 # It should be done in this way to allow undo 764 # It should be done in this way to allow undo
757 editor.beginUndoAction() 765 editor.beginUndoAction()
758 if editor.hasSelectedText(): 766 if editor.hasSelectedText():
759 line, index = editor.getSelection()[0:2] 767 line, index = editor.getSelection()[0:2]
760 editor.removeSelectedText() 768 editor.removeSelectedText()
761 else: 769 else:
762 line, index = editor.getCursorPosition() 770 line, index = editor.getCursorPosition()
763 771
764 if lines == 1: 772 if lines == 1:
765 count += index 773 count += index
766 else: 774 else:
767 if len(indent) > 0: 775 if len(indent) > 0:
768 count += len(indent) 776 count += len(indent)
769 777
770 if "i_n_s_e_r_t_i_o_n" in txt and "s_e_l_e_c_t" in txt: 778 if "i_n_s_e_r_t_i_o_n" in txt and "s_e_l_e_c_t" in txt:
771 txt = ( 779 txt = "'Insertion and selection can not be in" " template together'"
772 "'Insertion and selection can not be in" 780
773 " template together'"
774 )
775
776 if "i_n_s_e_r_t_i_o_n" in txt: 781 if "i_n_s_e_r_t_i_o_n" in txt:
777 lines = 1 782 lines = 1
778 for aline in txt.splitlines(): 783 for aline in txt.splitlines():
779 count = aline.find("i_n_s_e_r_t_i_o_n") 784 count = aline.find("i_n_s_e_r_t_i_o_n")
780 if count >= 0: 785 if count >= 0:
785 if len(indent) > 0: 790 if len(indent) > 0:
786 count += len(indent) 791 count += len(indent)
787 break 792 break
788 else: 793 else:
789 lines += 1 794 lines += 1
790 795
791 setselect = False 796 setselect = False
792 if "s_e_l_e_c_t_s_t_a_r_t" in txt and "s_e_l_e_c_t_e_n_d" in txt: 797 if "s_e_l_e_c_t_s_t_a_r_t" in txt and "s_e_l_e_c_t_e_n_d" in txt:
793 setselect = True 798 setselect = True
794 linea = 1 799 linea = 1
795 for aline in txt.splitlines(): 800 for aline in txt.splitlines():
805 if posb >= 0: 810 if posb >= 0:
806 txt = txt.replace("s_e_l_e_c_t_e_n_d", "") 811 txt = txt.replace("s_e_l_e_c_t_e_n_d", "")
807 break 812 break
808 else: 813 else:
809 lineb += 1 814 lineb += 1
810 815
811 editor.insert(txt) 816 editor.insert(txt)
812 817
813 if setselect: 818 if setselect:
814 editor.setSelection(line + linea - 1, posa, 819 editor.setSelection(line + linea - 1, posa, line + lineb - 1, posb)
815 line + lineb - 1, posb)
816 else: 820 else:
817 editor.setCursorPosition(line + lines - 1, count) 821 editor.setCursorPosition(line + lines - 1, count)
818 822
819 editor.endUndoAction() 823 editor.endUndoAction()
820 editor.setFocus() 824 editor.setFocus()
821 825
822 def applyNamedTemplate(self, templateName, groupName=None): 826 def applyNamedTemplate(self, templateName, groupName=None):
823 """ 827 """
824 Public method to apply a template given a template name. 828 Public method to apply a template given a template name.
825 829
826 @param templateName name of the template item to apply (string) 830 @param templateName name of the template item to apply (string)
827 @param groupName name of the group to get the entry from (string). 831 @param groupName name of the group to get the entry from (string).
828 None or empty means to apply the first template found with the 832 None or empty means to apply the first template found with the
829 given name. 833 given name.
830 """ 834 """
838 for group in groups: 842 for group in groups:
839 template = group.getEntry(templateName) 843 template = group.getEntry(templateName)
840 if template is not None: 844 if template is not None:
841 self.applyTemplate(template) 845 self.applyTemplate(template)
842 break 846 break
843 847
844 def addEntry(self, groupName, name, description, template, quiet=False): 848 def addEntry(self, groupName, name, description, template, quiet=False):
845 """ 849 """
846 Public method to add a template entry. 850 Public method to add a template entry.
847 851
848 @param groupName name of the group to add to (string) 852 @param groupName name of the group to add to (string)
849 @param name name of the entry to add (string) 853 @param name name of the entry to add (string)
850 @param description description of the entry to add (string) 854 @param description description of the entry to add (string)
851 @param template template text of the entry (string) 855 @param template template text of the entry (string)
852 @param quiet flag indicating quiet operation (boolean) 856 @param quiet flag indicating quiet operation (boolean)
853 """ 857 """
854 self.groups[groupName].addEntry( 858 self.groups[groupName].addEntry(name, description, template, quiet=quiet)
855 name, description, template, quiet=quiet)
856 self.__resort() 859 self.__resort()
857 860
858 def hasGroup(self, name): 861 def hasGroup(self, name):
859 """ 862 """
860 Public method to check, if a group with the given name exists. 863 Public method to check, if a group with the given name exists.
861 864
862 @param name name of the group to be checked for (string) 865 @param name name of the group to be checked for (string)
863 @return flag indicating an existing group (boolean) 866 @return flag indicating an existing group (boolean)
864 """ 867 """
865 return name in self.groups 868 return name in self.groups
866 869
867 def addGroup(self, name, language="All"): 870 def addGroup(self, name, language="All"):
868 """ 871 """
869 Public method to add a group. 872 Public method to add a group.
870 873
871 @param name name of the group to be added (string) 874 @param name name of the group to be added (string)
872 @param language programming language for the group (string) 875 @param language programming language for the group (string)
873 """ 876 """
874 if name not in self.groups: 877 if name not in self.groups:
875 self.groups[name] = TemplateGroup(self, name, language) 878 self.groups[name] = TemplateGroup(self, name, language)
876 self.__resort() 879 self.__resort()
877 880
878 def changeGroup(self, oldname, newname, language="All"): 881 def changeGroup(self, oldname, newname, language="All"):
879 """ 882 """
880 Public method to rename a group. 883 Public method to rename a group.
881 884
882 @param oldname old name of the group (string) 885 @param oldname old name of the group (string)
883 @param newname new name of the group (string) 886 @param newname new name of the group (string)
884 @param language programming language for the group (string) 887 @param language programming language for the group (string)
885 """ 888 """
886 if oldname != newname: 889 if oldname != newname:
887 if newname in self.groups: 890 if newname in self.groups:
888 EricMessageBox.warning( 891 EricMessageBox.warning(
889 self, 892 self,
890 self.tr("Edit Template Group"), 893 self.tr("Edit Template Group"),
891 self.tr("""<p>A template group with the name""" 894 self.tr(
892 """ <b>{0}</b> already exists.</p>""") 895 """<p>A template group with the name"""
893 .format(newname)) 896 """ <b>{0}</b> already exists.</p>"""
897 ).format(newname),
898 )
894 return 899 return
895 900
896 self.groups[newname] = self.groups[oldname] 901 self.groups[newname] = self.groups[oldname]
897 del self.groups[oldname] 902 del self.groups[oldname]
898 self.groups[newname].setName(newname) 903 self.groups[newname].setName(newname)
899 904
900 self.groups[newname].setLanguage(language) 905 self.groups[newname].setLanguage(language)
901 self.__resort() 906 self.__resort()
902 907
903 def getAllGroups(self): 908 def getAllGroups(self):
904 """ 909 """
905 Public method to get all groups. 910 Public method to get all groups.
906 911
907 @return list of all groups (list of TemplateGroup) 912 @return list of all groups (list of TemplateGroup)
908 """ 913 """
909 return list(self.groups.values()) 914 return list(self.groups.values())
910 915
911 def getGroupNames(self): 916 def getGroupNames(self):
912 """ 917 """
913 Public method to get all group names. 918 Public method to get all group names.
914 919
915 @return list of all group names (list of strings) 920 @return list of all group names (list of strings)
916 """ 921 """
917 groups = sorted(list(self.groups.keys())[:]) 922 groups = sorted(list(self.groups.keys())[:])
918 return groups 923 return groups
919 924
920 def removeGroup(self, itm): 925 def removeGroup(self, itm):
921 """ 926 """
922 Public method to remove a group. 927 Public method to remove a group.
923 928
924 @param itm template group to be removed (TemplateGroup) 929 @param itm template group to be removed (TemplateGroup)
925 """ 930 """
926 name = itm.getName() 931 name = itm.getName()
927 itm.removeAllEntries() 932 itm.removeAllEntries()
928 index = self.indexOfTopLevelItem(itm) 933 index = self.indexOfTopLevelItem(itm)
930 del self.groups[name] 935 del self.groups[name]
931 936
932 def removeEntry(self, itm): 937 def removeEntry(self, itm):
933 """ 938 """
934 Public method to remove a template entry. 939 Public method to remove a template entry.
935 940
936 @param itm template entry to be removed (TemplateEntry) 941 @param itm template entry to be removed (TemplateEntry)
937 """ 942 """
938 groupName = itm.getGroupName() 943 groupName = itm.getGroupName()
939 self.groups[groupName].removeEntry(itm.getName()) 944 self.groups[groupName].removeEntry(itm.getName())
940 945
941 def changeEntry(self, itm, name, groupName, description, template): 946 def changeEntry(self, itm, name, groupName, description, template):
942 """ 947 """
943 Public method to change a template entry. 948 Public method to change a template entry.
944 949
945 @param itm template entry to be changed (TemplateEntry) 950 @param itm template entry to be changed (TemplateEntry)
946 @param name new name for the entry (string) 951 @param name new name for the entry (string)
947 @param groupName name of the group the entry should belong to 952 @param groupName name of the group the entry should belong to
948 (string) 953 (string)
949 @param description description of the entry (string) 954 @param description description of the entry (string)
952 if itm.getGroupName() != groupName: 957 if itm.getGroupName() != groupName:
953 # move entry to another group 958 # move entry to another group
954 self.groups[itm.getGroupName()].removeEntry(itm.getName()) 959 self.groups[itm.getGroupName()].removeEntry(itm.getName())
955 self.groups[groupName].addEntry(name, description, template) 960 self.groups[groupName].addEntry(name, description, template)
956 return 961 return
957 962
958 if itm.getName() != name: 963 if itm.getName() != name:
959 # entry was renamed 964 # entry was renamed
960 self.groups[groupName].removeEntry(itm.getName()) 965 self.groups[groupName].removeEntry(itm.getName())
961 self.groups[groupName].addEntry(name, description, template) 966 self.groups[groupName].addEntry(name, description, template)
962 return 967 return
963 968
964 tmpl = self.groups[groupName].getEntry(name) 969 tmpl = self.groups[groupName].getEntry(name)
965 tmpl.setDescription(description) 970 tmpl.setDescription(description)
966 tmpl.setTemplateText(template) 971 tmpl.setTemplateText(template)
967 self.__resort() 972 self.__resort()
968 973
969 def writeTemplates(self, filename=None): 974 def writeTemplates(self, filename=None):
970 """ 975 """
971 Public method to write the templates data to a JSON file (.ecj). 976 Public method to write the templates data to a JSON file (.ecj).
972 977
973 @param filename name of a templates file to write 978 @param filename name of a templates file to write
974 @type str 979 @type str
975 @return flag indicating success 980 @return flag indicating success
976 @rtype bool 981 @rtype bool
977 """ 982 """
978 if filename is None: 983 if filename is None:
979 filename = os.path.join( 984 filename = os.path.join(Utilities.getConfigDir(), "eric7templates.ecj")
980 Utilities.getConfigDir(), "eric7templates.ecj") 985
981
982 return self.__templatesFile.writeFile(filename) 986 return self.__templatesFile.writeFile(filename)
983 987
984 def readTemplates(self, filename=None): 988 def readTemplates(self, filename=None):
985 """ 989 """
986 Public method to read in the templates file (.e4c). 990 Public method to read in the templates file (.e4c).
987 991
988 @param filename name of a templates file to read 992 @param filename name of a templates file to read
989 @type str 993 @type str
990 """ 994 """
991 if filename is None: 995 if filename is None:
992 # new JSON based file first 996 # new JSON based file first
993 filename = os.path.join( 997 filename = os.path.join(Utilities.getConfigDir(), "eric7templates.ecj")
994 Utilities.getConfigDir(), "eric7templates.ecj")
995 if not os.path.exists(filename): 998 if not os.path.exists(filename):
996 # old XML based file second 999 # old XML based file second
997 filename = os.path.join( 1000 filename = os.path.join(Utilities.getConfigDir(), "eric7templates.e4c")
998 Utilities.getConfigDir(), "eric7templates.e4c")
999 if not os.path.exists(filename): 1001 if not os.path.exists(filename):
1000 return 1002 return
1001 1003
1002 if filename.endswith(".ecj"): 1004 if filename.endswith(".ecj"):
1003 self.__templatesFile.readFile(filename) 1005 self.__templatesFile.readFile(filename)
1004 else: 1006 else:
1005 f = QFile(filename) 1007 f = QFile(filename)
1006 if f.open(QIODevice.OpenModeFlag.ReadOnly): 1008 if f.open(QIODevice.OpenModeFlag.ReadOnly):
1007 from EricXML.TemplatesReader import TemplatesReader 1009 from EricXML.TemplatesReader import TemplatesReader
1010
1008 reader = TemplatesReader(f, viewer=self) 1011 reader = TemplatesReader(f, viewer=self)
1009 reader.readXML() 1012 reader.readXML()
1010 f.close() 1013 f.close()
1011 else: 1014 else:
1012 EricMessageBox.critical( 1015 EricMessageBox.critical(
1013 self, 1016 self,
1014 self.tr("Read Templates"), 1017 self.tr("Read Templates"),
1015 self.tr( 1018 self.tr(
1016 "<p>The templates file <b>{0}</b> could not be read." 1019 "<p>The templates file <b>{0}</b> could not be read." "</p>"
1017 "</p>") 1020 ).format(filename),
1018 .format(filename)) 1021 )
1019 1022
1020 def __configure(self): 1023 def __configure(self):
1021 """ 1024 """
1022 Private method to open the configuration dialog. 1025 Private method to open the configuration dialog.
1023 """ 1026 """
1024 ericApp().getObject("UserInterface").showPreferences("templatesPage") 1027 ericApp().getObject("UserInterface").showPreferences("templatesPage")
1025 1028
1026 def hasTemplate(self, entryName, groupName=None): 1029 def hasTemplate(self, entryName, groupName=None):
1027 """ 1030 """
1028 Public method to check, if an entry of the given name exists. 1031 Public method to check, if an entry of the given name exists.
1029 1032
1030 @param entryName name of the entry to check for (string) 1033 @param entryName name of the entry to check for (string)
1031 @param groupName name of the group to check for the entry (string). 1034 @param groupName name of the group to check for the entry (string).
1032 None or empty means to check all groups. 1035 None or empty means to check all groups.
1033 @return flag indicating the existence (boolean) 1036 @return flag indicating the existence (boolean)
1034 """ 1037 """
1037 groups = [self.groups[groupName]] 1040 groups = [self.groups[groupName]]
1038 else: 1041 else:
1039 groups = [] 1042 groups = []
1040 else: 1043 else:
1041 groups = list(self.groups.values()) 1044 groups = list(self.groups.values())
1042 1045
1043 return any(group.hasEntry(entryName) for group in groups) 1046 return any(group.hasEntry(entryName) for group in groups)
1044 1047
1045 def getTemplateNames(self, start, groupName=None): 1048 def getTemplateNames(self, start, groupName=None):
1046 """ 1049 """
1047 Public method to get the names of templates starting with the 1050 Public method to get the names of templates starting with the
1048 given string. 1051 given string.
1049 1052
1050 @param start start string of the name (string) 1053 @param start start string of the name (string)
1051 @param groupName name of the group to get the entry from (string). 1054 @param groupName name of the group to get the entry from (string).
1052 None or empty means to look in all groups. 1055 None or empty means to look in all groups.
1053 @return sorted list of matching template names (list of strings) 1056 @return sorted list of matching template names (list of strings)
1054 """ 1057 """

eric ide

mercurial