81 @type QWidget (optional) |
82 @type QWidget (optional) |
82 """ |
83 """ |
83 super().__init__(parent) |
84 super().__init__(parent) |
84 self.setupUi(self) |
85 self.setupUi(self) |
85 |
86 |
|
87 self.__project = project |
|
88 |
86 self.layout().setContentsMargins(0, 3, 0, 0) |
89 self.layout().setContentsMargins(0, 3, 0, 0) |
87 |
90 |
88 self.caseToolButton.setIcon(EricPixmapCache.getIcon("caseSensitive")) |
91 self.caseToolButton.setIcon(EricPixmapCache.getIcon("caseSensitive")) |
89 self.wordToolButton.setIcon(EricPixmapCache.getIcon("wholeWord")) |
92 self.wordToolButton.setIcon(EricPixmapCache.getIcon("wholeWord")) |
90 self.escapeToolButton.setIcon(EricPixmapCache.getIcon("esc-code")) |
93 self.escapeToolButton.setIcon(EricPixmapCache.getIcon("esc-code")) |
91 self.regexpToolButton.setIcon(EricPixmapCache.getIcon("regexp")) |
94 self.regexpToolButton.setIcon(EricPixmapCache.getIcon("regexp")) |
|
95 self.filtersConfigButton.setIcon(EricPixmapCache.getIcon("edit")) |
92 |
96 |
93 self.dirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
97 self.dirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
94 self.dirPicker.setInsertPolicy(QComboBox.InsertPolicy.InsertAtTop) |
98 self.dirPicker.setInsertPolicy(QComboBox.InsertPolicy.InsertAtTop) |
95 self.dirPicker.setSizeAdjustPolicy( |
99 self.dirPicker.setSizeAdjustPolicy( |
96 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon |
100 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon |
146 Preferences.toBool( |
150 Preferences.toBool( |
147 Preferences.getSettings().value("FindFileWidget/ExcludeHidden", True) |
151 Preferences.getSettings().value("FindFileWidget/ExcludeHidden", True) |
148 ) |
152 ) |
149 ) |
153 ) |
150 |
154 |
151 self.__project = project |
155 self.__populateFiltersSelector() |
152 |
|
153 self.populateFileCategories() |
156 self.populateFileCategories() |
154 |
157 |
155 # ensure the file type tab is the current one |
158 # ensure the file type tab is the current one |
156 self.fileOptionsWidget.setCurrentWidget(self.fileTypeTab) |
159 self.fileOptionsWidget.setCurrentWidget(self.fileTypeTab) |
157 |
160 |
171 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) |
174 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) |
172 self.customContextMenuRequested.connect(self.__contextMenuRequested) |
175 self.customContextMenuRequested.connect(self.__contextMenuRequested) |
173 |
176 |
174 self.__replaceMode = True |
177 self.__replaceMode = True |
175 self.__toggleReplaceMode() |
178 self.__toggleReplaceMode() |
|
179 |
|
180 def __populateFiltersSelector(self): |
|
181 """ |
|
182 Private method to (re-)populate the file filters selector. |
|
183 """ |
|
184 currentFilter = self.filterComboBox.currentText() |
|
185 self.filterComboBox.clear() |
|
186 |
|
187 # add standard entries |
|
188 self.filterComboBox.addItem("") |
|
189 self.filterComboBox.addItem(self.tr("All Files"), "*") |
|
190 |
|
191 # add configured entries |
|
192 # filters is a dictionary with the filter text as key and the pattern as value |
|
193 self.__filters = json.loads( |
|
194 Preferences.getSettings().value("FindFileWidget/FileFilters", "{}") |
|
195 # noqa: M613 |
|
196 ) |
|
197 for fileFilter in sorted(self.__filters): |
|
198 self.filterComboBox.addItem(fileFilter, self.__filters[filter]) |
|
199 |
|
200 # reselect the current entry |
|
201 index = self.filterComboBox.findText(currentFilter) |
|
202 if index == -1: |
|
203 index = 0 |
|
204 self.filterComboBox.setCurrentIndex(index) |
176 |
205 |
177 def populateFileCategories(self): |
206 def populateFileCategories(self): |
178 """ |
207 """ |
179 Public method to populate the search file categories list. |
208 Public method to populate the search file categories list. |
180 """ |
209 """ |
368 """ |
397 """ |
369 if checked: |
398 if checked: |
370 # only one of regexp or escape can be selected |
399 # only one of regexp or escape can be selected |
371 self.escapeToolButton.setChecked(False) |
400 self.escapeToolButton.setChecked(False) |
372 |
401 |
|
402 @pyqtSlot() |
|
403 def on_filtersConfigButton_clicked(self): |
|
404 """ |
|
405 Private slot to edit the list of defined file filter entries. |
|
406 """ |
|
407 from .FindFileFiltersEditDialog import FindFileFiltersEditDialog |
|
408 |
|
409 dlg = FindFileFiltersEditDialog(self.__filters, self) |
|
410 if dlg.exec() == QDialog.DialogCode.Accepted: |
|
411 filters = dlg.getFilters() |
|
412 Preferences.getSettings().setValue( |
|
413 "FindFileWidget/FileFilters", json.dumps(filters) |
|
414 ) |
|
415 self.__populateFiltersSelector() |
|
416 |
373 @pyqtSlot(str) |
417 @pyqtSlot(str) |
374 def on_findtextCombo_editTextChanged(self, text): |
418 def on_findtextCombo_editTextChanged(self, text): |
375 """ |
419 """ |
376 Private slot to handle the editTextChanged signal of the find |
420 Private slot to handle the editTextChanged signal of the find |
377 text combo. |
421 text combo. |
429 """ |
473 """ |
430 Private slot to handle the selection of the file filter check box. |
474 Private slot to handle the selection of the file filter check box. |
431 """ |
475 """ |
432 self.__enableFindButton() |
476 self.__enableFindButton() |
433 |
477 |
434 @pyqtSlot(str) |
478 @pyqtSlot(int) |
435 def on_filterEdit_textEdited(self, text): |
479 def on_filterComboBox_currentIndexChanged(self, index): |
436 """ |
480 """ |
437 Private slot to handle the textChanged signal of the file filter edit. |
481 Private slot to handle the selection of a file filter. |
438 |
482 |
439 @param text (ignored) |
483 @param index index of the selected entry |
440 @type str |
484 @type int |
441 """ |
485 """ |
442 self.__enableFindButton() |
486 self.__enableFindButton() |
443 |
487 |
444 @pyqtSlot() |
488 @pyqtSlot() |
445 def __enableFindButton(self): |
489 def __enableFindButton(self): |
453 and ( |
497 and ( |
454 self.dirPicker.currentText() == "" |
498 self.dirPicker.currentText() == "" |
455 or not os.path.exists(os.path.abspath(self.dirPicker.currentText())) |
499 or not os.path.exists(os.path.abspath(self.dirPicker.currentText())) |
456 ) |
500 ) |
457 ) |
501 ) |
458 or (self.filterCheckBox.isChecked() and self.filterEdit.text() == "") |
502 or ( |
|
503 self.filterCheckBox.isChecked() |
|
504 and self.filterComboBox.currentText() == "" |
|
505 ) |
|
506 or (self.projectButton.isChecked() and not self.__project.isOpen()) |
459 ): |
507 ): |
460 self.findButton.setEnabled(False) |
508 self.findButton.setEnabled(False) |
461 else: |
509 else: |
462 self.findButton.setEnabled(True) |
510 self.findButton.setEnabled(True) |
463 |
511 |
469 @type str |
517 @type str |
470 @return text with eol stripped |
518 @return text with eol stripped |
471 @rtype str |
519 @rtype str |
472 """ |
520 """ |
473 return txt.rstrip("\n\r") |
521 return txt.rstrip("\n\r") |
|
522 |
|
523 def __buildReFileFilter(self, fileFilter): |
|
524 """ |
|
525 Private method to convert a file filter expression into a valid re search |
|
526 pattern. |
|
527 |
|
528 @param fileFilter file filter expression |
|
529 @type str |
|
530 @return re search pattern with dot, question mark and star converted |
|
531 @rtype str |
|
532 """ |
|
533 return "^{0}$".format( |
|
534 fileFilter.strip().replace(".", r"\.").replace("*", ".*").replace("?", ".") |
|
535 ) |
474 |
536 |
475 @pyqtSlot() |
537 @pyqtSlot() |
476 def __stopSearch(self): |
538 def __stopSearch(self): |
477 """ |
539 """ |
478 Private slot to handle the stop button being pressed. |
540 Private slot to handle the stop button being pressed. |
491 return |
553 return |
492 |
554 |
493 self.__cancelSearch = False |
555 self.__cancelSearch = False |
494 |
556 |
495 if self.filterCheckBox.isChecked(): |
557 if self.filterCheckBox.isChecked(): |
496 fileFilter = self.filterEdit.text() |
558 fileFilter = self.filterComboBox.currentData() |
497 fileFilterList = [ |
559 fileFilterList = [ |
498 "^{0}$".format(filter.replace(".", r"\.").replace("*", ".*")) |
560 self.__buildReFileFilter(filter) for filter in fileFilter.split(";") |
499 for filter in fileFilter.split(";") |
|
500 ] |
561 ] |
501 filterRe = re.compile("|".join(fileFilterList)) |
562 filterRe = re.compile("|".join(fileFilterList)) |
502 |
563 |
503 if self.projectButton.isChecked(): |
564 if self.projectButton.isChecked(): |
504 if self.filterCheckBox.isChecked(): |
565 if self.filterCheckBox.isChecked(): |
527 for row in range(self.fileTypeList.count()): |
588 for row in range(self.fileTypeList.count()): |
528 itm = self.fileTypeList.item(row) |
589 itm = self.fileTypeList.item(row) |
529 if itm.checkState() == Qt.CheckState.Checked: |
590 if itm.checkState() == Qt.CheckState.Checked: |
530 filters.extend( |
591 filters.extend( |
531 [ |
592 [ |
532 "^{0}$".format( |
593 self.__buildReFileFilter(assoc) |
533 assoc.replace(".", r"\.").replace("*", ".*") |
|
534 ) |
|
535 for assoc in self.__project.getFiletypeAssociations( |
594 for assoc in self.__project.getFiletypeAssociations( |
536 itm.data(Qt.ItemDataRole.UserRole) |
595 itm.data(Qt.ItemDataRole.UserRole) |
537 ) |
596 ) |
538 ] |
597 ] |
539 ) |
598 ) |
543 if itm.checkState() == Qt.CheckState.Checked: |
602 if itm.checkState() == Qt.CheckState.Checked: |
544 fileType = itm.data(Qt.ItemDataRole.UserRole) |
603 fileType = itm.data(Qt.ItemDataRole.UserRole) |
545 if fileType == "SOURCES": |
604 if fileType == "SOURCES": |
546 filters.extend( |
605 filters.extend( |
547 [ |
606 [ |
548 "^{0}$".format( |
607 self.__buildReFileFilter(assoc) |
549 assoc.replace(".", r"\.").replace("*", ".*") |
|
550 ) |
|
551 for assoc in Preferences.getEditorLexerAssocs() |
608 for assoc in Preferences.getEditorLexerAssocs() |
552 if assoc |
609 if assoc |
553 not in self.__project.getFileCategoryExtension( |
610 not in self.__project.getFileCategoryExtension( |
554 fileType, reverse=True |
611 fileType, reverse=True |
555 ) |
612 ) |
556 ] |
613 ] |
557 ) |
614 ) |
558 else: |
615 else: |
559 filters.extend( |
616 filters.extend( |
560 [ |
617 [ |
561 "^{0}$".format( |
618 self.__buildReFileFilter(ext) |
562 ext.replace(".", r"\.").replace("*", ".*") |
|
563 ) |
|
564 for ext in self.__project.getFileCategoryExtension( |
619 for ext in self.__project.getFileCategoryExtension( |
565 # __IGNORE_WARNING__ |
620 # __IGNORE_WARNING__ |
566 fileType |
621 fileType |
567 ) |
622 ) |
568 ] |
623 ] |