dialog-define-names.c 6.41 KB
Newer Older
Michael Meeks's avatar
Michael Meeks committed
1 2
/**
 * dialog-summary.c:  Implements the summary info stuff
Miguel de Icaza's avatar
Miguel de Icaza committed
3 4
 *
 * Author:
Michael Meeks's avatar
Michael Meeks committed
5
 *        Michael Meeks <michael@imaginator.com>
Miguel de Icaza's avatar
Miguel de Icaza committed
6
 *
Michael Meeks's avatar
Michael Meeks committed
7
 **/
Miguel de Icaza's avatar
Miguel de Icaza committed
8 9
#include <config.h>
#include <gnome.h>
Michael Meeks's avatar
Michael Meeks committed
10
#include <glade/glade.h>
Miguel de Icaza's avatar
Miguel de Icaza committed
11
#include "dialogs.h"
12
#include "expr.h"
13
#include "expr-name.h"
14
#include "workbook.h"
15
#include "gnumeric-util.h"
Miguel de Icaza's avatar
Miguel de Icaza committed
16

17 18
#define LIST_KEY "name_list_data"

Michael Meeks's avatar
Michael Meeks committed
19 20 21
typedef struct {
	GladeXML  *gui;
	GtkWidget *dia;
22 23 24
	GtkList   *list;
	GtkEntry  *name;
	GtkEntry  *value;
Michael Meeks's avatar
Michael Meeks committed
25 26
	GList     *expr_names;
	gint       selected;
Jody Goldberg's avatar
Jody Goldberg committed
27 28

	Workbook  *wb;
Michael Meeks's avatar
Michael Meeks committed
29 30
} state_t;

31 32 33 34
static void
update_edit (state_t *state)
{
	gint          i = state->selected;
35
	NamedExpression     *expr_name;
36 37
	Sheet        *sheet;
	char         *txt;
38

39
	sheet = state->wb->current_sheet;
40 41 42 43 44 45 46
	g_return_if_fail (sheet != NULL);

	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, "");
47

48 49 50 51 52
	txt = expr_name_value (expr_name);
	gtk_entry_set_text (state->value, txt);
	g_free (txt);
}

Michael Meeks's avatar
Michael Meeks committed
53 54 55
static void
select_name (GtkWidget *w, state_t *state)
{
56 57 58
	guint     i    = 0;
	GList    *sel  = GTK_LIST(w)->selection;
	GList    *p    = state->expr_names;
59
	NamedExpression *name;
60 61 62 63 64 65 66 67

	if (sel == NULL)
		return;

	g_return_if_fail (sel->data != NULL);

	name = gtk_object_get_data (GTK_OBJECT (sel->data), LIST_KEY);

Michael Meeks's avatar
Michael Meeks committed
68
	while (p) {
69
		if (p->data == name) {
Michael Meeks's avatar
Michael Meeks committed
70
			state->selected = i;
71
			update_edit (state);
Michael Meeks's avatar
Michael Meeks committed
72 73 74 75 76 77 78 79 80 81 82
			return;
		}
		i++;
		p = g_list_next (p);
	}
}

static void
fill_list (state_t *state)
{
	GList *names;
Jody Goldberg's avatar
Jody Goldberg committed
83
	GtkContainer *list;
Michael Meeks's avatar
Michael Meeks committed
84

85 86
	g_return_if_fail (state != NULL);
	g_return_if_fail (state->list != NULL);
Michael Meeks's avatar
Michael Meeks committed
87

Jody Goldberg's avatar
Jody Goldberg committed
88 89 90
	list = GTK_CONTAINER (state->list);
	g_return_if_fail (list != NULL);

91
	state->selected   = -1;
Michael Meeks's avatar
Michael Meeks committed
92

93
	/* FIXME: scoping issues here */
Jody Goldberg's avatar
Jody Goldberg committed
94
	names = state->expr_names = expr_name_list (state->wb, NULL, FALSE);
95

Jody Goldberg's avatar
Jody Goldberg committed
96
	for (; names != NULL ; names = g_list_next (names)) {
97
		NamedExpression *expr_name = names->data;
Michael Meeks's avatar
Michael Meeks committed
98
		GtkWidget *li = gtk_list_item_new_with_label (expr_name->name->str);
99
		gtk_object_set_data (GTK_OBJECT (li), LIST_KEY, expr_name);
Jody Goldberg's avatar
Jody Goldberg committed
100
		gtk_container_add (list, li);
Michael Meeks's avatar
Michael Meeks committed
101
	}
Jody Goldberg's avatar
Jody Goldberg committed
102
	gtk_widget_show_all (GTK_WIDGET (state->list));
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
}

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);
Michael Meeks's avatar
Michael Meeks committed
121 122 123 124 125
}

static void
remove_name (GtkWidget *widget, state_t *state)
{
Jody Goldberg's avatar
Jody Goldberg committed
126
	gint i;
127 128 129 130 131
	g_return_if_fail (state != NULL);
	g_return_if_fail (widget != NULL);

	i = state->selected;
	if (i >= 0) {
Jody Goldberg's avatar
Jody Goldberg committed
132
		GList *na = g_list_nth (state->expr_names, i);
133

Jody Goldberg's avatar
Jody Goldberg committed
134 135
		g_return_if_fail (na != NULL);
		g_return_if_fail (na->data != NULL);
136 137 138 139 140 141

		expr_name_remove (na->data);
		state->expr_names = g_list_remove (state->expr_names, na->data);

		gtk_entry_set_text (state->name, "");
		gtk_entry_set_text (state->value, "");
Jody Goldberg's avatar
Jody Goldberg committed
142
	}
143 144 145 146 147
}

static gboolean
grab_text_ok (state_t *state, gboolean update_list)
{
148
	NamedExpression     *expr_name;
Jody Goldberg's avatar
Jody Goldberg committed
149 150 151
	ExprTree     *expr;
	gchar        *name, *value, *error;
	ParsePos      pos, *pp;
152 153 154 155 156 157 158 159

	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;
160

Jody Goldberg's avatar
Jody Goldberg committed
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
	/* FIXME : Need to be able to control scope.
	 *        1) sheet
	 *        2) workbook
	 *        3) global
	 *
	 * default to workbook for now.
	 */
	pp = parse_pos_init (&pos, state->wb, NULL, 0, 0);

	expr_name = expr_name_lookup (pp, name);

	expr = expr_parse_string (value, pp, NULL, &error);

	/* If name already exists replace the its content */
	if (expr_name) {
		if (!expr_name->builtin) {
			expr_tree_unref (expr_name->t.expr_tree);
			expr_name->t.expr_tree = expr;
		} else
			gnumeric_notice (state->wb, GNOME_MESSAGE_BOX_ERROR,
					 _("You can not redefine a builtin name."));
	} else
		expr_name = expr_name_add (state->wb, NULL, name, expr, &error);
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229

	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);
Michael Meeks's avatar
Michael Meeks committed
230 231
}

Miguel de Icaza's avatar
Miguel de Icaza committed
232 233 234
void
dialog_define_names (Workbook *wb)
{
Michael Meeks's avatar
Michael Meeks committed
235 236 237 238 239 240 241
	gint       v;
	state_t    state;
	GtkWidget *w;

	g_return_if_fail (wb != NULL);

	state.wb  = wb;
242 243 244 245 246
	state.gui = gnumeric_glade_xml_new (workbook_command_context_gui (wb),
				      "names.glade");
        if (state.gui == NULL)
                return;

247 248 249 250 251
	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;
Michael Meeks's avatar
Michael Meeks committed
252

253 254 255
	w = glade_xml_get_widget (state.gui, "ok");
	gtk_signal_connect (GTK_OBJECT (w), "clicked",
			    GTK_SIGNAL_FUNC (ok_name), &state);
Michael Meeks's avatar
Michael Meeks committed
256

257 258 259 260 261 262 263
	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);
264

Michael Meeks's avatar
Michael Meeks committed
265 266 267
	w = glade_xml_get_widget (state.gui, "delete");
	gtk_signal_connect (GTK_OBJECT (w), "clicked",
			    GTK_SIGNAL_FUNC (remove_name), &state);
268

Michael Meeks's avatar
Michael Meeks committed
269 270 271 272 273
	state.dia = glade_xml_get_widget (state.gui, "NamesDialog");
	if (!state.dia) {
		printf ("Corrupt file names.glade\n");
		return;
	}
274
 	gnome_dialog_editable_enters(GNOME_DIALOG(state.dia),
Jody Goldberg's avatar
Jody Goldberg committed
275
				     GTK_EDITABLE(state.name));
276
 	gnome_dialog_editable_enters(GNOME_DIALOG(state.dia),
Jody Goldberg's avatar
Jody Goldberg committed
277
				     GTK_EDITABLE(state.value));
Michael Meeks's avatar
Michael Meeks committed
278

279 280 281 282
	fill_list (&state);

	gtk_signal_connect (GTK_OBJECT (state.list), "selection_changed",
			    GTK_SIGNAL_FUNC (select_name), &state);
Miguel de Icaza's avatar
Miguel de Icaza committed
283

284
	v = gnumeric_dialog_run (wb, GNOME_DIALOG (state.dia));
285

286 287 288 289
	if (v == -1)
		destroy_state (&state);
	else
		destroy_dialog (&state);
Michael Meeks's avatar
Michael Meeks committed
290 291

	gtk_object_unref (GTK_OBJECT (state.gui));
Miguel de Icaza's avatar
Miguel de Icaza committed
292
}