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
This commit is contained in:
Axel Dörfler 2004-02-24 16:54:28 +00:00
parent 13cdd48215
commit 66fcb84e31
2 changed files with 75 additions and 6 deletions

View File

@ -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)
{

View File

@ -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<BMessenger> fObservers;