forked from qt-creator/qt-creator
QmlDesigner: Adjust ComponentTextModifier offsets for whitespace change
Whitespace change can also occur inside the subcomponent code when new nodes are added into subcomponent and the document is saved. Changed the text change handling to adjust for whitespace changes both before and inside the subcomponent code. The new handling is simpler and doesn't require subcomponent to have id to work. The downside is that non-whitespace changes before subcomponent code are no longer adjusted for, but that was just a hacky workaround for a small part of a much larger issue that needs to be tackled properly anyway (i.e. supporting arbitrary undo/redo/manual edits), so losing it is not a big deal. Fixes: QDS-5362 Change-Id: I1ca1084baf78709727b1b4726b4c034558063401 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -111,7 +111,8 @@ void ComponentTextModifier::commitGroup()
|
|||||||
{
|
{
|
||||||
m_originalModifier->commitGroup();
|
m_originalModifier->commitGroup();
|
||||||
|
|
||||||
int textLength = m_originalModifier->text().length();
|
m_originalText = m_originalModifier->text();
|
||||||
|
int textLength = m_originalText.length();
|
||||||
m_componentEndOffset += (textLength - m_startLength);
|
m_componentEndOffset += (textLength - m_startLength);
|
||||||
m_startLength = textLength;
|
m_startLength = textLength;
|
||||||
}
|
}
|
||||||
@@ -157,40 +158,42 @@ void ComponentTextModifier::handleOriginalTextChanged()
|
|||||||
{
|
{
|
||||||
// Update offsets when original text changes, if necessary
|
// Update offsets when original text changes, if necessary
|
||||||
|
|
||||||
// Detect and adjust for removal/addition of unrelated text before the subcomponent code,
|
|
||||||
// as that can happen even without user editing the text (e.g. whitespace removal at save time)
|
|
||||||
|
|
||||||
const QString currentText = m_originalModifier->text();
|
const QString currentText = m_originalModifier->text();
|
||||||
|
|
||||||
if (m_originalText.left(m_componentStartOffset) != currentText.left(m_componentStartOffset)) {
|
// Adjust for removal/addition of whitespace in the document
|
||||||
// Subcomponent item id is the only reliable indicator for adjustment
|
// Check that non-whitespace portion of the text is the same and count the whitespace diff
|
||||||
const int idIndex = m_originalText.indexOf("id:", m_componentStartOffset);
|
const int oldLen = m_originalText.size();
|
||||||
if (idIndex != -1 && idIndex < m_componentEndOffset) {
|
const int newLen = currentText.size();
|
||||||
int newLineIndex = m_originalText.indexOf('\n', idIndex);
|
int newSpace = 0;
|
||||||
if (newLineIndex != -1) {
|
int oldSpace = 0;
|
||||||
const QString checkLine = m_originalText.mid(idIndex, newLineIndex - idIndex);
|
int newIdx = 0;
|
||||||
int lineIndex = currentText.indexOf(checkLine);
|
for (int oldIdx = 0; oldIdx < oldLen; ++oldIdx) {
|
||||||
if (lineIndex != -1) {
|
const QChar oldChar = m_originalText[oldIdx];
|
||||||
// Paranoia check - This shouldn't happen except when modifying text manually,
|
if (oldIdx == m_componentStartOffset)
|
||||||
// but it's possible something was inserted between id and start
|
m_componentStartOffset += newSpace - oldSpace;
|
||||||
// of the component, which would throw off the calculation, so check that
|
if (oldIdx == m_componentEndOffset) {
|
||||||
// the first line is still correct even with new offset.
|
m_componentEndOffset += newSpace - oldSpace;
|
||||||
const int diff = idIndex - lineIndex;
|
break;
|
||||||
newLineIndex = m_originalText.indexOf('\n', m_componentStartOffset);
|
}
|
||||||
if (newLineIndex != -1) {
|
|
||||||
const QString firstLine = m_originalText.mid(m_componentStartOffset,
|
while (newIdx < newLen && currentText[newIdx].isSpace()) {
|
||||||
newLineIndex - m_componentStartOffset);
|
++newSpace;
|
||||||
const int newStart = m_componentStartOffset - diff;
|
++newIdx;
|
||||||
if (firstLine == currentText.mid(newStart, firstLine.size())) {
|
}
|
||||||
m_componentEndOffset -= diff;
|
|
||||||
m_componentStartOffset = newStart;
|
if (oldChar.isSpace()) {
|
||||||
m_originalText = currentText;
|
++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();
|
emit textChanged();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user