Plugins/WizardPlugins/PyRegExpWizard/PyRegExpWizardDialog.py

branch
Py2 comp.
changeset 3056
9986ec0e559a
parent 2847
1843ef6e2656
parent 2893
150de635fa29
child 3142
55030c09e142
equal deleted inserted replaced
2911:ce77f0b1ee67 3056:9986ec0e559a
11 11
12 import os 12 import os
13 import re 13 import re
14 14
15 from PyQt4.QtCore import QFileInfo, pyqtSlot 15 from PyQt4.QtCore import QFileInfo, pyqtSlot
16 from PyQt4.QtGui import QWidget, QDialog, QInputDialog, QApplication, QClipboard, \ 16 from PyQt4.QtGui import QWidget, QDialog, QInputDialog, QApplication, \
17 QTextCursor, QDialogButtonBox, QVBoxLayout, QTableWidgetItem 17 QClipboard, QTextCursor, QDialogButtonBox, QVBoxLayout, QTableWidgetItem
18 18
19 from E5Gui import E5MessageBox, E5FileDialog 19 from E5Gui import E5MessageBox, E5FileDialog
20 from E5Gui.E5MainWindow import E5MainWindow 20 from E5Gui.E5MainWindow import E5MainWindow
21 21
22 from .Ui_PyRegExpWizardDialog import Ui_PyRegExpWizardDialog 22 from .Ui_PyRegExpWizardDialog import Ui_PyRegExpWizardDialog
47 self.anycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png")) 47 self.anycharButton.setIcon(UI.PixmapCache.getIcon("anychar.png"))
48 self.repeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png")) 48 self.repeatButton.setIcon(UI.PixmapCache.getIcon("repeat.png"))
49 self.nonGroupButton.setIcon(UI.PixmapCache.getIcon("nongroup.png")) 49 self.nonGroupButton.setIcon(UI.PixmapCache.getIcon("nongroup.png"))
50 self.groupButton.setIcon(UI.PixmapCache.getIcon("group.png")) 50 self.groupButton.setIcon(UI.PixmapCache.getIcon("group.png"))
51 self.namedGroupButton.setIcon(UI.PixmapCache.getIcon("namedgroup.png")) 51 self.namedGroupButton.setIcon(UI.PixmapCache.getIcon("namedgroup.png"))
52 self.namedReferenceButton.setIcon(UI.PixmapCache.getIcon("namedreference.png")) 52 self.namedReferenceButton.setIcon(
53 UI.PixmapCache.getIcon("namedreference.png"))
53 self.altnButton.setIcon(UI.PixmapCache.getIcon("altn.png")) 54 self.altnButton.setIcon(UI.PixmapCache.getIcon("altn.png"))
54 self.beglineButton.setIcon(UI.PixmapCache.getIcon("begline.png")) 55 self.beglineButton.setIcon(UI.PixmapCache.getIcon("begline.png"))
55 self.endlineButton.setIcon(UI.PixmapCache.getIcon("endline.png")) 56 self.endlineButton.setIcon(UI.PixmapCache.getIcon("endline.png"))
56 self.wordboundButton.setIcon(UI.PixmapCache.getIcon("wordboundary.png")) 57 self.wordboundButton.setIcon(
57 self.nonwordboundButton.setIcon(UI.PixmapCache.getIcon("nonwordboundary.png")) 58 UI.PixmapCache.getIcon("wordboundary.png"))
58 self.poslookaheadButton.setIcon(UI.PixmapCache.getIcon("poslookahead.png")) 59 self.nonwordboundButton.setIcon(
59 self.neglookaheadButton.setIcon(UI.PixmapCache.getIcon("neglookahead.png")) 60 UI.PixmapCache.getIcon("nonwordboundary.png"))
60 self.poslookbehindButton.setIcon(UI.PixmapCache.getIcon("poslookbehind.png")) 61 self.poslookaheadButton.setIcon(
61 self.neglookbehindButton.setIcon(UI.PixmapCache.getIcon("neglookbehind.png")) 62 UI.PixmapCache.getIcon("poslookahead.png"))
63 self.neglookaheadButton.setIcon(
64 UI.PixmapCache.getIcon("neglookahead.png"))
65 self.poslookbehindButton.setIcon(
66 UI.PixmapCache.getIcon("poslookbehind.png"))
67 self.neglookbehindButton.setIcon(
68 UI.PixmapCache.getIcon("neglookbehind.png"))
62 self.undoButton.setIcon(UI.PixmapCache.getIcon("editUndo.png")) 69 self.undoButton.setIcon(UI.PixmapCache.getIcon("editUndo.png"))
63 self.redoButton.setIcon(UI.PixmapCache.getIcon("editRedo.png")) 70 self.redoButton.setIcon(UI.PixmapCache.getIcon("editRedo.png"))
64 71
65 self.namedGroups = re.compile(r"""\(?P<([^>]+)>""").findall 72 self.namedGroups = re.compile(r"""\(?P<([^>]+)>""").findall
66 73
67 self.saveButton = \ 74 self.saveButton = self.buttonBox.addButton(
68 self.buttonBox.addButton(self.trUtf8("Save"), QDialogButtonBox.ActionRole) 75 self.trUtf8("Save"), QDialogButtonBox.ActionRole)
69 self.saveButton.setToolTip(self.trUtf8("Save the regular expression to a file")) 76 self.saveButton.setToolTip(
70 self.loadButton = \ 77 self.trUtf8("Save the regular expression to a file"))
71 self.buttonBox.addButton(self.trUtf8("Load"), QDialogButtonBox.ActionRole) 78 self.loadButton = self.buttonBox.addButton(
72 self.loadButton.setToolTip(self.trUtf8("Load a regular expression from a file")) 79 self.trUtf8("Load"), QDialogButtonBox.ActionRole)
73 self.validateButton = \ 80 self.loadButton.setToolTip(
74 self.buttonBox.addButton(self.trUtf8("Validate"), QDialogButtonBox.ActionRole) 81 self.trUtf8("Load a regular expression from a file"))
75 self.validateButton.setToolTip(self.trUtf8("Validate the regular expression")) 82 self.validateButton = self.buttonBox.addButton(
76 self.executeButton = \ 83 self.trUtf8("Validate"), QDialogButtonBox.ActionRole)
77 self.buttonBox.addButton(self.trUtf8("Execute"), QDialogButtonBox.ActionRole) 84 self.validateButton.setToolTip(
78 self.executeButton.setToolTip(self.trUtf8("Execute the regular expression")) 85 self.trUtf8("Validate the regular expression"))
79 self.nextButton = \ 86 self.executeButton = self.buttonBox.addButton(
80 self.buttonBox.addButton(self.trUtf8("Next match"), 87 self.trUtf8("Execute"), QDialogButtonBox.ActionRole)
81 QDialogButtonBox.ActionRole) 88 self.executeButton.setToolTip(
89 self.trUtf8("Execute the regular expression"))
90 self.nextButton = self.buttonBox.addButton(
91 self.trUtf8("Next match"), QDialogButtonBox.ActionRole)
82 self.nextButton.setToolTip( 92 self.nextButton.setToolTip(
83 self.trUtf8("Show the next match of the regular expression")) 93 self.trUtf8("Show the next match of the regular expression"))
84 self.nextButton.setEnabled(False) 94 self.nextButton.setEnabled(False)
85 95
86 if fromEric: 96 if fromEric:
87 self.buttonBox.setStandardButtons( 97 self.buttonBox.setStandardButtons(
88 QDialogButtonBox.Cancel | QDialogButtonBox.Ok) 98 QDialogButtonBox.Cancel | QDialogButtonBox.Ok)
89 self.copyButton = None 99 self.copyButton = None
90 else: 100 else:
91 self.copyButton = \ 101 self.copyButton = self.buttonBox.addButton(
92 self.buttonBox.addButton(self.trUtf8("Copy"), QDialogButtonBox.ActionRole) 102 self.trUtf8("Copy"), QDialogButtonBox.ActionRole)
93 self.copyButton.setToolTip( 103 self.copyButton.setToolTip(
94 self.trUtf8("Copy the regular expression to the clipboard")) 104 self.trUtf8("Copy the regular expression to the clipboard"))
95 self.buttonBox.setStandardButtons(QDialogButtonBox.Close) 105 self.buttonBox.setStandardButtons(QDialogButtonBox.Close)
96 self.variableLabel.hide() 106 self.variableLabel.hide()
97 self.variableLineEdit.hide() 107 self.variableLineEdit.hide()
161 Private slot to handle the named reference toolbutton. 171 Private slot to handle the named reference toolbutton.
162 """ 172 """
163 # determine cursor position as length into text 173 # determine cursor position as length into text
164 length = self.regexpTextEdit.textCursor().position() 174 length = self.regexpTextEdit.textCursor().position()
165 175
166 # only present group names that occur before the current cursor position 176 # only present group names that occur before the
177 # current cursor position
167 regex = self.regexpTextEdit.toPlainText()[:length] 178 regex = self.regexpTextEdit.toPlainText()[:length]
168 names = self.namedGroups(regex) 179 names = self.namedGroups(regex)
169 if not names: 180 if not names:
170 E5MessageBox.information(self, 181 E5MessageBox.information(
182 self,
171 self.trUtf8("Named reference"), 183 self.trUtf8("Named reference"),
172 self.trUtf8("""No named groups have been defined yet.""")) 184 self.trUtf8("""No named groups have been defined yet."""))
173 return 185 return
174 186
175 groupName, ok = QInputDialog.getItem( 187 groupName, ok = QInputDialog.getItem(
257 @pyqtSlot() 269 @pyqtSlot()
258 def on_charButton_clicked(self): 270 def on_charButton_clicked(self):
259 """ 271 """
260 Private slot to handle the characters toolbutton. 272 Private slot to handle the characters toolbutton.
261 """ 273 """
262 from .PyRegExpWizardCharactersDialog import PyRegExpWizardCharactersDialog 274 from .PyRegExpWizardCharactersDialog import \
275 PyRegExpWizardCharactersDialog
263 dlg = PyRegExpWizardCharactersDialog(self) 276 dlg = PyRegExpWizardCharactersDialog(self)
264 if dlg.exec_() == QDialog.Accepted: 277 if dlg.exec_() == QDialog.Accepted:
265 self.__insertString(dlg.getCharacters()) 278 self.__insertString(dlg.getCharacters())
266 279
267 @pyqtSlot() 280 @pyqtSlot()
314 if not ext: 327 if not ext:
315 ex = selectedFilter.split("(*")[1].split(")")[0] 328 ex = selectedFilter.split("(*")[1].split(")")[0]
316 if ex: 329 if ex:
317 fname += ex 330 fname += ex
318 if QFileInfo(fname).exists(): 331 if QFileInfo(fname).exists():
319 res = E5MessageBox.yesNo(self, 332 res = E5MessageBox.yesNo(
333 self,
320 self.trUtf8("Save regular expression"), 334 self.trUtf8("Save regular expression"),
321 self.trUtf8("<p>The file <b>{0}</b> already exists." 335 self.trUtf8("<p>The file <b>{0}</b> already exists."
322 " Overwrite it?</p>").format(fname), 336 " Overwrite it?</p>").format(fname),
323 icon=E5MessageBox.Warning) 337 icon=E5MessageBox.Warning)
324 if not res: 338 if not res:
325 return 339 return
326 340
327 try: 341 try:
328 f = open(Utilities.toNativeSeparators(fname), "w", encoding="utf-8") 342 f = open(
343 Utilities.toNativeSeparators(fname), "w", encoding="utf-8")
329 f.write(self.regexpTextEdit.toPlainText()) 344 f.write(self.regexpTextEdit.toPlainText())
330 f.close() 345 f.close()
331 except IOError as err: 346 except IOError as err:
332 E5MessageBox.information(self, 347 E5MessageBox.information(
348 self,
333 self.trUtf8("Save regular expression"), 349 self.trUtf8("Save regular expression"),
334 self.trUtf8("""<p>The regular expression could not be saved.</p>""" 350 self.trUtf8("""<p>The regular expression could not"""
335 """<p>Reason: {0}</p>""").format(str(err))) 351 """ be saved.</p><p>Reason: {0}</p>""")
352 .format(str(err)))
336 353
337 @pyqtSlot() 354 @pyqtSlot()
338 def on_loadButton_clicked(self): 355 def on_loadButton_clicked(self):
339 """ 356 """
340 Private slot to load a regexp from a file. 357 Private slot to load a regexp from a file.
344 self.trUtf8("Load regular expression"), 361 self.trUtf8("Load regular expression"),
345 "", 362 "",
346 self.trUtf8("RegExp Files (*.rx);;All Files (*)")) 363 self.trUtf8("RegExp Files (*.rx);;All Files (*)"))
347 if fname: 364 if fname:
348 try: 365 try:
349 f = open(Utilities.toNativeSeparators(fname), "r", encoding="utf-8") 366 f = open(
367 Utilities.toNativeSeparators(fname), "r", encoding="utf-8")
350 regexp = f.read() 368 regexp = f.read()
351 f.close() 369 f.close()
352 self.regexpTextEdit.setPlainText(regexp) 370 self.regexpTextEdit.setPlainText(regexp)
353 except IOError as err: 371 except IOError as err:
354 E5MessageBox.information(self, 372 E5MessageBox.information(
373 self,
355 self.trUtf8("Save regular expression"), 374 self.trUtf8("Save regular expression"),
356 self.trUtf8("""<p>The regular expression could not be saved.</p>""" 375 self.trUtf8("""<p>The regular expression could not"""
357 """<p>Reason: {0}</p>""").format(str(err))) 376 """ be saved.</p><p>Reason: {0}</p>""")
377 .format(str(err)))
358 378
359 @pyqtSlot() 379 @pyqtSlot()
360 def on_copyButton_clicked(self): 380 def on_copyButton_clicked(self):
361 """ 381 """
362 Private slot to copy the regexp string into the clipboard. 382 Private slot to copy the regexp string into the clipboard.
395 flags |= re.UNICODE 415 flags |= re.UNICODE
396 else: 416 else:
397 if self.unicodeCheckBox.isChecked(): 417 if self.unicodeCheckBox.isChecked():
398 flags |= re.ASCII 418 flags |= re.ASCII
399 re.compile(regex, flags) 419 re.compile(regex, flags)
400 E5MessageBox.information(self, 420 E5MessageBox.information(
421 self,
401 self.trUtf8("Validation"), 422 self.trUtf8("Validation"),
402 self.trUtf8("""The regular expression is valid.""")) 423 self.trUtf8("""The regular expression is valid."""))
403 except re.error as e: 424 except re.error as e:
404 E5MessageBox.critical(self, 425 E5MessageBox.critical(
426 self,
405 self.trUtf8("Error"), 427 self.trUtf8("Error"),
406 self.trUtf8("""Invalid regular expression: {0}""") 428 self.trUtf8("""Invalid regular expression: {0}""")
407 .format(str(e))) 429 .format(str(e)))
408 return 430 return
409 except IndexError: 431 except IndexError:
410 E5MessageBox.critical(self, 432 E5MessageBox.critical(
433 self,
411 self.trUtf8("Error"), 434 self.trUtf8("Error"),
412 self.trUtf8("""Invalid regular expression: missing group name""")) 435 self.trUtf8("""Invalid regular expression: missing"""
436 """ group name"""))
413 return 437 return
414 else: 438 else:
415 E5MessageBox.critical(self, 439 E5MessageBox.critical(
440 self,
416 self.trUtf8("Error"), 441 self.trUtf8("Error"),
417 self.trUtf8("""A regular expression must be given.""")) 442 self.trUtf8("""A regular expression must be given."""))
418 443
419 @pyqtSlot() 444 @pyqtSlot()
420 def on_executeButton_clicked(self, startpos=0): 445 def on_executeButton_clicked(self, startpos=0):
460 485
461 self.resultTable.setColumnCount(0) 486 self.resultTable.setColumnCount(0)
462 self.resultTable.setColumnCount(3) 487 self.resultTable.setColumnCount(3)
463 self.resultTable.setRowCount(0) 488 self.resultTable.setRowCount(0)
464 self.resultTable.setRowCount(OFFSET) 489 self.resultTable.setRowCount(OFFSET)
465 self.resultTable.setItem(row, 0, QTableWidgetItem(self.trUtf8("Regexp"))) 490 self.resultTable.setItem(
466 self.resultTable.setItem(row, 1, QTableWidgetItem(regex)) 491 row, 0, QTableWidgetItem(self.trUtf8("Regexp")))
492 self.resultTable.setItem(
493 row, 1, QTableWidgetItem(regex))
467 494
468 if matchobj is not None: 495 if matchobj is not None:
469 offset = matchobj.start() 496 offset = matchobj.start()
470 self.lastMatchEnd = matchobj.end() 497 self.lastMatchEnd = matchobj.end()
471 self.nextButton.setEnabled(True) 498 self.nextButton.setEnabled(True)
472 row += 1 499 row += 1
473 self.resultTable.setItem(row, 0, 500 self.resultTable.setItem(
501 row, 0,
474 QTableWidgetItem(self.trUtf8("Offset"))) 502 QTableWidgetItem(self.trUtf8("Offset")))
475 self.resultTable.setItem(row, 1, 503 self.resultTable.setItem(
504 row, 1,
476 QTableWidgetItem("{0:d}".format(matchobj.start(0)))) 505 QTableWidgetItem("{0:d}".format(matchobj.start(0))))
477 506
478 row += 1 507 row += 1
479 self.resultTable.setItem(row, 0, 508 self.resultTable.setItem(
509 row, 0,
480 QTableWidgetItem(self.trUtf8("Captures"))) 510 QTableWidgetItem(self.trUtf8("Captures")))
481 self.resultTable.setItem(row, 1, 511 self.resultTable.setItem(
512 row, 1,
482 QTableWidgetItem("{0:d}".format(captures))) 513 QTableWidgetItem("{0:d}".format(captures)))
483 row += 1 514 row += 1
484 self.resultTable.setItem(row, 1, 515 self.resultTable.setItem(
516 row, 1,
485 QTableWidgetItem(self.trUtf8("Text"))) 517 QTableWidgetItem(self.trUtf8("Text")))
486 self.resultTable.setItem(row, 2, 518 self.resultTable.setItem(
519 row, 2,
487 QTableWidgetItem(self.trUtf8("Characters"))) 520 QTableWidgetItem(self.trUtf8("Characters")))
488 521
489 row += 1 522 row += 1
490 self.resultTable.setItem(row, 0, 523 self.resultTable.setItem(
524 row, 0,
491 QTableWidgetItem(self.trUtf8("Match"))) 525 QTableWidgetItem(self.trUtf8("Match")))
492 self.resultTable.setItem(row, 1, 526 self.resultTable.setItem(
527 row, 1,
493 QTableWidgetItem(matchobj.group(0))) 528 QTableWidgetItem(matchobj.group(0)))
494 self.resultTable.setItem(row, 2, 529 self.resultTable.setItem(
495 QTableWidgetItem("{0:d}".format(len(matchobj.group(0))))) 530 row, 2,
531 QTableWidgetItem(
532 "{0:d}".format(len(matchobj.group(0)))))
496 533
497 for i in range(1, captures + 1): 534 for i in range(1, captures + 1):
498 if matchobj.group(i) is not None: 535 if matchobj.group(i) is not None:
499 row += 1 536 row += 1
500 self.resultTable.insertRow(row) 537 self.resultTable.insertRow(row)
501 self.resultTable.setItem(row, 0, 538 self.resultTable.setItem(
502 QTableWidgetItem(self.trUtf8("Capture #{0}").format(i))) 539 row, 0,
503 self.resultTable.setItem(row, 1, 540 QTableWidgetItem(
504 QTableWidgetItem(matchobj.group(i))) 541 self.trUtf8("Capture #{0}").format(i)))
505 self.resultTable.setItem(row, 2, 542 self.resultTable.setItem(
506 QTableWidgetItem("{0:d}".format(len(matchobj.group(i))))) 543 row, 1, QTableWidgetItem(matchobj.group(i)))
544 self.resultTable.setItem(
545 row, 2, QTableWidgetItem(
546 "{0:d}".format(len(matchobj.group(i)))))
507 547
508 # highlight the matched text 548 # highlight the matched text
509 tc = self.textTextEdit.textCursor() 549 tc = self.textTextEdit.textCursor()
510 tc.setPosition(offset) 550 tc.setPosition(offset)
511 tc.setPosition(self.lastMatchEnd, QTextCursor.KeepAnchor) 551 tc.setPosition(self.lastMatchEnd, QTextCursor.KeepAnchor)
513 else: 553 else:
514 self.nextButton.setEnabled(False) 554 self.nextButton.setEnabled(False)
515 self.resultTable.setRowCount(2) 555 self.resultTable.setRowCount(2)
516 row += 1 556 row += 1
517 if startpos > 0: 557 if startpos > 0:
518 self.resultTable.setItem(row, 0, 558 self.resultTable.setItem(
559 row, 0,
519 QTableWidgetItem(self.trUtf8("No more matches"))) 560 QTableWidgetItem(self.trUtf8("No more matches")))
520 else: 561 else:
521 self.resultTable.setItem(row, 0, 562 self.resultTable.setItem(
563 row, 0,
522 QTableWidgetItem(self.trUtf8("No matches"))) 564 QTableWidgetItem(self.trUtf8("No matches")))
523 565
524 # remove the highlight 566 # remove the highlight
525 tc = self.textTextEdit.textCursor() 567 tc = self.textTextEdit.textCursor()
526 tc.setPosition(0) 568 tc.setPosition(0)
529 self.resultTable.resizeColumnsToContents() 571 self.resultTable.resizeColumnsToContents()
530 self.resultTable.resizeRowsToContents() 572 self.resultTable.resizeRowsToContents()
531 self.resultTable.verticalHeader().hide() 573 self.resultTable.verticalHeader().hide()
532 self.resultTable.horizontalHeader().hide() 574 self.resultTable.horizontalHeader().hide()
533 except re.error as e: 575 except re.error as e:
534 E5MessageBox.critical(self, 576 E5MessageBox.critical(
577 self,
535 self.trUtf8("Error"), 578 self.trUtf8("Error"),
536 self.trUtf8("""Invalid regular expression: {0}""") 579 self.trUtf8("""Invalid regular expression: {0}""")
537 .format(str(e))) 580 .format(str(e)))
538 return 581 return
539 except IndexError: 582 except IndexError:
540 E5MessageBox.critical(self, 583 E5MessageBox.critical(
584 self,
541 self.trUtf8("Error"), 585 self.trUtf8("Error"),
542 self.trUtf8("""Invalid regular expression: missing group name""")) 586 self.trUtf8("""Invalid regular expression: missing"""
587 """ group name"""))
543 return 588 return
544 else: 589 else:
545 E5MessageBox.critical(self, 590 E5MessageBox.critical(
591 self,
546 self.trUtf8("Error"), 592 self.trUtf8("Error"),
547 self.trUtf8("""A regular expression and a text must be given.""")) 593 self.trUtf8("""A regular expression and a text must be"""
594 """ given."""))
548 595
549 @pyqtSlot() 596 @pyqtSlot()
550 def on_nextButton_clicked(self): 597 def on_nextButton_clicked(self):
551 """ 598 """
552 Private slot to find the next match. 599 Private slot to find the next match.
687 self.cw = PyRegExpWizardWidget(self, fromEric=False) 734 self.cw = PyRegExpWizardWidget(self, fromEric=False)
688 size = self.cw.size() 735 size = self.cw.size()
689 self.setCentralWidget(self.cw) 736 self.setCentralWidget(self.cw)
690 self.resize(size) 737 self.resize(size)
691 738
692 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) 739 self.setStyle(
740 Preferences.getUI("Style"), Preferences.getUI("StyleSheet"))
693 741
694 self.cw.buttonBox.accepted[()].connect(self.close) 742 self.cw.buttonBox.accepted[()].connect(self.close)
695 self.cw.buttonBox.rejected[()].connect(self.close) 743 self.cw.buttonBox.rejected[()].connect(self.close)

eric ide

mercurial