dialog-define-names.c 7.1 KB
Newer Older
Jody Goldberg's avatar
Jody Goldberg committed
1 2 3 4
/* vim: set sw=8: */

/*
 * dialog-define-name.c: Edit named regions.
Miguel de Icaza's avatar
Miguel de Icaza committed
5 6
 *
 * Author:
Jody Goldberg's avatar
Jody Goldberg committed
7 8 9
 * 	Jody Goldberg <jgoldberg@home.com> 
 *	Michael Meeks <michael@imaginator.com>
 */
Miguel de Icaza's avatar
Miguel de Icaza committed
10 11
#include <config.h>
#include <gnome.h>
Michael Meeks's avatar
Michael Meeks committed
12
#include <glade/glade.h>
Miguel de Icaza's avatar
Miguel de Icaza committed
13
#include "dialogs.h"
14
#include "expr.h"
15
#include "expr-name.h"
16
#include "workbook.h"
17
#include "workbook-edit.h"
18
#include "gnumeric-util.h"
Miguel de Icaza's avatar
Miguel de Icaza committed
19

20 21
#define LIST_KEY "name_list_data"

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

31 32 33 34 35
	GtkWidget *ok_button;
	GtkWidget *add_button;
	GtkWidget *close_button;
	GtkWidget *delete_button;

Jody Goldberg's avatar
Jody Goldberg committed
36
	Workbook  *wb;
37
} NameGuruState;
Michael Meeks's avatar
Michael Meeks committed
38

39
static void
Jody Goldberg's avatar
Jody Goldberg committed
40
cb_name_guru_select_name (GtkWidget *list, NameGuruState *state)
41
{
Jody Goldberg's avatar
Jody Goldberg committed
42 43 44
	NamedExpression *expr_name;
	GList *sel = GTK_LIST(list)->selection;
	char *txt;
45 46 47 48 49 50

	if (sel == NULL)
		return;

	g_return_if_fail (sel->data != NULL);

Jody Goldberg's avatar
Jody Goldberg committed
51
	expr_name = gtk_object_get_data (GTK_OBJECT (sel->data), LIST_KEY);
52

Jody Goldberg's avatar
Jody Goldberg committed
53 54 55 56 57 58 59 60 61 62
	g_return_if_fail (expr_name->name != NULL);
	g_return_if_fail (expr_name->name->str != NULL);

	/* Display the name */
	gtk_entry_set_text (state->name, expr_name->name->str);

	/* Display the value */
	txt = expr_name_value (expr_name);
	gtk_entry_set_text (state->value, txt);
	g_free (txt);
Michael Meeks's avatar
Michael Meeks committed
63 64 65
}

static void
Jody Goldberg's avatar
Jody Goldberg committed
66
name_guru_populate_list (NameGuruState *state)
Michael Meeks's avatar
Michael Meeks committed
67 68
{
	GList *names;
Jody Goldberg's avatar
Jody Goldberg committed
69
	GtkContainer *list;
Michael Meeks's avatar
Michael Meeks committed
70

71 72
	g_return_if_fail (state != NULL);
	g_return_if_fail (state->list != NULL);
Michael Meeks's avatar
Michael Meeks committed
73

74
	state->selected   = -1;
75 76
	if (state->expr_names != NULL)
		g_list_free (state->expr_names);
Michael Meeks's avatar
Michael Meeks committed
77

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

81
	list = GTK_CONTAINER (state->list);
Jody Goldberg's avatar
Jody Goldberg committed
82
	for (; names != NULL ; names = g_list_next (names)) {
83
		NamedExpression *expr_name = names->data;
Michael Meeks's avatar
Michael Meeks committed
84
		GtkWidget *li = gtk_list_item_new_with_label (expr_name->name->str);
85
		gtk_object_set_data (GTK_OBJECT (li), LIST_KEY, expr_name);
Jody Goldberg's avatar
Jody Goldberg committed
86
		gtk_container_add (list, li);
Michael Meeks's avatar
Michael Meeks committed
87
	}
Jody Goldberg's avatar
Jody Goldberg committed
88
	gtk_widget_show_all (GTK_WIDGET (state->list));
89 90 91
}

static void
92
cb_name_guru_remove (GtkWidget *ignored, NameGuruState *state)
Michael Meeks's avatar
Michael Meeks committed
93
{
Jody Goldberg's avatar
Jody Goldberg committed
94
	gint i;
95 96 97 98
	g_return_if_fail (state != NULL);

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

Jody Goldberg's avatar
Jody Goldberg committed
101 102
		g_return_if_fail (na != NULL);
		g_return_if_fail (na->data != NULL);
103 104 105 106 107 108

		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
109
	}
110 111 112
}

static gboolean
113
cb_name_guru_add (NameGuruState *state)
114
{
115
	NamedExpression     *expr_name;
Jody Goldberg's avatar
Jody Goldberg committed
116 117 118
	ExprTree     *expr;
	gchar        *name, *value, *error;
	ParsePos      pos, *pp;
119 120 121 122 123 124 125 126

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

Jody Goldberg's avatar
Jody Goldberg committed
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
	/* 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);
151 152 153 154 155 156 157 158 159

	if (expr_name == NULL) {
		if (error)
			gnumeric_notice (state->wb, GNOME_MESSAGE_BOX_ERROR, error);
		else
			g_warning ("serious name error");
		return FALSE;
	}

160
	gtk_list_clear_items (state->list, 0, -1);
Jody Goldberg's avatar
Jody Goldberg committed
161
	name_guru_populate_list (state);
162 163 164 165

	return TRUE;
}

Jody Goldberg's avatar
Jody Goldberg committed
166 167 168 169 170 171 172 173 174 175
static void
cb_name_guru_value_focus (GtkWidget *w, GdkEventFocus *ev, NameGuruState *state)
{
	if (w == state->value) {
		workbook_set_entry (state->wb, state->value);
		workbook_edit_select_absolute (state->wb);
	} else
		workbook_set_entry (state->wb, NULL);
}

176
static void
177
cb_name_guru_clicked (GtkWidget *button, NameGuruState *state)
178
{
179 180 181
	if (state->dialog == NULL)
		return;

Jody Goldberg's avatar
Jody Goldberg committed
182 183
	workbook_set_entry (state->wb, NULL);

184
	if (button == state->delete_button) {
185
		cb_name_guru_remove (NULL, state);
186 187 188 189
		return;
	}

	if (button == state->add_button || button == state->ok_button)
190
		cb_name_guru_add (state);
191 192 193

	if (button == state->close_button || button == state->ok_button)
		gtk_widget_destroy (state->dialog);
194 195
}

196 197
static GtkWidget *
name_guru_init_button (NameGuruState *state, char const *name)
198
{
199 200 201 202 203
	GtkWidget *tmp = glade_xml_get_widget (state->gui, name);
	gtk_signal_connect (GTK_OBJECT (tmp), "clicked",
			    GTK_SIGNAL_FUNC (cb_name_guru_clicked),
			    state);
	return tmp;
204 205
}

206 207
static gboolean
cb_name_guru_destroy (GtkObject *w, NameGuruState *state)
208
{
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
	g_return_val_if_fail (w != NULL, FALSE);
	g_return_val_if_fail (state != NULL, FALSE);

	workbook_edit_detach_guru (state->wb);

	if (state->gui != NULL) {
		gtk_object_unref (GTK_OBJECT (state->gui));
		state->gui = NULL;
	}

	/* Handle window manger closing the dialog.
	 * This will be ignored if we are being destroyed differently.
	 */
	workbook_finish_editing (state->wb, FALSE);

	state->dialog = NULL;

	g_free (state);
	return FALSE;
228 229
}

230 231
static gboolean
name_guru_init (NameGuruState *state)
232
{
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
	state->gui = gnumeric_glade_xml_new (workbook_command_context_gui (state->wb),
					     "names.glade");
        if (state->gui == NULL)
                return TRUE;

	state->dialog = glade_xml_get_widget (state->gui, "NamesDialog");
	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;

	state->ok_button = name_guru_init_button (state, "ok_button");
	state->close_button = name_guru_init_button (state, "close_button");
	state->add_button = name_guru_init_button (state, "add_button");
	state->delete_button = name_guru_init_button (state, "delete_button");

	gtk_signal_connect (GTK_OBJECT (state->list), "selection_changed",
251
			    GTK_SIGNAL_FUNC (cb_name_guru_select_name), state);
Jody Goldberg's avatar
Jody Goldberg committed
252 253 254 255
	gtk_signal_connect (GTK_OBJECT (state->name), "focus-in-event",
			    GTK_SIGNAL_FUNC (cb_name_guru_value_focus), state);
	gtk_signal_connect (GTK_OBJECT (state->value), "focus-in-event",
			    GTK_SIGNAL_FUNC (cb_name_guru_value_focus), state);
256
	gtk_signal_connect (GTK_OBJECT (state->dialog), "destroy",
Jody Goldberg's avatar
Jody Goldberg committed
257
			    GTK_SIGNAL_FUNC (cb_name_guru_destroy), state);
258 259 260

	gtk_window_set_transient_for (GTK_WINDOW (state->dialog),
				      GTK_WINDOW (state->wb->toplevel));
Jody Goldberg's avatar
Jody Goldberg committed
261 262 263 264
 	gnumeric_editable_enters (GTK_WINDOW (state->dialog),
				  GTK_EDITABLE(state->name));
 	gnumeric_editable_enters (GTK_WINDOW (state->dialog),
				  GTK_EDITABLE (state->value));
265 266 267 268

	workbook_edit_attach_guru (state->wb, state->dialog);

	return FALSE;
Michael Meeks's avatar
Michael Meeks committed
269 270
}

Miguel de Icaza's avatar
Miguel de Icaza committed
271 272 273
void
dialog_define_names (Workbook *wb)
{
274
	NameGuruState *state;
Michael Meeks's avatar
Michael Meeks committed
275 276 277

	g_return_if_fail (wb != NULL);

278 279 280 281
	state = g_new (NameGuruState, 1);
	state->wb  = wb;
	if (name_guru_init (state)) {
		g_free (state);
Michael Meeks's avatar
Michael Meeks committed
282 283 284
		return;
	}

Jody Goldberg's avatar
Jody Goldberg committed
285
	name_guru_populate_list (state);
286
	gtk_widget_show (state->dialog);
Miguel de Icaza's avatar
Miguel de Icaza committed
287
}