dialog-autofilter.c 16.1 KB
Newer Older
1
/*
2 3 4 5
 * dialog-autofilter.c:  A pair of dialogs for autofilter conditions
 *
 * (c) Copyright 2002 Jody Goldberg <jody@gnome.org>
 *
6 7 8 9
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) version 3.
10 11 12 13 14 15 16 17
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
18 19
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
20
 */
21

22
#include <gnumeric-config.h>
23
#include <glib/gi18n-lib.h>
24 25
#include <gnumeric.h>
#include "dialogs.h"
26
#include "help.h"
27 28 29 30 31

#include <gui-util.h>
#include <commands.h>
#include <workbook-control.h>
#include <workbook.h>
32
#include <wbc-gtk.h>
33
#include <sheet.h>
34
#include <cell.h>
35
#include <ranges.h>
36
#include <value.h>
37
#include <sheet-filter.h>
38
#include <number-match.h>
39
#include <undo.h>
40

41
#include <gtk/gtk.h>
Jody Goldberg's avatar
Jody Goldberg committed
42
#include <string.h>
43 44

typedef struct {
45
	GtkBuilder         *gui;
46
	WBCGtk *wbcg;
47 48 49 50 51 52 53
	GtkWidget          *dialog;
	GnmFilter	   *filter;
	unsigned	    field;
	gboolean	    is_expr;
} AutoFilterState;

#define DIALOG_KEY "autofilter"
54
#define DIALOG_KEY_EXPRESSION "autofilter-expression"
55
#define UNICODE_ELLIPSIS "\xe2\x80\xa6"
56

57 58 59 60 61
static char const * const type_group[] = {
	"items-largest",
	"items-smallest",
	"percentage-largest",
	"percentage-smallest",
62 63
	"percentage-largest-number",
	"percentage-smallest-number",
64 65 66 67 68 69
	NULL
};

static GnmFilterOp
autofilter_get_type (AutoFilterState *state)
{
Morten Welinder's avatar
Morten Welinder committed
70
	return (GNM_FILTER_OP_TYPE_BUCKETS |
71 72 73 74
		gnm_gui_group_value (state->gui, type_group));
}


75 76 77 78
static void
cb_autofilter_destroy (AutoFilterState *state)
{
	if (state->gui != NULL) {
79
		g_object_unref (state->gui);
80 81 82 83 84 85 86
		state->gui = NULL;
	}

	state->dialog = NULL;
	g_free (state);
}

Jody Goldberg's avatar
Jody Goldberg committed
87
static GnmValue *
88 89 90 91
map_op (AutoFilterState *state, GnmFilterOp *op,
	char const *op_widget, char const *val_widget)
{
	int i;
Morten Welinder's avatar
Morten Welinder committed
92
	GtkWidget *w = go_gtk_builder_get_widget (state->gui, val_widget);
93
	char const *txt = gtk_entry_get_text (GTK_ENTRY (w));
Jody Goldberg's avatar
Jody Goldberg committed
94
	GnmValue *v = NULL;
95 96 97 98 99

	*op = GNM_FILTER_UNUSED;
	if (txt == NULL || *txt == '\0')
		return NULL;

Morten Welinder's avatar
Morten Welinder committed
100
	w = go_gtk_builder_get_widget (state->gui, op_widget);
101
	i = gtk_combo_box_get_active (GTK_COMBO_BOX (w));
102 103 104 105 106 107 108 109 110
	switch (i) {
	case 0: return NULL;
	case 1: *op = GNM_FILTER_OP_EQUAL;	break;
	case 2: *op = GNM_FILTER_OP_NOT_EQUAL;	break;
	case 3: *op = GNM_FILTER_OP_GT;		break;
	case 4: *op = GNM_FILTER_OP_GTE;	break;
	case 5: *op = GNM_FILTER_OP_LT;		break;
	case 6: *op = GNM_FILTER_OP_LTE;	break;

Morten Welinder's avatar
Morten Welinder committed
111
	case 7:
112
	case 8: *op = (i == 8) ? GNM_FILTER_OP_NOT_EQUAL : GNM_FILTER_OP_EQUAL;
113
		v = value_new_string_nocopy (g_strconcat (txt, "*", NULL));
114 115
		break;

Morten Welinder's avatar
Morten Welinder committed
116
	case 9:
117
	case 10: *op = (i == 10) ? GNM_FILTER_OP_NOT_EQUAL : GNM_FILTER_OP_EQUAL;
118
		v = value_new_string_nocopy (g_strconcat ("*", txt, NULL));
119 120
		break;

Morten Welinder's avatar
Morten Welinder committed
121
	case 11:
122 123 124 125 126 127
	case 12: *op = (i == 12) ? GNM_FILTER_OP_NOT_EQUAL : GNM_FILTER_OP_EQUAL;
		v = value_new_string_nocopy (g_strconcat ("*", txt, "*", NULL));
		break;
	default :
		g_warning ("huh?");
		return NULL;
128
	}
129

130
	if (v == NULL) {
Morten Welinder's avatar
Morten Welinder committed
131
		Workbook *wb = wb_control_get_workbook (GNM_WBC (state->wbcg));
132 133
		v = format_match (txt, NULL, workbook_date_conv (wb));
	}
134 135 136 137 138 139
	if (v == NULL)
		v = value_new_string (txt);

	return v;
}

140
static void
141
cb_autofilter_ok (G_GNUC_UNUSED GtkWidget *button,
142 143 144 145 146 147
		  AutoFilterState *state)
{
	GnmFilterCondition *cond = NULL;
	GtkWidget *w;

	if (state->is_expr) {
148
		GnmFilterOp op0;
Jody Goldberg's avatar
Jody Goldberg committed
149
		GnmValue *v0 = map_op (state, &op0, "op0", "value0");
150

151 152
		if (op0 != GNM_FILTER_UNUSED) {
			GnmFilterOp op1;
Jody Goldberg's avatar
Jody Goldberg committed
153
			GnmValue *v1 = map_op (state, &op1, "op1", "value1");
154
			if (op1 != GNM_FILTER_UNUSED) {
Morten Welinder's avatar
Morten Welinder committed
155
				w = go_gtk_builder_get_widget (state->gui,
156
							       "and_button");
Morten Welinder's avatar
Morten Welinder committed
157
				cond = gnm_filter_condition_new_double
158
					(op0, v0,
Morten Welinder's avatar
Morten Welinder committed
159
					 gtk_toggle_button_get_active
160 161
					 (GTK_TOGGLE_BUTTON (w)),
					 op1, v1);
162
			} else
Morten Welinder's avatar
Morten Welinder committed
163
				cond = gnm_filter_condition_new_single
164
					(op0, v0);
165
		}
166
	} else {
167 168
		int count;
		GnmFilterOp op = autofilter_get_type (state);
169

Morten Welinder's avatar
Morten Welinder committed
170
		w = go_gtk_builder_get_widget (state->gui, "item_count");
171
		count = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w));
172

Morten Welinder's avatar
Morten Welinder committed
173 174 175
		cond = gnm_filter_condition_new_bucket
			(!(op & GNM_FILTER_OP_BOTTOM_MASK),
			 !(op & GNM_FILTER_OP_PERCENT_MASK),
176
			 !(op & GNM_FILTER_OP_REL_N_MASK),
177
			 count);
178
	}
179
	if (cond != NULL)
Morten Welinder's avatar
Morten Welinder committed
180
		cmd_autofilter_set_condition (GNM_WBC (state->wbcg),
Morten Welinder's avatar
Morten Welinder committed
181
					      state->filter, state->field,
182
					      cond);
183 184 185 186 187

	gtk_widget_destroy (state->dialog);
}

static void
188 189
cb_autofilter_cancel (G_GNUC_UNUSED GtkWidget *button,
		      AutoFilterState *state)
190 191 192 193
{
	gtk_widget_destroy (state->dialog);
}

194
static void
195 196 197 198 199 200
cb_top10_count_changed (GtkSpinButton *button,
			AutoFilterState *state)
{
	int val = 0.5 + gtk_spin_button_get_value (button);
	GtkWidget *w;
	gchar *label;
201 202 203 204 205 206
	int cval = val, count;

	count = range_height(&(state->filter->r)) - 1;

	if (cval > count)
		cval = count;
207 208 209 210

	w = go_gtk_builder_get_widget (state->gui, type_group[0]);
	/* xgettext : %d gives the number of items in the autofilter. */
	/* This is input to ngettext. */
Morten Welinder's avatar
Morten Welinder committed
211 212 213
	label = g_strdup_printf (ngettext ("Show the largest item",
					   "Show the %3d largest items",
					   cval),
214
				 cval);
215 216 217 218 219 220
	gtk_button_set_label (GTK_BUTTON (w),label);
	g_free(label);

	w = go_gtk_builder_get_widget (state->gui, type_group[1]);
	/* xgettext : %d gives the number of items in the autofilter. */
	/* This is input to ngettext. */
Morten Welinder's avatar
Morten Welinder committed
221 222 223
	label = g_strdup_printf (ngettext ("Show the smallest item",
					   "Show the %3d smallest items",
					   cval),
224
				 cval);
225 226 227 228 229 230 231
	gtk_button_set_label (GTK_BUTTON (w),label);
	g_free(label);

	if (val > 100)
		val = 100;

	w = go_gtk_builder_get_widget (state->gui, type_group[2]);
232
	/* xgettext : %d gives the percentage of the data range in the autofilter. */
233
	/* This is input to ngettext. */
Morten Welinder's avatar
Morten Welinder committed
234 235 236
	label = g_strdup_printf
		(ngettext ("Show the items in the top %3d%% of the data range",
			   "Show the items in the top %3d%% of the data range", val),
237 238 239 240 241
		 val);
	gtk_button_set_label (GTK_BUTTON (w),label);
	g_free(label);

	w = go_gtk_builder_get_widget (state->gui, type_group[3]);
242
	/* xgettext : %d gives the percentage of the data range in the autofilter. */
243
	/* This is input to ngettext. */
Morten Welinder's avatar
Morten Welinder committed
244 245 246
	label = g_strdup_printf
		(ngettext ("Show the items in the bottom %3d%% of the data range",
			   "Show the items in the bottom %3d%% of the data range", val),
247 248 249 250 251
		 val);
	gtk_button_set_label (GTK_BUTTON (w),label);
	g_free(label);


252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
	w = go_gtk_builder_get_widget (state->gui, type_group[4]);
	/* xgettext : %d gives the percentage of item number in the autofilter. */
	/* This is input to ngettext. */
	label = g_strdup_printf
		(ngettext ("Show the top %3d%% of all items",
			   "Show the top %3d%% of all items", val),
		 val);
	gtk_button_set_label (GTK_BUTTON (w),label);
	g_free(label);

	w = go_gtk_builder_get_widget (state->gui, type_group[5]);
	/* xgettext : %d gives the percentage of the item number in the autofilter. */
	/* This is input to ngettext. */
	label = g_strdup_printf
		(ngettext ("Show the bottom %3d%% of all items",
			   "Show the bottom %3d%% of all items", val),
		 val);
	gtk_button_set_label (GTK_BUTTON (w),label);
	g_free(label);


273 274 275 276
}

static void
cb_top10_type_changed (G_GNUC_UNUSED GtkToggleButton *button,
277 278
		       AutoFilterState *state)
{
279
	GnmFilterOp op = autofilter_get_type (state);
Morten Welinder's avatar
Morten Welinder committed
280
	GtkWidget *spin = go_gtk_builder_get_widget (state->gui, "item_count");
281
	GtkWidget *label = go_gtk_builder_get_widget (state->gui, "cp-label");
282

283
	if ((op & GNM_FILTER_OP_PERCENT_MASK) != 0) {
284 285 286 287
		gtk_spin_button_set_range (GTK_SPIN_BUTTON (spin), 1.,
					   100.);
		gtk_label_set_text (GTK_LABEL (label), _("Percentage:"));
	} else {
Morten Welinder's avatar
Morten Welinder committed
288
		gtk_spin_button_set_range
289 290 291 292
			(GTK_SPIN_BUTTON (spin), 1.,
			 range_height(&(state->filter->r)) - 1);
		gtk_label_set_text (GTK_LABEL (label), _("Count:"));
	}
293 294
}

295
static void
Jody Goldberg's avatar
Jody Goldberg committed
296
init_operator (AutoFilterState *state, GnmFilterOp op, GnmValue const *v,
297 298
	       char const *op_widget, char const *val_widget)
{
Morten Welinder's avatar
Morten Welinder committed
299
	GtkWidget *w = go_gtk_builder_get_widget (state->gui, op_widget);
300 301
	char const *str = v ? value_peek_string (v) : NULL;
	char *content = NULL;
302 303 304 305 306 307 308 309 310 311 312
	int i;

	switch (op) {
	case GNM_FILTER_OP_EQUAL:	i = 1; break;
	case GNM_FILTER_OP_GT:		i = 3; break;
	case GNM_FILTER_OP_LT:		i = 5; break;
	case GNM_FILTER_OP_GTE:		i = 4; break;
	case GNM_FILTER_OP_LTE:		i = 6; break;
	case GNM_FILTER_OP_NOT_EQUAL:	i = 2; break;
	default :
		return;
313
	}
314

315
	if (v != NULL && VALUE_IS_STRING (v) && (i == 1 || i == 2)) {
316
		unsigned const len = strlen (str);
317

318
		/* there needs to be at least 1 letter */
319
		int ends = (len > 1 && str[0] == '*') ? 1 : 0; /* as a bool and offset */
320

321 322 323
		if (len > 1 && str[len-1] == '*' && str[len-2] != '~') {
			content = g_strdup (str + ends);
			content[len - ends - 1] = '\0';
324
			i += (ends ? 10 : 6);
325 326
		} else if (ends) {
			str += 1;
327
			i += 8;
328
		}
329
	}
330
	gtk_combo_box_set_active (GTK_COMBO_BOX (w), i);
331

Morten Welinder's avatar
Morten Welinder committed
332
	w = go_gtk_builder_get_widget (state->gui, val_widget);
Morten Welinder's avatar
Morten Welinder committed
333
	gnm_editable_enters (GTK_WINDOW (state->dialog), w);
334
	if (v != NULL)
335
		gtk_entry_set_text (GTK_ENTRY (w), content ? content : str);
336

337
	g_free (content);
338 339
}

340 341 342 343 344 345
static gchar *
dialog_auto_filter_get_col_name (GnmCell *cell, int col, int len)
{
	gchar *label;
	char *content = gnm_cell_get_rendered_text (cell);
	if (g_utf8_strlen (content, -1) > len) {
Morten Welinder's avatar
Morten Welinder committed
346
		char *end = g_utf8_find_prev_char
347 348 349 350 351 352 353 354 355 356 357 358
			(content, content + len + 1 - strlen (UNICODE_ELLIPSIS));
		strcpy (end, UNICODE_ELLIPSIS);
	}
	label = g_strdup_printf (_("Column %s (\"%s\")"),
				 col_name (col), content);
	g_free (content);
	return label;
}
static void
dialog_auto_filter_expression (WBCGtk *wbcg,
			       GnmFilter *filter, int field,
			       GnmFilterCondition *cond)
359 360 361
{
	AutoFilterState *state;
	GtkWidget *w;
362
	GtkBuilder *gui;
363 364 365
	int col;
	gchar *label;
	GnmCell *cell;
366
	int const len = 15;
367 368 369

	g_return_if_fail (wbcg != NULL);

Morten Welinder's avatar
Morten Welinder committed
370
	if (gnm_dialog_raise_if_exists
371
	    (wbcg, DIALOG_KEY_EXPRESSION))
372
		return;
373
	gui = gnm_gtk_builder_load ("res:ui/autofilter-expression.ui",
374
				   NULL, GO_CMD_CONTEXT (wbcg));
375 376
	if (gui == NULL)
		return;
377 378 379 380 381

	state = g_new (AutoFilterState, 1);
	state->wbcg	= wbcg;
	state->filter	= filter;
	state->field	= field;
382
	state->is_expr	= TRUE;
383
	state->gui	= gui;
384 385 386

	g_return_if_fail (state->gui != NULL);

387 388 389 390 391 392
	col = filter->r.start.col + field;

	cell = sheet_cell_get (filter->sheet, col, filter->r.start.row);

	if (cell == NULL || gnm_cell_is_blank (cell))
		label = g_strdup_printf (_("Column %s"), col_name (col));
Morten Welinder's avatar
Morten Welinder committed
393
	else
394
		label = dialog_auto_filter_get_col_name (cell, col, len);
395

396 397 398 399
	gtk_label_set_text
		(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label1")), label);
	gtk_label_set_text
		(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label2")), label);
400
	g_free (label);
401

Morten Welinder's avatar
Morten Welinder committed
402
	state->dialog = go_gtk_builder_get_widget (state->gui, "dialog");
403 404
	if (cond != NULL) {
		GnmFilterOp const op = cond->op[0];
405
		if (0 == (op & GNM_FILTER_OP_TYPE_MASK)) {
406 407 408 409 410
			init_operator (state, cond->op[0],
				       cond->value[0], "op0", "value0");
			if (cond->op[1] != GNM_FILTER_UNUSED)
				init_operator (state, cond->op[1],
					       cond->value[1], "op1", "value1");
Morten Welinder's avatar
Morten Welinder committed
411
			w = go_gtk_builder_get_widget (state->gui,
412 413
				cond->is_and ? "and_button" : "or_button");
			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
414
		}
415
	} else {
416
		/* initialize the combo boxes (not done by li.ui) */
417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
		w = go_gtk_builder_get_widget (state->gui, "op0");
		gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
		w = go_gtk_builder_get_widget (state->gui, "op1");
		gtk_combo_box_set_active (GTK_COMBO_BOX (w), 0);
	}

	w = go_gtk_builder_get_widget (state->gui, "ok_button");
	g_signal_connect (G_OBJECT (w),
		"clicked",
		G_CALLBACK (cb_autofilter_ok), state);
	w = go_gtk_builder_get_widget (state->gui, "cancel_button");
	g_signal_connect (G_OBJECT (w),
		"clicked",
		G_CALLBACK (cb_autofilter_cancel), state);

	/* a candidate for merging into attach guru */
Morten Welinder's avatar
Morten Welinder committed
433
	gnm_init_help_button (
434 435 436 437 438 439 440 441 442 443 444
		go_gtk_builder_get_widget (state->gui, "help_button"),
		GNUMERIC_HELP_LINK_AUTOFILTER_CUSTOM);

	gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
					   state->wbcg,
					   GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED);

	wbc_gtk_attach_guru (state->wbcg, state->dialog);
	g_object_set_data_full (G_OBJECT (state->dialog),
		"state", state, (GDestroyNotify)cb_autofilter_destroy);

Morten Welinder's avatar
Morten Welinder committed
445
	gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
			       DIALOG_KEY_EXPRESSION);
	gtk_widget_show (state->dialog);
}

void
dialog_auto_filter (WBCGtk *wbcg,
		    GnmFilter *filter, int field,
		    gboolean is_expr, GnmFilterCondition *cond)
{
	AutoFilterState *state;
	GtkWidget *w;
	GtkBuilder *gui;
	int col;
	gchar *label;
	GnmCell *cell;
	int len = is_expr ? 15 : 30;
	char const * const *rb;

	if (is_expr) {
		dialog_auto_filter_expression (wbcg, filter, field, cond);
		return;
	}

	g_return_if_fail (wbcg != NULL);

Morten Welinder's avatar
Morten Welinder committed
471
	if (gnm_dialog_raise_if_exists (wbcg, DIALOG_KEY))
472
		return;
473
	gui = gnm_gtk_builder_load ("res:ui/autofilter-top10.ui",
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
				   NULL, GO_CMD_CONTEXT (wbcg));
	if (gui == NULL)
		return;

	state = g_new (AutoFilterState, 1);
	state->wbcg	= wbcg;
	state->filter	= filter;
	state->field	= field;
	state->is_expr	= FALSE;
	state->gui	= gui;

	g_return_if_fail (state->gui != NULL);

	col = filter->r.start.col + field;

	cell = sheet_cell_get (filter->sheet, col, filter->r.start.row);

	if (cell == NULL || gnm_cell_is_blank (cell))
		label = g_strdup_printf (_("Column %s"), col_name (col));
Morten Welinder's avatar
Morten Welinder committed
493
	else
494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
		label = dialog_auto_filter_get_col_name (cell, col, len);

	gtk_label_set_text
		(GTK_LABEL (go_gtk_builder_get_widget (state->gui, "col-label")), label);
	g_free (label);

	state->dialog = go_gtk_builder_get_widget (state->gui, "dialog");
	if (cond != NULL && GNM_FILTER_OP_TOP_N == (cond->op[0] & GNM_FILTER_OP_TYPE_MASK)) {
		gchar const *radio = NULL;
		switch (cond->op[0]) {
		case GNM_FILTER_OP_TOP_N:
		default:
			radio = type_group[0];
			break;
		case GNM_FILTER_OP_BOTTOM_N:
			radio = type_group[1];
			break;
		case GNM_FILTER_OP_TOP_N_PERCENT:
			radio = type_group[2];
			break;
		case GNM_FILTER_OP_BOTTOM_N_PERCENT:
			radio = type_group[3];
			break;
517 518 519 520 521 522
		case GNM_FILTER_OP_TOP_N_PERCENT_N:
			radio = type_group[4];
			break;
		case GNM_FILTER_OP_BOTTOM_N_PERCENT_N:
			radio = type_group[5];
			break;
523
		}
524 525 526 527
		w = go_gtk_builder_get_widget (state->gui, radio);
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
	} else {
		w = go_gtk_builder_get_widget (state->gui, "items-largest");
Morten Welinder's avatar
Morten Welinder committed
528
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
529 530
	}

531
	w = go_gtk_builder_get_widget (state->gui, "item_count");
532 533 534
	g_signal_connect (G_OBJECT (w),
			  "value-changed",
			  G_CALLBACK (cb_top10_count_changed), state);
535 536 537 538 539
	if (cond != NULL && GNM_FILTER_OP_TOP_N == (cond->op[0] & GNM_FILTER_OP_TYPE_MASK))
		gtk_spin_button_set_value (GTK_SPIN_BUTTON (w), cond->count);
	else
		gtk_spin_button_set_value (GTK_SPIN_BUTTON (w),
				   range_height(&(state->filter->r))/2);
540
	cb_top10_count_changed (GTK_SPIN_BUTTON (w), state);
541
	cb_top10_type_changed (NULL, state);
542 543 544 545 546 547 548 549

	rb = type_group;
	while (*rb != NULL) {
		w = go_gtk_builder_get_widget (state->gui, *rb);
		g_signal_connect (G_OBJECT (w),
				  "toggled",
				  G_CALLBACK (cb_top10_type_changed), state);
		rb++;
550
	}
Morten Welinder's avatar
Morten Welinder committed
551

552

Morten Welinder's avatar
Morten Welinder committed
553
	w = go_gtk_builder_get_widget (state->gui, "ok_button");
554 555 556
	g_signal_connect (G_OBJECT (w),
		"clicked",
		G_CALLBACK (cb_autofilter_ok), state);
Morten Welinder's avatar
Morten Welinder committed
557
	w = go_gtk_builder_get_widget (state->gui, "cancel_button");
558 559 560 561 562
	g_signal_connect (G_OBJECT (w),
		"clicked",
		G_CALLBACK (cb_autofilter_cancel), state);

	/* a candidate for merging into attach guru */
Morten Welinder's avatar
Morten Welinder committed
563
	gnm_init_help_button (
Morten Welinder's avatar
Morten Welinder committed
564
		go_gtk_builder_get_widget (state->gui, "help_button"),
565
		GNUMERIC_HELP_LINK_AUTOFILTER_TOP_TEN);
566

Morten Welinder's avatar
Morten Welinder committed
567
	gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
568 569 570
					   state->wbcg,
					   GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED);

571
	wbc_gtk_attach_guru (state->wbcg, state->dialog);
572 573
	g_object_set_data_full (G_OBJECT (state->dialog),
		"state", state, (GDestroyNotify)cb_autofilter_destroy);
574

Morten Welinder's avatar
Morten Welinder committed
575
	gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
576
			       DIALOG_KEY);
577 578
	gtk_widget_show (state->dialog);
}