Commit 2821f0c8 authored by Jody Goldberg's avatar Jody Goldberg Committed by Jody Goldberg

begin support for intersection and sets, still needs lots of work, but I


2002-09-25  Jody Goldberg <jody@gnome.org>

	* src/parser.y : begin support for intersection and sets, still needs
	  lots of work, but I don't want to get too out of sync.

	* src/expr.c : handle intersection and sets.
	* src/expr-name.c (name_refer_circular) : ditto.

	* src/workbook.c (post_sheet_index_change) : don't emit the signal
	  during destruction.

2002-09-24  Lutz Müller <lutz@users.sourceforge.net>

	* src/dialogs/dialog-sheet-order.c: Be aware of changes in the
	  sheet order.
	* src/workbook.[c,h]: Provide a "sheet_order_changed" signal.
	* src/workbook-control-gui.c: Remove debugging messages. Allow
	  dropping the sheet anywhere in the workbook - reordering will still
	  be done.
parent d7604570
2002-09-25 Jody Goldberg <jody@gnome.org>
* src/parser.y : begin support for intersection and sets, still needs
lots of work, but I don't want to get too out of sync.
* src/expr.c : handle intersection and sets.
* src/expr-name.c (name_refer_circular) : ditto.
* src/workbook.c (post_sheet_index_change) : don't emit the signal
during destruction.
2002-09-24 Lutz Mller <lutz@users.sourceforge.net>
* src/dialogs/dialog-sheet-order.c: Be aware of changes in the
sheet order.
* src/workbook.[c,h]: Provide a "sheet_order_changed" signal.
* src/workbook-control-gui.c: Remove debugging messages. Allow
dropping the sheet anywhere in the workbook - reordering will still
be done.
2002-09-24 Morten Welinder <terra@diku.dk>
* src/parser.y (yylex): Handle error constants. (And fix utf8
......@@ -34,6 +54,8 @@
* src/parser.y : remove sheet_ref RANGEREF production. RANGEREF
already handles sheet references internally.
2002-09-23 Jody Goldberg <jody@gnome.org>
* src/expr.c (gnm_expr_eval) : handle empties when implicit
intersection is valid but accesses an empty cell.
......
......@@ -28,6 +28,8 @@ Jody:
* Move the CORBA support code into a plugin and make more functional.
* Add some UI for managing hyperlinks of various sorts (unfinished)
* Make the location status box smarter about named ranges
* Begin support for intersection
* Start parsing range sets
Michael Meeks:
* Spruce up the CORBA code to use some bonobo utils.
......
2002-09-25 Jody Goldberg <jody@gnome.org>
* src/parser.y : begin support for intersection and sets, still needs
lots of work, but I don't want to get too out of sync.
* src/expr.c : handle intersection and sets.
* src/expr-name.c (name_refer_circular) : ditto.
* src/workbook.c (post_sheet_index_change) : don't emit the signal
during destruction.
2002-09-24 Lutz Mller <lutz@users.sourceforge.net>
* src/dialogs/dialog-sheet-order.c: Be aware of changes in the
sheet order.
* src/workbook.[c,h]: Provide a "sheet_order_changed" signal.
* src/workbook-control-gui.c: Remove debugging messages. Allow
dropping the sheet anywhere in the workbook - reordering will still
be done.
2002-09-24 Morten Welinder <terra@diku.dk>
* src/parser.y (yylex): Handle error constants. (And fix utf8
......@@ -34,6 +54,8 @@
* src/parser.y : remove sheet_ref RANGEREF production. RANGEREF
already handles sheet references internally.
2002-09-23 Jody Goldberg <jody@gnome.org>
* src/expr.c (gnm_expr_eval) : handle empties when implicit
intersection is valid but accesses an empty cell.
......
2002-09-25 Jody Goldberg <jody@gnome.org>
* src/parser.y : begin support for intersection and sets, still needs
lots of work, but I don't want to get too out of sync.
* src/expr.c : handle intersection and sets.
* src/expr-name.c (name_refer_circular) : ditto.
* src/workbook.c (post_sheet_index_change) : don't emit the signal
during destruction.
2002-09-24 Lutz Mller <lutz@users.sourceforge.net>
* src/dialogs/dialog-sheet-order.c: Be aware of changes in the
sheet order.
* src/workbook.[c,h]: Provide a "sheet_order_changed" signal.
* src/workbook-control-gui.c: Remove debugging messages. Allow
dropping the sheet anywhere in the workbook - reordering will still
be done.
2002-09-24 Morten Welinder <terra@diku.dk>
* src/parser.y (yylex): Handle error constants. (And fix utf8
......@@ -34,6 +54,8 @@
* src/parser.y : remove sheet_ref RANGEREF production. RANGEREF
already handles sheet references internally.
2002-09-23 Jody Goldberg <jody@gnome.org>
* src/expr.c (gnm_expr_eval) : handle empties when implicit
intersection is valid but accesses an empty cell.
......
2002-09-25 Jody Goldberg <jody@gnome.org>
* ms-formula-read.c (binary_ops) : enable intersection
still needs work.
* ms-formula-write.c (ms_formula_build_pre_data) : ditt.
(write_node) : ditto.
2002-09-15 Jody Goldberg <jody@gnome.org>
* ms-formula-read.c (const) : DateDif takes 3 arguments.
......
......@@ -699,7 +699,7 @@ static GnmExprOp const binary_ops [] = {
GNM_EXPR_OP_NOT_EQUAL, /* 0x0e, ptgNE */
/* FIXME: These need implementing ... */
GNM_EXPR_OP_ADD, /* 0x0f, ptgIsect : Intersection */
GNM_EXPR_OP_INTERSECT, /* 0x0f, ptgIsect : Intersection */
GNM_EXPR_OP_ADD, /* 0x10, ptgUnion : Union */
GNM_EXPR_OP_RANGE_CTOR /* 0x11, ptgRange : Range */
};
......
......@@ -161,6 +161,8 @@ ms_formula_build_pre_data (ExcelSheet *sheet, GnmExpr const *tree)
switch (tree->any.oper) {
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY:
ms_formula_build_pre_data (sheet, tree->binary.value_a);
ms_formula_build_pre_data (sheet, tree->binary.value_b);
......@@ -557,7 +559,8 @@ write_node (PolishData *pd, GnmExpr const *tree, int paren_level)
{ FORMULA_PTG_PERCENT, 5, 0, 0 }, /* Percentage (NOT MODULO) */
{ 0, 0, 0, 0 }, /* Array */
{ 0, 0, 0, 0 }, /* Set */
{ FORMULA_PTG_RANGE, 0, 0, 0 }
{ FORMULA_PTG_RANGE, 0, 0, 0 },
{ FORMULA_PTG_INTERSECT, 0, 0, 0 }
};
int op;
g_return_if_fail (pd);
......@@ -566,6 +569,7 @@ write_node (PolishData *pd, GnmExpr const *tree, int paren_level)
op = tree->any.oper;
switch (op) {
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY : {
int const prec = operations[op].prec;
......
......@@ -67,6 +67,8 @@ typedef struct {
gboolean initial_colors_set;
GSList *old_order;
gulong sheet_order_changed_listener;
} SheetManager;
enum {
......@@ -676,6 +678,12 @@ cb_ok_clicked (GtkWidget *ignore, SheetManager *state)
static void
cb_sheet_order_destroy (GtkWidget *ignored, SheetManager *state)
{
Workbook *wb = wb_control_workbook (WORKBOOK_CONTROL (state->wbcg));
/* Stop to listen to changes in the sheet order. */
g_signal_handler_disconnect (G_OBJECT (wb),
state->sheet_order_changed_listener);
wbcg_edit_detach_guru (state->wbcg);
g_object_unref (G_OBJECT (state->gui));
state->gui = NULL;
......@@ -691,6 +699,144 @@ cb_sheet_order_destroy (GtkWidget *ignored, SheetManager *state)
g_free (state);
}
static void
dialog_sheet_order_update_sheet_order (SheetManager *state)
{
gchar *name, *new_name;
gboolean is_deleted;
gboolean is_editable;
gboolean is_locked;
GdkColor *back, *fore;
GtkTreeIter iter;
Workbook *wb = wb_control_workbook (WORKBOOK_CONTROL (state->wbcg));
gint i, j, n_sheets, n_children;
GtkTreeModel *model = GTK_TREE_MODEL (state->model);
Sheet *sheet_wb, *sheet_model;
GtkTreeSelection *sel = gtk_tree_view_get_selection (state->sheet_list);
gboolean selected;
n_sheets = workbook_sheet_count (wb);
n_children = gtk_tree_model_iter_n_children (model, NULL);
g_return_if_fail (n_sheets == n_children);
for (i = 0; i < n_sheets; i++) {
sheet_wb = workbook_sheet_by_index (wb, i);
for (j = i; j < n_children; j++) {
if (!gtk_tree_model_iter_nth_child (model, &iter,
NULL, j))
break;
gtk_tree_model_get (model, &iter, SHEET_POINTER,
&sheet_model, -1);
if (sheet_model == sheet_wb)
break;
}
if (j == i)
continue;
if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, j))
break;
selected = gtk_tree_selection_iter_is_selected (sel, &iter);
gtk_tree_model_get (model, &iter,
SHEET_LOCKED, &is_locked,
SHEET_NAME, &name,
SHEET_NEW_NAME, &new_name,
IS_EDITABLE_COLUMN, &is_editable,
SHEET_POINTER, &sheet_model,
IS_DELETED, &is_deleted,
BACKGROUND_COLOUR_POINTER, &back,
FOREGROUND_COLOUR_POINTER, &fore,
-1);
gtk_list_store_remove (state->model, &iter);
gtk_list_store_insert (state->model, &iter, i);
gtk_list_store_set (state->model, &iter,
SHEET_LOCKED, is_locked,
SHEET_LOCK_IMAGE, is_locked ?
state->image_padlock : state->image_padlock_no,
SHEET_NAME, name,
SHEET_NEW_NAME, new_name,
IS_EDITABLE_COLUMN, is_editable,
SHEET_POINTER, sheet_model,
IS_DELETED, is_deleted,
BACKGROUND_COLOUR_POINTER, back,
FOREGROUND_COLOUR_POINTER, fore,
-1);
if (back)
gdk_color_free (back);
if (fore)
gdk_color_free (fore);
g_free (name);
g_free (new_name);
if (selected)
gtk_tree_selection_select_iter (sel, &iter);
}
g_slist_free (state->old_order);
state->old_order = NULL;
for (i = 0; i < n_sheets; i++)
state->old_order = g_slist_append (state->old_order,
workbook_sheet_by_index (wb, i));
cb_selection_changed (NULL, state);
}
static void
cb_sheet_order_changed (Workbook *wb, SheetManager *state)
{
GtkTreeIter iter;
GtkTreeModel *model = GTK_TREE_MODEL (state->model);
guint i, n = 0;
Sheet *sheet;
/*
* First question: Has the user already changed the order via
* the dialog? If no, we assume that the user wants to see the
* sheet order change reflected in the dialog.
*/
n = g_slist_length (state->old_order);
for (i = 0; i < n; i++) {
if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, i))
break;
gtk_tree_model_get (model, &iter, SHEET_POINTER, &sheet, -1);
if (sheet != g_slist_nth_data (state->old_order, i))
break;
}
if (n == i) {
dialog_sheet_order_update_sheet_order (state);
return;
}
/*
* The user has already changed the order via the dialog.
* Let's check if the new sheet order is already reflected
* in the dialog. If yes, things are easy.
*/
n = workbook_sheet_count (wb);
for (i = 0; i < n; i++) {
if (!gtk_tree_model_iter_nth_child (model, &iter, NULL, i))
break;
gtk_tree_model_get (model, &iter, SHEET_POINTER, &sheet, -1);
if (sheet != workbook_sheet_by_index (wb, i))
break;
}
if (i == n) {
g_slist_free (state->old_order);
state->old_order = NULL;
for (i = 0; i < n; i++)
state->old_order = g_slist_append (state->old_order,
workbook_sheet_by_index (wb, i));
return;
}
/*
* The order in the dialog and the new sheet order are totally
* different. Ask the user what to do.
*/
if (gnumeric_dialog_question_yes_no (state->wbcg,
_("The sheet order has changed. Do you want to "
"update the list?"), TRUE))
dialog_sheet_order_update_sheet_order (state);
}
void
dialog_sheet_order (WorkbookControlGUI *wbcg)
{
......@@ -698,6 +844,7 @@ dialog_sheet_order (WorkbookControlGUI *wbcg)
GladeXML *gui;
GtkTable *table;
ColorGroup *cg;
Workbook *wb;
g_return_if_fail (wbcg != NULL);
......@@ -728,6 +875,12 @@ dialog_sheet_order (WorkbookControlGUI *wbcg)
GTK_ICON_SIZE_LARGE_TOOLBAR,
"Gnumeric-Sheet-Manger");
/* Listen for changes in the sheet order. */
wb = wb_control_workbook (WORKBOOK_CONTROL (wbcg));
state->sheet_order_changed_listener = g_signal_connect (G_OBJECT (wb),
"sheet_order_changed", G_CALLBACK (cb_sheet_order_changed),
state);
gtk_button_stock_alignment_set (GTK_BUTTON (state->up_btn), 0., .5, 0., 0.);
gtk_button_stock_alignment_set (GTK_BUTTON (state->down_btn), 0., .5, 0., 0.);
gtk_button_stock_alignment_set (GTK_BUTTON (state->add_btn), 0., .5, 0., 0.);
......
......@@ -214,6 +214,7 @@ name_refer_circular (char const *name, GnmExpr const *expr)
switch (expr->any.oper) {
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY:
return (name_refer_circular (name, expr->binary.value_a) ||
name_refer_circular (name, expr->binary.value_b));
......
......@@ -338,6 +338,7 @@ do_gnm_expr_unref (GnmExpr const *expr)
switch (expr->any.oper) {
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY:
do_gnm_expr_unref (expr->binary.value_a);
do_gnm_expr_unref (expr->binary.value_b);
......@@ -432,6 +433,7 @@ gnm_expr_equal (GnmExpr const *a, GnmExpr const *b)
switch (a->any.oper) {
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY:
return gnm_expr_equal (a->binary.value_a, b->binary.value_a) &&
gnm_expr_equal (a->binary.value_b, b->binary.value_b);
......@@ -476,9 +478,6 @@ gnm_expr_equal (GnmExpr const *a, GnmExpr const *b)
case GNM_EXPR_OP_SET:
return gnm_expr_list_equal (a->set.set, b->set.set);
default :
g_assert_not_reached ();
}
return FALSE;
......@@ -1061,6 +1060,8 @@ gnm_expr_eval (GnmExpr const *expr, EvalPos const *pos,
return value_new_error (pos, gnumeric_err_REF);
return value_new_cellrange (&a, &b, pos->eval.col, pos->eval.row);
}
case GNM_EXPR_OP_INTERSECT: {
};
}
return value_new_error (pos, _("Unknown evaluation error"));
......@@ -1077,11 +1078,11 @@ static char *
do_expr_as_string (GnmExpr const *expr, ParsePos const *pp,
int paren_level)
{
static const struct {
static struct {
char const *name;
int prec; /* Precedences -- should match parser.y */
int assoc_left, assoc_right; /* 0: no, 1: yes. */
} operations[] = {
} const operations[] = {
{ "=", 1, 1, 0 },
{ ">", 1, 1, 0 },
{ "<", 1, 1, 0 },
......@@ -1102,8 +1103,9 @@ do_expr_as_string (GnmExpr const *expr, ParsePos const *pp,
{ "+", 5, 0, 0 }, /* Unary + */
{ "%", 5, 0, 0 }, /* Percentage (NOT MODULO) */
{ NULL, 0, 0, 0 }, /* Array */
{ NULL, 0, 0, 0 }, /* Set */
{ NULL, 0, 0, 0 } /* Range Ctor */
{ NULL, 0, 0, 0 }, /* Set */
{ NULL, 0, 0, 0 }, /* Range Ctor */
{ NULL, 0, 0, 0 } /* intersection */
};
int const op = expr->any.oper;
......@@ -1495,6 +1497,7 @@ gnm_expr_rewrite (GnmExpr const *expr, GnmExprRewriteInfo const *rwinfo)
switch (expr->any.oper) {
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY: {
GnmExpr const *a = gnm_expr_rewrite (expr->binary.value_a, rwinfo);
GnmExpr const *b = gnm_expr_rewrite (expr->binary.value_b, rwinfo);
......@@ -1709,6 +1712,8 @@ gnm_expr_first_func (GnmExpr const *expr)
case GNM_EXPR_OP_FUNCALL:
return expr;
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY:
tmp = gnm_expr_first_func (expr->binary.value_a);
if (tmp != NULL)
......@@ -1765,6 +1770,8 @@ static GSList *
do_referenced_sheets (GnmExpr const *expr, GSList *sheets)
{
switch (expr->any.oper) {
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY:
return do_referenced_sheets (
expr->binary.value_b,
......@@ -1781,6 +1788,12 @@ do_referenced_sheets (GnmExpr const *expr, GSList *sheets)
sheets = do_referenced_sheets (l->data, sheets);
return sheets;
}
case GNM_EXPR_OP_SET: {
GnmExprList *l;
for (l = expr->set.set; l; l = l->next)
sheets = do_referenced_sheets (l->data, sheets);
return sheets;
}
case GNM_EXPR_OP_NAME:
return sheets;
......@@ -1793,16 +1806,13 @@ do_referenced_sheets (GnmExpr const *expr, GSList *sheets)
if (v->type != VALUE_CELLRANGE)
return sheets;
return g_slist_insert_unique (
g_slist_insert_unique (sheets,
v->v_range.cell.a.sheet),
v->v_range.cell.b.sheet);
g_slist_insert_unique (sheets,
v->v_range.cell.a.sheet),
v->v_range.cell.b.sheet);
}
/* constant arrays can only contain simple values, no references */
case GNM_EXPR_OP_ARRAY:
g_warning ("An array in a NAME?");
break;
default :
break;
}
return sheets;
......@@ -1835,6 +1845,8 @@ gnm_expr_get_boundingbox (GnmExpr const *expr, Range *bound)
g_return_if_fail (expr != NULL);
switch (expr->any.oper) {
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY:
gnm_expr_get_boundingbox (expr->binary.value_a, bound);
gnm_expr_get_boundingbox (expr->binary.value_b, bound);
......@@ -1850,6 +1862,12 @@ gnm_expr_get_boundingbox (GnmExpr const *expr, Range *bound)
gnm_expr_get_boundingbox (l->data, bound);
break;
}
case GNM_EXPR_OP_SET: {
GnmExprList *l;
for (l = expr->set.set; l; l = l->next)
gnm_expr_get_boundingbox (l->data, bound);
break;
}
case GNM_EXPR_OP_NAME:
/* Do NOT validate the name. */
......@@ -1876,9 +1894,6 @@ gnm_expr_get_boundingbox (GnmExpr const *expr, Range *bound)
gnm_expr_get_boundingbox (a->corner.expr, bound);
break;
}
default :
g_assert_not_reached ();
}
}
......@@ -1991,6 +2006,7 @@ ets_hash (gconstpointer key)
guint h = (guint)(expr->any.oper);
switch (expr->any.oper){
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_ANY_BINARY:
return ((GPOINTER_TO_INT (expr->binary.value_a) * 7) ^
......@@ -2020,17 +2036,12 @@ ets_hash (gconstpointer key)
case GNM_EXPR_OP_CONSTANT:
return value_hash (expr->constant.value);
#ifndef DEBUG_SWITCH_ENUM
default:
g_assert_not_reached ();
return h;
#endif
case GNM_EXPR_OP_CELLREF:
case GNM_EXPR_OP_NAME:
case GNM_EXPR_OP_ARRAY:
return h; /* FIXME */
break;
}
return h;
}
/*
......@@ -2048,6 +2059,7 @@ ets_equal (gconstpointer _a, gconstpointer _b)
switch (ea->any.oper){
case GNM_EXPR_OP_RANGE_CTOR:
case GNM_EXPR_OP_INTERSECT:
case GNM_EXPR_OP_ANY_BINARY:
return (ea->binary.value_a == eb->binary.value_a &&
ea->binary.value_b == eb->binary.value_b);
......
......@@ -31,7 +31,8 @@ typedef enum {
GNM_EXPR_OP_PERCENTAGE, /* Percentage (value/100) */
GNM_EXPR_OP_ARRAY, /* Array access */
GNM_EXPR_OP_SET, /* A set of expressions */
GNM_EXPR_OP_RANGE_CTOR /* A constructed range eg A1:index(1,2) */
GNM_EXPR_OP_RANGE_CTOR, /* A constructed range eg A1:index(1,2) */
GNM_EXPR_OP_INTERSECT /* The intersection of multiple ranges */
} GnmExprOp;
/* Shorthands for case statements. Easy to read, easy to maintain. */
......
......@@ -42,7 +42,8 @@ typedef enum {
PERR_SHEET_IS_REQUIRED,
PERR_SINGLE_RANGE,
PERR_3D_NAME,
PERR_MULTIPLE_EXPRESSIONS
PERR_MULTIPLE_EXPRESSIONS,
PERR_INVALID_EMPTY
} ParseErrorID;
/* In parser.y */
......
......@@ -339,6 +339,20 @@ build_range_ctor (GnmExpr *l, GnmExpr *r, GnmExpr *validate)
return build_binop (l, GNM_EXPR_OP_RANGE_CTOR, r);
}
static GnmExpr *
build_intersect (GnmExpr *l, GnmExpr *r)
{
#if 0
gnumeric_parse_error (state, PERR_UNEXPECTED_TOKEN,
_("Constructed ranges use simple references"),
state->expr_text - state->expr_backup, 0);
return NULL;
}
}
#endif
return build_binop (l, GNM_EXPR_OP_INTERSECT, r);
}
/**
* parse_string_as_value :
*
......@@ -412,10 +426,9 @@ parser_sheet_by_name (Workbook *wb, GnmExpr *name_expr)
sheet = workbook_sheet_by_name (wb, name+1);
if (sheet == NULL) {
gnumeric_parse_error (
state, PERR_UNKNOWN_SHEET,
g_strdup_printf (_("Unknown sheet '%s'"), name),
state->expr_text - state->expr_backup, strlen (name));
gnumeric_parse_error (state, PERR_UNKNOWN_SHEET,
g_strdup_printf (_("Unknown sheet '%s'"), name),
state->expr_text - state->expr_backup, strlen (name));
}
return sheet;
}
......@@ -493,13 +506,27 @@ exp: CONSTANT { $$ = $1; }
| exp LTE exp { $$ = build_binop ($1, GNM_EXPR_OP_LTE, $3); }
| exp AND exp { $$ = build_logical ($1, TRUE, $3); }
| exp OR exp { $$ = build_logical ($1, FALSE, $3); }
| '(' exp ')' { $$ = $2; }
| exp ' ' exp { $$ = build_intersect ($1, $3); }
| '-' exp %prec NEG { $$ = build_unary_op (GNM_EXPR_OP_UNARY_NEG, $2); }
| '+' exp %prec PLUS { $$ = build_unary_op (GNM_EXPR_OP_UNARY_PLUS, $2); }
| NOT exp { $$ = build_not ($2); }
| exp '%' { $$ = build_unary_op (GNM_EXPR_OP_PERCENTAGE, $1); }
| '(' arg_list ')' {
if ($2 == NULL) {
gnumeric_parse_error (state, PERR_INVALID_EMPTY,
g_strdup_printf (_("() is an invalid expression")),
state->expr_text - state->expr_backup + 1, 0);
} else if ($2->next != NULL) {
unregister_allocation ($2);
$$ = register_expr_allocation (gnm_expr_new_set ($2));
} else {
unregister_allocation ($2);
$$ = register_expr_allocation ($2->data);
gnm_expr_list_free ($2);
}
}
| '{' array_cols '}' {
unregister_allocation ($2);
$$ = build_array ($2);
......@@ -514,8 +541,7 @@ exp: CONSTANT { $$ = $1; }
pos.sheet = $1.first;
if ($1.last != NULL)
gnumeric_parse_error (
state, PERR_3D_NAME,
gnumeric_parse_error (state, PERR_3D_NAME,
g_strdup_printf (_("What is a 3D name %s:%s!%s ?"),
$1.first->name_quoted,
$1.last->name_quoted,
......@@ -524,8 +550,7 @@ exp: CONSTANT { $$ = $1; }
else {
expr_name = expr_name_lookup (&pos, name);
if (expr_name == NULL)
gnumeric_parse_error (
state, PERR_UNKNOWN_NAME,
gnumeric_parse_error (state, PERR_UNKNOWN_NAME,
g_strdup_printf (_("Name '%s' does not exist in sheet '%s'"),
name, pos.sheet->name_quoted),
state->expr_text - state->expr_backup + 1, strlen (name));
......@@ -546,8 +571,7 @@ exp: CONSTANT { $$ = $1; }
pos.wb = application_workbook_get_by_name (wb_name);
if (pos.wb == NULL) {
int retval = gnumeric_parse_error (
state, PERR_UNKNOWN_WORKBOOK,
int retval = gnumeric_parse_error (state, PERR_UNKNOWN_WORKBOOK,
g_strdup_printf (_("Unknown workbook '%s'"), wb_name),
state->expr_text - state->expr_backup + 1, strlen (name));
......@@ -558,8 +582,7 @@ exp: CONSTANT { $$ = $1; }
expr_name = expr_name_lookup (&pos, name);
if (expr_name == NULL) {
int retval = gnumeric_parse_error (
state, PERR_UNKNOWN_NAME,
int retval = gnumeric_parse_error (state, PERR_UNKNOWN_NAME,
g_strdup_printf (_("Name '%s' does not exist in workbook '%s'"),
name, wb_name),
state->expr_text - state->expr_backup + 1, strlen (name));
......@@ -699,8 +722,7 @@ array_row: array_exp {
$$ = g_slist_prepend ($3, $1);
register_expr_list_allocation ($$);
} else {
return gnumeric_parse_error (
state, PERR_INVALID_ARRAY_SEPARATOR,
return gnumeric_parse_error (state, PERR_INVALID_ARRAY_SEPARATOR,
g_strdup_printf (_("The character %c cannot be used to separate array elements"),
state->array_col_separator), state->expr_text - state->expr_backup + 1, 1);
}
......@@ -713,8 +735,7 @@ array_row: array_exp {
register_expr_list_allocation ($$);
} else {
/* FIXME: Is this the right error to display? */
return gnumeric_parse_error (
state, PERR_INVALID_ARRAY_SEPARATOR,
return gnumeric_parse_error (state, PERR_INVALID_ARRAY_SEPARATOR,
g_strdup_printf (_("The character %c cannot be used to separate array elements"),
state->array_col_separator), state->expr_text - state->expr_backup + 1, 1);
}
......@@ -867,8 +888,7 @@ yylex (void)
v = value_new_float (d);
state->expr_text = end;
} else if (c != 'e' && c != 'E') {
gnumeric_parse_error (
state, PERR_OUT_OF_RANGE,
gnumeric_parse_error (state, PERR_OUT_OF_RANGE,
g_strdup (_("The number is out of range")),
state->expr_text - state->expr_backup, end - start);
return INVALID_TOKEN;
......@@ -877,8 +897,7 @@ yylex (void)
* right region w/o it turning into an ugly
* hack, for now the cursor is put at the end.
*/
gnumeric_parse_error (
state, PERR_OUT_OF_RANGE,
gnumeric_parse_error (state, PERR_OUT_OF_RANGE,
g_strdup (_("The number is out of range")),
0, 0);
return INVALID_TOKEN;
......@@ -904,8 +923,7 @@ yylex (void)
v = value_new_float (d);
state->expr_text = end;
} else {
gnumeric_parse_error (
state, PERR_OUT_OF_RANGE,
gnumeric_parse_error (state, PERR_OUT_OF_RANGE,
g_strdup (_("The number is out of range")),
state->expr_text - state->expr_backup, end - start);
return INVALID_TOKEN;
......@@ -932,8 +950,7 @@ yylex (void)
p = state->expr_text;
state->expr_text = find_char (state->expr_text, quotes_end);
if (!*state->expr_text) {
gnumeric_parse_error (
state, PERR_MISSING_CLOSING_QUOTE,
gnumeric_parse_error (state, PERR_MISSING_CLOSING_QUOTE,
g_strdup (_("Could not find matching closing quote")),
(p - state->expr_backup) + 1, 1);
return INVALID_TOKEN;
......
......@@ -36,6 +36,7 @@
#include "application.h"
#include "value.h"
#include "parse-util.h"
#include "expr-name.h"
#include <gsf/gsf-impl-utils.h>
......
......@@ -728,6 +728,7 @@ cb_sheet_label_drag_data_received (GtkWidget *widget, GdkDragContext *context,
guint n, i;
g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));
g_return_if_fail (GTK_IS_WIDGET (widget));
w_source = gtk_drag_get_source_widget (context);
n_source = gtk_notebook_page_num_by_label (wbcg->notebook, w_source);
......@@ -796,8 +797,6 @@ cb_sheet_label_drag_begin (GtkWidget *widget, GdkDragContext *context,
g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));
g_message ("cb_sheet_label_drag_begin");
/* Create the arrow. */
arrow = gtk_window_new (GTK_WINDOW_POPUP);
gtk_widget_realize (arrow);
......@@ -828,6 +827,18 @@ cb_sheet_label_drag_end (GtkWidget *widget, GdkDragContext *context,
g_object_set_data (G_OBJECT (widget), "arrow", NULL);
}
static void
cb_sheet_label_drag_leave (GtkWidget *widget, GdkDragContext *context,
guint time, WorkbookControlGUI *wbcg)
{
GtkWidget *w_source, *arrow;
/* Hide the arrow. */
w_source = gtk_drag_get_source_widget (context);
arrow = g_object_get_data (G_OBJECT (w_source), "arrow");
gtk_widget_hide (arrow);