HaikuDepot: Base-classes for generic undo/redo support.
I plan to use these in the text view and editor framework.
This commit is contained in:
parent
ee3b36afff
commit
651e8326ca
@ -4,7 +4,7 @@ UsePrivateHeaders interface shared package ;
|
|||||||
|
|
||||||
# source directories
|
# source directories
|
||||||
local sourceDirs =
|
local sourceDirs =
|
||||||
model textview ui ui_generic
|
edits_generic model textview ui ui_generic
|
||||||
;
|
;
|
||||||
|
|
||||||
local sourceDir ;
|
local sourceDir ;
|
||||||
@ -15,6 +15,13 @@ for sourceDir in $(sourceDirs) {
|
|||||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src servers package ] ;
|
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src servers package ] ;
|
||||||
|
|
||||||
local textDocumentSources =
|
local textDocumentSources =
|
||||||
|
# edits_generic
|
||||||
|
CompoundEdit.cpp
|
||||||
|
EditContext.cpp
|
||||||
|
EditManager.cpp
|
||||||
|
EditStack.cpp
|
||||||
|
UndoableEdit.cpp
|
||||||
|
# textview
|
||||||
Bullet.cpp
|
Bullet.cpp
|
||||||
BulletData.cpp
|
BulletData.cpp
|
||||||
CharacterStyle.cpp
|
CharacterStyle.cpp
|
||||||
|
117
src/apps/haikudepot/edits_generic/CompoundEdit.cpp
Normal file
117
src/apps/haikudepot/edits_generic/CompoundEdit.cpp
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2112, Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CompoundEdit.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
CompoundEdit::CompoundEdit(const char* name)
|
||||||
|
: UndoableEdit()
|
||||||
|
, fEdits()
|
||||||
|
, fName(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CompoundEdit::~CompoundEdit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CompoundEdit::InitCheck()
|
||||||
|
{
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CompoundEdit::Perform(EditContext& context)
|
||||||
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
int32 count = fEdits.CountItems();
|
||||||
|
int32 i = 0;
|
||||||
|
for (; i < count; i++) {
|
||||||
|
status = fEdits.ItemAtFast(i)->Perform(context);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
// roll back
|
||||||
|
i--;
|
||||||
|
for (; i >= 0; i--) {
|
||||||
|
fEdits.ItemAtFast(i)->Undo(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CompoundEdit::Undo(EditContext& context)
|
||||||
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
int32 count = fEdits.CountItems();
|
||||||
|
int32 i = count - 1;
|
||||||
|
for (; i >= 0; i--) {
|
||||||
|
status = fEdits.ItemAtFast(i)->Undo(context);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
// roll back
|
||||||
|
i++;
|
||||||
|
for (; i < count; i++) {
|
||||||
|
fEdits.ItemAtFast(i)->Redo(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
CompoundEdit::Redo(EditContext& context)
|
||||||
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
int32 count = fEdits.CountItems();
|
||||||
|
int32 i = 0;
|
||||||
|
for (; i < count; i++) {
|
||||||
|
status = fEdits.ItemAtFast(i)->Redo(context);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
// roll back
|
||||||
|
i--;
|
||||||
|
for (; i >= 0; i--) {
|
||||||
|
fEdits.ItemAtFast(i)->Undo(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
CompoundEdit::GetName(BString& name)
|
||||||
|
{
|
||||||
|
name << fName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
CompoundEdit::AppendEdit(const UndoableEditRef& edit)
|
||||||
|
{
|
||||||
|
return fEdits.Add(edit);
|
||||||
|
}
|
36
src/apps/haikudepot/edits_generic/CompoundEdit.h
Normal file
36
src/apps/haikudepot/edits_generic/CompoundEdit.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2112, Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMPOUND_EDIT_H
|
||||||
|
#define COMPOUND_EDIT_H
|
||||||
|
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "List.h"
|
||||||
|
#include "UndoableEdit.h"
|
||||||
|
|
||||||
|
class CompoundEdit : public UndoableEdit {
|
||||||
|
public:
|
||||||
|
CompoundEdit(const char* name);
|
||||||
|
virtual ~CompoundEdit();
|
||||||
|
|
||||||
|
virtual status_t InitCheck();
|
||||||
|
|
||||||
|
virtual status_t Perform(EditContext& context);
|
||||||
|
virtual status_t Undo(EditContext& context);
|
||||||
|
virtual status_t Redo(EditContext& context);
|
||||||
|
|
||||||
|
virtual void GetName(BString& name);
|
||||||
|
|
||||||
|
bool AppendEdit(const UndoableEditRef& edit);
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef List<UndoableEditRef, false, 2> EditList;
|
||||||
|
|
||||||
|
EditList fEdits;
|
||||||
|
BString fName;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COMPOUND_EDIT_H
|
18
src/apps/haikudepot/edits_generic/EditContext.cpp
Normal file
18
src/apps/haikudepot/edits_generic/EditContext.cpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "EditContext.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
EditContext::EditContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EditContext::~EditContext()
|
||||||
|
{
|
||||||
|
}
|
26
src/apps/haikudepot/edits_generic/EditContext.h
Normal file
26
src/apps/haikudepot/edits_generic/EditContext.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EDIT_CONTEXT_H
|
||||||
|
#define EDIT_CONTEXT_H
|
||||||
|
|
||||||
|
#include <Referenceable.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EditContext is passed to UndoableEdits in Perform(), Undo(), and Redo().
|
||||||
|
* It provides a context in which the user performs these operations
|
||||||
|
* and can be used for example to control the selection or visible
|
||||||
|
* portion of the document to focus the user's attention on the
|
||||||
|
* elements affected by the UndoableEdit.
|
||||||
|
*/
|
||||||
|
class EditContext : public BReferenceable {
|
||||||
|
public:
|
||||||
|
EditContext();
|
||||||
|
virtual ~EditContext();
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BReference<EditContext> EditContextRef;
|
||||||
|
|
||||||
|
#endif // EDIT_CONTEXT_H
|
244
src/apps/haikudepot/edits_generic/EditManager.cpp
Normal file
244
src/apps/haikudepot/edits_generic/EditManager.cpp
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2012, Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "EditManager.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
EditManager::Listener::~Listener()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EditManager::EditManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EditManager::~EditManager()
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EditManager::Perform(UndoableEdit* edit, EditContext& context)
|
||||||
|
{
|
||||||
|
if (edit == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
return Perform(UndoableEditRef(edit, true), context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EditManager::Perform(const UndoableEditRef& edit, EditContext& context)
|
||||||
|
{
|
||||||
|
status_t ret = edit.Get() != NULL ? B_OK : B_BAD_VALUE;
|
||||||
|
if (ret == B_OK)
|
||||||
|
ret = edit->InitCheck();
|
||||||
|
|
||||||
|
if (ret == B_OK)
|
||||||
|
ret = edit->Perform(context);
|
||||||
|
|
||||||
|
if (ret == B_OK) {
|
||||||
|
ret = _AddEdit(edit);
|
||||||
|
if (ret != B_OK)
|
||||||
|
edit->Undo(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
_NotifyListeners();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EditManager::Undo(EditContext& context)
|
||||||
|
{
|
||||||
|
status_t status = B_ERROR;
|
||||||
|
if (!fUndoHistory.IsEmpty()) {
|
||||||
|
UndoableEditRef edit(fUndoHistory.Top());
|
||||||
|
fUndoHistory.Pop();
|
||||||
|
status = edit->Undo(context);
|
||||||
|
if (status == B_OK)
|
||||||
|
fRedoHistory.Push(edit);
|
||||||
|
else
|
||||||
|
fUndoHistory.Push(edit);
|
||||||
|
}
|
||||||
|
|
||||||
|
_NotifyListeners();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EditManager::Redo(EditContext& context)
|
||||||
|
{
|
||||||
|
status_t status = B_ERROR;
|
||||||
|
if (!fRedoHistory.IsEmpty()) {
|
||||||
|
UndoableEditRef edit(fRedoHistory.Top());
|
||||||
|
fRedoHistory.Pop();
|
||||||
|
status = edit->Redo(context);
|
||||||
|
if (status == B_OK)
|
||||||
|
fUndoHistory.Push(edit);
|
||||||
|
else
|
||||||
|
fRedoHistory.Push(edit);
|
||||||
|
}
|
||||||
|
|
||||||
|
_NotifyListeners();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
EditManager::GetUndoName(BString& name)
|
||||||
|
{
|
||||||
|
if (!fUndoHistory.IsEmpty()) {
|
||||||
|
name << " ";
|
||||||
|
fUndoHistory.Top()->GetName(name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
EditManager::GetRedoName(BString& name)
|
||||||
|
{
|
||||||
|
if (!fRedoHistory.IsEmpty()) {
|
||||||
|
name << " ";
|
||||||
|
fRedoHistory.Top()->GetName(name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EditManager::Clear()
|
||||||
|
{
|
||||||
|
while (!fUndoHistory.IsEmpty())
|
||||||
|
fUndoHistory.Pop();
|
||||||
|
while (!fRedoHistory.IsEmpty())
|
||||||
|
fRedoHistory.Pop();
|
||||||
|
|
||||||
|
_NotifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EditManager::Save()
|
||||||
|
{
|
||||||
|
if (!fUndoHistory.IsEmpty())
|
||||||
|
fEditAtSave = fUndoHistory.Top();
|
||||||
|
|
||||||
|
_NotifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
EditManager::IsSaved()
|
||||||
|
{
|
||||||
|
bool saved = fUndoHistory.IsEmpty();
|
||||||
|
if (fEditAtSave.Get() != NULL && !saved) {
|
||||||
|
if (fEditAtSave == fUndoHistory.Top())
|
||||||
|
saved = true;
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
EditManager::AddListener(Listener* listener)
|
||||||
|
{
|
||||||
|
return fListeners.Add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EditManager::RemoveListener(Listener* listener)
|
||||||
|
{
|
||||||
|
fListeners.Remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
EditManager::_AddEdit(const UndoableEditRef& edit)
|
||||||
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
bool add = true;
|
||||||
|
if (!fUndoHistory.IsEmpty()) {
|
||||||
|
// Try to collapse edits to a single edit
|
||||||
|
// or remove this and the previous edit if
|
||||||
|
// they reverse each other
|
||||||
|
const UndoableEditRef& top = fUndoHistory.Top();
|
||||||
|
if (edit->UndoesPrevious(top.Get())) {
|
||||||
|
add = false;
|
||||||
|
fUndoHistory.Pop();
|
||||||
|
} else if (top->CombineWithNext(edit.Get())) {
|
||||||
|
add = false;
|
||||||
|
// After collapsing, the edit might
|
||||||
|
// have changed it's mind about InitCheck()
|
||||||
|
// (the commands reversed each other)
|
||||||
|
if (top->InitCheck() != B_OK) {
|
||||||
|
fUndoHistory.Pop();
|
||||||
|
}
|
||||||
|
} else if (edit->CombineWithPrevious(top.Get())) {
|
||||||
|
fUndoHistory.Pop();
|
||||||
|
// After collapsing, the edit might
|
||||||
|
// have changed it's mind about InitCheck()
|
||||||
|
// (the commands reversed each other)
|
||||||
|
if (edit->InitCheck() != B_OK) {
|
||||||
|
add = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (add) {
|
||||||
|
if (!fUndoHistory.Push(edit))
|
||||||
|
status = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == B_OK) {
|
||||||
|
// The redo stack needs to be empty
|
||||||
|
// as soon as an edit was added (also in case of collapsing)
|
||||||
|
while (!fRedoHistory.IsEmpty()) {
|
||||||
|
fRedoHistory.Pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
EditManager::_NotifyListeners()
|
||||||
|
{
|
||||||
|
int32 count = fListeners.CountItems();
|
||||||
|
if (count == 0)
|
||||||
|
return;
|
||||||
|
// Iterate a copy of the list, so we don't crash if listeners
|
||||||
|
// detach themselves while being notified.
|
||||||
|
ListenerList listenersCopy(fListeners);
|
||||||
|
if (listenersCopy.CountItems() != count)
|
||||||
|
return;
|
||||||
|
for (int32 i = 0; i < count; i++)
|
||||||
|
listenersCopy.ItemAtFast(i)->EditManagerChanged(this);
|
||||||
|
}
|
||||||
|
|
60
src/apps/haikudepot/edits_generic/EditManager.h
Normal file
60
src/apps/haikudepot/edits_generic/EditManager.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2012, Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef EDIT_MANAGER_H
|
||||||
|
#define EDIT_MANAGER_H
|
||||||
|
|
||||||
|
#include "EditStack.h"
|
||||||
|
#include "UndoableEdit.h"
|
||||||
|
|
||||||
|
class BString;
|
||||||
|
class EditContext;
|
||||||
|
|
||||||
|
|
||||||
|
class EditManager {
|
||||||
|
public:
|
||||||
|
class Listener {
|
||||||
|
public:
|
||||||
|
virtual ~Listener();
|
||||||
|
virtual void EditManagerChanged(
|
||||||
|
const EditManager* manager) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
EditManager();
|
||||||
|
virtual ~EditManager();
|
||||||
|
|
||||||
|
status_t Perform(UndoableEdit* edit,
|
||||||
|
EditContext& context);
|
||||||
|
status_t Perform(const UndoableEditRef& edit,
|
||||||
|
EditContext& context);
|
||||||
|
|
||||||
|
status_t Undo(EditContext& context);
|
||||||
|
status_t Redo(EditContext& context);
|
||||||
|
|
||||||
|
bool GetUndoName(BString& name);
|
||||||
|
bool GetRedoName(BString& name);
|
||||||
|
|
||||||
|
void Clear();
|
||||||
|
void Save();
|
||||||
|
bool IsSaved();
|
||||||
|
|
||||||
|
bool AddListener(Listener* listener);
|
||||||
|
void RemoveListener(Listener* listener);
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t _AddEdit(const UndoableEditRef& edit);
|
||||||
|
|
||||||
|
void _NotifyListeners();
|
||||||
|
|
||||||
|
private:
|
||||||
|
EditStack fUndoHistory;
|
||||||
|
EditStack fRedoHistory;
|
||||||
|
UndoableEditRef fEditAtSave;
|
||||||
|
|
||||||
|
typedef List<Listener*, true, 4> ListenerList;
|
||||||
|
ListenerList fListeners;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDIT_MANAGER_H
|
49
src/apps/haikudepot/edits_generic/EditStack.cpp
Normal file
49
src/apps/haikudepot/edits_generic/EditStack.cpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "EditStack.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
EditStack::EditStack()
|
||||||
|
: fEdits()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EditStack::~EditStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
EditStack::Push(const UndoableEditRef& edit)
|
||||||
|
{
|
||||||
|
return fEdits.Add(edit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UndoableEditRef
|
||||||
|
EditStack::Pop()
|
||||||
|
{
|
||||||
|
UndoableEditRef edit(Top());
|
||||||
|
fEdits.Remove();
|
||||||
|
return edit;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const UndoableEditRef&
|
||||||
|
EditStack::Top() const
|
||||||
|
{
|
||||||
|
return fEdits.LastItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
EditStack::IsEmpty() const
|
||||||
|
{
|
||||||
|
return fEdits.CountItems() == 0;
|
||||||
|
}
|
30
src/apps/haikudepot/edits_generic/EditStack.h
Normal file
30
src/apps/haikudepot/edits_generic/EditStack.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EDIT_STACK_H
|
||||||
|
#define EDIT_STACK_H
|
||||||
|
|
||||||
|
#include "List.h"
|
||||||
|
#include "UndoableEdit.h"
|
||||||
|
|
||||||
|
class EditStack {
|
||||||
|
public:
|
||||||
|
EditStack();
|
||||||
|
virtual ~EditStack();
|
||||||
|
|
||||||
|
bool Push(const UndoableEditRef& edit);
|
||||||
|
UndoableEditRef Pop();
|
||||||
|
|
||||||
|
const UndoableEditRef& Top() const;
|
||||||
|
|
||||||
|
bool IsEmpty() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef List<UndoableEditRef, false> EditList;
|
||||||
|
|
||||||
|
EditList fEdits;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // EDIT_STACK_H
|
86
src/apps/haikudepot/edits_generic/UndoableEdit.cpp
Normal file
86
src/apps/haikudepot/edits_generic/UndoableEdit.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2012, Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "UndoableEdit.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
|
||||||
|
//static int32 sInstanceCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
UndoableEdit::UndoableEdit()
|
||||||
|
:
|
||||||
|
fTimeStamp(system_time())
|
||||||
|
{
|
||||||
|
// sInstanceCount++;
|
||||||
|
// printf("UndoableEdits: %ld\n", sInstanceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UndoableEdit::~UndoableEdit()
|
||||||
|
{
|
||||||
|
// sInstanceCount--;
|
||||||
|
// printf("UndoableEdits: %ld\n", sInstanceCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoableEdit::InitCheck()
|
||||||
|
{
|
||||||
|
return B_NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoableEdit::Perform(EditContext& context)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoableEdit::Undo(EditContext& context)
|
||||||
|
{
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
UndoableEdit::Redo(EditContext& context)
|
||||||
|
{
|
||||||
|
return Perform(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
UndoableEdit::GetName(BString& name)
|
||||||
|
{
|
||||||
|
name << "Name of edit goes here.";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
UndoableEdit::UndoesPrevious(const UndoableEdit* previous)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
UndoableEdit::CombineWithNext(const UndoableEdit* next)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
UndoableEdit::CombineWithPrevious(const UndoableEdit* previous)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
41
src/apps/haikudepot/edits_generic/UndoableEdit.h
Normal file
41
src/apps/haikudepot/edits_generic/UndoableEdit.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006-2012 Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UNDOABLE_EDIT_H
|
||||||
|
#define UNDOABLE_EDIT_H
|
||||||
|
|
||||||
|
#include <Referenceable.h>
|
||||||
|
|
||||||
|
class BString;
|
||||||
|
class EditContext;
|
||||||
|
|
||||||
|
class UndoableEdit : public BReferenceable {
|
||||||
|
public:
|
||||||
|
UndoableEdit();
|
||||||
|
virtual ~UndoableEdit();
|
||||||
|
|
||||||
|
virtual status_t InitCheck();
|
||||||
|
|
||||||
|
virtual status_t Perform(EditContext& context);
|
||||||
|
virtual status_t Undo(EditContext& context);
|
||||||
|
virtual status_t Redo(EditContext& context);
|
||||||
|
|
||||||
|
virtual void GetName(BString& name);
|
||||||
|
|
||||||
|
virtual bool UndoesPrevious(const UndoableEdit* previous);
|
||||||
|
virtual bool CombineWithNext(const UndoableEdit* next);
|
||||||
|
virtual bool CombineWithPrevious(
|
||||||
|
const UndoableEdit* previous);
|
||||||
|
|
||||||
|
inline bigtime_t TimeStamp() const
|
||||||
|
{ return fTimeStamp; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bigtime_t fTimeStamp;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef BReference<UndoableEdit> UndoableEditRef;
|
||||||
|
|
||||||
|
#endif // UNDOABLE_EDIT_H
|
Loading…
Reference in New Issue
Block a user