dialog-function-select.c 5.28 KB
Newer Older
Michael Meeks's avatar
Michael Meeks committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * dialog-function-wizard.c:  Implements the function wizard
 *
 * Author:
 *  Michael Meeks <michael@imaginator.com>
 *
 */
#include <config.h>
#include <gnome.h>
#include "gnumeric.h"
#include "gnumeric-util.h"
#include "gnumeric-sheet.h"
#include "dialogs.h"
#include "cell.h"
#include "expr.h"
#include "func.h"

typedef struct {
19 20 21 22 23 24 25 26 27 28 29 30
	GtkWidget *widget, *dlg;
	GtkBox *dialog_box;
	Workbook *wb;
	GPtrArray *cats;
	GtkCList *function_list;
	GtkCList *cl_funcs;
	GtkCList *cl_cats;
	int selected_func;  /* An Entry */
	int selected_cat;   /* An Array */
} SelectorState;

static void function_select_create (SelectorState *state);
Michael Meeks's avatar
Michael Meeks committed
31

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
static void
function_categories_fill (SelectorState *selector_state)
{
	GtkCList *cl = selector_state->cl_cats;
	int lp;
	
	for (lp = 0; lp < selector_state->cats->len; lp++){
		FunctionCategory *fc;
		gchar *cols [1];
		
		fc = g_ptr_array_index (selector_state->cats, lp);
		cols[0] = fc->name;
		gtk_clist_append (cl, cols);

		if (lp == selector_state->selected_cat)
			gtk_clist_select_row (cl, lp, 0);
	}
Michael Meeks's avatar
Michael Meeks committed
49 50 51
}

static void
52
function_definition_update (SelectorState *selector_state)
Michael Meeks's avatar
Michael Meeks committed
53
{
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
	FunctionCategory *cat; 
	FunctionDefinition *fn;
	GtkCList *cl;
	FunctionDefinition *fd = NULL;
	int lp, max;

	cl = selector_state->cl_funcs;
	gtk_clist_freeze (cl);
	gtk_clist_clear (cl);
	
	cat = g_ptr_array_index (selector_state->cats, selector_state->selected_cat);
	fn = cat->functions;
	max = 0;
	
	for (lp = 0; fn [lp].name; lp++){
		gchar *cols [1];
		
		cols [0] = fn [lp].name;
		gtk_clist_append (cl, cols);
Michael Meeks's avatar
Michael Meeks committed
73
		
74 75 76
		if (lp == selector_state->selected_func){
			fd = &fn [lp];
			gtk_clist_select_row (cl, lp, 0);
Michael Meeks's avatar
Michael Meeks committed
77
		}
78 79 80 81 82 83 84 85 86
		max++;
	}
	gtk_clist_thaw (cl);
}

static void
function_select_row (GtkCList *clist, gint row, gint col,
		     GdkEvent *event, SelectorState *selector_state)
{
Michael Meeks's avatar
Michael Meeks committed
87
	if (event && event->type == GDK_2BUTTON_PRESS){
88 89 90 91 92 93 94
		gtk_signal_emit_by_name (GTK_OBJECT (selector_state->dlg),
					 "clicked", 0);
	}
	selector_state->selected_func = row;
	gtk_widget_show_all (GTK_WIDGET (selector_state->dialog_box));
}

Michael Meeks's avatar
Michael Meeks committed
95 96 97 98 99 100 101 102 103
static void
category_select_row (GtkCList *clist, gint row, gint col,
		     GdkEvent *event, SelectorState *state)
{
	state->selected_cat = row;
	state->selected_func = 0;
	function_definition_update (state);
	gtk_widget_show_all (GTK_WIDGET(state->dialog_box));
}
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125

#define USIZE_WIDTH  100
#define USIZE_HEIGHT 150

static void
function_select_create (SelectorState *selector_state)
{
	GtkWidget *box, *vbox;
	GtkWidget *scroll;
	GtkCList *cl;

	vbox = gtk_vbox_new (0, 0);
	box  = gtk_hbox_new (0, 0);

	/* The Category List */
	{ 

		selector_state->cl_cats = cl = GTK_CLIST (gtk_clist_new (1));
		gtk_clist_column_titles_hide (cl);

		function_categories_fill (selector_state);
		gtk_clist_set_selection_mode (cl,GTK_SELECTION_SINGLE);
Michael Meeks's avatar
Michael Meeks committed
126 127
		gtk_signal_connect (GTK_OBJECT (cl), "select_row",
				    GTK_SIGNAL_FUNC (category_select_row),
128 129
				    selector_state);
		gtk_widget_set_usize (GTK_WIDGET(cl), USIZE_WIDTH, USIZE_HEIGHT);
Michael Meeks's avatar
Michael Meeks committed
130 131 132 133 134 135
		scroll = gtk_scrolled_window_new (NULL, NULL);
		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
						GTK_POLICY_AUTOMATIC,
						GTK_POLICY_AUTOMATIC);
		gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET(cl));
		gtk_box_pack_start (GTK_BOX(box), GTK_WIDGET(scroll),
136
				    TRUE, TRUE, 0);
Michael Meeks's avatar
Michael Meeks committed
137 138
	}
	
139 140 141 142 143 144 145
	/* The Function List */
	{ 
		selector_state->cl_funcs = cl = GTK_CLIST (gtk_clist_new(1));
		gtk_clist_column_titles_hide (cl);

		function_definition_update (selector_state);
		gtk_clist_set_selection_mode (cl,GTK_SELECTION_SINGLE);
Michael Meeks's avatar
Michael Meeks committed
146 147
		gtk_signal_connect (GTK_OBJECT (cl), "select_row",
				    GTK_SIGNAL_FUNC (function_select_row),
148 149
				    selector_state);
		gtk_widget_set_usize (GTK_WIDGET (cl), USIZE_WIDTH, USIZE_HEIGHT);
Michael Meeks's avatar
Michael Meeks committed
150 151 152 153
		scroll = gtk_scrolled_window_new (NULL, NULL);
		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
						GTK_POLICY_AUTOMATIC,
						GTK_POLICY_AUTOMATIC);
154 155
		gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (cl));
		gtk_box_pack_start (GTK_BOX (box), scroll, TRUE, TRUE, 0);
Michael Meeks's avatar
Michael Meeks committed
156 157
	}

158 159 160 161 162
	gtk_box_pack_start (GTK_BOX(vbox), box, TRUE, TRUE, 0);
	
	selector_state->widget = vbox;
	gtk_box_pack_start (selector_state->dialog_box, vbox,
			    FALSE, FALSE, 0);
Michael Meeks's avatar
Michael Meeks committed
163

164
	gtk_widget_show_all (GTK_WIDGET(selector_state->dialog_box));
Michael Meeks's avatar
Michael Meeks committed
165 166 167 168 169 170 171 172
}

/**
 * Main entry point for the Cell Sort dialog box
 **/
FunctionDefinition *
dialog_function_select (Workbook *wb)
{
173 174 175
	GtkWidget *dialog;
	SelectorState selector_state;
	FunctionDefinition *ans = NULL;
Michael Meeks's avatar
Michael Meeks committed
176

177
	g_return_val_if_fail (wb, NULL);
Michael Meeks's avatar
Michael Meeks committed
178

179 180 181 182
	selector_state.wb   = wb;
	selector_state.cats = function_categories_get ();
	selector_state.selected_cat  = 0;
	selector_state.selected_func = 0;
Michael Meeks's avatar
Michael Meeks committed
183 184 185 186 187

	dialog = gnome_dialog_new (_("Formula Selection"),
				   GNOME_STOCK_BUTTON_OK,
				   GNOME_STOCK_BUTTON_CANCEL,
				   NULL);
188
	gtk_window_set_policy (GTK_WINDOW (dialog), TRUE, TRUE, TRUE);
Michael Meeks's avatar
Michael Meeks committed
189
	gnome_dialog_set_parent (GNOME_DIALOG (dialog),
190 191
				 GTK_WINDOW (wb->toplevel));
	gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
Michael Meeks's avatar
Michael Meeks committed
192

193 194
	selector_state.dlg        = dialog;
	selector_state.dialog_box = GTK_BOX(GNOME_DIALOG (dialog)->vbox);
Michael Meeks's avatar
Michael Meeks committed
195

196
	function_select_create (&selector_state);
Michael Meeks's avatar
Michael Meeks committed
197

198 199 200 201
	if (gnome_dialog_run (GNOME_DIALOG(dialog)) == 0){
		FunctionCategory *cat = g_ptr_array_index (selector_state.cats,
							   selector_state.selected_cat);
		ans = &cat->functions[selector_state.selected_func];
Michael Meeks's avatar
Michael Meeks committed
202 203
	}
	
204
	gtk_object_destroy (GTK_OBJECT (dialog));
205
	return ans;
Michael Meeks's avatar
Michael Meeks committed
206
}