From c65f61d4ad188611beaa221851599820bbdc71e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 26 Feb 2004 15:18:02 +0000 Subject: [PATCH] Added a StateWatcher class that will automatically send notices for all changed states during the lifetime of the object upon destruction. Added some comments. Uncommented the IsModified() method (does not yet work correctly, though). git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6760 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/apps/diskprobe/DataEditor.cpp | 106 ++++++++++++++++++++---------- src/apps/diskprobe/DataEditor.h | 9 ++- 2 files changed, 77 insertions(+), 38 deletions(-) diff --git a/src/apps/diskprobe/DataEditor.cpp b/src/apps/diskprobe/DataEditor.cpp index 477e6599b0..5c6faba023 100644 --- a/src/apps/diskprobe/DataEditor.cpp +++ b/src/apps/diskprobe/DataEditor.cpp @@ -15,6 +15,18 @@ #include +class StateWatcher { + public: + StateWatcher(DataEditor &editor); + ~StateWatcher(); + + private: + DataEditor &fEditor; + bool fCouldUndo; + bool fCouldRedo; + bool fWasModified; +}; + class DataChange { public: virtual ~DataChange(); @@ -44,6 +56,36 @@ class ReplaceChange : public DataChange { }; +//--------------------- + + +StateWatcher::StateWatcher(DataEditor &editor) + : + fEditor(editor) +{ + fCouldUndo = editor.CanUndo(); + fCouldRedo = editor.CanRedo(); + fWasModified = editor.IsModified(); +} + + +StateWatcher::~StateWatcher() +{ + BMessage update; + if (fCouldRedo != fEditor.CanRedo()) + update.AddBool("can_redo", fEditor.CanRedo()); + if (fCouldUndo != fEditor.CanUndo()) + update.AddBool("can_undo", fEditor.CanUndo()); + if (fWasModified != fEditor.IsModified()) + update.AddBool("modified", fEditor.IsModified()); + + fEditor.SendNotices(kMsgDataEditorStateChange, &update); +} + + +// #pragma mark - + + DataChange::~DataChange() { } @@ -272,34 +314,30 @@ DataEditor::InitCheck() } -void +void DataEditor::AddChange(DataChange *change) { if (change == NULL) return; - bool removed = RemoveRedos(); - bool changed = !CanUndo(); + StateWatcher watcher(*this); + // update state observers + + RemoveRedos(); fChanges.AddItem(change); fLastChange = change; fLastChange->Apply(fRealViewOffset, fView, fRealViewSize); + // ToDo: try to join changes // update observers SendNotices(fLastChange); - - BMessage update; - if (removed) - update.AddBool("can_redo", false); - if (changed) - update.AddBool("can_undo", true); - SendNotices(kMsgDataEditorStateChange, &update); } -status_t +status_t DataEditor::Replace(off_t offset, const uint8 *data, size_t length) { BAutolock locker(this); @@ -322,29 +360,31 @@ DataEditor::Replace(off_t offset, const uint8 *data, size_t length) } -status_t +status_t DataEditor::Remove(off_t offset, off_t length) { BAutolock locker(this); // not yet implemented + // ToDo: this needs some changes to the whole change mechanism return B_ERROR; } -status_t +status_t DataEditor::Insert(off_t offset, const uint8 *text, size_t length) { BAutolock locker(this); // not yet implemented + // ToDo: this needs some changes to the whole change mechanism return B_ERROR; } -void +void DataEditor::ApplyChanges() { if (fLastChange == NULL) @@ -359,28 +399,33 @@ DataEditor::ApplyChanges() } +status_t +DataEditor::Save() +{ + // collect ranges of data we need to write + + // read in data and apply changes, write it back to disk +} + + /** 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. */ -bool +void DataEditor::RemoveRedos() { if (fLastChange == NULL) - return false; + return; 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; } @@ -392,7 +437,9 @@ DataEditor::Undo() if (!CanUndo()) return B_ERROR; - bool couldRedo = CanRedo(); + StateWatcher watcher(*this); + // update state observers + DataChange *undoChange = fLastChange; int32 index = fChanges.IndexOf(undoChange); @@ -406,13 +453,6 @@ DataEditor::Undo() // 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; } @@ -425,7 +465,8 @@ DataEditor::Redo() if (!CanRedo()) return B_ERROR; - bool couldUndo = CanUndo(); + StateWatcher watcher(*this); + // update state observers int32 index = fChanges.IndexOf(fLastChange); fLastChange = fChanges.ItemAt(index + 1); @@ -435,13 +476,6 @@ DataEditor::Redo() // 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; } diff --git a/src/apps/diskprobe/DataEditor.h b/src/apps/diskprobe/DataEditor.h index bbf67d9e89..1b5e78fda0 100644 --- a/src/apps/diskprobe/DataEditor.h +++ b/src/apps/diskprobe/DataEditor.h @@ -13,6 +13,7 @@ class DataChange; +class StateWatcher; class DataEditor : public BLocker { public: @@ -26,10 +27,12 @@ class DataEditor : public BLocker { status_t SetTo(entry_ref &ref, const char *attribute = NULL); status_t SetTo(BEntry &entry, const char *attribute = NULL); + status_t Save(); + bool IsReadOnly() const { return fIsReadOnly; } bool IsDevice() const { return fIsDevice; } bool IsAttribute() const { return fAttribute != NULL; } - //bool IsModified() const { return fIsModified; } + bool IsModified() const { return fLastChange != fFirstChange; } const char *Attribute() const { return fAttribute; } type_code Type() const { return fType; } @@ -73,12 +76,14 @@ class DataEditor : public BLocker { const entry_ref &Ref() const { return fRef; } private: + friend class StateWatcher; + void SendNotices(uint32 what, BMessage *message = NULL); void SendNotices(DataChange *change); status_t Update(); void AddChange(DataChange *change); void ApplyChanges(); - bool RemoveRedos(); + void RemoveRedos(); BObjectList fObservers;