From 5af91ef5cb7c468bc0670caec533cfc8eef7e77f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 16 Jan 2004 04:52:44 +0000 Subject: [PATCH] Implemented DataEditor::Redo(), and RemoveRedos(); the latter will now be called by AddChange(). Fixed ApplyChanges() to only apply changes up to (and incl.) the last change; it won't apply all changes anymore. DataEditor::Undo() and Redo() now lock themselves. Added some more simple tests to DiskProbe. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6102 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/diskprobe/DataEditor.cpp | 37 +++++++++++++++++++++++++++++-- src/apps/diskprobe/DiskProbe.cpp | 23 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/apps/diskprobe/DataEditor.cpp b/src/apps/diskprobe/DataEditor.cpp index 3861be2f34..9731f386c6 100644 --- a/src/apps/diskprobe/DataEditor.cpp +++ b/src/apps/diskprobe/DataEditor.cpp @@ -248,6 +248,8 @@ DataEditor::AddChange(DataChange *change) if (change == NULL) return; + RemoveRedos(); + fChanges.AddItem(change); fLastChange = change; } @@ -299,7 +301,10 @@ DataEditor::Insert(off_t offset, const uint8 *text, size_t length) void DataEditor::ApplyChanges() { - int32 count = fChanges.CountItems(); + if (fLastChange == NULL) + return; + + int32 count = fChanges.IndexOf(fLastChange) + 1; for (int32 i = 0; i < count; i++) { DataChange *change = fChanges.ItemAt(i); @@ -308,15 +313,32 @@ DataEditor::ApplyChanges() } +/** This method will be called by DataEditor::AddChange() + * immediately before a change is applied. + * It removes all pending redo nodes from the list that would + * come after the current change. + */ + void DataEditor::RemoveRedos() { + if (fLastChange == NULL) + return; + + int32 start = fChanges.IndexOf(fLastChange) + 1; + + for (int32 i = fChanges.CountItems(); i-- > start; ) { + DataChange *change = fChanges.RemoveItemAt(i); + delete change; + } } status_t DataEditor::Undo() { + BAutolock locker(fLock); + if (!CanUndo()) return B_ERROR; @@ -335,6 +357,17 @@ DataEditor::Undo() status_t DataEditor::Redo() { + BAutolock locker(fLock); + + if (!CanRedo()) + return B_ERROR; + + int32 index = fChanges.IndexOf(fLastChange); + fLastChange = fChanges.ItemAt(index + 1); + + fLastChange->Apply(fRealViewOffset, fView, fRealViewSize); + + return B_OK; } @@ -348,7 +381,7 @@ DataEditor::CanUndo() const bool DataEditor::CanRedo() const { - return fLastChange != NULL && fChanges.IndexOf(fLastChange) < fChanges.CountItems() - 1; + return fChanges.IndexOf(fLastChange) < fChanges.CountItems() - 1; } diff --git a/src/apps/diskprobe/DiskProbe.cpp b/src/apps/diskprobe/DiskProbe.cpp index 5e6afbf3e9..d0be583886 100644 --- a/src/apps/diskprobe/DiskProbe.cpp +++ b/src/apps/diskprobe/DiskProbe.cpp @@ -131,6 +131,29 @@ DiskProbe::DiskProbe() if (printBlock(editor, "undo (location 0):") < B_OK) return; + status = editor.Redo(); + if (status < B_OK) + fprintf(stderr, "Could not redo: %s\n", strerror(status)); + if (printBlock(editor, "redo (location 0):") < B_OK) + return; + + status = editor.Redo(); + editor.SetViewOffset(700); + if (status < B_OK) + fprintf(stderr, "Could not redo: %s\n", strerror(status)); + if (printBlock(editor, "redo (location 700):") < B_OK) + return; + + status = editor.Redo(); + if (status == B_OK) + fprintf(stderr, "Could apply redo (non-expected behaviour)!\n"); + + status = editor.Undo(); + if (status < B_OK) + fprintf(stderr, "Could not undo: %s\n", strerror(status)); + if (printBlock(editor, "undo (location 700):") < B_OK) + return; + PostMessage(B_QUIT_REQUESTED); }