Move responsibility for loading scripts to QgsCodeEditorWidget

This commit is contained in:
Nyall Dawson 2024-06-13 14:42:01 +10:00
parent 69218ba187
commit d345c68c5a
6 changed files with 89 additions and 23 deletions

View File

@ -145,12 +145,24 @@ Triggers a find operation, using the default behavior.
This will automatically open the search bar and start a find operation using
the default behavior, e.g. searching for any selected text in the code editor.
%End
bool loadFile( const QString &path );
%Docstring
Loads the file at the specified ``path`` into the widget, replacing the code editor's
content with that from the file.
This automatically sets the widget's :py:func:`~QgsCodeEditorWidget.filePath`
Returns ``True`` if the file was loaded successfully.
%End
void setFilePath( const QString &path );
%Docstring
Sets the widget's associated file ``path``.
.. seealso:: :py:func:`loadFile`
.. seealso:: :py:func:`filePathChanged`
.. seealso:: :py:func:`filePath`
@ -185,6 +197,12 @@ Emitted when the widget's associated file path is changed.
.. seealso:: :py:func:`setFilePath`
.. seealso:: :py:func:`filePath`
%End
void loadedExternalChanges();
%Docstring
Emitted when the widget loads in text from the associated file to bring in
changes made externally to the file.
%End
};

View File

@ -424,14 +424,6 @@ class Editor(QgsCodeEditorPython):
'The file <b>"{0}"</b> is read only, please save to different file first.').format(self.code_editor_widget.filePath())
self.showMessage(msgText)
def loadFile(self, filename: str, read_only: bool = False):
self.lastModified = QFileInfo(filename).lastModified()
self.code_editor_widget.setFilePath(filename)
self.setText(Path(filename).read_text(encoding='utf-8'))
self.setReadOnly(read_only)
self.setModified(False)
self.recolor()
def save(self, filename: Optional[str] = None):
if self.isReadOnly():
return
@ -468,7 +460,6 @@ class Editor(QgsCodeEditorPython):
self.tab_widget.setTabToolTip(index, self.code_editor_widget.filePath())
self.setModified(False)
self.console_widget.saveFileButton.setEnabled(False)
self.lastModified = QFileInfo(self.code_editor_widget.filePath()).lastModified()
self.console_widget.updateTabListScript(self.code_editor_widget.filePath(), action='append')
self.tab_widget.listObject(self.editor_tab)
QgsSettings().setValue("pythonConsole/lastDirPath",
@ -556,7 +547,9 @@ class EditorTab(QWidget):
if filename:
if QFileInfo(filename).exists():
self._editor.loadFile(filename, read_only)
self._editor_code_widget.loadFile(filename)
if read_only:
self._editor.setReadOnly(True)
self.tabLayout = QGridLayout(self)
self.tabLayout.setContentsMargins(0, 0, 0, 0)

View File

@ -10,6 +10,7 @@
class QgsCodeEditorWidget : QgsPanelWidget
{
%Docstring(signature="appended")
@ -145,12 +146,24 @@ Triggers a find operation, using the default behavior.
This will automatically open the search bar and start a find operation using
the default behavior, e.g. searching for any selected text in the code editor.
%End
bool loadFile( const QString &path );
%Docstring
Loads the file at the specified ``path`` into the widget, replacing the code editor's
content with that from the file.
This automatically sets the widget's :py:func:`~QgsCodeEditorWidget.filePath`
Returns ``True`` if the file was loaded successfully.
%End
void setFilePath( const QString &path );
%Docstring
Sets the widget's associated file ``path``.
.. seealso:: :py:func:`loadFile`
.. seealso:: :py:func:`filePathChanged`
.. seealso:: :py:func:`filePath`
@ -185,6 +198,12 @@ Emitted when the widget's associated file path is changed.
.. seealso:: :py:func:`setFilePath`
.. seealso:: :py:func:`filePath`
%End
void loadedExternalChanges();
%Docstring
Emitted when the widget loads in text from the associated file to bring in
changes made externally to the file.
%End
};

View File

@ -149,7 +149,6 @@ class ScriptEditorDialog(BASE, WIDGET):
self.run_dialog = None
self.filePath = None
if filePath is not None:
self._loadFile(filePath)
@ -159,8 +158,10 @@ class ScriptEditorDialog(BASE, WIDGET):
"""
Updates the script editor dialog title
"""
if self.filePath:
path, file_name = os.path.split(self.filePath)
if self.code_editor_widget.filePath():
path, file_name = os.path.split(
self.code_editor_widget.filePath()
)
else:
file_name = self.tr('Untitled Script')
@ -219,7 +220,7 @@ class ScriptEditorDialog(BASE, WIDGET):
def saveScript(self, saveAs):
newPath = None
if self.filePath is None or saveAs:
if not self.code_editor_widget.filePath() or saveAs:
scriptDir = ScriptUtils.scriptsFolders()[0]
newPath, _ = QFileDialog.getSaveFileName(self,
self.tr("Save script"),
@ -230,12 +231,13 @@ class ScriptEditorDialog(BASE, WIDGET):
if not newPath.lower().endswith(".py"):
newPath += ".py"
self.filePath = newPath
self.code_editor_widget.setFilePath(newPath)
if self.filePath:
if self.code_editor_widget.filePath():
text = self.editor.text()
try:
with codecs.open(self.filePath, "w", encoding="utf-8") as f:
with codecs.open(self.code_editor_widget.filePath(),
"w", encoding="utf-8") as f:
f.write(text)
except OSError as e:
QMessageBox.warning(self,
@ -307,13 +309,8 @@ class ScriptEditorDialog(BASE, WIDGET):
canvas.setMapTool(prevMapTool)
def _loadFile(self, filePath):
with codecs.open(filePath, "r", encoding="utf-8") as f:
txt = f.read()
self.editor.setText(txt)
self.code_editor_widget.loadFile(filePath)
self.hasChanged = False
self.editor.setModified(False)
self.editor.recolor()
self.filePath = filePath
self.update_dialog_title()

View File

@ -342,6 +342,25 @@ void QgsCodeEditorWidget::triggerFind()
showSearchBar();
}
bool QgsCodeEditorWidget::loadFile( const QString &path )
{
if ( !QFile::exists( path ) )
return false;
QFile file( path );
if ( file.open( QFile::ReadOnly ) )
{
const QString content = file.readAll();
mEditor->setText( content );
mEditor->setModified( false );
mEditor->recolor();
mLastModified = QFileInfo( path ).lastModified();
setFilePath( path );
return true;
}
return false;
}
void QgsCodeEditorWidget::setFilePath( const QString &path )
{
if ( mFilePath == path )

View File

@ -20,6 +20,8 @@
#include "qgis_sip.h"
#include "qgspanelwidget.h"
#include <QDateTime>
class QgsCodeEditor;
class QgsFilterLineEdit;
class QToolButton;
@ -156,9 +158,20 @@ class GUI_EXPORT QgsCodeEditorWidget : public QgsPanelWidget
*/
void triggerFind();
/**
* Loads the file at the specified \a path into the widget, replacing the code editor's
* content with that from the file.
*
* This automatically sets the widget's filePath()
*
* Returns TRUE if the file was loaded successfully.
*/
bool loadFile( const QString &path );
/**
* Sets the widget's associated file \a path.
*
* \see loadFile()
* \see filePathChanged()
* \see filePath()
*/
@ -194,6 +207,12 @@ class GUI_EXPORT QgsCodeEditorWidget : public QgsPanelWidget
*/
void filePathChanged( const QString &path );
/**
* Emitted when the widget loads in text from the associated file to bring in
* changes made externally to the file.
*/
void loadedExternalChanges();
private slots:
bool findNext();
@ -236,6 +255,7 @@ class GUI_EXPORT QgsCodeEditorWidget : public QgsPanelWidget
QgsMessageBar *mMessageBar = nullptr;
std::unique_ptr< QgsScrollBarHighlightController > mHighlightController;
QString mFilePath;
QDateTime mLastModified;
};
#endif // QGSCODEEDITORWIDGET_H