From 8e72432654736a1a4ad081a7378e7fb487f94e56 Mon Sep 17 00:00:00 2001 From: Marco Benelli Date: Thu, 29 Jun 2017 17:48:19 +0200 Subject: QmlJs: avoid overwrites by auto-completion During auto-completion, the cursor used to randomly jump to the beginning of line, eventually overwriting existing text. This patch blocks the signals of the selectionModel while it refreshes the content of the outline model. Also cleans up a unnecessary variable and make it clear where we blocks with using a lambda. Task-number: QTCREATORBUG-18449 Change-Id: I94317c76b4e13d07ef7f3355b766e5473ab21011 Reviewed-by: Tim Jenssen --- src/plugins/qmljseditor/qmljseditor.cpp | 4 +-- src/plugins/qmljseditor/qmljseditor.h | 1 - src/plugins/qmljseditor/qmljsoutline.cpp | 59 +++++++++++++++++++------------- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index cf84adfae4d..1de265a8519 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -220,7 +220,7 @@ void QmlJSEditorWidget::modificationChanged(bool changed) bool QmlJSEditorWidget::isOutlineCursorChangesBlocked() { - return hasFocus() || m_blockOutLineCursorChanges; + return hasFocus(); } void QmlJSEditorWidget::jumpToOutlineElement(int /*index*/) @@ -813,7 +813,6 @@ void QmlJSEditorWidget::showContextPane() void QmlJSEditorWidget::contextMenuEvent(QContextMenuEvent *e) { - m_blockOutLineCursorChanges = true; QPointer menu(new QMenu(this)); QMenu *refactoringMenu = new QMenu(tr("Refactoring"), menu); @@ -858,7 +857,6 @@ void QmlJSEditorWidget::contextMenuEvent(QContextMenuEvent *e) menu->exec(e->globalPos()); delete menu; - m_blockOutLineCursorChanges = false; } bool QmlJSEditorWidget::event(QEvent *e) diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h index 2710e29fa0c..322228e6a47 100644 --- a/src/plugins/qmljseditor/qmljseditor.h +++ b/src/plugins/qmljseditor/qmljseditor.h @@ -122,7 +122,6 @@ private: QTimer m_contextPaneTimer; QComboBox *m_outlineCombo; QModelIndex m_outlineModelIndex; - bool m_blockOutLineCursorChanges = false; QmlJS::ModelManagerInterface *m_modelManager = nullptr; QmlJS::IContextPane *m_contextPane = nullptr; diff --git a/src/plugins/qmljseditor/qmljsoutline.cpp b/src/plugins/qmljseditor/qmljsoutline.cpp index ffe938e543a..9cd3e78eae6 100644 --- a/src/plugins/qmljseditor/qmljsoutline.cpp +++ b/src/plugins/qmljseditor/qmljsoutline.cpp @@ -125,6 +125,14 @@ void QmlJSOutlineWidget::setEditor(QmlJSEditorWidget *editor) m_filterModel->setSourceModel(m_editor->qmlJsEditorDocument()->outlineModel()); m_treeView->expandAll(); + connect(m_editor->qmlJsEditorDocument()->outlineModel(), &QAbstractItemModel::modelAboutToBeReset, [this]() { + if (m_treeView && m_treeView->selectionModel()) + m_treeView->selectionModel()->blockSignals(true); + }); + connect(m_editor->qmlJsEditorDocument()->outlineModel(), &QAbstractItemModel::modelReset, [this]() { + if (m_treeView && m_treeView->selectionModel()) + m_treeView->selectionModel()->blockSignals(false); + }); connect(m_treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QmlJSOutlineWidget::updateSelectionInText); @@ -195,29 +203,34 @@ void QmlJSOutlineWidget::updateSelectionInText(const QItemSelection &selection) void QmlJSOutlineWidget::updateTextCursor(const QModelIndex &index) { - if (!m_editor->isOutlineCursorChangesBlocked()) { - QModelIndex sourceIndex = m_filterModel->mapToSource(index); - AST::SourceLocation location - = m_editor->qmlJsEditorDocument()->outlineModel()->sourceLocation(sourceIndex); - - if (!location.isValid()) - return; - - const QTextBlock lastBlock = m_editor->document()->lastBlock(); - const uint textLength = lastBlock.position() + lastBlock.length(); - if (location.offset >= textLength) - return; - - Core::EditorManager::cutForwardNavigationHistory(); - Core::EditorManager::addCurrentPositionToNavigationHistory(); - - QTextCursor textCursor = m_editor->textCursor(); - m_blockCursorSync = true; - textCursor.setPosition(location.offset); - m_editor->setTextCursor(textCursor); - m_editor->centerCursor(); - m_blockCursorSync = false; - } + const auto update = [this](const QModelIndex &index) { + if (!m_editor->isOutlineCursorChangesBlocked()) { + QModelIndex sourceIndex = m_filterModel->mapToSource(index); + + AST::SourceLocation location + = m_editor->qmlJsEditorDocument()->outlineModel()->sourceLocation(sourceIndex); + + if (!location.isValid()) + return; + + const QTextBlock lastBlock = m_editor->document()->lastBlock(); + const uint textLength = lastBlock.position() + lastBlock.length(); + if (location.offset >= textLength) + return; + + Core::EditorManager::cutForwardNavigationHistory(); + Core::EditorManager::addCurrentPositionToNavigationHistory(); + + QTextCursor textCursor = m_editor->textCursor(); + + textCursor.setPosition(location.offset); + m_editor->setTextCursor(textCursor); + m_editor->centerCursor(); + } + }; + m_blockCursorSync = true; + update(index); + m_blockCursorSync = false; } void QmlJSOutlineWidget::focusEditor() -- cgit v1.2.3