[gcalctool] Reformat display for answer format and number bases
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcalctool] Reformat display for answer format and number bases
- Date: Thu, 22 Apr 2010 12:05:01 +0000 (UTC)
commit 8024d64ebb10747817270c73862d3cdc0adc5633
Author: Robert Ancell <robert ancell gmail com>
Date: Thu Apr 22 21:56:22 2010 +1000
Reformat display for answer format and number bases
src/math-equation.c | 225 ++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 188 insertions(+), 37 deletions(-)
---
diff --git a/src/math-equation.c b/src/math-equation.c
index 82bdb76..f87182e 100644
--- a/src/math-equation.c
+++ b/src/math-equation.c
@@ -138,51 +138,202 @@ get_ans_offsets(MathEquation *equation, gint *start, gint *end)
static void
-reformat_display(MathEquation *equation, gint old_base)
+reformat_ans(MathEquation *equation)
{
- gchar *text;
+ if (!equation->priv->ans_start)
+ return;
- text = math_equation_get_display(equation);
+ gchar *orig_ans_text;
+ gchar ans_text[MAX_DIGITS];
+ GtkTextIter ans_start, ans_end;
- /* Reformat answer */
- if (equation->priv->ans_start) {
- gchar *orig_ans_text;
- gchar ans_text[MAX_DIGITS];
- GtkTextIter ans_start, ans_end;
-
- gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(equation), &ans_start, equation->priv->ans_start);
- gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(equation), &ans_end, equation->priv->ans_end);
- orig_ans_text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(equation), &ans_start, &ans_end, FALSE);
- display_make_number(equation, ans_text, MAX_DIGITS, &equation->priv->state.ans);
- if (strcmp(orig_ans_text, ans_text) != 0) {
- gint start;
-
- equation->priv->in_undo_operation = TRUE;
- equation->priv->in_reformat = TRUE;
-
- start = gtk_text_iter_get_offset(&ans_start);
- gtk_text_buffer_delete(GTK_TEXT_BUFFER(equation), &ans_start, &ans_end);
- gtk_text_buffer_insert_with_tags(GTK_TEXT_BUFFER(equation), &ans_end, ans_text, -1, equation->priv->ans_tag, NULL);
-
- /* There seems to be a bug in the marks as they alternate being the correct and incorrect ways. Reset them */
- gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &ans_start, start);
- gtk_text_buffer_move_mark(GTK_TEXT_BUFFER(equation), equation->priv->ans_start, &ans_start);
- gtk_text_buffer_move_mark(GTK_TEXT_BUFFER(equation), equation->priv->ans_end, &ans_end);
-
- equation->priv->in_reformat = FALSE;
- equation->priv->in_undo_operation = FALSE;
+ gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(equation), &ans_start, equation->priv->ans_start);
+ gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(equation), &ans_end, equation->priv->ans_end);
+ orig_ans_text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(equation), &ans_start, &ans_end, FALSE);
+ display_make_number(equation, ans_text, MAX_DIGITS, &equation->priv->state.ans);
+ if (strcmp(orig_ans_text, ans_text) != 0) {
+ gint start;
+
+ equation->priv->in_undo_operation = TRUE;
+ equation->priv->in_reformat = TRUE;
+
+ start = gtk_text_iter_get_offset(&ans_start);
+ gtk_text_buffer_delete(GTK_TEXT_BUFFER(equation), &ans_start, &ans_end);
+ gtk_text_buffer_insert_with_tags(GTK_TEXT_BUFFER(equation), &ans_end, ans_text, -1, equation->priv->ans_tag, NULL);
+
+ /* There seems to be a bug in the marks as they alternate being the correct and incorrect ways. Reset them */
+ gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &ans_start, start);
+ gtk_text_buffer_move_mark(GTK_TEXT_BUFFER(equation), equation->priv->ans_start, &ans_start);
+ gtk_text_buffer_move_mark(GTK_TEXT_BUFFER(equation), equation->priv->ans_end, &ans_end);
+
+ equation->priv->in_reformat = FALSE;
+ equation->priv->in_undo_operation = FALSE;
+ }
+ gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(equation), &ans_start, equation->priv->ans_start);
+ gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(equation), &ans_end, equation->priv->ans_end);
+ g_free(orig_ans_text);
+}
+
+
+/* NOTE: Not efficent but easy to write */
+// FIXME: This is just a lexer - use the same lexer as the solver
+static void
+reformat_base(MathEquation *equation, gint old_base)
+{
+ gunichar sub_zero, sub_nine;
+ gchar *text, *read_iter;
+ gboolean in_number = FALSE, have_radix = FALSE;
+ gint offset = 0, offset_step = 0, max_digit = 0, base = -1, base_offset;
+ gint ans_start, ans_end;
+
+ if (equation->priv->base == old_base)
+ return;
+
+ sub_zero = g_utf8_get_char("â??");
+ sub_nine = g_utf8_get_char("â??");
+
+ read_iter = text = math_equation_get_display(equation);
+ get_ans_offsets(equation, &ans_start, &ans_end);
+ while (TRUE) {
+ gunichar c;
+ gint digit = -1, sub_digit = -1;
+
+ /* See what digit this character is */
+ c = g_utf8_get_char(read_iter);
+ if (c >= sub_zero && c <= sub_nine)
+ sub_digit = c - sub_zero;
+ else if (c >= 'a' && c <= 'z')
+ digit = c - 'a';
+ else if (c >= 'A' && c <= 'Z')
+ digit = c - 'A';
+ else
+ digit = g_unichar_digit_value(c);
+
+ /* Don't mess with ans */
+ if (offset >= ans_start && offset <= ans_end) {
+ digit = -1;
+ sub_digit = -1;
+ }
+
+ if (in_number && digit >= 0) {
+ if (digit > max_digit)
+ max_digit = digit;
+ }
+ else if (in_number && sub_digit >= 0) {
+ if (base < 0) {
+ base_offset = offset;
+ base = 0;
+ }
+
+ base = base * 10 + sub_digit;
+ }
+ else if (in_number) {
+ /* Allow one radix inside a number */
+ if (!have_radix && base < 0 && strncmp(read_iter, equation->priv->radix, strlen(equation->priv->radix)) == 0) {
+ have_radix = TRUE;
+ read_iter += strlen(equation->priv->radix);
+ offset += g_utf8_strlen(equation->priv->radix, -1);
+ continue;
+ }
+
+ /* If had no base then insert it */
+ if (base < 0) {
+ GtkTextIter iter;
+ gint multiplier = 1;
+ gint b = old_base;
+ const char *digits[] = {"â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??"};
+
+ equation->priv->in_undo_operation = TRUE;
+ equation->priv->in_reformat = TRUE;
+
+ while (b / multiplier != 0)
+ multiplier *= 10;
+ while (multiplier != 1) {
+ int d;
+ multiplier /= 10;
+ d = b / multiplier;
+ gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &iter, offset + offset_step);
+ gtk_text_buffer_insert(GTK_TEXT_BUFFER(equation), &iter, digits[d], -1);
+ offset_step++;
+ b -= d * multiplier;
+ }
+
+ equation->priv->in_reformat = FALSE;
+ equation->priv->in_undo_operation = FALSE;
+ }
+ /* Remove the base if the current value */
+ else if (max_digit < base && base == equation->priv->base) {
+ GtkTextIter start, end;
+
+ equation->priv->in_undo_operation = TRUE;
+ equation->priv->in_reformat = TRUE;
+
+ gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &start, base_offset + offset_step);
+ gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &end, offset + offset_step);
+ gtk_text_buffer_delete(GTK_TEXT_BUFFER(equation), &start, &end);
+ offset_step -= offset - base_offset;
+
+ equation->priv->in_reformat = FALSE;
+ equation->priv->in_undo_operation = FALSE;
+ }
+
+ in_number = FALSE;
+ }
+ else if (digit >= 0) {
+ in_number = TRUE;
+ have_radix = FALSE;
+ base = -1;
+ max_digit = digit;
}
- gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(equation), &ans_start, equation->priv->ans_start);
- gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(equation), &ans_end, equation->priv->ans_end);
- g_free(orig_ans_text);
+
+ if (c == '\0')
+ break;
+
+ read_iter = g_utf8_next_char(read_iter);
+ offset++;
}
- // FIXME: Need to know old base to do base changes
- // FIXME: Need to keep cursor location correct
+ g_free(text);
+}
+
+
+static void
+reformat_separators(MathEquation *equation)
+{
+#if 0
+ gchar *text, *read_iter;
+ gboolean in_number = FALSE, in_fraction = FALSE;
+
+ text = math_equation_get_display(equation);
+
+ /* Find numbers in display, and modify if necessary */
+ read_iter = text;
+ while(*read_iter != '\0') {
+ gunichar c;
+
+ c = g_utf8_get_char(read_iter);
+
+ if (strncmp(read_iter, equation->priv->tsep, strlen(equation->priv->tsep)) == 0)
+ ;
+ read_iter = g_utf8_next_char(read_iter);
+ }
- /* Find numbers in display, format and then replace if changed */
-
g_free(text);
+#endif
+}
+
+
+static void
+reformat_display(MathEquation *equation, gint old_base)
+{
+ /* Change ans */
+ reformat_ans(equation);
+
+ /* Add/remove base suffixes if have changed base */
+ reformat_base(equation, old_base);
+
+ /* Add/remove thousands separators */
+ reformat_separators(equation);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]