UI/Browser.py

changeset 3012
d177226027e2
parent 2965
d133c7edd88a
child 3030
4a0a82ddd9d2
child 3057
10516539f238
equal deleted inserted replaced
3011:18292228c724 3012:d177226027e2
9 9
10 import os 10 import os
11 import mimetypes 11 import mimetypes
12 12
13 from PyQt4.QtCore import QModelIndex, pyqtSignal, QUrl, Qt, qVersion 13 from PyQt4.QtCore import QModelIndex, pyqtSignal, QUrl, Qt, qVersion
14 from PyQt4.QtGui import QTreeView, QDesktopServices, QItemSelectionModel, QApplication, \ 14 from PyQt4.QtGui import QTreeView, QDesktopServices, QItemSelectionModel, \
15 QMenu, QAbstractItemView 15 QApplication, QMenu, QAbstractItemView
16 16
17 from E5Gui.E5Application import e5App 17 from E5Gui.E5Application import e5App
18 from E5Gui import E5FileDialog 18 from E5Gui import E5FileDialog
19 19
20 from .BrowserModel import BrowserModel, \ 20 from .BrowserModel import BrowserModel, BrowserDirectoryItem, \
21 BrowserDirectoryItem, BrowserFileItem, BrowserClassItem, BrowserMethodItem, \ 21 BrowserFileItem, BrowserClassItem, BrowserMethodItem, \
22 BrowserClassAttributeItem 22 BrowserClassAttributeItem
23 from .BrowserSortFilterProxyModel import BrowserSortFilterProxyModel 23 from .BrowserSortFilterProxyModel import BrowserSortFilterProxyModel
24 24
25 import UI.PixmapCache 25 import UI.PixmapCache
26 import Preferences 26 import Preferences
33 33
34 Via the context menu that 34 Via the context menu that
35 is displayed by a right click the user can select various actions on 35 is displayed by a right click the user can select various actions on
36 the selected file. 36 the selected file.
37 37
38 @signal sourceFile(str, int = 0, str = "") emitted to open a Python file at a line 38 @signal sourceFile(str, int = 0, str = "") emitted to open a Python file
39 at a line
39 @signal designerFile(str) emitted to open a Qt-Designer file 40 @signal designerFile(str) emitted to open a Qt-Designer file
40 @signal linguistFile(str) emitted to open a Qt-Linguist (*.ts) file 41 @signal linguistFile(str) emitted to open a Qt-Linguist (*.ts) file
41 @signal trpreview(list of str, bool = False) emitted to preview a Qt-Linguist 42 @signal trpreview(list of str, bool = False) emitted to preview a
42 (*.qm) file 43 Qt-Linguist (*.qm) file
43 @signal projectFile(str) emitted to open an eric4/5 project file 44 @signal projectFile(str) emitted to open an eric4/5 project file
44 @signal multiProjectFile(str) emitted to open an eric4/5 multi project file 45 @signal multiProjectFile(str) emitted to open an eric4/5 multi project file
45 @signal pixmapFile(str) emitted to open a pixmap file 46 @signal pixmapFile(str) emitted to open a pixmap file
46 @signal pixmapEditFile(str) emitted to edit a pixmap file 47 @signal pixmapEditFile(str) emitted to edit a pixmap file
47 @signal svgFile(str) emitted to open a SVG file 48 @signal svgFile(str) emitted to open a SVG file
84 self.customContextMenuRequested.connect(self._contextMenuRequested) 85 self.customContextMenuRequested.connect(self._contextMenuRequested)
85 self.activated.connect(self._openItem) 86 self.activated.connect(self._openItem)
86 self.expanded.connect(self._resizeColumns) 87 self.expanded.connect(self._resizeColumns)
87 self.collapsed.connect(self._resizeColumns) 88 self.collapsed.connect(self._resizeColumns)
88 89
89 self.setWhatsThis(QApplication.translate('Browser', 90 self.setWhatsThis(QApplication.translate(
91 'Browser',
90 """<b>The Browser Window</b>""" 92 """<b>The Browser Window</b>"""
91 """<p>This allows you to easily navigate the hierachy of directories and""" 93 """<p>This allows you to easily navigate the hierarchy of"""
92 """ files on your system, identify the Python programs and open them up in""" 94 """ directories and files on your system, identify the Python"""
93 """ a Source Viewer window. The window displays several separate""" 95 """ programs and open them up in a Source Viewer window. The"""
94 """ hierachies.</p>""" 96 """ window displays several separate hierarchies.</p>"""
95 """<p>The first hierachy is only shown if you have opened a program for""" 97 """<p>The first hierarchy is only shown if you have opened a"""
96 """ debugging and its root is the directory containing that program.""" 98 """ program for debugging and its root is the directory"""
97 """ Usually all of the separate files that make up a Python application are""" 99 """ containing that program. Usually all of the separate files"""
98 """ held in the same directory, so this hierachy gives you easy access to""" 100 """ that make up a Python application are held in the same"""
99 """ most of what you will need.</p>""" 101 """ directory, so this hierarchy gives you easy access to most"""
100 """<p>The next hierachy is used to easily navigate the directories that are""" 102 """ of what you will need.</p>"""
101 """ specified in the Python <tt>sys.path</tt> variable.</p>""" 103 """<p>The next hierarchy is used to easily navigate the"""
102 """<p>The remaining hierachies allow you navigate your system as a whole.""" 104 """ directories that are specified in the Python"""
103 """ On a UNIX system there will be a hierachy with <tt>/</tt> at its""" 105 """ <tt>sys.path</tt> variable.</p>"""
104 """ root and another with the user home directory.""" 106 """<p>The remaining hierarchies allow you navigate your system"""
105 """ On a Windows system there will be a hierachy for each drive on the""" 107 """ as a whole. On a UNIX system there will be a hierarchy with"""
108 """ <tt>/</tt> at its root and another with the user home"""
109 """ directory. On a Windows system there will be a hierarchy for"""
110 """ each drive on the"""
106 """ system.</p>""" 111 """ system.</p>"""
107 """<p>Python programs (i.e. those with a <tt>.py</tt> file name suffix)""" 112 """<p>Python programs (i.e. those with a <tt>.py</tt> file name"""
108 """ are identified in the hierachies with a Python icon.""" 113 """ suffix) are identified in the hierarchies with a Python"""
109 """ The right mouse button will popup a menu which lets you""" 114 """ icon. The right mouse button will popup a menu which lets"""
110 """ open the file in a Source Viewer window,""" 115 """ you open the file in a Source Viewer window, open the file"""
111 """ open the file for debugging or use it for a unittest run.</p>""" 116 """ for debugging or use it for a unittest run.</p>"""
112 """<p>The context menu of a class, function or method allows you to open""" 117 """<p>The context menu of a class, function or method allows you"""
113 """ the file defining this class, function or method and will ensure, that""" 118 """ to open the file defining this class, function or method and"""
114 """ the correct source line is visible.</p>""" 119 """ will ensure, that the correct source line is visible.</p>"""
115 """<p>Qt-Designer files (i.e. those with a <tt>.ui</tt> file name suffix)""" 120 """<p>Qt-Designer files (i.e. those with a <tt>.ui</tt> file"""
116 """ are shown with a Designer icon. The context menu of these files""" 121 """ name suffix) are shown with a Designer icon. The context"""
117 """ allows you to start Qt-Designer with that file.</p>""" 122 """ menu of these files allows you to start Qt-Designer with"""
118 """<p>Qt-Linguist files (i.e. those with a <tt>.ts</tt> file name suffix)""" 123 """ that file.</p>"""
119 """ are shown with a Linguist icon. The context menu of these files""" 124 """<p>Qt-Linguist files (i.e. those with a <tt>.ts</tt> file"""
120 """ allows you to start Qt-Linguist with that file.</p>""" 125 """ name suffix) are shown with a Linguist icon. The context"""
126 """ menu of these files allows you to start Qt-Linguist with"""
127 """ that file.</p>"""
121 )) 128 ))
122 129
123 self.__createPopupMenus() 130 self.__createPopupMenus()
124 131
125 self._init() # perform common initialization tasks 132 self._init() # perform common initialization tasks
181 # create the popup menu for source files 188 # create the popup menu for source files
182 self.sourceMenu = QMenu(self) 189 self.sourceMenu = QMenu(self)
183 self.sourceMenu.addAction(QApplication.translate('Browser', 'Open'), 190 self.sourceMenu.addAction(QApplication.translate('Browser', 'Open'),
184 self._openItem) 191 self._openItem)
185 self.unittestAct = self.sourceMenu.addAction( 192 self.unittestAct = self.sourceMenu.addAction(
186 QApplication.translate('Browser', 'Run unittest...'), self.handleUnittest) 193 QApplication.translate('Browser', 'Run unittest...'),
194 self.handleUnittest)
187 self.sourceMenu.addAction( 195 self.sourceMenu.addAction(
188 QApplication.translate('Browser', 'Copy Path to Clipboard'), 196 QApplication.translate('Browser', 'Copy Path to Clipboard'),
189 self._copyToClipboard) 197 self._copyToClipboard)
190 198
191 # create the popup menu for general use 199 # create the popup menu for general use
192 self.menu = QMenu(self) 200 self.menu = QMenu(self)
193 self.menu.addAction(QApplication.translate('Browser', 'Open'), self._openItem) 201 self.menu.addAction(
194 self.editPixmapAct = \ 202 QApplication.translate('Browser', 'Open'), self._openItem)
195 self.menu.addAction(QApplication.translate('Browser', 'Open in Icon Editor'), 203 self.editPixmapAct = self.menu.addAction(
204 QApplication.translate('Browser', 'Open in Icon Editor'),
196 self._editPixmap) 205 self._editPixmap)
197 self.menu.addAction( 206 self.menu.addAction(
198 QApplication.translate('Browser', 'Copy Path to Clipboard'), 207 QApplication.translate('Browser', 'Copy Path to Clipboard'),
199 self._copyToClipboard) 208 self._copyToClipboard)
200 if self.__embeddedBrowser in [1, 2]: 209 if self.__embeddedBrowser in [1, 2]:
201 self.menu.addSeparator() 210 self.menu.addSeparator()
202 self.menu.addAction(QApplication.translate('Browser', 'Configure...'), 211 self.menu.addAction(
203 self.__configure) 212 QApplication.translate('Browser', 'Configure...'),
213 self.__configure)
204 214
205 # create the menu for multiple selected files 215 # create the menu for multiple selected files
206 self.multiMenu = QMenu(self) 216 self.multiMenu = QMenu(self)
207 self.multiMenu.addAction(QApplication.translate('Browser', 'Open'), 217 self.multiMenu.addAction(QApplication.translate('Browser', 'Open'),
208 self._openItem) 218 self._openItem)
209 if self.__embeddedBrowser in [1, 2]: 219 if self.__embeddedBrowser in [1, 2]:
210 self.multiMenu.addSeparator() 220 self.multiMenu.addSeparator()
211 self.multiMenu.addAction(QApplication.translate('Browser', 'Configure...'), 221 self.multiMenu.addAction(
212 self.__configure) 222 QApplication.translate('Browser', 'Configure...'),
223 self.__configure)
213 224
214 # create the directory menu 225 # create the directory menu
215 self.dirMenu = QMenu(self) 226 self.dirMenu = QMenu(self)
216 self.dirMenu.addAction(QApplication.translate('Browser', 227 self.dirMenu.addAction(QApplication.translate('Browser',
217 'New toplevel directory...'), 228 'New toplevel directory...'),
236 self.dirMenu.addAction( 247 self.dirMenu.addAction(
237 QApplication.translate('Browser', 'Copy Path to Clipboard'), 248 QApplication.translate('Browser', 'Copy Path to Clipboard'),
238 self._copyToClipboard) 249 self._copyToClipboard)
239 if self.__embeddedBrowser in [1, 2]: 250 if self.__embeddedBrowser in [1, 2]:
240 self.dirMenu.addSeparator() 251 self.dirMenu.addSeparator()
241 self.dirMenu.addAction(QApplication.translate('Browser', 'Configure...'), 252 self.dirMenu.addAction(
242 self.__configure) 253 QApplication.translate('Browser', 'Configure...'),
254 self.__configure)
243 255
244 # create the attribute menu 256 # create the attribute menu
245 self.gotoMenu = QMenu(self.trUtf8("Goto"), self) 257 self.gotoMenu = QMenu(self.trUtf8("Goto"), self)
246 self.gotoMenu.aboutToShow.connect(self._showGotoMenu) 258 self.gotoMenu.aboutToShow.connect(self._showGotoMenu)
247 self.gotoMenu.triggered.connect(self._gotoAttribute) 259 self.gotoMenu.triggered.connect(self._gotoAttribute)
263 self.backMenu.addAction(QApplication.translate('Browser', 275 self.backMenu.addAction(QApplication.translate('Browser',
264 'New toplevel directory...'), 276 'New toplevel directory...'),
265 self.__newToplevelDir) 277 self.__newToplevelDir)
266 if self.__embeddedBrowser in [1, 2]: 278 if self.__embeddedBrowser in [1, 2]:
267 self.backMenu.addSeparator() 279 self.backMenu.addSeparator()
268 self.backMenu.addAction(QApplication.translate('Browser', 'Configure...'), 280 self.backMenu.addAction(
269 self.__configure) 281 QApplication.translate('Browser', 'Configure...'),
282 self.__configure)
270 283
271 def mouseDoubleClickEvent(self, mouseEvent): 284 def mouseDoubleClickEvent(self, mouseEvent):
272 """ 285 """
273 Protected method of QAbstractItemView. 286 Protected method of QAbstractItemView.
274 287
275 Reimplemented to disable expanding/collapsing 288 Reimplemented to disable expanding/collapsing of items when
276 of items when double-clicking. Instead the double-clicked entry is opened. 289 double-clicking. Instead the double-clicked entry is opened.
277 290
278 @param mouseEvent the mouse event (QMouseEvent) 291 @param mouseEvent the mouse event (QMouseEvent)
279 """ 292 """
280 index = self.indexAt(mouseEvent.pos()) 293 index = self.indexAt(mouseEvent.pos())
281 if index.isValid(): 294 if index.isValid():
298 index = self.indexAt(coord) 311 index = self.indexAt(coord)
299 312
300 if index.isValid(): 313 if index.isValid():
301 self.setCurrentIndex(index) 314 self.setCurrentIndex(index)
302 flags = QItemSelectionModel.SelectionFlags( 315 flags = QItemSelectionModel.SelectionFlags(
303 QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows) 316 QItemSelectionModel.ClearAndSelect |
317 QItemSelectionModel.Rows)
304 self.selectionModel().select(index, flags) 318 self.selectionModel().select(index, flags)
305 319
306 itm = self.model().item(index) 320 itm = self.model().item(index)
307 coord = self.mapToGlobal(coord) 321 coord = self.mapToGlobal(coord)
308 if isinstance(itm, BrowserFileItem): 322 if isinstance(itm, BrowserFileItem):
342 itm = self.model().item(self.currentIndex()) 356 itm = self.model().item(self.currentIndex())
343 linenos = itm.linenos() 357 linenos = itm.linenos()
344 fileName = itm.fileName() 358 fileName = itm.fileName()
345 359
346 for lineno in sorted(linenos): 360 for lineno in sorted(linenos):
347 act = self.gotoMenu.addAction(self.trUtf8("Line {0}".format(lineno))) 361 act = self.gotoMenu.addAction(
362 self.trUtf8("Line {0}".format(lineno)))
348 act.setData([fileName, lineno]) 363 act.setData([fileName, lineno])
349 364
350 def _gotoAttribute(self, act): 365 def _gotoAttribute(self, act):
351 """ 366 """
352 Protected slot to handle the selection of the goto menu. 367 Protected slot to handle the selection of the goto menu.
378 if itm.isPython2File(): 393 if itm.isPython2File():
379 self.sourceFile[str].emit(itm.fileName()) 394 self.sourceFile[str].emit(itm.fileName())
380 elif itm.isPython3File(): 395 elif itm.isPython3File():
381 self.sourceFile[str].emit(itm.fileName()) 396 self.sourceFile[str].emit(itm.fileName())
382 elif itm.isRubyFile(): 397 elif itm.isRubyFile():
383 self.sourceFile[str, int, str].emit(itm.fileName(), -1, "Ruby") 398 self.sourceFile[str, int, str].emit(
399 itm.fileName(), -1, "Ruby")
384 elif itm.isDFile(): 400 elif itm.isDFile():
385 self.sourceFile[str, int, str].emit(itm.fileName(), -1, "D") 401 self.sourceFile[str, int, str].emit(
402 itm.fileName(), -1, "D")
386 elif itm.isDesignerFile(): 403 elif itm.isDesignerFile():
387 self.designerFile.emit(itm.fileName()) 404 self.designerFile.emit(itm.fileName())
388 elif itm.isLinguistFile(): 405 elif itm.isLinguistFile():
389 if itm.fileExt() == '.ts': 406 if itm.fileExt() == '.ts':
390 self.linguistFile.emit(itm.fileName()) 407 self.linguistFile.emit(itm.fileName())
503 Private slot to handle the Find in directory popup menu entry. 520 Private slot to handle the Find in directory popup menu entry.
504 """ 521 """
505 index = self.currentIndex() 522 index = self.currentIndex()
506 searchDir = self.model().item(index).dirName() 523 searchDir = self.model().item(index).dirName()
507 524
508 e5App().getObject("UserInterface").showFindFilesDialog(searchDir=searchDir) 525 e5App().getObject("UserInterface")\
526 .showFindFilesDialog(searchDir=searchDir)
509 527
510 def __replaceInDirectory(self): 528 def __replaceInDirectory(self):
511 """ 529 """
512 Private slot to handle the Find&Replace in directory popup menu entry. 530 Private slot to handle the Find&Replace in directory popup menu entry.
513 """ 531 """
514 index = self.currentIndex() 532 index = self.currentIndex()
515 searchDir = self.model().item(index).dirName() 533 searchDir = self.model().item(index).dirName()
516 534
517 e5App().getObject("UserInterface").showReplaceFilesDialog(searchDir=searchDir) 535 e5App().getObject("UserInterface")\
536 .showReplaceFilesDialog(searchDir=searchDir)
518 537
519 def handleProgramChange(self, fn): 538 def handleProgramChange(self, fn):
520 """ 539 """
521 Public slot to handle the programChange signal. 540 Public slot to handle the programChange signal.
522 541
610 def __configure(self): 629 def __configure(self):
611 """ 630 """
612 Private method to open the configuration dialog. 631 Private method to open the configuration dialog.
613 """ 632 """
614 if self.__embeddedBrowser == 1: 633 if self.__embeddedBrowser == 1:
615 e5App().getObject("UserInterface").showPreferences("debuggerGeneralPage") 634 e5App().getObject("UserInterface")\
635 .showPreferences("debuggerGeneralPage")
616 elif self.__embeddedBrowser == 2: 636 elif self.__embeddedBrowser == 2:
617 e5App().getObject("UserInterface").showPreferences("projectBrowserPage") 637 e5App().getObject("UserInterface")\
638 .showPreferences("projectBrowserPage")

eric ide

mercurial