Wed, 23 Nov 2022 16:07:16 +0100
Continued refactoring of the project browser related code in order to extract some as plugins later on.
--- a/eric7.epj Wed Nov 23 11:09:33 2022 +0100 +++ b/eric7.epj Wed Nov 23 16:07:16 2022 +0100 @@ -1906,6 +1906,7 @@ "src/eric7/Project/ProjectBrowser.py", "src/eric7/Project/ProjectBrowserFlags.py", "src/eric7/Project/ProjectBrowserModel.py", + "src/eric7/Project/ProjectBrowserRepositoryItem.py", "src/eric7/Project/ProjectBrowserSortFilterProxyModel.py", "src/eric7/Project/ProjectFile.py", "src/eric7/Project/ProjectFormsBrowser.py",
--- a/src/eric7/Project/ProjectBrowser.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectBrowser.py Wed Nov 23 16:07:16 2022 +0100 @@ -7,12 +7,15 @@ Module implementing the project browser part of the eric UI. """ +import contextlib + from PyQt6.QtCore import Qt, pyqtSignal from PyQt6.QtGui import QColor from PyQt6.QtWidgets import QApplication from eric7 import Preferences from eric7.EricGui import EricPixmapCache +from eric7.EricWidgets import EricMessageBox from eric7.EricWidgets.EricLed import EricClickableLed from eric7.EricWidgets.EricTabWidget import EricTabWidget @@ -26,6 +29,7 @@ SourcesBrowserFlag, TranslationsBrowserFlag, ) +from .ProjectBrowserRepositoryItem import ProjectBrowserRepositoryItem from .ProjectFormsBrowser import ProjectFormsBrowser from .ProjectInterfacesBrowser import ProjectInterfacesBrowser from .ProjectOthersBrowser import ProjectOthersBrowser @@ -135,23 +139,20 @@ } self.__vcsStateChanged(" ") + self.__browserRepository = {} + # create all the individual browsers - self.__browsers = { - # sources browser - "sources": ProjectSourcesBrowser(self.project, self), - # forms browser - "forms": ProjectFormsBrowser(self.project, self), - # resources browser - "resources": ProjectResourcesBrowser(self.project, self), - # translations browser - "translations": ProjectTranslationsBrowser(self.project, self), - # others browser - "others": ProjectOthersBrowser(self.project, self), - # interfaces (IDL) browser - "interfaces": ProjectInterfacesBrowser(self.project, self), - # protocols (protobuf) browser - "protocols": ProjectProtocolsBrowser(self.project, self), - } + for browserClass in ( + ProjectSourcesBrowser, + ProjectFormsBrowser, + ProjectResourcesBrowser, + ProjectTranslationsBrowser, + ProjectOthersBrowser, + # TODO: move the next two browsers to plugins + ProjectInterfacesBrowser, + ProjectProtocolsBrowser, + ): + browserClass(self.project, self) # add signal connection to ourselves self.project.projectOpened.connect(self.__projectOpened) @@ -165,6 +166,82 @@ self.__projectPropertiesChanged() self.setCurrentIndex(0) + def addTypedProjectBrowser(self, browserType, projectBrowserItem): + """ + Public method to add a project browser type to the browser repository. + + @param browserType type of the project browser + @type str + @param projectBrowserItem data structure containing the type specific data + @type ProjectBrowserRepositoryItem + @exception TypeError raised to signal a wrong type for the project browser item + """ + if not isinstance(projectBrowserItem, ProjectBrowserRepositoryItem): + raise TypeError( + "'projectBrowserItem' must be an instance of" + " 'ProjectBrowserRepositoryItem'." + ) + + if browserType in self.__browserRepository: + EricMessageBox.critical( + self.ui, + self.tr("Add Project Browser Type"), + self.tr( + "<p>The project browser type <b>{0}</b> has already been added." + " This attempt will be ignored.</p>" + ), + ) + else: + self.__browserRepository[browserType] = projectBrowserItem + + def removeTypedProjectBrowser(self, browserType): + """ + Public method to remove a browser type from the browsers repository. + + Note: If the browser type is not contained in the repository, the request to + remove it will be ignored silently. + + @param browserType project browser type + @type str + """ + with contextlib.suppress(KeyError): + browserIndex = self.indexOf(self.getProjectBrowser(browserType)) + if browserIndex >= 0: + self.removeTab(browserIndex) + del self.__browserRepository[browserType] + + def getProjectBrowsers(self): + """ + Public method to get references to the individual project browsers. + + @return list of references to project browsers + @rtype list of ProjectBaseBrowser + """ + return [itm.projectBrowser for itm in self.__browserRepository.items()] + + def getProjectBrowser(self, browserType): + """ + Public method to get a reference to the project browser of given type. + + @param browserType type of the requested project browser + @type str + @return reference to the requested browser or None + @rtype ProjectBaseBrowser or None + """ + try: + return self.__browserRepository[browserType].projectBrowser + except KeyError: + return None + + def getProjectBrowserNames(self): + """ + Public method to get the types of the various project browsers. + + @return list of project browser types + @rtype list of str + """ + return list(self.__browserRepository.keys()) + def __setBrowsersAvailable(self, browserFlags): """ Private method to add selected browsers to the project browser. @@ -176,55 +253,83 @@ self.removeTab(0) # step 2: add browsers + # TODO: change the logic after browser flags have been eliminated if browserFlags & SourcesBrowserFlag: index = self.addTab( - self.__browsers["sources"], - EricPixmapCache.getIcon("projectSources"), + self.__browserRepository["sources"].projectBrowser, + self.__browserRepository["sources"].getIcon(), "", ) - self.setTabToolTip(index, self.__browsers["sources"].windowTitle()) + self.setTabToolTip( + index, + self.__browserRepository["sources"].projectBrowser.windowTitle(), + ) if browserFlags & FormsBrowserFlag: index = self.addTab( - self.__browsers["forms"], EricPixmapCache.getIcon("projectForms"), "" + self.__browserRepository["forms"].projectBrowser, + self.__browserRepository["forms"].getIcon(), + "", ) - self.setTabToolTip(index, self.__browsers["forms"].windowTitle()) + self.setTabToolTip( + index, + self.__browserRepository["forms"].projectBrowser.windowTitle(), + ) if browserFlags & ResourcesBrowserFlag: index = self.addTab( - self.__browsers["resources"], - EricPixmapCache.getIcon("projectResources"), + self.__browserRepository["resources"].projectBrowser, + self.__browserRepository["resources"].getIcon(), "", ) - self.setTabToolTip(index, self.__browsers["resources"].windowTitle()) + self.setTabToolTip( + index, + self.__browserRepository["resources"].projectBrowser.windowTitle(), + ) if browserFlags & TranslationsBrowserFlag: index = self.addTab( - self.__browsers["translations"], - EricPixmapCache.getIcon("projectTranslations"), + self.__browserRepository["translations"].projectBrowser, + self.__browserRepository["translations"].getIcon(), "", ) - self.setTabToolTip(index, self.__browsers["translations"].windowTitle()) + self.setTabToolTip( + index, + self.__browserRepository["translations"].projectBrowser.windowTitle(), + ) if browserFlags & InterfacesBrowserFlag: index = self.addTab( - self.__browsers["interfaces"], - EricPixmapCache.getIcon("projectInterfaces"), + self.__browserRepository["interfaces"].projectBrowser, + self.__browserRepository["interfaces"].getIcon(), "", ) - self.setTabToolTip(index, self.__browsers["interfaces"].windowTitle()) + self.setTabToolTip( + index, + self.__browserRepository["interfaces"].projectBrowser.windowTitle(), + ) if browserFlags & ProtocolsBrowserFlag: index = self.addTab( - self.__browsers["protocols"], EricPixmapCache.getIcon("protobuf"), "" + self.__browserRepository["protocols"].projectBrowser, + self.__browserRepository["protocols"].getIcon(), + "", ) - self.setTabToolTip(index, self.__browsers["protocols"].windowTitle()) + self.setTabToolTip( + index, + self.__browserRepository["protocols"].projectBrowser.windowTitle(), + ) if browserFlags & OthersBrowserFlag: index = self.addTab( - self.__browsers["others"], EricPixmapCache.getIcon("projectOthers"), "" + self.__browserRepository["others"].projectBrowser, + self.__browserRepository["others"].getIcon(), + "", ) - self.setTabToolTip(index, self.__browsers["others"].windowTitle()) + self.setTabToolTip( + index, + self.__browserRepository["others"].projectBrowser.windowTitle(), + ) QApplication.processEvents() @@ -283,6 +388,7 @@ self.__setSourcesIcon() + # TODO: move the logic to determine the icon to the sources browser. def __setSourcesIcon(self): """ Private method to set the right icon for the sources browser tab. @@ -306,7 +412,7 @@ icon = EricPixmapCache.getIcon("projectSourcesJavaScript") else: icon = EricPixmapCache.getIcon("projectSources") - self.setTabIcon(self.indexOf(self.__browsers["sources"]), icon) + self.setTabIcon(self.indexOf(self.getProjectBrowser("sources")), icon) def handleEditorChanged(self, fn): """ @@ -322,7 +428,7 @@ if cat not in ("TRANSLATIONS", "OTHERS") ): if self.project.isProjectCategory(fn, fileCategory): - self.__browsers[fileCategory.lower()].selectFile(fn) + self.getProjectBrowser(fileCategory.lower()).selectFile(fn) break def handleEditorLineChanged(self, fn, lineno): @@ -337,36 +443,7 @@ and Preferences.getProject("FollowCursorLine") and self.project.isProjectCategory(fn, "SOURCES") ): - self.__browsers["sources"].selectFileLine(fn, lineno) - - def getProjectBrowsers(self): - """ - Public method to get references to the individual project browsers. - - @return list of references to project browsers - @rtype list of ProjectBaseBrowser - """ - return list(self.__browsers.items()) - - def getProjectBrowser(self, name): - """ - Public method to get a reference to the named project browser. - - @param name name of the requested project browser. - @type str - @return reference to the requested browser or None - @rtype ProjectBaseBrowser or None - """ - return self.__browsers.get(name, None) - - def getProjectBrowserNames(self): - """ - Public method to get the names of the various project browsers. - - @return list of project browser names - @rtype list of str - """ - return list(self.__browsers.keys()) + self.getProjectBrowser("sources").selectFileLine(fn, lineno) def handlePreferencesChanged(self): """
--- a/src/eric7/Project/ProjectBrowserModel.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectBrowserModel.py Wed Nov 23 16:07:16 2022 +0100 @@ -28,15 +28,15 @@ ProjectBrowserItemDirectory = 101 ProjectBrowserItemFile = 102 -# TODO: change to project browser provided IDs -ProjectBrowserNoType = 0 -ProjectBrowserSourceType = 1 -ProjectBrowserFormType = 2 -ProjectBrowserInterfaceType = 3 -ProjectBrowserTranslationType = 4 -ProjectBrowserOthersType = 5 -ProjectBrowserResourceType = 6 -ProjectBrowserProtocolsType = 7 +# TODO: move these definitions to the project browser repository +ProjectBrowserNoType = "none" +ProjectBrowserSourceType = "source" +ProjectBrowserFormType = "form" +ProjectBrowserInterfaceType = "interface" +ProjectBrowserTranslationType = "translation" +ProjectBrowserOthersType = "other" +ProjectBrowserResourceType = "resource" +ProjectBrowserProtocolsType = "protocol" class ProjectBrowserItemMixin: @@ -257,6 +257,8 @@ self.inRefresh = False + # TODO: move this to ProjectBrowser (ProjectBrowserRepository) + # mapping of file category to project browser type self.projectBrowserTypes = { "SOURCES": ProjectBrowserSourceType, "FORMS": ProjectBrowserFormType,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/eric7/Project/ProjectBrowserRepositoryItem.py Wed Nov 23 16:07:16 2022 +0100 @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a data structure holding the data associated with a project browser +type. +""" + +from dataclasses import dataclass +from typing import Callable + +from .ProjectBaseBrowser import ProjectBaseBrowser + + +@dataclass +class ProjectBrowserRepositoryItem: + """ + Class holding the data associated with a project browser type. + """ + projectBrowser: ProjectBaseBrowser + projectBrowserUserString: str + fileCategory: str + getIcon: Callable +
--- a/src/eric7/Project/ProjectFormsBrowser.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectFormsBrowser.py Wed Nov 23 16:07:16 2022 +0100 @@ -33,6 +33,7 @@ ProjectBrowserFormType, ProjectBrowserSimpleDirectoryItem, ) +from .ProjectBrowserRepositoryItem import ProjectBrowserRepositoryItem class ProjectFormsBrowser(ProjectBaseBrowser): @@ -144,6 +145,17 @@ ), ) + # Add the project browser type to the browser type repository. + projectBrowser.addTypedProjectBrowser( + "forms", + ProjectBrowserRepositoryItem( + projectBrowser=self, + projectBrowserUserString=self.tr("Forms Browser"), + fileCategory="FORMS", + getIcon=self.getIcon, + ), + ) + # Connect signals of Project. project.projectClosed.connect(self.__resetUiCompiler) project.projectPropertiesChanged.connect(self.__resetUiCompiler) @@ -165,6 +177,15 @@ self.uipreview.connect(projectBrowser.uipreview) self.trpreview[list].connect(projectBrowser.trpreview[list]) + def getIcon(self): + """ + Public method to get an icon for the project browser. + + @return icon for the browser + @rtype QIcon + """ + return EricPixmapCache.getIcon("projectForms") + def _createPopupMenus(self): """ Protected overloaded method to generate the popup menu.
--- a/src/eric7/Project/ProjectInterfacesBrowser.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectInterfacesBrowser.py Wed Nov 23 16:07:16 2022 +0100 @@ -37,6 +37,7 @@ ProjectBrowserInterfaceType, ProjectBrowserSimpleDirectoryItem, ) +from .ProjectBrowserRepositoryItem import ProjectBrowserRepositoryItem class ProjectInterfacesBrowser(ProjectBaseBrowser): @@ -101,6 +102,17 @@ ), ) + # Add the project browser type to the browser type repository. + projectBrowser.addTypedProjectBrowser( + "interfaces", + ProjectBrowserRepositoryItem( + projectBrowser=self, + projectBrowserUserString=self.tr("Interfaces (IDL) Browser"), + fileCategory="INTERFACES", + getIcon=self.getIcon, + ), + ) + # Connect signals of Project. project.prepareRepopulateItem.connect(self._prepareRepopulateItem) project.completeRepopulateItem.connect(self._completeRepopulateItem) @@ -120,6 +132,15 @@ self.sourceFile[str].connect(projectBrowser.sourceFile[str]) self.sourceFile[str, int].connect(projectBrowser.sourceFile[str, int]) + def getIcon(self): + """ + Public method to get an icon for the project browser. + + @return icon for the browser + @rtype QIcon + """ + return EricPixmapCache.getIcon("projectInterfaces") + def _createPopupMenus(self): """ Protected overloaded method to generate the popup menu.
--- a/src/eric7/Project/ProjectOthersBrowser.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectOthersBrowser.py Wed Nov 23 16:07:16 2022 +0100 @@ -16,6 +16,7 @@ from PyQt6.QtWidgets import QDialog, QMenu from eric7 import Preferences +from eric7.EricGui import EricPixmapCache from eric7.EricWidgets import EricMessageBox from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog from eric7.Utilities import MimeTypes @@ -28,6 +29,7 @@ ProjectBrowserOthersType, ProjectBrowserSimpleDirectoryItem, ) +from .ProjectBrowserRepositoryItem import ProjectBrowserRepositoryItem class ProjectOthersBrowser(ProjectBaseBrowser): @@ -80,6 +82,17 @@ ), ) + # Add the project browser type to the browser type repository. + projectBrowser.addTypedProjectBrowser( + "others", + ProjectBrowserRepositoryItem( + projectBrowser=self, + projectBrowserUserString=self.tr("Others Browser"), + fileCategory="OTHERS", + getIcon=self.getIcon, + ), + ) + # Connect signals of Project. project.prepareRepopulateItem.connect(self._prepareRepopulateItem) project.completeRepopulateItem.connect(self._completeRepopulateItem) @@ -101,6 +114,15 @@ self.umlFile.connect(projectBrowser.umlFile) self.binaryFile.connect(projectBrowser.binaryFile) + def getIcon(self): + """ + Public method to get an icon for the project browser. + + @return icon for the browser + @rtype QIcon + """ + return EricPixmapCache.getIcon("projectOthers") + def _createPopupMenus(self): """ Protected overloaded method to generate the popup menu.
--- a/src/eric7/Project/ProjectProtocolsBrowser.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectProtocolsBrowser.py Wed Nov 23 16:07:16 2022 +0100 @@ -37,6 +37,7 @@ ProjectBrowserProtocolsType, ProjectBrowserSimpleDirectoryItem, ) +from .ProjectBrowserRepositoryItem import ProjectBrowserRepositoryItem class ProjectProtocolsBrowser(ProjectBaseBrowser): @@ -95,6 +96,17 @@ ), ) + # Add the project browser type to the browser type repository. + projectBrowser.addTypedProjectBrowser( + "protocols", + ProjectBrowserRepositoryItem( + projectBrowser=self, + projectBrowserUserString=self.tr("Protocols (protobuf) Browser"), + fileCategory="PROTOCOLS", + getIcon=self.getIcon, + ), + ) + # Connect signals of Project. project.prepareRepopulateItem.connect(self._prepareRepopulateItem) project.completeRepopulateItem.connect(self._completeRepopulateItem) @@ -114,6 +126,15 @@ self.sourceFile[str].connect(projectBrowser.sourceFile[str]) self.sourceFile[str, int].connect(projectBrowser.sourceFile[str, int]) + def getIcon(self): + """ + Public method to get an icon for the project browser. + + @return icon for the browser + @rtype QIcon + """ + return EricPixmapCache.getIcon("protobuf") + def _createPopupMenus(self): """ Protected overloaded method to generate the popup menu.
--- a/src/eric7/Project/ProjectResourcesBrowser.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectResourcesBrowser.py Wed Nov 23 16:07:16 2022 +0100 @@ -30,6 +30,7 @@ ProjectBrowserResourceType, ProjectBrowserSimpleDirectoryItem, ) +from .ProjectBrowserRepositoryItem import ProjectBrowserRepositoryItem class ProjectResourcesBrowser(ProjectBaseBrowser): @@ -90,6 +91,17 @@ ), ) + # Add the project browser type to the browser type repository. + projectBrowser.addTypedProjectBrowser( + "resources", + ProjectBrowserRepositoryItem( + projectBrowser=self, + projectBrowserUserString=self.tr("Resources Browser"), + fileCategory="RESOURCES", + getIcon=self.getIcon, + ), + ) + # Connect signals of Project. project.projectClosed.connect(self._projectClosed) project.projectOpened.connect(self._projectOpened) @@ -108,6 +120,15 @@ self.closeSourceWindow.connect(projectBrowser.closeSourceWindow) self.sourceFile[str].connect(projectBrowser.sourceFile[str]) + def getIcon(self): + """ + Public method to get an icon for the project browser. + + @return icon for the browser + @rtype QIcon + """ + return EricPixmapCache.getIcon("projectResources") + def _createPopupMenus(self): """ Protected overloaded method to generate the popup menu.
--- a/src/eric7/Project/ProjectSourcesBrowser.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectSourcesBrowser.py Wed Nov 23 16:07:16 2022 +0100 @@ -39,6 +39,7 @@ ProjectBrowserSimpleDirectoryItem, ProjectBrowserSourceType, ) +from .ProjectBrowserRepositoryItem import ProjectBrowserRepositoryItem class ProjectSourcesBrowser(ProjectBaseBrowser): @@ -91,6 +92,17 @@ ), ) + # Add the project browser type to the browser type repository. + projectBrowser.addTypedProjectBrowser( + "sources", + ProjectBrowserRepositoryItem( + projectBrowser=self, + projectBrowserUserString=self.tr("Sources Browser"), + fileCategory="SOURCES", + getIcon=self.getIcon, + ), + ) + # Connect signals of Project. project.prepareRepopulateItem.connect(self._prepareRepopulateItem) project.completeRepopulateItem.connect(self._completeRepopulateItem) @@ -120,6 +132,15 @@ self.applicationDiagram = None self.loadedDiagram = None + def getIcon(self): + """ + Public method to get an icon for the project browser. + + @return icon for the browser + @rtype QIcon + """ + return EricPixmapCache.getIcon("projectSources") + def __closeAllWindows(self): """ Private method to close all project related windows.
--- a/src/eric7/Project/ProjectTranslationsBrowser.py Wed Nov 23 11:09:33 2022 +0100 +++ b/src/eric7/Project/ProjectTranslationsBrowser.py Wed Nov 23 16:07:16 2022 +0100 @@ -34,6 +34,7 @@ ProjectBrowserSimpleDirectoryItem, ProjectBrowserTranslationType, ) +from .ProjectBrowserRepositoryItem import ProjectBrowserRepositoryItem class ProjectTranslationsBrowser(ProjectBaseBrowser): @@ -101,6 +102,17 @@ ), ) + # Add the project browser type to the browser type repository. + projectBrowser.addTypedProjectBrowser( + "translations", + ProjectBrowserRepositoryItem( + projectBrowser=self, + projectBrowserUserString=self.tr("Translations Browser"), + fileCategory="TRANSLATIONS", + getIcon=self.getIcon, + ), + ) + # Connect signals of Project. project.projectClosed.connect(self._projectClosed) project.projectOpened.connect(self._projectOpened) @@ -120,6 +132,15 @@ self.trpreview[list].connect(projectBrowser.trpreview[list]) self.trpreview[list, bool].connect(projectBrowser.trpreview[list, bool]) + def getIcon(self): + """ + Public method to get an icon for the project browser. + + @return icon for the browser + @rtype QIcon + """ + return EricPixmapCache.getIcon("projectTranslations") + def _createPopupMenus(self): """ Protected overloaded method to generate the popup menu.