src/eric7/Project/ProjectSourcesBrowser.py

branch
eric7-maintenance
changeset 9264
18a7312cfdb3
parent 9192
a763d57e23bc
parent 9246
f3120bfe82fb
child 9442
906485dcd210
equal deleted inserted replaced
9241:d23e9854aea4 9264:18a7312cfdb3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2002 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a class used to display the Sources part of the project.
8 """
9
10 import os
11 import contextlib
12
13 from PyQt6.QtCore import pyqtSignal
14 from PyQt6.QtWidgets import QDialog, QInputDialog, QMenu
15
16 from EricWidgets import EricMessageBox
17 from EricWidgets.EricApplication import ericApp
18
19 from UI.BrowserModel import (
20 BrowserFileItem,
21 BrowserClassItem,
22 BrowserMethodItem,
23 BrowserClassAttributeItem,
24 BrowserImportItem,
25 )
26
27 from .ProjectBrowserModel import (
28 ProjectBrowserFileItem,
29 ProjectBrowserSimpleDirectoryItem,
30 ProjectBrowserDirectoryItem,
31 ProjectBrowserSourceType,
32 )
33 from .ProjectBaseBrowser import ProjectBaseBrowser
34
35 import Utilities
36 import UI.PixmapCache
37
38 from CodeFormatting.BlackFormattingAction import BlackFormattingAction
39
40
41 class ProjectSourcesBrowser(ProjectBaseBrowser):
42 """
43 A class used to display the Sources part of the project.
44
45 @signal showMenu(str, QMenu) emitted when a menu is about to be shown.
46 The name of the menu and a reference to the menu are given.
47 """
48
49 showMenu = pyqtSignal(str, QMenu)
50
51 def __init__(self, project, parent=None):
52 """
53 Constructor
54
55 @param project reference to the project object
56 @param parent parent widget of this browser (QWidget)
57 """
58 ProjectBaseBrowser.__init__(self, project, ProjectBrowserSourceType, parent)
59
60 self.selectedItemsFilter = [
61 ProjectBrowserFileItem,
62 ProjectBrowserSimpleDirectoryItem,
63 ]
64
65 self.setWindowTitle(self.tr("Sources"))
66
67 self.setWhatsThis(
68 self.tr(
69 """<b>Project Sources Browser</b>"""
70 """<p>This allows to easily see all sources contained in the"""
71 """ current project. Several actions can be executed via the"""
72 """ context menu.</p>"""
73 )
74 )
75
76 project.prepareRepopulateItem.connect(self._prepareRepopulateItem)
77 project.completeRepopulateItem.connect(self._completeRepopulateItem)
78
79 self.codemetrics = None
80 self.codecoverage = None
81 self.profiledata = None
82 self.classDiagram = None
83 self.importsDiagram = None
84 self.packageDiagram = None
85 self.applicationDiagram = None
86 self.loadedDiagram = None
87
88 def __closeAllWindows(self):
89 """
90 Private method to close all project related windows.
91 """
92 self.codemetrics and self.codemetrics.close()
93 self.codecoverage and self.codecoverage.close()
94 self.profiledata and self.profiledata.close()
95 self.classDiagram and self.classDiagram.close()
96 self.importsDiagram and self.importsDiagram.close()
97 self.packageDiagram and self.packageDiagram.close()
98 self.applicationDiagram and self.applicationDiagram.close()
99 self.loadedDiagram and self.loadedDiagram.close()
100
101 def _projectClosed(self):
102 """
103 Protected slot to handle the projectClosed signal.
104 """
105 self.__closeAllWindows()
106 ProjectBaseBrowser._projectClosed(self)
107
108 def _createPopupMenus(self):
109 """
110 Protected overloaded method to generate the popup menu.
111 """
112 ProjectBaseBrowser._createPopupMenus(self)
113 self.sourceMenuActions = {}
114
115 if self.project.isPythonProject():
116 self.__createPythonPopupMenus()
117 elif self.project.isRubyProject():
118 self.__createRubyPopupMenus()
119 elif self.project.isJavaScriptProject():
120 self.__createJavaScriptPopupMenus()
121 else:
122 # assign generic source menu
123 self.mainMenu = self.sourceMenu
124
125 def __createPythonPopupMenus(self):
126 """
127 Private method to generate the popup menus for a Python project.
128 """
129 self.checksMenu = QMenu(self.tr("Check"))
130 self.checksMenu.aboutToShow.connect(self.__showContextMenuCheck)
131
132 self.formattingMenu = QMenu(self.tr("Code Formatting"))
133 self.formattingMenu.addAction(
134 self.tr("Format Code"),
135 lambda: self.__performFormatWithBlack(BlackFormattingAction.Format),
136 )
137 self.formattingMenu.addAction(
138 self.tr("Check Formatting"),
139 lambda: self.__performFormatWithBlack(BlackFormattingAction.Check),
140 )
141 self.formattingMenu.addAction(
142 self.tr("Formatting Diff"),
143 lambda: self.__performFormatWithBlack(BlackFormattingAction.Diff),
144 )
145 self.formattingMenu.aboutToShow.connect(self.__showContextMenuFormatting)
146
147 self.menuShow = QMenu(self.tr("Show"))
148 self.menuShow.addAction(self.tr("Code metrics..."), self.__showCodeMetrics)
149 self.coverageMenuAction = self.menuShow.addAction(
150 self.tr("Code coverage..."), self.__showCodeCoverage
151 )
152 self.profileMenuAction = self.menuShow.addAction(
153 self.tr("Profile data..."), self.__showProfileData
154 )
155 self.menuShow.aboutToShow.connect(self.__showContextMenuShow)
156
157 self.graphicsMenu = QMenu(self.tr("Diagrams"))
158 self.classDiagramAction = self.graphicsMenu.addAction(
159 self.tr("Class Diagram..."), self.__showClassDiagram
160 )
161 self.graphicsMenu.addAction(
162 self.tr("Package Diagram..."), self.__showPackageDiagram
163 )
164 self.importsDiagramAction = self.graphicsMenu.addAction(
165 self.tr("Imports Diagram..."), self.__showImportsDiagram
166 )
167 self.graphicsMenu.addAction(
168 self.tr("Application Diagram..."), self.__showApplicationDiagram
169 )
170 self.graphicsMenu.addSeparator()
171 self.graphicsMenu.addAction(
172 UI.PixmapCache.getIcon("open"),
173 self.tr("Load Diagram..."),
174 self.__loadDiagram,
175 )
176 self.graphicsMenu.aboutToShow.connect(self.__showContextMenuGraphics)
177
178 self.__startMenu = QMenu(self.tr("Start"), self)
179 self.__startMenu.addAction(
180 UI.PixmapCache.getIcon("runScript"),
181 self.tr("Run Script..."),
182 self.__contextMenuRunScript,
183 )
184 self.__startMenu.addAction(
185 UI.PixmapCache.getIcon("debugScript"),
186 self.tr("Debug Script..."),
187 self.__contextMenuDebugScript,
188 )
189 self.__startMenu.addAction(
190 UI.PixmapCache.getIcon("profileScript"),
191 self.tr("Profile Script..."),
192 self.__contextMenuProfileScript,
193 )
194 self.__startMenu.addAction(
195 UI.PixmapCache.getIcon("coverageScript"),
196 self.tr("Coverage run of Script..."),
197 self.__contextMenuCoverageScript,
198 )
199
200 self.testingAction = self.sourceMenu.addAction(
201 self.tr("Run tests..."), self.handleTesting
202 )
203 self.sourceMenu.addSeparator()
204 act = self.sourceMenu.addAction(self.tr("Rename file"), self._renameFile)
205 self.menuActions.append(act)
206 act = self.sourceMenu.addAction(
207 self.tr("Remove from project"), self._removeFile
208 )
209 self.menuActions.append(act)
210 act = self.sourceMenu.addAction(self.tr("Delete"), self.__deleteFile)
211 self.menuActions.append(act)
212 self.sourceMenu.addSeparator()
213 self.sourceMenu.addAction(self.tr("New package..."), self.__addNewPackage)
214 self.sourceMenu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
215 self.sourceMenu.addAction(
216 self.tr("Add source directory..."), self.__addSourceDirectory
217 )
218 self.sourceMenu.addSeparator()
219 self.sourceMenu.addMenu(self.graphicsMenu)
220 self.sourceMenu.addMenu(self.checksMenu)
221 self.sourceMenu.addMenu(self.formattingMenu)
222 self.sourceMenuActions["Show"] = self.sourceMenu.addMenu(self.menuShow)
223 self.sourceMenu.addSeparator()
224 self.__startAct = self.sourceMenu.addMenu(self.__startMenu)
225 self.sourceMenu.addSeparator()
226 self.sourceMenu.addAction(
227 self.tr("Copy Path to Clipboard"), self._copyToClipboard
228 )
229 self.sourceMenu.addSeparator()
230 self.sourceMenu.addAction(
231 self.tr("Expand all directories"), self._expandAllDirs
232 )
233 self.sourceMenu.addAction(
234 self.tr("Collapse all directories"), self._collapseAllDirs
235 )
236 self.sourceMenu.addSeparator()
237 self.sourceMenu.addAction(self.tr("Configure..."), self._configure)
238
239 self.menu.addSeparator()
240 self.menu.addAction(self.tr("New package..."), self.__addNewPackage)
241 self.menu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
242 self.menu.addAction(
243 self.tr("Add source directory..."), self.__addSourceDirectory
244 )
245 self.menu.addSeparator()
246 self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
247 self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs)
248 self.menu.addSeparator()
249 self.menu.addAction(self.tr("Configure..."), self._configure)
250
251 # create the attribute menu
252 self.gotoMenu = QMenu(self.tr("Goto"), self)
253 self.gotoMenu.aboutToShow.connect(self._showGotoMenu)
254 self.gotoMenu.triggered.connect(self._gotoAttribute)
255
256 self.attributeMenu = QMenu(self)
257 self.attributeMenu.addMenu(self.gotoMenu)
258 self.attributeMenu.addSeparator()
259 self.attributeMenu.addAction(self.tr("New package..."), self.__addNewPackage)
260 self.attributeMenu.addAction(
261 self.tr("Add source files..."), self.project.addSourceFiles
262 )
263 self.attributeMenu.addAction(
264 self.tr("Add source directory..."), self.project.addSourceDir
265 )
266 self.attributeMenu.addSeparator()
267 self.attributeMenu.addAction(
268 self.tr("Expand all directories"), self._expandAllDirs
269 )
270 self.attributeMenu.addAction(
271 self.tr("Collapse all directories"), self._collapseAllDirs
272 )
273 self.attributeMenu.addSeparator()
274 self.attributeMenu.addAction(self.tr("Configure..."), self._configure)
275
276 self.backMenu = QMenu(self)
277 self.backMenu.addAction(self.tr("New package..."), self.__addNewPackage)
278 self.backMenu.addAction(
279 self.tr("Add source files..."), self.project.addSourceFiles
280 )
281 self.backMenu.addAction(
282 self.tr("Add source directory..."), self.project.addSourceDir
283 )
284 self.backMenu.addSeparator()
285 self.backMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
286 self.backMenu.addAction(
287 self.tr("Collapse all directories"), self._collapseAllDirs
288 )
289 self.backMenu.addSeparator()
290 self.backMenu.addAction(self.tr("Configure..."), self._configure)
291 self.backMenu.setEnabled(False)
292
293 self.multiMenu.addSeparator()
294 act = self.multiMenu.addAction(self.tr("Remove from project"), self._removeFile)
295 self.multiMenuActions.append(act)
296 act = self.multiMenu.addAction(self.tr("Delete"), self.__deleteFile)
297 self.multiMenuActions.append(act)
298 self.multiMenu.addSeparator()
299 self.multiMenu.addMenu(self.checksMenu)
300 self.multiMenu.addMenu(self.formattingMenu)
301 self.multiMenu.addSeparator()
302 self.multiMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
303 self.multiMenu.addAction(
304 self.tr("Collapse all directories"), self._collapseAllDirs
305 )
306 self.multiMenu.addSeparator()
307 self.multiMenu.addAction(self.tr("Configure..."), self._configure)
308
309 self.dirMenu = QMenu(self)
310 act = self.dirMenu.addAction(self.tr("Remove from project"), self._removeDir)
311 self.dirMenuActions.append(act)
312 act = self.dirMenu.addAction(self.tr("Delete"), self._deleteDirectory)
313 self.dirMenuActions.append(act)
314 self.dirMenu.addSeparator()
315 self.dirMenu.addAction(self.tr("New package..."), self.__addNewPackage)
316 self.dirMenu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
317 self.dirMenu.addAction(
318 self.tr("Add source directory..."), self.__addSourceDirectory
319 )
320 self.dirMenu.addSeparator()
321 act = self.dirMenu.addMenu(self.graphicsMenu)
322 self.dirMenu.addMenu(self.checksMenu)
323 self.dirMenu.addMenu(self.formattingMenu)
324 self.dirMenu.addSeparator()
325 self.dirMenu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard)
326 self.dirMenu.addSeparator()
327 self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
328 self.dirMenu.addAction(
329 self.tr("Collapse all directories"), self._collapseAllDirs
330 )
331 self.dirMenu.addSeparator()
332 self.dirMenu.addAction(self.tr("Configure..."), self._configure)
333
334 self.dirMultiMenu = QMenu(self)
335 self.dirMultiMenu.addAction(
336 self.tr("Expand all directories"), self._expandAllDirs
337 )
338 self.dirMultiMenu.addAction(
339 self.tr("Collapse all directories"), self._collapseAllDirs
340 )
341 self.dirMultiMenu.addSeparator()
342 self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure)
343
344 self.sourceMenu.aboutToShow.connect(self.__showContextMenu)
345 self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti)
346 self.dirMenu.aboutToShow.connect(self.__showContextMenuDir)
347 self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti)
348 self.backMenu.aboutToShow.connect(self.__showContextMenuBack)
349 self.mainMenu = self.sourceMenu
350
351 def __createRubyPopupMenus(self):
352 """
353 Private method to generate the popup menus for a Ruby project.
354 """
355 self.graphicsMenu = QMenu(self.tr("Diagrams"))
356 self.classDiagramAction = self.graphicsMenu.addAction(
357 self.tr("Class Diagram..."), self.__showClassDiagram
358 )
359 self.graphicsMenu.addAction(
360 self.tr("Package Diagram..."), self.__showPackageDiagram
361 )
362 self.graphicsMenu.addAction(
363 self.tr("Application Diagram..."), self.__showApplicationDiagram
364 )
365 self.graphicsMenu.addSeparator()
366 self.graphicsMenu.addAction(
367 UI.PixmapCache.getIcon("fileOpen"),
368 self.tr("Load Diagram..."),
369 self.__loadDiagram,
370 )
371
372 self.sourceMenu.addSeparator()
373 act = self.sourceMenu.addAction(self.tr("Rename file"), self._renameFile)
374 self.menuActions.append(act)
375 act = self.sourceMenu.addAction(
376 self.tr("Remove from project"), self._removeFile
377 )
378 self.menuActions.append(act)
379 act = self.sourceMenu.addAction(self.tr("Delete"), self.__deleteFile)
380 self.menuActions.append(act)
381 self.sourceMenu.addSeparator()
382 self.sourceMenu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
383 self.sourceMenu.addAction(
384 self.tr("Add source directory..."), self.__addSourceDirectory
385 )
386 self.sourceMenu.addSeparator()
387 act = self.sourceMenu.addMenu(self.graphicsMenu)
388 self.sourceMenu.addSeparator()
389 self.sourceMenu.addAction(
390 self.tr("Expand all directories"), self._expandAllDirs
391 )
392 self.sourceMenu.addAction(
393 self.tr("Collapse all directories"), self._collapseAllDirs
394 )
395 self.sourceMenu.addSeparator()
396 self.sourceMenu.addAction(self.tr("Configure..."), self._configure)
397
398 self.menu.addSeparator()
399 self.menu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
400 self.menu.addAction(
401 self.tr("Add source directory..."), self.__addSourceDirectory
402 )
403 self.menu.addSeparator()
404 self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
405 self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs)
406 self.menu.addSeparator()
407 self.menu.addAction(self.tr("Configure..."), self._configure)
408
409 # create the attribute menu
410 self.gotoMenu = QMenu(self.tr("Goto"), self)
411 self.gotoMenu.aboutToShow.connect(self._showGotoMenu)
412 self.gotoMenu.triggered.connect(self._gotoAttribute)
413
414 self.attributeMenu = QMenu(self)
415 self.attributeMenu.addMenu(self.gotoMenu)
416 self.attributeMenu.addSeparator()
417 self.attributeMenu.addAction(
418 self.tr("Add source files..."), self.project.addSourceFiles
419 )
420 self.attributeMenu.addAction(
421 self.tr("Add source directory..."), self.project.addSourceDir
422 )
423 self.attributeMenu.addSeparator()
424 self.attributeMenu.addAction(
425 self.tr("Expand all directories"), self._expandAllDirs
426 )
427 self.attributeMenu.addAction(
428 self.tr("Collapse all directories"), self._collapseAllDirs
429 )
430 self.attributeMenu.addSeparator()
431 self.attributeMenu.addAction(self.tr("Configure..."), self._configure)
432
433 self.backMenu = QMenu(self)
434 self.backMenu.addAction(
435 self.tr("Add source files..."), self.project.addSourceFiles
436 )
437 self.backMenu.addAction(
438 self.tr("Add source directory..."), self.project.addSourceDir
439 )
440 self.backMenu.addSeparator()
441 self.backMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
442 self.backMenu.addAction(
443 self.tr("Collapse all directories"), self._collapseAllDirs
444 )
445 self.backMenu.setEnabled(False)
446 self.backMenu.addSeparator()
447 self.backMenu.addAction(self.tr("Configure..."), self._configure)
448
449 self.multiMenu.addSeparator()
450 act = self.multiMenu.addAction(self.tr("Remove from project"), self._removeFile)
451 self.multiMenuActions.append(act)
452 act = self.multiMenu.addAction(self.tr("Delete"), self.__deleteFile)
453 self.multiMenuActions.append(act)
454 self.multiMenu.addSeparator()
455 self.multiMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
456 self.multiMenu.addAction(
457 self.tr("Collapse all directories"), self._collapseAllDirs
458 )
459 self.multiMenu.addSeparator()
460 self.multiMenu.addAction(self.tr("Configure..."), self._configure)
461
462 self.dirMenu = QMenu(self)
463 act = self.dirMenu.addAction(self.tr("Remove from project"), self._removeDir)
464 self.dirMenuActions.append(act)
465 self.dirMenu.addSeparator()
466 self.dirMenu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
467 self.dirMenu.addAction(
468 self.tr("Add source directory..."), self.__addSourceDirectory
469 )
470 self.dirMenu.addSeparator()
471 act = self.dirMenu.addMenu(self.graphicsMenu)
472 self.dirMenu.addSeparator()
473 self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
474 self.dirMenu.addAction(
475 self.tr("Collapse all directories"), self._collapseAllDirs
476 )
477 self.dirMenu.addSeparator()
478 self.dirMenu.addAction(self.tr("Configure..."), self._configure)
479
480 self.dirMultiMenu = QMenu(self)
481 self.dirMultiMenu.addAction(
482 self.tr("Expand all directories"), self._expandAllDirs
483 )
484 self.dirMultiMenu.addAction(
485 self.tr("Collapse all directories"), self._collapseAllDirs
486 )
487 self.dirMultiMenu.addSeparator()
488 self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure)
489
490 self.sourceMenu.aboutToShow.connect(self.__showContextMenu)
491 self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti)
492 self.dirMenu.aboutToShow.connect(self.__showContextMenuDir)
493 self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti)
494 self.backMenu.aboutToShow.connect(self.__showContextMenuBack)
495 self.mainMenu = self.sourceMenu
496
497 def __createJavaScriptPopupMenus(self):
498 """
499 Private method to generate the popup menus for a Python project.
500 """
501 self.checksMenu = QMenu(self.tr("Check"))
502 self.checksMenu.aboutToShow.connect(self.__showContextMenuCheck)
503
504 self.sourceMenu.addSeparator()
505 act = self.sourceMenu.addAction(self.tr("Rename file"), self._renameFile)
506 self.menuActions.append(act)
507 act = self.sourceMenu.addAction(
508 self.tr("Remove from project"), self._removeFile
509 )
510 self.menuActions.append(act)
511 act = self.sourceMenu.addAction(self.tr("Delete"), self.__deleteFile)
512 self.menuActions.append(act)
513 self.sourceMenu.addSeparator()
514 self.sourceMenu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
515 self.sourceMenu.addAction(
516 self.tr("Add source directory..."), self.__addSourceDirectory
517 )
518 self.sourceMenu.addSeparator()
519 self.sourceMenu.addMenu(self.checksMenu)
520 self.sourceMenu.addSeparator()
521 self.sourceMenu.addAction(
522 self.tr("Copy Path to Clipboard"), self._copyToClipboard
523 )
524 self.sourceMenu.addSeparator()
525 self.sourceMenu.addAction(
526 self.tr("Expand all directories"), self._expandAllDirs
527 )
528 self.sourceMenu.addAction(
529 self.tr("Collapse all directories"), self._collapseAllDirs
530 )
531 self.sourceMenu.addSeparator()
532 self.sourceMenu.addAction(self.tr("Configure..."), self._configure)
533
534 self.menu.addSeparator()
535 self.menu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
536 self.menu.addAction(
537 self.tr("Add source directory..."), self.__addSourceDirectory
538 )
539 self.menu.addSeparator()
540 self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
541 self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs)
542 self.menu.addSeparator()
543 self.menu.addAction(self.tr("Configure..."), self._configure)
544
545 # create the attribute menu
546 self.gotoMenu = QMenu(self.tr("Goto"), self)
547 self.gotoMenu.aboutToShow.connect(self._showGotoMenu)
548 self.gotoMenu.triggered.connect(self._gotoAttribute)
549
550 self.attributeMenu = QMenu(self)
551 self.attributeMenu.addMenu(self.gotoMenu)
552 self.attributeMenu.addSeparator()
553 self.attributeMenu.addAction(
554 self.tr("Add source files..."), self.project.addSourceFiles
555 )
556 self.attributeMenu.addAction(
557 self.tr("Add source directory..."), self.project.addSourceDir
558 )
559 self.attributeMenu.addSeparator()
560 self.attributeMenu.addAction(
561 self.tr("Expand all directories"), self._expandAllDirs
562 )
563 self.attributeMenu.addAction(
564 self.tr("Collapse all directories"), self._collapseAllDirs
565 )
566 self.attributeMenu.addSeparator()
567 self.attributeMenu.addAction(self.tr("Configure..."), self._configure)
568
569 self.backMenu = QMenu(self)
570 self.backMenu.addAction(
571 self.tr("Add source files..."), self.project.addSourceFiles
572 )
573 self.backMenu.addAction(
574 self.tr("Add source directory..."), self.project.addSourceDir
575 )
576 self.backMenu.addSeparator()
577 self.backMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
578 self.backMenu.addAction(
579 self.tr("Collapse all directories"), self._collapseAllDirs
580 )
581 self.backMenu.addSeparator()
582 self.backMenu.addAction(self.tr("Configure..."), self._configure)
583 self.backMenu.setEnabled(False)
584
585 self.multiMenu.addSeparator()
586 act = self.multiMenu.addAction(self.tr("Remove from project"), self._removeFile)
587 self.multiMenuActions.append(act)
588 act = self.multiMenu.addAction(self.tr("Delete"), self.__deleteFile)
589 self.multiMenuActions.append(act)
590 self.multiMenu.addSeparator()
591 self.multiMenu.addMenu(self.checksMenu)
592 self.multiMenu.addSeparator()
593 self.multiMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
594 self.multiMenu.addAction(
595 self.tr("Collapse all directories"), self._collapseAllDirs
596 )
597 self.multiMenu.addSeparator()
598 self.multiMenu.addAction(self.tr("Configure..."), self._configure)
599
600 self.dirMenu = QMenu(self)
601 act = self.dirMenu.addAction(self.tr("Remove from project"), self._removeDir)
602 self.dirMenuActions.append(act)
603 act = self.dirMenu.addAction(self.tr("Delete"), self._deleteDirectory)
604 self.dirMenuActions.append(act)
605 self.dirMenu.addSeparator()
606 self.dirMenu.addAction(self.tr("Add source files..."), self.__addSourceFiles)
607 self.dirMenu.addAction(
608 self.tr("Add source directory..."), self.__addSourceDirectory
609 )
610 self.dirMenu.addSeparator()
611 self.dirMenu.addMenu(self.checksMenu)
612 self.dirMenu.addSeparator()
613 self.dirMenu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard)
614 self.dirMenu.addSeparator()
615 self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs)
616 self.dirMenu.addAction(
617 self.tr("Collapse all directories"), self._collapseAllDirs
618 )
619 self.dirMenu.addSeparator()
620 self.dirMenu.addAction(self.tr("Configure..."), self._configure)
621
622 self.dirMultiMenu = QMenu(self)
623 self.dirMultiMenu.addAction(
624 self.tr("Expand all directories"), self._expandAllDirs
625 )
626 self.dirMultiMenu.addAction(
627 self.tr("Collapse all directories"), self._collapseAllDirs
628 )
629 self.dirMultiMenu.addSeparator()
630 self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure)
631
632 self.sourceMenu.aboutToShow.connect(self.__showContextMenu)
633 self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti)
634 self.dirMenu.aboutToShow.connect(self.__showContextMenuDir)
635 self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti)
636 self.backMenu.aboutToShow.connect(self.__showContextMenuBack)
637 self.mainMenu = self.sourceMenu
638
639 def _contextMenuRequested(self, coord):
640 """
641 Protected slot to show the context menu.
642
643 @param coord the position of the mouse pointer (QPoint)
644 """
645 if not self.project.isOpen():
646 return
647
648 with contextlib.suppress(Exception):
649 categories = self.getSelectedItemsCountCategorized(
650 [
651 ProjectBrowserFileItem,
652 BrowserClassItem,
653 BrowserMethodItem,
654 ProjectBrowserSimpleDirectoryItem,
655 BrowserClassAttributeItem,
656 BrowserImportItem,
657 ]
658 )
659 cnt = categories["sum"]
660 if cnt <= 1:
661 index = self.indexAt(coord)
662 if index.isValid():
663 self._selectSingleItem(index)
664 categories = self.getSelectedItemsCountCategorized(
665 [
666 ProjectBrowserFileItem,
667 BrowserClassItem,
668 BrowserMethodItem,
669 ProjectBrowserSimpleDirectoryItem,
670 BrowserClassAttributeItem,
671 BrowserImportItem,
672 ]
673 )
674 cnt = categories["sum"]
675
676 bfcnt = categories[str(ProjectBrowserFileItem)]
677 cmcnt = (
678 categories[str(BrowserClassItem)]
679 + categories[str(BrowserMethodItem)]
680 + categories[str(BrowserClassAttributeItem)]
681 + categories[str(BrowserImportItem)]
682 )
683 sdcnt = categories[str(ProjectBrowserSimpleDirectoryItem)]
684 if cnt > 1 and cnt == bfcnt:
685 self.multiMenu.popup(self.mapToGlobal(coord))
686 elif cnt > 1 and cnt == sdcnt:
687 self.dirMultiMenu.popup(self.mapToGlobal(coord))
688 else:
689 index = self.indexAt(coord)
690 if cnt == 1 and index.isValid():
691 if bfcnt == 1 or cmcnt == 1:
692 itm = self.model().item(index)
693 if isinstance(itm, ProjectBrowserFileItem):
694 fn = itm.fileName()
695 if self.project.isPythonProject():
696 if fn.endswith(".ptl"):
697 for act in self.sourceMenuActions.values():
698 act.setEnabled(False)
699 self.classDiagramAction.setEnabled(True)
700 self.importsDiagramAction.setEnabled(True)
701 self.testingAction.setEnabled(False)
702 self.checksMenu.menuAction().setEnabled(False)
703 elif fn.endswith(".rb"):
704 # entry for mixed mode programs
705 for act in self.sourceMenuActions.values():
706 act.setEnabled(False)
707 self.classDiagramAction.setEnabled(True)
708 self.importsDiagramAction.setEnabled(False)
709 self.testingAction.setEnabled(False)
710 self.checksMenu.menuAction().setEnabled(False)
711 elif fn.endswith(".js"):
712 # entry for mixed mode programs
713 for act in self.sourceMenuActions.values():
714 act.setEnabled(False)
715 self.testingAction.setEnabled(False)
716 self.checksMenu.menuAction().setEnabled(False)
717 self.graphicsMenu.menuAction().setEnabled(False)
718 else:
719 # assume the source file is a Python file
720 for act in self.sourceMenuActions.values():
721 act.setEnabled(True)
722 self.classDiagramAction.setEnabled(True)
723 self.importsDiagramAction.setEnabled(True)
724 self.testingAction.setEnabled(True)
725 self.checksMenu.menuAction().setEnabled(True)
726 self.sourceMenu.popup(self.mapToGlobal(coord))
727 elif isinstance(
728 itm,
729 (BrowserClassItem, BrowserMethodItem, BrowserImportItem),
730 ):
731 self.menu.popup(self.mapToGlobal(coord))
732 elif isinstance(itm, BrowserClassAttributeItem):
733 self.attributeMenu.popup(self.mapToGlobal(coord))
734 else:
735 self.backMenu.popup(self.mapToGlobal(coord))
736 elif sdcnt == 1:
737 self.classDiagramAction.setEnabled(False)
738 self.dirMenu.popup(self.mapToGlobal(coord))
739 else:
740 self.backMenu.popup(self.mapToGlobal(coord))
741 else:
742 self.backMenu.popup(self.mapToGlobal(coord))
743
744 def __showContextMenu(self):
745 """
746 Private slot called by the sourceMenu aboutToShow signal.
747 """
748 ProjectBaseBrowser._showContextMenu(self, self.sourceMenu)
749
750 itm = self.model().item(self.currentIndex())
751 if itm:
752 try:
753 self.__startAct.setEnabled(itm.isPython3File())
754 except AttributeError:
755 self.__startAct.setEnabled(False)
756 else:
757 self.__startAct.setEnabled(False)
758
759 self.showMenu.emit("Main", self.sourceMenu)
760
761 def __showContextMenuMulti(self):
762 """
763 Private slot called by the multiMenu aboutToShow signal.
764 """
765 ProjectBaseBrowser._showContextMenuMulti(self, self.multiMenu)
766
767 self.showMenu.emit("MainMulti", self.multiMenu)
768
769 def __showContextMenuDir(self):
770 """
771 Private slot called by the dirMenu aboutToShow signal.
772 """
773 ProjectBaseBrowser._showContextMenuDir(self, self.dirMenu)
774
775 self.showMenu.emit("MainDir", self.dirMenu)
776
777 def __showContextMenuDirMulti(self):
778 """
779 Private slot called by the dirMultiMenu aboutToShow signal.
780 """
781 ProjectBaseBrowser._showContextMenuDirMulti(self, self.dirMultiMenu)
782
783 self.showMenu.emit("MainDirMulti", self.dirMultiMenu)
784
785 def __showContextMenuBack(self):
786 """
787 Private slot called by the backMenu aboutToShow signal.
788 """
789 ProjectBaseBrowser._showContextMenuBack(self, self.backMenu)
790
791 self.showMenu.emit("MainBack", self.backMenu)
792
793 def __showContextMenuShow(self):
794 """
795 Private slot called before the show menu is shown.
796 """
797 prEnable = False
798 coEnable = False
799
800 # first check if the file belongs to a project and there is
801 # a project coverage file
802 fn = self.project.getMainScript(True)
803 if fn is not None:
804 prEnable = self.project.isPy3Project() and bool(
805 Utilities.getProfileFileNames(fn)
806 )
807 coEnable = self.project.isPy3Project() and bool(
808 Utilities.getCoverageFileNames(fn)
809 )
810
811 # now check the selected item
812 itm = self.model().item(self.currentIndex())
813 fn = itm.fileName()
814 if fn is not None:
815 prEnable |= itm.isPython3File() and bool(Utilities.getProfileFileNames(fn))
816 coEnable |= itm.isPython3File() and bool(Utilities.getCoverageFileName(fn))
817
818 self.profileMenuAction.setEnabled(prEnable)
819 self.coverageMenuAction.setEnabled(coEnable)
820
821 self.showMenu.emit("Show", self.menuShow)
822
823 def _openItem(self):
824 """
825 Protected slot to handle the open popup menu entry.
826 """
827 itmList = self.getSelectedItems(
828 [
829 BrowserFileItem,
830 BrowserClassItem,
831 BrowserMethodItem,
832 BrowserClassAttributeItem,
833 BrowserImportItem,
834 ]
835 )
836
837 for itm in itmList:
838 if isinstance(itm, BrowserFileItem):
839 if itm.isPython3File():
840 self.sourceFile[str].emit(itm.fileName())
841 elif itm.isRubyFile():
842 self.sourceFile[str, int, str].emit(itm.fileName(), -1, "Ruby")
843 elif itm.isDFile():
844 self.sourceFile[str, int, str].emit(itm.fileName(), -1, "D")
845 else:
846 self.sourceFile[str].emit(itm.fileName())
847 elif isinstance(itm, BrowserClassItem):
848 self.sourceFile[str, int].emit(itm.fileName(), itm.classObject().lineno)
849 elif isinstance(itm, BrowserMethodItem):
850 self.sourceFile[str, int].emit(
851 itm.fileName(), itm.functionObject().lineno
852 )
853 elif isinstance(itm, BrowserClassAttributeItem):
854 self.sourceFile[str, int].emit(
855 itm.fileName(), itm.attributeObject().lineno
856 )
857 elif isinstance(itm, BrowserImportItem):
858 self.sourceFile[str, list].emit(itm.fileName(), itm.linenos())
859
860 def __addNewPackage(self):
861 """
862 Private method to add a new package to the project.
863 """
864 itm = self.model().item(self.currentIndex())
865 if isinstance(
866 itm, (ProjectBrowserFileItem, BrowserClassItem, BrowserMethodItem)
867 ):
868 dn = os.path.dirname(itm.fileName())
869 elif isinstance(
870 itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
871 ):
872 dn = itm.dirName()
873 else:
874 dn = ""
875
876 dn = self.project.getRelativePath(dn)
877 if dn.startswith(os.sep):
878 dn = dn[1:]
879 from .NewPythonPackageDialog import NewPythonPackageDialog
880
881 dlg = NewPythonPackageDialog(dn, self)
882 if dlg.exec() == QDialog.DialogCode.Accepted:
883 packageName = dlg.getData()
884 nameParts = packageName.split(".")
885 packagePath = self.project.ppath
886 packageFile = ""
887 for name in nameParts:
888 packagePath = os.path.join(packagePath, name)
889 if not os.path.exists(packagePath):
890 try:
891 os.mkdir(packagePath)
892 except OSError as err:
893 EricMessageBox.critical(
894 self,
895 self.tr("Add new Python package"),
896 self.tr(
897 """<p>The package directory <b>{0}</b> could"""
898 """ not be created. Aborting...</p>"""
899 """<p>Reason: {1}</p>"""
900 ).format(packagePath, str(err)),
901 )
902 return
903 packageFile = os.path.join(packagePath, "__init__.py")
904 if not os.path.exists(packageFile):
905 try:
906 with open(packageFile, "w", encoding="utf-8"):
907 pass
908 except OSError as err:
909 EricMessageBox.critical(
910 self,
911 self.tr("Add new Python package"),
912 self.tr(
913 """<p>The package file <b>{0}</b> could"""
914 """ not be created. Aborting...</p>"""
915 """<p>Reason: {1}</p>"""
916 ).format(packageFile, str(err)),
917 )
918 return
919 self.project.appendFile(packageFile)
920 if packageFile:
921 self.sourceFile[str].emit(packageFile)
922
923 def __addSourceFiles(self):
924 """
925 Private method to add a source file to the project.
926 """
927 itm = self.model().item(self.currentIndex())
928 if isinstance(
929 itm, (ProjectBrowserFileItem, BrowserClassItem, BrowserMethodItem)
930 ):
931 dn = os.path.dirname(itm.fileName())
932 elif isinstance(
933 itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
934 ):
935 dn = itm.dirName()
936 else:
937 dn = None
938 self.project.addFiles("source", dn)
939
940 def __addSourceDirectory(self):
941 """
942 Private method to add source files of a directory to the project.
943 """
944 itm = self.model().item(self.currentIndex())
945 if isinstance(
946 itm, (ProjectBrowserFileItem, BrowserClassItem, BrowserMethodItem)
947 ):
948 dn = os.path.dirname(itm.fileName())
949 elif isinstance(
950 itm, (ProjectBrowserSimpleDirectoryItem, ProjectBrowserDirectoryItem)
951 ):
952 dn = itm.dirName()
953 else:
954 dn = None
955 self.project.addDirectory("source", dn)
956
957 def __deleteFile(self):
958 """
959 Private method to delete files from the project.
960 """
961 itmList = self.getSelectedItems()
962
963 files = []
964 fullNames = []
965 for itm in itmList:
966 fn2 = itm.fileName()
967 fullNames.append(fn2)
968 fn = self.project.getRelativePath(fn2)
969 files.append(fn)
970
971 from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
972
973 dlg = DeleteFilesConfirmationDialog(
974 self.parent(),
975 self.tr("Delete files"),
976 self.tr("Do you really want to delete these files from the project?"),
977 files,
978 )
979
980 if dlg.exec() == QDialog.DialogCode.Accepted:
981 for fn2, fn in zip(fullNames, files):
982 self.closeSourceWindow.emit(fn2)
983 self.project.deleteFile(fn)
984
985 ###########################################################################
986 ## Methods for the Checks submenu
987 ###########################################################################
988
989 def __showContextMenuCheck(self):
990 """
991 Private slot called before the checks menu is shown.
992 """
993 self.showMenu.emit("Checks", self.checksMenu)
994
995 ###########################################################################
996 ## Methods for the Show submenu
997 ###########################################################################
998
999 def __showCodeMetrics(self):
1000 """
1001 Private method to handle the code metrics context menu action.
1002 """
1003 itm = self.model().item(self.currentIndex())
1004 fn = itm.fileName()
1005
1006 from DataViews.CodeMetricsDialog import CodeMetricsDialog
1007
1008 self.codemetrics = CodeMetricsDialog()
1009 self.codemetrics.show()
1010 self.codemetrics.start(fn)
1011
1012 def __showCodeCoverage(self):
1013 """
1014 Private method to handle the code coverage context menu action.
1015 """
1016 itm = self.model().item(self.currentIndex())
1017 fn = itm.fileName()
1018 pfn = self.project.getMainScript(True)
1019
1020 files = set()
1021
1022 if pfn is not None:
1023 files |= set(Utilities.getCoverageFileNames(pfn))
1024
1025 if fn is not None:
1026 files |= set(Utilities.getCoverageFileNames(fn))
1027
1028 if list(files):
1029 if len(files) > 1:
1030 cfn, ok = QInputDialog.getItem(
1031 None,
1032 self.tr("Code Coverage"),
1033 self.tr("Please select a coverage file"),
1034 files,
1035 0,
1036 False,
1037 )
1038 if not ok:
1039 return
1040 else:
1041 cfn = files[0]
1042 else:
1043 return
1044
1045 from DataViews.PyCoverageDialog import PyCoverageDialog
1046
1047 self.codecoverage = PyCoverageDialog()
1048 self.codecoverage.show()
1049 self.codecoverage.start(cfn, fn)
1050
1051 def __showProfileData(self):
1052 """
1053 Private method to handle the show profile data context menu action.
1054 """
1055 itm = self.model().item(self.currentIndex())
1056 fn = itm.fileName()
1057 pfn = self.project.getMainScript(True)
1058
1059 files = set()
1060
1061 if pfn is not None:
1062 files |= set(Utilities.getProfileFileNames(pfn))
1063
1064 if fn is not None:
1065 files |= set(Utilities.getProfileFileNames(fn))
1066
1067 if list(files):
1068 if len(files) > 1:
1069 pfn, ok = QInputDialog.getItem(
1070 None,
1071 self.tr("Profile Data"),
1072 self.tr("Please select a profile file"),
1073 files,
1074 0,
1075 False,
1076 )
1077 if not ok:
1078 return
1079 else:
1080 pfn = files[0]
1081 else:
1082 return
1083
1084 from DataViews.PyProfileDialog import PyProfileDialog
1085
1086 self.profiledata = PyProfileDialog()
1087 self.profiledata.show()
1088 self.profiledata.start(pfn, fn)
1089
1090 ###########################################################################
1091 ## Methods for the Graphics submenu
1092 ###########################################################################
1093
1094 def __showContextMenuGraphics(self):
1095 """
1096 Private slot called before the checks menu is shown.
1097 """
1098 self.showMenu.emit("Graphics", self.graphicsMenu)
1099
1100 def __showClassDiagram(self):
1101 """
1102 Private method to handle the class diagram context menu action.
1103 """
1104 itm = self.model().item(self.currentIndex())
1105 try:
1106 fn = itm.fileName()
1107 except AttributeError:
1108 fn = itm.dirName()
1109 res = EricMessageBox.yesNo(
1110 self,
1111 self.tr("Class Diagram"),
1112 self.tr("""Include class attributes?"""),
1113 yesDefault=True,
1114 )
1115
1116 from Graphics.UMLDialog import UMLDialog, UMLDialogType
1117
1118 self.classDiagram = UMLDialog(
1119 UMLDialogType.CLASS_DIAGRAM, self.project, fn, self, noAttrs=not res
1120 )
1121 self.classDiagram.show()
1122
1123 def __showImportsDiagram(self):
1124 """
1125 Private method to handle the imports diagram context menu action.
1126 """
1127 itm = self.model().item(self.currentIndex())
1128 try:
1129 fn = itm.fileName()
1130 except AttributeError:
1131 fn = itm.dirName()
1132 package = fn if os.path.isdir(fn) else os.path.dirname(fn)
1133 res = EricMessageBox.yesNo(
1134 self,
1135 self.tr("Imports Diagram"),
1136 self.tr("""Include imports from external modules?"""),
1137 )
1138
1139 from Graphics.UMLDialog import UMLDialog, UMLDialogType
1140
1141 self.importsDiagram = UMLDialog(
1142 UMLDialogType.IMPORTS_DIAGRAM,
1143 self.project,
1144 package,
1145 self,
1146 showExternalImports=res,
1147 )
1148 self.importsDiagram.show()
1149
1150 def __showPackageDiagram(self):
1151 """
1152 Private method to handle the package diagram context menu action.
1153 """
1154 itm = self.model().item(self.currentIndex())
1155 try:
1156 fn = itm.fileName()
1157 except AttributeError:
1158 fn = itm.dirName()
1159 package = fn if os.path.isdir(fn) else os.path.dirname(fn)
1160 res = EricMessageBox.yesNo(
1161 self,
1162 self.tr("Package Diagram"),
1163 self.tr("""Include class attributes?"""),
1164 yesDefault=True,
1165 )
1166
1167 from Graphics.UMLDialog import UMLDialog, UMLDialogType
1168
1169 self.packageDiagram = UMLDialog(
1170 UMLDialogType.PACKAGE_DIAGRAM, self.project, package, self, noAttrs=not res
1171 )
1172 self.packageDiagram.show()
1173
1174 def __showApplicationDiagram(self):
1175 """
1176 Private method to handle the application diagram context menu action.
1177 """
1178 res = EricMessageBox.yesNo(
1179 self,
1180 self.tr("Application Diagram"),
1181 self.tr("""Include module names?"""),
1182 yesDefault=True,
1183 )
1184
1185 from Graphics.UMLDialog import UMLDialog, UMLDialogType
1186
1187 self.applicationDiagram = UMLDialog(
1188 UMLDialogType.APPLICATION_DIAGRAM, self.project, self, noModules=not res
1189 )
1190 self.applicationDiagram.show()
1191
1192 def __loadDiagram(self):
1193 """
1194 Private slot to load a diagram from file.
1195 """
1196 from Graphics.UMLDialog import UMLDialog, UMLDialogType
1197
1198 self.loadedDiagram = None
1199 loadedDiagram = UMLDialog(UMLDialogType.NO_DIAGRAM, self.project, parent=self)
1200 if loadedDiagram.load():
1201 self.loadedDiagram = loadedDiagram
1202 self.loadedDiagram.show(fromFile=True)
1203
1204 ###########################################################################
1205 ## Methods for the Start submenu
1206 ###########################################################################
1207
1208 def __contextMenuRunScript(self):
1209 """
1210 Private method to run the editor script.
1211 """
1212 fn = self.model().item(self.currentIndex()).fileName()
1213 ericApp().getObject("DebugUI").doRun(False, script=fn)
1214
1215 def __contextMenuDebugScript(self):
1216 """
1217 Private method to debug the editor script.
1218 """
1219 fn = self.model().item(self.currentIndex()).fileName()
1220 ericApp().getObject("DebugUI").doDebug(False, script=fn)
1221
1222 def __contextMenuProfileScript(self):
1223 """
1224 Private method to profile the editor script.
1225 """
1226 fn = self.model().item(self.currentIndex()).fileName()
1227 ericApp().getObject("DebugUI").doProfile(False, script=fn)
1228
1229 def __contextMenuCoverageScript(self):
1230 """
1231 Private method to run a coverage test of the editor script.
1232 """
1233 fn = self.model().item(self.currentIndex()).fileName()
1234 ericApp().getObject("DebugUI").doCoverage(False, script=fn)
1235
1236 ###########################################################################
1237 ## Methods for the Code Formatting submenu
1238 ###########################################################################
1239
1240 def __showContextMenuFormatting(self):
1241 """
1242 Private slot called before the Code Formatting menu is shown.
1243 """
1244 self.showMenu.emit("Formatting", self.formattingMenu)
1245
1246 def __performFormatWithBlack(self, action):
1247 """
1248 Private method to format the selected project sources using the 'Black' tool.
1249
1250 Following actions are supported.
1251 <ul>
1252 <li>BlackFormattingAction.Format - the code reformatting is performed</li>
1253 <li>BlackFormattingAction.Check - a check is performed, if code formatting
1254 is necessary</li>
1255 <li>BlackFormattingAction.Diff - a unified diff of potential code formatting
1256 changes is generated</li>
1257 </ul>
1258
1259 @param action formatting operation to be performed
1260 @type BlackFormattingAction
1261 """
1262 from CodeFormatting.BlackConfigurationDialog import BlackConfigurationDialog
1263 from CodeFormatting.BlackFormattingDialog import BlackFormattingDialog
1264
1265 files = [
1266 itm.fileName()
1267 for itm in self.getSelectedItems(
1268 [
1269 BrowserFileItem,
1270 BrowserClassItem,
1271 BrowserMethodItem,
1272 BrowserClassAttributeItem,
1273 BrowserImportItem,
1274 ]
1275 )
1276 if itm.isPython3File()
1277 ]
1278 if not files:
1279 # called for a directory
1280 itm = self.model().item(self.currentIndex())
1281 dirName = itm.dirName()
1282 files = [
1283 f
1284 for f in self.project.getProjectFiles("SOURCES", normalized=True)
1285 if f.startswith(dirName)
1286 ]
1287
1288 vm = ericApp().getObject("ViewManager")
1289 files = [fn for fn in files if vm.checkFileDirty(fn)]
1290
1291 if files:
1292 dlg = BlackConfigurationDialog(withProject=True)
1293 if dlg.exec() == QDialog.DialogCode.Accepted:
1294 config = dlg.getConfiguration()
1295
1296 formattingDialog = BlackFormattingDialog(
1297 config, files, project=self.project, action=action
1298 )
1299 formattingDialog.exec()
1300 else:
1301 EricMessageBox.information(
1302 self,
1303 self.tr("Code Formatting"),
1304 self.tr("""There are no files left for reformatting."""),
1305 )

eric ide

mercurial