[gcalctool] Use correct UTF-8 mathematical characters (Robert Ancell, Bug #347630)



commit d76194956a3e99f289fc90afe988512e3ca06003
Author: Robert Ancell <robert ancell gmail com>
Date:   Mon Jun 15 17:49:43 2009 +1000

    Use correct UTF-8 mathematical characters (Robert Ancell, Bug #347630)

 ChangeLog       |    1 +
 src/display.c   |  106 +++++++++++++++++++++++++++++-------------------------
 src/display.h   |   10 ++---
 src/functions.c |   35 +++++++++---------
 src/functions.h |    2 +-
 src/gtk.c       |   29 ++++++++-------
 6 files changed, 95 insertions(+), 88 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 2f4ea1c..83113ad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,6 +11,7 @@ gcalctool change history.
 
     * Percentage operation for addition and subtraction now takes percentage of
       first value (Robert Ancell, Bug #480207)
+    * Use correct UTF-8 mathematical characters (Robert Ancell, Bug #347630)
 
 2009-05-27 Robert Ancell <robert ancell gmail com>
 
diff --git a/src/display.c b/src/display.c
index 1dbbc1d..033e1c7 100644
--- a/src/display.c
+++ b/src/display.c
@@ -26,6 +26,7 @@
 #include <math.h>
 #include <errno.h>
 #include <assert.h>
+#include <glib.h>
 
 #include "display.h"
 
@@ -98,6 +99,7 @@ str_replace(char *str, char *from, char *to)
  */
 
 /* Add in the thousand separators characters if required */
+//FIXME: UTF-8
 static void
 localize_expression(char *dest, const char *src, int dest_length, int *cursor)
 {
@@ -257,13 +259,12 @@ display_set_answer(GCDisplay *display)
 
 
 static void
-display_refresh(GCDisplay *display)
+display_make_text(GCDisplay *display, char *localized, int length, int *cursor)
 {
     int i;
     MPNumber MP_reg;
-    char localized[MAX_LOCALIZED], temp[MAX_LOCALIZED], *str, reg[3];
+    char temp[MAX_LOCALIZED], *str, reg[3];
     GCDisplayState *e;
-    int cursor = display_get_cursor(display);
 
     e = get_state(display);
     if (display_is_empty(display)) {
@@ -286,12 +287,23 @@ display_refresh(GCDisplay *display)
         str = str_replace(str, reg, temp);
     }
 
-    localize_expression(localized, str, MAX_LOCALIZED, &cursor);
-    ui_set_display(localized, cursor);
+    localize_expression(localized, str, length, cursor);
     free(str);
 }
 
 
+static void
+display_refresh(GCDisplay *display)
+{
+    char localized[MAX_LOCALIZED];
+    int cursor;
+    
+    cursor = display_get_cursor(display);
+    display_make_text(display, localized, MAX_LOCALIZED, &cursor);
+    ui_set_display(localized, cursor);
+}
+
+
 void
 display_set_string(GCDisplay *display, const char *value, int cursor)
 {
@@ -305,6 +317,7 @@ display_set_string(GCDisplay *display, const char *value, int cursor)
     display_refresh(display);
 }
 
+
 void
 display_set_cursor(GCDisplay *display, int cursor)
 {
@@ -315,6 +328,7 @@ display_set_cursor(GCDisplay *display, int cursor)
     display_refresh(display);
 }
 
+
 void
 display_set_error(GCDisplay *display, const char *message)
 {
@@ -427,54 +441,52 @@ display_is_undo_step(GCDisplay *display)
     return(display->h.current != display->h.begin);
 }
 
+
+//FIXME: UTF-8
 void
-display_insert(GCDisplay *display, int cursor, const char *text)
+display_insert(GCDisplay *display, int cursor_start, int cursor_end, const char *text)
 {
     char buf[MAX_DISPLAY], *currentText;
     
-    if (cursor < 0) {
+    if (cursor_start < 0) {
         SNPRINTF(buf, MAX_DISPLAY, "%s%s", display_get_text(display), text);
     } else {
         currentText = ui_get_display();
-        SNPRINTF(buf, MAX_DISPLAY, "%.*s%s%s", cursor, currentText, text, currentText + cursor);
-        cursor += strlen(text);
+        SNPRINTF(buf, MAX_DISPLAY, "%.*s%s%s",
+                 g_utf8_offset_to_pointer(currentText, cursor_start) - currentText, currentText,
+                 text,
+                 g_utf8_offset_to_pointer(currentText, cursor_end));
+        cursor_start += strlen(text);
     }
-    display_set_string(display, buf, cursor);
+    display_set_string(display, buf, cursor_start);
 }
 
-void
-display_insert_at_cursor(GCDisplay *display, const char *text)
-{
-    display_insert(display, display_get_cursor(display), text);
-}
 
 void
-display_insert_number(GCDisplay *display, int cursor, const MPNumber *value)
+display_insert_number(GCDisplay *display, int cursor_start, int cursor_end, const MPNumber *value)
 {
     char text[MAX_DISPLAY];
     display_make_number(display, text, MAX_DISPLAY, value, v->base, FALSE);
-    display_insert(display, cursor, text);
-}
-
-void
-display_insert_number_at_cursor(GCDisplay *display, const MPNumber *value)
-{
-    display_insert_number(display, display_get_cursor(display), value);
+    display_insert(display, cursor_start, cursor_end, text);
 }
 
 
 void
-display_backspace(GCDisplay *display)
+display_backspace(GCDisplay *display, int cursor_start, int cursor_end)
 {
-    char buf[MAX_DISPLAY] = "", buf2[MAX_DISPLAY], *t;
+    char buf[MAX_DISPLAY] = "", buf2[MAX_DISPLAY];
     GCDisplayState *e = get_state(display);
     int i, cursor;
     MPNumber MP_reg;
     
     cursor = display_get_cursor(display);
-
+    
     /* If cursor is at end of the line then delete the last character preserving accuracy */
-    if (cursor < 0) {
+    if (cursor_start < 0) {
+        int len;
+        
+        len = g_utf8_strlen(ui_get_display(), -1);
+        
         if (exp_has_postfix(e->expression, "Ans")) {
             display_make_number(display, buf, MAX_DISPLAY, &e->ans, v->base, FALSE);
             e->expression = str_replace(e->expression, "Ans", buf);
@@ -484,38 +496,32 @@ display_backspace(GCDisplay *display)
                 if (exp_has_postfix(e->expression, buf)) {
                     register_get(i, &MP_reg);
                     display_make_number(display, buf2, MAX_DISPLAY, &MP_reg, v->base, FALSE);
-                    /* Remove "Rx" postfix and replace with backspaced number */
-                    SNPRINTF(buf, MAX_DISPLAY, "%.*s%s", strlen(e->expression) - 2, e->expression - 3, buf2);
-                    display_set_string(display, buf, cursor - 1);
-                    return;
+                    SNPRINTF(buf, MAX_DISPLAY, "%.*s%s", strlen(e->expression) - 2, e->expression - 2, buf2);
+                    break;
                 }
             }
         }
 
-        SNPRINTF(buf, MAX_DISPLAY, "%.*s", strlen(e->expression) - 1, e->expression);
-    } else if (cursor > 0) {
-        t = ui_get_display();
-        SNPRINTF(buf, MAX_DISPLAY, "%.*s%s", cursor - 1, t, t + cursor);
-    } else {
-        return; /* At the start of the line */
+        display_insert(display, len - 1, len, ""); // FIXME: Not working for empty display
+    } else if (cursor_start != cursor_end) {
+        display_insert(display, cursor_start, cursor_end, "");
+    } else if (cursor_start > 0) {
+        display_insert(display, cursor_start - 1, cursor_start, "");
     }
 
-    display_set_string(display, buf, cursor - 1);
 }
 
 void
-display_delete(GCDisplay *display)
+display_delete(GCDisplay *display, int cursor_start, int cursor_end)
 {
-    char buf[MAX_DISPLAY] = "", *text;
-    int cursor = display_get_cursor(display);    
-    
-    if (cursor >= 0) {
-        text = ui_get_display();
-        SNPRINTF(buf, MAX_DISPLAY, "%.*s%s", cursor, text, text + cursor + 1);
-        display_set_string(display, buf, cursor);
-    }
+    /* Delete selected block */
+    if (cursor_start != cursor_end)
+        display_insert(display, cursor_start, cursor_end, "");
+    else if (cursor_start >= 0)
+        display_insert(display, cursor_start, cursor_start + 1, "");
 }
 
+
 void
 display_surround(GCDisplay *display, const char *prefix, const char *suffix)
 {
@@ -532,6 +538,7 @@ display_is_empty(GCDisplay *display)
     return strcmp(display_get_text(display), "") == 0;
 }
 
+
 gboolean
 display_is_result(GCDisplay *display)
 {
@@ -541,6 +548,7 @@ display_is_result(GCDisplay *display)
     return FALSE;
 }
 
+
 gboolean
 display_is_usable_number(GCDisplay *display, MPNumber *MPnum)
 {
@@ -705,7 +713,7 @@ make_eng_sci(GCDisplay *display, char *target, int target_len, const MPNumber *M
  
     if (exp < 0) {
         exp = -exp;
-        *optr++ = '-';
+        *optr++ = '-';//FIXME: UTF-8
     } else {
         *optr++ = '+';
     }
@@ -766,6 +774,6 @@ display_make_number(GCDisplay *display, char *target, int target_len, const MPNu
         (display->format == FIX && val != 0.0 && (val > max_fix[base]))) {
         make_eng_sci(display, target, target_len, MPnumber, base);
     } else {
-        mp_cast_to_string(MPnumber, basevals[base], v->accuracy, !v->display.show_zeroes, target, target_len);
+        mp_cast_to_string(MPnumber, basevals[base], v->accuracy, !v->display.show_zeroes, target, target_len);//FIXME: UTF-8
     }
 }
diff --git a/src/display.h b/src/display.h
index d956ff1..1d1dfca 100644
--- a/src/display.h
+++ b/src/display.h
@@ -81,12 +81,10 @@ void display_pop(GCDisplay *);
 void display_unpop(GCDisplay *);
 gboolean display_is_undo_step(GCDisplay *display);
 
-void display_insert(GCDisplay *display, int, const char *);
-void display_insert_at_cursor(GCDisplay *display, const char *);
-void display_insert_number(GCDisplay *display, int, const MPNumber *);
-void display_insert_number_at_cursor(GCDisplay *display, const MPNumber *value);
-void display_backspace(GCDisplay *);
-void display_delete(GCDisplay *);
+void display_insert(GCDisplay *display, int, int, const char *);
+void display_insert_number(GCDisplay *display, int, int, const MPNumber *);
+void display_backspace(GCDisplay *, int, int);
+void display_delete(GCDisplay *, int, int);
 void display_surround(GCDisplay *display, const char *, const char *);
 
 gboolean display_is_empty(GCDisplay *);
diff --git a/src/functions.c b/src/functions.c
index 15a4212..f98cf40 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -75,17 +75,17 @@ static Function functions[NFUNCTIONS] = {
 { FN_START_BLOCK,       "(", 0 },
 { FN_END_BLOCK,         ")", 0 },
 { FN_ADD,               "+", 0 },
-{ FN_SUBTRACT,          "-", 0 },
-{ FN_MULTIPLY,          "*", 0 },
-{ FN_DIVIDE,            "/", 0 },
+{ FN_SUBTRACT,          "â??", 0 },
+{ FN_MULTIPLY,          "Ã?", 0 },
+{ FN_DIVIDE,            "÷", 0 },
 { FN_BACKSPACE,         NULL, 0 },
 { FN_DELETE,            NULL, 0 },
 { FN_CHANGE_SIGN,       NULL, 0 },
 { FN_INTEGER,           "Int", FUNC },
 { FN_FRACTION,          "Frac", FUNC },
 { FN_PERCENTAGE,        "%", 0 },
-{ FN_SQUARE,            "^2", 0 },
-{ FN_SQUARE_ROOT,       "Sqrt", FUNC },
+{ FN_SQUARE,            "²", 0 },
+{ FN_SQUARE_ROOT,       "â??", 0 },
 { FN_RECIPROCAL,        NULL, 0 },
 { FN_E_POW_X,           "e^", PREFIXOP },
 { FN_10_POW_X,          "10^", PREFIXOP },       
@@ -111,7 +111,7 @@ static Function functions[NFUNCTIONS] = {
 { FN_LOGARITHM2,        "Log2", FUNC },
 { FN_ABSOLUTE_VALUE,    "Abs", FUNC },
 { FN_TRUNC,             "Trunc", FUNC },
-{ FN_MODULUS_DIVIDE,    " Mod ", 0 },
+{ FN_MODULUS_DIVIDE,    " mod ", 0 },
 { FN_1S_COMPLEMENT,     "1s", FUNC },
 { FN_2S_COMPLEMENT,     "2s", FUNC },
 { FN_EXPONENTIAL,       "e", 0 },
@@ -189,7 +189,7 @@ do_function(int index)
 
 
 static void
-do_paste(const char *text)
+do_paste(int cursor_start, int cursor_end, const char *text)
 {
     const char *input;
     char c, *output, *clean_text;
@@ -248,7 +248,7 @@ do_paste(const char *text)
     }
     *output++ = '\0';
 
-    display_insert_at_cursor(&v->display, clean_text);
+    display_insert(&v->display, cursor_start, cursor_end, clean_text);
 }
 
 
@@ -376,7 +376,7 @@ do_sto(int index)
 
 
 void
-do_expression(int function, int arg, int cursor)
+do_expression(int function, int arg, int cursor_start, int cursor_end)
 {
     char buf[MAXLINE];
     MPNumber *ans;
@@ -398,7 +398,7 @@ do_expression(int function, int arg, int cursor)
     
     display_push(&v->display);
 
-    display_set_cursor(&v->display, cursor);
+    display_set_cursor(&v->display, cursor_start);
     ans = display_get_answer(&v->display);
 
     ui_set_statusbar("", "");
@@ -448,7 +448,7 @@ do_expression(int function, int arg, int cursor)
             return;
         
         case FN_PASTE:
-            do_paste((const char *)arg); // FIXME: Probably not 64 bit safe
+            do_paste(cursor_start, cursor_end, (const char *)arg); // FIXME: Probably not 64 bit safe
             return;
         
         case FN_INSERT_CHARACTER:
@@ -465,19 +465,19 @@ do_expression(int function, int arg, int cursor)
 
         case FN_RECALL:
             SNPRINTF(buf, MAXLINE, "R%d", arg);
-            display_insert_at_cursor(&v->display, buf);
+            display_insert(&v->display, cursor_start, cursor_end, buf);
             break;
 
         case FN_CONSTANT:
-            display_insert_number_at_cursor(&v->display, constant_get_value(arg));
+            display_insert_number(&v->display, cursor_start, cursor_end, constant_get_value(arg));
             break;
 
         case FN_BACKSPACE:
-            display_backspace(&v->display);
+            display_backspace(&v->display, cursor_start, cursor_end);
             break;
         
         case FN_DELETE:
-            display_delete(&v->display);
+            display_delete(&v->display, cursor_start, cursor_end);
             break;
 
         case FN_CHANGE_SIGN:
@@ -509,7 +509,6 @@ do_expression(int function, int arg, int cursor)
              * the cursor must be taken from the first undo */
             if (display_is_result(&v->display)) {
                 display_pop(&v->display);
-                cursor = display_get_cursor(&v->display);
                 if (display_is_undo_step(&v->display)) {
                     display_pop(&v->display);
                 }
@@ -583,9 +582,9 @@ do_expression(int function, int arg, int cursor)
             } else {
                 if (functions[function].flags & FUNC) {
                     SNPRINTF(buf, MAXLINE, "%s(", functions[function].symname);
-                    display_insert_at_cursor(&v->display, buf);
+                    display_insert(&v->display, cursor_start, cursor_end, buf);
                 } else {
-                    display_insert_at_cursor(&v->display, functions[function].symname);
+                    display_insert(&v->display, cursor_start, cursor_end, functions[function].symname);
                 }
             }
             break;
diff --git a/src/functions.h b/src/functions.h
index 8cb4f42..4713531 100644
--- a/src/functions.h
+++ b/src/functions.h
@@ -92,6 +92,6 @@ enum
     NFUNCTIONS
 };
 
-void do_expression(int function, int arg, int cursor);
+void do_expression(int function, int arg, int cursor_start, int cursor_end);
 
 #endif /*FUNCTIONS_H*/
diff --git a/src/gtk.c b/src/gtk.c
index 1515a3b..5adc4cb 100644
--- a/src/gtk.c
+++ b/src/gtk.c
@@ -939,19 +939,6 @@ ui_get_display(void)
 }
 
 
-static int
-get_cursor(void)
-{
-    gint pos;
-    g_object_get(G_OBJECT(X.display_buffer), "cursor-position", &pos, NULL);
-    
-    /* Convert the last position to -1 */
-    if (pos == gtk_text_buffer_get_char_count(X.display_buffer))
-        return -1;
-    else
-        return pos;
-}
-
 void
 ui_set_bitfield(int enabled, guint64 bits)
 {
@@ -971,7 +958,21 @@ ui_set_bitfield(int enabled, guint64 bits)
 
 static void do_button(int function, int arg)
 {
-    do_expression(function, arg, get_cursor());
+    GtkTextIter start, end;
+    gint cursor_start, cursor_end;
+
+    if(gtk_text_buffer_get_selection_bounds(X.display_buffer, &start, &end)) {
+        cursor_start = gtk_text_iter_get_offset(&start);
+        cursor_end = gtk_text_iter_get_offset(&end);
+    }
+    else {
+        g_object_get(G_OBJECT(X.display_buffer), "cursor-position", &cursor_start, NULL);
+        if (cursor_start == gtk_text_buffer_get_char_count(X.display_buffer))
+            cursor_start = -1;
+        cursor_end = cursor_start;
+    }
+
+    do_expression(function, arg, cursor_start, cursor_end);
 }
 
 static void



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