Skip to content

Commit

Permalink
Move console script editor external file watching logic to QgsCodeEdi…
Browse files Browse the repository at this point in the history
…torWidget

Ensures a consistent behavior between console script editor and
eg processing script editor
  • Loading branch information
nyalldawson committed Jun 17, 2024
1 parent d345c68 commit 9946a1d
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@




class QgsCodeEditorWidget : QgsPanelWidget
{
%Docstring(signature="appended")
Expand Down Expand Up @@ -50,6 +51,8 @@ feedback, otherwise an integrated message bar will be used.

virtual void showEvent( QShowEvent *event );

virtual bool eventFilter( QObject *obj, QEvent *event );


QgsCodeEditor *editor();
%Docstring
Expand Down
32 changes: 9 additions & 23 deletions python/console/console_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ def __init__(self,
self.tab_widget: EditorTabWidget = tab_widget
self.code_editor_widget: Optional[QgsCodeEditorWidget] = None

# recent modification time
self.lastModified = 0

self.setMinimumHeight(120)
self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)

Expand Down Expand Up @@ -126,6 +123,12 @@ def __init__(self,
self.modificationChanged.connect(self.editor_tab.modified)
self.modificationAttempted.connect(self.fileReadOnly)

def set_code_editor_widget(self, widget: QgsCodeEditorWidget):
self.code_editor_widget = widget
self.code_editor_widget.loadedExternalChanges.connect(
self.loaded_external_changes
)

def settingsEditor(self):
# Set Python lexer
self.initializeLexer()
Expand Down Expand Up @@ -399,25 +402,8 @@ def syntaxCheck(self):

return True

def focusInEvent(self, e):
if self.code_editor_widget.filePath():
if not QFileInfo(self.code_editor_widget.filePath()).exists():
msgText = QCoreApplication.translate('PythonConsole',
'The file <b>"{0}"</b> has been deleted or is not accessible').format(self.code_editor_widget.filePath())
self.showMessage(msgText,
level=Qgis.MessageLevel.Critical)
return
if self.code_editor_widget.filePath() and self.lastModified != QFileInfo(self.code_editor_widget.filePath()).lastModified():
self.beginUndoAction()
self.selectAll()
self.removeSelectedText()
self.insert(Path(self.code_editor_widget.filePath()).read_text(encoding='utf-8'))
self.setModified(False)
self.endUndoAction()

self.tab_widget.listObject(self.tab_widget.currentWidget())
self.lastModified = QFileInfo(self.code_editor_widget.filePath()).lastModified()
super().focusInEvent(e)
def loaded_external_changes(self):
self.tab_widget.listObject(self.tab_widget.currentWidget())

def fileReadOnly(self):
msgText = QCoreApplication.translate('PythonConsole',
Expand Down Expand Up @@ -536,7 +522,7 @@ def __init__(self,
self._editor_code_widget = QgsCodeEditorWidget(
self._editor
)
self._editor.code_editor_widget = self._editor_code_widget
self._editor.set_code_editor_widget(self._editor_code_widget)
self._editor_code_widget.searchBarToggled.connect(
self.search_bar_toggled
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ feedback, otherwise an integrated message bar will be used.

virtual void showEvent( QShowEvent *event );

virtual bool eventFilter( QObject *obj, QEvent *event );


QgsCodeEditor *editor();
%Docstring
Expand Down
48 changes: 48 additions & 0 deletions src/gui/codeeditors/qgscodeeditorwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ QgsCodeEditorWidget::QgsCodeEditorWidget(
{
Q_ASSERT( mEditor );

mEditor->installEventFilter( this );
installEventFilter( this );

QVBoxLayout *vl = new QVBoxLayout();
vl->setContentsMargins( 0, 0, 0, 0 );
vl->setSpacing( 0 );
Expand Down Expand Up @@ -242,6 +245,51 @@ void QgsCodeEditorWidget::showEvent( QShowEvent *event )
updateHighlightController();
}

bool QgsCodeEditorWidget::eventFilter( QObject *obj, QEvent *event )
{
if ( event->type() == QEvent::FocusIn )
{
if ( !mFilePath.isEmpty() )
{
if ( !QFile::exists( mFilePath ) )
{
// file deleted externally
if ( mMessageBar )
{
mMessageBar->pushCritical( QString(), tr( "The file <b>\"%1\"</b> has been deleted or is not accessible" ).arg( QDir::toNativeSeparators( mFilePath ) ) );
}
}
else
{
const QFileInfo fi( mFilePath );
if ( mLastModified != fi.lastModified() )
{
// TODO - we should give users a choice of how to react to this, eg "ignore changes"
// note -- we intentionally don't call loadFile here -- we want this action to be undo-able
QFile file( mFilePath );
if ( file.open( QFile::ReadOnly ) )
{
const QString content = file.readAll();

// don't clear, instead perform undoable actions:
mEditor->beginUndoAction();
mEditor->selectAll();
mEditor->removeSelectedText();
mEditor->insert( content );
mEditor->setModified( false );
mEditor->recolor();
mEditor->endUndoAction();

mLastModified = fi.lastModified();
emit loadedExternalChanges();
}
}
}
}
}
return QgsPanelWidget::eventFilter( obj, event );
}

QgsCodeEditorWidget::~QgsCodeEditorWidget() = default;

bool QgsCodeEditorWidget::isSearchBarVisible() const
Expand Down
1 change: 1 addition & 0 deletions src/gui/codeeditors/qgscodeeditorwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class GUI_EXPORT QgsCodeEditorWidget : public QgsPanelWidget

void resizeEvent( QResizeEvent *event ) override;
void showEvent( QShowEvent *event ) override;
bool eventFilter( QObject *obj, QEvent *event ) override;

/**
* Returns the wrapped code editor.
Expand Down

0 comments on commit 9946a1d

Please sign in to comment.