dialog-stf-format-page.c 24.5 KB
Newer Older
1
/*
Morten Welinder's avatar
Morten Welinder committed
2
 * dialog-stf-format-page.c : Controls the widgets on the format page of the dialog
3
 *
4 5
 * Copyright 2001 Almer S. Tigelaar <almer@gnome.org>
 * Copyright 2003 Morten Welinder <terra@gnome.org>
6
 *
jpekka's avatar
jpekka committed
7 8 9 10 11 12 13 14 15 16 17
 * 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) any later version.
 *
 * 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
18
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
19 20
 */

21
#include <gnumeric-config.h>
22
#include <glib/gi18n-lib.h>
23
#include <gnumeric.h>
24
#include <libgnumeric.h>
25
#include <dialogs/dialog-stf.h>
26
#include <gnm-format.h>
27
#include <sheet.h>
28
#include <workbook.h>
29
#include <workbook-control.h>
30
#include <gui-util.h>
31
#include <gdk/gdkkeysyms.h>
32 33 34 35 36

/*************************************************************************************************
 * MISC UTILITY FUNCTIONS
 *************************************************************************************************/

37 38
static void format_page_update_preview (StfDialogData *pagedata);

39 40 41 42
static void
format_page_update_column_selection (StfDialogData *pagedata)
{
	char *text = NULL;
Morten Welinder's avatar
Morten Welinder committed
43

44 45 46 47 48 49 50 51 52
	if (pagedata->format.col_import_count == pagedata->format.col_import_array_len) {
		text = g_strdup_printf (_("Importing %i columns and ignoring none."),
					pagedata->format.col_import_count);
	} else {
		text = g_strdup_printf (_("Importing %i columns and ignoring %i."),
					pagedata->format.col_import_count,
					pagedata->format.col_import_array_len - pagedata->format.col_import_count);
	}

Morten Welinder's avatar
Morten Welinder committed
53
	gtk_label_set_text (GTK_LABEL (pagedata->format.column_selection_label), text);
54 55 56 57

	g_free (text);
}

58
static void
59
format_page_trim_menu_changed (G_GNUC_UNUSED GtkMenu *menu,
60
				  StfDialogData *data)
61
{
62
	StfTrimType_t trim;
63
	int trimtype = gtk_combo_box_get_active (GTK_COMBO_BOX (data->format.format_trim));
64 65 66

	switch (trimtype) {
	case -1:
67 68
	case 0:
		trim = TRIM_TYPE_LEFT | TRIM_TYPE_RIGHT;
69
		break;
70 71 72 73 74
	default:
		g_warning ("Unknown trim type selected (%d)", trimtype);
		/* Fall through.  */
	case 1:
		trim = TRIM_TYPE_NEVER;
75
		break;
76 77
	case 2:
		trim = TRIM_TYPE_LEFT;
78
		break;
79 80
	case 3:
		trim = TRIM_TYPE_RIGHT;
81 82
		break;
	}
83 84

	stf_parse_options_set_trim_spaces (data->parseoptions, trim);
85
	format_page_update_preview (data);
86 87
}

88 89 90 91 92 93 94
/*
 * More or less a copy of gtk_tree_view_clamp_column_visible.
 */
static void
tree_view_clamp_column_visible (GtkTreeView       *tree_view,
				GtkTreeViewColumn *column)
{
95
	GtkAdjustment *hadjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (tree_view));
96 97
	double hval = gtk_adjustment_get_value (hadjustment);
	double hps = gtk_adjustment_get_page_size (hadjustment);
98
	GtkWidget *button = gtk_tree_view_column_get_button (column);
99
	GtkAllocation ba;
100

101
	gtk_widget_get_allocation (button, &ba);
Morten Welinder's avatar
Morten Welinder committed
102

103
	if (hval + hps < ba.x + ba.width)
104
		gtk_adjustment_set_value (hadjustment,
105 106 107
					  ba.x + ba.width - hps);
	else if (hval > ba.x)
		gtk_adjustment_set_value (hadjustment, ba.x);
108 109
}

110 111 112 113
static void
activate_column (StfDialogData *pagedata, int i)
{
	GtkCellRenderer *cell;
114
	GtkTreeViewColumn *column;
115 116 117 118 119 120 121 122 123 124 125
	RenderData_t *renderdata = pagedata->format.renderdata;

	cell = stf_preview_get_cell_renderer (renderdata,
					      pagedata->format.index);
	if (cell) {
		g_object_set (G_OBJECT (cell),
			      "background", NULL,
			      NULL);
	}

	pagedata->format.index = i;
126 127 128 129 130 131 132

	column = stf_preview_get_column (renderdata, i);
	if (column) {
		tree_view_clamp_column_visible (renderdata->tree_view, column);
	}

	cell = stf_preview_get_cell_renderer (renderdata, i);
133 134 135 136 137 138 139 140 141 142
	if (cell) {
		g_object_set (G_OBJECT (cell),
			      "background", "lightgrey",
			      NULL);
		gtk_widget_queue_draw (GTK_WIDGET (renderdata->tree_view));
	}

	/* FIXME: warp focus away from the header.  */
}

143 144
static void
cb_col_check_clicked (GtkToggleButton *togglebutton, gpointer _i)
145 146 147 148 149
{
	int i = GPOINTER_TO_INT (_i);
	StfDialogData *pagedata =
		g_object_get_data (G_OBJECT (togglebutton), "pagedata");
	gboolean active = gtk_toggle_button_get_active (togglebutton);
150
	GtkCellRenderer *renderer;
151 152
	GtkTreeViewColumn* column;
	GtkWidget *check_autofit;
153

154 155
	g_return_if_fail (i < pagedata->format.col_import_array_len);

156
	if (pagedata->format.col_import_array[i] == active)
157
		return;
158 159 160

	renderer = stf_preview_get_cell_renderer (pagedata->format.renderdata, i);
	g_object_set (G_OBJECT (renderer), "strikethrough", !active, NULL);
161
	gtk_widget_queue_draw (GTK_WIDGET (pagedata->format.renderdata->tree_view));
162

163
	if (!active) {
164
		pagedata->format.col_import_array[i] = FALSE;
165 166
		pagedata->format.col_import_count--;
		format_page_update_column_selection (pagedata);
167
	} else {
168
		if (pagedata->format.col_import_count < GNM_MAX_COLS) {
169 170
			pagedata->format.col_import_array[i] = TRUE;
			pagedata->format.col_import_count++;
171
			format_page_update_column_selection (pagedata);
172
		} else {
Morten Welinder's avatar
Morten Welinder committed
173
			char *msg = g_strdup_printf(
174 175
				ngettext("A maximum of %d column can be imported.",
					 "A maximum of %d columns can be imported.",
Morten Welinder's avatar
Morten Welinder committed
176
					 GNM_MAX_COLS),
177
				GNM_MAX_COLS);
178
			gtk_toggle_button_set_active (togglebutton, FALSE);
Jody Goldberg's avatar
Jody Goldberg committed
179
			go_gtk_notice_dialog (GTK_WINDOW (pagedata->dialog),
180 181
					      GTK_MESSAGE_WARNING,
					      "%s", msg);
182 183
			g_free (msg);
		}
184
	}
185 186 187 188 189 190 191 192

	column = stf_preview_get_column (pagedata->format.renderdata, i);
	check_autofit = g_object_get_data (G_OBJECT (column), "checkbox-autofit");

	gtk_widget_set_sensitive (check_autofit, active);
	return;
}

Morten Welinder's avatar
Morten Welinder committed
193
static void
194 195 196 197 198 199
cb_format_clicked (GtkButton *widget, gpointer _i)
{
	int i = GPOINTER_TO_INT (_i);
	StfDialogData *pagedata =
		g_object_get_data (G_OBJECT (widget), "pagedata");
	gint result;
Morten Welinder's avatar
Morten Welinder committed
200
	GtkWidget *dialog = gtk_dialog_new_with_buttons
201 202 203
		(_("Format Selector"),
		 GTK_WINDOW (pagedata->dialog),
		 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
204 205
		 GNM_STOCK_OK,      GTK_RESPONSE_ACCEPT,
		 GNM_STOCK_CANCEL,  GTK_RESPONSE_REJECT,
206
		 NULL);
207
	GOFormatSel *format_selector
208
		= GO_FORMAT_SEL (go_format_sel_new_full (TRUE));
209 210
	GtkWidget *w = gtk_dialog_get_content_area (GTK_DIALOG (dialog));

Morten Welinder's avatar
Morten Welinder committed
211
	go_format_sel_set_style_format (format_selector, g_ptr_array_index (pagedata->format.formats, i));
212 213 214 215 216 217
	go_format_sel_set_locale (format_selector, pagedata->locale);
	gtk_box_pack_start (GTK_BOX (w), GTK_WIDGET (format_selector),
			    FALSE, TRUE, 5);
	gtk_widget_show (GTK_WIDGET (format_selector));

	result = gtk_dialog_run (GTK_DIALOG (dialog));
Morten Welinder's avatar
Morten Welinder committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
	switch (result) {
	case GTK_RESPONSE_ACCEPT: {
		GOFormat *sf;
		GtkTreeViewColumn* column = stf_preview_get_column (pagedata->format.renderdata, i);
		GtkWidget *format_label = g_object_get_data (G_OBJECT (column),
							     "formatlabel");

		sf = g_ptr_array_index (pagedata->format.formats, i);
		go_format_unref (sf);

		sf = go_format_ref (go_format_sel_get_fmt (format_selector));
		gtk_button_set_label (GTK_BUTTON (format_label),
				      go_format_sel_format_classification (sf));
		g_ptr_array_index (pagedata->format.formats, i) = sf;

		format_page_update_preview (pagedata);
		break;
	}
	default:
		break;
	}
239 240 241 242
	gtk_widget_destroy (dialog);
	return;
}

243 244 245 246 247 248 249 250 251 252 253 254
static void
cb_col_check_autofit_clicked (GtkToggleButton *togglebutton, gpointer _i)
{
	int i = GPOINTER_TO_INT (_i);
	StfDialogData *pagedata =
		g_object_get_data (G_OBJECT (togglebutton), "pagedata");
	gboolean active = gtk_toggle_button_get_active (togglebutton);

	g_return_if_fail (i < pagedata->format.col_import_array_len);

	pagedata->format.col_autofit_array[i] = active;

255 256 257
	return;
}

Morten Welinder's avatar
Morten Welinder committed
258
static void
259 260 261 262 263 264 265
check_columns_for_import (StfDialogData *pagedata, int from, int to)
{
	int i;

	g_return_if_fail (pagedata != NULL);
	g_return_if_fail (!(from < 0));
	g_return_if_fail (to < pagedata->format.renderdata->colcount);
266
	g_return_if_fail (to < pagedata->format.col_import_array_len);
267 268 269 270 271

	for (i = from; i <= to; i++) {
		if (!pagedata->format.col_import_array[i]) {
			GtkTreeViewColumn* column = stf_preview_get_column (pagedata->format.renderdata, i);
			GtkWidget *w = g_object_get_data (G_OBJECT (column), "checkbox");
272 273
			if (pagedata->format.col_import_count >= GNM_MAX_COLS)
				break;
274
			gtk_widget_hide (w);
275
			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), TRUE);
276 277 278 279 280 281 282
			/* Note this caused a signal to be send that sets the */
			/* pagedata fields */
			gtk_widget_show (w);
		}
	}
}

Morten Welinder's avatar
Morten Welinder committed
283
static void
284 285 286
uncheck_columns_for_import (StfDialogData *pagedata, int from, int to)
{
	int i;
Morten Welinder's avatar
Morten Welinder committed
287

288 289 290
	g_return_if_fail (pagedata != NULL);
	g_return_if_fail (!(from < 0));
	g_return_if_fail (to < pagedata->format.renderdata->colcount);
291
	g_return_if_fail (to < pagedata->format.col_import_array_len);
Morten Welinder's avatar
Morten Welinder committed
292

293 294 295 296
	for (i = from; i <= to; i++) {
		if (pagedata->format.col_import_array[i]) {
			GtkTreeViewColumn* column = stf_preview_get_column (pagedata->format.renderdata, i);
			GtkWidget *w = g_object_get_data (G_OBJECT (column), "checkbox");
Morten Welinder's avatar
Morten Welinder committed
297

298
			gtk_widget_hide (w);
299
			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), FALSE);
300 301 302 303 304 305 306
			/* Note this caused a signal to be send that sets the */
			/* pagedata fields */
			gtk_widget_show (w);
		}
	}
}

307 308 309
static void
cb_popup_menu_uncheck_right (GtkWidget *widget, gpointer data)
{
310
	StfDialogData *pagedata = data;
Morten Welinder's avatar
Morten Welinder committed
311

312 313
	uncheck_columns_for_import (pagedata, pagedata->format.index + 1,
				    pagedata->format.renderdata->colcount - 1);
314 315 316 317 318
}

static void
cb_popup_menu_check_right (GtkWidget *widget, gpointer data)
{
319
	StfDialogData *pagedata = data;
Morten Welinder's avatar
Morten Welinder committed
320

321
	check_columns_for_import (pagedata, pagedata->format.index + 1,
322
				  pagedata->format.renderdata->colcount - 1);
323 324 325 326 327 328
}

static void
cb_popup_menu_uncheck_left (GtkWidget *widget, gpointer data)
{
	StfDialogData *pagedata = data;
Morten Welinder's avatar
Morten Welinder committed
329

330 331 332 333 334 335 336
	uncheck_columns_for_import (pagedata, 0, pagedata->format.index - 1);
}

static void
cb_popup_menu_check_left (GtkWidget *widget, gpointer data)
{
	StfDialogData *pagedata = data;
Morten Welinder's avatar
Morten Welinder committed
337

338
	check_columns_for_import (pagedata, 0, pagedata->format.index - 1);
339 340 341 342 343 344 345
}

static void
cb_popup_menu_extend_format (GtkWidget *widget, gpointer data)
{
	StfDialogData *pagedata = data;
	guint index = pagedata->format.index;
Morten Welinder's avatar
Morten Welinder committed
346 347
	GPtrArray *formats = pagedata->format.formats;
	GOFormat *colformat = g_ptr_array_index (formats, pagedata->format.index);
348

Morten Welinder's avatar
Morten Welinder committed
349 350
	for (index++; index < formats->len; index++) {
		GOFormat *sf = g_ptr_array_index (formats, index);
Morten Welinder's avatar
Morten Welinder committed
351 352
		GtkTreeViewColumn* column =
			stf_preview_get_column (pagedata->format.renderdata,
353
						index);
Morten Welinder's avatar
Morten Welinder committed
354
		GtkWidget *w = g_object_get_data (G_OBJECT (column),
355
						  "formatlabel");
356
		go_format_unref (sf);
Morten Welinder's avatar
Morten Welinder committed
357
		g_ptr_array_index (formats, index) = go_format_ref (colformat);
358
		gtk_button_set_label (GTK_BUTTON (w),
Morten Welinder's avatar
Morten Welinder committed
359
				      go_format_sel_format_classification (colformat));
360 361 362 363 364
	}

	format_page_update_preview (data);
}

365 366
static void
format_context_menu (StfDialogData *pagedata,
367
		     GdkEvent *event,
368
		     int col)
369 370 371 372 373 374 375 376
{
	enum {
		COLUMN_POPUP_ITEM_IGNORE,
		COLUMN_POPUP_ITEM_NOT_FIRST,
		COLUMN_POPUP_ITEM_NOT_LAST,
		COLUMN_POPUP_ITEM_ANY
	};

377
	static const struct {
378 379
		const char *text;
		void (*function) (GtkWidget *widget, gpointer data);
380 381
		int flags;
	} actions[] = {
382 383 384 385
		{ N_("Ignore all columns on right"), &cb_popup_menu_uncheck_right, COLUMN_POPUP_ITEM_NOT_LAST},
		{ N_("Ignore all columns on left"), &cb_popup_menu_uncheck_left, COLUMN_POPUP_ITEM_NOT_FIRST},
		{ N_("Import all columns on right"), &cb_popup_menu_check_right, COLUMN_POPUP_ITEM_NOT_LAST},
		{ N_("Import all columns on left"), &cb_popup_menu_check_left, COLUMN_POPUP_ITEM_NOT_FIRST},
386
		{ N_("Copy format to right"), &cb_popup_menu_extend_format, COLUMN_POPUP_ITEM_NOT_LAST}
387
	};
Morten Welinder's avatar
Morten Welinder committed
388

389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
	GtkWidget *menu = gtk_menu_new ();
	unsigned i;

	for (i = 0; i < G_N_ELEMENTS (actions); i++) {
		int flags = actions[i].flags;
		GtkWidget *item = gtk_menu_item_new_with_label
			(_(actions[i].text));
		switch (flags) {
		case COLUMN_POPUP_ITEM_IGNORE:
			gtk_widget_set_sensitive (item, FALSE);
			break;
		case COLUMN_POPUP_ITEM_NOT_FIRST:
			gtk_widget_set_sensitive (item, col > 0);
			break;
		case COLUMN_POPUP_ITEM_NOT_LAST:
Morten Welinder's avatar
Morten Welinder committed
404
			gtk_widget_set_sensitive
405 406 407 408 409 410 411 412 413 414 415 416 417 418
				(item, col < pagedata->format.renderdata->colcount - 1);
			break;
		case COLUMN_POPUP_ITEM_ANY:
		default:
			break;
		}
		gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
		gtk_widget_show (item);
		g_signal_connect (G_OBJECT (item),
				  "activate",
				  G_CALLBACK (actions[i].function),
				  pagedata);
	}

419
	gnumeric_popup_menu (GTK_MENU (menu), event);
420 421 422 423 424 425 426
}


static gint
cb_col_event (GtkWidget *widget, GdkEvent *event, gpointer _col)
{
	if (event->type == GDK_BUTTON_PRESS) {
427
		GdkEventButton *event_button = &event->button;
428 429
		StfDialogData *pagedata =
			g_object_get_data (G_OBJECT (widget), "pagedata");
430
		int col = GPOINTER_TO_INT (_col);
431

432
		activate_column (pagedata, col);
433 434 435

		if (event_button->button == 1) {
			GtkWidget *check = g_object_get_data (G_OBJECT (widget), "checkbox");
436
			GtkAllocation a;
437
			/*
438 439
			 * We use overlapping buttons and that does not
			 * actually work...
440
			 *
441
			 * In a square area the height of the hbox, click the
442 443
			 * checkbox.
			 */
444 445 446 447 448 449
			int xmax;

			gtk_widget_get_allocation
				(gtk_bin_get_child (GTK_BIN (widget)),
				 &a);
			xmax = a.height;
450 451 452
			if (event_button->x <= xmax)
				gtk_button_clicked (GTK_BUTTON (check));
		} else if (event_button->button == 3) {
453
			format_context_menu (pagedata, event, col);
454
		}
455
		return TRUE;
456
	}
457

458 459 460
	return FALSE;
}

461 462 463 464 465 466 467 468 469 470 471 472 473 474
static gint
cb_treeview_button_press (GtkWidget *treeview,
			  GdkEventButton *event,
			  StfDialogData *pagedata)
{
	if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
		int dx, col;
		stf_preview_find_column (pagedata->format.renderdata, (int)event->x, &col, &dx);
		activate_column (pagedata, col);
		return TRUE;
	} else if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
		int dx, col;
		stf_preview_find_column (pagedata->format.renderdata, (int)event->x, &col, &dx);
		activate_column (pagedata, col);
475
		format_context_menu (pagedata, (GdkEvent*)event, col);
476 477 478 479 480 481
		return TRUE;
	}

	return FALSE;
}

482 483 484 485 486 487 488
static gint
cb_treeview_key_press (GtkWidget *treeview,
		       GdkEventKey *event,
		       StfDialogData *pagedata)
{
	if (event->type == GDK_KEY_PRESS) {
		switch (event->keyval) {
489 490
		case GDK_KEY_Left:
		case GDK_KEY_KP_Left:
491 492 493 494 495
			if (pagedata->format.index > 0)
				activate_column (pagedata,
						 pagedata->format.index - 1);
			return TRUE;

496 497
		case GDK_KEY_Right:
		case GDK_KEY_KP_Right:
498 499 500 501 502
			if (pagedata->format.index + 1 < (int)pagedata->format.formats->len)
				activate_column (pagedata,
						 pagedata->format.index + 1);
			return TRUE;

503 504
		case GDK_KEY_space:
		case GDK_KEY_Return: {
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
			GtkTreeViewColumn *column = stf_preview_get_column
				(pagedata->format.renderdata,
				 pagedata->format.index);
			GtkToggleButton *button =
				g_object_get_data (G_OBJECT (column),
						   "checkbox");
			gtk_toggle_button_set_active
				(button,
				 !gtk_toggle_button_get_active (button));
			return TRUE;
		}

		default:
			; /*  Nothing.  */
		}
	}

	return FALSE;
}
524

525
/**
526
 * format_page_update_preview
527
 * @pagedata: mother struct
528
 *
529 530
 * Will simply utilize the preview rendering functions to update
 * the preview
531
 *
532 533
 * returns : nothing
 **/
534
static void
535
format_page_update_preview (StfDialogData *pagedata)
536
{
Morten Welinder's avatar
Morten Welinder committed
537
	RenderData_t *renderdata = pagedata->format.renderdata;
538 539
	unsigned int ui;
	int i;
540
	int col_import_array_len_old, old_part;
541
	GStringChunk *lines_chunk;
542
	char *msg = NULL;
543

544
	stf_preview_colformats_clear (renderdata);
Morten Welinder's avatar
Morten Welinder committed
545
	for (ui = 0; ui < pagedata->format.formats->len; ui++) {
546
		GOFormat *sf = g_ptr_array_index (pagedata->format.formats, ui);
547
		stf_preview_colformats_add (renderdata, sf);
548
	}
549

550 551
	lines_chunk = g_string_chunk_new (100 * 1024);
	stf_preview_set_lines (renderdata, lines_chunk,
552
			       stf_parse_general (pagedata->parseoptions,
553
						  lines_chunk,
554
						  pagedata->cur,
555
						  pagedata->cur_end));
556

557 558
	col_import_array_len_old = pagedata->format.col_import_array_len;
	pagedata->format.col_import_array_len = renderdata->colcount;
559

560 561 562
	pagedata->format.col_autofit_array =
		g_renew(gboolean, pagedata->format.col_autofit_array,
			pagedata->format.col_import_array_len);
Morten Welinder's avatar
Morten Welinder committed
563 564
	pagedata->format.col_import_array =
		g_renew(gboolean, pagedata->format.col_import_array,
565
			pagedata->format.col_import_array_len);
Morten Welinder's avatar
Morten Welinder committed
566 567 568
	old_part = (col_import_array_len_old < pagedata->format.col_import_array_len)
		? col_import_array_len_old
		: pagedata->format.col_import_array_len;
569 570 571 572
	pagedata->format.col_import_count = 0;
	for (i = 0; i < old_part; i++)
		if (pagedata->format.col_import_array[i])
			pagedata->format.col_import_count++;
Morten Welinder's avatar
Morten Welinder committed
573
	for (i = old_part;
574
	     i < pagedata->format.col_import_array_len; i++) {
575
		if (pagedata->format.col_import_count < GNM_MAX_COLS) {
576 577 578
			pagedata->format.col_import_array[i] = TRUE;
			pagedata->format.col_import_count++;
		} else {
Morten Welinder's avatar
Morten Welinder committed
579
			pagedata->format.col_import_array[i] = FALSE;
580
		}
581 582
		pagedata->format.col_autofit_array[i] = TRUE;
	}
583 584

	format_page_update_column_selection (pagedata);
Morten Welinder's avatar
Morten Welinder committed
585

586
	if (old_part < renderdata->colcount)
Morten Welinder's avatar
Morten Welinder committed
587 588
		msg = g_strdup_printf
			(_("A maximum of %d columns can be imported."),
589
			 GNM_MAX_COLS);
590

591
	for (i = old_part; i < renderdata->colcount; i++) {
592 593
		GtkTreeViewColumn *column =
			stf_preview_get_column (renderdata, i);
594
		GtkWidget *button = gtk_tree_view_column_get_button (column);
Morten Welinder's avatar
Morten Welinder committed
595

596
		if (NULL == g_object_get_data (G_OBJECT (column), "checkbox")) {
597
			GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
Morten Welinder's avatar
Morten Welinder committed
598
			GtkWidget *check,
599
				*check_autofit = gtk_check_button_new_with_label (_("Auto fit"));
Morten Welinder's avatar
Morten Welinder committed
600
			char * label_text = g_strdup_printf
601
				(pagedata->format.col_header, i+1);
602 603 604
			GOFormat const *fmt = i < (int)pagedata->parseoptions->formats->len
				? g_ptr_array_index (pagedata->parseoptions->formats, i)
				: go_format_general ();
605
			GtkWidget *format_label = gtk_button_new_with_label
606
				(go_format_sel_format_classification (fmt));
Morten Welinder's avatar
Morten Welinder committed
607
			GtkWidget *format_icon
608
				= gtk_image_new_from_stock (GTK_STOCK_INFO, GTK_ICON_SIZE_BUTTON);
Morten Welinder's avatar
Morten Welinder committed
609

610
			check = gtk_check_button_new_with_label (label_text);
611
			g_free (label_text);
612
			gtk_button_set_image (GTK_BUTTON (format_label), format_icon);
Andreas J. Guelzow's avatar
Andreas J. Guelzow committed
613

Morten Welinder's avatar
Morten Welinder committed
614 615 616
			g_object_set (G_OBJECT (stf_preview_get_cell_renderer
						(pagedata->format.renderdata, i)),
				      "strikethrough",
617
				      !pagedata->format.col_import_array[i], NULL);
618 619
			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(check),
						      pagedata->
620
						      format.col_import_array[i]);
621 622 623 624
			label_text = g_strdup_printf
				(_("If this checkbox is selected, "
				   "column %i will be imported into "
				   "Gnumeric."), i+1);
625
			gtk_widget_set_tooltip_text
626
				(check,
627
				 label_text);
628
			gtk_widget_set_tooltip_text
629 630 631 632 633 634 635 636
				(check_autofit,
				 _("If this checkbox is selected, "
				   "the width of the column will be adjusted "
				   "to the longest entry."));
			g_free (label_text);
			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(check_autofit),
						      pagedata->
						      format.col_autofit_array[i]);
637
			g_object_set_data (G_OBJECT (check), "pagedata", pagedata);
638
			g_object_set_data (G_OBJECT (check_autofit), "pagedata", pagedata);
639
			g_object_set_data (G_OBJECT (format_label), "pagedata", pagedata);
640
			gtk_box_pack_start (GTK_BOX(vbox), check, FALSE, FALSE, 0);
Andreas J. Guelzow's avatar
Andreas J. Guelzow committed
641
			gtk_box_pack_start (GTK_BOX(vbox), format_label, TRUE, TRUE, 0);
642
			gtk_box_pack_start (GTK_BOX(vbox), check_autofit, TRUE, TRUE, 0);
Andreas J. Guelzow's avatar
Andreas J. Guelzow committed
643
			gtk_widget_show_all (vbox);
Morten Welinder's avatar
Morten Welinder committed
644

Andreas J. Guelzow's avatar
Andreas J. Guelzow committed
645
			gtk_tree_view_column_set_widget (column, vbox);
646 647
			g_object_set_data (G_OBJECT (column), "pagedata", pagedata);
			g_object_set_data (G_OBJECT (column), "checkbox", check);
648
			g_object_set_data (G_OBJECT (column), "checkbox-autofit", check_autofit);
Andreas J. Guelzow's avatar
Andreas J. Guelzow committed
649
			g_object_set_data (G_OBJECT (column), "formatlabel", format_label);
650
			g_object_set_data (G_OBJECT (button),
651
					   "pagedata", pagedata);
652
			g_object_set_data (G_OBJECT (button),
653
					   "checkbox", check);
654
			g_object_set_data (G_OBJECT (button),
Andreas J. Guelzow's avatar
Andreas J. Guelzow committed
655
					   "formatlabel", format_label);
656
			g_object_set (G_OBJECT (column), "clickable", TRUE, NULL);
657

658 659 660 661
			g_signal_connect (G_OBJECT (check),
					  "toggled",
					  G_CALLBACK (cb_col_check_clicked),
					  GINT_TO_POINTER (i));
662 663 664 665
			g_signal_connect (G_OBJECT (check_autofit),
					  "toggled",
					  G_CALLBACK (cb_col_check_autofit_clicked),
					  GINT_TO_POINTER (i));
666 667 668 669
			g_signal_connect (G_OBJECT (format_label),
					  "clicked",
					  G_CALLBACK (cb_format_clicked),
					  GINT_TO_POINTER (i));
670
			g_signal_connect (G_OBJECT (button),
671
					  "event",
Morten Welinder's avatar
Morten Welinder committed
672
					  G_CALLBACK (cb_col_event),
673 674
					  GINT_TO_POINTER (i));
		}
675
	}
676
	g_free (msg);
677 678 679 680 681 682
}

/*************************************************************************************************
 * SIGNAL HANDLERS
 *************************************************************************************************/

683
static void
684 685
locale_changed_cb (GOLocaleSel *ls, char const *new_locale,
		   StfDialogData *pagedata)
686
{
687 688
	g_free (pagedata->locale);
	pagedata->locale = g_strdup (new_locale);
689 690 691
}

/**
692
 * stf_dialog_format_page_prepare
693
 * @pagedata: mother struct
694 695 696
 *
 * This will prepare the widgets on the format page before
 * the page gets displayed
697
 **/
698 699
void
stf_dialog_format_page_prepare (StfDialogData *data)
700
{
701
	GOFormat *general = go_format_general ();
702
	GPtrArray *formats = data->parseoptions->formats;
703

704
	/* Set the trim.  */
705
	format_page_trim_menu_changed (NULL, data);
706

707
	/* If necessary add new items (non-visual) */
708 709 710 711 712 713 714
	while ((int)data->format.formats->len < data->format.renderdata->colcount) {
		GOFormat const *fmt =
			data->format.formats->len < formats->len
			? g_ptr_array_index (formats, data->format.formats->len)
			: general;
		g_ptr_array_add (data->format.formats, go_format_ref (fmt));
	}
715

Morten Welinder's avatar
Morten Welinder committed
716
	data->format.manual_change = TRUE;
717
	activate_column (data, 0);
718 719
}

720 721 722 723
/*************************************************************************************************
 * FORMAT EXPORTED FUNCTIONS
 *************************************************************************************************/

724
void
725
stf_dialog_format_page_cleanup (StfDialogData *pagedata)
726
{
Morten Welinder's avatar
Morten Welinder committed
727
	GPtrArray *formats = pagedata->format.formats;
Morten Welinder's avatar
Morten Welinder committed
728
	if (formats)
729 730
		g_ptr_array_free (formats, TRUE);

Morten Welinder's avatar
Morten Welinder committed
731
	stf_preview_free (pagedata->format.renderdata);
732
	g_free (pagedata->format.col_import_array);
733
	g_free (pagedata->format.col_autofit_array);
734
	pagedata->format.col_import_array = NULL;
735
	pagedata->format.col_autofit_array = NULL;
736
	pagedata->format.col_import_array_len = 0;
Morten Welinder's avatar
Morten Welinder committed
737
	pagedata->format.col_import_count = 0;
738 739 740
}

void
741
stf_dialog_format_page_init (GtkBuilder *gui, StfDialogData *pagedata)
742
{
743
/* 	GtkWidget * format_hbox; */
744 745 746

	g_return_if_fail (gui != NULL);
	g_return_if_fail (pagedata != NULL);
747

748
        /* Create/get object and fill information struct */
749
	pagedata->format.col_import_array = NULL;
750
	pagedata->format.col_autofit_array = NULL;
751
	pagedata->format.col_import_array_len = 0;
752
	pagedata->format.col_import_count = 0;
753
	pagedata->format.col_header = _("Column %d");
Morten Welinder's avatar
Morten Welinder committed
754

Morten Welinder's avatar
Morten Welinder committed
755 756 757
	pagedata->format.format_data_container = go_gtk_builder_get_widget (gui, "format_data_container");
	pagedata->format.format_trim   = go_gtk_builder_get_widget (gui, "format_trim");
	pagedata->format.column_selection_label   = go_gtk_builder_get_widget (gui, "column_selection_label");
Emmanuel Pacaud's avatar
Emmanuel Pacaud committed
758

759
	pagedata->format.locale_selector =
760
		GO_LOCALE_SEL (go_locale_sel_new ());
761 762 763 764
	if (pagedata->locale && !go_locale_sel_set_locale (pagedata->format.locale_selector, pagedata->locale)) {
		g_free (pagedata->locale);
		pagedata->locale = go_locale_sel_get_locale (pagedata->format.locale_selector);
	}
765 766
	gtk_grid_attach (
		GTK_GRID (go_gtk_builder_get_widget (gui, "locale-grid")),
767
		GTK_WIDGET (pagedata->format.locale_selector),
768
		3, 0, 1, 1);
769
	gtk_widget_show_all (GTK_WIDGET (pagedata->format.locale_selector));
770 771
	gtk_widget_set_sensitive
		(GTK_WIDGET (pagedata->format.locale_selector),
772
		 !pagedata->fixed_locale);
773

774
	/* Set properties */
Morten Welinder's avatar
Morten Welinder committed
775
	pagedata->format.renderdata =
776
		stf_preview_new (pagedata->format.format_data_container,
Morten Welinder's avatar
Morten Welinder committed
777
				 workbook_date_conv (wb_control_get_workbook (GNM_WBC (pagedata->wbcg))));
Morten Welinder's avatar
Morten Welinder committed
778 779
	pagedata->format.formats = g_ptr_array_new_with_free_func ((GDestroyNotify)go_format_unref);
	pagedata->format.index = -1;
Morten Welinder's avatar
Morten Welinder committed
780
	pagedata->format.manual_change = FALSE;
781

782 783 784 785 786
	/* Update widgets before connecting signals, see #333407.  */
	gtk_combo_box_set_active (GTK_COMBO_BOX (pagedata->format.format_trim),
				  0);
	format_page_update_column_selection (pagedata);

787
	/* Connect signals */
788 789 790
	g_signal_connect (G_OBJECT (pagedata->format.locale_selector),
			  "locale_changed",
			  G_CALLBACK (locale_changed_cb), pagedata);
791

792 793 794
        g_signal_connect (G_OBJECT (pagedata->format.format_trim),
			  "changed",
			  G_CALLBACK (format_page_trim_menu_changed), pagedata);
795 796 797 798
	g_signal_connect (G_OBJECT (pagedata->format.renderdata->tree_view),
			  "button_press_event",
			  G_CALLBACK (cb_treeview_button_press),
			  pagedata);
799 800 801 802
	g_signal_connect (G_OBJECT (pagedata->format.renderdata->tree_view),
			  "key_press_event",
			  G_CALLBACK (cb_treeview_key_press),
			  pagedata);
803
}