diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index a5d904c495a..8b8b3b91253 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -279,6 +279,7 @@ bool DesignDocument::isDocumentLoaded() const void DesignDocument::resetToDocumentModel() { + plainTextEdit()->document()->clearUndoRedoStacks(); m_inFileComponentModel.reset(); } @@ -310,6 +311,8 @@ void DesignDocument::changeToDocumentModel() viewManager().detachRewriterView(); viewManager().detachViewsExceptRewriterAndComponetView(); + plainTextEdit()->document()->clearUndoRedoStacks(); + m_inFileComponentModel.reset(); m_inFileComponentTextModifier.reset(); @@ -345,6 +348,8 @@ void DesignDocument::changeToInFileComponentModel(ComponentTextModifier *textMod viewManager().detachRewriterView(); viewManager().detachViewsExceptRewriterAndComponetView(); + plainTextEdit()->document()->clearUndoRedoStacks(); + m_inFileComponentModel.reset(createInFileComponentModel()); m_inFileComponentModel->setTextModifier(m_inFileComponentTextModifier.data()); diff --git a/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp b/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp index 6aca50c4334..aaccaee40db 100644 --- a/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp +++ b/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp @@ -160,40 +160,65 @@ void ComponentTextModifier::handleOriginalTextChanged() const QString currentText = m_originalModifier->text(); - // Adjust for removal/addition of whitespace in the document - // Check that non-whitespace portion of the text is the same and count the whitespace diff const int oldLen = m_originalText.size(); const int newLen = currentText.size(); - int newSpace = 0; - int oldSpace = 0; - int newIdx = 0; - for (int oldIdx = 0; oldIdx < oldLen; ++oldIdx) { - const QChar oldChar = m_originalText[oldIdx]; - if (oldIdx == m_componentStartOffset) - m_componentStartOffset += newSpace - oldSpace; - if (oldIdx == m_componentEndOffset) { - m_componentEndOffset += newSpace - oldSpace; - break; + + if (oldLen != newLen) { + int newSpace = 0; + int oldSpace = 0; + int newIdx = 0; + int nonWhiteSpaceChangeIdx = -1; + int newStartOffset = m_componentStartOffset; + + // Adjust for removal/addition of whitespace in the document. + // Whitespace changes that happen when document is saved can be spread around throughout + // the entire document in multiple places. + // Check that non-whitespace portion of the text is the same and count the whitespace diff + for (int oldIdx = 0; oldIdx < oldLen; ++oldIdx) { + const QChar oldChar = m_originalText[oldIdx]; + if (oldIdx == m_componentStartOffset) + newStartOffset += newSpace - oldSpace; + if (oldIdx == m_componentEndOffset) { + m_componentEndOffset += newSpace - oldSpace; + m_componentStartOffset = newStartOffset; + m_originalText = currentText; + break; + } + + while (newIdx < newLen && currentText[newIdx].isSpace()) { + ++newSpace; + ++newIdx; + } + + if (oldChar.isSpace()) { + ++oldSpace; + continue; + } + + if (currentText[newIdx] != oldChar) { + nonWhiteSpaceChangeIdx = oldIdx; + // A non-whitespace change is a result of manual text edit or undo/redo operation. + // Assumption is that separate whitespace changes and a non-whitespace change can't + // both happen simultaneously, so break out of whitespace check loop. + break; + } else { + ++newIdx; + } } - while (newIdx < newLen && currentText[newIdx].isSpace()) { - ++newSpace; - ++newIdx; + if (nonWhiteSpaceChangeIdx >= 0) { + // For non-whitespace change, we assume the whole change is either before the component + // or inside the component. If the change spans both, it's likely the change is + // invalid anyway, and we don't care about trying to keep offsets up to date. + int diff = newLen - oldLen; + if (nonWhiteSpaceChangeIdx < m_componentEndOffset) + m_componentEndOffset += diff; + if (nonWhiteSpaceChangeIdx < m_componentStartOffset) + m_componentStartOffset += diff; + m_originalText = currentText; } - if (oldChar.isSpace()) { - ++oldSpace; - continue; - } - - if (currentText[newIdx] != oldChar) { - // Non-whitespace difference, we can't determine a valid offset in this case - // TODO: Needs proper handling to deal with undo/redo/arbitrary edits somehow (QDS-5392) - break; - } else { - ++newIdx; - } } - m_originalText = currentText; + emit textChanged(); }