Modified Editor and view managers to be usable with files loaded from a connected device and (potentially) remote files. eric7

Mon, 13 Feb 2023 17:52:26 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Mon, 13 Feb 2023 17:52:26 +0100
branch
eric7
changeset 9758
6d24ab9c0404
parent 9757
ab6e87f6f1c4
child 9759
4543b7876047

Modified Editor and view managers to be usable with files loaded from a connected device and (potentially) remote files.

src/eric7/Documentation/Source/eric7.QScintilla.Editor.html file | annotate | diff | comparison | revisions
src/eric7/Documentation/Source/eric7.ViewManager.ViewManager.html file | annotate | diff | comparison | revisions
src/eric7/Plugins/ViewManagerPlugins/Listspace/Listspace.py file | annotate | diff | comparison | revisions
src/eric7/Plugins/ViewManagerPlugins/Tabview/Tabview.py file | annotate | diff | comparison | revisions
src/eric7/QScintilla/Editor.py file | annotate | diff | comparison | revisions
src/eric7/ViewManager/ViewManager.py file | annotate | diff | comparison | revisions
--- a/src/eric7/Documentation/Source/eric7.QScintilla.Editor.html	Mon Feb 13 17:51:03 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.QScintilla.Editor.html	Mon Feb 13 17:52:26 2023 +0100
@@ -743,10 +743,6 @@
 <td>Private method to configure the eol mode of the editor.</td>
 </tr>
 <tr>
-<td><a href="#Editor.__setFileName">__setFileName</a></td>
-<td>Private method to set the file name of the current file.</td>
-</tr>
-<tr>
 <td><a href="#Editor.__setLineMarkerColours">__setLineMarkerColours</a></td>
 <td>Private method to set the line marker colours.</td>
 </tr>
@@ -983,6 +979,10 @@
 <td>Public method to check dirty status and open a message window.</td>
 </tr>
 <tr>
+<td><a href="#Editor.checkReadOnly">checkReadOnly</a></td>
+<td>Public method to check the 'read only' state.</td>
+</tr>
+<tr>
 <td><a href="#Editor.checkSpelling">checkSpelling</a></td>
 <td>Public slot to perform an interactive spell check of the document.</td>
 </tr>
@@ -1003,6 +1003,10 @@
 <td>Public method to clear a breakpoint.</td>
 </tr>
 <tr>
+<td><a href="#Editor.clearChangeMarkers">clearChangeMarkers</a></td>
+<td>Public method to clear all change markers.</td>
+</tr>
+<tr>
 <td><a href="#Editor.clearFlakesWarnings">clearFlakesWarnings</a></td>
 <td>Public slot to clear all pyflakes warnings.</td>
 </tr>
@@ -1379,6 +1383,10 @@
 <td>Public method to check, if a last edit position is available.</td>
 </tr>
 <tr>
+<td><a href="#Editor.isLocalFile">isLocalFile</a></td>
+<td>Public method to check, if the editor contains a local file.</td>
+</tr>
+<tr>
 <td><a href="#Editor.isMicroPythonFile">isMicroPythonFile</a></td>
 <td>Public method to return a flag indicating a MicroPython file.</td>
 </tr>
@@ -1623,6 +1631,10 @@
 <td>Public method to set the automatic spell checking.</td>
 </tr>
 <tr>
+<td><a href="#Editor.setFileName">setFileName</a></td>
+<td>Public method to set the file name of the current file.</td>
+</tr>
+<tr>
 <td><a href="#Editor.setHighlight">setHighlight</a></td>
 <td>Public method to set a text highlight.</td>
 </tr>
@@ -3712,20 +3724,6 @@
 <p>
         Private method to configure the eol mode of the editor.
 </p>
-<a NAME="Editor.__setFileName" ID="Editor.__setFileName"></a>
-<h4>Editor.__setFileName</h4>
-<b>__setFileName</b>(<i>name</i>)
-
-<p>
-        Private method to set the file name of the current file.
-</p>
-<dl>
-
-<dt><i>name</i> (str)</dt>
-<dd>
-name of the current file
-</dd>
-</dl>
 <a NAME="Editor.__setLineMarkerColours" ID="Editor.__setLineMarkerColours"></a>
 <h4>Editor.__setLineMarkerColours</h4>
 <b>__setLineMarkerColours</b>(<i></i>)
@@ -4385,6 +4383,25 @@
 flag indicating successful reset of the dirty flag (boolean)
 </dd>
 </dl>
+<a NAME="Editor.checkReadOnly" ID="Editor.checkReadOnly"></a>
+<h4>Editor.checkReadOnly</h4>
+<b>checkReadOnly</b>(<i></i>)
+
+<p>
+        Public method to check the 'read only' state.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicate a 'read only' state
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
 <a NAME="Editor.checkSpelling" ID="Editor.checkSpelling"></a>
 <h4>Editor.checkSpelling</h4>
 <b>checkSpelling</b>(<i></i>)
@@ -4431,6 +4448,13 @@
 line number of the breakpoint (integer)
 </dd>
 </dl>
+<a NAME="Editor.clearChangeMarkers" ID="Editor.clearChangeMarkers"></a>
+<h4>Editor.clearChangeMarkers</h4>
+<b>clearChangeMarkers</b>(<i></i>)
+
+<p>
+        Public method to clear all change markers.
+</p>
 <a NAME="Editor.clearFlakesWarnings" ID="Editor.clearFlakesWarnings"></a>
 <h4>Editor.clearFlakesWarnings</h4>
 <b>clearFlakesWarnings</b>(<i></i>)
@@ -5881,6 +5905,25 @@
 flag indicating availability (boolean)
 </dd>
 </dl>
+<a NAME="Editor.isLocalFile" ID="Editor.isLocalFile"></a>
+<h4>Editor.isLocalFile</h4>
+<b>isLocalFile</b>(<i></i>)
+
+<p>
+        Public method to check, if the editor contains a local file.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+flag indicating a local file
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+bool
+</dd>
+</dl>
 <a NAME="Editor.isMicroPythonFile" ID="Editor.isMicroPythonFile"></a>
 <h4>Editor.isMicroPythonFile</h4>
 <b>isMicroPythonFile</b>(<i></i>)
@@ -6564,6 +6607,20 @@
 <p>
         Public method to set the automatic spell checking.
 </p>
+<a NAME="Editor.setFileName" ID="Editor.setFileName"></a>
+<h4>Editor.setFileName</h4>
+<b>setFileName</b>(<i>name</i>)
+
+<p>
+        Public method to set the file name of the current file.
+</p>
+<dl>
+
+<dt><i>name</i> (str)</dt>
+<dd>
+name of the current file
+</dd>
+</dl>
 <a NAME="Editor.setHighlight" ID="Editor.setHighlight"></a>
 <h4>Editor.setHighlight</h4>
 <b>setHighlight</b>(<i>startLine, startIndex, endLine, endIndex</i>)
--- a/src/eric7/Documentation/Source/eric7.ViewManager.ViewManager.html	Mon Feb 13 17:51:03 2023 +0100
+++ b/src/eric7/Documentation/Source/eric7.ViewManager.ViewManager.html	Mon Feb 13 17:52:26 2023 +0100
@@ -1007,13 +1007,17 @@
 </tr>
 <tr>
 <td><a href="#ViewManager.newEditor">newEditor</a></td>
-<td>Public slot to generate a new empty editor.</td>
+<td>Public method to generate a new empty editor.</td>
 </tr>
 <tr>
 <td><a href="#ViewManager.newEditorView">newEditorView</a></td>
 <td>Public method to create a new editor displaying the given document.</td>
 </tr>
 <tr>
+<td><a href="#ViewManager.newEditorWithText">newEditorWithText</a></td>
+<td>Public method to generate a new editor with a given text and associated file name.</td>
+</tr>
+<tr>
 <td><a href="#ViewManager.nextSplit">nextSplit</a></td>
 <td>Public slot used to move to the next split.</td>
 </tr>
@@ -3244,8 +3248,8 @@
 </dd>
 <dt><i>indexes</i> (tuple of two int)</dt>
 <dd>
-of the editor, first the split view index, second the
-            index within the view
+tuple containing the indexes of the editor, first the split
+            view index, second the index within the view
 </dd>
 </dl>
 <dl>
@@ -3765,8 +3769,20 @@
 <b>newEditor</b>(<i></i>)
 
 <p>
-        Public slot to generate a new empty editor.
-</p>
+        Public method to generate a new empty editor.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+reference to the new editor
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+Editor
+</dd>
+</dl>
 <a NAME="ViewManager.newEditorView" ID="ViewManager.newEditorView"></a>
 <h4>ViewManager.newEditorView</h4>
 <b>newEditorView</b>(<i>fn, caller, filetype="", indexes=None</i>)
@@ -3806,6 +3822,29 @@
 Editor
 </dd>
 </dl>
+<a NAME="ViewManager.newEditorWithText" ID="ViewManager.newEditorWithText"></a>
+<h4>ViewManager.newEditorWithText</h4>
+<b>newEditorWithText</b>(<i>text, language="", fileName=""</i>)
+
+<p>
+        Public method to generate a new editor with a given text and associated file
+        name.
+</p>
+<dl>
+
+<dt><i>text</i> (str)</dt>
+<dd>
+text for the editor
+</dd>
+<dt><i>language</i> (str (optional))</dt>
+<dd>
+source language (defaults to "")
+</dd>
+<dt><i>fileName</i> (str (optional))</dt>
+<dd>
+associated file name (defaults to "")
+</dd>
+</dl>
 <a NAME="ViewManager.nextSplit" ID="ViewManager.nextSplit"></a>
 <h4>ViewManager.nextSplit</h4>
 <b>nextSplit</b>(<i></i>)
--- a/src/eric7/Plugins/ViewManagerPlugins/Listspace/Listspace.py	Mon Feb 13 17:51:03 2023 +0100
+++ b/src/eric7/Plugins/ViewManagerPlugins/Listspace/Listspace.py	Mon Feb 13 17:52:26 2023 +0100
@@ -487,7 +487,7 @@
             editor.setNoName(noName)
         else:
             txt = os.path.basename(fn)
-            if not os.access(fn, os.W_OK):
+            if editor.checkReadOnly():
                 txt = self.tr("{0} (ro)").format(txt)
             itm = QListWidgetItem(txt)
             itm.setToolTip(fn)
@@ -623,7 +623,7 @@
             currentRow = self.viewlist.currentRow()
             index = self.editors.index(editor)
             txt = os.path.basename(newName)
-            if not os.access(newName, os.W_OK):
+            if editor.checkReadOnly():
                 txt = self.tr("{0} (ro)").format(txt)
             itm = self.viewlist.item(index)
             if itm:
--- a/src/eric7/Plugins/ViewManagerPlugins/Tabview/Tabview.py	Mon Feb 13 17:51:03 2023 +0100
+++ b/src/eric7/Plugins/ViewManagerPlugins/Tabview/Tabview.py	Mon Feb 13 17:52:26 2023 +0100
@@ -488,7 +488,7 @@
             maxFileNameChars = Preferences.getUI("TabViewManagerFilenameLength")
             if len(txt) > maxFileNameChars:
                 txt = "...{0}".format(txt[-maxFileNameChars:])
-            if editor.isReadOnly():
+            if editor.checkReadOnly():
                 txt = self.tr("{0} (ro)").format(txt)
 
             assembly = editor.parent()
@@ -1052,7 +1052,7 @@
                 txt = ericApp().getObject("Project").getRelativePath(fn)
             if len(txt) > self.maxFileNameChars:
                 txt = "...{0}".format(txt[-self.maxFileNameChars :])
-            if not os.access(fn, os.W_OK):
+            if editor.checkReadOnly():
                 txt = self.tr("{0} (ro)").format(txt)
             if addNext:
                 index = self.currentTabWidget.currentIndex() + 1
@@ -1107,7 +1107,7 @@
                 txt = ericApp().getObject("Project").getRelativePath(fn)
             if len(txt) > self.maxFileNameChars:
                 txt = "...{0}".format(txt[-self.maxFileNameChars :])
-            if not os.access(fn, os.W_OK):
+            if editor.checkReadOnly():
                 txt = self.tr("{0} (ro)").format(txt)
             nindex = tabWidget.insertWidget(index, win, txt)
             tabWidget.setTabToolTip(nindex, fn)
@@ -1498,7 +1498,7 @@
                             txt = ericApp().getObject("Project").getRelativePath(fn)
                         if len(txt) > self.maxFileNameChars:
                             txt = "...{0}".format(txt[-self.maxFileNameChars :])
-                        if not os.access(fn, os.W_OK):
+                        if editor.checkReadOnly():
                             txt = self.tr("{0} (ro)").format(txt)
                         tabWidget.setTabText(index, txt)
 
--- a/src/eric7/QScintilla/Editor.py	Mon Feb 13 17:51:03 2023 +0100
+++ b/src/eric7/QScintilla/Editor.py	Mon Feb 13 17:52:26 2023 +0100
@@ -227,7 +227,7 @@
 
         self.dbs = dbs
         self.taskViewer = tv
-        self.__setFileName(fn)
+        self.setFileName(fn)
         self.vm = vm
         self.filetype = filetype
         self.filetypeByFlag = False
@@ -404,37 +404,39 @@
                 if not Utilities.MimeTypes.isTextFile(self.fileName):
                     raise OSError()
 
-                fileSizeKB = pathlib.Path(self.fileName).stat().st_size // 1024
-                if fileSizeKB > Preferences.getEditor("RejectFilesize"):
-                    EricMessageBox.warning(
-                        None,
-                        self.tr("Open File"),
-                        self.tr(
-                            "<p>The size of the file <b>{0}</b> is <b>{1} KB</b> and"
-                            " exceeds the configured limit of <b>{2} KB</b>. It will"
-                            " not be opened!</p>"
-                        ).format(
-                            self.fileName,
-                            fileSizeKB,
-                            Preferences.getEditor("RejectFilesize"),
-                        ),
-                    )
-                    raise OSError()
-                elif fileSizeKB > Preferences.getEditor("WarnFilesize"):
-                    res = EricMessageBox.yesNo(
-                        None,
-                        self.tr("Open File"),
-                        self.tr(
-                            """<p>The size of the file <b>{0}</b>"""
-                            """ is <b>{1} KB</b>."""
-                            """ Do you really want to load it?</p>"""
-                        ).format(self.fileName, fileSizeKB),
-                        icon=EricMessageBox.Warning,
-                    )
-                    if not res:
+                if self.isLocalFile():
+                    fileSizeKB = pathlib.Path(self.fileName).stat().st_size // 1024
+                    if fileSizeKB > Preferences.getEditor("RejectFilesize"):
+                        EricMessageBox.warning(
+                            None,
+                            self.tr("Open File"),
+                            self.tr(
+                                "<p>The size of the file <b>{0}</b> is <b>{1} KB</b> and"
+                                " exceeds the configured limit of <b>{2} KB</b>. It will"
+                                " not be opened!</p>"
+                            ).format(
+                                self.fileName,
+                                fileSizeKB,
+                                Preferences.getEditor("RejectFilesize"),
+                            ),
+                        )
                         raise OSError()
-
-                self.readFile(self.fileName, True)
+                    elif fileSizeKB > Preferences.getEditor("WarnFilesize"):
+                        res = EricMessageBox.yesNo(
+                            None,
+                            self.tr("Open File"),
+                            self.tr(
+                                """<p>The size of the file <b>{0}</b>"""
+                                """ is <b>{1} KB</b>."""
+                                """ Do you really want to load it?</p>"""
+                            ).format(self.fileName, fileSizeKB),
+                            icon=EricMessageBox.Warning,
+                        )
+                        if not res:
+                            raise OSError()
+
+                    self.readFile(self.fileName, True)
+
                 self.__bindLexer(self.fileName)
                 self.__bindCompleter(self.fileName)
                 self.checkSyntax()
@@ -611,9 +613,9 @@
         self.SCN_ZOOM.connect(self.__markerMap.update)
         self.__markerMap.update()
 
-    def __setFileName(self, name):
-        """
-        Private method to set the file name of the current file.
+    def setFileName(self, name):
+        """
+        Public method to set the file name of the current file.
 
         @param name name of the current file
         @type str
@@ -625,6 +627,15 @@
         else:
             self.__fileNameExtension = ""
 
+    def isLocalFile(self):
+        """
+        Public method to check, if the editor contains a local file.
+
+        @return flag indicating a local file
+        @rtype bool
+        """
+        return not self.fileName.startswith(("device:", "remote:"))
+
     def __registerImages(self):
         """
         Private method to register images for autocompletion lists.
@@ -3111,6 +3122,12 @@
         self.changeMarkersUpdated.emit(self)
         self.__markerMap.update()
 
+    def clearChangeMarkers(self):
+        """
+        Public method to clear all change markers.
+        """
+        self.__reinitOnlineChangeTrace()
+
     def getChangeLines(self):
         """
         Public method to get the lines containing a change.
@@ -3221,7 +3238,7 @@
                 self,
                 self.tr("File Modified"),
                 self.tr("<p>The file <b>{0}</b> has unsaved changes.</p>").format(fn),
-                self.saveFile,
+                self.saveFile if self.isLocalFile() else None,
             )
             if res:
                 self.vm.setEditorName(self, self.fileName)
@@ -3493,8 +3510,9 @@
         @param path directory to save the file in (string)
         @return flag indicating success (boolean)
         """
-        if not saveas and not self.isModified():
-            return False  # do nothing if text wasn't changed
+        if not saveas and (not self.isModified() or not self.isLocalFile()):
+            # do nothing if text wasn't changed or is not a local file
+            return False
 
         newName = None
         if saveas or self.fileName == "":
@@ -3524,7 +3542,7 @@
         if self.writeFile(fn):
             if saveas:
                 self.__clearBreakpoints(self.fileName)
-            self.__setFileName(fn)
+            self.setFileName(fn)
             self.setModified(False)
             self.setReadOnly(False)
             self.setWindowTitle(self.fileName)
@@ -3580,7 +3598,7 @@
         """
         self.__clearBreakpoints(fn)
 
-        self.__setFileName(fn)
+        self.setFileName(fn)
         self.setWindowTitle(self.fileName)
 
         self.__loadEditorConfig()
@@ -7251,7 +7269,7 @@
                 if self.windowState() == Qt.WindowState.WindowMinimized
                 else self.fileName
             )
-            if self.isReadOnly():
+            if self.checkReadOnly():
                 cap = self.tr("{0} (ro)").format(cap)
             self.setWindowTitle(cap)
 
@@ -7394,10 +7412,10 @@
         @param bForce True to force change, False to only update and emit
                 signal if there was an attribute change.
         """
-        if self.fileName == "":
+        if self.fileName == "" or not self.isLocalFile():
             return
 
-        readOnly = not os.access(self.fileName, os.W_OK) or self.isReadOnly()
+        readOnly = self.checkReadOnly()
         if not bForce and (readOnly == self.isReadOnly()):
             return
 
@@ -7408,6 +7426,18 @@
         self.setWindowTitle(cap)
         self.captionChanged.emit(cap, self)
 
+    def checkReadOnly(self):
+        """
+        Public method to check the 'read only' state.
+
+        @return flag indicate a 'read only' state
+        @rtype bool
+        """
+        return (
+            (self.isLocalFile() and not os.access(self.fileName, os.W_OK))
+            or self.isReadOnly()
+        )
+
     def refresh(self):
         """
         Public slot to refresh the editor contents.
@@ -8785,7 +8815,7 @@
         """
         editorConfig = {}
 
-        if fileName:
+        if fileName and self.isLocalFile():
             try:
                 editorConfig = editorconfig.get_properties(fileName)
             except editorconfig.EditorConfigError:
--- a/src/eric7/ViewManager/ViewManager.py	Mon Feb 13 17:51:03 2023 +0100
+++ b/src/eric7/ViewManager/ViewManager.py	Mon Feb 13 17:52:26 2023 +0100
@@ -5402,7 +5402,7 @@
                         "ViewManager",
                         """<p>The file <b>{0}</b> has unsaved changes.</p>""",
                     ).format(fn),
-                    editor.saveFile,
+                    editor.saveFile if editor.isLocalFile() else None,
                 )
             if res:
                 self.setEditorName(editor, editor.getFileName())
@@ -5938,8 +5938,8 @@
         @param addNext flag indicating that if a new editor needs to be
             created, it should be added next to the current editor
         @type bool
-        @param indexes of the editor, first the split view index, second the
-            index within the view
+        @param indexes tuple containing the indexes of the editor, first the split
+            view index, second the index within the view
         @type tuple of two int
         @return tuple of two values giving a flag indicating a new window
             creation and a reference to the editor displaying this file
@@ -6161,7 +6161,10 @@
 
     def newEditor(self):
         """
-        Public slot to generate a new empty editor.
+        Public method to generate a new empty editor.
+
+        @return reference to the new editor
+        @rtype Editor
         """
         from eric7.QScintilla.EditorAssembly import EditorAssembly
 
@@ -6177,6 +6180,38 @@
         self.editorOpened.emit("")
         self.editorOpenedEd.emit(editor)
 
+        return editor
+
+    def newEditorWithText(self, text, language="", fileName=""):
+        """
+        Public method to generate a new editor with a given text and associated file
+        name.
+
+        @param text text for the editor
+        @type str
+        @param language source language (defaults to "")
+        @type str (optional)
+        @param fileName associated file name (defaults to "")
+        @type str (optional)
+        """
+        from eric7.QScintilla.EditorAssembly import EditorAssembly
+
+        assembly = EditorAssembly(
+            self.dbs, fileName, vm=self, filetype=language, tv=ericApp().getObject("TaskViewer")
+        )
+        editor = assembly.getEditor()
+        self.editors.append(editor)
+        self.__connectEditor(editor)
+        self._addView(assembly, fileName)
+        self.__editorOpened()
+        self._checkActions(editor)
+        self.editorOpened.emit(fileName)
+        self.editorOpenedEd.emit(editor)
+        
+        editor.setText(text)
+        editor.setModified(False)
+        editor.clearChangeMarkers()
+
     def printEditor(self, editor):
         """
         Public slot to print an editor.
@@ -7482,7 +7517,7 @@
             (boolean)
         """
         if editor is not None:
-            self.saveAct.setEnabled(editor.isModified())
+            self.saveAct.setEnabled(editor.isModified() and editor.isLocalFile())
             self.revertAct.setEnabled(editor.isModified())
 
             self.undoAct.setEnabled(editor.isUndoAvailable())

eric ide

mercurial