RemoteDrawingEngine: Reduce RP_READ_BITMAP result timeout.
[haiku.git] / src / apps / mail / KUndoBuffer.cpp
blob8b4533c1ae5d4bf8d5138d44956a7d9b8588a7a4
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <memory.h>
4 #include "KUndoBuffer.h"
7 KUndoItem::KUndoItem(const char* redo_text, int32 length, int32 offset,
8 undo_type history, int32 cursor_pos)
10 Offset = offset;
11 Length = length;
12 History = history;
13 CursorPos = cursor_pos;
15 if (redo_text != NULL) {
16 RedoText = (char*)malloc(length);
17 memcpy(RedoText, redo_text, length);
18 if (RedoText != NULL)
19 fStatus = B_OK;
20 else
21 fStatus = B_ERROR;
26 KUndoItem::~KUndoItem()
28 free(RedoText);
32 status_t
33 KUndoItem::InitCheck()
35 return fStatus;
39 void
40 KUndoItem::Merge(const char* text, int32 length)
42 RedoText = (char*)realloc(RedoText, Length + length);
43 memcpy(&RedoText[Length], text, length);
44 Length += length;
48 KUndoBuffer::KUndoBuffer():BList(1024)
50 fIndex = 0;
51 Off();
52 fNewItem = true;
56 KUndoBuffer::~KUndoBuffer()
58 MakeEmpty();
62 bool
63 KUndoBuffer::AddItem(KUndoItem* item, int32 index)
65 for (int32 i = CountItems() - 1; i >= index; i--)
66 RemoveItem(i);
68 return AddItem(item);
72 bool
73 KUndoBuffer::AddItem(KUndoItem* item)
75 return BList::AddItem(item);
79 void
80 KUndoBuffer::MakeEmpty(void)
82 for (int32 i = CountItems() - 1; i >= 0; i--)
83 RemoveItem(i);
87 KUndoItem*
88 KUndoBuffer::RemoveItem(int32 index)
90 if (fIndex >= CountItems())
91 fIndex--;
92 delete this->ItemAt(index);
93 return (KUndoItem*)BList::RemoveItem(index);
97 KUndoItem*
98 KUndoBuffer::ItemAt(int32 index) const
100 return (KUndoItem*)BList::ItemAt(index);
104 void
105 KUndoBuffer::On()
107 fNoTouch = false;
111 void
112 KUndoBuffer::Off()
114 fNoTouch = true;
118 status_t
119 KUndoBuffer::NewUndo(const char* text, int32 length, int32 offset,
120 undo_type history, int32 cursor_pos)
122 KUndoItem* NewUndoItem = new KUndoItem(text, length, offset, history,
123 cursor_pos);
125 status_t status = NewUndoItem->InitCheck();
126 if (status != B_OK) {
127 delete NewUndoItem;
128 return status;
130 AddItem(NewUndoItem, fIndex);
131 fIndex++;
132 return status;
136 status_t
137 KUndoBuffer::AddUndo(const char* text, int32 length, int32 offset,
138 undo_type history, int32 cursor_pos)
140 if (fNoTouch)
141 return B_OK;
143 status_t status = B_OK;
145 if (fNewItem || fIndex < CountItems() || CountItems() == 0) {
146 status = NewUndo(text, length, offset, history, cursor_pos);
147 fNewItem = false;
148 } else {
149 KUndoItem* CurrentUndoItem;
150 CurrentUndoItem = ItemAt(fIndex - 1);
151 if (CurrentUndoItem != NULL) {
152 int32 c_length = CurrentUndoItem->Length;
153 int32 c_offset = CurrentUndoItem->Offset;
154 undo_type c_history = CurrentUndoItem->History;
155 if (c_history == history) {
156 switch(c_history) {
157 case K_INSERTED:
158 case K_REPLACED:
159 if ((c_offset + c_length) == offset)
160 CurrentUndoItem->Merge(text, length);
161 else {
162 status = NewUndo(text, length, offset, history,
163 cursor_pos);
165 break;
166 case K_DELETED:
167 status = NewUndo(text, length, offset, history,
168 cursor_pos);
169 break;
171 } else
172 status = NewUndo(text, length, offset, history, cursor_pos);
176 return status;
180 status_t
181 KUndoBuffer::MakeNewUndoItem()
183 if (fIndex >= CountItems()) {
184 fNewItem = true;
185 return B_OK;
187 return B_ERROR;
191 status_t
192 KUndoBuffer::Undo(char** text, int32* length, int32* offset,
193 undo_type* history, int32* cursor_pos)
195 KUndoItem* undoItem;
196 status_t status = B_ERROR;
198 if (fIndex > 0) {
199 undoItem = ItemAt(fIndex - 1);
200 if (undoItem != NULL) {
201 *text = undoItem->RedoText;
202 *length = undoItem->Length;
203 *offset = undoItem->Offset;
204 *history = undoItem->History;
205 *cursor_pos = undoItem->CursorPos + undoItem->Length;
206 status = B_OK;
208 fIndex--;
210 return status;
214 status_t
215 KUndoBuffer::Redo(char** text, int32* length, int32* offset,
216 undo_type* history, int32* cursor_pos, bool* replaced)
218 KUndoItem* undoItem;
219 status_t status = B_ERROR;
221 if (fIndex < CountItems()) {
222 undoItem = ItemAt(fIndex);
223 if (undoItem != NULL) {
224 *text = undoItem->RedoText;
225 *length = undoItem->Length;
226 *offset = undoItem->Offset;
227 *history = undoItem->History;
228 *cursor_pos = undoItem->CursorPos;
229 if (fIndex + 1 < CountItems())
230 *replaced = ItemAt(fIndex + 1)->History == K_REPLACED;
231 else
232 *replaced = false;
233 status = B_OK;
235 fIndex++;
237 return status;
241 void
242 KUndoBuffer::PrintToStream()
244 for (int32 i = 0; i < CountItems(); i++) {
245 KUndoItem* item = ItemAt(i);
246 printf("%3.3d ", (int)i);
247 switch (item->History) {
248 case K_INSERTED:
249 printf("INSERTED ");
250 break;
251 case K_DELETED:
252 printf("DELETED ");
253 break;
254 case K_REPLACED:
255 printf("REPLACED ");
256 break;
258 printf("Offset = %d ", (int)item->Offset);
259 printf("Length = %d ", (int)item->Length);
260 printf("CursorPos = %d ", (int)item->CursorPos);
261 printf("RedoText = '");
262 for (int32 j = 0; j < item->Length; j++) {
263 uchar c = (uchar)item->RedoText[j];
264 if (c >= 0x20)
265 printf("%c", c);
266 else
267 printf("?");
269 printf("'\n");