Commit 6fc402c5 authored by Michael Meeks's avatar Michael Meeks

Fixed sillyness with auto-expressions properly,

Improved parsing structure, and handling of in-sheet references,
Finished 'Names' dialog,
Preliminary Names XML-I/O
Added check against circular name definitions a=b, b=a :-)
parent c034bc44
1999-07-25 Michael Meeks <michael@edenproject.org>
* src/expr.c (expr_tree_invalidate_references): Debugging that
needs cleaning to new PP stuff #if-def'd out.
(expr_tree_fixup_references): ditto.
* src/xml-io.c (xml_write_names, xml_read_names): Implemented
(xml_workbook_write, xml_workbook_read): Hooks added, but reading
disabled: something dodgy somewhere.
* src/sheet.c (sheet_lookup_by_name): Fixed to use simply a
Workbook pointer.
* src/workbook.c (workbook_set_auto_expr): Fix old hack using
new PP stuff.
* src/sheet.c (sheet_fill_selection_with): Updated to new PP code.
* src/parser.y (gnumeric_expr_parser): Updated to new PP code,
removed redundant and nasty _unsafe_expr_parser hack. Essentialy
nothing new, but removes daft parser_sheet and replaces with
parser_workbook, leaving sheet stuff to the evaluation stage.
* src/dialog-define-names.c: Major fixups, killed obscure bug
cause by freeing a copy of a list I passed to gtk_list_append_items.
* src/expr.c (expr_parse_string, do_expr_decode_tree):
(expr_decode_tree): Updated to new
* src/expr-name.c (expr_name_create): Added for convenience.
(expr_name_value): Updated to new PP scheme
* src/cell.c (cell_set_formula, cell_get_text, cell_get_content):
Update to new ParsePosition scheme.
* src/expr.c (parse_pos_init, parse_pos_cell): Created.
* src/expr.h: Add ParsePosition & prototpes
1999-07-25 Michael Meeks <michael@edenproject.org>
* src/dialog-define-names.c (update_edit): use expr_name_value.
(grab_text_ok): Update to use new functions.
* src/expr-name.c (expr_name_value): Added.
(expr_name_create): Convenience function
* src/xml-io.c (xml_workbook_write): Added names writing.
1999-07-24 Michael Meeks <michael@edenproject.org>
* src/expr-name.c (expr_name_add): Add check for circular
references in (name_refer_circular): created.
(add_real): More paranoia.
1999-07-23 Michael Meeks <michael@edenproject.org>
* src/expr-name.c (expr_name_list): Expand.
(expr_name_remove): Serious bug freeing names.
(expr_name_lookup): precondition.
(expr_name_remove): more sanity checks.
* src/dialog-define-names.c (fill_list): Append instead of inserting
items. use "select" signal, hand the correct pointer on.
Implemented guts, fixed lots of bugs.
1999-07-25 Karsten Weiss <karsten@addx.au.s.shuttle.de>
* src/print.glade.h: Fixed three typos.
......
1999-07-25 Michael Meeks <michael@edenproject.org>
* src/expr.c (expr_tree_invalidate_references): Debugging that
needs cleaning to new PP stuff #if-def'd out.
(expr_tree_fixup_references): ditto.
* src/xml-io.c (xml_write_names, xml_read_names): Implemented
(xml_workbook_write, xml_workbook_read): Hooks added, but reading
disabled: something dodgy somewhere.
* src/sheet.c (sheet_lookup_by_name): Fixed to use simply a
Workbook pointer.
* src/workbook.c (workbook_set_auto_expr): Fix old hack using
new PP stuff.
* src/sheet.c (sheet_fill_selection_with): Updated to new PP code.
* src/parser.y (gnumeric_expr_parser): Updated to new PP code,
removed redundant and nasty _unsafe_expr_parser hack. Essentialy
nothing new, but removes daft parser_sheet and replaces with
parser_workbook, leaving sheet stuff to the evaluation stage.
* src/dialog-define-names.c: Major fixups, killed obscure bug
cause by freeing a copy of a list I passed to gtk_list_append_items.
* src/expr.c (expr_parse_string, do_expr_decode_tree):
(expr_decode_tree): Updated to new
* src/expr-name.c (expr_name_create): Added for convenience.
(expr_name_value): Updated to new PP scheme
* src/cell.c (cell_set_formula, cell_get_text, cell_get_content):
Update to new ParsePosition scheme.
* src/expr.c (parse_pos_init, parse_pos_cell): Created.
* src/expr.h: Add ParsePosition & prototpes
1999-07-25 Michael Meeks <michael@edenproject.org>
* src/dialog-define-names.c (update_edit): use expr_name_value.
(grab_text_ok): Update to use new functions.
* src/expr-name.c (expr_name_value): Added.
(expr_name_create): Convenience function
* src/xml-io.c (xml_workbook_write): Added names writing.
1999-07-24 Michael Meeks <michael@edenproject.org>
* src/expr-name.c (expr_name_add): Add check for circular
references in (name_refer_circular): created.
(add_real): More paranoia.
1999-07-23 Michael Meeks <michael@edenproject.org>
* src/expr-name.c (expr_name_list): Expand.
(expr_name_remove): Serious bug freeing names.
(expr_name_lookup): precondition.
(expr_name_remove): more sanity checks.
* src/dialog-define-names.c (fill_list): Append instead of inserting
items. use "select" signal, hand the correct pointer on.
Implemented guts, fixed lots of bugs.
1999-07-25 Karsten Weiss <karsten@addx.au.s.shuttle.de>
* src/print.glade.h: Fixed three typos.
......
......@@ -48,14 +48,14 @@ cell_set_formula (Cell *cell, const char *text)
ExprTree *new_expr;
char *error_msg = _("ERROR");
const char *desired_format = NULL;
EvalPosition fp;
ParsePosition pp;
g_return_if_fail (cell != NULL);
g_return_if_fail (text != NULL);
cell_modified (cell);
new_expr = expr_parse_string (&text [1],
eval_pos_cell (&fp, cell),
parse_pos_cell (&pp, cell),
&desired_format,
&error_msg);
if (new_expr == NULL){
......@@ -1471,14 +1471,15 @@ char *
cell_get_text (Cell *cell)
{
char *str;
EvalPosition fp;
ParsePosition pp;
g_return_val_if_fail (cell != NULL, NULL);
if (cell->parsed_node && cell->sheet){
char *func, *ret;
func = expr_decode_tree (cell->parsed_node, eval_pos_cell (&fp, cell));
func = expr_decode_tree (cell->parsed_node,
parse_pos_cell (&pp, cell));
ret = g_strconcat ("=", func, NULL);
g_free (func);
......@@ -1511,14 +1512,15 @@ char *
cell_get_content (Cell *cell)
{
char *str;
EvalPosition fp;
ParsePosition pp;
g_return_val_if_fail (cell != NULL, NULL);
if (cell->parsed_node){
char *func, *ret;
func = expr_decode_tree (cell->parsed_node, eval_pos_cell (&fp, cell));
func = expr_decode_tree (cell->parsed_node,
parse_pos_cell (&pp, cell));
ret = g_strconcat ("=", func, NULL);
g_free (func);
......
......@@ -13,26 +13,63 @@
#include "gnumeric-sheet.h"
#include "dialogs.h"
#define LIST_KEY "name_list_data"
typedef struct {
Workbook *wb;
GladeXML *gui;
GtkWidget *dia;
GtkWidget *list;
GtkWidget *name;
GtkWidget *value;
GtkList *list;
GtkEntry *name;
GtkEntry *value;
GList *expr_names;
GList *list_items;
gint selected;
} state_t;
static void
update_edit (state_t *state)
{
gint i = state->selected;
ExprName *expr_name;
Sheet *sheet;
EvalPosition ep;
char *txt;
sheet = workbook_get_current_sheet (state->wb);
g_return_if_fail (sheet != NULL);
eval_pos_init (&ep, sheet, 0, 0);
expr_name = g_list_nth (state->expr_names, i)->data;
if (expr_name->name && expr_name->name->str)
gtk_entry_set_text (state->name, expr_name->name->str);
else
gtk_entry_set_text (state->name, "");
txt = expr_name_value (expr_name);
gtk_entry_set_text (state->value, txt);
g_free (txt);
}
static void
select_name (GtkWidget *w, state_t *state)
{
guint i = 0;
GList *p = state->list_items;
guint i = 0;
GList *sel = GTK_LIST(w)->selection;
GList *p = state->expr_names;
ExprName *name;
if (sel == NULL)
return;
g_return_if_fail (sel->data != NULL);
name = gtk_object_get_data (GTK_OBJECT (sel->data), LIST_KEY);
while (p) {
if (p->data == w) {
if (p->data == name) {
state->selected = i;
update_edit (state);
return;
}
i++;
......@@ -44,31 +81,142 @@ static void
fill_list (state_t *state)
{
GList *names;
GList *items = NULL;
g_return_if_fail (state);
g_return_if_fail (state->list);
g_return_if_fail (state != NULL);
g_return_if_fail (state->list != NULL);
state->list_items = NULL;
state->selected = 0;
state->selected = -1;
state->expr_names = names = expr_name_list (state->wb, FALSE);
while (names) {
ExprName *expr_name = names->data;
GtkWidget *li = gtk_list_item_new_with_label (expr_name->name->str);
gtk_signal_connect (GTK_OBJECT (li), "toggle-focus-row",
GTK_SIGNAL_FUNC (select_name), &state);
state->list_items = g_list_append (state->list_items, li);
gtk_object_set_data (GTK_OBJECT (li), LIST_KEY, expr_name);
gtk_widget_show (GTK_WIDGET (li));
items = g_list_append (items, li);
names = g_list_next (names);
}
gtk_list_insert_items (GTK_LIST (state->list), state->list_items, 0);
gtk_list_append_items (state->list, items);
}
static void
destroy_state (state_t *state)
{
if (state->expr_names)
g_list_free (state->expr_names);
state->expr_names = NULL;
state->selected = -1;
}
static void
empty_list (state_t *state)
{
if (state->list)
gtk_list_clear_items (state->list, 0, -1);
state->list = NULL;
destroy_state (state);
}
static void
remove_name (GtkWidget *widget, state_t *state)
{
/* gint i;
g_return_if_fail (state != NULL);
g_return_if_fail (widget != NULL);
i = state->selected;
if (i >= 0) {
GList *na = g_list_nth (state->expr_names, i);
GList *it = g_list_nth (state->list_items, i);
GList *l;
g_return_if_fail (it != NULL && na != NULL);
g_return_if_fail (it->data != NULL && na->data != NULL);
expr_name_remove (na->data);
state->expr_names = g_list_remove (state->expr_names, na->data);
l = g_list_append (NULL, it->data);
gtk_list_remove_items (state->list, l);
g_list_free (l);
state->list_items = g_list_remove (state->list_items, it->data);
gtk_entry_set_text (state->name, "");
gtk_entry_set_text (state->value, "");
}*/
g_warning ("Unimplemented, need to sweep sheets to check for usage");
}
static gboolean
grab_text_ok (state_t *state, gboolean update_list)
{
gchar *name;
gchar *value;
ExprName *expr_name;
char *error;
g_return_val_if_fail (state != NULL, FALSE);
value = gtk_entry_get_text (state->value);
name = gtk_entry_get_text (state->name);
if (!name || (name[0] == '\0'))
return TRUE;
expr_name = expr_name_lookup (state->wb, name);
if (expr_name)
expr_name_remove (expr_name);
expr_name = expr_name_create (state->wb, name,
value, &error);
if (expr_name == NULL) {
if (error)
gnumeric_notice (state->wb, GNOME_MESSAGE_BOX_ERROR, error);
else
g_warning ("serious name error");
return FALSE;
}
if (update_list) {
empty_list (state);
fill_list (state);
}
return TRUE;
}
static void
destroy_dialog (state_t *state)
{
if (state->dia)
gnome_dialog_close (GNOME_DIALOG (state->dia));
state->dia = NULL;
state->list = NULL;
state->name = NULL;
state->value = NULL;
}
static void
add_name (GtkWidget *widget, state_t *state)
{
grab_text_ok (state, TRUE);
}
static void
close_name (GtkWidget *widget, state_t *state)
{
destroy_state (state);
destroy_dialog (state);
}
static void
ok_name (GtkWidget *widget, state_t *state)
{
if (grab_text_ok (state, FALSE))
close_name (widget, state);
}
void
......@@ -87,12 +235,24 @@ dialog_define_names (Workbook *wb)
return;
}
state.name = glade_xml_get_widget (state.gui, "name");
state.value = glade_xml_get_widget (state.gui, "value");
state.list = glade_xml_get_widget (state.gui, "name_list");
state.name = GTK_ENTRY (glade_xml_get_widget (state.gui, "name"));
state.value = GTK_ENTRY (glade_xml_get_widget (state.gui, "value"));
state.list = GTK_LIST (glade_xml_get_widget (state.gui, "name_list"));
state.expr_names = NULL;
state.selected = -1;
fill_list (&state);
w = glade_xml_get_widget (state.gui, "ok");
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (ok_name), &state);
w = glade_xml_get_widget (state.gui, "close");
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (close_name), &state);
w = glade_xml_get_widget (state.gui, "add");
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (add_name), &state);
w = glade_xml_get_widget (state.gui, "delete");
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (remove_name), &state);
......@@ -103,14 +263,17 @@ dialog_define_names (Workbook *wb)
return;
}
v = gnome_dialog_run (GNOME_DIALOG (state.dia));
if (v == 0) { /* OK */
}
fill_list (&state);
gtk_signal_connect (GTK_OBJECT (state.list), "selection_changed",
GTK_SIGNAL_FUNC (select_name), &state);
if (v != -1)
gtk_object_destroy (GTK_OBJECT (state.dia));
v = gnome_dialog_run (GNOME_DIALOG (state.dia));
if (v == -1)
destroy_state (&state);
else
destroy_dialog (&state);
gtk_object_unref (GTK_OBJECT (state.gui));
}
......@@ -13,26 +13,63 @@
#include "gnumeric-sheet.h"
#include "dialogs.h"
#define LIST_KEY "name_list_data"
typedef struct {
Workbook *wb;
GladeXML *gui;
GtkWidget *dia;
GtkWidget *list;
GtkWidget *name;
GtkWidget *value;
GtkList *list;
GtkEntry *name;
GtkEntry *value;
GList *expr_names;
GList *list_items;
gint selected;
} state_t;
static void
update_edit (state_t *state)
{
gint i = state->selected;
ExprName *expr_name;
Sheet *sheet;
EvalPosition ep;
char *txt;
sheet = workbook_get_current_sheet (state->wb);
g_return_if_fail (sheet != NULL);
eval_pos_init (&ep, sheet, 0, 0);
expr_name = g_list_nth (state->expr_names, i)->data;
if (expr_name->name && expr_name->name->str)
gtk_entry_set_text (state->name, expr_name->name->str);
else
gtk_entry_set_text (state->name, "");
txt = expr_name_value (expr_name);
gtk_entry_set_text (state->value, txt);
g_free (txt);
}
static void
select_name (GtkWidget *w, state_t *state)
{
guint i = 0;
GList *p = state->list_items;
guint i = 0;
GList *sel = GTK_LIST(w)->selection;
GList *p = state->expr_names;
ExprName *name;
if (sel == NULL)
return;
g_return_if_fail (sel->data != NULL);
name = gtk_object_get_data (GTK_OBJECT (sel->data), LIST_KEY);
while (p) {
if (p->data == w) {
if (p->data == name) {
state->selected = i;
update_edit (state);
return;
}
i++;
......@@ -44,31 +81,142 @@ static void
fill_list (state_t *state)
{
GList *names;
GList *items = NULL;
g_return_if_fail (state);
g_return_if_fail (state->list);
g_return_if_fail (state != NULL);
g_return_if_fail (state->list != NULL);
state->list_items = NULL;
state->selected = 0;
state->selected = -1;
state->expr_names = names = expr_name_list (state->wb, FALSE);
while (names) {
ExprName *expr_name = names->data;
GtkWidget *li = gtk_list_item_new_with_label (expr_name->name->str);
gtk_signal_connect (GTK_OBJECT (li), "toggle-focus-row",
GTK_SIGNAL_FUNC (select_name), &state);
state->list_items = g_list_append (state->list_items, li);
gtk_object_set_data (GTK_OBJECT (li), LIST_KEY, expr_name);
gtk_widget_show (GTK_WIDGET (li));
items = g_list_append (items, li);
names = g_list_next (names);
}
gtk_list_insert_items (GTK_LIST (state->list), state->list_items, 0);
gtk_list_append_items (state->list, items);
}
static void
destroy_state (state_t *state)
{
if (state->expr_names)
g_list_free (state->expr_names);
state->expr_names = NULL;
state->selected = -1;
}
static void
empty_list (state_t *state)
{
if (state->list)
gtk_list_clear_items (state->list, 0, -1);
state->list = NULL;
destroy_state (state);
}
static void
remove_name (GtkWidget *widget, state_t *state)
{
/* gint i;
g_return_if_fail (state != NULL);
g_return_if_fail (widget != NULL);
i = state->selected;
if (i >= 0) {
GList *na = g_list_nth (state->expr_names, i);
GList *it = g_list_nth (state->list_items, i);
GList *l;
g_return_if_fail (it != NULL && na != NULL);
g_return_if_fail (it->data != NULL && na->data != NULL);
expr_name_remove (na->data);
state->expr_names = g_list_remove (state->expr_names, na->data);
l = g_list_append (NULL, it->data);
gtk_list_remove_items (state->list, l);
g_list_free (l);
state->list_items = g_list_remove (state->list_items, it->data);
gtk_entry_set_text (state->name, "");
gtk_entry_set_text (state->value, "");
}*/
g_warning ("Unimplemented, need to sweep sheets to check for usage");
}
static gboolean
grab_text_ok (state_t *state, gboolean update_list)
{
gchar *name;
gchar *value;
ExprName *expr_name;
char *error;