1 /*
2 * dialog-autoformat.c : implementation of the autoformat dialog
3 *
4 * Author : Almer S. Tigelaar <almer@gnome.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <https://www.gnu.org/licenses/>.
18 */
19
20 /*
21 * WORKING NOTE : Once the edit dialog is ready, search for FIXME and
22 * remove the disabling of new/edit/remove buttons!
23 */
24
25 #include <gnumeric-config.h>
26 #include <glib/gi18n-lib.h>
27 #include <gnumeric.h>
28 #include <dialogs/dialogs.h>
29 #include <dialogs/help.h>
30
31 #include <gui-util.h>
32 #include <mstyle.h>
33 #include <style-border.h>
34 #include <value.h>
35 #include <preview-grid-impl.h>
36 #include <format-template.h>
37 #include <file-autoft.h>
38 #include <command-context.h>
39 #include <workbook-control.h>
40 #include <workbook.h>
41 #include <wbc-gtk.h>
42 #include <commands.h>
43 #include <selection.h>
44 #include <ranges.h>
45
46 #include <goffice/goffice.h>
47 #include <gsf/gsf-impl-utils.h>
48 #include <string.h>
49
50 /* Table to show for
51 * previews, please don't make this larger than 5x5
52 */
53 #define PREVIEW_COLS 5
54 #define PREVIEW_ROWS 5
55 #define NUM_PREVIEWS 6
56 #define DEFAULT_COL_WIDTH 52
57 #define DEFAULT_ROW_HEIGHT 17
58 #define BORDER 7
59 #define INNER_BORDER 5
60 #define TOTAL_WIDTH (DEFAULT_COL_WIDTH * PREVIEW_COLS)
61 #define TOTAL_HEIGHT (DEFAULT_ROW_HEIGHT * PREVIEW_ROWS)
62
63 /* Keep these strings very short.
64 They are used as a sample data for a sheet, so you can put anything here
65 ("One", "Two", "Three" for example) */
66 static char const *const
67 demotable[PREVIEW_ROWS][PREVIEW_COLS] = {
68 { N_(" ") , N_("Jan"), N_("Feb"), N_("Mar"), N_("Total") },
69 { N_("North"), N_("6"), N_("13"), N_("20"), N_("39") },
70 { N_("South"), N_("12"), N_("4"), N_("17"), N_("33") },
71 { N_("West") , N_("8"), N_("2"), N_("0"), N_("10") },
72 { N_("Total"), N_("26"), N_("19"), N_("37"), N_("81") }
73 };
74
75 typedef struct {
76 Workbook *wb; /* Workbook we are working on */
77 WBCGtk *wbcg;
78 GocItem *grid[NUM_PREVIEWS]; /* Previewgrid's */
79 GocItem *selrect; /* Selection rectangle */
80 GSList *templates; /* List of GnmFT's */
81 GnmFT *selected_template; /* The currently selected template */
82 GList *category_groups; /* List of groups of categories */
83
84 GnmFTCategoryGroup *current_category_group; /* Currently selected category group */
85
86 int preview_top; /* Top index of the previewlist */
87 int preview_index; /* Selected canvas in previewlist */
88 gboolean previews_locked; /* If true, the preview_free and preview_load will not function */
89 gboolean more_down; /* If true, more was clicked and the button caption is now 'Less' */
90
91 /*
92 * Gui elements
93 */
94 GtkDialog *dialog;
95
96 GtkComboBox *category;
97
98 GocCanvas *canvas[NUM_PREVIEWS];
99 GtkFrame *frame[NUM_PREVIEWS];
100 GtkScrollbar *scroll;
101 GtkCheckMenuItem *gridlines;
102
103 GtkEntry *info_name, *info_author, *info_cat;
104 GtkTextView *info_descr;
105
106 GtkCheckMenuItem *number, *border, *font, *patterns, *alignment;
107
108 struct {
109 GtkCheckMenuItem *left;
110 GtkCheckMenuItem *right;
111 GtkCheckMenuItem *top;
112 GtkCheckMenuItem *bottom;
113 } edges;
114
115 GtkButton *ok, *cancel;
116 } AutoFormatState;
117
118 /********************************************************************************/
119
120 typedef struct {
121 GnmPreviewGrid base;
122 GnmFT *ft;
123 } AutoFormatGrid;
124 typedef GnmPreviewGridClass AutoFormatGridClass;
125
126 static GnmStyle *
afg_get_cell_style(GnmPreviewGrid * pg,int col,int row)127 afg_get_cell_style (GnmPreviewGrid *pg, int col, int row)
128 {
129 /* If this happens to be NULL the default style
130 * will automatically be used. */
131 AutoFormatGrid *ag = (AutoFormatGrid *) pg;
132 return gnm_ft_get_style (ag->ft, row, col);
133 }
134
135 static GnmValue *
afg_get_cell_value(G_GNUC_UNUSED GnmPreviewGrid * pg,int col,int row)136 afg_get_cell_value (G_GNUC_UNUSED GnmPreviewGrid *pg, int col, int row)
137 {
138 char const *text;
139 char *endptr = NULL;
140 double tmp;
141
142 if (row >= PREVIEW_ROWS || col >= PREVIEW_COLS)
143 return NULL;
144
145 text = _(demotable[row][col]);
146 tmp = go_strtod (text, &endptr);
147
148 if (*endptr == '\0')
149 return value_new_float (tmp);
150 return value_new_string (text);
151 }
152
153 static void
auto_format_grid_class_init(GnmPreviewGridClass * klass)154 auto_format_grid_class_init (GnmPreviewGridClass *klass)
155 {
156 klass->get_cell_style = afg_get_cell_style;
157 klass->get_cell_value = afg_get_cell_value;
158 }
159
GSF_CLASS(AutoFormatGrid,auto_format_grid,auto_format_grid_class_init,NULL,gnm_preview_grid_get_type ())160 static GSF_CLASS (AutoFormatGrid, auto_format_grid,
161 auto_format_grid_class_init, NULL,
162 gnm_preview_grid_get_type())
163
164 static GocItem *
165 auto_format_grid_new (AutoFormatState *state, int i, GnmFT *ft)
166 {
167 GocItem *item = goc_item_new (
168 goc_canvas_get_root (state->canvas[i]),
169 auto_format_grid_get_type (),
170 "render-gridlines", gtk_check_menu_item_get_active (state->gridlines),
171 "default-col-width", DEFAULT_COL_WIDTH,
172 "default-row-height", DEFAULT_ROW_HEIGHT,
173 "x", 0.,
174 "y", 0.,
175 NULL);
176 ((AutoFormatGrid *) item)->ft = ft;
177 return item;
178 }
179 /********************************************************************************
180 * UTILITY FUNCTIONS
181 ********************************************************************************/
182
183 static void
templates_free(AutoFormatState * state)184 templates_free (AutoFormatState *state)
185 {
186 GSList *ptr;
187
188 g_return_if_fail (state != NULL);
189
190 for (ptr = state->templates; ptr != NULL ; ptr = ptr->next)
191 gnm_ft_free (ptr->data);
192 g_slist_free (state->templates);
193 state->templates = NULL;
194 }
195
196 /**
197 * templates_load:
198 * @state: AutoFormatState
199 *
200 * This function will load the templates in the currently selected
201 * category group (it looks at state->category_groups to determine the selection)
202 *
203 * Returns: %TRUE if all went well, %FALSE otherwise.
204 **/
205 static gboolean
templates_load(AutoFormatState * state)206 templates_load (AutoFormatState *state)
207 {
208 GSList *l;
209 gint n_templates;
210
211 g_return_val_if_fail (state != NULL, FALSE);
212
213 if (state->category_groups == NULL)
214 return FALSE;
215
216 state->templates = gnm_ft_category_group_get_templates_list (
217 state->current_category_group, GO_CMD_CONTEXT (state->wbcg));
218 for (l = state->templates; l != NULL; l = l->next) {
219 GnmFT *ft = l->data;
220 range_init (&ft->dimension,
221 0, 0, PREVIEW_COLS - 1, PREVIEW_ROWS - 1);
222 ft->invalidate_hash = TRUE;
223 }
224 n_templates = g_slist_length (state->templates);
225
226 /*
227 * We need to temporary lock the preview loading/freeing or
228 * else our scrollbar will trigger an event (value_changed) and create the
229 * previews. (which we don't want to happen at this moment)
230 */
231 state->previews_locked = TRUE;
232 {
233 GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (state->scroll));
234 gtk_adjustment_configure (adjustment,
235 0, 0, n_templates / 2,
236 1, 3, 3);
237 }
238 state->previews_locked = FALSE;
239
240 /*
241 * Hide the scrollbar when it's not needed
242 */
243 gtk_widget_set_visible (GTK_WIDGET (state->scroll),
244 n_templates > NUM_PREVIEWS);
245
246 return TRUE;
247 }
248
249 /**
250 * previews_free:
251 * @state: AutoFormatState
252 *
253 * This function will free all previews.
254 **/
255 static void
previews_free(AutoFormatState * state)256 previews_free (AutoFormatState *state)
257 {
258 int i;
259
260 if (state->previews_locked)
261 return;
262
263 if (state->selrect) {
264 goc_item_destroy (state->selrect);
265 state->selrect = NULL;
266 }
267
268 for (i = 0; i < NUM_PREVIEWS; i++) {
269 GocItem *item = state->grid[i];
270 if (item) {
271 goc_item_destroy (state->grid[i]);
272 state->grid[i] = NULL;
273 }
274 }
275 }
276
277 /**
278 * previews_load:
279 * @state: AutoFormatState
280 * @topindex: The index of the template to be displayed in the upper left corner
281 *
282 * This function will create grids and rects for each canvas and associate
283 * them with the right format templates.
284 * NOTE : if state->preview_locked is %TRUE this function will do nothing,
285 * this is handy in situation where signals can cause previews_load to be
286 * called before previews_free.
287 **/
288 static void
previews_load(AutoFormatState * state,int topindex)289 previews_load (AutoFormatState *state, int topindex)
290 {
291 GSList *iterator, *start;
292 int i, count = topindex;
293
294 g_return_if_fail (state != NULL);
295
296 if (state->previews_locked)
297 return;
298
299 iterator = state->templates;
300 start = iterator;
301 while (iterator && count > 0) {
302 iterator = g_slist_next (iterator);
303 start = iterator;
304 count--;
305 }
306
307 for (i = 0; i < NUM_PREVIEWS; i++) {
308 if (start == NULL) {
309 gtk_widget_hide (GTK_WIDGET (state->canvas[i]));
310 gtk_frame_set_shadow_type (state->frame[i], GTK_SHADOW_NONE);
311 } else {
312 GnmFT *ft = start->data;
313
314 state->grid[i] = auto_format_grid_new (state, i, ft);
315
316 /* Are we selected? Then draw a selection rectangle */
317 if (topindex + i == state->preview_index) {
318 GOStyle *style;
319 g_return_if_fail (state->selrect == NULL);
320
321 state->selrect = goc_item_new (goc_canvas_get_root (state->canvas[i]),
322 GOC_TYPE_RECTANGLE,
323 "x", (double)(-INNER_BORDER),
324 "y", (double)(-INNER_BORDER),
325 "width", (double)(TOTAL_WIDTH + 2 * INNER_BORDER),
326 "height", (double)(TOTAL_HEIGHT + 2 * INNER_BORDER),
327 NULL);
328 style = go_styled_object_get_style (GO_STYLED_OBJECT (state->selrect));
329 style->line.width = 3.;
330 style->line.color = GO_COLOR_RED;
331 style->fill.pattern.back = 0;
332
333 gtk_frame_set_shadow_type (state->frame[i], GTK_SHADOW_IN);
334 } else
335 gtk_frame_set_shadow_type (state->frame[i], GTK_SHADOW_ETCHED_IN);
336
337 goc_canvas_scroll_to (state->canvas[i],
338 -BORDER, -BORDER);
339
340 gtk_widget_set_tooltip_text
341 (GTK_WIDGET (state->canvas[i]),
342 _(ft->name));
343
344 gtk_widget_show (GTK_WIDGET (state->canvas[i]));
345 start = g_slist_next (start);
346 }
347 }
348
349 state->preview_top = topindex;
350 }
351
352 /********************************************************************************
353 * SIGNAL HANDLERS
354 ********************************************************************************/
355
356 static void
cb_ok_clicked(G_GNUC_UNUSED GtkButton * button,AutoFormatState * state)357 cb_ok_clicked (G_GNUC_UNUSED GtkButton *button,
358 AutoFormatState *state)
359 {
360 if (state->selected_template)
361 cmd_selection_autoformat (GNM_WBC (state->wbcg),
362 gnm_ft_clone (state->selected_template));
363
364 gtk_widget_destroy (GTK_WIDGET (state->dialog));
365 }
366
367 static void
cb_autoformat_destroy(AutoFormatState * state)368 cb_autoformat_destroy (AutoFormatState *state)
369 {
370 templates_free (state);
371 gnm_ft_category_group_list_free (state->category_groups);
372 g_free (state);
373 }
374
375 static void
cb_scroll_value_changed(GtkAdjustment * adjustment,AutoFormatState * state)376 cb_scroll_value_changed (GtkAdjustment *adjustment, AutoFormatState *state)
377 {
378 previews_free (state);
379 previews_load (state, rint (gtk_adjustment_get_value (adjustment)) * 2);
380 }
381
382 static gboolean
cb_canvas_button_press(GocCanvas * canvas,G_GNUC_UNUSED GdkEventButton * event,AutoFormatState * state)383 cb_canvas_button_press (GocCanvas *canvas,
384 G_GNUC_UNUSED GdkEventButton *event,
385 AutoFormatState *state)
386 {
387 GnmFT *ft;
388 GSList *ptr;
389 int index = 0;
390
391 while (index < NUM_PREVIEWS && canvas != state->canvas[index])
392 index++;
393
394 g_return_val_if_fail (index < NUM_PREVIEWS, FALSE);
395
396 state->preview_index = state->preview_top + index;
397
398 previews_free (state);
399 previews_load (state, state->preview_top);
400
401 for (ptr = state->templates, index = 0; ptr != NULL ; ptr = ptr->next, index++)
402 if (index == state->preview_index)
403 break;
404
405 g_return_val_if_fail (ptr != NULL && ptr->data != NULL, FALSE);
406
407 ft = ptr->data;
408 state->selected_template = ft;
409 gtk_entry_set_text (state->info_name, _(ft->name));
410 gtk_entry_set_text (state->info_author, ft->author);
411 gnm_textview_set_text (GTK_TEXT_VIEW (state->info_descr),
412 _(ft->description));
413
414 gtk_entry_set_text (state->info_cat, _(ft->category->name));
415
416 return TRUE;
417 }
418
419 static void
cb_check_item_toggled(G_GNUC_UNUSED GtkCheckMenuItem * item,AutoFormatState * state)420 cb_check_item_toggled (G_GNUC_UNUSED GtkCheckMenuItem *item,
421 AutoFormatState *state)
422 {
423 GSList *ptr;
424 int i;
425
426 for (ptr = state->templates; ptr != NULL ; ptr = ptr->next) {
427 GnmFT *ft = ptr->data;
428
429 ft->number = gtk_check_menu_item_get_active (state->number);
430 ft->border = gtk_check_menu_item_get_active (state->border);
431 ft->font = gtk_check_menu_item_get_active (state->font);
432 ft->patterns = gtk_check_menu_item_get_active (state->patterns);
433 ft->alignment = gtk_check_menu_item_get_active (state->alignment);
434
435 ft->edges.left = gtk_check_menu_item_get_active (state->edges.left);
436 ft->edges.right = gtk_check_menu_item_get_active (state->edges.right);
437 ft->edges.top = gtk_check_menu_item_get_active (state->edges.top);
438 ft->edges.bottom = gtk_check_menu_item_get_active (state->edges.bottom);
439
440 ft->invalidate_hash = TRUE;
441 }
442
443 for (i = 0; i < NUM_PREVIEWS; i++)
444 goc_canvas_invalidate (state->canvas [i],
445 -2, -2, INT_MAX/2, INT_MAX/2);
446 }
447
448 static void
cb_category_changed(AutoFormatState * state)449 cb_category_changed (AutoFormatState *state)
450 {
451 GList *selection = g_list_nth (state->category_groups,
452 gtk_combo_box_get_active (state->category));
453 char const *tip = NULL;
454
455 state->current_category_group = (selection != NULL) ? selection->data : NULL;
456 previews_free (state);
457 templates_free (state);
458 if (templates_load (state) == FALSE)
459 g_warning ("Error while loading templates!");
460
461 if (NULL != state->current_category_group) {
462 tip = state->current_category_group->description;
463 if (NULL == tip)
464 tip = state->current_category_group->name;
465 }
466 gtk_widget_set_tooltip_text (GTK_WIDGET (state->category),
467 (NULL != tip) ? _(tip) : "");
468 previews_load (state, 0);
469 cb_check_item_toggled (NULL, state);
470 cb_canvas_button_press (state->canvas[0], NULL, state);
471 }
472
473 static void
cb_gridlines_item_toggled(G_GNUC_UNUSED GtkCheckMenuItem * item,AutoFormatState * state)474 cb_gridlines_item_toggled (G_GNUC_UNUSED GtkCheckMenuItem *item,
475 AutoFormatState *state)
476 {
477 previews_free (state);
478 previews_load (state, state->preview_top);
479 }
480
481 /********************************************************************************
482 * MAIN
483 ********************************************************************************/
484
485 static gboolean
cb_canvas_focus(GtkWidget * canvas,G_GNUC_UNUSED GtkDirectionType direction,AutoFormatState * state)486 cb_canvas_focus (GtkWidget *canvas,
487 G_GNUC_UNUSED GtkDirectionType direction,
488 AutoFormatState *state)
489 {
490 if (!gtk_widget_has_focus (canvas)) {
491 gtk_widget_grab_focus (canvas);
492 cb_canvas_button_press (GOC_CANVAS (canvas), NULL, state);
493 return TRUE;
494 }
495 return FALSE;
496 }
497
498 /**
499 * dialog_autoformat:
500 * @wbcg: the control that invoked this dialog
501 *
502 * This function will show the AutoFormatTemplate dialog and apply
503 * the template the user chooses to the current selection in the active
504 * sheet of the workbook if the user desires.
505 **/
506 void
dialog_autoformat(WBCGtk * wbcg)507 dialog_autoformat (WBCGtk *wbcg)
508 {
509 GtkBuilder *gui;
510 AutoFormatState *state;
511 int i;
512
513 gui = gnm_gtk_builder_load ("res:ui/autoformat.ui", NULL, GO_CMD_CONTEXT (wbcg));
514 if (gui == NULL)
515 return;
516
517 state = g_new0 (AutoFormatState, 1);
518 state->wb = wb_control_get_workbook (GNM_WBC (wbcg));
519 state->wbcg = wbcg;
520 state->templates = NULL;
521 state->category_groups = NULL;
522 state->selrect = NULL;
523 for (i = 0; i < NUM_PREVIEWS; i++)
524 state->grid[i] = NULL;
525
526 state->current_category_group = NULL;
527 state->preview_top = 0;
528 state->preview_index = -1;
529 state->previews_locked = FALSE;
530 state->more_down = FALSE;
531 state->selected_template = NULL;
532
533 state->dialog = GTK_DIALOG (go_gtk_builder_get_widget (gui, "dialog"));
534 state->category = GTK_COMBO_BOX (go_gtk_builder_get_widget (gui, "format_category"));
535 state->scroll = GTK_SCROLLBAR (go_gtk_builder_get_widget (gui, "format_scroll"));
536 state->gridlines = GTK_CHECK_MENU_ITEM (go_gtk_builder_get_widget (gui, "format_gridlines"));
537
538 state->info_name = GTK_ENTRY (go_gtk_builder_get_widget (gui, "format_info_name"));
539 state->info_author = GTK_ENTRY (go_gtk_builder_get_widget (gui, "format_info_author"));
540 state->info_cat = GTK_ENTRY (go_gtk_builder_get_widget (gui, "format_info_cat"));
541 state->info_descr = GTK_TEXT_VIEW (go_gtk_builder_get_widget (gui, "format_info_descr"));
542
543 state->ok = GTK_BUTTON (go_gtk_builder_get_widget (gui, "format_ok"));
544 state->cancel = GTK_BUTTON (go_gtk_builder_get_widget (gui, "format_cancel"));
545
546 #define CHECK_ITEM(v_, w_,h_) do { \
547 GtkWidget *w = go_gtk_builder_get_widget (gui, (w_)); \
548 state->v_ = GTK_CHECK_MENU_ITEM (w); \
549 g_signal_connect (w, "activate", G_CALLBACK (h_), state); \
550 } while (0)
551
552 CHECK_ITEM (number, "number_menuitem", cb_check_item_toggled);
553 CHECK_ITEM (border, "border_menuitem", cb_check_item_toggled);
554 CHECK_ITEM (font, "font_menuitem", cb_check_item_toggled);
555 CHECK_ITEM (patterns, "pattern_menuitem", cb_check_item_toggled);
556 CHECK_ITEM (alignment, "alignment_menuitem", cb_check_item_toggled);
557 CHECK_ITEM (edges.left, "left_menuitem", cb_check_item_toggled);
558 CHECK_ITEM (edges.right, "right_menuitem", cb_check_item_toggled);
559 CHECK_ITEM (edges.top, "top_menuitem", cb_check_item_toggled);
560 CHECK_ITEM (edges.bottom, "bottom_menuitem", cb_check_item_toggled);
561 CHECK_ITEM (gridlines, "gridlines_menuitem", cb_gridlines_item_toggled);
562
563 #undef CHECK_ITEM
564
565 for (i = 0; i < NUM_PREVIEWS; i++) {
566 char *name;
567
568 name = g_strdup_printf ("format_frame%d", i+1);
569 state->frame[i] = GTK_FRAME (go_gtk_builder_get_widget (gui, name));
570 g_free (name);
571
572 state->canvas[i] = GOC_CANVAS (g_object_new (GOC_TYPE_CANVAS, NULL));
573 gtk_widget_set_size_request (GTK_WIDGET (state->canvas[i]),
574 TOTAL_WIDTH + (2 * BORDER),
575 TOTAL_HEIGHT + (2 * BORDER));
576 gtk_container_add (GTK_CONTAINER (state->frame[i]),
577 GTK_WIDGET (state->canvas[i]));
578
579 g_signal_connect (G_OBJECT (state->canvas[i]),
580 "button-press-event",
581 G_CALLBACK (cb_canvas_button_press), state);
582 g_signal_connect (G_OBJECT (state->canvas[i]),
583 "focus",
584 G_CALLBACK (cb_canvas_focus), state);
585 }
586
587 g_signal_connect (G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (state->scroll))),
588 "value_changed",
589 G_CALLBACK (cb_scroll_value_changed), state);
590 g_signal_connect (G_OBJECT (state->gridlines),
591 "toggled",
592 G_CALLBACK (cb_gridlines_item_toggled), state);
593 g_signal_connect (G_OBJECT (state->ok),
594 "clicked",
595 G_CALLBACK (cb_ok_clicked), state);
596 g_signal_connect_swapped (G_OBJECT (state->cancel), "clicked",
597 G_CALLBACK (gtk_widget_destroy), state->dialog);
598
599 /* Fill category list */
600 state->category_groups =
601 g_list_sort (gnm_ft_category_group_list_get (), gnm_ft_category_group_cmp);
602
603 if (state->category_groups == NULL) {
604 GtkWidget *dialog;
605
606 dialog = gtk_message_dialog_new (GTK_WINDOW (state->dialog),
607 GTK_DIALOG_DESTROY_WITH_PARENT,
608 GTK_MESSAGE_WARNING,
609 GTK_BUTTONS_CLOSE,
610 _("An error occurred while reading the category list"));
611 gtk_dialog_run (GTK_DIALOG (dialog));
612 } else {
613 unsigned i, select = 0;
614 GList *ptr = state->category_groups;
615 GtkListStore* store = gtk_list_store_new (1, G_TYPE_STRING);
616 GtkTreeIter iter;
617 GtkCellRenderer *renderer = (GtkCellRenderer*) gtk_cell_renderer_text_new();
618 gtk_combo_box_set_model (state->category, GTK_TREE_MODEL (store));
619 g_object_unref (store);
620 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (state->category), renderer, TRUE);
621 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (state->category), renderer,
622 "text", 0,
623 NULL);
624
625 for (i = 0 ; ptr != NULL ; ptr = ptr->next, i++) {
626 GnmFTCategoryGroup *group = ptr->data;
627 if (!strcmp (group->name, "General" ))
628 select = i;
629 gtk_list_store_append (store, &iter);
630 gtk_list_store_set (store, &iter,
631 0, _(group->name),
632 -1);
633 }
634
635 g_signal_connect_swapped (G_OBJECT (state->category),
636 "changed",
637 G_CALLBACK (cb_category_changed), state);
638 gtk_combo_box_set_active (GTK_COMBO_BOX (state->category), select);
639 gtk_widget_show_all (GTK_WIDGET (state->category));
640 }
641
642 gnm_init_help_button (
643 go_gtk_builder_get_widget (gui, "help_button"),
644 GNUMERIC_HELP_LINK_AUTOFORMAT);
645
646 gtk_dialog_set_default_response (state->dialog, GTK_RESPONSE_OK);
647
648 /* a candidate for merging into attach guru */
649 go_gtk_nonmodal_dialog (wbcg_toplevel (state->wbcg),
650 GTK_WINDOW (state->dialog));
651 wbc_gtk_attach_guru (state->wbcg, GTK_WIDGET (state->dialog));
652 g_object_set_data_full (G_OBJECT (state->dialog),
653 "state", state, (GDestroyNotify)cb_autoformat_destroy);
654
655 /* not show all or the scrollbars will appear */
656 gtk_widget_show (GTK_WIDGET (state->dialog));
657 g_object_unref (gui);
658 }
659