aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CellBuffer.cxx56
-rw-r--r--src/CellBuffer.h12
-rw-r--r--src/ContractionState.cxx9
-rw-r--r--src/Document.cxx55
-rw-r--r--src/Document.h10
-rw-r--r--src/Editor.cxx6
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);
}