|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2004 - 2009 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 PyQt4.QtCore import * |
|
14 from PyQt4.QtGui import * |
|
15 |
|
16 from E4Gui.E4Completers import E4DirCompleter |
|
17 |
|
18 from Ui_FindFileNameDialog import Ui_FindFileNameDialog |
|
19 from Utilities import direntries |
|
20 import Utilities |
|
21 |
|
22 |
|
23 class FindFileNameDialog(QWidget, Ui_FindFileNameDialog): |
|
24 """ |
|
25 Class implementing a dialog to search for files. |
|
26 |
|
27 The occurrences found are displayed in a QTreeWidget showing the |
|
28 filename and the pathname. The file will be opened upon a double click |
|
29 onto the respective entry of the list. |
|
30 |
|
31 @signal sourceFile(string) emitted to open a file in the editor |
|
32 @signal designerFile(string) emitted to open a Qt-Designer file |
|
33 """ |
|
34 def __init__(self, project, parent = None): |
|
35 """ |
|
36 Constructor |
|
37 |
|
38 @param project reference to the project object |
|
39 @param parent parent widget of this dialog (QWidget) |
|
40 """ |
|
41 QWidget.__init__(self, parent) |
|
42 self.setupUi(self) |
|
43 |
|
44 self.searchDirCompleter = E4DirCompleter(self.searchDirEdit) |
|
45 |
|
46 self.fileList.headerItem().setText(self.fileList.columnCount(), "") |
|
47 |
|
48 self.stopButton = \ |
|
49 self.buttonBox.addButton(self.trUtf8("Stop"), QDialogButtonBox.ActionRole) |
|
50 self.stopButton.setToolTip(self.trUtf8("Press to stop the search")) |
|
51 self.stopButton.setEnabled(False) |
|
52 self.buttonBox.button(QDialogButtonBox.Open).setToolTip(\ |
|
53 self.trUtf8("Opens the selected file")) |
|
54 |
|
55 self.project = project |
|
56 self.extsepLabel.setText(os.extsep) |
|
57 |
|
58 self.shouldStop = False |
|
59 |
|
60 def on_buttonBox_clicked(self, button): |
|
61 """ |
|
62 Private slot called by a button of the button box clicked. |
|
63 |
|
64 @param button button that was clicked (QAbstractButton) |
|
65 """ |
|
66 if button == self.stopButton: |
|
67 self.shouldStop = True |
|
68 elif button == self.buttonBox.button(QDialogButtonBox.Open): |
|
69 self.__openFile() |
|
70 |
|
71 def __openFile(self): |
|
72 """ |
|
73 Private slot to open a file. |
|
74 |
|
75 It emits the signal |
|
76 sourceFile or designerFile depending on the file extension. |
|
77 """ |
|
78 itm = self.fileList.currentItem() |
|
79 fileName = itm.text(0) |
|
80 filePath = itm.text(1) |
|
81 |
|
82 if fileName.endswith('.ui'): |
|
83 self.emit(SIGNAL('designerFile'), os.path.join(filePath, fileName)) |
|
84 else: |
|
85 self.emit(SIGNAL('sourceFile'), os.path.join(filePath, fileName)) |
|
86 |
|
87 def __searchFile(self): |
|
88 """ |
|
89 Private slot to handle the search. |
|
90 """ |
|
91 fileName = self.fileNameEdit.text() |
|
92 if not fileName: |
|
93 return |
|
94 fileExt = self.fileExtEdit.text() |
|
95 patternFormat = fileExt and "%s%s%s*" or "%s*%s%s" |
|
96 fileNamePattern = patternFormat % (fileName, os.extsep, |
|
97 fileExt and fileExt or '*') |
|
98 |
|
99 searchPaths = [] |
|
100 if self.searchDirCheckBox.isChecked() and \ |
|
101 self.searchDirEdit.text() == "": |
|
102 searchPaths.append(self.searchDirEdit.text()) |
|
103 if self.projectCheckBox.isChecked(): |
|
104 searchPaths.append(self.project.ppath) |
|
105 if self.syspathCheckBox.isChecked(): |
|
106 searchPaths.extend(sys.path) |
|
107 |
|
108 found = False |
|
109 self.fileList.clear() |
|
110 locations = {} |
|
111 self.shouldStop = False |
|
112 self.stopButton.setEnabled(True) |
|
113 QApplication.processEvents() |
|
114 |
|
115 for path in searchPaths: |
|
116 if os.path.isdir(path): |
|
117 files = direntries(path, True, fileNamePattern, False, self.checkStop) |
|
118 if files: |
|
119 found = True |
|
120 for file in files: |
|
121 fp, fn = os.path.split(file) |
|
122 if locations.has_key(fn): |
|
123 if fp in locations[fn]: |
|
124 continue |
|
125 else: |
|
126 locations[fn].append(fp) |
|
127 else: |
|
128 locations[fn] = [fp] |
|
129 QTreeWidgetItem(self.fileList, [fn, fp]) |
|
130 QApplication.processEvents() |
|
131 |
|
132 del locations |
|
133 self.buttonBox.button(QDialogButtonBox.Open).setEnabled(found) |
|
134 self.stopButton.setEnabled(False) |
|
135 self.fileList.header().resizeSections(QHeaderView.ResizeToContents) |
|
136 self.fileList.header().setStretchLastSection(True) |
|
137 |
|
138 def checkStop(self): |
|
139 """ |
|
140 Public method to check, if the search should be stopped. |
|
141 |
|
142 @return flag indicating the search should be stopped (boolean) |
|
143 """ |
|
144 QApplication.processEvents() |
|
145 return self.shouldStop |
|
146 |
|
147 def on_fileNameEdit_textChanged(self, text): |
|
148 """ |
|
149 Private slot to handle the textChanged signal of the file name edit. |
|
150 |
|
151 @param text (ignored) |
|
152 """ |
|
153 self.__searchFile() |
|
154 |
|
155 def on_fileExtEdit_textChanged(self, text): |
|
156 """ |
|
157 Private slot to handle the textChanged signal of the file extension edit. |
|
158 |
|
159 @param text (ignored) |
|
160 """ |
|
161 self.__searchFile() |
|
162 |
|
163 def on_searchDirEdit_textChanged(self, text): |
|
164 """ |
|
165 Private slot to handle the textChanged signal of the search directory edit. |
|
166 |
|
167 @param text text of the search dir edit (string) |
|
168 """ |
|
169 self.searchDirCheckBox.setEnabled(text != "") |
|
170 if self.searchDirCheckBox.isChecked(): |
|
171 self.__searchFile() |
|
172 |
|
173 |
|
174 @pyqtSlot() |
|
175 def on_searchDirButton_clicked(self): |
|
176 """ |
|
177 Private slot to handle the clicked signal of the search directory selection |
|
178 button. |
|
179 """ |
|
180 searchDir = QFileDialog.getExistingDirectory(\ |
|
181 None, |
|
182 self.trUtf8("Select search directory"), |
|
183 self.searchDirEdit.text(), |
|
184 QFileDialog.Options(QFileDialog.ShowDirsOnly)) |
|
185 |
|
186 if searchDir: |
|
187 self.searchDirEdit.setText(Utilities.toNativeSeparators(searchDir)) |
|
188 |
|
189 def on_searchDirCheckBox_toggled(self, checked): |
|
190 """ |
|
191 Private slot to handle the toggled signal of the search directory checkbox. |
|
192 |
|
193 @param checked flag indicating the state of the checkbox (boolean) |
|
194 """ |
|
195 if self.searchDirEdit.text(): |
|
196 self.__searchFile() |
|
197 |
|
198 def on_projectCheckBox_toggled(self, checked): |
|
199 """ |
|
200 Private slot to handle the toggled signal of the project checkbox. |
|
201 |
|
202 @param checked flag indicating the state of the checkbox (boolean) |
|
203 """ |
|
204 self.__searchFile() |
|
205 |
|
206 def on_syspathCheckBox_toggled(self, checked): |
|
207 """ |
|
208 Private slot to handle the toggled signal of the sys.path checkbox. |
|
209 |
|
210 @param checked flag indicating the state of the checkbox (boolean) |
|
211 """ |
|
212 self.__searchFile() |
|
213 |
|
214 def on_fileList_itemActivated(self, itm, column): |
|
215 """ |
|
216 Private slot to handle the double click on a file item. |
|
217 |
|
218 It emits the signal |
|
219 sourceFile or designerFile depending on the file extension. |
|
220 |
|
221 @param itm the double clicked listview item (QTreeWidgetItem) |
|
222 @param column column that was double clicked (integer) (ignored) |
|
223 """ |
|
224 self.__openFile() |
|
225 |
|
226 def show(self): |
|
227 """ |
|
228 Overwritten method to enable/disable the project checkbox. |
|
229 """ |
|
230 if self.project and self.project.isOpen(): |
|
231 self.projectCheckBox.setEnabled(True) |
|
232 self.projectCheckBox.setChecked(True) |
|
233 else: |
|
234 self.projectCheckBox.setEnabled(False) |
|
235 self.projectCheckBox.setChecked(False) |
|
236 |
|
237 self.fileNameEdit.selectAll() |
|
238 self.fileNameEdit.setFocus() |
|
239 |
|
240 QWidget.show(self) |