src/eric7/Project/ProjectOthersBrowser.py

branch
eric7
changeset 10845
bbcad422aea7
parent 10631
00f5aae565a3
child 11006
a671918232f3
--- a/src/eric7/Project/ProjectOthersBrowser.py	Sun Jul 14 17:24:03 2024 +0200
+++ b/src/eric7/Project/ProjectOthersBrowser.py	Sun Jul 14 17:38:30 2024 +0200
@@ -9,6 +9,7 @@
 """
 
 import contextlib
+import os
 
 from PyQt6.QtCore import QUrl, pyqtSignal
 from PyQt6.QtGui import QDesktopServices
@@ -16,7 +17,9 @@
 
 from eric7 import Preferences
 from eric7.EricGui import EricPixmapCache
-from eric7.EricWidgets import EricMessageBox
+from eric7.EricWidgets import EricMessageBox, EricPathPickerDialog
+from eric7.EricWidgets.EricApplication import ericApp
+from eric7.EricWidgets.EricPathPickerDialog import EricPathPickerModes
 from eric7.SystemUtilities import FileSystemUtilities
 from eric7.UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
 from eric7.Utilities import MimeTypes
@@ -155,6 +158,9 @@
         act = self.menu.addAction(self.tr("Delete"), self.__deleteItem)
         self.menuActions.append(act)
         self.menu.addSeparator()
+        self.menu.addAction(self.tr("New file..."), self.__addNewOthersFile)
+        self.menu.addAction(self.tr("New directory..."), self.__addNewOthersDirectory)
+        self.menu.addSeparator()
         self.menu.addAction(self.tr("Add files..."), self.__addOthersFiles)
         self.menu.addAction(self.tr("Add directory..."), self.__addOthersDirectory)
         self.menu.addSeparator()
@@ -180,6 +186,11 @@
         )
         self.dirMenuActions.append(self.deleteDirAct)
         self.dirMenu.addSeparator()
+        self.dirMenu.addAction(self.tr("New file..."), self.__addNewOthersFile)
+        self.dirMenu.addAction(
+            self.tr("New directory..."), self.__addNewOthersDirectory
+        )
+        self.dirMenu.addSeparator()
         self.dirMenu.addAction(self.tr("Add files..."), self.__addOthersFiles)
         self.dirMenu.addAction(self.tr("Add directory..."), self.__addOthersDirectory)
         self.dirMenu.addSeparator()
@@ -197,6 +208,15 @@
 
         self.backMenu = QMenu(self)
         self.backMenu.addAction(
+            self.tr("New file..."),
+            lambda: self.__addNewOthersFile(useCurrent=False),
+        )
+        self.backMenu.addAction(
+            self.tr("New directory..."),
+            lambda: self.__addNewOthersDirectory(useCurrent=False),
+        )
+        self.backMenu.addSeparator()
+        self.backMenu.addAction(
             self.tr("Add files..."), lambda: self.project.addFiles("OTHERS")
         )
         self.backMenu.addAction(
@@ -461,6 +481,175 @@
                         textMimeTypesList.append(mimetype)
                         Preferences.setUI("TextMimeTypes", textMimeTypesList)
 
+    def __addNewOthersDirectory(self, useCurrent=True):
+        """
+        Private method to add a new directory to the project.
+
+        @param useCurrent flag indicating to use the current index for the directory
+            dialog (defaults to True)
+        @type bool (optional)
+        """
+        from .NewDirectoryDialog import NewDirectoryDialog
+
+        isRemote = FileSystemUtilities.isRemoteFileName(self.project.getProjectPath())
+        remotefsInterface = (
+            ericApp().getObject("EricServer").getServiceInterface("FileSystem")
+        )
+
+        dn = self.currentDirectory() if useCurrent else self.project.getProjectPath()
+        dlg = NewDirectoryDialog(strPath=dn, defaultDirectory=dn, remote=isRemote)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            dirname, addToProject = dlg.getDirectory()
+            exists = (
+                remotefsInterface.exists(dirname)
+                if isRemote
+                else os.path.exists(dirname)
+            )
+            if exists:
+                EricMessageBox.critical(
+                    self,
+                    self.tr("New directory"),
+                    self.tr(
+                        "<p>A file or directory named <b>{0}</b> already exists."
+                        " The action will be aborted.</p>"
+                    ).format(dirname),
+                )
+                return
+
+            try:
+                if isRemote:
+                    remotefsInterface.makedirs(dirname)
+                else:
+                    os.makedirs(dirname)
+            except OSError as err:
+                EricMessageBox.critical(
+                    self,
+                    self.tr("New directory"),
+                    self.tr(
+                        "<p>The directory <b>{0}</b> could not be created."
+                        " Aborting...</p><p>Reason: {1}</p>"
+                    ).format(dirname, str(err)),
+                )
+                return
+
+            parentDirname = (
+                remotefsInterface.dirname(dirname)
+                if isRemote
+                else os.path.dirname(dirname)
+            )
+
+            if addToProject and not self.project.isProjectCategory(dirname, "OTHERS"):
+                self.project.addToOthers(dirname)
+            elif parentDirname == self.project.getProjectPath():
+                dn = self.project.getRelativePath(dirname)
+                self._model.addNewItem("OTHERS", dn, simple=True)
+            while True:
+                # recursively expand all parent items
+                dirname = (
+                    remotefsInterface.dirname(dirname)
+                    if isRemote
+                    else os.path.dirname(dirname)
+                )
+                dirIndex = self._sortModel.mapFromSource(
+                    self._model.itemIndexByName(dirname)
+                )
+                if dirIndex.isValid():
+                    self.expand(dirIndex)
+                else:
+                    break
+
+    def __addNewOthersFile(self, useCurrent=True):
+        """
+        Private method to add a new source file to the project.
+
+        @param useCurrent flag indicating to use the current index for the directory
+            dialog (defaults to True)
+        @type bool (optional)
+        """
+        isRemote = FileSystemUtilities.isRemoteFileName(self.project.getProjectPath())
+        remotefsInterface = (
+            ericApp().getObject("EricServer").getServiceInterface("FileSystem")
+        )
+
+        dn = self.currentDirectory() if useCurrent else self.project.getProjectPath()
+        filename, ok = EricPathPickerDialog.getStrPath(
+            self,
+            self.tr("New file"),
+            self.tr("Enter the path of the new file:"),
+            mode=EricPathPickerModes.SAVE_FILE_ENSURE_EXTENSION_MODE,
+            strPath=dn,
+            defaultDirectory=dn,
+            filters=self.project.getFileCategoryFilters(
+                categories=["OTHERS"], withAll=False
+            ),
+            remote=isRemote,
+        )
+        if ok:
+            exists = (
+                remotefsInterface.exists(filename)
+                if isRemote
+                else os.path.exists(filename)
+            )
+            if exists:
+                EricMessageBox.critical(
+                    self,
+                    self.tr("New file"),
+                    self.tr(
+                        "<p>The file <b>{0}</b> already exists. The action will be"
+                        " aborted.</p>"
+                    ).format(filename),
+                )
+                return
+
+            dirname = (
+                remotefsInterface.dirname(filename)
+                if isRemote
+                else os.path.dirname(filename)
+            )
+            try:
+                if isRemote:
+                    remotefsInterface.makedirs(dirname, exist_ok=True)
+                else:
+                    os.makedirs(dirname, exist_ok=True)
+                newline = (
+                    None if self.project.useSystemEol() else self.project.getEolString()
+                )
+                if isRemote:
+                    remotefsInterface.writeFile(filename, b"", newline=newline)
+                else:
+                    with open(filename, "w", newline=newline) as f:
+                        f.write("")
+            except OSError as err:
+                EricMessageBox.critical(
+                    self,
+                    self.tr("New file"),
+                    self.tr(
+                        "<p>The file <b>{0}</b> could not be created. Aborting...</p>"
+                        "<p>Reason: {1}</p>"
+                    ).format(filename, str(err)),
+                )
+                return
+
+            if not self.project.isProjectCategory(filename, "OTHERS"):
+                self.project.appendFile(filename)
+            while True:
+                # recursively expand all parent items
+                dirIndex = self._sortModel.mapFromSource(
+                    self._model.itemIndexByName(dirname)
+                )
+                if dirIndex.isValid():
+                    self.expand(dirIndex)
+                    dirname = (
+                        remotefsInterface.dirname(dirname)
+                        if isRemote
+                        else os.path.dirname(dirname)
+                    )
+                else:
+                    break
+
+            if MimeTypes.isTextFile(filename):
+                self.sourceFile.emit(filename)
+
     def __addOthersFiles(self):
         """
         Private method to add files to the project.

eric ide

mercurial