diff --git a/src/dialogs/dialog-cell-format.c b/src/dialogs/dialog-cell-format.c index 6001e09..e38b7f3 100644 --- a/src/dialogs/dialog-cell-format.c +++ b/src/dialogs/dialog-cell-format.c @@ -1535,7 +1535,7 @@ validation_entry_to_expr (Sheet *sheet, GnmExprEntry *gee) { GnmParsePos pp; parse_pos_init_sheet (&pp, sheet); - return gnm_expr_entry_parse (gee, &pp, NULL, FALSE, GNM_EXPR_PARSE_DEFAULT); + return gnm_expr_entry_parse (gee, &pp, NULL, FALSE, GNM_EXPR_PARSE_DEFAULT, TRUE); } static void diff --git a/src/dialogs/dialog-define-names.c b/src/dialogs/dialog-define-names.c index 8d88130..5d2d16a 100644 --- a/src/dialogs/dialog-define-names.c +++ b/src/dialogs/dialog-define-names.c @@ -406,7 +406,8 @@ name_guru_add (NameGuruState *state) texpr = gnm_expr_entry_parse (state->expr_entry, &pp, parse_error_init (&perr), FALSE, - GNM_EXPR_PARSE_DEFAULT | GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_INVALID); + GNM_EXPR_PARSE_DEFAULT | GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_INVALID, + TRUE); if (texpr == NULL) { if (perr.err == NULL) return TRUE; diff --git a/src/sheet-object-widget.c b/src/sheet-object-widget.c index 5b5876f..2de25f4 100644 --- a/src/sheet-object-widget.c +++ b/src/sheet-object-widget.c @@ -883,7 +883,7 @@ cb_adjustment_set_focus (GtkWidget *window, GtkWidget *focus_widget, GnmExprTop const *texpr = gnm_expr_entry_parse ( GNM_EXPR_ENTRY (state->old_focus->parent), parse_pos_init_sheet (&pp, state->sheet), - NULL, FALSE, GNM_EXPR_PARSE_DEFAULT); + NULL, FALSE, GNM_EXPR_PARSE_DEFAULT, TRUE); if (texpr != NULL) gnm_expr_top_unref (texpr); } @@ -911,7 +911,7 @@ cb_adjustment_config_ok_clicked (GtkWidget *button, AdjustmentConfigState *state GnmParsePos pp; GnmExprTop const *texpr = gnm_expr_entry_parse (state->expression, parse_pos_init_sheet (&pp, so->sheet), - NULL, FALSE, GNM_EXPR_PARSE_DEFAULT); + NULL, FALSE, GNM_EXPR_PARSE_DEFAULT, TRUE); if (texpr != NULL) { dependent_set_expr (&state->swa->dep, texpr); dependent_link (&state->swa->dep); @@ -1520,7 +1520,7 @@ cb_checkbox_set_focus (GtkWidget *window, GtkWidget *focus_widget, GnmExprTop const *texpr = gnm_expr_entry_parse ( GNM_EXPR_ENTRY (state->old_focus->parent), parse_pos_init_sheet (&pp, state->sheet), - NULL, FALSE, GNM_EXPR_PARSE_DEFAULT); + NULL, FALSE, GNM_EXPR_PARSE_DEFAULT, TRUE); if (texpr != NULL) gnm_expr_top_unref (texpr); } @@ -1550,7 +1550,7 @@ cb_checkbox_config_ok_clicked (GtkWidget *button, CheckboxConfigState *state) GnmParsePos pp; GnmExprTop const *texpr = gnm_expr_entry_parse (state->expression, parse_pos_init_sheet (&pp, so->sheet), - NULL, FALSE, GNM_EXPR_PARSE_DEFAULT); + NULL, FALSE, GNM_EXPR_PARSE_DEFAULT, TRUE); if (texpr != NULL) { dependent_set_expr (&state->swc->dep, texpr); dependent_link (&state->swc->dep); diff --git a/src/wbc-gtk.c b/src/wbc-gtk.c index ccdd01c..2b2acda 100644 --- a/src/wbc-gtk.c +++ b/src/wbc-gtk.c @@ -4024,53 +4024,84 @@ typedef struct { gulong entry_update_handler; } GraphDimEditor; -static void -cb_graph_dim_editor_update (GnmExprEntry *gee, - G_GNUC_UNUSED gboolean user_requested, - GraphDimEditor *editor) +static gboolean +get_texpr (GraphDimEditor *editor, GnmExprTop const **new_texpr) { - GOData *data = NULL; + GnmExprEntry *gee; + GnmExprTop const *texpr = NULL; Sheet *sheet; SheetControlGUI *scg; + gboolean is_valid = TRUE; - /* Ignore changes while we are insensitive. useful for displaying - * values, without storing then as Data. Also ignore updates if the - * dataset has been cleared via the weakref handler */ - if (!GTK_WIDGET_SENSITIVE (gee) || editor->dataset == NULL) - return; + gee = editor->entry; g_object_get (G_OBJECT (gee), "scg", &scg, NULL); sheet = scg_sheet (scg); g_object_unref (G_OBJECT (scg)); - /* If we are setting something */ if (!gnm_expr_entry_is_blank (editor->entry)) { GnmParsePos pos; - GnmParseError perr; - GnmExprTop const *texpr; - parse_error_init (&perr); - texpr = gnm_expr_entry_parse (editor->entry, + texpr = gnm_expr_entry_parse (gee, parse_pos_init_sheet (&pos, sheet), - &perr, TRUE, GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS); + NULL, TRUE, GNM_EXPR_PARSE_UNKNOWN_NAMES_ARE_STRINGS, FALSE); - /* TODO : add some error dialogs split out - * the code in workbok_edit to add parens. */ if (texpr == NULL) { - if (editor->data_type == GOG_DATA_SCALAR) + if (editor->data_type == GOG_DATA_SCALAR) { + if (new_texpr != NULL) texpr = gnm_expr_top_new_constant ( value_new_string ( - gnm_expr_entry_get_text (editor->entry))); - else { - g_return_if_fail (perr.err != NULL); - - wb_control_validation_msg (WORKBOOK_CONTROL (scg_wbcg (scg)), - VALIDATION_STYLE_PARSE_ERROR, NULL, perr.err->message); - parse_error_free (&perr); - return; + gnm_expr_entry_get_text (gee))); + } else + is_valid = FALSE; } } + gnm_expr_entry_set_error_state (editor->entry, !is_valid); + + if (new_texpr != NULL) + *new_texpr = texpr; + else + if (texpr != NULL) + gnm_expr_top_unref (texpr); + + return is_valid; +} + +static void +cb_graph_dim_entry_changed (GnmExprEntry *gee, + GraphDimEditor *editor) +{ + if (!GTK_WIDGET_SENSITIVE (gee) || editor->dataset == NULL) + return; + + get_texpr (editor, NULL); +} + +static void +cb_graph_dim_editor_update (GnmExprEntry *gee, + G_GNUC_UNUSED gboolean user_requested, + GraphDimEditor *editor) +{ + GnmExprTop const *texpr; + + /* Ignore changes while we are insensitive. useful for displaying + * values, without storing then as Data. Also ignore updates if the + * dataset has been cleared via the weakref handler */ + if (!GTK_WIDGET_SENSITIVE (gee) || editor->dataset == NULL) + return; + + if (get_texpr (editor, &texpr)) { + GOData *data = NULL; + + if (texpr != NULL) { + Sheet *sheet; + SheetControlGUI *scg; + + g_object_get (G_OBJECT (gee), "scg", &scg, NULL); + sheet = scg_sheet (scg); + g_object_unref (G_OBJECT (scg)); + switch (editor->data_type) { case GOG_DATA_SCALAR: data = gnm_go_data_scalar_new_expr (sheet, texpr); @@ -4082,9 +4113,9 @@ cb_graph_dim_editor_update (GnmExprEntry *gee, data = gnm_go_data_matrix_new_expr (sheet, texpr); } } - /* The SheetObjectGraph does the magic to link things in */ gog_dataset_set_dim (editor->dataset, editor->dim_i, data, NULL); + } } static gboolean @@ -4165,6 +4196,9 @@ wbcg_data_allocator_editor (GogDataAllocator *dalloc, "update", G_CALLBACK (cb_graph_dim_editor_update), editor); g_signal_connect (G_OBJECT (gnm_expr_entry_get_entry (editor->entry)), + "changed", + G_CALLBACK (cb_graph_dim_entry_changed), editor); + g_signal_connect (G_OBJECT (gnm_expr_entry_get_entry (editor->entry)), "focus-out-event", G_CALLBACK (cb_graph_dim_entry_focus_out_event), editor); editor->dataset_changed_handler = g_signal_connect (G_OBJECT (editor->dataset), diff --git a/src/widgets/gnumeric-expr-entry.c b/src/widgets/gnumeric-expr-entry.c index fdd34a0..4ff722c 100644 --- a/src/widgets/gnumeric-expr-entry.c +++ b/src/widgets/gnumeric-expr-entry.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -1377,10 +1378,9 @@ gnm_expr_entry_can_rangesel (GnmExprEntry *gee) GnmExprTop const * gnm_expr_entry_parse (GnmExprEntry *gee, GnmParsePos const *pp, GnmParseError *perr, gboolean start_sel, - GnmExprParseFlags flags) + GnmExprParseFlags flags, gboolean update_entry) { char const *text; - char *str; GnmExprTop const *texpr; g_return_val_if_fail (IS_GNM_EXPR_ENTRY (gee), NULL); @@ -1416,6 +1416,9 @@ gnm_expr_entry_parse (GnmExprEntry *gee, GnmParsePos const *pp, } /* Reset the entry in case something changed */ + if (update_entry) { + char *str; + str = gnm_expr_top_as_string (texpr, pp, gnm_conventions_default); if (strcmp (str, text)) { SheetControlGUI *scg = wbcg_cur_scg (gee->wbcg); @@ -1428,6 +1431,7 @@ gnm_expr_entry_parse (GnmExprEntry *gee, GnmParsePos const *pp, gtk_entry_set_text (gee->entry, str); } g_free (str); + } return texpr; } @@ -1591,3 +1595,30 @@ gnm_expr_entry_enable_highlight (GnmExprEntry *gee) gee->feedback_disabled = FALSE; } +void +gnm_expr_entry_set_error_state (GnmExprEntry *gee, gboolean is_error) +{ + GtkRcStyle *modifier_style; + unsigned int flags; + + g_return_if_fail (IS_GNM_EXPR_ENTRY (gee)); + + modifier_style = gtk_widget_get_modifier_style(GTK_WIDGET (gee->entry)); + g_return_if_fail (modifier_style != NULL); + + if (is_error) { + GdkColor color = {0, 0xffff, 0x8000, 0x8000}; + + modifier_style->base[GTK_STATE_NORMAL] = color; + modifier_style->base[GTK_STATE_PRELIGHT] = color; + modifier_style->base[GTK_STATE_ACTIVE] = color; + flags = GTK_RC_BASE; + } else + flags = 0; + + modifier_style->color_flags[GTK_STATE_NORMAL] = flags; + modifier_style->color_flags[GTK_STATE_PRELIGHT] = flags; + modifier_style->color_flags[GTK_STATE_ACTIVE] = flags; + + gtk_widget_modify_style (GTK_WIDGET (gee->entry), modifier_style); +} diff --git a/src/widgets/gnumeric-expr-entry.h b/src/widgets/gnumeric-expr-entry.h index 2cd141f..842d75a 100644 --- a/src/widgets/gnumeric-expr-entry.h +++ b/src/widgets/gnumeric-expr-entry.h @@ -55,7 +55,8 @@ GSList *gnm_expr_entry_parse_as_list (GnmExprEntry *gee, Sheet *sheet); GnmExprTop const *gnm_expr_entry_parse (GnmExprEntry *gee, GnmParsePos const *pp, GnmParseError *perr, gboolean start_sel, - GnmExprParseFlags flags); + GnmExprParseFlags flags, + gboolean update_entry); char *gnm_expr_entry_global_range_name (GnmExprEntry *gee, Sheet *sheet); void gnm_expr_entry_load_from_text (GnmExprEntry *gee, char const *str); void gnm_expr_entry_load_from_dep (GnmExprEntry *gee, @@ -73,6 +74,8 @@ void gnm_expr_entry_grab_focus (GnmExprEntry *gee, gboolean select_all); void gnm_expr_entry_disable_highlight (GnmExprEntry *gee); void gnm_expr_entry_enable_highlight (GnmExprEntry *gee); +void gnm_expr_entry_set_error_state (GnmExprEntry *gee, gboolean is_error); + /* Cell Renderer Specific Method */ gboolean gnm_expr_entry_editing_canceled (GnmExprEntry *gee);