|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2004 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a dialog for entering character classes. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 from PyQt5.QtCore import QRegExp |
|
13 from PyQt5.QtGui import QRegExpValidator |
|
14 from PyQt5.QtWidgets import QSizePolicy, QSpacerItem, QWidget, QHBoxLayout, \ |
|
15 QLineEdit, QPushButton, QDialog, QScrollArea, QComboBox, QVBoxLayout, \ |
|
16 QLabel |
|
17 |
|
18 from .Ui_QRegExpWizardCharactersDialog import Ui_QRegExpWizardCharactersDialog |
|
19 |
|
20 |
|
21 class QRegExpWizardCharactersDialog(QDialog, Ui_QRegExpWizardCharactersDialog): |
|
22 """ |
|
23 Class implementing a dialog for entering character classes. |
|
24 """ |
|
25 RegExpMode = 0 |
|
26 WildcardMode = 1 |
|
27 W3CMode = 2 |
|
28 |
|
29 def __init__(self, mode=RegExpMode, parent=None): |
|
30 """ |
|
31 Constructor |
|
32 |
|
33 @param mode mode of the dialog (one of RegExpMode, WildcardMode, |
|
34 W3CMode) |
|
35 @param parent parent widget (QWidget) |
|
36 """ |
|
37 super(QRegExpWizardCharactersDialog, self).__init__(parent) |
|
38 self.setupUi(self) |
|
39 |
|
40 self.__mode = mode |
|
41 |
|
42 if mode == QRegExpWizardCharactersDialog.WildcardMode: |
|
43 self.predefinedBox.setEnabled(False) |
|
44 self.predefinedBox.hide() |
|
45 elif mode == QRegExpWizardCharactersDialog.RegExpMode: |
|
46 self.w3cInitialIdentifierCheckBox.hide() |
|
47 self.w3cNonInitialIdentifierCheckBox.hide() |
|
48 self.w3cNmtokenCheckBox.hide() |
|
49 self.w3cNonNmtokenCheckBox.hide() |
|
50 elif mode == QRegExpWizardCharactersDialog.W3CMode: |
|
51 self.__initCharacterSelectors() |
|
52 |
|
53 self.comboItems = [] |
|
54 self.singleComboItems = [] # these are in addition to the above |
|
55 self.comboItems.append((self.tr("Normal character"), "-c")) |
|
56 if mode == QRegExpWizardCharactersDialog.RegExpMode: |
|
57 self.comboItems.append((self.tr( |
|
58 "Unicode character in hexadecimal notation"), "-h")) |
|
59 self.comboItems.append((self.tr( |
|
60 "ASCII/Latin1 character in octal notation"), "-o")) |
|
61 self.singleComboItems.append(("---", "-i")) |
|
62 self.singleComboItems.append( |
|
63 (self.tr("Bell character (\\a)"), "\\a")) |
|
64 self.singleComboItems.append( |
|
65 (self.tr("Page break (\\f)"), "\\f")) |
|
66 self.singleComboItems.append( |
|
67 (self.tr("Line feed (\\n)"), "\\n")) |
|
68 self.singleComboItems.append( |
|
69 (self.tr("Carriage return (\\r)"), "\\r")) |
|
70 self.singleComboItems.append( |
|
71 (self.tr("Horizontal tabulator (\\t)"), "\\t")) |
|
72 self.singleComboItems.append( |
|
73 (self.tr("Vertical tabulator (\\v)"), "\\v")) |
|
74 elif mode == QRegExpWizardCharactersDialog.W3CMode: |
|
75 self.comboItems.append((self.tr( |
|
76 "Unicode character in hexadecimal notation"), "-h")) |
|
77 self.comboItems.append((self.tr( |
|
78 "ASCII/Latin1 character in octal notation"), "-o")) |
|
79 self.singleComboItems.append(("---", "-i")) |
|
80 self.singleComboItems.append( |
|
81 (self.tr("Line feed (\\n)"), "\\n")) |
|
82 self.singleComboItems.append( |
|
83 (self.tr("Carriage return (\\r)"), "\\r")) |
|
84 self.singleComboItems.append( |
|
85 (self.tr("Horizontal tabulator (\\t)"), "\\t")) |
|
86 self.singleComboItems.append(("---", "-i")) |
|
87 self.singleComboItems.append( |
|
88 (self.tr("Character Category"), "-ccp")) |
|
89 self.singleComboItems.append( |
|
90 (self.tr("Character Block"), "-cbp")) |
|
91 self.singleComboItems.append( |
|
92 (self.tr("Not Character Category"), "-ccn")) |
|
93 self.singleComboItems.append( |
|
94 (self.tr("Not Character Block"), "-cbn")) |
|
95 |
|
96 self.charValidator = QRegExpValidator(QRegExp(".{0,1}"), self) |
|
97 self.hexValidator = QRegExpValidator(QRegExp("[0-9a-fA-F]{0,4}"), self) |
|
98 self.octValidator = QRegExpValidator(QRegExp("[0-3]?[0-7]{0,2}"), self) |
|
99 |
|
100 # generate dialog part for single characters |
|
101 self.singlesBoxLayout = QVBoxLayout(self.singlesBox) |
|
102 self.singlesBoxLayout.setObjectName("singlesBoxLayout") |
|
103 self.singlesBoxLayout.setSpacing(6) |
|
104 self.singlesBoxLayout.setContentsMargins(6, 6, 6, 6) |
|
105 self.singlesBox.setLayout(self.singlesBoxLayout) |
|
106 self.singlesView = QScrollArea(self.singlesBox) |
|
107 self.singlesView.setObjectName("singlesView") |
|
108 self.singlesBoxLayout.addWidget(self.singlesView) |
|
109 |
|
110 self.singlesItemsBox = QWidget(self) |
|
111 self.singlesView.setWidget(self.singlesItemsBox) |
|
112 self.singlesItemsBox.setObjectName("singlesItemsBox") |
|
113 self.singlesItemsBox.setMinimumWidth(1000) |
|
114 self.singlesItemsBoxLayout = QVBoxLayout(self.singlesItemsBox) |
|
115 self.singlesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) |
|
116 self.singlesItemsBoxLayout.setSpacing(6) |
|
117 self.singlesItemsBox.setLayout(self.singlesItemsBoxLayout) |
|
118 self.singlesEntries = [] |
|
119 self.__addSinglesLine() |
|
120 |
|
121 hlayout0 = QHBoxLayout() |
|
122 hlayout0.setContentsMargins(0, 0, 0, 0) |
|
123 hlayout0.setSpacing(6) |
|
124 hlayout0.setObjectName("hlayout0") |
|
125 self.moreSinglesButton = QPushButton( |
|
126 self.tr("Additional Entries"), self.singlesBox) |
|
127 self.moreSinglesButton.setObjectName("moreSinglesButton") |
|
128 hlayout0.addWidget(self.moreSinglesButton) |
|
129 hspacer0 = QSpacerItem( |
|
130 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) |
|
131 hlayout0.addItem(hspacer0) |
|
132 self.singlesBoxLayout.addLayout(hlayout0) |
|
133 self.moreSinglesButton.clicked.connect(self.__addSinglesLine) |
|
134 |
|
135 # generate dialog part for character ranges |
|
136 self.rangesBoxLayout = QVBoxLayout(self.rangesBox) |
|
137 self.rangesBoxLayout.setObjectName("rangesBoxLayout") |
|
138 self.rangesBoxLayout.setSpacing(6) |
|
139 self.rangesBoxLayout.setContentsMargins(6, 6, 6, 6) |
|
140 self.rangesBox.setLayout(self.rangesBoxLayout) |
|
141 self.rangesView = QScrollArea(self.rangesBox) |
|
142 self.rangesView.setObjectName("rangesView") |
|
143 self.rangesBoxLayout.addWidget(self.rangesView) |
|
144 |
|
145 self.rangesItemsBox = QWidget(self) |
|
146 self.rangesView.setWidget(self.rangesItemsBox) |
|
147 self.rangesItemsBox.setObjectName("rangesItemsBox") |
|
148 self.rangesItemsBox.setMinimumWidth(1000) |
|
149 self.rangesItemsBoxLayout = QVBoxLayout(self.rangesItemsBox) |
|
150 self.rangesItemsBoxLayout.setContentsMargins(6, 6, 6, 6) |
|
151 self.rangesItemsBoxLayout.setSpacing(6) |
|
152 self.rangesItemsBox.setLayout(self.rangesItemsBoxLayout) |
|
153 self.rangesEntries = [] |
|
154 self.__addRangesLine() |
|
155 |
|
156 hlayout1 = QHBoxLayout() |
|
157 hlayout1.setContentsMargins(0, 0, 0, 0) |
|
158 hlayout1.setSpacing(6) |
|
159 hlayout1.setObjectName("hlayout1") |
|
160 self.moreRangesButton = QPushButton( |
|
161 self.tr("Additional Entries"), self.rangesBox) |
|
162 self.moreSinglesButton.setObjectName("moreRangesButton") |
|
163 hlayout1.addWidget(self.moreRangesButton) |
|
164 hspacer1 = QSpacerItem( |
|
165 30, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) |
|
166 hlayout1.addItem(hspacer1) |
|
167 self.rangesBoxLayout.addLayout(hlayout1) |
|
168 self.moreRangesButton.clicked.connect(self.__addRangesLine) |
|
169 |
|
170 def __initCharacterSelectors(self): |
|
171 """ |
|
172 Private method to initialize the W3C character selector entries. |
|
173 """ |
|
174 self.__characterCategories = ( |
|
175 # display name code |
|
176 (self.tr("Letter, Any"), "L"), |
|
177 (self.tr("Letter, Uppercase"), "Lu"), |
|
178 (self.tr("Letter, Lowercase"), "Ll"), |
|
179 (self.tr("Letter, Titlecase"), "Lt"), |
|
180 (self.tr("Letter, Modifier"), "Lm"), |
|
181 (self.tr("Letter, Other"), "Lo"), |
|
182 (self.tr("Mark, Any"), "M"), |
|
183 (self.tr("Mark, Nonspacing"), "Mn"), |
|
184 (self.tr("Mark, Spacing Combining"), "Mc"), |
|
185 (self.tr("Mark, Enclosing"), "Me"), |
|
186 (self.tr("Number, Any"), "N"), |
|
187 (self.tr("Number, Decimal Digit"), "Nd"), |
|
188 (self.tr("Number, Letter"), "Nl"), |
|
189 (self.tr("Number, Other"), "No"), |
|
190 (self.tr("Punctuation, Any"), "P"), |
|
191 (self.tr("Punctuation, Connector"), "Pc"), |
|
192 (self.tr("Punctuation, Dash"), "Pd"), |
|
193 (self.tr("Punctuation, Open"), "Ps"), |
|
194 (self.tr("Punctuation, Close"), "Pe"), |
|
195 (self.tr("Punctuation, Initial Quote"), "Pi"), |
|
196 (self.tr("Punctuation, Final Quote"), "Pf"), |
|
197 (self.tr("Punctuation, Other"), "Po"), |
|
198 (self.tr("Symbol, Any"), "S"), |
|
199 (self.tr("Symbol, Math"), "Sm"), |
|
200 (self.tr("Symbol, Currency"), "Sc"), |
|
201 (self.tr("Symbol, Modifier"), "Sk"), |
|
202 (self.tr("Symbol, Other"), "So"), |
|
203 (self.tr("Separator, Any"), "Z"), |
|
204 (self.tr("Separator, Space"), "Zs"), |
|
205 (self.tr("Separator, Line"), "Zl"), |
|
206 (self.tr("Separator, Paragraph"), "Zp"), |
|
207 (self.tr("Other, Any"), "C"), |
|
208 (self.tr("Other, Control"), "Cc"), |
|
209 (self.tr("Other, Format"), "Cf"), |
|
210 (self.tr("Other, Private Use"), "Co"), |
|
211 (self.tr("Other, Not Assigned"), "Cn"), |
|
212 ) |
|
213 |
|
214 self.__characterBlocks = ( |
|
215 (self.tr("Basic Latin"), |
|
216 "IsBasicLatin"), |
|
217 (self.tr("Latin-1 Supplement"), |
|
218 "IsLatin-1Supplement"), |
|
219 (self.tr("Latin Extended-A"), |
|
220 "IsLatinExtended-A"), |
|
221 (self.tr("Latin Extended-B"), |
|
222 "IsLatinExtended-B"), |
|
223 (self.tr("IPA Extensions"), |
|
224 "IsIPAExtensions"), |
|
225 (self.tr("Spacing Modifier Letters"), |
|
226 "IsSpacingModifierLetters"), |
|
227 (self.tr("Combining Diacritical Marks"), |
|
228 "IsCombiningDiacriticalMarks"), |
|
229 (self.tr("Greek"), |
|
230 "IsGreek"), |
|
231 (self.tr("Cyrillic"), |
|
232 "IsCyrillic"), |
|
233 (self.tr("Armenian"), |
|
234 "IsArmenian"), |
|
235 (self.tr("Hebrew"), |
|
236 "IsHebrew"), |
|
237 (self.tr("Arabic"), |
|
238 "IsArabic"), |
|
239 (self.tr("Syriac"), |
|
240 "IsSyriac"), |
|
241 (self.tr("Thaana"), |
|
242 "IsThaana"), |
|
243 (self.tr("Devanagari"), |
|
244 "IsDevanagari"), |
|
245 (self.tr("Bengali"), |
|
246 "IsBengali"), |
|
247 (self.tr("Gurmukhi"), |
|
248 "IsBengali"), |
|
249 (self.tr("Gujarati"), |
|
250 "IsGujarati"), |
|
251 (self.tr("Oriya"), |
|
252 "IsOriya"), |
|
253 (self.tr("Tamil"), |
|
254 "IsTamil"), |
|
255 (self.tr("Telugu"), |
|
256 "IsTelugu"), |
|
257 (self.tr("Kannada"), |
|
258 "IsKannada"), |
|
259 (self.tr("Malayalam"), |
|
260 "IsMalayalam"), |
|
261 (self.tr("Sinhala"), |
|
262 "IsSinhala"), |
|
263 (self.tr("Thai"), |
|
264 "IsThai"), |
|
265 (self.tr("Lao"), |
|
266 "IsLao"), |
|
267 (self.tr("Tibetan"), |
|
268 "IsTibetan"), |
|
269 (self.tr("Myanmar"), |
|
270 "IsMyanmar"), |
|
271 (self.tr("Georgian"), |
|
272 "IsGeorgian"), |
|
273 (self.tr("Hangul Jamo"), |
|
274 "IsHangulJamo"), |
|
275 (self.tr("Ethiopic"), |
|
276 "IsEthiopic"), |
|
277 (self.tr("Cherokee"), |
|
278 "IsCherokee"), |
|
279 (self.tr("Unified Canadian Aboriginal Syllabics"), |
|
280 "IsUnifiedCanadianAboriginalSyllabics"), |
|
281 (self.tr("Ogham"), |
|
282 "IsOgham"), |
|
283 (self.tr("Runic"), |
|
284 "IsRunic"), |
|
285 (self.tr("Khmer"), |
|
286 "IsKhmer"), |
|
287 (self.tr("Mongolian"), |
|
288 "IsMongolian"), |
|
289 (self.tr("Latin Extended Additional"), |
|
290 "IsLatinExtendedAdditional"), |
|
291 (self.tr("Greek Extended"), |
|
292 "IsGreekExtended"), |
|
293 (self.tr("General Punctuation"), |
|
294 "IsGeneralPunctuation"), |
|
295 (self.tr("Superscripts and Subscripts"), |
|
296 "IsSuperscriptsandSubscripts"), |
|
297 (self.tr("Currency Symbols"), |
|
298 "IsCurrencySymbols"), |
|
299 (self.tr("Combining Marks for Symbols"), |
|
300 "IsCombiningMarksforSymbols"), |
|
301 (self.tr("Letterlike Symbols"), |
|
302 "IsLetterlikeSymbols"), |
|
303 (self.tr("Number Forms"), |
|
304 "IsNumberForms"), |
|
305 (self.tr("Arrows"), |
|
306 "IsArrows"), |
|
307 (self.tr("Mathematical Operators"), |
|
308 "IsMathematicalOperators"), |
|
309 (self.tr("Miscellaneous Technical"), |
|
310 "IsMiscellaneousTechnical"), |
|
311 (self.tr("Control Pictures"), |
|
312 "IsControlPictures"), |
|
313 (self.tr("Optical Character Recognition"), |
|
314 "IsOpticalCharacterRecognition"), |
|
315 (self.tr("Enclosed Alphanumerics"), |
|
316 "IsEnclosedAlphanumerics"), |
|
317 (self.tr("Box Drawing"), |
|
318 "IsBoxDrawing"), |
|
319 (self.tr("Block Elements"), |
|
320 "IsBlockElements"), |
|
321 (self.tr("Geometric Shapes"), |
|
322 "IsGeometricShapes"), |
|
323 (self.tr("Miscellaneous Symbols"), |
|
324 "IsMiscellaneousSymbols"), |
|
325 (self.tr("Dingbats"), |
|
326 "IsDingbats"), |
|
327 (self.tr("Braille Patterns"), |
|
328 "IsBraillePatterns"), |
|
329 (self.tr("CJK Radicals Supplement"), |
|
330 "IsCJKRadicalsSupplement"), |
|
331 (self.tr("KangXi Radicals"), |
|
332 "IsKangXiRadicals"), |
|
333 (self.tr("Ideographic Description Chars"), |
|
334 "IsIdeographicDescriptionChars"), |
|
335 (self.tr("CJK Symbols and Punctuation"), |
|
336 "IsCJKSymbolsandPunctuation"), |
|
337 (self.tr("Hiragana"), |
|
338 "IsHiragana"), |
|
339 (self.tr("Katakana"), |
|
340 "IsKatakana"), |
|
341 (self.tr("Bopomofo"), |
|
342 "IsBopomofo"), |
|
343 (self.tr("Hangul Compatibility Jamo"), |
|
344 "IsHangulCompatibilityJamo"), |
|
345 (self.tr("Kanbun"), |
|
346 "IsKanbun"), |
|
347 (self.tr("Bopomofo Extended"), |
|
348 "IsBopomofoExtended"), |
|
349 (self.tr("Enclosed CJK Letters and Months"), |
|
350 "IsEnclosedCJKLettersandMonths"), |
|
351 (self.tr("CJK Compatibility"), |
|
352 "IsCJKCompatibility"), |
|
353 (self.tr("CJK Unified Ideographs Extension A"), |
|
354 "IsCJKUnifiedIdeographsExtensionA"), |
|
355 (self.tr("CJK Unified Ideographs"), |
|
356 "IsCJKUnifiedIdeographs"), |
|
357 (self.tr("Yi Syllables"), |
|
358 "IsYiSyllables"), |
|
359 (self.tr("Yi Radicals"), |
|
360 "IsYiRadicals"), |
|
361 (self.tr("Hangul Syllables"), |
|
362 "IsHangulSyllables"), |
|
363 (self.tr("Private Use"), |
|
364 "IsPrivateUse"), |
|
365 (self.tr("CJK Compatibility Ideographs"), |
|
366 "IsCJKCompatibilityIdeographs"), |
|
367 (self.tr("Alphabetic Presentation Forms"), |
|
368 "IsAlphabeticPresentationForms"), |
|
369 (self.tr("Arabic Presentation Forms-A"), |
|
370 "IsArabicPresentationForms-A"), |
|
371 (self.tr("Combining Half Marks"), |
|
372 "IsCombiningHalfMarks"), |
|
373 (self.tr("CJK Compatibility Forms"), |
|
374 "IsCJKCompatibilityForms"), |
|
375 (self.tr("Small Form Variants"), |
|
376 "IsSmallFormVariants"), |
|
377 (self.tr("Arabic Presentation Forms-B"), |
|
378 "IsArabicPresentationForms-B"), |
|
379 (self.tr("Halfwidth and Fullwidth Forms"), |
|
380 "IsHalfwidthandFullwidthForms"), |
|
381 (self.tr("Specials"), |
|
382 "IsSpecials"), |
|
383 (self.tr("Old Italic"), |
|
384 "IsOldItalic"), |
|
385 (self.tr("Gothic"), |
|
386 "IsGothic"), |
|
387 (self.tr("Deseret"), |
|
388 "IsDeseret"), |
|
389 (self.tr("Byzantine Musical Symbols"), |
|
390 "IsByzantineMusicalSymbols"), |
|
391 (self.tr("Musical Symbols"), |
|
392 "IsMusicalSymbols"), |
|
393 (self.tr("Mathematical Alphanumeric Symbols"), |
|
394 "IsMathematicalAlphanumericSymbols"), |
|
395 (self.tr("CJK Unified Ideographic Extension B"), |
|
396 "IsCJKUnifiedIdeographicExtensionB"), |
|
397 (self.tr("CJK Compatapility Ideographic Supplement"), |
|
398 "IsCJKCompatapilityIdeographicSupplement"), |
|
399 (self.tr("Tags"), |
|
400 "IsTags"), |
|
401 ) |
|
402 |
|
403 def __populateCharTypeCombo(self, combo, isSingle): |
|
404 """ |
|
405 Private method to populate a given character type selection combo box. |
|
406 |
|
407 @param combo reference to the combo box to be populated (QComboBox) |
|
408 @param isSingle flag indicating a singles combo (boolean) |
|
409 """ |
|
410 for txt, value in self.comboItems: |
|
411 combo.addItem(txt, value) |
|
412 if isSingle: |
|
413 for txt, value in self.singleComboItems: |
|
414 combo.addItem(txt, value) |
|
415 |
|
416 def __addSinglesLine(self): |
|
417 """ |
|
418 Private slot to add a line of entry widgets for single characters. |
|
419 """ |
|
420 hbox = QWidget(self.singlesItemsBox) |
|
421 hboxLayout = QHBoxLayout(hbox) |
|
422 hboxLayout.setContentsMargins(0, 0, 0, 0) |
|
423 hboxLayout.setSpacing(6) |
|
424 hbox.setLayout(hboxLayout) |
|
425 cb1 = QComboBox(hbox) |
|
426 cb1.setEditable(False) |
|
427 self.__populateCharTypeCombo(cb1, True) |
|
428 hboxLayout.addWidget(cb1) |
|
429 le1 = QLineEdit(hbox) |
|
430 le1.setValidator(self.charValidator) |
|
431 hboxLayout.addWidget(le1) |
|
432 cb1a = QComboBox(hbox) |
|
433 cb1a.setEditable(False) |
|
434 cb1a.setSizeAdjustPolicy(QComboBox.AdjustToContents) |
|
435 hboxLayout.addWidget(cb1a) |
|
436 cb1a.hide() |
|
437 cb2 = QComboBox(hbox) |
|
438 cb2.setEditable(False) |
|
439 self.__populateCharTypeCombo(cb2, True) |
|
440 hboxLayout.addWidget(cb2) |
|
441 le2 = QLineEdit(hbox) |
|
442 le2.setValidator(self.charValidator) |
|
443 hboxLayout.addWidget(le2) |
|
444 cb2a = QComboBox(hbox) |
|
445 cb2a.setEditable(False) |
|
446 cb2a.setSizeAdjustPolicy(QComboBox.AdjustToContents) |
|
447 hboxLayout.addWidget(cb2a) |
|
448 cb2a.hide() |
|
449 self.singlesItemsBoxLayout.addWidget(hbox) |
|
450 |
|
451 cb1.activated[int].connect( |
|
452 lambda i: self.__singlesCharTypeSelected(i, cb1)) |
|
453 cb2.activated[int].connect( |
|
454 lambda i: self.__singlesCharTypeSelected(i, cb2)) |
|
455 hbox.show() |
|
456 |
|
457 self.singlesItemsBox.adjustSize() |
|
458 |
|
459 self.singlesEntries.append([cb1, le1, cb1a]) |
|
460 self.singlesEntries.append([cb2, le2, cb2a]) |
|
461 |
|
462 def __addRangesLine(self): |
|
463 """ |
|
464 Private slot to add a line of entry widgets for character ranges. |
|
465 """ |
|
466 hbox = QWidget(self.rangesItemsBox) |
|
467 hboxLayout = QHBoxLayout(hbox) |
|
468 hboxLayout.setContentsMargins(0, 0, 0, 0) |
|
469 hboxLayout.setSpacing(6) |
|
470 hbox.setLayout(hboxLayout) |
|
471 cb1 = QComboBox(hbox) |
|
472 cb1.setEditable(False) |
|
473 self.__populateCharTypeCombo(cb1, False) |
|
474 hboxLayout.addWidget(cb1) |
|
475 l1 = QLabel(self.tr("Between:"), hbox) |
|
476 hboxLayout.addWidget(l1) |
|
477 le1 = QLineEdit(hbox) |
|
478 le1.setValidator(self.charValidator) |
|
479 hboxLayout.addWidget(le1) |
|
480 l2 = QLabel(self.tr("And:"), hbox) |
|
481 hboxLayout.addWidget(l2) |
|
482 le2 = QLineEdit(hbox) |
|
483 le2.setValidator(self.charValidator) |
|
484 hboxLayout.addWidget(le2) |
|
485 self.rangesItemsBoxLayout.addWidget(hbox) |
|
486 |
|
487 cb1.activated[int].connect( |
|
488 lambda i: self.__rangesCharTypeSelected(i, cb1)) |
|
489 |
|
490 hbox.show() |
|
491 |
|
492 self.rangesItemsBox.adjustSize() |
|
493 |
|
494 self.rangesEntries.append([cb1, le1, le2]) |
|
495 |
|
496 def __populateW3cCharacterCombo(self, combo, formatIdentifier): |
|
497 """ |
|
498 Private method to populate a W3C character selection combo. |
|
499 |
|
500 @param combo combo box to be populated (QComboBox) |
|
501 @param formatIdentifier format identifier (one of "-ccp", "-ccn", |
|
502 "-cbp", "-cbn") |
|
503 """ |
|
504 combo.clear() |
|
505 |
|
506 if formatIdentifier in ["-ccp", "-ccn"]: |
|
507 comboLen = 0 |
|
508 for txt, code in self.__characterCategories: |
|
509 combo.addItem(txt, code) |
|
510 comboLen = max(comboLen, len(txt)) |
|
511 combo.setMinimumContentsLength(comboLen) |
|
512 elif formatIdentifier in ["-cbp", "-cbn"]: |
|
513 comboLen = 0 |
|
514 for txt, code in self.__characterBlocks: |
|
515 combo.addItem(txt, code) |
|
516 comboLen = max(comboLen, len(txt)) |
|
517 combo.setMinimumContentsLength(comboLen) |
|
518 |
|
519 def __performSelectedAction(self, formatIdentifier, lineedit, combo): |
|
520 """ |
|
521 Private method performing some actions depending on the input. |
|
522 |
|
523 @param formatIdentifier format of the selected entry (string) |
|
524 @param lineedit line edit widget to act on (QLineEdit) |
|
525 @param combo combo box widget to act on (QComboBox) |
|
526 """ |
|
527 if formatIdentifier == "-i": |
|
528 return |
|
529 |
|
530 if formatIdentifier in ["-c", "-h", "-o"]: |
|
531 lineedit.show() |
|
532 lineedit.setEnabled(True) |
|
533 if combo is not None: |
|
534 combo.hide() |
|
535 if formatIdentifier == "-c": |
|
536 lineedit.setValidator(self.charValidator) |
|
537 elif formatIdentifier == "-h": |
|
538 lineedit.setValidator(self.hexValidator) |
|
539 elif formatIdentifier == "-o": |
|
540 lineedit.setValidator(self.octValidator) |
|
541 elif formatIdentifier in ["-ccp", "-ccn", "-cbp", "-cbn"]: |
|
542 lineedit.setEnabled(False) |
|
543 lineedit.hide() |
|
544 if combo is not None: |
|
545 combo.show() |
|
546 self.__populateW3cCharacterCombo(combo, formatIdentifier) |
|
547 else: |
|
548 lineedit.setEnabled(False) |
|
549 lineedit.hide() |
|
550 if combo is not None: |
|
551 combo.hide() |
|
552 lineedit.clear() |
|
553 |
|
554 def __singlesCharTypeSelected(self, index, combo): |
|
555 """ |
|
556 Private slot to handle the activated(int) signal of the single chars |
|
557 combo boxes. |
|
558 |
|
559 @param index selected list index |
|
560 @type int |
|
561 @param combo reference to the combo box |
|
562 @type QComboBox |
|
563 """ |
|
564 for entriesList in self.singlesEntries: |
|
565 if combo == entriesList[0]: |
|
566 formatIdentifier = combo.itemData(index) |
|
567 self.__performSelectedAction( |
|
568 formatIdentifier, entriesList[1], entriesList[2]) |
|
569 break |
|
570 |
|
571 def __rangesCharTypeSelected(self, index, combo): |
|
572 """ |
|
573 Private slot to handle the activated(int) signal of the char ranges |
|
574 combo boxes. |
|
575 |
|
576 @param index selected list index |
|
577 @type int |
|
578 @param combo reference to the combo box |
|
579 @type QComboBox |
|
580 """ |
|
581 for entriesList in self.rangesEntries: |
|
582 if combo == entriesList[0]: |
|
583 formatIdentifier = combo.itemData(index) |
|
584 self.__performSelectedAction(formatIdentifier, entriesList[1], |
|
585 None) |
|
586 self.__performSelectedAction(formatIdentifier, entriesList[2], |
|
587 None) |
|
588 break |
|
589 |
|
590 def __formatCharacter(self, char, formatIdentifier): |
|
591 """ |
|
592 Private method to format the characters entered into the dialog. |
|
593 |
|
594 @param char character string entered into the dialog (string) |
|
595 @param formatIdentifier string giving a special format (-c, -h, -i or |
|
596 -o) or the already formatted character (string) |
|
597 @return formatted character string (string) |
|
598 """ |
|
599 if formatIdentifier == "-c": |
|
600 return char |
|
601 elif formatIdentifier == "-i": |
|
602 return "" |
|
603 |
|
604 if self.__mode in [QRegExpWizardCharactersDialog.RegExpMode, |
|
605 QRegExpWizardCharactersDialog.W3CMode]: |
|
606 if formatIdentifier == "-h": |
|
607 return "\\x{0}".format(char.lower()) |
|
608 elif formatIdentifier == "-o": |
|
609 return "\\0{0}".format(char) |
|
610 elif formatIdentifier in ["-ccp", "-cbp"]: |
|
611 return "\\p{{{0}}}".format(char) |
|
612 elif formatIdentifier in ["-ccn", "-cbn"]: |
|
613 return "\\P{{{0}}}".format(char) |
|
614 else: |
|
615 return formatIdentifier |
|
616 |
|
617 return "" |
|
618 |
|
619 def getCharacters(self): |
|
620 """ |
|
621 Public method to return the character string assembled via the dialog. |
|
622 |
|
623 @return formatted string for character classes (string) |
|
624 """ |
|
625 regexp = "" |
|
626 |
|
627 # negative character range |
|
628 if self.negativeCheckBox.isChecked(): |
|
629 regexp += "^" |
|
630 |
|
631 # predefined character ranges |
|
632 if self.wordCharCheckBox.isChecked(): |
|
633 regexp += "\\w" |
|
634 if self.nonWordCharCheckBox.isChecked(): |
|
635 regexp += "\\W" |
|
636 if self.digitsCheckBox.isChecked(): |
|
637 regexp += "\\d" |
|
638 if self.nonDigitsCheckBox.isChecked(): |
|
639 regexp += "\\D" |
|
640 if self.whitespaceCheckBox.isChecked(): |
|
641 regexp += "\\s" |
|
642 if self.nonWhitespaceCheckBox.isChecked(): |
|
643 regexp += "\\S" |
|
644 if self.w3cInitialIdentifierCheckBox.isChecked(): |
|
645 regexp += "\\i" |
|
646 if self.w3cNonInitialIdentifierCheckBox.isChecked(): |
|
647 regexp += "\\I" |
|
648 if self.w3cNmtokenCheckBox.isChecked(): |
|
649 regexp += "\\c" |
|
650 if self.w3cNonNmtokenCheckBox.isChecked(): |
|
651 regexp += "\\C" |
|
652 |
|
653 # single characters |
|
654 for entrieslist in self.singlesEntries: |
|
655 formatIdentifier = entrieslist[0].itemData( |
|
656 entrieslist[0].currentIndex()) |
|
657 if formatIdentifier in ["-ccp", "-ccn", "-cbp", "-cbn"]: |
|
658 char = entrieslist[2].itemData(entrieslist[2].currentIndex()) |
|
659 else: |
|
660 char = entrieslist[1].text() |
|
661 regexp += self.__formatCharacter(char, formatIdentifier) |
|
662 |
|
663 # character ranges |
|
664 for entrieslist in self.rangesEntries: |
|
665 if not entrieslist[1].text() or \ |
|
666 not entrieslist[2].text(): |
|
667 continue |
|
668 formatIdentifier = entrieslist[0].itemData( |
|
669 entrieslist[0].currentIndex()) |
|
670 char1 = entrieslist[1].text() |
|
671 char2 = entrieslist[2].text() |
|
672 regexp += "{0}-{1}".format( |
|
673 self.__formatCharacter(char1, formatIdentifier), |
|
674 self.__formatCharacter(char2, formatIdentifier)) |
|
675 |
|
676 if regexp: |
|
677 if (regexp.startswith("\\") and |
|
678 regexp.count("\\") == 1 and |
|
679 "-" not in regexp) or \ |
|
680 len(regexp) == 1: |
|
681 return regexp |
|
682 else: |
|
683 return "[{0}]".format(regexp) |
|
684 else: |
|
685 return "" |