dialog-stf-fixed-page.c 17.7 KB
Newer Older
1
/*
Morten Welinder's avatar
Morten Welinder committed
2
 * dialog-stf-fixed-page.c : Controls the widgets on the fixed page of the dialog (fixed-width page that is)
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 18 19
 * 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
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 21
 */

22
#include <gnumeric-config.h>
23
#include <glib/gi18n-lib.h>
24
#include <gnumeric.h>
25
#include "dialog-stf.h"
26
#include <gui-util.h>
27
#include <gdk/gdkkeysyms.h>
28
#include <gtk/gtk.h>
29 30 31 32 33

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

34 35 36
/**
 * fixed_page_autodiscover:
 * @pagedata: a mother struct
37
 *
38 39 40 41
 * Use the STF's autodiscovery function and put the
 * result in the fixed_collist
 **/
static void
42
fixed_page_autodiscover (StfDialogData *pagedata)
43
{
44
	stf_parse_options_fixed_autodiscover (pagedata->parseoptions,
45
					      pagedata->cur, pagedata->cur_end);
46

47
	if (pagedata->parseoptions->splitpositions->len <= 1) {
48 49 50 51 52
		GtkWidget *dialog = gtk_message_dialog_new (NULL,
			GTK_DIALOG_DESTROY_WITH_PARENT,
			GTK_MESSAGE_INFO,
			GTK_BUTTONS_OK,
			_("Autodiscovery did not find any columns in the text. Try manually"));
Jody Goldberg's avatar
Jody Goldberg committed
53
		go_gtk_dialog_run (GTK_DIALOG (dialog), GTK_WINDOW (pagedata->dialog));
54 55 56
	}
}

57
static void fixed_page_update_preview (StfDialogData *pagedata);
58

59 60 61 62 63 64 65 66 67
enum {
	CONTEXT_STF_IMPORT_MERGE_LEFT = 1,
	CONTEXT_STF_IMPORT_MERGE_RIGHT = 2,
	CONTEXT_STF_IMPORT_SPLIT = 3,
	CONTEXT_STF_IMPORT_WIDEN = 4,
	CONTEXT_STF_IMPORT_NARROW = 5
};

static GnumericPopupMenuElement const popup_elements[] = {
68
	{ N_("Merge with column on _left"), GTK_STOCK_REMOVE,
69
	  0, 1 << CONTEXT_STF_IMPORT_MERGE_LEFT, CONTEXT_STF_IMPORT_MERGE_LEFT },
70
	{ N_("Merge with column on _right"), GTK_STOCK_REMOVE,
71 72
	  0, 1 << CONTEXT_STF_IMPORT_MERGE_RIGHT, CONTEXT_STF_IMPORT_MERGE_RIGHT },
	{ "", NULL, 0, 0, 0 },
73
	{ N_("_Split this column"), NULL,
74 75
	  0, 1 << CONTEXT_STF_IMPORT_SPLIT, CONTEXT_STF_IMPORT_SPLIT },
	{ "", NULL, 0, 0, 0 },
76
	{ N_("_Widen this column"), GTK_STOCK_GO_FORWARD,
77
	  0, 1 << CONTEXT_STF_IMPORT_WIDEN, CONTEXT_STF_IMPORT_WIDEN },
78
	{ N_("_Narrow this column"), GTK_STOCK_GO_BACK,
79 80 81 82
	  0, 1 << CONTEXT_STF_IMPORT_NARROW, CONTEXT_STF_IMPORT_NARROW },
	{ NULL, NULL, 0, 0, 0 },
};

83 84 85 86 87 88
static int
calc_char_index (RenderData_t *renderdata, int col, int *dx)
{
	GtkCellRenderer *cell =	stf_preview_get_cell_renderer (renderdata, col);
	PangoLayout *layout;
	PangoFontDescription *font_desc;
89 90 91
	int ci, width, padx;

	gtk_cell_renderer_get_padding (cell, &padx, NULL);
92 93 94 95 96 97 98 99 100

	g_object_get (G_OBJECT (cell), "font_desc", &font_desc, NULL);
	layout = gtk_widget_create_pango_layout (GTK_WIDGET (renderdata->tree_view), "x");
	pango_layout_set_font_description (layout, font_desc);
	pango_layout_get_pixel_size (layout, &width, NULL);
	g_object_unref (layout);
	pango_font_description_free (font_desc);

	if (width < 1) width = 1;
101
	ci = (*dx < padx) ? 0 : (*dx - padx + width / 2) / width;
102 103 104 105 106
	*dx -= ci * width;

	return ci;
}

107 108 109

static gboolean
make_new_column (StfDialogData *pagedata, int col, int dx, gboolean test_only)
110
{
111
	int charindex;
112 113 114 115 116 117 118
	RenderData_t *renderdata = pagedata->fixed.renderdata;
	int colstart, colend;

	colstart = (col == 0)
		? 0
		: stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col - 1);
	colend = stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col);
119

120
	charindex = colstart + calc_char_index (renderdata, col, &dx);
121 122

	if (charindex <= colstart || (colend != -1 && charindex >= colend))
123
		return FALSE;
124

125 126 127
	if (!test_only) {
		stf_parse_options_fixed_splitpositions_add (pagedata->parseoptions, charindex);
		fixed_page_update_preview (pagedata);
128 129
	}

130 131 132 133 134 135 136 137
	return TRUE;
}


static gboolean
widen_column (StfDialogData *pagedata, int col, gboolean test_only)
{
	int colcount = stf_parse_options_fixed_splitpositions_count (pagedata->parseoptions);
Morten Welinder's avatar
Morten Welinder committed
138
	int nextstart, nextnextstart;
139 140 141 142 143 144

	if (col >= colcount - 1)
		return FALSE;

	nextstart = stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col);

Morten Welinder's avatar
Morten Welinder committed
145 146 147
	nextnextstart = (col == colcount - 2)
		? pagedata->longest_line
		: stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col + 1);
148

Morten Welinder's avatar
Morten Welinder committed
149 150
	if (nextstart + 1 >= nextnextstart)
		return FALSE;
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209

	if (!test_only) {
		stf_parse_options_fixed_splitpositions_remove (pagedata->parseoptions, nextstart);
		stf_parse_options_fixed_splitpositions_add (pagedata->parseoptions, nextstart + 1);
		fixed_page_update_preview (pagedata);
	}
	return TRUE;
}

static gboolean
narrow_column (StfDialogData *pagedata, int col, gboolean test_only)
{
	int colcount = stf_parse_options_fixed_splitpositions_count (pagedata->parseoptions);
	int thisstart, nextstart;

	if (col >= colcount - 1)
		return FALSE;

	thisstart = (col == 0)
		? 0
		: stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col - 1);
	nextstart = stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col);

	if (nextstart - 1 <= thisstart)
		return FALSE;

	if (!test_only) {
		stf_parse_options_fixed_splitpositions_remove (pagedata->parseoptions, nextstart);
		stf_parse_options_fixed_splitpositions_add (pagedata->parseoptions, nextstart - 1);
		fixed_page_update_preview (pagedata);
	}
	return TRUE;
}

static gboolean
delete_column (StfDialogData *pagedata, int col, gboolean test_only)
{
	int colcount = stf_parse_options_fixed_splitpositions_count (pagedata->parseoptions);
	if (col < 0 || col >= colcount - 1)
		return FALSE;

	if (!test_only) {
		int nextstart = stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col);
		stf_parse_options_fixed_splitpositions_remove (pagedata->parseoptions, nextstart);
		fixed_page_update_preview (pagedata);
	}
	return TRUE;
}

static void
select_column (StfDialogData *pagedata, int col)
{
	int colcount = stf_parse_options_fixed_splitpositions_count (pagedata->parseoptions);
	GtkTreeViewColumn *column;

	if (col < 0 || col >= colcount)
		return;

	column = stf_preview_get_column (pagedata->fixed.renderdata, col);
210
	gtk_widget_grab_focus (gtk_tree_view_column_get_button (column));
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237
}

static gboolean
fixed_context_menu_handler (GnumericPopupMenuElement const *element,
			    gpointer user_data)
{
	StfDialogData *pagedata = user_data;
	int col = pagedata->fixed.context_col;

	switch (element->index) {
	case CONTEXT_STF_IMPORT_MERGE_LEFT:
		delete_column (pagedata, col - 1, FALSE);
		break;
	case CONTEXT_STF_IMPORT_MERGE_RIGHT:
		delete_column (pagedata, col, FALSE);
		break;
	case CONTEXT_STF_IMPORT_SPLIT:
		make_new_column (pagedata, col, pagedata->fixed.context_dx, FALSE);
		break;
	case CONTEXT_STF_IMPORT_WIDEN:
		widen_column (pagedata, col, FALSE);
		break;
	case CONTEXT_STF_IMPORT_NARROW:
		narrow_column (pagedata, col, FALSE);
		break;
	default:
		; /* Nothing */
238
	}
239
	return TRUE;
240 241
}

242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
static void
fixed_context_menu (StfDialogData *pagedata, GdkEventButton *event,
		    int col, int dx)
{
	int sensitivity_filter = 0;

	pagedata->fixed.context_col = col;
	pagedata->fixed.context_dx = dx;

	if (!delete_column (pagedata, col - 1, TRUE))
		sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_MERGE_LEFT);
	if (!delete_column (pagedata, col, TRUE))
		sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_MERGE_RIGHT);
	if (!make_new_column (pagedata, col, dx, TRUE))
		sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_SPLIT);
	if (!widen_column (pagedata, col, TRUE))
		sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_WIDEN);
	if (!narrow_column (pagedata, col, TRUE))
		sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_NARROW);

	select_column (pagedata, col);
	gnumeric_create_popup_menu (popup_elements, &fixed_context_menu_handler,
				    pagedata, 0,
265 266
				    sensitivity_filter,
				    (GdkEvent*)event);
267 268
}

269
static gint
270 271 272
cb_treeview_button_press (GtkWidget *treeview,
			  GdkEventButton *event,
			  StfDialogData *pagedata)
273
{
274
	if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
275
		int dx, col;
276
		stf_preview_find_column (pagedata->fixed.renderdata, (int)event->x, &col, &dx);
277 278
		make_new_column (pagedata, col, dx, FALSE);
		return TRUE;
279
	}
280

281 282
	if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
		int dx, col;
283
		stf_preview_find_column (pagedata->fixed.renderdata, (int)event->x, &col, &dx);
284 285 286 287
		fixed_context_menu (pagedata, event, col, dx);
		return TRUE;
	}

288 289 290 291
	return FALSE;
}


292
static gint
293 294 295
cb_col_button_press (GtkWidget *button,
		     GdkEventButton *event,
		     gpointer   _col)
296 297
{
	int col = GPOINTER_TO_INT (_col);
298 299 300
	StfDialogData *data = g_object_get_data (G_OBJECT (button), "fixed-data");

	if (event->type == GDK_2BUTTON_PRESS && event->button == 1) {
301 302
		GtkAllocation bca, ba;
		int offset;
303 304 305
		/* Split column.  */

		/* Correct for indentation of button.  */
306 307 308 309
		gtk_widget_get_allocation (gtk_bin_get_child (GTK_BIN (button)),
					   &bca);
		gtk_widget_get_allocation (button, &ba);
		offset = bca.x - ba.x;
310 311 312 313
		make_new_column (data, col, (int)event->x - offset, FALSE);

		return TRUE;
	}
314

315
	if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
316 317 318
		GtkAllocation bca, ba;
		int offset;

319
		/* Correct for indentation of button.  */
320 321 322 323
		gtk_widget_get_allocation (gtk_bin_get_child (GTK_BIN (button)),
					   &bca);
		gtk_widget_get_allocation (button, &ba);
		offset = bca.x - ba.x;
324

325
		fixed_context_menu (data, event, col, (int)event->x - offset);
326 327 328 329 330
		return TRUE;
	}

	return FALSE;
}
331

332 333 334 335 336 337 338 339 340 341
static gint
cb_col_key_press (GtkWidget *button,
		  GdkEventKey *event,
		  gpointer   _col)
{
	int col = GPOINTER_TO_INT (_col);
	StfDialogData *data = g_object_get_data (G_OBJECT (button), "fixed-data");

	if (event->type == GDK_KEY_PRESS) {
		switch (event->keyval) {
342 343 344
		case GDK_KEY_plus:
		case GDK_KEY_KP_Add:
		case GDK_KEY_greater:
345
			widen_column (data, col, FALSE);
346 347
			return TRUE;

348 349 350
		case GDK_KEY_minus:
		case GDK_KEY_KP_Subtract:
		case GDK_KEY_less:
351 352 353
			narrow_column (data, col, FALSE);
			return TRUE;

354 355
		case GDK_KEY_Left:
		case GDK_KEY_Up:
356 357
			select_column (data, col - 1);
			return TRUE;
358

359 360
		case GDK_KEY_Right:
		case GDK_KEY_Down:
361
			select_column (data, col + 1);
362
			return TRUE;
363 364 365

		default:
			; /*  Nothing.  */
366 367
		}
	}
368

369 370 371
	return FALSE;
}

372 373
/**
 * fixed_page_update_preview
374
 * @pagedata: mother struct
375 376 377 378 379 380
 *
 * Will simply update the preview
 *
 * returns : nothing
 **/
static void
381
fixed_page_update_preview (StfDialogData *pagedata)
382
{
383
	StfParseOptions_t *parseoptions = pagedata->parseoptions;
Morten Welinder's avatar
Morten Welinder committed
384
	RenderData_t *renderdata = pagedata->fixed.renderdata;
385
	int i;
386
	GStringChunk *lines_chunk;
387 388
	GPtrArray *lines;
	StfTrimType_t trim;
389

390 391
	lines_chunk = g_string_chunk_new (100 * 1024);

392
	/* Don't trim on this page.  */
393
	trim = parseoptions->trim_spaces;
394
	stf_parse_options_set_trim_spaces (parseoptions, TRIM_TYPE_NEVER);
395
	lines = stf_parse_general (parseoptions, lines_chunk,
396
				   pagedata->cur, pagedata->cur_end);
397 398
	stf_parse_options_set_trim_spaces (parseoptions, trim);

399
	stf_preview_set_lines (renderdata, lines_chunk, lines);
400

401 402 403 404 405
	for (i = 0; i < renderdata->colcount; i++) {
		GtkTreeViewColumn *column =
			stf_preview_get_column (renderdata, i);
		GtkCellRenderer *cell =
			stf_preview_get_cell_renderer (renderdata, i);
406 407
		GtkWidget *button =
			gtk_tree_view_column_get_button (column);
408

409 410
		gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);

411 412 413 414
		g_object_set (G_OBJECT (cell),
			      "family", "monospace",
			      NULL);

415
		g_object_set_data (G_OBJECT (button), "fixed-data", pagedata);
416
		g_object_set (G_OBJECT (column), "clickable", TRUE, NULL);
417
		g_signal_connect (button, "button_press_event",
418 419
				  G_CALLBACK (cb_col_button_press),
				  GINT_TO_POINTER (i));
420
		g_signal_connect (button, "key_press_event",
421
				  G_CALLBACK (cb_col_key_press),
422 423
				  GINT_TO_POINTER (i));
	}
424 425 426 427 428 429
}

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

430 431 432 433
/**
 * fixed_page_clear_clicked:
 * @button: GtkButton
 * @data: mother struct
434
 *
435 436 437
 * Will clear all entries in fixed_collist
 **/
static void
Morten Welinder's avatar
Morten Welinder committed
438
fixed_page_clear_clicked (G_GNUC_UNUSED GtkButton *button,
439
			  StfDialogData *data)
440
{
441
	stf_parse_options_fixed_splitpositions_clear (data->parseoptions);
442 443 444 445 446 447 448
	fixed_page_update_preview (data);
}

/**
 * fixed_page_auto_clicked:
 * @button: GtkButton
 * @data: mother struct
449
 *
450 451 452 453
 * Will try to automatically recognize columns in the
 * text.
 **/
static void
Morten Welinder's avatar
Morten Welinder committed
454
fixed_page_auto_clicked (G_GNUC_UNUSED GtkButton *button,
455
			 StfDialogData *data)
456 457 458 459 460 461
{
	fixed_page_autodiscover (data);

	fixed_page_update_preview (data);
}

462
/**
463
 * stf_dialog_fixed_page_prepare
464
 * @data: mother struct
465 466 467 468 469
 *
 * Will prepare the fixed page
 *
 * returns : nothing
 **/
470 471
void
stf_dialog_fixed_page_prepare (StfDialogData *pagedata)
472
{
473
	stf_parse_options_set_trim_spaces (pagedata->parseoptions, TRIM_TYPE_NEVER);
474 475 476
	fixed_page_update_preview (pagedata);
}

477 478 479 480
static void
queue_redraw (GtkWidget *widget, int x)
{
	int hh, xo;
481
	GtkAllocation a;
482 483 484 485 486 487 488

	if (x < 0)
		return;

	gtk_tree_view_convert_bin_window_to_widget_coords
		(GTK_TREE_VIEW (widget), 0, 0, &xo, &hh);

489
	gtk_widget_get_allocation (widget, &a);
490 491
	gtk_widget_queue_draw_area (widget,
				    x + xo, hh,
492
				    1, a.height - hh);
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
}


static gboolean
cb_treeview_motion (GtkWidget *widget,
		    GdkEventMotion *event,
		    StfDialogData *pagedata)
{
	int x = (int)event->x;
	int col, dx;
	RenderData_t *renderdata = pagedata->fixed.renderdata;
	int old_ruler_x = pagedata->fixed.ruler_x;
	int colstart, colend, colwidth;
	gpointer user;

	pagedata->fixed.ruler_x = -1;

	/* We get events from the buttons too.  Translate x.  */
	gdk_window_get_user_data (event->window, &user);
	if (GTK_IS_BUTTON (user)) {
		int ewx;
		gdk_window_get_position (event->window, &ewx, NULL);
		x += ewx;
	}

	stf_preview_find_column (renderdata, x, &col, &dx);

	colstart = (col == 0)
		? 0
		: stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col - 1);
	colend = stf_parse_options_fixed_splitpositions_nth (pagedata->parseoptions, col);
	colwidth = (colend == -1) ? G_MAXINT : colend - colstart;

	if (col >= 0 && col < renderdata->colcount) {
		int ci = calc_char_index (renderdata, col, &dx);
528 529 530 531 532 533 534 535
		if (ci <= colwidth) {
			int padx;
			GtkCellRenderer *cell =
				stf_preview_get_cell_renderer (renderdata, col);

			gtk_cell_renderer_get_padding (cell, &padx, NULL);
			pagedata->fixed.ruler_x = x - dx + padx;
		}
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550
	}

	gdk_event_request_motions (event);

	if (pagedata->fixed.ruler_x == old_ruler_x)
		return FALSE;

	queue_redraw (widget, old_ruler_x);
	queue_redraw (widget, pagedata->fixed.ruler_x);

	return FALSE;
}


static gboolean
551 552 553
cb_treeview_draw (GtkWidget *widget,
		  cairo_t *cr,
		  StfDialogData *pagedata)
554 555
{
	int ruler_x = pagedata->fixed.ruler_x;
556 557
	int height;
	GtkAllocation a;
558
	GdkWindow *bin_window;
559 560
	GdkRGBA ruler_color;
	GtkStyleContext *context;
561 562 563 564

	if (ruler_x < 0)
		return FALSE;

565 566 567 568
	bin_window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget));
	if (!gtk_cairo_should_draw_window (cr, bin_window))
		return FALSE;

569 570 571
	gtk_widget_get_allocation (widget, &a);
	height = a.height;

572 573 574 575 576 577 578
	context = gtk_widget_get_style_context (GTK_WIDGET (pagedata->dialog));
	gtk_style_context_save (context);
	gtk_style_context_add_region (context, "fixed-format-ruler", 0);
	gtk_style_context_get_color (context, GTK_STATE_FLAG_NORMAL,
				     &ruler_color);
	gtk_style_context_restore (context);

579
	cairo_save (cr);
580 581
	cairo_rectangle (cr, ruler_x, 0, ruler_x + 1, height);
	cairo_clip (cr);
582
	gdk_cairo_set_source_rgba (cr, &ruler_color);
583 584 585
	cairo_move_to (cr, ruler_x, 0);
	cairo_line_to (cr, ruler_x, height);
	cairo_stroke (cr);
586
	cairo_restore (cr);
587 588 589 590

	return FALSE;
}

591 592 593 594
/*************************************************************************************************
 * FIXED EXPORTED FUNCTIONS
 *************************************************************************************************/

595
/**
596
 * stf_dialog_fixed_page_cleanup
597
 * @pagedata: mother struct
598 599 600 601 602 603
 *
 * Will cleanup fixed page run-time data
 *
 * returns : nothing
 **/
void
604
stf_dialog_fixed_page_cleanup (StfDialogData *pagedata)
605
{
Morten Welinder's avatar
Morten Welinder committed
606
	stf_preview_free (pagedata->fixed.renderdata);
607 608 609
}

void
610
stf_dialog_fixed_page_init (GtkBuilder *gui, StfDialogData *pagedata)
611
{
612
	RenderData_t *renderdata;
613 614 615

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

617
        /* Create/get object and fill information struct */
Morten Welinder's avatar
Morten Welinder committed
618 619 620
	pagedata->fixed.fixed_clear   = GTK_BUTTON      (go_gtk_builder_get_widget (gui, "fixed_clear"));
	pagedata->fixed.fixed_auto    = GTK_BUTTON      (go_gtk_builder_get_widget (gui, "fixed_auto"));
	pagedata->fixed.fixed_data_container =          (go_gtk_builder_get_widget (gui, "fixed_data_container"));
621 622

	/* Set properties */
623
	renderdata = pagedata->fixed.renderdata =
624 625
		stf_preview_new (pagedata->fixed.fixed_data_container,
				 NULL);
626
	pagedata->fixed.ruler_x = -1;
627

628
	/* Connect signals */
629
	g_signal_connect (G_OBJECT (pagedata->fixed.fixed_clear),
630 631
		"clicked",
		G_CALLBACK (fixed_page_clear_clicked), pagedata);
632
	g_signal_connect (G_OBJECT (pagedata->fixed.fixed_auto),
633 634
		"clicked",
		G_CALLBACK (fixed_page_auto_clicked), pagedata);
635
	g_signal_connect (G_OBJECT (renderdata->tree_view),
636 637
		"button_press_event",
		 G_CALLBACK (cb_treeview_button_press), pagedata);
638 639 640
	g_signal_connect (G_OBJECT (renderdata->tree_view),
		"motion_notify_event",
		 G_CALLBACK (cb_treeview_motion), pagedata);
Morten Welinder's avatar
Morten Welinder committed
641

642
	g_signal_connect_after (G_OBJECT (renderdata->tree_view),
643 644
		"draw",
		 G_CALLBACK (cb_treeview_draw), pagedata);
645
}