[gcalctool] Add back in undo and redo



commit 43fb9bcf1c40b0e90e5a2d82a9b1bae1066688ff
Author: Robert Ancell <robert ancell gmail com>
Date:   Wed Apr 14 23:23:30 2010 +0800

    Add back in undo and redo

 NEWS                |    2 +
 src/math-equation.c |  101 ++++++++++++++++++++++++++++++++++++---------------
 src/math-equation.h |    2 +
 src/math-window.c   |   18 +++++++++
 4 files changed, 94 insertions(+), 29 deletions(-)
---
diff --git a/NEWS b/NEWS
index 7d6c513..4e64e94 100644
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,8 @@ Overview of changes in gcalctool 5.31.1
     * Make inverses of variables work (Bug #614979)
 
     * Show answer in bold (Bug #505168)
+    
+    * Add back in undo and redo
 
 Overview of changes in gcalctool 5.30.0
 
diff --git a/src/math-equation.c b/src/math-equation.c
index a363695..813de90 100644
--- a/src/math-equation.c
+++ b/src/math-equation.c
@@ -86,7 +86,8 @@ struct MathEquationPrivate
     GtkTextMark *ans_start, *ans_end;
 
     MathEquationState state;  /* Equation state */
-    GList *history;           /* History of expression mode states */
+    GList *undo_stack;           /* History of expression mode states */
+    GList *redo_stack;
 
     // FIXME: Replace with GtkClipboard
     GdkAtom clipboard_atom;   /* ??? */ // 
@@ -140,13 +141,23 @@ reformat_display(MathEquation *equation)
 
 
 static void
-display_push(MathEquation *equation)
+math_equation_push_undo_stack(MathEquation *equation)
 {
+    GList *link;
     MathEquationState *state;
     gint ans_start = -1, ans_end = -1;
 
+    /* Can't redo anymore */
+    for (link = equation->priv->redo_stack; link; link = link->next) {
+        state = link->data;
+        g_free(state->expression);
+        g_free(state);
+    }
+    g_list_free(equation->priv->redo_stack);
+    equation->priv->redo_stack = NULL;
+
     state = g_malloc0(sizeof(MathEquationState));
-    equation->priv->history = g_list_prepend(equation->priv->history, state);
+    equation->priv->undo_stack = g_list_prepend(equation->priv->undo_stack, state);  
   
     if (equation->priv->ans_start) 
     {
@@ -190,23 +201,9 @@ clear_ans(MathEquation *equation, gboolean remove_tag)
 
 
 static void
-display_pop(MathEquation *equation)
+apply_state(MathEquation *equation, MathEquationState *state)
 {
-    GList *link;
-    MathEquationState *state;
     GtkTextIter cursor;
-  
-    if (!equation->priv->history) {
-        math_equation_set_status(equation,
-                                 /* Error shown when trying to undo with no undo history */
-                                 _("No undo history"));
-        return;
-    }
-
-    link = equation->priv->history;
-    equation->priv->history = g_list_remove_link(equation->priv->history, link);
-    state = link->data;
-    g_list_free(link);
 
     mp_set_from_mp(&state->ans, &equation->priv->state.ans);
 
@@ -227,8 +224,54 @@ display_pop(MathEquation *equation)
     math_equation_set_number_mode(equation, state->number_mode);
     equation->priv->can_super_minus = state->can_super_minus;
     equation->priv->state.entered_multiply = state->entered_multiply;
-    g_free(state->expression);
-    g_free(state);
+}
+
+
+void
+math_equation_undo(MathEquation *equation)
+{
+    GList *link;
+    MathEquationState *state;
+  
+    if (!equation->priv->undo_stack) {
+        math_equation_set_status(equation,
+                                 /* Error shown when trying to undo with no undo history */
+                                 _("No undo history"));
+        return;
+    }
+
+    link = equation->priv->undo_stack;
+    equation->priv->undo_stack = g_list_remove_link(equation->priv->undo_stack, link);
+    state = link->data;
+    g_list_free(link);
+
+    apply_state(equation, state);
+  
+    equation->priv->redo_stack = g_list_prepend(equation->priv->redo_stack, state);
+}
+
+
+void
+math_equation_redo(MathEquation *equation)
+{
+    GList *link;
+    MathEquationState *state;
+
+    if (!equation->priv->redo_stack) {
+        math_equation_set_status(equation,
+                                 /* Error shown when trying to redo with no redo history */
+                                 _("No redo history"));
+        return;
+    }
+
+    link = equation->priv->redo_stack;
+    equation->priv->redo_stack = g_list_remove_link(equation->priv->redo_stack, link);
+    state = link->data;
+    g_list_free(link);
+
+    apply_state(equation, state);
+
+    equation->priv->undo_stack = g_list_prepend(equation->priv->undo_stack, state);
 }
 
 
@@ -585,7 +628,7 @@ void
 math_equation_set(MathEquation *equation, const gchar *text)
 
 {
-    display_push(equation);
+    math_equation_push_undo_stack(equation);
     gtk_text_buffer_set_text(GTK_TEXT_BUFFER(equation), text, -1);
     clear_ans(equation, FALSE);
 }
@@ -597,7 +640,7 @@ math_equation_set_number(MathEquation *equation, const MPNumber *x)
     char text[MAX_DIGITS];
     GtkTextIter start, end;  
 
-    display_push(equation);
+    math_equation_push_undo_stack(equation);
 
     /* Show the number in the user chosen format */
     display_make_number(equation, text, MAX_DIGITS, x);
@@ -616,7 +659,7 @@ math_equation_set_number(MathEquation *equation, const MPNumber *x)
 void
 math_equation_insert(MathEquation *equation, const gchar *text)
 {
-    display_push(equation);
+    math_equation_push_undo_stack(equation);
 
     /* Replace ** with ^ (not on all keyboards) */
     if (!gtk_text_buffer_get_has_selection(GTK_TEXT_BUFFER(equation)) &&
@@ -801,14 +844,14 @@ math_equation_solve(MathEquation *equation)
     MPNumber z;
     int result;
     gchar *text, *error_token = NULL, *message = NULL;
-  
+
     if (math_equation_is_empty(equation))
         return;
 
     /* If showing a result return to the equation that caused it */
     // FIXME: Result may not be here due to solve (i.e. the user may have entered "ans")
     if (math_equation_is_result(equation)) {
-        display_pop(equation);
+        math_equation_undo(equation);
         return;
     }
 
@@ -908,7 +951,7 @@ math_equation_delete(MathEquation *equation)
     if (cursor >= gtk_text_buffer_get_char_count(GTK_TEXT_BUFFER(equation)))
         return;
 
-    display_push(equation);
+    math_equation_push_undo_stack(equation);
 
     gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &start, cursor);
     gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &end, cursor+1);
@@ -923,7 +966,7 @@ math_equation_backspace(MathEquation *equation)
     if (math_equation_is_empty(equation))
         return;
 
-    display_push(equation);
+    math_equation_push_undo_stack(equation);
 
     if (gtk_text_buffer_get_has_selection(GTK_TEXT_BUFFER(equation)))
         gtk_text_buffer_delete_selection(GTK_TEXT_BUFFER(equation), FALSE, FALSE);
@@ -938,7 +981,7 @@ math_equation_backspace(MathEquation *equation)
 void
 math_equation_clear(MathEquation *equation)
 {
-    display_push(equation);
+    math_equation_push_undo_stack(equation);
     math_equation_set_number_mode(equation, NORMAL);
     gtk_text_buffer_set_text(GTK_TEXT_BUFFER(equation), "", -1);
     clear_ans(equation, FALSE);
@@ -958,7 +1001,7 @@ math_equation_shift(MathEquation *equation, gint count)
         return;
     }
 
-    display_push(equation);
+    math_equation_push_undo_stack(equation);
     
     mp_shift(&z, count, &z);
     math_equation_set_number(equation, &z);
diff --git a/src/math-equation.h b/src/math-equation.h
index a0f68bd..688aca7 100644
--- a/src/math-equation.h
+++ b/src/math-equation.h
@@ -95,6 +95,8 @@ MPAngleUnit math_equation_get_angle_unit(MathEquation *equation);
 
 void math_equation_copy(MathEquation *equation);
 void math_equation_paste(MathEquation *equation);
+void math_equation_undo(MathEquation *equation);
+//FIXMEvoid math_equation_redo(MathEquation *equation);
 void math_equation_store(MathEquation *equation, const gchar *name);
 void math_equation_recall(MathEquation *equation, const gchar *name);
 void math_equation_set(MathEquation *equation, const gchar *text);
diff --git a/src/math-window.c b/src/math-window.c
index 36cd3eb..2eef157 100644
--- a/src/math-window.c
+++ b/src/math-window.c
@@ -117,6 +117,20 @@ paste_cb(GtkWidget *widget, MathWindow *window)
 
 
 static void
+undo_cb(GtkWidget *widget, MathWindow *window)
+{
+    math_equation_undo(window->priv->equation);
+}
+
+
+static void
+redo_cb(GtkWidget *widget, MathWindow *window)
+{
+    math_equation_redo(window->priv->equation);
+}
+
+
+static void
 mode_changed_cb(GtkWidget *menu, MathWindow *window)
 {
     int mode;
@@ -355,6 +369,10 @@ create_menu(MathWindow *window)
     menu = add_menu(window->priv->menu_bar, CALCULATOR_MENU_LABEL);
     add_menu_item(menu, gtk_image_menu_item_new_from_stock(GTK_STOCK_COPY, accel_group), G_CALLBACK(copy_cb), window);
     add_menu_item(menu, gtk_image_menu_item_new_from_stock(GTK_STOCK_PASTE, accel_group), G_CALLBACK(paste_cb), window);
+    add_menu_item(menu, gtk_image_menu_item_new_from_stock(GTK_STOCK_UNDO, accel_group), G_CALLBACK(undo_cb), window);
+    // FIXME: Make Ctrl+Z work for undo
+    add_menu_item(menu, gtk_image_menu_item_new_from_stock(GTK_STOCK_REDO, accel_group), G_CALLBACK(redo_cb), window);
+    // FIXME: Make Ctrl+Shift+Z work for redo
     add_menu_item(menu, gtk_separator_menu_item_new(), NULL, NULL);
     add_menu_item(menu, gtk_image_menu_item_new_from_stock(GTK_STOCK_PREFERENCES, accel_group), G_CALLBACK(show_preferences_cb), window);
     add_menu_item(menu, gtk_separator_menu_item_new(), NULL, NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]