From 66fcb84e31c9c6f645bafa46ac145fa95f44612a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 24 Feb 2004 16:54:28 +0000 Subject: [PATCH] Now maintains the undo/redo state watcher, and also the data update containing the range of affected bytes. Added missing initialization of fLastChange and fFirstChange. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6733 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/diskprobe/DataEditor.cpp | 78 +++++++++++++++++++++++++++++-- src/apps/diskprobe/DataEditor.h | 3 +- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/apps/diskprobe/DataEditor.cpp b/src/apps/diskprobe/DataEditor.cpp index 1272e0c602..3a589083fe 100644 --- a/src/apps/diskprobe/DataEditor.cpp +++ b/src/apps/diskprobe/DataEditor.cpp @@ -21,6 +21,7 @@ class DataChange { virtual void Apply(off_t offset, uint8 *buffer, size_t size) = 0; virtual void Revert(off_t offset, uint8 *buffer, size_t size) = 0; + virtual void GetRange(off_t fileSize, off_t &_offset, off_t &_size) = 0; }; class ReplaceChange : public DataChange { @@ -30,6 +31,7 @@ class ReplaceChange : public DataChange { virtual void Apply(off_t offset, uint8 *buffer, size_t size); virtual void Revert(off_t offset, uint8 *buffer, size_t size); + virtual void GetRange(off_t fileSize, off_t &_offset, off_t &_size); private: void Normalize(off_t bufferOffset, size_t bufferSize, @@ -133,6 +135,14 @@ ReplaceChange::Revert(off_t bufferOffset, uint8 *buffer, size_t bufferSize) } +void +ReplaceChange::GetRange(off_t /*fileSize*/, off_t &_offset, off_t &_size) +{ + _offset = fOffset; + _size = fSize; +} + + // #pragma mark - @@ -242,6 +252,7 @@ DataEditor::SetTo(BEntry &entry, const char *attribute) } } + fLastChange = fFirstChange = NULL; fView = NULL; fRealViewOffset = 0; fViewOffset = 0; @@ -283,12 +294,24 @@ DataEditor::AddChange(DataChange *change) if (change == NULL) return; - RemoveRedos(); + bool removed = RemoveRedos(); + bool changed = !CanUndo(); fChanges.AddItem(change); fLastChange = change; fLastChange->Apply(fRealViewOffset, fView, fRealViewSize); + + // update observers + + SendNotices(fLastChange); + + BMessage update; + if (removed) + update.AddBool("can_redo", false); + if (changed) + update.AddBool("can_undo", true); + SendNotices(kMsgDataEditorStateChange, &update); } @@ -356,18 +379,22 @@ DataEditor::ApplyChanges() * come after the current change. */ -void +bool DataEditor::RemoveRedos() { if (fLastChange == NULL) - return; + return false; int32 start = fChanges.IndexOf(fLastChange) + 1; + bool removed = false; for (int32 i = fChanges.CountItems(); i-- > start; ) { DataChange *change = fChanges.RemoveItemAt(i); delete change; + removed = true; } + + return removed; } @@ -379,14 +406,27 @@ DataEditor::Undo() if (!CanUndo()) return B_ERROR; - int32 index = fChanges.IndexOf(fLastChange); - fLastChange->Revert(fRealViewOffset, fView, fRealViewSize); + bool couldRedo = CanRedo(); + DataChange *undoChange = fLastChange; + + int32 index = fChanges.IndexOf(undoChange); + undoChange->Revert(fRealViewOffset, fView, fRealViewSize); if (index > 0) fLastChange = fChanges.ItemAt(index - 1); else fLastChange = NULL; + // update observers + SendNotices(undoChange); + + BMessage update; + if (!couldRedo) + update.AddBool("can_redo", true); + if (!CanUndo()) + update.AddBool("can_undo", false); + SendNotices(kMsgDataEditorStateChange, &update); + return B_OK; } @@ -399,11 +439,23 @@ DataEditor::Redo() if (!CanRedo()) return B_ERROR; + bool couldUndo = CanUndo(); + int32 index = fChanges.IndexOf(fLastChange); fLastChange = fChanges.ItemAt(index + 1); fLastChange->Apply(fRealViewOffset, fView, fRealViewSize); + // update observers + SendNotices(fLastChange); + + BMessage update; + if (!CanRedo()) + update.AddBool("can_redo", false); + if (!couldUndo) + update.AddBool("can_undo", true); + SendNotices(kMsgDataEditorStateChange, &update); + return B_OK; } @@ -458,6 +510,8 @@ DataEditor::SetViewSize(size_t size) fViewSize = size; return B_OK; } + if (realSize == 0) + return B_BAD_VALUE; uint8 *view = (uint8 *)realloc(fView, realSize); if (view == NULL) @@ -537,6 +591,20 @@ DataEditor::GetViewBuffer(const uint8 **_buffer) } +void +DataEditor::SendNotices(DataChange *change) +{ + off_t offset, size; + change->GetRange(FileSize(), offset, size); + + // update observer + BMessage update; + update.AddInt64("offset", offset); + update.AddInt32("size", size); + SendNotices(kMsgDataEditorUpdate, &update); +} + + void DataEditor::SendNotices(uint32 what, BMessage *message) { diff --git a/src/apps/diskprobe/DataEditor.h b/src/apps/diskprobe/DataEditor.h index 0b8a827363..08f45b9594 100644 --- a/src/apps/diskprobe/DataEditor.h +++ b/src/apps/diskprobe/DataEditor.h @@ -75,10 +75,11 @@ class DataEditor : public BLocker { private: void SendNotices(uint32 what, BMessage *message = NULL); + void SendNotices(DataChange *change); status_t Update(); void AddChange(DataChange *change); void ApplyChanges(); - void RemoveRedos(); + bool RemoveRedos(); BObjectList fObservers;