eric7/UI/FindLocationWidget.py

branch
eric7
changeset 8632
f25cd4b94eb0
parent 8358
144a6b854f70
child 8636
c0a3a6e40815
equal deleted inserted replaced
8631:b2c4c2f3fda7 8632:f25cd4b94eb0
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2004 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to search for files.
8 """
9
10 import os
11 import sys
12
13 from PyQt6.QtCore import pyqtSignal, pyqtSlot
14 from PyQt6.QtWidgets import (
15 QWidget, QHeaderView, QApplication, QTreeWidgetItem
16 )
17
18 from EricWidgets.EricPathPicker import EricPathPickerModes
19
20 from .Ui_FindLocationWidget import Ui_FindLocationWidget
21
22 import UI.PixmapCache
23 from Utilities import direntries
24 import Utilities
25
26
27 class FindLocationWidget(QWidget, Ui_FindLocationWidget):
28 """
29 Class implementing a widget to search for files.
30
31 The occurrences found are displayed in a QTreeWidget showing the
32 filename and the pathname. The file will be opened upon a double click
33 onto the respective entry of the list or by pressing the open button.
34
35 @signal sourceFile(str) emitted to open a file in the editor
36 @signal designerFile(str) emitted to open a Qt-Designer file
37 """
38 sourceFile = pyqtSignal(str)
39 designerFile = pyqtSignal(str)
40
41 def __init__(self, project, parent=None):
42 """
43 Constructor
44
45 @param project reference to the project object
46 @type Project
47 @param parent parent widget of this dialog
48 @type QWidget
49 """
50 super().__init__(parent)
51 self.setupUi(self)
52
53 self.layout().setContentsMargins(0, 3, 0, 0)
54
55 self.searchDirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
56
57 self.fileList.headerItem().setText(self.fileList.columnCount(), "")
58
59 self.stopButton.setEnabled(False)
60 self.stopButton.clicked.connect(self.__stopSearch)
61 self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading"))
62
63 self.findButton.setEnabled(False)
64 self.findButton.clicked.connect(self.__searchFile)
65 self.findButton.setIcon(UI.PixmapCache.getIcon("find"))
66
67 self.openButton.setIcon(UI.PixmapCache.getIcon("open"))
68 self.openButton.clicked.connect(self.__openFile)
69
70 self.project = project
71 self.extsepLabel.setText(os.extsep)
72
73 self.__shouldStop = False
74
75 self.fileNameEdit.returnPressed.connect(self.__searchFile)
76 self.fileExtEdit.returnPressed.connect(self.__searchFile)
77
78 @pyqtSlot()
79 def __stopSearch(self):
80 """
81 Private slot to handle the stop button being pressed.
82 """
83 self.__shouldStop = True
84
85 @pyqtSlot()
86 def __openFile(self, itm=None):
87 """
88 Private slot to open a file.
89
90 It emits the signal sourceFile or designerFile depending on the
91 file extension.
92
93 @param itm item to be opened
94 @type QTreeWidgetItem
95 """
96 if itm is None:
97 itm = self.fileList.currentItem()
98 if itm is not None:
99 fileName = itm.text(0)
100 filePath = itm.text(1)
101
102 # TODO: add more extensions and use mimetype
103 # - *.ts, *.qm->*.ts
104 # Utilities.MimeTypes.isTextFile(filename)
105 if fileName.endswith('.ui'):
106 self.designerFile.emit(os.path.join(filePath, fileName))
107 else:
108 self.sourceFile.emit(os.path.join(filePath, fileName))
109
110 @pyqtSlot()
111 def __searchFile(self):
112 """
113 Private slot to handle the search.
114 """
115 fileName = self.fileNameEdit.text()
116 if not fileName:
117 self.fileList.clear()
118 return
119
120 fileExt = self.fileExtEdit.text()
121 if not fileExt and Utilities.isWindowsPlatform():
122 self.fileList.clear()
123 return
124
125 self.findStatusLabel.clear()
126
127 patternFormat = fileExt and "{0}{1}{2}" or "{0}*{1}{2}"
128 fileNamePattern = patternFormat.format(
129 fileName, os.extsep, fileExt and fileExt or '*')
130
131 searchPaths = []
132 if (
133 self.searchDirCheckBox.isChecked() and
134 self.searchDirPicker.text() != ""
135 ):
136 searchPaths.append(self.searchDirPicker.text())
137 if self.projectCheckBox.isChecked():
138 searchPaths.append(self.project.ppath)
139 if self.syspathCheckBox.isChecked():
140 searchPaths.extend(sys.path)
141
142 self.fileList.clear()
143 locations = {}
144 self.__shouldStop = False
145 self.stopButton.setEnabled(True)
146 QApplication.processEvents()
147
148 for path in searchPaths:
149 if os.path.isdir(path):
150 files = direntries(path, True, fileNamePattern,
151 False, self.checkStop)
152 if files:
153 for file in files:
154 fp, fn = os.path.split(file)
155 if fn in locations:
156 if fp in locations[fn]:
157 continue
158 else:
159 locations[fn].append(fp)
160 else:
161 locations[fn] = [fp]
162 QTreeWidgetItem(self.fileList, [fn, fp])
163 QApplication.processEvents()
164
165 del locations
166 self.stopButton.setEnabled(False)
167 self.fileList.header().resizeSections(
168 QHeaderView.ResizeMode.ResizeToContents)
169 self.fileList.header().setStretchLastSection(True)
170
171 self.findStatusLabel.setText(self.tr(
172 "%n file(s) found", "", self.fileList.topLevelItemCount()))
173
174 def checkStop(self):
175 """
176 Public method to check, if the search should be stopped.
177
178 @return flag indicating the search should be stopped
179 @rtype bool
180 """
181 QApplication.processEvents()
182 return self.__shouldStop
183
184 @pyqtSlot(str)
185 def on_fileNameEdit_textChanged(self, text):
186 """
187 Private slot to handle the textChanged signal of the file name edit.
188
189 @param text (ignored)
190 @type str
191 """
192 self.findButton.setEnabled(bool(text))
193
194 @pyqtSlot(str)
195 def on_searchDirPicker_textChanged(self, text):
196 """
197 Private slot to handle the textChanged signal of the search directory
198 edit.
199
200 @param text text of the search dir edit
201 @type str
202 """
203 self.searchDirCheckBox.setEnabled(text != "")
204
205 @pyqtSlot(QTreeWidgetItem, int)
206 def on_fileList_itemActivated(self, itm, column):
207 """
208 Private slot to handle the double click on a file item.
209
210 It emits the signal sourceFile or designerFile depending on the
211 file extension.
212
213 @param itm the double clicked listview item
214 @type QTreeWidgetItem
215 @param column column that was double clicked (ignored)
216 @type int
217 """
218 self.__openFile(itm)
219
220 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
221 def on_fileList_currentItemChanged(self, current, previous):
222 """
223 Private slot handling a change of the current item.
224
225 @param current current item
226 @type QTreeWidgetItem
227 @param previous prevoius current item
228 @type QTreeWidgetItem
229 """
230 self.openButton.setEnabled(current is not None)
231
232 @pyqtSlot()
233 def activate(self):
234 """
235 Public slot to enable/disable the project checkbox.
236 """
237 if self.project and self.project.isOpen():
238 self.projectCheckBox.setEnabled(True)
239 self.projectCheckBox.setChecked(True)
240 else:
241 self.projectCheckBox.setEnabled(False)
242 self.projectCheckBox.setChecked(False)
243
244 self.fileNameEdit.selectAll()
245 self.fileNameEdit.setFocus()

eric ide

mercurial