Commit 985de071 authored by Halla Rempt's avatar Halla Rempt

CCBUG:373821 Try to avoid a crash in the text editor

This seems to happen in the change tracker, according to the
backtrace for this bug. Well, we don't need no changetracker in
Krita (it's not the thing that's used for undo), so remove all
this highly complex code and let's hope that tonight's nightly
build on https://ci.appveyor.com/project/alvinhochun/krita/build/artifacts
doesn't crash anymore.
parent bccf8567
......@@ -257,127 +257,8 @@ const QTextCursor KoTextEditor::constCursor() const
return QTextCursor(d->caret);
}
void KoTextEditor::registerTrackedChange(QTextCursor &selection, KoGenChange::Type changeType, const KUndo2MagicString &title, QTextFormat& format, QTextFormat& prevFormat, bool applyToWholeBlock)
void KoTextEditor::registerTrackedChange(QTextCursor &/*selection*/, KoGenChange::Type /*changeType*/, const KUndo2MagicString &/*title*/, QTextFormat& /*format*/, QTextFormat& /*prevFormat*/, bool /*applyToWholeBlock*/)
{
KoChangeTracker *changeTracker = KoTextDocument(d->document).changeTracker();
if (!changeTracker || !changeTracker->recordChanges()) {
// clear the ChangeTrackerId from the passed in selection, without recursively registring
// change tracking again ;)
int start = qMin(selection.position(), selection.anchor());
int end = qMax(selection.position(), selection.anchor());
QTextBlock block = selection.block();
if (block.position() > start)
block = block.document()->findBlock(start);
while (block.isValid() && block.position() < end) {
QTextBlock::iterator iter = block.begin();
while (!iter.atEnd()) {
QTextFragment fragment = iter.fragment();
if (fragment.position() > end) {
break;
}
if (fragment.position() + fragment.length() <= start) {
++iter;
continue;
}
QTextCursor cursor(block);
cursor.setPosition(fragment.position());
QTextCharFormat fm = fragment.charFormat();
if (fm.hasProperty(KoCharacterStyle::ChangeTrackerId)) {
fm.clearProperty(KoCharacterStyle::ChangeTrackerId);
int to = qMin(end, fragment.position() + fragment.length());
cursor.setPosition(to, QTextCursor::KeepAnchor);
cursor.setCharFormat(fm);
iter = block.begin();
} else {
++iter;
}
}
block = block.next();
}
} else {
if (changeType != KoGenChange::DeleteChange) {
//first check if there already is an identical change registered just before or just after the selection. If so, merge appropriatly.
//TODO implement for format change. handle the prevFormat/newFormat check.
QTextCursor checker = QTextCursor(selection);
int idBefore = 0;
int idAfter = 0;
int changeId = 0;
int selectionBegin = qMin(checker.anchor(), checker.position());
int selectionEnd = qMax(checker.anchor(), checker.position());
checker.setPosition(selectionBegin);
if (!checker.atBlockStart()) {
int changeId = checker.charFormat().property(KoCharacterStyle::ChangeTrackerId).toInt();
if (changeId && changeTracker->elementById(changeId)->getChangeType() == changeType)
idBefore = changeId;
} else {
if (!checker.currentTable()) {
int changeId = checker.blockFormat().intProperty(KoCharacterStyle::ChangeTrackerId);
if (changeId && changeTracker->elementById(changeId)->getChangeType() == changeType)
idBefore = changeId;
} else {
idBefore = checker.currentTable()->format().intProperty(KoCharacterStyle::ChangeTrackerId);
if (!idBefore) {
idBefore = checker.currentTable()->cellAt(checker).format().intProperty(KoCharacterStyle::ChangeTrackerId);
}
}
}
checker.setPosition(selectionEnd);
if (!checker.atEnd()) {
checker.movePosition(QTextCursor::NextCharacter);
idAfter = changeTracker->mergeableId(changeType, title, checker.charFormat().property( KoCharacterStyle::ChangeTrackerId ).toInt());
}
changeId = (idBefore)?idBefore:idAfter;
switch (changeType) {//TODO: this whole thing actually needs to be done like a visitor. If the selection contains several change regions, the parenting needs to be individualised.
case KoGenChange::InsertChange:
if (!changeId)
changeId = changeTracker->getInsertChangeId(title, 0);
break;
case KoGenChange::FormatChange:
if (!changeId)
changeId = changeTracker->getFormatChangeId(title, format, prevFormat, 0);
break;
case KoGenChange::DeleteChange:
//this should never be the case
break;
default:
;// do nothing
}
if (applyToWholeBlock) {
selection.movePosition(QTextCursor::StartOfBlock);
selection.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
}
QTextCharFormat f;
f.setProperty(KoCharacterStyle::ChangeTrackerId, changeId);
selection.mergeCharFormat(f);
QTextBlock startBlock = selection.document()->findBlock(selection.anchor());
QTextBlock endBlock = selection.document()->findBlock(selection.position());
while (startBlock.isValid() && startBlock != endBlock) {
startBlock = startBlock.next();
QTextCursor cursor(startBlock);
QTextBlockFormat blockFormat;
blockFormat.setProperty(KoCharacterStyle::ChangeTrackerId, changeId);
cursor.mergeBlockFormat(blockFormat);
QTextCharFormat blockCharFormat = cursor.blockCharFormat();
if (blockCharFormat.hasProperty(KoCharacterStyle::ChangeTrackerId)) {
blockCharFormat.clearProperty(KoCharacterStyle::ChangeTrackerId);
cursor.setBlockCharFormat(blockCharFormat);
}
}
}
}
}
// To figure out if a the blocks of the selection are write protected we need to
......@@ -570,7 +451,7 @@ void KoTextEditor::insertInlineObject(KoInlineObject *inliner, KUndo2Command *cm
InsertInlineObjectCommand *insertInlineObjectCommand = new InsertInlineObjectCommand(inliner, d->document, topCommand);
Q_UNUSED(insertInlineObjectCommand);
d->caret.endEditBlock();
if (!cmd) {
addCommand(topCommand);
endEditBlock();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment