--- a/src/eric7/Project/ProjectSourcesBrowser.py Fri Mar 08 15:30:23 2024 +0100 +++ b/src/eric7/Project/ProjectSourcesBrowser.py Fri Mar 08 15:30:53 2024 +0100 @@ -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, @@ -317,12 +318,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( @@ -348,7 +351,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) @@ -378,7 +383,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() @@ -407,7 +412,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() @@ -427,7 +432,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( @@ -453,9 +458,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) @@ -480,6 +487,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) @@ -524,7 +533,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() @@ -544,7 +553,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) @@ -569,7 +580,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() @@ -595,7 +606,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() @@ -633,7 +644,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( @@ -657,6 +670,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) @@ -687,7 +702,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( @@ -710,7 +725,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) @@ -735,7 +752,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() @@ -761,7 +778,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() @@ -803,7 +820,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) @@ -828,6 +847,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) @@ -955,14 +976,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): @@ -971,6 +1024,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): @@ -987,6 +1047,10 @@ """ ProjectBaseBrowser._showContextMenuBack(self, self.backMenu) + self.__backMenuFileManagerAct.setEnabled( + not FileSystemUtilities.isRemoteFileName(self.project.getProjectPath()) + ) + self.showMenu.emit("MainBack", self.backMenu) def __showContextMenuShow(self): @@ -1062,8 +1126,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: @@ -1072,10 +1142,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, @@ -1087,11 +1169,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, @@ -1111,6 +1205,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, @@ -1122,9 +1221,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"), @@ -1139,9 +1244,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, @@ -1342,12 +1454,22 @@ """ 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) + if isRemote: + package = ( + fn if remotefsInterface.isdir(fn) else remotefsInterface.dirname(fn) + ) + else: + package = fn if os.path.isdir(fn) else os.path.dirname(fn) res = EricMessageBox.yesNo( self, self.tr("Imports Diagram"), @@ -1367,12 +1489,22 @@ """ 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) + if isRemote: + package = ( + fn if remotefsInterface.isdir(fn) else remotefsInterface.dirname(fn) + ) + else: + package = fn if os.path.isdir(fn) else os.path.dirname(fn) res = EricMessageBox.yesNo( self, self.tr("Package Diagram"),