[gcalctool] Reimplement automatic ans substitution
- From: Robert Ancell <rancell src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gcalctool] Reimplement automatic ans substitution
- Date: Tue, 26 Jan 2010 11:00:17 +0000 (UTC)
commit 78ecf98ff386aaa9aadfa7ec68292a8cd5fad9dc
Author: Robert Ancell <robert ancell gmail com>
Date: Sun Jan 17 21:37:04 2010 +1300
Reimplement automatic ans substitution
src/display.c | 167 +++++++++++++++++++++++++++++++--------------------------
src/display.h | 8 +--
src/gtk.c | 4 --
3 files changed, 93 insertions(+), 86 deletions(-)
---
diff --git a/src/display.c b/src/display.c
index 453cc08..aef037b 100644
--- a/src/display.c
+++ b/src/display.c
@@ -40,34 +40,6 @@ get_state(GCDisplay *display)
}
-static char *
-str_replace(char *str, char *from, char *to)
-{
- char output[MAX_DISPLAY];
- int offset = 0;
- char *c;
- int flen = strlen(from);
- int tlen = strlen(to);
-
- for (c = str; *c && offset < MAX_DISPLAY - 1; c++, offset++) {
- if (strncasecmp(from, c, flen) == 0) {
- SNPRINTF(output + offset, MAX_DISPLAY - offset, "%s", to);
- c += flen - 1;
- offset += tlen - 1;
- } else {
- output[offset] = *c;
- }
- }
-
- if (offset >= MAX_DISPLAY)
- offset = MAX_DISPLAY - 1;
- output[offset] = '\0';
-
- free(str);
-
- return strdup(output);
-}
-
/* Add in the thousand separators characters if required and if we are
* currently in the decimal numeric base, use the "right" radix character.
*/
@@ -140,43 +112,60 @@ localize_expression(GCDisplay *display, char *dest, const char *src, int dest_le
void
display_clear(GCDisplay *display)
{
+ GCDisplayState *state;
+
+ state = get_state(display);
display_set_string(display, "", -1);
+ state->ans_start = -1;
+ state->ans_end = -1;
}
-const char *
-display_get_text(GCDisplay *display)
+static const char *
+get_text(GCDisplay *display)
{
return get_state(display)->expression;
}
-gboolean display_get_integer(GCDisplay *display, gint64 *value)
+static char *
+get_expression(GCDisplay *display)
+{
+ GCDisplayState *state;
+
+ state = get_state(display);
+ if(state->ans_start >= 0)
+ return g_strdup_printf("%.*sans%s", state->ans_start, state->expression, g_utf8_offset_to_pointer(state->expression, state->ans_end));
+ else
+ return g_strdup(state->expression);
+}
+
+
+gboolean
+display_get_integer(GCDisplay *display, gint64 *value)
{
- const char *text;
- char buf[MAX_DISPLAY];
gchar *endptr;
- text = display_get_text(display);
if (display_is_result(display)) {
- display_make_number(display, buf, MAX_DISPLAY, display_get_answer(display));
- text = buf;
+ *value = mp_cast_to_int(display_get_answer(display));
+ return TRUE;
}
- *value = g_ascii_strtoll(text, &endptr, 10);
+ *value = g_ascii_strtoll(get_text(display), &endptr, 10);
if(*endptr != '\0' || ((*value == G_MAXINT64 || *value == G_MININT64) && errno == ERANGE))
return FALSE;
return TRUE;
}
-gboolean display_get_unsigned_integer(GCDisplay *display, guint64 *value)
+gboolean
+display_get_unsigned_integer(GCDisplay *display, guint64 *value)
{
const char *text;
char buf[MAX_DISPLAY];
gchar *endptr;
- text = display_get_text(display);
+ text = get_text(display);
if (display_is_result(display)) {
display_make_number(display, buf, MAX_DISPLAY, display_get_answer(display));
text = buf;
@@ -193,7 +182,8 @@ gboolean display_get_unsigned_integer(GCDisplay *display, guint64 *value)
}
-MPNumber *display_get_answer(GCDisplay *display)
+MPNumber *
+display_get_answer(GCDisplay *display)
{
return &get_state(display)->ans;
}
@@ -213,6 +203,7 @@ display_set_number(GCDisplay *display, const MPNumber *x)
char text[MAX_DISPLAY];
int enabled;
guint64 bit_value;
+
display_make_number(display, text, MAX_DISPLAY, x);
display_set_string(display, text, -1);
@@ -224,7 +215,14 @@ display_set_number(GCDisplay *display, const MPNumber *x)
void
display_set_answer(GCDisplay *display)
{
- display_set_string(display, "ans", -1);
+ GCDisplayState *state;
+ char text[MAX_DISPLAY];
+
+ state = get_state(display);
+ display_make_number(display, text, MAX_DISPLAY, &state->ans);
+ display_set_string(display, text, -1);
+ state->ans_start = 0;
+ state->ans_end = g_utf8_strlen(text, -1);
}
@@ -323,7 +321,8 @@ update_undo_redo_button_sensitivity(GCDisplay *display)
}
-void display_clear_stack(GCDisplay *display)
+void
+display_clear_stack(GCDisplay *display)
{
int i = display->h.begin;
while (i != display->h.end) {
@@ -338,7 +337,8 @@ void display_clear_stack(GCDisplay *display)
}
-void display_push(GCDisplay *display)
+void
+display_push(GCDisplay *display)
{
int c;
@@ -348,7 +348,9 @@ void display_push(GCDisplay *display)
do {
i = ((i + 1) % UNDO_HISTORY_LENGTH);
free(display->h.e[i].expression);
- display->h.e[i].expression = strdup("ans");
+ display->h.e[i].expression = strdup("ans"); // FIXME: Use actual number
+ display->h.e[i].ans_start = -1;
+ display->h.e[i].ans_end = -1;
} while (i != display->h.end);
}
@@ -367,7 +369,8 @@ void display_push(GCDisplay *display)
}
-void display_pop(GCDisplay *display)
+void
+display_pop(GCDisplay *display)
{
if (display->h.current != display->h.begin) {
display->h.current = ((display->h.current - 1) % UNDO_HISTORY_LENGTH);
@@ -406,10 +409,19 @@ display_is_undo_step(GCDisplay *display)
void
display_insert(GCDisplay *display, int cursor_start, int cursor_end, const char *text)
{
+ GCDisplayState *state;
char buf[MAX_DISPLAY];
+ state = get_state(display);
+
+ /* If inside ans variable then modify number */
+ if (state->ans_start >= 0 && cursor_start >= state->ans_start && cursor_start <= state->ans_end) {
+ state->ans_start = -1;
+ state->ans_end = -1;
+ }
+
if (cursor_start < 0) {
- SNPRINTF(buf, MAX_DISPLAY, "%s%s", display_get_text(display), text);
+ SNPRINTF(buf, MAX_DISPLAY, "%s%s", get_text(display), text);
display_set_string(display, buf, -1);
} else {
GString *new_text;
@@ -468,8 +480,6 @@ display_insert_number(GCDisplay *display, int cursor_start, int cursor_end, cons
void
display_backspace(GCDisplay *display, int cursor_start, int cursor_end)
{
- char buf[MAX_DISPLAY] = "";
- GCDisplayState *e = get_state(display);
int cursor;
/* Can't delete empty display */
@@ -481,14 +491,7 @@ display_backspace(GCDisplay *display, int cursor_start, int cursor_end)
/* If cursor is at end of the line then delete the last character preserving accuracy */
if (cursor_start < 0) {
int len;
-
len = g_utf8_strlen(ui_get_display(), -1);
-
- if (display_is_result(display)) {
- display_make_number(display, buf, MAX_DISPLAY, &e->ans);
- e->expression = str_replace(e->expression, "ans", buf);
- }
-
display_insert(display, len - 1, len, "");
} else if (cursor_start != cursor_end) {
display_insert(display, cursor_start, cursor_end, "");
@@ -509,27 +512,20 @@ display_delete(GCDisplay *display, int cursor_start, int cursor_end)
}
-void
-display_surround(GCDisplay *display, const char *prefix, const char *suffix)
-{
- char buffer[MAX_DISPLAY];
-
- SNPRINTF(buffer, MAX_DISPLAY, "%s%s%s", prefix, display_get_text(display), suffix);
- display_set_string(display, buffer, -1);
-}
-
-
gboolean
display_is_empty(GCDisplay *display)
{
- return strcmp(display_get_text(display), "") == 0;
+ return strcmp(get_text(display), "") == 0;
}
gboolean
display_is_result(GCDisplay *display)
{
- if (strcmp(display_get_text(display), "ans") == 0)
+ GCDisplayState *state;
+
+ state = get_state(display);
+ if (state->ans_start == 0 && state->ans_end == g_utf8_strlen(state->expression, -1))
return TRUE;
return FALSE;
@@ -546,7 +542,7 @@ display_is_usable_number(GCDisplay *display, MPNumber *z)
mp_set_from_mp(display_get_answer(display), z);
return TRUE;
} else {
- return mp_set_from_string(display_get_text(display), z) == 0;
+ return mp_set_from_string(get_text(display), z) == 0;
}
}
@@ -565,12 +561,16 @@ display_init(GCDisplay *display)
display->word_size = 32;
display->angle_unit = MP_DEGREES;
- for (i = 0; i < UNDO_HISTORY_LENGTH; i++)
+ for (i = 0; i < UNDO_HISTORY_LENGTH; i++) {
display->h.e[i].expression = strdup("");
+ display->h.e[i].ans_start = -1;
+ display->h.e[i].ans_end = -1;
+ }
}
-void display_set_accuracy(GCDisplay *display, int accuracy)
+void
+display_set_accuracy(GCDisplay *display, int accuracy)
{
display->accuracy = accuracy;
get_state(display)->cursor = -1;
@@ -578,7 +578,8 @@ void display_set_accuracy(GCDisplay *display, int accuracy)
}
-void display_set_show_thousands_separator(GCDisplay *display, gboolean visible)
+void
+display_set_show_thousands_separator(GCDisplay *display, gboolean visible)
{
display->show_tsep = visible;
display_set_cursor(display, -1);
@@ -586,7 +587,8 @@ void display_set_show_thousands_separator(GCDisplay *display, gboolean visible)
}
-void display_set_show_trailing_zeroes(GCDisplay *display, gboolean visible)
+void
+display_set_show_trailing_zeroes(GCDisplay *display, gboolean visible)
{
display->show_zeroes = visible;
get_state(display)->cursor = -1;
@@ -594,23 +596,29 @@ void display_set_show_trailing_zeroes(GCDisplay *display, gboolean visible)
}
-void display_set_format(GCDisplay *display, DisplayFormat format)
+void
+display_set_format(GCDisplay *display, DisplayFormat format)
{
display->format = format;
get_state(display)->cursor = -1;
display_refresh(display);
}
-void display_set_word_size(GCDisplay *display, int word_size)
+
+void
+display_set_word_size(GCDisplay *display, int word_size)
{
display->word_size = word_size;
}
-void display_set_angle_unit(GCDisplay *display, MPAngleUnit angle_unit)
+
+void
+display_set_angle_unit(GCDisplay *display, MPAngleUnit angle_unit)
{
display->angle_unit = angle_unit;
}
+
/* Convert engineering or scientific number in the given base. */
static void
make_eng_sci(GCDisplay *display, char *target, int target_len, const MPNumber *x, int base_)
@@ -1165,12 +1173,15 @@ display_do_function(GCDisplay *display, int function, gpointer arg, int cursor_s
MPNumber z;
int result;
const char *message = NULL;
- char *error_token;
+ char *text, *error_token;
+ text = get_expression (display);
result = parse(display,
- display_get_text(display),
+ text,
&z,
&error_token);
+ g_free(text);
+
switch (result) {
case PARSER_ERR_NONE:
mp_set_from_mp(&z, ans);
@@ -1214,8 +1225,10 @@ display_do_function(GCDisplay *display, int function, gpointer arg, int cursor_s
break;
case FN_TEXT:
+ /* Start new equation when entering digits after existing result */
if(display_is_result(display) && g_unichar_isdigit(g_utf8_get_char((char*)arg)))
display_clear(display);
+
display_insert(display, cursor_start, cursor_end, (const char *)arg);
break;
}
diff --git a/src/display.h b/src/display.h
index bcb1a9b..1ccda3b 100644
--- a/src/display.h
+++ b/src/display.h
@@ -29,8 +29,9 @@
/* Expression mode state */
typedef struct {
- MPNumber ans; /* Previously calculated answer */
- char *expression; /* Expression entered by user */
+ MPNumber ans; /* Previously calculated answer */
+ char *expression; /* Expression entered by user */
+ int ans_start, ans_end; /* Start and end characters for ans variable in expression */
int cursor;
} GCDisplayState;
@@ -105,14 +106,11 @@ 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 *);
gboolean display_is_result(GCDisplay *);
gboolean display_is_usable_number(GCDisplay *display, MPNumber *);
-const char *display_get_text(GCDisplay *display);
-
void display_make_number(GCDisplay *display, char *target, int target_len, const MPNumber *x);
void display_do_function(GCDisplay *display, int function, gpointer arg, int cursor_start, int cursor_end);
diff --git a/src/gtk.c b/src/gtk.c
index 3dd12ea..d2ea15b 100644
--- a/src/gtk.c
+++ b/src/gtk.c
@@ -512,10 +512,6 @@ ui_set_display(char *str, int cursor)
GtkTextIter iter;
GtkAdjustment *adj;
- // ???
- if (str[0] == '\0')
- str = " ";
-
gtk_text_buffer_set_text(X.display_buffer, str, -1);
if (cursor < 0)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]