7 Module implementing the QRegExp wizard dialog. |
7 Module implementing the QRegExp wizard dialog. |
8 """ |
8 """ |
9 |
9 |
10 import os |
10 import os |
11 |
11 |
12 from PyQt4.QtCore import QFileInfo, QRegExp, Qt, pyqtSlot |
12 from PyQt4.QtCore import QFileInfo, QRegExp, Qt, pyqtSlot, qVersion |
13 from PyQt4.QtGui import QWidget, QDialog, QApplication, QClipboard, QTextCursor, \ |
13 from PyQt4.QtGui import QWidget, QDialog, QApplication, QClipboard, QTextCursor, \ |
14 QDialogButtonBox, QMainWindow, QVBoxLayout, QTableWidgetItem |
14 QDialogButtonBox, QMainWindow, QVBoxLayout, QTableWidgetItem |
15 |
15 |
16 from E5Gui import E5MessageBox, E5FileDialog |
16 from E5Gui import E5MessageBox, E5FileDialog |
17 |
17 |
18 from .Ui_QRegExpWizardDialog import Ui_QRegExpWizardDialog |
18 from .Ui_QRegExpWizardDialog import Ui_QRegExpWizardWidget |
19 |
19 |
20 from .QRegExpWizardRepeatDialog import QRegExpWizardRepeatDialog |
20 from .QRegExpWizardRepeatDialog import QRegExpWizardRepeatDialog |
21 from .QRegExpWizardCharactersDialog import QRegExpWizardCharactersDialog |
21 from .QRegExpWizardCharactersDialog import QRegExpWizardCharactersDialog |
22 |
22 |
23 import UI.PixmapCache |
23 import UI.PixmapCache |
24 |
24 |
25 import Utilities |
25 import Utilities |
26 |
26 |
27 |
27 |
28 class QRegExpWizardWidget(QWidget, Ui_QRegExpWizardDialog): |
28 class QRegExpWizardWidget(QWidget, Ui_QRegExpWizardWidget): |
29 """ |
29 """ |
30 Class implementing the QRegExp wizard dialog. |
30 Class implementing the QRegExp wizard dialog. |
31 """ |
31 """ |
32 def __init__(self, parent=None, fromEric=True): |
32 def __init__(self, parent=None, fromEric=True): |
33 """ |
33 """ |
38 """ |
38 """ |
39 super().__init__(parent) |
39 super().__init__(parent) |
40 self.setupUi(self) |
40 self.setupUi(self) |
41 |
41 |
42 # initialize icons of the tool buttons |
42 # initialize icons of the tool buttons |
|
43 # regexp tool buttons |
43 self.charButton.setIcon(UI.PixmapCache.getIcon("characters.png")) |
44 self.charButton.setIcon(UI.PixmapCache.getIcon("characters.png")) |
44 self.anycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) |
45 self.anycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) |
45 self.repeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) |
46 self.repeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) |
46 self.nonGroupButton.setIcon(UI.PixmapCache.getIcon("nongroup.png")) |
47 self.nonGroupButton.setIcon(UI.PixmapCache.getIcon("nongroup.png")) |
47 self.groupButton.setIcon(UI.PixmapCache.getIcon("group.png")) |
48 self.groupButton.setIcon(UI.PixmapCache.getIcon("group.png")) |
52 self.nonwordboundButton.setIcon(UI.PixmapCache.getIcon("nonwordboundary.png")) |
53 self.nonwordboundButton.setIcon(UI.PixmapCache.getIcon("nonwordboundary.png")) |
53 self.poslookaheadButton.setIcon(UI.PixmapCache.getIcon("poslookahead.png")) |
54 self.poslookaheadButton.setIcon(UI.PixmapCache.getIcon("poslookahead.png")) |
54 self.neglookaheadButton.setIcon(UI.PixmapCache.getIcon("neglookahead.png")) |
55 self.neglookaheadButton.setIcon(UI.PixmapCache.getIcon("neglookahead.png")) |
55 self.undoButton.setIcon(UI.PixmapCache.getIcon("editUndo.png")) |
56 self.undoButton.setIcon(UI.PixmapCache.getIcon("editUndo.png")) |
56 self.redoButton.setIcon(UI.PixmapCache.getIcon("editRedo.png")) |
57 self.redoButton.setIcon(UI.PixmapCache.getIcon("editRedo.png")) |
|
58 # wildcard tool buttons |
|
59 self.wildcardCharButton.setIcon(UI.PixmapCache.getIcon("characters.png")) |
|
60 self.wildcardAnycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) |
|
61 self.wildcardRepeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) |
|
62 # W3C tool buttons |
|
63 self.w3cCharButton.setIcon(UI.PixmapCache.getIcon("characters.png")) |
|
64 self.w3cAnycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) |
|
65 self.w3cRepeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) |
|
66 self.w3cGroupButton.setIcon(UI.PixmapCache.getIcon("group.png")) |
|
67 self.w3cAltnButton.setIcon(UI.PixmapCache.getIcon("altn.png")) |
|
68 |
|
69 # initialize the syntax pattern combo |
|
70 self.syntaxCombo.addItem("RegExp", QRegExp.RegExp) |
|
71 self.syntaxCombo.addItem("RegExp2", QRegExp.RegExp2) |
|
72 self.syntaxCombo.addItem("Wildcard", QRegExp.Wildcard) |
|
73 self.syntaxCombo.addItem("Unix Wildcard", QRegExp.WildcardUnix) |
|
74 self.syntaxCombo.addItem("Fixed String", QRegExp.FixedString) |
|
75 self.syntaxCombo.addItem("W3C XML Schema 1.1", QRegExp.W3CXmlSchema11) |
|
76 if qVersion() >= "5.0.0": |
|
77 self.syntaxCombo.setCurrentIndex(1) |
57 |
78 |
58 self.saveButton = \ |
79 self.saveButton = \ |
59 self.buttonBox.addButton(self.trUtf8("Save"), QDialogButtonBox.ActionRole) |
80 self.buttonBox.addButton(self.trUtf8("Save"), QDialogButtonBox.ActionRole) |
60 self.saveButton.setToolTip(self.trUtf8("Save the regular expression to a file")) |
81 self.saveButton.setToolTip(self.trUtf8("Save the regular expression to a file")) |
61 self.loadButton = \ |
82 self.loadButton = \ |
86 self.buttonBox.button(QDialogButtonBox.Cancel).hide() |
107 self.buttonBox.button(QDialogButtonBox.Cancel).hide() |
87 self.variableLabel.hide() |
108 self.variableLabel.hide() |
88 self.variableLineEdit.hide() |
109 self.variableLineEdit.hide() |
89 self.variableLine.hide() |
110 self.variableLine.hide() |
90 self.regexpLineEdit.setFocus() |
111 self.regexpLineEdit.setFocus() |
|
112 |
|
113 @pyqtSlot(int) |
|
114 def on_syntaxCombo_currentIndexChanged(self, index): |
|
115 """ |
|
116 Private slot handling the selection of a pattern syntax. |
|
117 |
|
118 @param index index of the selected entry (integer) |
|
119 """ |
|
120 syntax = self.syntaxCombo.itemData(index) |
|
121 self.regexpButtonsFrame.setVisible(syntax in [ |
|
122 QRegExp.RegExp, QRegExp.RegExp2]) |
|
123 self.regexpButtonsFrame.setEnabled(syntax in [ |
|
124 QRegExp.RegExp, QRegExp.RegExp2]) |
|
125 self.wildcardButtonsFrame.setVisible(syntax in [ |
|
126 QRegExp.Wildcard, QRegExp.WildcardUnix]) |
|
127 self.wildcardButtonsFrame.setEnabled(syntax in [ |
|
128 QRegExp.Wildcard, QRegExp.WildcardUnix]) |
|
129 self.w3cButtonsFrame.setVisible(syntax in [QRegExp.W3CXmlSchema11]) |
|
130 self.w3cButtonsFrame.setEnabled(syntax in [QRegExp.W3CXmlSchema11]) |
91 |
131 |
92 def __insertString(self, s, steps=0): |
132 def __insertString(self, s, steps=0): |
93 """ |
133 """ |
94 Private method to insert a string into line edit and move cursor. |
134 Private method to insert a string into line edit and move cursor. |
95 |
135 |
183 @pyqtSlot() |
223 @pyqtSlot() |
184 def on_charButton_clicked(self): |
224 def on_charButton_clicked(self): |
185 """ |
225 """ |
186 Private slot to handle the characters toolbutton. |
226 Private slot to handle the characters toolbutton. |
187 """ |
227 """ |
188 dlg = QRegExpWizardCharactersDialog(self) |
228 dlg = QRegExpWizardCharactersDialog( |
|
229 mode=QRegExpWizardCharactersDialog.RegExpMode, parent=self) |
189 if dlg.exec_() == QDialog.Accepted: |
230 if dlg.exec_() == QDialog.Accepted: |
190 self.__insertString(dlg.getCharacters()) |
231 self.__insertString(dlg.getCharacters()) |
|
232 |
|
233 @pyqtSlot() |
|
234 def on_wildcardCharButton_clicked(self): |
|
235 """ |
|
236 Private slot to handle the wildcard characters toolbutton. |
|
237 """ |
|
238 dlg = QRegExpWizardCharactersDialog( |
|
239 mode=QRegExpWizardCharactersDialog.WildcardMode, parent=self) |
|
240 if dlg.exec_() == QDialog.Accepted: |
|
241 self.__insertString(dlg.getCharacters()) |
|
242 |
|
243 @pyqtSlot() |
|
244 def on_wildcardAnycharButton_clicked(self): |
|
245 """ |
|
246 Private slot to handle the wildcard any character toolbutton. |
|
247 """ |
|
248 self.__insertString("?") |
|
249 |
|
250 @pyqtSlot() |
|
251 def on_wildcardRepeatButton_clicked(self): |
|
252 """ |
|
253 Private slot to handle the wildcard multiple characters toolbutton. |
|
254 """ |
|
255 self.__insertString("*") |
|
256 |
|
257 @pyqtSlot() |
|
258 def on_w3cCharButton_clicked(self): |
|
259 """ |
|
260 Private slot to handle the wildcard characters toolbutton. |
|
261 """ |
|
262 dlg = QRegExpWizardCharactersDialog( |
|
263 mode=QRegExpWizardCharactersDialog.W3CMode, parent=self) |
|
264 if dlg.exec_() == QDialog.Accepted: |
|
265 self.__insertString(dlg.getCharacters()) |
|
266 |
|
267 @pyqtSlot() |
|
268 def on_w3cAnycharButton_clicked(self): |
|
269 """ |
|
270 Private slot to handle the W3C any character toolbutton. |
|
271 """ |
|
272 self.__insertString(".") |
|
273 |
|
274 @pyqtSlot() |
|
275 def on_w3cRepeatButton_clicked(self): |
|
276 """ |
|
277 Private slot to handle the W3C repeat toolbutton. |
|
278 """ |
|
279 dlg = QRegExpWizardRepeatDialog(self) |
|
280 if dlg.exec_() == QDialog.Accepted: |
|
281 self.__insertString(dlg.getRepeat()) |
|
282 |
|
283 @pyqtSlot() |
|
284 def on_w3cGroupButton_clicked(self): |
|
285 """ |
|
286 Private slot to handle the W3C group toolbutton. |
|
287 """ |
|
288 self.__insertString("()", -1) |
|
289 |
|
290 @pyqtSlot() |
|
291 def on_w3cAltnButton_clicked(self): |
|
292 """ |
|
293 Private slot to handle the alternatives toolbutton. |
|
294 """ |
|
295 self.__insertString("(|)", -2) |
191 |
296 |
192 def on_buttonBox_clicked(self, button): |
297 def on_buttonBox_clicked(self, button): |
193 """ |
298 """ |
194 Private slot called by a button of the button box clicked. |
299 Private slot called by a button of the button box clicked. |
195 |
300 |
233 " Overwrite it?</p>").format(fname), |
338 " Overwrite it?</p>").format(fname), |
234 icon=E5MessageBox.Warning) |
339 icon=E5MessageBox.Warning) |
235 if not res: |
340 if not res: |
236 return |
341 return |
237 |
342 |
|
343 syntax = self.syntaxCombo.itemData(self.syntaxCombo.currentIndex()) |
238 try: |
344 try: |
239 f = open(Utilities.toNativeSeparators(fname), "w", encoding="utf-8") |
345 f = open(Utilities.toNativeSeparators(fname), "w", encoding="utf-8") |
|
346 f.write("syntax={0}\n".format(syntax)) |
240 f.write(self.regexpLineEdit.text()) |
347 f.write(self.regexpLineEdit.text()) |
241 f.close() |
348 f.close() |
242 except IOError as err: |
349 except IOError as err: |
243 E5MessageBox.information(self, |
350 E5MessageBox.information(self, |
244 self.trUtf8("Save regular expression"), |
351 self.trUtf8("Save regular expression"), |
258 if fname: |
365 if fname: |
259 try: |
366 try: |
260 f = open(Utilities.toNativeSeparators(fname), "r", encoding="utf-8") |
367 f = open(Utilities.toNativeSeparators(fname), "r", encoding="utf-8") |
261 regexp = f.read() |
368 regexp = f.read() |
262 f.close() |
369 f.close() |
|
370 if regexp.startswith("syntax="): |
|
371 lines = regexp.splitlines() |
|
372 syntax = int(lines[0].replace("syntax=", "")) |
|
373 index = self.syntaxCombo.findData(syntax) |
|
374 self.syntaxCombo.setCurrentIndex(index) |
|
375 regexp = lines[1] |
263 self.regexpLineEdit.setText(regexp) |
376 self.regexpLineEdit.setText(regexp) |
264 except IOError as err: |
377 except IOError as err: |
265 E5MessageBox.information(self, |
378 E5MessageBox.information(self, |
266 self.trUtf8("Save regular expression"), |
379 self.trUtf8("Save regular expression"), |
267 self.trUtf8("""<p>The regular expression could not be saved.</p>""" |
380 self.trUtf8("""<p>The regular expression could not be saved.</p>""" |
293 if self.caseSensitiveCheckBox.isChecked(): |
406 if self.caseSensitiveCheckBox.isChecked(): |
294 re.setCaseSensitivity(Qt.CaseSensitive) |
407 re.setCaseSensitivity(Qt.CaseSensitive) |
295 else: |
408 else: |
296 re.setCaseSensitivity(Qt.CaseInsensitive) |
409 re.setCaseSensitivity(Qt.CaseInsensitive) |
297 re.setMinimal(self.minimalCheckBox.isChecked()) |
410 re.setMinimal(self.minimalCheckBox.isChecked()) |
298 if self.wildcardCheckBox.isChecked(): |
411 re.setPatternSyntax(self.syntaxCombo.itemData(self.syntaxCombo.currentIndex())) |
299 re.setPatternSyntax(QRegExp.Wildcard) |
|
300 else: |
|
301 re.setPatternSyntax(QRegExp.RegExp) |
|
302 if re.isValid(): |
412 if re.isValid(): |
303 E5MessageBox.information(self, |
413 E5MessageBox.information(self, |
304 self.trUtf8("Validation"), |
414 self.trUtf8("Validation"), |
305 self.trUtf8("""The regular expression is valid.""")) |
415 self.trUtf8("""The regular expression is valid.""")) |
306 else: |
416 else: |
331 if self.caseSensitiveCheckBox.isChecked(): |
441 if self.caseSensitiveCheckBox.isChecked(): |
332 re.setCaseSensitivity(Qt.CaseSensitive) |
442 re.setCaseSensitivity(Qt.CaseSensitive) |
333 else: |
443 else: |
334 re.setCaseSensitivity(Qt.CaseInsensitive) |
444 re.setCaseSensitivity(Qt.CaseInsensitive) |
335 re.setMinimal(self.minimalCheckBox.isChecked()) |
445 re.setMinimal(self.minimalCheckBox.isChecked()) |
336 wildcard = self.wildcardCheckBox.isChecked() |
446 syntax = self.syntaxCombo.itemData(self.syntaxCombo.currentIndex()) |
337 if wildcard: |
447 wildcard = syntax in [QRegExp.Wildcard, QRegExp.WildcardUnix] |
338 re.setPatternSyntax(QRegExp.Wildcard) |
448 re.setPatternSyntax(syntax) |
339 else: |
|
340 re.setPatternSyntax(QRegExp.RegExp) |
|
341 if not re.isValid(): |
449 if not re.isValid(): |
342 E5MessageBox.critical(self, |
450 E5MessageBox.critical(self, |
343 self.trUtf8("Error"), |
451 self.trUtf8("Error"), |
344 self.trUtf8("""Invalid regular expression: {0}""") |
452 self.trUtf8("""Invalid regular expression: {0}""") |
345 .format(re.errorString())) |
453 .format(re.errorString())) |
440 |
548 |
441 @param txt the new text of the line edit (string) |
549 @param txt the new text of the line edit (string) |
442 """ |
550 """ |
443 self.nextButton.setEnabled(False) |
551 self.nextButton.setEnabled(False) |
444 |
552 |
|
553 def __getPatternSyntaxCode(self, syntaxValue): |
|
554 """ |
|
555 Private method to convert a pattern syntax value into a pattern syntax string. |
|
556 |
|
557 @param syntaxValue pattern syntax value (integer) |
|
558 @return pattern syntax string (string) |
|
559 """ |
|
560 syntax = "QRegExp." |
|
561 if syntaxValue == QRegExp.RegExp: |
|
562 syntax += "RegExp" |
|
563 elif syntaxValue == QRegExp.RegExp2: |
|
564 syntax += "RegExp2" |
|
565 elif syntaxValue == QRegExp.Wildcard: |
|
566 syntax += "Wildcard" |
|
567 elif syntaxValue == QRegExp.WildcardUnix: |
|
568 syntax += "WildcardUnix" |
|
569 elif syntaxValue == QRegExp.FixedString: |
|
570 syntax += "FixedString" |
|
571 elif syntaxValue == QRegExp.W3CXmlSchema11: |
|
572 syntax += "W3CXmlSchema11" |
|
573 return syntax |
|
574 |
445 def getCode(self, indLevel, indString): |
575 def getCode(self, indLevel, indString): |
446 """ |
576 """ |
447 Public method to get the source code. |
577 Public method to get the source code. |
448 |
578 |
449 @param indLevel indentation level (int) |
579 @param indLevel indentation level (int) |
466 if not self.caseSensitiveCheckBox.isChecked(): |
596 if not self.caseSensitiveCheckBox.isChecked(): |
467 code += '{0}{1}.setCaseSensitivity(Qt.CaseInsensitive){2}'.format( |
597 code += '{0}{1}.setCaseSensitivity(Qt.CaseInsensitive){2}'.format( |
468 istring, reVar, os.linesep) |
598 istring, reVar, os.linesep) |
469 if self.minimalCheckBox.isChecked(): |
599 if self.minimalCheckBox.isChecked(): |
470 code += '{0}{1}.setMinimal(True){2}'.format(istring, reVar, os.linesep) |
600 code += '{0}{1}.setMinimal(True){2}'.format(istring, reVar, os.linesep) |
471 if self.wildcardCheckBox.isChecked(): |
601 syntax = self.syntaxCombo.itemData(self.syntaxCombo.currentIndex()) |
472 code += '{0}{1}.setPatternSyntax(QRegExp.Wildcard){2}'.format( |
602 needPatternSyntax = True |
473 istring, reVar, estring) |
603 if qVersion() < "5.0.0" and syntax == QRegExp.RegExp or \ |
|
604 qVersion() >= "5.0.0" and syntax == QRegExp.RegExp2: |
|
605 # default value selected |
|
606 needPatternSyntax = False |
|
607 if needPatternSyntax: |
|
608 code += '{0}{1}.setPatternSyntax({2}){3}'.format( |
|
609 istring, reVar, self.__getPatternSyntaxCode(syntax), estring) |
474 return code |
610 return code |
475 |
611 |
476 |
612 |
477 class QRegExpWizardDialog(QDialog): |
613 class QRegExpWizardDialog(QDialog): |
478 """ |
614 """ |