[gnumeric] Improve function tooltips. [#623322]
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Improve function tooltips. [#623322]
- Date: Tue, 13 Jul 2010 20:30:53 +0000 (UTC)
commit 9ea964acfe00fd01754373c863f0262800f2e17f
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date: Tue Jul 13 14:30:54 2010 -0600
Improve function tooltips. [#623322]
2010-07-13 Andreas J. Guelzow <aguelzow pyrshep ca>
* gnumeric-expr-entry.c (gee_dump_lexer): new
(gee_check_tooltip): rewrite using gnm_expr_lex_all
2010-07-13 Morten Welinder <terra gnome org>
* src/parse-util.h (gnm_expr_lex_all): new
(GnmLexerItem): new type
* src/parser.y (setup_state): new (code from gnm_expr_parse_str)
(gnm_expr_lex_all): new
(gnm_expr_parse_str): use setup_state
ChangeLog | 8 ++
NEWS | 1 +
src/parse-util.h | 10 ++
src/parser.y | 155 ++++++++++++++++++++++---------
src/widgets/ChangeLog | 5 +
src/widgets/gnumeric-expr-entry.c | 184 ++++++++++++++++++++++--------------
6 files changed, 245 insertions(+), 118 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 700293f..33900ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2010-07-13 Morten Welinder <terra gnome org>
+
+ * src/parse-util.h (gnm_expr_lex_all): new
+ (GnmLexerItem): new type
+ * src/parser.y (setup_state): new (code from gnm_expr_parse_str)
+ (gnm_expr_lex_all): new
+ (gnm_expr_parse_str): use setup_state
+
2010-07-13 Jean Brefort <jean brefort normalesup org>
* src/cellspan.c (cell_calc_span): fixed crash introduced earlier. [#624274]
diff --git a/NEWS b/NEWS
index 9313104..6031fb8 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,7 @@ Andreas:
* Add new function SORT. [#59144]
* Add menu item to wrap SORT around an existing range.
* Show the number of rows filtered by the auto filter. [#346002]
+ * Improve function tooltips. [#623322]
Jean:
* Fix strong/weak cursor display. [#623241]
diff --git a/src/parse-util.h b/src/parse-util.h
index 4da653a..ed52b42 100644
--- a/src/parse-util.h
+++ b/src/parse-util.h
@@ -76,6 +76,11 @@ struct _GnmParseError {
int begin_char, end_char;
};
+typedef struct {
+ gsize start, end;
+ int token;
+} GnmLexerItem;
+
GnmParseError *parse_error_init (GnmParseError *pe);
void parse_error_free (GnmParseError *pe);
@@ -200,6 +205,11 @@ GnmExprTop const *gnm_expr_parse_str (char const *str, GnmParsePos const *pp,
GnmConventions const *convs,
GnmParseError *error);
+GnmLexerItem *gnm_expr_lex_all (char const *str, GnmParsePos const *pp,
+ GnmExprParseFlags flags,
+ GnmConventions const *convs);
+
+
/* Is this string potentially the start of an expression */
char const *gnm_expr_char_start_p (char const *c);
diff --git a/src/parser.y b/src/parser.y
index 4eb6ec9..4c7c811 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -1440,6 +1440,59 @@ yyerror (char const *s)
return 0;
}
+static void
+setup_state (ParserState *pstate, const char *str,
+ GnmParsePos const *pp,
+ GnmExprParseFlags flags,
+ GnmConventions const *convs,
+ GnmParseError *error)
+{
+ pstate->start = pstate->ptr = str;
+ pstate->pos = pp;
+
+ pstate->flags = flags;
+ pstate->convs =
+ (NULL != convs) ? convs : ((NULL != pp->sheet) ? pp->sheet->convs : gnm_conventions_default);
+
+
+ pstate->decimal_point = pstate->convs->decimal_sep_dot
+ ? '.'
+ : g_utf8_get_char (go_locale_get_decimal ()->str); /* FIXME: one char handled. */
+
+ if (pstate->convs->arg_sep != 0)
+ pstate->arg_sep = pstate->convs->arg_sep;
+ else
+ pstate->arg_sep = go_locale_get_arg_sep ();
+ if (pstate->convs->array_col_sep != 0)
+ pstate->array_col_sep = pstate->convs->array_col_sep;
+ else
+ pstate->array_col_sep = go_locale_get_col_sep ();
+ if (pstate->convs->array_row_sep != 0)
+ pstate->array_row_sep = pstate->convs->array_row_sep;
+ else
+ pstate->array_row_sep = go_locale_get_row_sep ();
+
+ /* Some locales/conventions have ARG_SEP == ARRAY_ROW_SEP
+ * eg {1\2\3;4\5\6} for XL style with ',' as a decimal
+ * some have ARG_SEP == ARRAY_COL_SEPARATOR
+ * eg {1,2,3;4,5,6} for XL style with '.' as a decimal
+ * or {1;2;3|4;5;6} for OOo/
+ * keep track of whether we are in an array to allow the lexer to
+ * dis-ambiguate. */
+ if (pstate->arg_sep == pstate->array_col_sep)
+ pstate->in_array_sep_is = ARRAY_COL_SEP;
+ else if (pstate->arg_sep == pstate->array_row_sep)
+ pstate->in_array_sep_is = ARRAY_ROW_SEP;
+ else
+ pstate->in_array_sep_is = ARG_SEP;
+ pstate->in_array = 0;
+
+ pstate->result = NULL;
+ pstate->error = error;
+
+ state = pstate;
+}
+
/**
* gnm_expr_parse_str:
*
@@ -1466,56 +1519,12 @@ gnm_expr_parse_str (char const *str, GnmParsePos const *pp,
g_return_val_if_fail (str != NULL, NULL);
g_return_val_if_fail (pp != NULL, NULL);
-
- pstate.start = pstate.ptr = str;
- pstate.pos = pp;
-
- pstate.flags = flags;
- pstate.convs =
- (NULL != convs) ? convs : ((NULL != pp->sheet) ? pp->sheet->convs : gnm_conventions_default);
-
-
- pstate.decimal_point = pstate.convs->decimal_sep_dot
- ? '.'
- : g_utf8_get_char (go_locale_get_decimal ()->str); /* FIXME: one char handled. */
-
- if (pstate.convs->arg_sep != 0)
- pstate.arg_sep = pstate.convs->arg_sep;
- else
- pstate.arg_sep = go_locale_get_arg_sep ();
- if (pstate.convs->array_col_sep != 0)
- pstate.array_col_sep = pstate.convs->array_col_sep;
- else
- pstate.array_col_sep = go_locale_get_col_sep ();
- if (pstate.convs->array_row_sep != 0)
- pstate.array_row_sep = pstate.convs->array_row_sep;
- else
- pstate.array_row_sep = go_locale_get_row_sep ();
-
- /* Some locales/conventions have ARG_SEP == ARRAY_ROW_SEP
- * eg {1\2\3;4\5\6} for XL style with ',' as a decimal
- * some have ARG_SEP == ARRAY_COL_SEPARATOR
- * eg {1,2,3;4,5,6} for XL style with '.' as a decimal
- * or {1;2;3|4;5;6} for OOo/
- * keep track of whether we are in an array to allow the lexer to
- * dis-ambiguate. */
- if (pstate.arg_sep == pstate.array_col_sep)
- pstate.in_array_sep_is = ARRAY_COL_SEP;
- else if (pstate.arg_sep == pstate.array_row_sep)
- pstate.in_array_sep_is = ARRAY_ROW_SEP;
- else
- pstate.in_array_sep_is = ARG_SEP;
- pstate.in_array = 0;
-
- pstate.result = NULL;
- pstate.error = error;
+ g_return_val_if_fail (state == NULL, NULL);
if (deallocate_stack == NULL)
deallocate_init ();
- g_return_val_if_fail (state == NULL, NULL);
-
- state = &pstate;
+ setup_state (&pstate, str, pp, flags, convs, error);
yyparse ();
state = NULL;
@@ -1586,3 +1595,57 @@ gnm_expr_parse_str (char const *str, GnmParsePos const *pp,
return gnm_expr_top_new (expr);
}
+
+GnmLexerItem *
+gnm_expr_lex_all (char const *str, GnmParsePos const *pp,
+ GnmExprParseFlags flags,
+ GnmConventions const *convs)
+{
+ GnmLexerItem *res = NULL;
+ int n = 0, alloc = 0;
+ ParserState pstate;
+ GnmParseError *error = NULL;
+
+ g_return_val_if_fail (str != NULL, NULL);
+ g_return_val_if_fail (pp != NULL, NULL);
+
+ if (deallocate_stack == NULL)
+ deallocate_init ();
+
+ setup_state (&pstate, str, pp, flags, convs, error);
+
+ while (1) {
+ int len;
+
+ if (alloc <= n) {
+ alloc = alloc * 2 + 20;
+ res = g_renew (GnmLexerItem, res, alloc);
+ }
+
+ res[n].start = pstate.ptr - pstate.start;
+ res[n].token = yylex ();
+ res[n].end = pstate.ptr - pstate.start;
+
+ if (res[n].token == 0)
+ break;
+
+ len = res[n].end - res[n].start;
+ /* Kill spaces that got eaten, but not a space operator */
+ while (len > 1 && str[res[n].start] == ' ') {
+ res[n].start++;
+ len--;
+ }
+ while (len > 1 && str[res[n].end - 1] == ' ') {
+ res[n].end--;
+ len--;
+ }
+
+ n++;
+ }
+
+ deallocate_all ();
+
+ state = NULL;
+
+ return res;
+}
diff --git a/src/widgets/ChangeLog b/src/widgets/ChangeLog
index c9953d8..029e10a 100644
--- a/src/widgets/ChangeLog
+++ b/src/widgets/ChangeLog
@@ -1,5 +1,10 @@
2010-07-13 Andreas J. Guelzow <aguelzow pyrshep ca>
+ * gnumeric-expr-entry.c (gee_dump_lexer): new
+ (gee_check_tooltip): rewrite using gnm_expr_lex_all
+
+2010-07-13 Andreas J. Guelzow <aguelzow pyrshep ca>
+
* gnm-filter-combo-view.c: show the number of filtered rows in
the progress bar region
diff --git a/src/widgets/gnumeric-expr-entry.c b/src/widgets/gnumeric-expr-entry.c
index 7b615f3..ea5f46d 100644
--- a/src/widgets/gnumeric-expr-entry.c
+++ b/src/widgets/gnumeric-expr-entry.c
@@ -735,17 +735,34 @@ gee_set_tooltip (GnmExprEntry *gee, GnmFunc *fd, gint args, gboolean had_stuff)
}
static void
+gee_dump_lexer (GnmLexerItem *gli) {
+ g_print ("************\n");
+ while (gli->token != 0) {
+ g_print ("%2d to %2d: %d\n",
+ gli->start, gli->end, gli->token);
+ gli++;
+ }
+ g_print ("************\n");
+
+}
+
+#warning We should replace these token names with the correct values
+#define TOKEN_UNMATCHED_APOSTROPHY 273
+#define TOKEN_PARENTHESIS_OPEN 40
+#define TOKEN_PARENTHESIS_CLOSED 41
+#define TOKEN_BRACE_OPEN 123
+#define TOKEN_BRACE_CLOSED 125
+#define TOKEN_SEPARATOR 269
+#define TOKEN_NAME 258
+
+static void
gee_check_tooltip (GnmExprEntry *gee)
{
GtkEditable *editable = GTK_EDITABLE (gee->entry);
- gint end;
+ gint end, args = 0;
char *str;
- char *prefix, *start;
- char *str_end;
- int args = 0;
- gchar sep = go_locale_get_arg_sep ();
- gint para = 0, stuff = 0;
- char quote;
+ gboolean stuff = FALSE;
+ GnmLexerItem *gli, *gli_c;
if (!gee->tooltip.enabled || gee->is_cell_renderer ||
(gee->flags & GNM_EE_SINGLE_RANGE) ||
@@ -760,83 +777,106 @@ gee_check_tooltip (GnmExprEntry *gee)
}
str = gtk_editable_get_chars (editable, 0, end);
- prefix = str_end = str + strlen (str) - 1;
+ gli = gnm_expr_lex_all (str, &gee->pp,
+ GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS,
+ NULL);
+ if (gnm_debug_flag ("functooltip"))
+ gee_dump_lexer (gli);
/*
* If we have an open string at the end of the entry, we
- * need to adjust "prefix" to be in front of that.
+ * need to adjust
*/
- start = str;
- while (*start) {
- if (*start == '"' || *start == '\'') {
- GString *dummy = g_string_new (NULL);
- const char *e = go_strunescape (dummy, start);
- g_string_free (dummy, TRUE);
- if (!e) {
- /* We never saw the end of the string */
- prefix = start;
- if (prefix != str)
- prefix--;
- stuff = 1;
- break;
- }
- start = (char *)e;
- } else
- start++;
- }
- while (str < prefix) {
- if (*prefix == ')') {
- para--;
- } else if (*prefix == '(') {
- para++;
- if (para == 1) {
- /* last opened and yet not closed ( */
- *prefix='\0';
-
- do {
- prefix--;
- } while (prefix >= str &&
- (g_ascii_isalnum (*prefix) ||
- *prefix == '.' ||
- *prefix == '_'));
- prefix++;
-
- if (*prefix != '\0') {
- GnmFunc *fd = gnm_func_lookup (prefix, NULL);
- if (fd != NULL) {
- gee_set_tooltip (gee, fd, args, !!stuff);
- g_free (str);
- return;
- }
+ for (gli_c = gli; gli->token != 0; gli++) {
+ if (gli->token != TOKEN_UNMATCHED_APOSTROPHY)
+ continue;
+ if (gli->start == 0)
+ goto not_found;
+ end = gli->start - 1;
+ gli->token = 0;
+ stuff = TRUE;
+ }
+ gli--;
+
+ while (gli->start > 1) {
+ switch (gli->token) {
+ case TOKEN_PARENTHESIS_OPEN:
+ if ((gli - 1)->token == TOKEN_NAME) {
+ gint start_t = (gli - 1)->start;
+ gint end_t = (gli - 1)->end;
+ char *name = g_strndup (str + start_t,
+ end_t - start_t);
+ GnmFunc *fd = gnm_func_lookup (name, NULL);
+ g_free (name);
+ if (fd != NULL) {
+ gee_set_tooltip (gee, fd, args, stuff);
+ g_free (str);
+ g_free (gli_c);
+ return;
}
- args = 0;
- para--;
}
- stuff++;
- } else if (*prefix == sep && para == 0) {
- stuff = 0;
- args++;
- } else if (*prefix != ' ')
- stuff++;
-
- if (*prefix == '\'' || *prefix == '"') {
- quote = *prefix--;
-
- while (*prefix != quote ||
- (prefix > str && prefix[-1] == '\\')) {
- if (prefix == str)
- goto not_found;
- prefix--;
+ stuff = TRUE;
+ args = 0;
+ break;
+ case TOKEN_BRACE_OPEN:
+ stuff = (args == 0);
+ args = 0;
+ break;
+ case TOKEN_PARENTHESIS_CLOSED: {
+ gint para = 1;
+ gli--;
+ while (gli->start > 1 && para > 0) {
+ switch (gli->token) {
+ case TOKEN_PARENTHESIS_CLOSED:
+ para++;
+ break;
+ case TOKEN_PARENTHESIS_OPEN:
+ para--;
+ break;
+ default:
+ break;
+ }
+ gli--;
}
-
- if (prefix == str)
- goto not_found;
+ gli++;
+ stuff = (args == 0);
+ break;
}
- prefix--;
+ case TOKEN_BRACE_CLOSED: {
+ gint para = 1;
+ gli--;
+ while (gli->start > 1 && para > 0) {
+ switch (gli->token) {
+ case TOKEN_BRACE_CLOSED:
+ para++;
+ break;
+ case TOKEN_BRACE_OPEN:
+ para--;
+ break;
+ default:
+ break;
+ }
+ gli--;
+ }
+ gli++;
+ stuff = (args == 0);
+ break;
+ }
+ case TOKEN_SEPARATOR:
+ args++;
+ break;
+ default:
+ stuff = (args == 0);
+ break;
+ }
+ if (gli->start > 1)
+ gli--;
}
+
not_found:
g_free (str);
+ g_free (gli_c);
gee_delete_tooltip (gee);
return;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]