src/eric7/Project/ProjectBrowser.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2002 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the project browser part of the eric UI.
8 """
9
10 from PyQt6.QtCore import Qt
11 from PyQt6.QtGui import QColor
12 from PyQt6.QtWidgets import QApplication
13
14 from EricWidgets.EricTabWidget import EricTabWidget
15 from EricWidgets.EricLed import EricClickableLed
16
17 import UI.PixmapCache
18 import Preferences
19
20 from .ProjectBrowserFlags import (
21 SourcesBrowserFlag, FormsBrowserFlag, ResourcesBrowserFlag,
22 TranslationsBrowserFlag, InterfacesBrowserFlag, OthersBrowserFlag,
23 ProtocolsBrowserFlag, AllBrowsersFlag
24 )
25
26
27 class ProjectBrowser(EricTabWidget):
28 """
29 Class implementing the project browser part of the eric UI.
30
31 It generates a widget with up to seven tabs. The individual tabs contain
32 the project sources browser, the project forms browser,
33 the project resources browser, the project translations browser,
34 the project interfaces (IDL) browser and a browser for stuff,
35 that doesn't fit these categories. Optionally it contains an additional
36 tab with the file system browser.
37 """
38 def __init__(self, project, parent=None):
39 """
40 Constructor
41
42 @param project reference to the project object
43 @param parent parent widget (QWidget)
44 """
45 EricTabWidget.__init__(self, parent)
46 self.project = project
47
48 self.setWindowIcon(UI.PixmapCache.getIcon("eric"))
49
50 self.setUsesScrollButtons(True)
51
52 self.vcsStatusIndicator = EricClickableLed(self)
53 self.setCornerWidget(self.vcsStatusIndicator, Qt.Corner.TopLeftCorner)
54 self.vcsStatusIndicator.clicked.connect(
55 self.__vcsStatusIndicatorClicked)
56 self.vcsStatusColorNames = {
57 "A": "VcsAdded",
58 "M": "VcsModified",
59 "O": "VcsRemoved",
60 "R": "VcsReplaced",
61 "U": "VcsUpdate",
62 "Z": "VcsConflict",
63 }
64 self.vcsStatusText = {
65 " ": self.tr("up to date"),
66 "A": self.tr("files added"),
67 "M": self.tr("local modifications"),
68 "O": self.tr("files removed"),
69 "R": self.tr("files replaced"),
70 "U": self.tr("update required"),
71 "Z": self.tr("conflict"),
72 }
73 self.__vcsStateChanged(" ")
74
75 # step 1: create all the individual browsers
76 from .ProjectSourcesBrowser import ProjectSourcesBrowser
77 from .ProjectFormsBrowser import ProjectFormsBrowser
78 from .ProjectTranslationsBrowser import ProjectTranslationsBrowser
79 from .ProjectResourcesBrowser import ProjectResourcesBrowser
80 from .ProjectInterfacesBrowser import ProjectInterfacesBrowser
81 from .ProjectOthersBrowser import ProjectOthersBrowser
82 from .ProjectProtocolsBrowser import ProjectProtocolsBrowser
83 # sources browser
84 self.psBrowser = ProjectSourcesBrowser(self.project)
85 # forms browser
86 self.pfBrowser = ProjectFormsBrowser(self.project)
87 # resources browser
88 self.prBrowser = ProjectResourcesBrowser(self.project)
89 # translations browser
90 self.ptBrowser = ProjectTranslationsBrowser(self.project)
91 # interfaces (IDL) browser
92 self.piBrowser = ProjectInterfacesBrowser(self.project)
93 # protocols (protobuf) browser
94 self.ppBrowser = ProjectProtocolsBrowser(self.project)
95 # others browser
96 self.poBrowser = ProjectOthersBrowser(self.project)
97
98 # step 2: connect all the browsers
99 # connect the sources browser
100 self.project.projectClosed.connect(self.psBrowser._projectClosed)
101 self.project.projectOpened.connect(self.psBrowser._projectOpened)
102 self.project.newProject.connect(self.psBrowser._newProject)
103 self.project.reinitVCS.connect(self.psBrowser._initMenusAndVcs)
104 self.project.projectPropertiesChanged.connect(
105 self.psBrowser._initMenusAndVcs)
106
107 # connect the forms browser
108 self.project.projectClosed.connect(self.pfBrowser._projectClosed)
109 self.project.projectOpened.connect(self.pfBrowser._projectOpened)
110 self.project.newProject.connect(self.pfBrowser._newProject)
111 self.project.reinitVCS.connect(self.pfBrowser._initMenusAndVcs)
112 self.project.projectPropertiesChanged.connect(
113 self.pfBrowser._initMenusAndVcs)
114
115 # connect the resources browser
116 self.project.projectClosed.connect(self.prBrowser._projectClosed)
117 self.project.projectOpened.connect(self.prBrowser._projectOpened)
118 self.project.newProject.connect(self.prBrowser._newProject)
119 self.project.reinitVCS.connect(self.prBrowser._initMenusAndVcs)
120 self.project.projectPropertiesChanged.connect(
121 self.prBrowser._initMenusAndVcs)
122
123 # connect the translations browser
124 self.project.projectClosed.connect(self.ptBrowser._projectClosed)
125 self.project.projectOpened.connect(self.ptBrowser._projectOpened)
126 self.project.newProject.connect(self.ptBrowser._newProject)
127 self.project.reinitVCS.connect(self.ptBrowser._initMenusAndVcs)
128 self.project.projectPropertiesChanged.connect(
129 self.ptBrowser._initMenusAndVcs)
130
131 # connect the interfaces (IDL) browser
132 self.project.projectClosed.connect(self.piBrowser._projectClosed)
133 self.project.projectOpened.connect(self.piBrowser._projectOpened)
134 self.project.newProject.connect(self.piBrowser._newProject)
135 self.project.reinitVCS.connect(self.piBrowser._initMenusAndVcs)
136 self.project.projectPropertiesChanged.connect(
137 self.piBrowser._initMenusAndVcs)
138
139 # connect the protocols (protobuf) browser
140 self.project.projectClosed.connect(self.ppBrowser._projectClosed)
141 self.project.projectOpened.connect(self.ppBrowser._projectOpened)
142 self.project.newProject.connect(self.ppBrowser._newProject)
143 self.project.reinitVCS.connect(self.ppBrowser._initMenusAndVcs)
144 self.project.projectPropertiesChanged.connect(
145 self.ppBrowser._initMenusAndVcs)
146
147 # connect the others browser
148 self.project.projectClosed.connect(self.poBrowser._projectClosed)
149 self.project.projectOpened.connect(self.poBrowser._projectOpened)
150 self.project.newProject.connect(self.poBrowser._newProject)
151 self.project.reinitVCS.connect(self.poBrowser._initMenusAndVcs)
152 self.project.projectPropertiesChanged.connect(
153 self.poBrowser._initMenusAndVcs)
154
155 # add signal connection to ourselves
156 self.project.projectOpened.connect(self.__projectOpened)
157 self.project.projectClosed.connect(self.__projectClosed)
158 self.project.newProject.connect(self.__newProject)
159 self.project.projectPropertiesChanged.connect(
160 self.__projectPropertiesChanged)
161 self.currentChanged.connect(self.__currentChanged)
162 self.project.getModel().vcsStateChanged.connect(self.__vcsStateChanged)
163
164 self.__currentBrowsersFlags = 0
165 self.__projectPropertiesChanged()
166 self.setCurrentIndex(0)
167
168 def __setBrowsersAvailable(self, browserFlags):
169 """
170 Private method to add selected browsers to the project browser.
171
172 @param browserFlags flags indicating the browsers to add (integer)
173 """
174 # step 1: remove all tabs
175 while self.count() > 0:
176 self.removeTab(0)
177
178 # step 2: add browsers
179 if browserFlags & SourcesBrowserFlag:
180 index = self.addTab(
181 self.psBrowser,
182 UI.PixmapCache.getIcon("projectSources"), '')
183 self.setTabToolTip(index, self.psBrowser.windowTitle())
184
185 if browserFlags & FormsBrowserFlag:
186 index = self.addTab(
187 self.pfBrowser,
188 UI.PixmapCache.getIcon("projectForms"), '')
189 self.setTabToolTip(index, self.pfBrowser.windowTitle())
190
191 if browserFlags & ResourcesBrowserFlag:
192 index = self.addTab(
193 self.prBrowser,
194 UI.PixmapCache.getIcon("projectResources"), '')
195 self.setTabToolTip(index, self.prBrowser.windowTitle())
196
197 if browserFlags & TranslationsBrowserFlag:
198 index = self.addTab(
199 self.ptBrowser,
200 UI.PixmapCache.getIcon("projectTranslations"), '')
201 self.setTabToolTip(index, self.ptBrowser.windowTitle())
202
203 if browserFlags & InterfacesBrowserFlag:
204 index = self.addTab(
205 self.piBrowser,
206 UI.PixmapCache.getIcon("projectInterfaces"), '')
207 self.setTabToolTip(index, self.piBrowser.windowTitle())
208
209 if browserFlags & ProtocolsBrowserFlag:
210 index = self.addTab(
211 self.ppBrowser,
212 UI.PixmapCache.getIcon("protobuf"), '')
213 self.setTabToolTip(index, self.ppBrowser.windowTitle())
214
215 if browserFlags & OthersBrowserFlag:
216 index = self.addTab(
217 self.poBrowser,
218 UI.PixmapCache.getIcon("projectOthers"), '')
219 self.setTabToolTip(index, self.poBrowser.windowTitle())
220
221 QApplication.processEvents()
222
223 def __currentChanged(self, index):
224 """
225 Private slot to handle the currentChanged(int) signal.
226
227 @param index index of the tab (integer)
228 """
229 if index > -1:
230 browser = self.widget(index)
231 if browser is not None:
232 browser.layoutDisplay()
233
234 def __projectOpened(self):
235 """
236 Private slot to handle the projectOpened signal.
237 """
238 self.__projectPropertiesChanged()
239 self.setCurrentIndex(0)
240 self.__vcsStateChanged(" ")
241
242 def __projectClosed(self):
243 """
244 Private slot to handle the projectClosed signal.
245 """
246 self.__projectPropertiesChanged()
247 self.setCurrentIndex(0)
248 self.__setSourcesIcon()
249 self.__vcsStateChanged(" ")
250
251 def __newProject(self):
252 """
253 Private slot to handle the newProject signal.
254 """
255 self.setCurrentIndex(0)
256 self.__projectPropertiesChanged()
257
258 def __projectPropertiesChanged(self):
259 """
260 Private slot to handle the projectPropertiesChanged signal.
261 """
262 flags = (
263 Preferences.getProjectBrowserFlags(self.project.getProjectType())
264 if self.project.isOpen() else
265 AllBrowsersFlag
266 )
267
268 if flags != self.__currentBrowsersFlags:
269 self.__currentBrowsersFlags = flags
270 self.__setBrowsersAvailable(flags)
271
272 endIndex = self.count()
273 for index in range(endIndex):
274 self.setTabEnabled(index, self.project.isOpen())
275
276 self.__setSourcesIcon()
277
278 def __setSourcesIcon(self):
279 """
280 Private method to set the right icon for the sources browser tab.
281 """
282 if not self.project.isOpen():
283 icon = UI.PixmapCache.getIcon("projectSources")
284 else:
285 if self.project.getProjectLanguage() == "Python3":
286 if self.project.isMixedLanguageProject():
287 icon = UI.PixmapCache.getIcon("projectSourcesPyMixed")
288 else:
289 icon = UI.PixmapCache.getIcon("projectSourcesPy")
290 elif self.project.getProjectLanguage() == "MicroPython":
291 icon = UI.PixmapCache.getIcon("micropython")
292 elif self.project.getProjectLanguage() == "Ruby":
293 if self.project.isMixedLanguageProject():
294 icon = UI.PixmapCache.getIcon("projectSourcesRbMixed")
295 else:
296 icon = UI.PixmapCache.getIcon("projectSourcesRb")
297 elif self.project.getProjectLanguage() == "JavaScript":
298 icon = UI.PixmapCache.getIcon("projectSourcesJavaScript")
299 else:
300 icon = UI.PixmapCache.getIcon("projectSources")
301 self.setTabIcon(self.indexOf(self.psBrowser), icon)
302
303 def handleEditorChanged(self, fn):
304 """
305 Public slot to handle the editorChanged signal.
306
307 @param fn filename of the changed file (string)
308 """
309 if Preferences.getProject("FollowEditor"):
310 if self.project.isProjectSource(fn):
311 self.psBrowser.selectFile(fn)
312 elif self.project.isProjectForm(fn):
313 self.pfBrowser.selectFile(fn)
314 elif self.project.isProjectResource(fn):
315 self.prBrowser.selectFile(fn)
316 elif self.project.isProjectInterface(fn):
317 self.piBrowser.selectFile(fn)
318 elif self.project.isProjectProtocol(fn):
319 self.ppBrowser.selectFile(fn)
320
321 def handleEditorLineChanged(self, fn, lineno):
322 """
323 Public slot to handle the editorLineChanged signal.
324
325 @param fn filename of the changed file (string)
326 @param lineno one based line number of the item (integer)
327 """
328 if (
329 Preferences.getProject("FollowEditor") and
330 Preferences.getProject("FollowCursorLine") and
331 self.project.isProjectSource(fn)
332 ):
333 self.psBrowser.selectFileLine(fn, lineno)
334
335 def getProjectBrowsers(self):
336 """
337 Public method to get references to the individual project browsers.
338
339 @return list of references to project browsers
340 """
341 return [self.psBrowser, self.pfBrowser, self.prBrowser,
342 self.ptBrowser, self.piBrowser, self.ppBrowser,
343 self.poBrowser]
344
345 def getProjectBrowser(self, name):
346 """
347 Public method to get a reference to the named project browser.
348
349 @param name name of the requested project browser (string).
350 Valid names are "sources, forms, resources, translations,
351 interfaces, protocols, others".
352 @return reference to the requested browser or None
353 """
354 return {
355 "sources": self.psBrowser,
356 "forms": self.pfBrowser,
357 "resources": self.prBrowser,
358 "translations": self.ptBrowser,
359 "interfaces": self.piBrowser,
360 "protocols": self.ppBrowser,
361 "others": self.poBrowser,
362 }.get(name, None)
363
364 def getProjectBrowserNames(self):
365 """
366 Public method to get the names of the various project browsers.
367
368 @return list of project browser names (list of string)
369 """
370 return ["sources", "forms", "resources",
371 "translations", "interfaces", "protocols", "others"]
372
373 def handlePreferencesChanged(self):
374 """
375 Public slot used to handle the preferencesChanged signal.
376 """
377 self.__projectPropertiesChanged()
378 self.__vcsStateChanged(self.currentVcsStatus)
379
380 def __vcsStateChanged(self, state):
381 """
382 Private slot to handle a change in the vcs state.
383
384 @param state new vcs state (string)
385 """
386 self.currentVcsStatus = state
387 if state == " " or state not in self.vcsStatusColorNames:
388 self.vcsStatusIndicator.setColor(QColor(Qt.GlobalColor.lightGray))
389 else:
390 self.vcsStatusIndicator.setColor(
391 Preferences.getProjectBrowserColour(
392 self.vcsStatusColorNames[state]))
393 if state not in self.vcsStatusText:
394 self.vcsStatusIndicator.setToolTip(self.tr("unknown status"))
395 else:
396 self.vcsStatusIndicator.setToolTip(self.vcsStatusText[state])
397
398 def __vcsStatusIndicatorClicked(self, pos):
399 """
400 Private slot to react upon clicks on the VCS indicator LED.
401
402 @param pos position of the click (QPoint)
403 """
404 vcs = self.project.getVcs()
405 if vcs:
406 if self.currentVcsStatus == " ":
407 # call log browser dialog
408 vcs.vcsLogBrowser(self.project.getProjectPath())
409 else:
410 # call status dialog
411 vcs.vcsStatus(self.project.getProjectPath())

eric ide

mercurial