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
This commit is contained in:
Axel Dörfler
2004-02-26 15:18:02 +00:00
parent 35789209bd
commit c65f61d4ad
2 changed files with 77 additions and 38 deletions
+70 -36
View File
@@ -15,6 +15,18 @@
#include <unistd.h>
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;
}
+7 -2
View File
@@ -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<BMessenger> fObservers;