--- a/src/eric7/Project/ProjectSourcesBrowser.py Sun Jun 02 09:51:47 2024 +0200 +++ b/src/eric7/Project/ProjectSourcesBrowser.py Wed Jul 03 09:20:41 2024 +0200 @@ -23,6 +23,7 @@ from eric7.EricWidgets.EricApplication import ericApp from eric7.EricWidgets.EricPathPickerDialog import EricPathPickerModes from eric7.Graphics.UMLDialog import UMLDialog, UMLDialogType +from eric7.SystemUtilities import FileSystemUtilities from eric7.UI.BrowserModel import ( BrowserClassAttributeItem, BrowserClassItem, @@ -318,12 +319,14 @@ self.sourceMenu.addSeparator() self.sourceMenu.addMenu(self.graphicsMenu) self.sourceMenu.addMenu(self.checksMenu) - self.sourceMenu.addMenu(self.formattingMenu) + self.sourceMenuActions["Formatting"] = self.sourceMenu.addMenu( + self.formattingMenu + ) self.sourceMenuActions["Show"] = self.sourceMenu.addMenu(self.menuShow) self.sourceMenu.addSeparator() self.__startAct = self.sourceMenu.addMenu(self.__startMenu) self.sourceMenu.addSeparator() - self.sourceMenu.addAction( + self.__sourceMenuFileManagerAct = self.sourceMenu.addAction( self.tr("Show in File Manager"), self._showInFileManager ) self.sourceMenu.addAction( @@ -349,7 +352,9 @@ self.tr("Add source directory..."), self.__addSourceDirectory ) self.menu.addSeparator() - self.menu.addAction(self.tr("Show in File Manager"), self._showInFileManager) + self.__menuFileManagerAct = self.menu.addAction( + self.tr("Show in File Manager"), self._showInFileManager + ) self.menu.addSeparator() self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs) self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs) @@ -379,7 +384,7 @@ lambda: self.project.addDirectory("SOURCES"), ) self.attributeMenu.addSeparator() - self.attributeMenu.addAction( + self.__attributeMenuFileManagerAct = self.attributeMenu.addAction( self.tr("Show in File Manager"), self._showInFileManager ) self.attributeMenu.addSeparator() @@ -408,7 +413,7 @@ lambda: self.project.addDirectory("SOURCES"), ) self.backMenu.addSeparator() - self.backMenu.addAction( + self.__backMenuFileManagerAct = self.backMenu.addAction( self.tr("Show in File Manager"), self._showProjectInFileManager ) self.backMenu.addSeparator() @@ -428,7 +433,7 @@ self.multiMenuActions.append(act) self.multiMenu.addSeparator() self.multiMenu.addMenu(self.checksMenu) - self.multiMenu.addMenu(self.formattingMenu) + self.__multiMenuFormattingAct = self.multiMenu.addMenu(self.formattingMenu) self.multiMenu.addSeparator() self.multiMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs) self.multiMenu.addAction( @@ -454,9 +459,11 @@ self.dirMenu.addSeparator() act = self.dirMenu.addMenu(self.graphicsMenu) self.dirMenu.addMenu(self.checksMenu) - self.dirMenu.addMenu(self.formattingMenu) + self.__dirMenuFormattingAct = self.dirMenu.addMenu(self.formattingMenu) self.dirMenu.addSeparator() - self.dirMenu.addAction(self.tr("Show in File Manager"), self._showInFileManager) + self.__dirMenuFileManagerAct = self.dirMenu.addAction( + self.tr("Show in File Manager"), self._showInFileManager + ) self.dirMenu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard) self.dirMenu.addSeparator() self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs) @@ -481,6 +488,8 @@ self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure) self.sourceMenu.aboutToShow.connect(self.__showContextMenu) + self.menu.aboutToShow.connect(self.__showContextMenuGeneral) + self.attributeMenu.aboutToShow.connect(self.__showContextMenuAttribute) self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti) self.dirMenu.aboutToShow.connect(self.__showContextMenuDir) self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti) @@ -525,7 +534,7 @@ self.sourceMenu.addSeparator() act = self.sourceMenu.addMenu(self.graphicsMenu) self.sourceMenu.addSeparator() - self.sourceMenu.addAction( + self.__sourceMenuFileManagerAct = self.sourceMenu.addAction( self.tr("Show in File Manager"), self._showInFileManager ) self.sourceMenu.addSeparator() @@ -545,7 +554,9 @@ self.tr("Add source directory..."), self.__addSourceDirectory ) self.menu.addSeparator() - self.menu.addAction(self.tr("Show in File Manager"), self._showInFileManager) + self.__menuFileManagerAct = self.menu.addAction( + self.tr("Show in File Manager"), self._showInFileManager + ) self.menu.addSeparator() self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs) self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs) @@ -570,7 +581,7 @@ lambda: self.project.addDirectory("SOURCES"), ) self.attributeMenu.addSeparator() - self.attributeMenu.addAction( + self.__attributeMenuFileManagerAct = self.attributeMenu.addAction( self.tr("Show in File Manager"), self._showInFileManager ) self.attributeMenu.addSeparator() @@ -596,7 +607,7 @@ lambda: self.project.addDirectory("SOURCES"), ) self.backMenu.addSeparator() - self.backMenu.addAction( + self.__backMenuFileManagerAct = self.backMenu.addAction( self.tr("Show in File Manager"), self._showProjectInFileManager ) self.backMenu.addSeparator() @@ -634,7 +645,9 @@ self.dirMenu.addSeparator() act = self.dirMenu.addMenu(self.graphicsMenu) self.dirMenu.addSeparator() - self.dirMenu.addAction(self.tr("Show in File Manager"), self._showInFileManager) + self.__dirMenuFileManagerAct = self.dirMenu.addAction( + self.tr("Show in File Manager"), self._showInFileManager + ) self.dirMenu.addSeparator() self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs) self.dirMenu.addAction( @@ -658,6 +671,8 @@ self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure) self.sourceMenu.aboutToShow.connect(self.__showContextMenu) + self.menu.aboutToShow.connect(self.__showContextMenuGeneral) + self.attributeMenu.aboutToShow.connect(self.__showContextMenuAttribute) self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti) self.dirMenu.aboutToShow.connect(self.__showContextMenuDir) self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti) @@ -688,7 +703,7 @@ self.sourceMenu.addSeparator() self.sourceMenu.addMenu(self.checksMenu) self.sourceMenu.addSeparator() - self.sourceMenu.addAction( + self.__sourceMenuFileManagerAct = self.sourceMenu.addAction( self.tr("Show in File Manager"), self._showInFileManager ) self.sourceMenu.addAction( @@ -711,7 +726,9 @@ self.tr("Add source directory..."), self.__addSourceDirectory ) self.menu.addSeparator() - self.menu.addAction(self.tr("Show in File Manager"), self._showInFileManager) + self.__menuFileManagerAct = self.menu.addAction( + self.tr("Show in File Manager"), self._showInFileManager + ) self.menu.addSeparator() self.menu.addAction(self.tr("Expand all directories"), self._expandAllDirs) self.menu.addAction(self.tr("Collapse all directories"), self._collapseAllDirs) @@ -736,7 +753,7 @@ lambda: self.project.addDirectory("SOURCES"), ) self.attributeMenu.addSeparator() - self.attributeMenu.addAction( + self.__attrMenuFileManagerAct = self.attributeMenu.addAction( self.tr("Show in File Manager"), self._showInFileManager ) self.attributeMenu.addSeparator() @@ -762,7 +779,7 @@ lambda: self.project.addDirectory("SOURCES"), ) self.backMenu.addSeparator() - self.backMenu.addAction( + self.__backMenuFileManagerAct = self.backMenu.addAction( self.tr("Show in File Manager"), self._showProjectInFileManager ) self.backMenu.addSeparator() @@ -804,7 +821,9 @@ self.dirMenu.addSeparator() self.dirMenu.addMenu(self.checksMenu) self.dirMenu.addSeparator() - self.dirMenu.addAction(self.tr("Show in File Manager"), self._showInFileManager) + self.__dirMenuFileManagerAct = self.dirMenu.addAction( + self.tr("Show in File Manager"), self._showInFileManager + ) self.dirMenu.addAction(self.tr("Copy Path to Clipboard"), self._copyToClipboard) self.dirMenu.addSeparator() self.dirMenu.addAction(self.tr("Expand all directories"), self._expandAllDirs) @@ -829,6 +848,8 @@ self.dirMultiMenu.addAction(self.tr("Configure..."), self._configure) self.sourceMenu.aboutToShow.connect(self.__showContextMenu) + self.menu.aboutToShow.connect(self.__showContextMenuGeneral) + self.attributeMenu.aboutToShow.connect(self.__showContextMenuAttribute) self.multiMenu.aboutToShow.connect(self.__showContextMenuMulti) self.dirMenu.aboutToShow.connect(self.__showContextMenuDir) self.dirMultiMenu.aboutToShow.connect(self.__showContextMenuDirMulti) @@ -956,14 +977,46 @@ else: self.__startAct.setEnabled(False) + self.sourceMenuActions["Formatting"].setEnabled( + self.sourceMenuActions["Formatting"].isEnabled() + and not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + self.__sourceMenuFileManagerAct.setEnabled( + not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + self.showMenu.emit("Main", self.sourceMenu) + def __showContextMenuGeneral(self): + """ + Private slot called by the menu aboutToShow signal. + """ + ProjectBaseBrowser._showContextMenu(self, self.menu) + + self.__menuFileManagerAct.setEnabled( + not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + + def __showContextMenuAttribute(self): + """ + Private slot called by the attributeMenu aboutToShow signal. + """ + ProjectBaseBrowser._showContextMenu(self, self.menu) + + self.__attributeMenuFileManagerAct.setEnabled( + not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + def __showContextMenuMulti(self): """ Private slot called by the multiMenu aboutToShow signal. """ ProjectBaseBrowser._showContextMenuMulti(self, self.multiMenu) + self.__multiMenuFormattingAct.setEnabled( + not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + self.showMenu.emit("MainMulti", self.multiMenu) def __showContextMenuDir(self): @@ -972,6 +1025,13 @@ """ ProjectBaseBrowser._showContextMenuDir(self, self.dirMenu) + self.__dirMenuFormattingAct.setEnabled( + not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + self.__dirMenuFileManagerAct.setEnabled( + not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + self.showMenu.emit("MainDir", self.dirMenu) def __showContextMenuDirMulti(self): @@ -988,6 +1048,10 @@ """ ProjectBaseBrowser._showContextMenuBack(self, self.backMenu) + self.__backMenuFileManagerAct.setEnabled( + not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + self.showMenu.emit("MainBack", self.backMenu) def __showContextMenuShow(self): @@ -1065,8 +1129,14 @@ """ from .NewPythonPackageDialog import NewPythonPackageDialog + isRemote = FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + remotefsInterface = ( + ericApp().getObject("EricServer").getServiceInterface("FileSystem") + ) + separator = remotefsInterface.separator() if isRemote else os.sep + dn = self.currentDirectory(relative=True) - if dn.startswith(os.sep): + if dn.startswith(separator): dn = dn[1:] dlg = NewPythonPackageDialog(dn, self) if dlg.exec() == QDialog.DialogCode.Accepted: @@ -1075,10 +1145,22 @@ packagePath = self.project.ppath packageFile = "" for name in nameParts: - packagePath = os.path.join(packagePath, name) - if not os.path.exists(packagePath): + packagePath = ( + remotefsInterface.join(packagePath, name) + if isRemote + else os.path.join(packagePath, name) + ) + exists = ( + remotefsInterface.exists(packagePath) + if isRemote + else os.path.exists(packagePath) + ) + if not exists: try: - os.mkdir(packagePath) + if isRemote: + remotefsInterface.mkdir(packagePath) + else: + os.mkdir(packagePath) except OSError as err: EricMessageBox.critical( self, @@ -1090,11 +1172,23 @@ ).format(packagePath, str(err)), ) return - packageFile = os.path.join(packagePath, "__init__.py") - if not os.path.exists(packageFile): + packageFile = ( + remotefsInterface.join(packagePath, "__init__.py") + if isRemote + else os.path.join(packagePath, "__init__.py") + ) + exists = ( + remotefsInterface.exists(packageFile) + if isRemote + else os.path.exists(packageFile) + ) + if not exists: try: - with open(packageFile, "w", encoding="utf-8"): - pass + if isRemote: + remotefsInterface.writeFile(packageFile, b"") + else: + with open(packageFile, "w", encoding="utf-8"): + pass except OSError as err: EricMessageBox.critical( self, @@ -1114,6 +1208,11 @@ """ Private method to add a new source file to the project. """ + isRemote = FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + remotefsInterface = ( + ericApp().getObject("EricServer").getServiceInterface("FileSystem") + ) + dn = self.currentDirectory() filename, ok = EricPathPickerDialog.getStrPath( self, @@ -1125,9 +1224,15 @@ filters=self.project.getFileCategoryFilters( categories=["SOURCES"], withAll=False ), + remote=isRemote, ) if ok: - if os.path.exists(filename): + exists = ( + remotefsInterface.exists(filename) + if isRemote + else os.path.exists(filename) + ) + if exists: EricMessageBox.critical( self, self.tr("New source file"), @@ -1142,9 +1247,16 @@ newline = ( None if self.project.useSystemEol() else self.project.getEolString() ) - with open(filename, "w", newline=newline) as f: - f.write("# -*- coding: utf-8 -*-\n") - f.write("# {0}\n".format(self.project.getRelativePath(filename))) + header = "# -*- coding: utf-8 -*-\n# {0}\n".format( + self.project.getRelativePath(filename) + ) + if isRemote: + remotefsInterface.writeFile( + filename, header.encode("utf-8"), newline=newline + ) + else: + with open(filename, "w", newline=newline) as f: + f.write(header) except OSError as err: EricMessageBox.critical( self, @@ -1345,12 +1457,25 @@ """ Private method to handle the imports diagram context menu action. """ + isRemote = FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + remotefsInterface = ( + ericApp().getObject("EricServer").getServiceInterface("FileSystem") + ) + itm = self.model().item(self.currentIndex()) try: fn = itm.fileName() except AttributeError: fn = itm.dirName() - package = fn if os.path.isdir(fn) else os.path.dirname(fn) + package = ( + fn + if remotefsInterface.isdir(fn) + else ( + remotefsInterface.dirname(fn) + if isRemote + else fn if os.path.isdir(fn) else os.path.dirname(fn) + ) + ) res = EricMessageBox.yesNo( self, self.tr("Imports Diagram"), @@ -1370,12 +1495,25 @@ """ Private method to handle the package diagram context menu action. """ + isRemote = FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + remotefsInterface = ( + ericApp().getObject("EricServer").getServiceInterface("FileSystem") + ) + itm = self.model().item(self.currentIndex()) try: fn = itm.fileName() except AttributeError: fn = itm.dirName() - package = fn if os.path.isdir(fn) else os.path.dirname(fn) + package = ( + fn + if remotefsInterface.isdir(fn) + else ( + remotefsInterface.dirname(fn) + if isRemote + else fn if os.path.isdir(fn) else os.path.dirname(fn) + ) + ) res = EricMessageBox.yesNo( self, self.tr("Package Diagram"),