summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2013-10-01 18:29:22 +0100
committerMichael Drake <tlsa@netsurf-browser.org>2013-10-01 18:29:22 +0100
commit0c4f32fb1d04657916d7da9ef94f82bb435a1a5e (patch)
tree068958d9df3fe2bf18195b899361aed79e4c3fb3
parent5809bcefa6bcff43a9d2208725105e4469624d28 (diff)
downloadnetsurf-0c4f32fb1d04657916d7da9ef94f82bb435a1a5e.tar.gz
netsurf-0c4f32fb1d04657916d7da9ef94f82bb435a1a5e.tar.bz2
Make undo and redo share common implementation.
-rw-r--r--desktop/textarea.c100
1 files changed, 28 insertions, 72 deletions
diff --git a/desktop/textarea.c b/desktop/textarea.c
index a1ebe0ddc..b112a6bcb 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -1600,14 +1600,15 @@ static bool textarea_replace_text(struct textarea *ta, size_t b_start,
/**
- * Undo previous change.
+ * Undo or redo previous change.
*
* \param ta Textarea widget
+ * \param forward Iff true, redo, else undo
* \param caret Updated to new caret pos in textarea (ta->show)
* \param r Updated to area where redraw is required
- * \return false if nothing to undo, true otherwise
+ * \return false if nothing to undo/redo, true otherwise
*/
-static bool textarea_undo(struct textarea *ta,
+static bool textarea_undo(struct textarea *ta, bool forward,
unsigned int *caret, struct rect *r)
{
unsigned int detail_n;
@@ -1617,84 +1618,32 @@ static bool textarea_undo(struct textarea *ta,
unsigned int b_text_len;
int byte_delta;
- if (ta->flags & TEXTAREA_PASSWORD)
- /* No undo for password fields */
- return false;
-
- if (ta->undo.next_detail == 0)
- /* Nothing to undo */
+ if (ta->flags & TEXTAREA_PASSWORD || ta->flags & TEXTAREA_READONLY)
+ /* No undo/redo for password or readonly fields */
return false;
- detail_n = ta->undo.next_detail - 1;
- detail = &(ta->undo.details[detail_n]);
-
- b_len = detail->b_end - detail->b_start;
- b_text_len = detail->b_text_end - detail->b_text_start;
+ if (forward) {
+ /* Redo */
+ if (ta->undo.next_detail > ta->undo.last_detail)
+ /* Nothing to redo */
+ return false;
- /* Take copy of any current textarea text that undo will remove */
- if (detail->b_text_end > detail->b_text_start) {
- temp = malloc(b_text_len);
- if (temp == NULL) {
- /* TODO */
+ detail_n = ta->undo.next_detail;
+ } else {
+ /* Undo */
+ if (ta->undo.next_detail == 0)
+ /* Nothing to undo */
return false;
- }
- memcpy(temp, ta->text.data + detail->b_text_start, b_text_len);
+ detail_n = ta->undo.next_detail - 1;
}
- /* Replace textarea text with undo buffer text */
- textarea_replace_text_internal(ta,
- detail->b_text_start, detail->b_text_end,
- ta->undo.text.data + detail->b_start, b_len,
- false, &byte_delta, r);
-
- /* Update undo buffer for redo */
- memcpy(ta->undo.text.data + detail->b_start, temp, b_text_len);
- detail->b_text_end = detail->b_text_start + b_len;
- detail->b_end = detail->b_start + b_text_len;
-
- *caret = detail->b_text_end;
- ta->undo.next_detail--;
-
- free(temp);
-
- return true;
-}
-
-
-/**
- * Redo previous undo.
- *
- * \param ta Textarea widget
- * \param caret Updated to new caret pos in textarea (ta->show)
- * \param r Updated to area where redraw is required
- * \return false if nothing to redo, true otherwise
- */
-static bool textarea_redo(struct textarea *ta,
- unsigned int *caret, struct rect *r)
-{
- unsigned int detail_n;
- struct textarea_undo_detail *detail;
- char *temp = NULL;
- unsigned int b_len;
- unsigned int b_text_len;
- int byte_delta;
-
- if (ta->flags & TEXTAREA_PASSWORD)
- /* No redo for password fields */
- return false;
-
- if (ta->undo.next_detail > ta->undo.last_detail)
- /* Nothing to redo */
- return false;
-
- detail_n = ta->undo.next_detail;
detail = &(ta->undo.details[detail_n]);
b_len = detail->b_end - detail->b_start;
b_text_len = detail->b_text_end - detail->b_text_start;
- /* Take copy of any current textarea text that redo will remove */
+ /* Take copy of any current textarea text that undo/redo will remove */
if (detail->b_text_end > detail->b_text_start) {
temp = malloc(b_text_len);
if (temp == NULL) {
@@ -1717,7 +1666,14 @@ static bool textarea_redo(struct textarea *ta,
detail->b_end = detail->b_start + b_text_len;
*caret = detail->b_text_end;
- ta->undo.next_detail++;
+
+ if (forward) {
+ /* Redo */
+ ta->undo.next_detail++;
+ } else {
+ /* Undo */
+ ta->undo.next_detail--;
+ }
free(temp);
@@ -2792,7 +2748,7 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
caret += byte_delta;
break;
case KEY_UNDO:
- if (!textarea_undo(ta, &caret, &r)) {
+ if (!textarea_undo(ta, false, &caret, &r)) {
/* We consume the UNDO, even if we can't act
* on it. */
return true;
@@ -2803,7 +2759,7 @@ bool textarea_keypress(struct textarea *ta, uint32_t key)
redraw = true;
break;
case KEY_REDO:
- if (!textarea_redo(ta, &caret, &r)) {
+ if (!textarea_undo(ta, true, &caret, &r)) {
/* We consume the REDO, even if we can't act
* on it. */
return true;