diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CellBuffer.cxx | 56 | ||||
-rw-r--r-- | src/CellBuffer.h | 12 | ||||
-rw-r--r-- | src/ContractionState.cxx | 9 | ||||
-rw-r--r-- | src/Document.cxx | 55 | ||||
-rw-r--r-- | src/Document.h | 10 | ||||
-rw-r--r-- | src/Editor.cxx | 6 |
6 files changed, 114 insertions, 34 deletions
diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index 0f33d48c4..e6aa4a013 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -200,10 +200,13 @@ void LineVector::InsertValue(int pos, int value) { for (int j = lines; j > pos; j--) { levels[j] = levels[j - 1]; } - if (pos == (lines-1)) // Last line will not be a folder + if (pos == 0) { levels[pos] = SC_FOLDLEVELBASE; - else - levels[pos] = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; + } else if (pos == (lines-1)) { // Last line will not be a folder + levels[pos] = SC_FOLDLEVELBASE; + } else { + levels[pos] = levels[pos-1]; + } } } @@ -230,6 +233,15 @@ void LineVector::Remove(int pos) { for (int i = pos; i < lines; i++) { linesData[i] = linesData[i + 1]; } + if (levels) { + // Level information merges back onto previous line + int posAbove = pos-1; + if (posAbove < 0) + posAbove = 0; + for (int j = posAbove; j < lines; j++) { + levels[j] = levels[j + 1]; + } + } lines--; } @@ -514,8 +526,12 @@ int UndoHistory::StartUndo() { return currentAction - act; } -const Action &UndoHistory::UndoStep() { - return actions[currentAction--]; +const Action &UndoHistory::GetUndoStep() const { + return actions[currentAction]; +} + +void UndoHistory::CompletedUndoStep() { + currentAction--; } bool UndoHistory::CanRedo() const { @@ -535,15 +551,19 @@ int UndoHistory::StartRedo() { return act - currentAction; } -const Action &UndoHistory::RedoStep() { - return actions[currentAction++]; +const Action &UndoHistory::GetRedoStep() const { + return actions[currentAction]; +} + +void UndoHistory::CompletedRedoStep() { + currentAction++; } CellBuffer::CellBuffer(int initialLength) { body = new char[initialLength]; size = initialLength; length = 0; - part1len = 0; + part1len = 0; gaplen = initialLength; part2body = body + gaplen; readOnly = false; @@ -962,8 +982,12 @@ int CellBuffer::StartUndo() { return uh.StartUndo(); } -const Action &CellBuffer::UndoStep() { - const Action &actionStep = uh.UndoStep(); +const Action &CellBuffer::GetUndoStep() const { + return uh.GetUndoStep(); +} + +void CellBuffer::PerformUndoStep() { + const Action &actionStep = uh.GetUndoStep(); if (actionStep.at == insertAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } else if (actionStep.at == removeAction) { @@ -975,7 +999,7 @@ const Action &CellBuffer::UndoStep() { BasicInsertString(actionStep.position, styledData, actionStep.lenData*2); delete []styledData; } - return actionStep; + uh.CompletedUndoStep(); } bool CellBuffer::CanRedo() { @@ -986,8 +1010,12 @@ int CellBuffer::StartRedo() { return uh.StartRedo(); } -const Action &CellBuffer::RedoStep() { - const Action &actionStep = uh.RedoStep(); +const Action &CellBuffer::GetRedoStep() const { + return uh.GetRedoStep(); +} + +void CellBuffer::PerformRedoStep() { + const Action &actionStep = uh.GetRedoStep(); if (actionStep.at == insertAction) { char *styledData = new char[actionStep.lenData * 2]; for (int i = 0; i < actionStep.lenData; i++) { @@ -999,7 +1027,7 @@ const Action &CellBuffer::RedoStep() { } else if (actionStep.at == removeAction) { BasicDeleteChars(actionStep.position, actionStep.lenData*2); } - return actionStep; + uh.CompletedRedoStep(); } int CellBuffer::SetLineState(int line, int state) { diff --git a/src/CellBuffer.h b/src/CellBuffer.h index 2fcaca3a5..409a8749d 100644 --- a/src/CellBuffer.h +++ b/src/CellBuffer.h @@ -120,10 +120,12 @@ public: // called that many times. Similarly for redo. bool CanUndo() const; int StartUndo(); - const Action &UndoStep(); + const Action &GetUndoStep() const; + void CompletedUndoStep(); bool CanRedo() const; int StartRedo(); - const Action &RedoStep(); + const Action &GetRedoStep() const; + void CompletedRedoStep(); }; // Holder for an expandable array of characters that supports undo and line markers @@ -207,10 +209,12 @@ public: // called that many times. Similarly for redo. bool CanUndo(); int StartUndo(); - const Action &UndoStep(); + const Action &GetUndoStep() const; + void PerformUndoStep(); bool CanRedo(); int StartRedo(); - const Action &RedoStep(); + const Action &GetRedoStep() const; + void PerformRedoStep(); int SetLineState(int line, int state); int GetLineState(int line); diff --git a/src/ContractionState.cxx b/src/ContractionState.cxx index b01081588..82bf40994 100644 --- a/src/ContractionState.cxx +++ b/src/ContractionState.cxx @@ -131,10 +131,11 @@ void ContractionState::DeleteLines(int lineDoc, int lineCount) { } int delta = 0; for (int d=0;d<lineCount;d++) - if (lines[lineDoc+d].visible) + if (lines[lineDoc+d].visible && (lineDoc+d != 0)) delta--; for (int i = lineDoc; i < linesInDoc-lineCount; i++) { - lines[i].visible = lines[i + lineCount].visible; + if (i != 0) // Line zero is always visible + lines[i].visible = lines[i + lineCount].visible; lines[i].expanded = lines[i + lineCount].expanded; } linesInDoc -= lineCount; @@ -153,6 +154,10 @@ bool ContractionState::GetVisible(int lineDoc) const { } bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool visible) { + if (lineDocStart == 0) + lineDocStart++; + if (lineDocStart > lineDocEnd) + return false; if (size == 0) { Grow(linesInDoc + growSize); } diff --git a/src/Document.cxx b/src/Document.cxx index 709deaf80..6614a7fc9 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -342,15 +342,22 @@ void Document::DeleteChars(int pos, int len) { if (enteredCount == 0) { enteredCount++; if (!cb.IsReadOnly()) { + NotifyModified( + DocModification( + SC_MOD_BEFOREDELETE | SC_PERFORMED_USER, + pos, len, + 0, 0)); int prevLinesTotal = LinesTotal(); bool startSavePoint = cb.IsSavePoint(); const char *text = cb.DeleteChars(pos*2, len * 2); if (startSavePoint && cb.IsCollectingUndo()) NotifySavePoint(!startSavePoint); ModifiedAt(pos); - int modFlags = SC_MOD_DELETETEXT | SC_PERFORMED_USER; - DocModification mh(modFlags, pos, len, LinesTotal() - prevLinesTotal, text); - NotifyModified(mh); + NotifyModified( + DocModification( + SC_MOD_DELETETEXT | SC_PERFORMED_USER, + pos, len, + LinesTotal() - prevLinesTotal, text)); } enteredCount--; } @@ -365,16 +372,22 @@ void Document::InsertStyledString(int position, char *s, int insertLength) { if (enteredCount == 0) { enteredCount++; if (!cb.IsReadOnly()) { + NotifyModified( + DocModification( + SC_MOD_BEFOREINSERT | SC_PERFORMED_USER, + position / 2, insertLength / 2, + 0, 0)); int prevLinesTotal = LinesTotal(); bool startSavePoint = cb.IsSavePoint(); const char *text = cb.InsertString(position, s, insertLength); if (startSavePoint && cb.IsCollectingUndo()) NotifySavePoint(!startSavePoint); ModifiedAt(position / 2); - - int modFlags = SC_MOD_INSERTTEXT | SC_PERFORMED_USER; - DocModification mh(modFlags, position / 2, insertLength / 2, LinesTotal() - prevLinesTotal, text); - NotifyModified(mh); + NotifyModified( + DocModification( + SC_MOD_INSERTTEXT | SC_PERFORMED_USER, + position / 2, insertLength / 2, + LinesTotal() - prevLinesTotal, text)); } enteredCount--; } @@ -389,7 +402,15 @@ int Document::Undo() { //Platform::DebugPrintf("Steps=%d\n", steps); for (int step=0; step<steps; step++) { int prevLinesTotal = LinesTotal(); - const Action &action = cb.UndoStep(); + const Action &action = cb.GetUndoStep(); + if (action.at == removeAction) { + NotifyModified(DocModification( + SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action)); + } else { + NotifyModified(DocModification( + SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); + } + cb.PerformUndoStep(); int cellPosition = action.position / 2; ModifiedAt(cellPosition); newPos = cellPosition; @@ -424,10 +445,17 @@ int Document::Redo() { int steps = cb.StartRedo(); for (int step=0; step<steps; step++) { int prevLinesTotal = LinesTotal(); - const Action &action = cb.RedoStep(); - int cellPosition = action.position / 2; - ModifiedAt(cellPosition); - newPos = cellPosition; + const Action &action = cb.GetRedoStep(); + if (action.at == insertAction) { + NotifyModified(DocModification( + SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action)); + } else { + NotifyModified(DocModification( + SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action)); + } + cb.PerformRedoStep(); + ModifiedAt(action.position / 2); + newPos = action.position / 2; int modFlags = SC_PERFORMED_REDO; if (action.at == insertAction) { @@ -438,7 +466,8 @@ int Document::Redo() { } if (step == steps-1) modFlags |= SC_LASTSTEPINUNDOREDO; - NotifyModified(DocModification(modFlags, cellPosition, action.lenData, + NotifyModified( + DocModification(modFlags, action.position / 2, action.lenData, LinesTotal() - prevLinesTotal, action.data)); } diff --git a/src/Document.h b/src/Document.h index 15f8f1121..92e4ff14f 100644 --- a/src/Document.h +++ b/src/Document.h @@ -220,6 +220,16 @@ public: line(0), foldLevelNow(0), foldLevelPrev(0) {} + + DocModification(int modificationType_, const Action &act, int linesAdded_=0) : + modificationType(modificationType_), + position(act.position / 2), + length(act.lenData), + linesAdded(linesAdded_), + text(act.data), + line(0), + foldLevelNow(0), + foldLevelPrev(0) {} }; // A class that wants to receive notifications from a Document must be derived from DocWatcher diff --git a/src/Editor.cxx b/src/Editor.cxx index 440cdeff1..e8e0f755c 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -1599,6 +1599,11 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { } } } + if (mh.modificationType & SC_MOD_BEFOREINSERT) { + NotifyNeedShown(mh.position, 0); + } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { + NotifyNeedShown(mh.position, mh.length); + } if (mh.linesAdded != 0) { // Update contraction state for inserted and removed lines @@ -1606,7 +1611,6 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) { int lineOfPos = pdoc->LineFromPosition(mh.position); if (mh.linesAdded > 0) { cs.InsertLines(lineOfPos, mh.linesAdded); - NotifyNeedShown(mh.position, mh.length); } else { cs.DeleteLines(lineOfPos, -mh.linesAdded); } |