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;