Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Immediately write out the console history file BEFORE running commands
This prevents loss of history when a user enters a Python command
which results in a QGIS crash
  • Loading branch information
nyalldawson committed Mar 28, 2023
1 parent b9b06b0 commit 03e1d90
Show file tree
Hide file tree
Showing 8 changed files with 20 additions and 6 deletions.
6 changes: 5 additions & 1 deletion python/console/console_sci.py
Expand Up @@ -137,7 +137,11 @@ def promptForState(self, state):
class ShellScintilla(QgsCodeEditorPython):

def __init__(self, parent=None):
super().__init__(parent, [], QgsCodeEditor.Mode.CommandInput)
# We set the ImmediatelyUpdateHistory flag here, as users can easily
# crash QGIS by entering a Python command, and we don't want the
# history leading to the crash lost..
super().__init__(parent, [], QgsCodeEditor.Mode.CommandInput,
flags=QgsCodeEditor.Flags(QgsCodeEditor.Flag.CodeFolding | QgsCodeEditor.Flag.ImmediatelyUpdateHistory))

self.parent = parent
self._interpreter = PythonInterpreter()
Expand Down
3 changes: 2 additions & 1 deletion python/gui/auto_additions/qgscodeeditor.py
Expand Up @@ -21,7 +21,8 @@
QgsCodeEditor.MarginRole.baseClass = QgsCodeEditor
# monkey patching scoped based enum
QgsCodeEditor.Flag.CodeFolding.__doc__ = "Indicates that code folding should be enabled for the editor"
QgsCodeEditor.Flag.__doc__ = 'Flags controlling behavior of code editor\n\n.. versionadded:: 3.28\n\n' + '* ``CodeFolding``: ' + QgsCodeEditor.Flag.CodeFolding.__doc__
QgsCodeEditor.Flag.ImmediatelyUpdateHistory.__doc__ = "Indicates that the history file should be immediately updated whenever a command is executed, instead of the default behavior of only writing the history on widget close. Since QGIS 3.32."
QgsCodeEditor.Flag.__doc__ = 'Flags controlling behavior of code editor\n\n.. versionadded:: 3.28\n\n' + '* ``CodeFolding``: ' + QgsCodeEditor.Flag.CodeFolding.__doc__ + '\n' + '* ``ImmediatelyUpdateHistory``: ' + QgsCodeEditor.Flag.ImmediatelyUpdateHistory.__doc__
# --
QgsCodeEditor.Flag.baseClass = QgsCodeEditor
QgsCodeEditor.Flags.baseClass = QgsCodeEditor
Expand Down
1 change: 1 addition & 0 deletions python/gui/auto_generated/codeeditors/qgscodeeditor.sip.in
Expand Up @@ -99,6 +99,7 @@ A text editor based on QScintilla2.
enum class Flag
{
CodeFolding,
ImmediatelyUpdateHistory,
};

typedef QFlags<QgsCodeEditor::Flag> Flags;
Expand Down
Expand Up @@ -31,13 +31,14 @@ code autocompletion.


QgsCodeEditorPython( QWidget *parent /TransferThis/ = 0, const QList<QString> &filenames = QList<QString>(),
QgsCodeEditor::Mode mode = QgsCodeEditor::Mode::ScriptEditor );
QgsCodeEditor::Mode mode = QgsCodeEditor::Mode::ScriptEditor, QgsCodeEditor::Flags flags = QgsCodeEditor::Flag::CodeFolding );
%Docstring
Construct a new Python editor.

:param parent: The parent QWidget
:param filenames: The list of apis files to load for the Python lexer
:param mode: code editor mode (since QGIS 3.30)
:param flags: code editor flags (since QGIS 3.32)

.. versionadded:: 2.6
%End
Expand Down
4 changes: 4 additions & 0 deletions src/gui/codeeditors/qgscodeeditor.cpp
Expand Up @@ -761,7 +761,11 @@ QStringList QgsCodeEditor::history() const
void QgsCodeEditor::runCommand( const QString &command, bool skipHistory )
{
if ( !skipHistory )
{
updateHistory( { command } );
if ( mFlags & QgsCodeEditor::Flag::ImmediatelyUpdateHistory )
writeHistoryFile();
}

if ( mInterpreter )
mInterpreter->exec( command );
Expand Down
1 change: 1 addition & 0 deletions src/gui/codeeditors/qgscodeeditor.h
Expand Up @@ -139,6 +139,7 @@ class GUI_EXPORT QgsCodeEditor : public QsciScintilla
enum class Flag : int
{
CodeFolding = 1 << 0, //!< Indicates that code folding should be enabled for the editor
ImmediatelyUpdateHistory = 1 << 1, //!< Indicates that the history file should be immediately updated whenever a command is executed, instead of the default behavior of only writing the history on widget close. Since QGIS 3.32.
};
Q_ENUM( Flag )

Expand Down
5 changes: 3 additions & 2 deletions src/gui/codeeditors/qgscodeeditorpython.cpp
Expand Up @@ -51,12 +51,13 @@ const QgsSettingsEntryBool *QgsCodeEditorPython::settingBlackNormalizeQuotes = n
///@endcond PRIVATE


QgsCodeEditorPython::QgsCodeEditorPython( QWidget *parent, const QList<QString> &filenames, Mode mode )
QgsCodeEditorPython::QgsCodeEditorPython( QWidget *parent, const QList<QString> &filenames, Mode mode, Flags flags )
: QgsCodeEditor( parent,
QString(),
false,
false,
QgsCodeEditor::Flag::CodeFolding, mode )
flags,
mode )
, mAPISFilesList( filenames )
{
if ( !parent )
Expand Down
3 changes: 2 additions & 1 deletion src/gui/codeeditors/qgscodeeditorpython.h
Expand Up @@ -71,10 +71,11 @@ class GUI_EXPORT QgsCodeEditorPython : public QgsCodeEditor
* \param parent The parent QWidget
* \param filenames The list of apis files to load for the Python lexer
* \param mode code editor mode (since QGIS 3.30)
* \param flags code editor flags (since QGIS 3.32)
* \since QGIS 2.6
*/
QgsCodeEditorPython( QWidget *parent SIP_TRANSFERTHIS = nullptr, const QList<QString> &filenames = QList<QString>(),
QgsCodeEditor::Mode mode = QgsCodeEditor::Mode::ScriptEditor );
QgsCodeEditor::Mode mode = QgsCodeEditor::Mode::ScriptEditor, QgsCodeEditor::Flags flags = QgsCodeEditor::Flag::CodeFolding );

Qgis::ScriptLanguage language() const override;
Qgis::ScriptLanguageCapabilities languageCapabilities() const override;
Expand Down

0 comments on commit 03e1d90

Please sign in to comment.