work save : undo almost done

This commit is contained in:
Roy Qu 2022-07-02 14:06:10 +08:00
parent 3f814901d5
commit 655f0bf83e
6 changed files with 122 additions and 98 deletions

View File

@ -645,3 +645,22 @@ BufferCoord maxBufferCoord(const BufferCoord &P1, const BufferCoord &P2)
return P1; return P1;
} }
} }
QStringList splitStrings(const QString &text)
{
QStringList list;
int start=0,i=0;
while(i<text.length()) {
if (text[i]=='\n' || text[i]=='\r') {
list.append(text.mid(start,i-start));
i++;
while (i<text.length() && (text[i]=='\n' || text[i]=='\r')) i++;
start=i;
} else {
i++;
}
}
if (i>=start)
list.append(text.mid(start,i));
return list;
}

View File

@ -81,6 +81,8 @@ int StrRScanForCharInSet(const QString& Line, int Start, const QSet<QChar>& ACh
int GetEOL(const QString& Line, int start); int GetEOL(const QString& Line, int start);
int CountLines(const QString& Line, int start); int CountLines(const QString& Line, int start);
QStringList splitStrings(const QString& text);
// Remove all '/' characters from string by changing them into '\.'. // Remove all '/' characters from string by changing them into '\.'.
// Change all '\' characters into '\\' to allow for unique decoding. // Change all '\' characters into '\\' to allow for unique decoding.
QString EncodeString(const QString & s); QString EncodeString(const QString & s);

View File

@ -462,7 +462,7 @@ void SynEdit::endUndoBlock()
void SynEdit::addCaretToUndo() void SynEdit::addCaretToUndo()
{ {
BufferCoord p=caretXY(); BufferCoord p=caretXY();
mUndoList->AddChange(SynChangeReason::crCaret,p,p,QStringList(), activeSelectionMode()); mUndoList->AddChange(SynChangeReason::crCaret,p,p,QStringList(), mActiveSelectionMode);
} }
void SynEdit::addLeftTopToUndo() void SynEdit::addLeftTopToUndo()
@ -470,7 +470,13 @@ void SynEdit::addLeftTopToUndo()
BufferCoord p; BufferCoord p;
p.Char = leftChar(); p.Char = leftChar();
p.Line = topLine(); p.Line = topLine();
mUndoList->AddChange(SynChangeReason::crLeftTop,p,p,QStringList(), activeSelectionMode()); mUndoList->AddChange(SynChangeReason::crLeftTop,p,p,QStringList(), mActiveSelectionMode);
}
void SynEdit::addSelectionToUndo()
{
mUndoList->AddChange(SynChangeReason::crSelection,mBlockBegin,
mBlockEnd,QStringList(),mActiveSelectionMode);
} }
void SynEdit::beginUpdate() void SynEdit::beginUpdate()
@ -2165,19 +2171,41 @@ void SynEdit::doDeleteFromBOL()
void SynEdit::doDeleteLine() void SynEdit::doDeleteLine()
{ {
if (!mReadOnly && (mDocument->count() > 0) if (!mReadOnly && (mDocument->count() > 0)) {
&& ! ((mCaretY == mDocument->count()) && (lineText().isEmpty()))) {
doOnPaintTransient(SynTransientType::ttBefore); doOnPaintTransient(SynTransientType::ttBefore);
mUndoList->BeginBlock();
mUndoList->AddChange(SynChangeReason::crCaret,
caretXY(),
caretXY(),
QStringList(),
mActiveSelectionMode);
mUndoList->AddChange(SynChangeReason::crSelection,
mBlockBegin,
mBlockEnd,
QStringList(),
mActiveSelectionMode);
if (selAvail()) if (selAvail())
setBlockBegin(caretXY()); setBlockBegin(caretXY());
QStringList helper; QStringList helper(lineText());
helper.append(lineText());
if (mCaretY == mDocument->count()) { if (mCaretY == mDocument->count()) {
if (mDocument->count()==1) {
mDocument->putString(mCaretY - 1,""); mDocument->putString(mCaretY - 1,"");
mUndoList->AddChange(SynChangeReason::crDelete, mUndoList->AddChange(SynChangeReason::crDelete,
BufferCoord{1, mCaretY}, BufferCoord{1, mCaretY},
BufferCoord{helper.length() + 1, mCaretY}, BufferCoord{helper.length() + 1, mCaretY},
helper, SynSelectionMode::smNormal); helper, SynSelectionMode::smNormal);
} else {
QString s = mDocument->getString(mCaretY-2);
mDocument->deleteAt(mCaretY - 1);
helper.insert(0,"");
qDebug()<<helper;
mUndoList->AddChange(SynChangeReason::crDelete,
BufferCoord{s.length()+1, mCaretY-1},
BufferCoord{helper.length() + 1, mCaretY},
helper, SynSelectionMode::smNormal);
doLinesDeleted(mCaretY, 1);
mCaretY--;
}
} else { } else {
mDocument->deleteAt(mCaretY - 1); mDocument->deleteAt(mCaretY - 1);
helper.append(""); helper.append("");
@ -2187,6 +2215,7 @@ void SynEdit::doDeleteLine()
helper, SynSelectionMode::smNormal); helper, SynSelectionMode::smNormal);
doLinesDeleted(mCaretY, 1); doLinesDeleted(mCaretY, 1);
} }
mUndoList->EndBlock();
internalSetCaretXY(BufferCoord{1, mCaretY}); // like seen in the Delphi editor internalSetCaretXY(BufferCoord{1, mCaretY}); // like seen in the Delphi editor
doOnPaintTransient(SynTransientType::ttAfter); doOnPaintTransient(SynTransientType::ttAfter);
} }
@ -2212,10 +2241,11 @@ void SynEdit::doDuplicateLine()
mUndoList->AddChange(SynChangeReason::crCaret, mUndoList->AddChange(SynChangeReason::crCaret,
caretXY(),caretXY(),QStringList(),SynSelectionMode::smNormal); caretXY(),caretXY(),QStringList(),SynSelectionMode::smNormal);
mUndoList->AddChange(SynChangeReason::crLineBreak, mUndoList->AddChange(SynChangeReason::crLineBreak,
caretXY(), caretXY(), QStringList(), SynSelectionMode::smNormal); BufferCoord{s.length()+1,mCaretY},
mUndoList->AddChange(SynChangeReason::crInsert,
BufferCoord{1,mCaretY},
BufferCoord{s.length()+1,mCaretY}, QStringList(), SynSelectionMode::smNormal); BufferCoord{s.length()+1,mCaretY}, QStringList(), SynSelectionMode::smNormal);
mUndoList->AddChange(SynChangeReason::crInsert,
BufferCoord{1,mCaretY+1},
BufferCoord{s.length()+1,mCaretY+1}, QStringList(), SynSelectionMode::smNormal);
mUndoList->EndBlock(); mUndoList->EndBlock();
internalSetCaretXY(BufferCoord{1, mCaretY}); // like seen in the Delphi editor internalSetCaretXY(BufferCoord{1, mCaretY}); // like seen in the Delphi editor
doOnPaintTransient(SynTransientType::ttAfter); doOnPaintTransient(SynTransientType::ttAfter);
@ -3006,7 +3036,8 @@ void SynEdit::doPasteFromClipboard()
BufferCoord vEndOfBlock = blockEnd(); BufferCoord vEndOfBlock = blockEnd();
mBlockBegin = vStartOfBlock; mBlockBegin = vStartOfBlock;
mBlockEnd = vEndOfBlock; mBlockEnd = vEndOfBlock;
setSelTextPrimitive(textToLines(text)); qDebug()<<textToLines(text);
setSelTextPrimitive(splitStrings(text));
mUndoList->EndBlock(); mUndoList->EndBlock();
} }
@ -4332,6 +4363,9 @@ void SynEdit::doUndoItem()
case SynChangeReason::crDelete: { case SynChangeReason::crDelete: {
// If there's no selection, we have to set // If there's no selection, we have to set
// the Caret's position manualy. // the Caret's position manualy.
qDebug()<<"undo delete";
qDebug()<<Item->changeText();
qDebug()<<Item->changeStartPos().Line<<Item->changeStartPos().Char;
doInsertText(Item->changeStartPos(),Item->changeText(),Item->changeSelMode()); doInsertText(Item->changeStartPos(),Item->changeText(),Item->changeSelMode());
internalSetCaretXY(Item->changeEndPos()); internalSetCaretXY(Item->changeEndPos());
mRedoList->AddChange( mRedoList->AddChange(
@ -5094,7 +5128,7 @@ void SynEdit::doSetSelText(const QString &value)
BufferCoord EndOfBlock = blockEnd(); BufferCoord EndOfBlock = blockEnd();
mBlockBegin = StartOfBlock; mBlockBegin = StartOfBlock;
mBlockEnd = EndOfBlock; mBlockEnd = EndOfBlock;
setSelTextPrimitive(textToLines(value)); setSelTextPrimitive(splitStrings(value));
} }
int SynEdit::searchReplace(const QString &sSearch, const QString &sReplace, SynSearchOptions sOptions, PSynSearchBase searchEngine, int SynEdit::searchReplace(const QString &sSearch, const QString &sReplace, SynSearchOptions sOptions, PSynSearchBase searchEngine,
@ -5329,6 +5363,9 @@ void SynEdit::doDeleteText(const BufferCoord &startPos, const BufferCoord &endPo
bool UpdateMarks = false; bool UpdateMarks = false;
int MarkOffset = 0; int MarkOffset = 0;
QStringList deleted=getContent(startPos,endPos,mode); QStringList deleted=getContent(startPos,endPos,mode);
qDebug()<<"D----";
qDebug()<<deleted;
switch(mode) { switch(mode) {
case SynSelectionMode::smNormal: case SynSelectionMode::smNormal:
if (mDocument->count() > 0) { if (mDocument->count() > 0) {
@ -5429,19 +5466,20 @@ int SynEdit::doInsertTextByNormalMode(const BufferCoord& pos, const QStringList&
QString sLeftSide; QString sLeftSide;
QString sRightSide; QString sRightSide;
QString Str; QString str;
bool bChangeScroll; bool bChangeScroll;
// int SpaceCount; // int SpaceCount;
int result = 0; int result = 0;
int startLine = pos.Line; int startLine = pos.Line;
sLeftSide = lineText().mid(0, pos.Char - 1); QString line=mDocument->getString(pos.Line-1);
sLeftSide = line.mid(0, pos.Char - 1);
if (pos.Char - 1 > sLeftSide.length()) { if (pos.Char - 1 > sLeftSide.length()) {
if (stringIsBlank(sLeftSide)) if (stringIsBlank(sLeftSide))
sLeftSide = GetLeftSpacing(displayX() - 1, true); sLeftSide = GetLeftSpacing(displayX() - 1, true);
else else
sLeftSide += QString(pos.Char - 1 - sLeftSide.length(),' '); sLeftSide += QString(pos.Char - 1 - sLeftSide.length(),' ');
} }
sRightSide = lineText().mid(pos.Char - 1); sRightSide = line.mid(pos.Char - 1);
// if (mUndoing) { // if (mUndoing) {
// SpaceCount = 0; // SpaceCount = 0;
// } else { // } else {
@ -5450,19 +5488,19 @@ int SynEdit::doInsertTextByNormalMode(const BufferCoord& pos, const QStringList&
int caretY=pos.Line; int caretY=pos.Line;
// step1: insert the first line of Value into current line // step1: insert the first line of Value into current line
if (text.length()>1) { if (text.length()>1) {
if (mHighlighter && mOptions.testFlag(eoAutoIndent)) { if (!mUndoing && mHighlighter && mOptions.testFlag(eoAutoIndent)) {
QString s = trimLeft(text[0]); QString s = trimLeft(text[0]);
if (sLeftSide.isEmpty()) { if (sLeftSide.isEmpty()) {
sLeftSide = GetLeftSpacing(calcIndentSpaces(caretY,s,true),true); sLeftSide = GetLeftSpacing(calcIndentSpaces(caretY,s,true),true);
} }
Str = sLeftSide + s; str = sLeftSide + s;
} else } else
Str = sLeftSide + text[0]; str = sLeftSide + text[0];
properSetLine(caretY - 1, Str); properSetLine(caretY - 1, str);
mDocument->insertLines(caretY, text.length()-1); mDocument->insertLines(caretY, text.length()-1);
} else { } else {
Str = sLeftSide + text[0] + sRightSide; str = sLeftSide + text[0] + sRightSide;
properSetLine(caretY - 1, Str); properSetLine(caretY - 1, str);
} }
rescanRange(caretY); rescanRange(caretY);
// step2: insert remaining lines of Value // step2: insert remaining lines of Value
@ -5474,28 +5512,28 @@ int SynEdit::doInsertTextByNormalMode(const BufferCoord& pos, const QStringList&
// && !mHighlighter->isLastLineStringNotFinished( // && !mHighlighter->isLastLineStringNotFinished(
// mHighlighter->getRangeState().state); // mHighlighter->getRangeState().state);
// } // }
// caretY++; caretY=pos.Line+i;
// mStatusChanges.setFlag(SynStatusChange::scCaretY); // mStatusChanges.setFlag(SynStatusChange::scCaretY);
if (text[i].isEmpty()) { if (text[i].isEmpty()) {
if (i==text.length()-1) { if (i==text.length()-1) {
Str = sRightSide; str = sRightSide;
} else { } else {
if (mHighlighter && mOptions.testFlag(eoAutoIndent) && notInComment) { if (!mUndoing && mHighlighter && mOptions.testFlag(eoAutoIndent) && notInComment) {
Str = GetLeftSpacing(calcIndentSpaces(caretY,"",true),true); str = GetLeftSpacing(calcIndentSpaces(caretY,"",true),true);
} else { } else {
Str = ""; str = "";
} }
} }
} else { } else {
Str = text[i]; str = text[i];
if (i==text.length()-1) if (i==text.length()-1)
Str += sRightSide; str += sRightSide;
if (mHighlighter && mOptions.testFlag(eoAutoIndent) && notInComment) { if (!mUndoing && mHighlighter && mOptions.testFlag(eoAutoIndent) && notInComment) {
int indentSpaces = calcIndentSpaces(caretY,Str,true); int indentSpaces = calcIndentSpaces(caretY,str,true);
Str = GetLeftSpacing(indentSpaces,true)+trimLeft(Str); str = GetLeftSpacing(indentSpaces,true)+trimLeft(str);
} }
} }
properSetLine(caretY - 1, Str,false); properSetLine(caretY - 1, str,false);
rescanRange(caretY); rescanRange(caretY);
result++; result++;
} }
@ -5506,17 +5544,16 @@ int SynEdit::doInsertTextByNormalMode(const BufferCoord& pos, const QStringList&
mOptions.setFlag(eoScrollPastEol,false); mOptions.setFlag(eoScrollPastEol,false);
}); });
if (mOptions.testFlag(eoTrimTrailingSpaces) && (sRightSide == "")) { if (mOptions.testFlag(eoTrimTrailingSpaces) && (sRightSide == "")) {
newPos=BufferCoord{lineText().length()+1,caretY}; newPos=BufferCoord{mDocument->getString(caretY-1).length()+1,caretY};
} else } else
newPos=BufferCoord{Str.length() - sRightSide.length()+1,caretY}; newPos=BufferCoord{str.length() - sRightSide.length()+1,caretY};
onLinesPutted(startLine-1,result+1);
if (!mUndoing) { if (!mUndoing) {
mUndoList->AddChange( mUndoList->AddChange(
SynChangeReason::crInsert, SynChangeReason::crInsert,
pos,newPos, pos,newPos,
QStringList(),SynSelectionMode::smNormal); QStringList(),SynSelectionMode::smNormal);
} }
onLinesPutted(startLine-1,result+1);
return result; return result;
} }
@ -6389,35 +6426,34 @@ void SynEdit::dropEvent(QDropEvent *event)
BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(event->pos().x(), BufferCoord coord = displayToBufferPos(pixelsToNearestRowColumn(event->pos().x(),
event->pos().y())); event->pos().y()));
setCaretXY(coord);
if (coord>=mDragSelBeginSave && coord<=mDragSelEndSave) { if (coord>=mDragSelBeginSave && coord<=mDragSelEndSave) {
//do nothing if drag onto itself //do nothing if drag onto itself
} else if (event->proposedAction() == Qt::DropAction::CopyAction) { event->acceptProposedAction();
//just copy it mDropped = true;
setSelText(event->mimeData()->text()); return;
} else if (event->proposedAction() == Qt::DropAction::MoveAction) { }
int topLine = mTopLine; int topLine = mTopLine;
int leftChar = mLeftChar; int leftChar = mLeftChar;
QStringList text=splitStrings(event->mimeData()->text());
mUndoList->BeginBlock(); mUndoList->BeginBlock();
addLeftTopToUndo();
addCaretToUndo();
addSelectionToUndo();
internalSetCaretXY(coord);
if (event->proposedAction() == Qt::DropAction::CopyAction) {
//just copy it
doInsertText(coord,text,mActiveSelectionMode);
} else if (event->proposedAction() == Qt::DropAction::MoveAction) {
if (coord < mDragSelBeginSave ) { if (coord < mDragSelBeginSave ) {
//delete old //delete old
setBlockBegin(mDragSelBeginSave); doDeleteText(mDragSelBeginSave,mDragSelEndSave,mActiveSelectionMode);
setBlockEnd(mDragSelEndSave);
setSelText("");
//paste to new position //paste to new position
setTopLine(topLine); doInsertText(coord,text,mActiveSelectionMode);
setLeftChar(leftChar);
setCaretXY(coord);
setSelText(event->mimeData()->text());
} else { } else {
//paste to new position //paste to new position
setTopLine(topLine); doInsertText(coord,text,mActiveSelectionMode);
setLeftChar(leftChar);
setSelText(event->mimeData()->text());
//delete old //delete old
setBlockBegin(mDragSelBeginSave); doDeleteText(mDragSelBeginSave,mDragSelEndSave,mActiveSelectionMode);
setBlockEnd(mDragSelEndSave);
setSelText("");
//set caret to right pos //set caret to right pos
if (mDragSelBeginSave.Line == mDragSelEndSave.Line) { if (mDragSelBeginSave.Line == mDragSelEndSave.Line) {
if (coord.Line == mDragSelEndSave.Line) { if (coord.Line == mDragSelEndSave.Line) {
@ -6431,14 +6467,15 @@ void SynEdit::dropEvent(QDropEvent *event)
topLine -= mDragSelEndSave.Line-mDragSelBeginSave.Line; topLine -= mDragSelEndSave.Line-mDragSelBeginSave.Line;
} }
} }
setTopLine(topLine);
setLeftChar(leftChar);
setCaretXY(coord);
} }
mUndoList->EndBlock(); mUndoList->EndBlock();
} }
event->acceptProposedAction(); event->acceptProposedAction();
mDropped = true; mDropped = true;
setTopLine(topLine);
setLeftChar(leftChar);
internalSetCaretXY(coord);
} }
void SynEdit::dragMoveEvent(QDragMoveEvent *event) void SynEdit::dragMoveEvent(QDragMoveEvent *event)

View File

@ -270,6 +270,7 @@ public:
void endUndoBlock(); void endUndoBlock();
void addCaretToUndo(); void addCaretToUndo();
void addLeftTopToUndo(); void addLeftTopToUndo();
void addSelectionToUndo();
void replaceAll(const QString& text) { void replaceAll(const QString& text) {
mUndoList->AddChange(SynChangeReason::crSelection,mBlockBegin,mBlockEnd,QStringList(), activeSelectionMode()); mUndoList->AddChange(SynChangeReason::crSelection,mBlockBegin,mBlockEnd,QStringList(), activeSelectionMode());
selectAll(); selectAll();

View File

@ -500,40 +500,6 @@ void SynDocument::insertLines(int Index, int NumLines)
emit inserted(Index,NumLines); emit inserted(Index,NumLines);
} }
void SynDocument::insertStrings(int Index, const QStringList &NewStrings)
{
QMutexLocker locker(&mMutex);
if (Index<0 || Index>mLines.count()) {
ListIndexOutOfBounds(Index);
}
if (NewStrings.isEmpty())
return;
beginUpdate();
auto action = finally([this]{
endUpdate();
});
mIndexOfLongestLine = -1;
PSynDocumentLine line;
mLines.insert(Index,NewStrings.length(),line);
for (int i=0;i<NewStrings.length();i++) {
line = std::make_shared<SynDocumentLine>();
line->fString = NewStrings[i];
mLines[i+Index]=line;
}
emit inserted(Index,NewStrings.length());
}
void SynDocument::insertText(int Index, const QString &NewText)
{
QMutexLocker locker(&mMutex);
if (Index<0 || Index>=mLines.count()) {
ListIndexOutOfBounds(Index);
}
if (NewText.isEmpty())
return;
QStringList lines = textToLines(NewText);
insertStrings(Index,lines);
}
bool SynDocument::tryLoadFileByEncoding(QByteArray encodingName, QFile& file) { bool SynDocument::tryLoadFileByEncoding(QByteArray encodingName, QFile& file) {
QTextCodec* codec = QTextCodec::codecForName(encodingName); QTextCodec* codec = QTextCodec::codecForName(encodingName);

View File

@ -97,8 +97,7 @@ public:
void exchange(int Index1, int Index2); void exchange(int Index1, int Index2);
void insert(int Index, const QString& s); void insert(int Index, const QString& s);
void insertLines(int Index, int NumLines); void insertLines(int Index, int NumLines);
void insertStrings(int Index, const QStringList& NewStrings);
void insertText(int Index,const QString& NewText);
void loadFromFile(const QString& filename, const QByteArray& encoding, QByteArray& realEncoding); void loadFromFile(const QString& filename, const QByteArray& encoding, QByteArray& realEncoding);
void saveToFile(QFile& file, const QByteArray& encoding, void saveToFile(QFile& file, const QByteArray& encoding,
const QByteArray& defaultEncoding, QByteArray& realEncoding); const QByteArray& defaultEncoding, QByteArray& realEncoding);