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:
@@ -21,6 +21,7 @@ class DataChange {
|
|||||||
|
|
||||||
virtual void Apply(off_t offset, uint8 *buffer, size_t size) = 0;
|
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 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 {
|
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 Apply(off_t offset, uint8 *buffer, size_t size);
|
||||||
virtual void Revert(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:
|
private:
|
||||||
void Normalize(off_t bufferOffset, size_t bufferSize,
|
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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -242,6 +252,7 @@ DataEditor::SetTo(BEntry &entry, const char *attribute)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fLastChange = fFirstChange = NULL;
|
||||||
fView = NULL;
|
fView = NULL;
|
||||||
fRealViewOffset = 0;
|
fRealViewOffset = 0;
|
||||||
fViewOffset = 0;
|
fViewOffset = 0;
|
||||||
@@ -283,12 +294,24 @@ DataEditor::AddChange(DataChange *change)
|
|||||||
if (change == NULL)
|
if (change == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RemoveRedos();
|
bool removed = RemoveRedos();
|
||||||
|
bool changed = !CanUndo();
|
||||||
|
|
||||||
fChanges.AddItem(change);
|
fChanges.AddItem(change);
|
||||||
fLastChange = change;
|
fLastChange = change;
|
||||||
|
|
||||||
fLastChange->Apply(fRealViewOffset, fView, fRealViewSize);
|
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.
|
* come after the current change.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
bool
|
||||||
DataEditor::RemoveRedos()
|
DataEditor::RemoveRedos()
|
||||||
{
|
{
|
||||||
if (fLastChange == NULL)
|
if (fLastChange == NULL)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
int32 start = fChanges.IndexOf(fLastChange) + 1;
|
int32 start = fChanges.IndexOf(fLastChange) + 1;
|
||||||
|
bool removed = false;
|
||||||
|
|
||||||
for (int32 i = fChanges.CountItems(); i-- > start; ) {
|
for (int32 i = fChanges.CountItems(); i-- > start; ) {
|
||||||
DataChange *change = fChanges.RemoveItemAt(i);
|
DataChange *change = fChanges.RemoveItemAt(i);
|
||||||
delete change;
|
delete change;
|
||||||
|
removed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -379,14 +406,27 @@ DataEditor::Undo()
|
|||||||
if (!CanUndo())
|
if (!CanUndo())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
int32 index = fChanges.IndexOf(fLastChange);
|
bool couldRedo = CanRedo();
|
||||||
fLastChange->Revert(fRealViewOffset, fView, fRealViewSize);
|
DataChange *undoChange = fLastChange;
|
||||||
|
|
||||||
|
int32 index = fChanges.IndexOf(undoChange);
|
||||||
|
undoChange->Revert(fRealViewOffset, fView, fRealViewSize);
|
||||||
|
|
||||||
if (index > 0)
|
if (index > 0)
|
||||||
fLastChange = fChanges.ItemAt(index - 1);
|
fLastChange = fChanges.ItemAt(index - 1);
|
||||||
else
|
else
|
||||||
fLastChange = NULL;
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,11 +439,23 @@ DataEditor::Redo()
|
|||||||
if (!CanRedo())
|
if (!CanRedo())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
bool couldUndo = CanUndo();
|
||||||
|
|
||||||
int32 index = fChanges.IndexOf(fLastChange);
|
int32 index = fChanges.IndexOf(fLastChange);
|
||||||
fLastChange = fChanges.ItemAt(index + 1);
|
fLastChange = fChanges.ItemAt(index + 1);
|
||||||
|
|
||||||
fLastChange->Apply(fRealViewOffset, fView, fRealViewSize);
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,6 +510,8 @@ DataEditor::SetViewSize(size_t size)
|
|||||||
fViewSize = size;
|
fViewSize = size;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
if (realSize == 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
uint8 *view = (uint8 *)realloc(fView, realSize);
|
uint8 *view = (uint8 *)realloc(fView, realSize);
|
||||||
if (view == NULL)
|
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
|
void
|
||||||
DataEditor::SendNotices(uint32 what, BMessage *message)
|
DataEditor::SendNotices(uint32 what, BMessage *message)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,10 +75,11 @@ class DataEditor : public BLocker {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void SendNotices(uint32 what, BMessage *message = NULL);
|
void SendNotices(uint32 what, BMessage *message = NULL);
|
||||||
|
void SendNotices(DataChange *change);
|
||||||
status_t Update();
|
status_t Update();
|
||||||
void AddChange(DataChange *change);
|
void AddChange(DataChange *change);
|
||||||
void ApplyChanges();
|
void ApplyChanges();
|
||||||
void RemoveRedos();
|
bool RemoveRedos();
|
||||||
|
|
||||||
BObjectList<BMessenger> fObservers;
|
BObjectList<BMessenger> fObservers;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user