- redesign redo system
- fix: correctly restore editor's modified status when undo/redo
This commit is contained in:
parent
10631f54d7
commit
8d59bf9abb
1
NEWS.md
1
NEWS.md
|
@ -11,6 +11,7 @@ Red Panda C++ Version 1.1.4
|
|||
- fix: undo chains
|
||||
- enhancement: prevent group undo when caret position changed
|
||||
- fix: undo link break may lose leading spaces
|
||||
- fix: correctly restore editor's modified status when undo/redo
|
||||
|
||||
Red Panda C++ Version 1.1.3
|
||||
|
||||
|
|
|
@ -80,8 +80,8 @@ SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent),
|
|||
|
||||
mUndoList = std::make_shared<SynEditUndoList>();
|
||||
mUndoList->connect(mUndoList.get(), &SynEditUndoList::addedUndo, this, &SynEdit::onUndoAdded);
|
||||
mRedoList = std::make_shared<SynEditUndoList>();
|
||||
mRedoList->connect(mRedoList.get(), &SynEditUndoList::addedUndo, this, &SynEdit::onRedoAdded);
|
||||
mRedoList = std::make_shared<SynEditRedoList>();
|
||||
// mRedoList->connect(mRedoList.get(), &SynEditUndoList::addedUndo, this, &SynEdit::onRedoAdded);
|
||||
|
||||
mForegroundColor=palette().color(QPalette::Text);
|
||||
mBackgroundColor=palette().color(QPalette::Base);
|
||||
|
@ -353,7 +353,7 @@ bool SynEdit::canUndo() const
|
|||
|
||||
bool SynEdit::canRedo() const
|
||||
{
|
||||
return !mReadOnly && mRedoList->canUndo();
|
||||
return !mReadOnly && mRedoList->canRedo();
|
||||
}
|
||||
|
||||
int SynEdit::maxScrollWidth() const
|
||||
|
@ -3089,7 +3089,7 @@ void SynEdit::doPasteFromClipboard()
|
|||
BufferCoord vEndOfBlock = blockEnd();
|
||||
mBlockBegin = vStartOfBlock;
|
||||
mBlockEnd = vEndOfBlock;
|
||||
qDebug()<<textToLines(text);
|
||||
// qDebug()<<textToLines(text);
|
||||
setSelTextPrimitive(splitStrings(text));
|
||||
mUndoList->endBlock();
|
||||
}
|
||||
|
@ -3428,7 +3428,7 @@ void SynEdit::updateModifiedStatus()
|
|||
bool oldModified = mModified;
|
||||
mModified = !mUndoList->initialState();
|
||||
setModified(mModified);
|
||||
qDebug()<<mModified<<oldModified;
|
||||
// qDebug()<<mModified<<oldModified;
|
||||
if (oldModified!=mModified)
|
||||
emit statusChanged(SynStatusChange::scModifyChanged);
|
||||
}
|
||||
|
@ -4294,31 +4294,15 @@ void SynEdit::doUndo()
|
|||
return;
|
||||
|
||||
//Remove Group Break;
|
||||
if (mUndoList->lastChangeReason() == SynChangeReason::GroupBreak) {
|
||||
int OldBlockNumber = mRedoList->blockChangeNumber();
|
||||
auto action = finally([&,this]{
|
||||
mRedoList->setBlockChangeNumber(OldBlockNumber);
|
||||
});
|
||||
while (mUndoList->lastChangeReason() == SynChangeReason::GroupBreak) {
|
||||
PSynEditUndoItem item = mUndoList->popItem();
|
||||
mRedoList->setBlockChangeNumber(item->changeNumber());
|
||||
mRedoList->addGroupBreak();
|
||||
mRedoList->addRedo(item);
|
||||
}
|
||||
|
||||
PSynEditUndoItem item = mUndoList->peekItem();
|
||||
if (item) {
|
||||
size_t oldChangeNumber = item->changeNumber();
|
||||
size_t saveChangeNumber = mRedoList->blockChangeNumber();
|
||||
mRedoList->setBlockChangeNumber(item->changeNumber());
|
||||
{
|
||||
auto action = finally([&,this] {
|
||||
mRedoList->setBlockChangeNumber(saveChangeNumber);
|
||||
});
|
||||
//skip group chain breakers
|
||||
if (mUndoList->lastChangeReason()==SynChangeReason::GroupBreak) {
|
||||
while (!mUndoList->isEmpty() && mUndoList->lastChangeReason()==SynChangeReason::GroupBreak) {
|
||||
doUndoItem();
|
||||
}
|
||||
}
|
||||
SynChangeReason lastChange = mUndoList->lastChangeReason();
|
||||
bool keepGoing;
|
||||
do {
|
||||
|
@ -4339,6 +4323,8 @@ void SynEdit::doUndo()
|
|||
} while (keepGoing);
|
||||
}
|
||||
}
|
||||
updateModifiedStatus();
|
||||
onChanged();
|
||||
}
|
||||
|
||||
void SynEdit::doUndoItem()
|
||||
|
@ -4359,43 +4345,47 @@ void SynEdit::doUndoItem()
|
|||
mOptions.setFlag(eoScrollPastEol);
|
||||
switch(item->changeReason()) {
|
||||
case SynChangeReason::Caret:
|
||||
mRedoList->addChange(
|
||||
mRedoList->addRedo(
|
||||
item->changeReason(),
|
||||
caretXY(),
|
||||
caretXY(), QStringList(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
internalSetCaretXY(item->changeStartPos());
|
||||
break;
|
||||
case SynChangeReason::LeftTop:
|
||||
BufferCoord p;
|
||||
p.ch = leftChar();
|
||||
p.line = topLine();
|
||||
mRedoList->addChange(
|
||||
mRedoList->addRedo(
|
||||
item->changeReason(),
|
||||
p,
|
||||
p, QStringList(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
setLeftChar(item->changeStartPos().ch);
|
||||
setTopLine(item->changeStartPos().line);
|
||||
break;
|
||||
case SynChangeReason::Selection:
|
||||
mRedoList->addChange(
|
||||
mRedoList->addRedo(
|
||||
item->changeReason(),
|
||||
mBlockBegin,
|
||||
mBlockEnd,
|
||||
QStringList(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
setCaretAndSelection(caretXY(), item->changeStartPos(), item->changeEndPos());
|
||||
break;
|
||||
case SynChangeReason::Insert: {
|
||||
QStringList tmpText = getContent(item->changeStartPos(),item->changeEndPos(),item->changeSelMode());
|
||||
doDeleteText(item->changeStartPos(),item->changeEndPos(),item->changeSelMode());
|
||||
mRedoList->addChange(
|
||||
mRedoList->addRedo(
|
||||
item->changeReason(),
|
||||
item->changeStartPos(),
|
||||
item->changeEndPos(),
|
||||
tmpText,
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
internalSetCaretXY(item->changeStartPos());
|
||||
break;
|
||||
}
|
||||
|
@ -4403,23 +4393,25 @@ void SynEdit::doUndoItem()
|
|||
setBlockBegin(BufferCoord{item->changeStartPos().ch, item->changeStartPos().line-1});
|
||||
setBlockEnd(BufferCoord{item->changeEndPos().ch, item->changeEndPos().line-1});
|
||||
doMoveSelDown();
|
||||
mRedoList->addChange(
|
||||
mRedoList->addRedo(
|
||||
item->changeReason(),
|
||||
item->changeStartPos(),
|
||||
item->changeEndPos(),
|
||||
item->changeText(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
break;
|
||||
case SynChangeReason::MoveSelectionDown:
|
||||
setBlockBegin(BufferCoord{item->changeStartPos().ch, item->changeStartPos().line+1});
|
||||
setBlockEnd(BufferCoord{item->changeEndPos().ch, item->changeEndPos().line+1});
|
||||
doMoveSelUp();
|
||||
mRedoList->addChange(
|
||||
mRedoList->addRedo(
|
||||
item->changeReason(),
|
||||
item->changeStartPos(),
|
||||
item->changeEndPos(),
|
||||
item->changeText(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
break;
|
||||
case SynChangeReason::Delete: {
|
||||
// If there's no selection, we have to set
|
||||
|
@ -4431,12 +4423,13 @@ void SynEdit::doUndoItem()
|
|||
item->changeStartPos().line,
|
||||
item->changeEndPos().line);
|
||||
internalSetCaretXY(item->changeEndPos());
|
||||
mRedoList->addChange(
|
||||
mRedoList->addRedo(
|
||||
item->changeReason(),
|
||||
item->changeStartPos(),
|
||||
item->changeEndPos(),
|
||||
item->changeText(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
ensureCursorPosVisible();
|
||||
break;
|
||||
}
|
||||
|
@ -4456,12 +4449,13 @@ void SynEdit::doUndoItem()
|
|||
mDocument->deleteAt(mCaretY);
|
||||
doLinesDeleted(mCaretY, 1);
|
||||
}
|
||||
mRedoList->addChange(
|
||||
mRedoList->addRedo(
|
||||
item->changeReason(),
|
||||
item->changeStartPos(),
|
||||
item->changeEndPos(),
|
||||
item->changeText(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -4479,51 +4473,38 @@ void SynEdit::doRedo()
|
|||
if (!item)
|
||||
return;
|
||||
size_t oldChangeNumber = item->changeNumber();
|
||||
size_t saveChangeNumber = mUndoList->blockChangeNumber();
|
||||
mUndoList->setBlockChangeNumber(item->changeNumber());
|
||||
{
|
||||
auto action = finally([&,this]{
|
||||
mUndoList->setBlockChangeNumber(saveChangeNumber);
|
||||
});
|
||||
//skip group chain breakers
|
||||
if (mRedoList->lastChangeReason()==SynChangeReason::GroupBreak) {
|
||||
while (!mRedoList->isEmpty() && mRedoList->lastChangeReason()==SynChangeReason::GroupBreak) {
|
||||
doRedoItem();
|
||||
}
|
||||
}
|
||||
SynChangeReason lastChange = mRedoList->lastChangeReason();
|
||||
bool keepGoing;
|
||||
do {
|
||||
doRedoItem();
|
||||
item = mRedoList->peekItem();
|
||||
if (!item)
|
||||
keepGoing = false;
|
||||
else {
|
||||
if (item->changeNumber() == oldChangeNumber)
|
||||
keepGoing = true;
|
||||
else {
|
||||
keepGoing = (mOptions.testFlag(eoGroupUndo) &&
|
||||
(lastChange == item->changeReason()));
|
||||
}
|
||||
oldChangeNumber=item->changeNumber();
|
||||
lastChange = item->changeReason();
|
||||
}
|
||||
} while (keepGoing);
|
||||
|
||||
//skip group chain breakers
|
||||
while (mRedoList->lastChangeReason()==SynChangeReason::GroupBreak) {
|
||||
PSynEditUndoItem item = mRedoList->popItem();
|
||||
mUndoList->restoreChange(item);
|
||||
}
|
||||
//Remove Group Break
|
||||
if (mRedoList->lastChangeReason() == SynChangeReason::GroupBreak) {
|
||||
int OldBlockNumber = mUndoList->blockChangeNumber();
|
||||
item = mRedoList->popItem();
|
||||
{
|
||||
auto action2=finally([&,this]{
|
||||
mUndoList->setBlockChangeNumber(OldBlockNumber);
|
||||
});
|
||||
mUndoList->setBlockChangeNumber(item->changeNumber());
|
||||
mUndoList->addGroupBreak();
|
||||
SynChangeReason lastChange = mRedoList->lastChangeReason();
|
||||
bool keepGoing;
|
||||
do {
|
||||
doRedoItem();
|
||||
item = mRedoList->peekItem();
|
||||
if (!item)
|
||||
keepGoing = false;
|
||||
else {
|
||||
if (item->changeNumber() == oldChangeNumber)
|
||||
keepGoing = true;
|
||||
else {
|
||||
keepGoing = (mOptions.testFlag(eoGroupUndo) &&
|
||||
(lastChange == item->changeReason()));
|
||||
}
|
||||
updateModifiedStatus();
|
||||
oldChangeNumber=item->changeNumber();
|
||||
lastChange = item->changeReason();
|
||||
}
|
||||
} while (keepGoing);
|
||||
|
||||
//restore Group Break
|
||||
while (mRedoList->lastChangeReason()==SynChangeReason::GroupBreak) {
|
||||
PSynEditUndoItem item = mRedoList->popItem();
|
||||
mUndoList->restoreChange(item);
|
||||
}
|
||||
updateModifiedStatus();
|
||||
onChanged();
|
||||
}
|
||||
|
||||
void SynEdit::doRedoItem()
|
||||
|
@ -4545,33 +4526,36 @@ void SynEdit::doRedoItem()
|
|||
});
|
||||
switch(item->changeReason()) {
|
||||
case SynChangeReason::Caret:
|
||||
mUndoList->addChange(
|
||||
mUndoList->restoreChange(
|
||||
item->changeReason(),
|
||||
caretXY(),
|
||||
caretXY(),
|
||||
QStringList(),
|
||||
mActiveSelectionMode);
|
||||
mActiveSelectionMode,
|
||||
item->changeNumber());
|
||||
internalSetCaretXY(item->changeStartPos());
|
||||
break;
|
||||
case SynChangeReason::LeftTop:
|
||||
BufferCoord p;
|
||||
p.ch = leftChar();
|
||||
p.line = topLine();
|
||||
mUndoList->addChange(
|
||||
mUndoList->restoreChange(
|
||||
item->changeReason(),
|
||||
p,
|
||||
p, QStringList(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
setLeftChar(item->changeStartPos().ch);
|
||||
setTopLine(item->changeStartPos().line);
|
||||
break;
|
||||
case SynChangeReason::Selection:
|
||||
mUndoList->addChange(
|
||||
mUndoList->restoreChange(
|
||||
item->changeReason(),
|
||||
mBlockBegin,
|
||||
mBlockEnd,
|
||||
QStringList(),
|
||||
mActiveSelectionMode);
|
||||
mActiveSelectionMode,
|
||||
item->changeNumber());
|
||||
setCaretAndSelection(
|
||||
caretXY(),
|
||||
item->changeStartPos(),
|
||||
|
@ -4581,23 +4565,25 @@ void SynEdit::doRedoItem()
|
|||
setBlockBegin(BufferCoord{item->changeStartPos().ch, item->changeStartPos().line});
|
||||
setBlockEnd(BufferCoord{item->changeEndPos().ch, item->changeEndPos().line});
|
||||
doMoveSelUp();
|
||||
mUndoList->addChange(
|
||||
mUndoList->restoreChange(
|
||||
item->changeReason(),
|
||||
item->changeStartPos(),
|
||||
item->changeEndPos(),
|
||||
item->changeText(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
break;
|
||||
case SynChangeReason::MoveSelectionDown:
|
||||
setBlockBegin(BufferCoord{item->changeStartPos().ch, item->changeStartPos().line});
|
||||
setBlockEnd(BufferCoord{item->changeEndPos().ch, item->changeEndPos().line});
|
||||
doMoveSelDown();
|
||||
mUndoList->addChange(
|
||||
mUndoList->restoreChange(
|
||||
item->changeReason(),
|
||||
item->changeStartPos(),
|
||||
item->changeEndPos(),
|
||||
item->changeText(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
break;
|
||||
case SynChangeReason::Insert:
|
||||
setCaretAndSelection(
|
||||
|
@ -4608,25 +4594,26 @@ void SynEdit::doRedoItem()
|
|||
item->changeStartPos().line,
|
||||
item->changeEndPos().line);
|
||||
internalSetCaretXY(item->changeEndPos());
|
||||
mUndoList->addChange(item->changeReason(),
|
||||
mUndoList->restoreChange(item->changeReason(),
|
||||
item->changeStartPos(),
|
||||
item->changeEndPos(),
|
||||
QStringList(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),
|
||||
item->changeNumber());
|
||||
break;
|
||||
case SynChangeReason::Delete: {
|
||||
doDeleteText(item->changeStartPos(),item->changeEndPos(),item->changeSelMode());
|
||||
mUndoList->addChange(item->changeReason(), item->changeStartPos(),
|
||||
mUndoList->restoreChange(item->changeReason(), item->changeStartPos(),
|
||||
item->changeEndPos(),item->changeText(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),item->changeNumber());
|
||||
internalSetCaretXY(item->changeStartPos());
|
||||
break;
|
||||
};
|
||||
case SynChangeReason::LineBreak: {
|
||||
BufferCoord CaretPt = item->changeStartPos();
|
||||
mUndoList->addChange(item->changeReason(), item->changeStartPos(),
|
||||
mUndoList->restoreChange(item->changeReason(), item->changeStartPos(),
|
||||
item->changeEndPos(),item->changeText(),
|
||||
item->changeSelMode());
|
||||
item->changeSelMode(),item->changeNumber());
|
||||
setCaretAndSelection(CaretPt, CaretPt, CaretPt);
|
||||
commandProcessor(SynEditorCommand::ecLineBreak);
|
||||
break;
|
||||
|
@ -6591,8 +6578,6 @@ int SynEdit::charWidth() const
|
|||
void SynEdit::setUndoLimit(int size)
|
||||
{
|
||||
mUndoList->setMaxUndoActions(size);
|
||||
|
||||
mRedoList->setMaxUndoActions(size);
|
||||
}
|
||||
|
||||
int SynEdit::charsInWindow() const
|
||||
|
@ -6909,12 +6894,6 @@ void SynEdit::setTopLine(int Value)
|
|||
}
|
||||
}
|
||||
|
||||
void SynEdit::onRedoAdded()
|
||||
{
|
||||
updateModifiedStatus();
|
||||
onChanged();
|
||||
}
|
||||
|
||||
void SynEdit::onGutterChanged()
|
||||
{
|
||||
if (mGutter.showLineNumbers() && mGutter.autoSize())
|
||||
|
|
|
@ -633,7 +633,7 @@ private slots:
|
|||
void onLinesDeleted(int index, int count);
|
||||
void onLinesInserted(int index, int count);
|
||||
void onLinesPutted(int index, int count);
|
||||
void onRedoAdded();
|
||||
//void onRedoAdded();
|
||||
void onScrollTimeout();
|
||||
void onDraggingScrollTimeout();
|
||||
void onUndoAdded();
|
||||
|
@ -687,7 +687,7 @@ private:
|
|||
bool mCaretUseTextColor;
|
||||
QColor mActiveLineColor;
|
||||
PSynEditUndoList mUndoList;
|
||||
PSynEditUndoList mRedoList;
|
||||
PSynEditRedoList mRedoList;
|
||||
QPoint mMouseDownPos;
|
||||
bool mHideSelection;
|
||||
int mMouseWheelAccumulator;
|
||||
|
|
|
@ -840,16 +840,17 @@ SynEditUndoList::SynEditUndoList():QObject()
|
|||
mInsideRedo = false;
|
||||
|
||||
mBlockChangeNumber=0;
|
||||
mBlockLockCount=0;
|
||||
mBlockLock=0;
|
||||
mFullUndoImposible=false;
|
||||
mBlockCount=0;
|
||||
mLastPoppedItemChangeNumber=0;
|
||||
mInitialChangeNumber = 0;
|
||||
mLastRestoredItemChangeNumber=0;
|
||||
}
|
||||
|
||||
void SynEditUndoList::addChange(SynChangeReason AReason, const BufferCoord &AStart,
|
||||
const BufferCoord &AEnd, const QStringList& ChangeText,
|
||||
SynSelectionMode SelMode)
|
||||
void SynEditUndoList::addChange(SynChangeReason reason, const BufferCoord &startPos,
|
||||
const BufferCoord &endPos, const QStringList& changeText,
|
||||
SynSelectionMode selMode)
|
||||
{
|
||||
int changeNumber;
|
||||
if (inBlock()) {
|
||||
|
@ -857,15 +858,41 @@ void SynEditUndoList::addChange(SynChangeReason AReason, const BufferCoord &ASta
|
|||
} else {
|
||||
changeNumber = getNextChangeNumber();
|
||||
}
|
||||
PSynEditUndoItem newItem = std::make_shared<SynEditUndoItem>(
|
||||
reason,
|
||||
selMode,startPos,endPos,changeText,
|
||||
changeNumber);
|
||||
// qDebug()<<"add change"<<changeNumber<<(int)reason;
|
||||
mItems.append(newItem);
|
||||
ensureMaxEntries();
|
||||
if (reason!=SynChangeReason::GroupBreak && !inBlock()) {
|
||||
mBlockCount++;
|
||||
// qDebug()<<"add"<<mBlockCount;
|
||||
emit addedUndo();
|
||||
}
|
||||
}
|
||||
|
||||
void SynEditUndoList::restoreChange(SynChangeReason AReason, const BufferCoord &AStart, const BufferCoord &AEnd, const QStringList &ChangeText, SynSelectionMode SelMode, size_t changeNumber)
|
||||
{
|
||||
PSynEditUndoItem newItem = std::make_shared<SynEditUndoItem>(AReason,
|
||||
SelMode,AStart,AEnd,ChangeText,
|
||||
changeNumber);
|
||||
mItems.append(newItem);
|
||||
restoreChange(newItem);
|
||||
}
|
||||
|
||||
void SynEditUndoList::restoreChange(PSynEditUndoItem item)
|
||||
{
|
||||
size_t changeNumber = item->changeNumber();
|
||||
mItems.append(item);
|
||||
ensureMaxEntries();
|
||||
if (AReason!=SynChangeReason::GroupBreak && !inBlock()) {
|
||||
if (changeNumber>mNextChangeNumber)
|
||||
mNextChangeNumber=changeNumber;
|
||||
if (changeNumber!=mLastRestoredItemChangeNumber) {
|
||||
// qDebug()<<"restore"<<mBlockCount;
|
||||
mBlockCount++;
|
||||
emit addedUndo();
|
||||
}
|
||||
mLastRestoredItemChangeNumber=changeNumber;
|
||||
}
|
||||
|
||||
void SynEditUndoList::addGroupBreak()
|
||||
|
@ -880,8 +907,11 @@ void SynEditUndoList::addGroupBreak()
|
|||
|
||||
void SynEditUndoList::beginBlock()
|
||||
{
|
||||
mBlockLockCount++;
|
||||
mBlockChangeNumber = getNextChangeNumber();
|
||||
// qDebug()<<"begin block";
|
||||
if (mBlockLock==0)
|
||||
mBlockChangeNumber = getNextChangeNumber();
|
||||
mBlockLock++;
|
||||
|
||||
}
|
||||
|
||||
void SynEditUndoList::clear()
|
||||
|
@ -890,19 +920,22 @@ void SynEditUndoList::clear()
|
|||
mFullUndoImposible = false;
|
||||
mInitialChangeNumber=0;
|
||||
mLastPoppedItemChangeNumber=0;
|
||||
mLastRestoredItemChangeNumber=0;
|
||||
mBlockCount=0;
|
||||
mBlockLockCount=0;
|
||||
mBlockLock=0;
|
||||
}
|
||||
|
||||
void SynEditUndoList::endBlock()
|
||||
{
|
||||
if (mBlockLockCount > 0) {
|
||||
mBlockLockCount--;
|
||||
if (mBlockLockCount == 0) {
|
||||
// qDebug()<<"end block";
|
||||
if (mBlockLock > 0) {
|
||||
mBlockLock--;
|
||||
if (mBlockLock == 0) {
|
||||
size_t iBlockID = mBlockChangeNumber;
|
||||
mBlockChangeNumber = 0;
|
||||
if (mItems.count() > 0 && peekItem()->changeNumber() == iBlockID) {
|
||||
mBlockCount++;
|
||||
// qDebug()<<"end block"<<mBlockCount;
|
||||
emit addedUndo();
|
||||
}
|
||||
}
|
||||
|
@ -911,7 +944,7 @@ void SynEditUndoList::endBlock()
|
|||
|
||||
bool SynEditUndoList::inBlock()
|
||||
{
|
||||
return mBlockLockCount>0;
|
||||
return mBlockLock>0;
|
||||
}
|
||||
|
||||
unsigned int SynEditUndoList::getNextChangeNumber()
|
||||
|
@ -946,10 +979,12 @@ PSynEditUndoItem SynEditUndoList::popItem()
|
|||
return PSynEditUndoItem();
|
||||
else {
|
||||
PSynEditUndoItem item = mItems.last();
|
||||
if (mLastPoppedItemChangeNumber!=item->changeNumber()) {
|
||||
// qDebug()<<"popped"<<item->changeNumber()<<item->changeText()<<(int)item->changeReason()<<mLastPoppedItemChangeNumber;
|
||||
if (mLastPoppedItemChangeNumber!=item->changeNumber() && item->changeReason()!=SynChangeReason::GroupBreak) {
|
||||
mBlockCount--;
|
||||
// qDebug()<<"pop"<<mBlockCount;
|
||||
if (mBlockCount<0) {
|
||||
qDebug()<<"block count calculation error";
|
||||
// qDebug()<<"block count calculation error";
|
||||
mBlockCount=0;
|
||||
}
|
||||
}
|
||||
|
@ -999,16 +1034,6 @@ void SynEditUndoList::setInitialState()
|
|||
mInitialChangeNumber = peekItem()->changeNumber();
|
||||
}
|
||||
|
||||
int SynEditUndoList::blockChangeNumber() const
|
||||
{
|
||||
return mBlockChangeNumber;
|
||||
}
|
||||
|
||||
void SynEditUndoList::setBlockChangeNumber(int blockChangeNumber)
|
||||
{
|
||||
mBlockChangeNumber = blockChangeNumber;
|
||||
}
|
||||
|
||||
bool SynEditUndoList::insideRedo() const
|
||||
{
|
||||
return mInsideRedo;
|
||||
|
@ -1030,10 +1055,12 @@ void SynEditUndoList::ensureMaxEntries()
|
|||
mFullUndoImposible = true;
|
||||
while (mBlockCount > mMaxUndoActions && !mItems.isEmpty()) {
|
||||
//remove all undo item in block
|
||||
size_t changeNumber = mItems.front()->changeNumber();
|
||||
PSynEditUndoItem item = mItems.front();
|
||||
size_t changeNumber = item->changeNumber();
|
||||
while (mItems.count()>0 && mItems.front()->changeNumber() == changeNumber)
|
||||
mItems.removeFirst();
|
||||
mBlockCount--;
|
||||
if (item->changeReason()!=SynChangeReason::GroupBreak)
|
||||
mBlockCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1079,3 +1106,69 @@ SynChangeReason SynEditUndoItem::changeReason() const
|
|||
{
|
||||
return mChangeReason;
|
||||
}
|
||||
|
||||
SynEditRedoList::SynEditRedoList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SynEditRedoList::addRedo(SynChangeReason AReason, const BufferCoord &AStart, const BufferCoord &AEnd, const QStringList &ChangeText, SynSelectionMode SelMode, size_t changeNumber)
|
||||
{
|
||||
PSynEditUndoItem newItem = std::make_shared<SynEditUndoItem>(
|
||||
AReason,
|
||||
SelMode,AStart,AEnd,ChangeText,
|
||||
changeNumber);
|
||||
mItems.append(newItem);
|
||||
}
|
||||
|
||||
void SynEditRedoList::addRedo(PSynEditUndoItem item)
|
||||
{
|
||||
mItems.append(item);
|
||||
}
|
||||
|
||||
void SynEditRedoList::clear()
|
||||
{
|
||||
mItems.clear();
|
||||
}
|
||||
|
||||
SynChangeReason SynEditRedoList::lastChangeReason()
|
||||
{
|
||||
if (mItems.count() == 0)
|
||||
return SynChangeReason::Nothing;
|
||||
else
|
||||
return mItems.last()->changeReason();
|
||||
}
|
||||
|
||||
bool SynEditRedoList::isEmpty()
|
||||
{
|
||||
return mItems.isEmpty();
|
||||
}
|
||||
|
||||
PSynEditUndoItem SynEditRedoList::peekItem()
|
||||
{
|
||||
if (mItems.count() == 0)
|
||||
return PSynEditUndoItem();
|
||||
else
|
||||
return mItems.last();
|
||||
}
|
||||
|
||||
PSynEditUndoItem SynEditRedoList::popItem()
|
||||
{
|
||||
if (mItems.count() == 0)
|
||||
return PSynEditUndoItem();
|
||||
else {
|
||||
PSynEditUndoItem item = mItems.last();
|
||||
mItems.removeLast();
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
bool SynEditRedoList::canRedo()
|
||||
{
|
||||
return mItems.count()>0;
|
||||
}
|
||||
|
||||
int SynEditRedoList::itemCount()
|
||||
{
|
||||
return mItems.count();
|
||||
}
|
||||
|
|
|
@ -196,6 +196,7 @@ public:
|
|||
QStringList changeText() const;
|
||||
size_t changeNumber() const;
|
||||
};
|
||||
|
||||
using PSynEditUndoItem = std::shared_ptr<SynEditUndoItem>;
|
||||
|
||||
class SynEditUndoList : public QObject {
|
||||
|
@ -206,6 +207,11 @@ public:
|
|||
void addChange(SynChangeReason AReason, const BufferCoord& AStart, const BufferCoord& AEnd,
|
||||
const QStringList& ChangeText, SynSelectionMode SelMode);
|
||||
|
||||
void restoreChange(SynChangeReason AReason, const BufferCoord& AStart, const BufferCoord& AEnd,
|
||||
const QStringList& ChangeText, SynSelectionMode SelMode, size_t changeNumber);
|
||||
|
||||
void restoreChange(PSynEditUndoItem item);
|
||||
|
||||
void addGroupBreak();
|
||||
void beginBlock();
|
||||
void endBlock();
|
||||
|
@ -224,9 +230,6 @@ public:
|
|||
bool initialState();
|
||||
void setInitialState();
|
||||
|
||||
int blockChangeNumber() const;
|
||||
void setBlockChangeNumber(int blockChangeNumber);
|
||||
|
||||
bool insideRedo() const;
|
||||
void setInsideRedo(bool insideRedo);
|
||||
|
||||
|
@ -240,9 +243,10 @@ protected:
|
|||
unsigned int getNextChangeNumber();
|
||||
protected:
|
||||
size_t mBlockChangeNumber;
|
||||
int mBlockLockCount;
|
||||
int mBlockLock;
|
||||
int mBlockCount; // count of action blocks;
|
||||
size_t mLastPoppedItemChangeNumber;
|
||||
size_t mLastRestoredItemChangeNumber;
|
||||
bool mFullUndoImposible;
|
||||
QVector<PSynEditUndoItem> mItems;
|
||||
int mMaxUndoActions;
|
||||
|
@ -251,6 +255,30 @@ protected:
|
|||
bool mInsideRedo;
|
||||
};
|
||||
|
||||
class SynEditRedoList : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SynEditRedoList();
|
||||
|
||||
void addRedo(SynChangeReason AReason, const BufferCoord& AStart, const BufferCoord& AEnd,
|
||||
const QStringList& ChangeText, SynSelectionMode SelMode, size_t changeNumber);
|
||||
void addRedo(PSynEditUndoItem item);
|
||||
|
||||
void clear();
|
||||
SynChangeReason lastChangeReason();
|
||||
bool isEmpty();
|
||||
PSynEditUndoItem peekItem();
|
||||
PSynEditUndoItem popItem();
|
||||
|
||||
bool canRedo();
|
||||
int itemCount();
|
||||
|
||||
protected:
|
||||
QVector<PSynEditUndoItem> mItems;
|
||||
};
|
||||
|
||||
|
||||
using PSynEditUndoList = std::shared_ptr<SynEditUndoList>;
|
||||
using PSynEditRedoList = std::shared_ptr<SynEditRedoList>;
|
||||
|
||||
#endif // SYNEDITSTRINGLIST_H
|
||||
|
|
Loading…
Reference in New Issue