application.c 19.1 KB
Newer Older
Jody Goldberg's avatar
Jody Goldberg committed
1
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 3 4 5
/*
 * application.c: Manage the data common to all workbooks
 *
 * Author:
Jody Goldberg's avatar
Jody Goldberg committed
6
 *     Jody Goldberg <jody@gnome.org>
7
 */
8
#include <gnumeric-config.h>
9
#include <string.h>
10
#include "gnumeric.h"
11
#include "application.h"
12

13
#include "clipboard.h"
14
#include "selection.h"
15
#include "workbook-control.h"
16
#include "workbook-view.h"
Jody Goldberg's avatar
Jody Goldberg committed
17
#include "workbook-priv.h" /* For Workbook::name */
18
#include "sheet.h"
19
#include "sheet-view.h"
20
#include "sheet-private.h"
21
#include "auto-correct.h"
22
#include "gutils.h"
Jody Goldberg's avatar
Jody Goldberg committed
23
#include "pixmaps/gnumeric-stock-pixbufs.h"
24
#include "gnm-marshalers.h"
Jody Goldberg's avatar
Jody Goldberg committed
25

26
#include <gnumeric-gconf.h>
Jody Goldberg's avatar
Jody Goldberg committed
27 28
#include <gsf/gsf-impl-utils.h>
#include <gtk/gtk.h>
29

30 31 32 33
enum {
	APPLICATION_PROP_0,
	APPLICATION_PROP_FILE_HISTORY_LIST
};
34 35
/* Signals */
enum {
36 37
	WORKBOOK_ADDED,
	WORKBOOK_REMOVED,
38 39 40 41 42 43 44 45 46
	CLIPBOARD_MODIFIED,
	LAST_SIGNAL
};

static GQuark signals [LAST_SIGNAL] = { 0 };

struct _GnumericApplication {
	GObject  base;

47
	/* Clipboard */
48
	SheetView	*clipboard_sheet_view;
49 50
	CellRegion	*clipboard_copied_contents;
	Range		 clipboard_cut_range;
51

52
	/* History for file menu */
53
	GSList           *history_list;
Miguel de Icaza's avatar
Miguel de Icaza committed
54

55
	/* Others */
56
	GConfClient     *gconf_client;
57
	GtkWidget       *pref_dialog;
58 59

	GList		*workbook_list;
Morten Welinder's avatar
Morten Welinder committed
60 61

	GHashTable      *named_pixbufs;
62 63
};

64
typedef struct {
65
	GObjectClass     parent;
66 67 68

	void (*workbook_added)     (GnumericApplication *gnm_app, Workbook *wb);
	void (*workbook_removed)   (GnumericApplication *gnm_app, Workbook *wb);
69
	void (*clipboard_modified) (GnumericApplication *gnm_app);
Morten Welinder's avatar
Morten Welinder committed
70

71 72
} GnumericApplicationClass;

73
static GObjectClass *parent_klass;
74
static GnumericApplication *app;
75

76 77 78 79 80 81
GObject *
gnumeric_application_get_app (void)
{
	return G_OBJECT (app);
}

Jody Goldberg's avatar
Jody Goldberg committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
static void
add_icon (GtkIconFactory *factory,
	  guchar const   *scalable_data,
	  guchar const   *sized_data,
	  gchar const    *stock_id)
{
	GtkIconSet *set = gtk_icon_set_new ();
	GtkIconSource *src = gtk_icon_source_new ();

	if (scalable_data != NULL) {
		gtk_icon_source_set_size_wildcarded (src, TRUE);
		gtk_icon_source_set_pixbuf (src,
			gdk_pixbuf_new_from_inline (-1, scalable_data, FALSE, NULL));
		gtk_icon_set_add_source (set, src);	/* copies the src */
	}
Jody Goldberg's avatar
Jody Goldberg committed
97

Jody Goldberg's avatar
Jody Goldberg committed
98 99 100 101 102 103 104 105 106 107 108 109 110
	if (sized_data != NULL) {
		gtk_icon_source_set_size (src, GTK_ICON_SIZE_MENU);
		gtk_icon_source_set_size_wildcarded (src, FALSE);
		gtk_icon_source_set_pixbuf (src,
			gdk_pixbuf_new_from_inline (-1, sized_data, FALSE, NULL));
		gtk_icon_set_add_source (set, src);	/* copies the src */
	}

	gtk_icon_factory_add (factory, stock_id, set);	/* keeps reference to set */
	gtk_icon_set_unref (set);
	gtk_icon_source_free (src);
}

111 112
/**
 * application_workbook_list_remove :
Morten Welinder's avatar
Morten Welinder committed
113
 * @wb :
114 115 116
 *
 * Remove @wb from the application's list of workbooks.
 **/
117 118 119
void
application_workbook_list_add (Workbook *wb)
{
120 121 122 123
	g_return_if_fail (IS_WORKBOOK (wb));

	app->workbook_list = g_list_prepend (app->workbook_list, wb);
	g_signal_emit (G_OBJECT (app), signals [WORKBOOK_ADDED], 0, wb);
124
}
125 126 127

/**
 * application_workbook_list_remove :
Morten Welinder's avatar
Morten Welinder committed
128
 * @wb :
129 130 131
 *
 * Remove @wb from the application's list of workbooks.
 **/
132 133 134
void
application_workbook_list_remove (Workbook *wb)
{
Jody Goldberg's avatar
Jody Goldberg committed
135
	g_return_if_fail (wb != NULL);
136 137

	app->workbook_list = g_list_remove (app->workbook_list, wb);
Jody Goldberg's avatar
Jody Goldberg committed
138
	g_signal_emit (G_OBJECT (app), signals [WORKBOOK_REMOVED], 0, wb);
139
}
140

141 142 143
GList *
application_workbook_list (void)
{
144
	return app->workbook_list;
145 146
}

147 148 149 150 151 152 153
/**
 * application_clipboard_clear:
 *
 * Clear and free the contents of the clipboard if it is
 * not empty.
 */
void
154
application_clipboard_clear (gboolean drop_selection)
155
{
156 157 158
	if (app->clipboard_copied_contents) {
		cellregion_free (app->clipboard_copied_contents);
		app->clipboard_copied_contents = NULL;
159
	}
160 161
	if (app->clipboard_sheet_view != NULL) {
		sv_unant (app->clipboard_sheet_view);
Jody Goldberg's avatar
Jody Goldberg committed
162

163
		g_signal_emit (G_OBJECT (app), signals [CLIPBOARD_MODIFIED], 0);
Jody Goldberg's avatar
Jody Goldberg committed
164

165
		sv_weak_unref (&(app->clipboard_sheet_view));
Jody Goldberg's avatar
Jody Goldberg committed
166 167

		/* Release the selection */
168
		if (drop_selection) {
Morten Welinder's avatar
Gripe.  
Morten Welinder committed
169
#warning "FIXME: 1: this doesn't belong here.  2: it is not multihead safe."
170 171 172
			gtk_selection_owner_set (NULL,
						 GDK_SELECTION_PRIMARY,
						 GDK_CURRENT_TIME);
173 174 175 176
			gtk_selection_owner_set (NULL,
						 GDK_SELECTION_CLIPBOARD,
						 GDK_CURRENT_TIME);
		}
177
	}
178 179
}

180 181 182
void
application_clipboard_unant (void)
{
183 184
	if (app->clipboard_sheet_view != NULL)
		sv_unant (app->clipboard_sheet_view);
185 186
}

187
/**
188
 * application_clipboard_cut_copy:
189
 *
190
 * @wbc   : the workbook control that requested the operation.
191
 * @is_cut: is this a cut or a copy.
192 193
 * @sheet : The source sheet for the copy.
 * @area  : A single rectangular range to be copied.
194
 * @animate_cursor : Do we want ot add an animated cursor around things.
195
 *
196 197 198 199
 * When Cutting we
 *   Clear and free the contents of the clipboard and save the sheet and area
 *   to be cut.  DO NOT ACTUALLY CUT!  Paste will move the region if this was a
 *   cut operation.
200
 *
201 202 203
 * When Copying we
 *   Clear and free the contents of the clipboard and COPY the designated region
 *   into the clipboard.
204
 *
205 206
 * we need to pass @wbc as a control rather than a simple command-context so
 * that the control can claim the selection.
207 208
 */
void
209
application_clipboard_cut_copy (WorkbookControl *wbc, gboolean is_cut,
210
				SheetView *sv, Range const *area,
211
				gboolean animate_cursor)
212
{
213
	g_return_if_fail (IS_SHEET_VIEW (sv));
214
	g_return_if_fail (area != NULL);
215

216 217 218
	application_clipboard_clear (FALSE);

	if (wb_control_claim_selection (wbc)) {
219
		Sheet *sheet = sv_sheet (sv);
220
		app->clipboard_cut_range = *area;
221
		sv_weak_ref (sv, &(app->clipboard_sheet_view));
222

223
		if (!is_cut)
224
			app->clipboard_copied_contents =
225 226
				clipboard_copy_range (sheet, area);

227
		g_signal_emit (G_OBJECT (app), signals [CLIPBOARD_MODIFIED], 0);
228

229
		if (animate_cursor) {
230
			GList *l = g_list_append (NULL, (gpointer)area);
231
			sv_ant (sv, l);
232 233
			g_list_free (l);
		}
234 235
	} else {
		g_warning ("Unable to set selection ?");
236
	}
237 238 239
}

gboolean
Morten Welinder's avatar
Morten Welinder committed
240
application_clipboard_is_empty (void)
241
{
242
	return app->clipboard_sheet_view == NULL;
243 244
}

245 246 247
gboolean
application_clipboard_is_cut (void)
{
248 249
	if (app->clipboard_sheet_view != NULL)
		return app->clipboard_copied_contents ? FALSE : TRUE;
250 251 252
	return FALSE;
}

253
Sheet *
Morten Welinder's avatar
Morten Welinder committed
254
application_clipboard_sheet_get (void)
255
{
256
	if (app->clipboard_sheet_view == NULL)
257
		return NULL;
258
	return sv_sheet (app->clipboard_sheet_view);
259 260 261 262 263
}

SheetView *
application_clipboard_sheet_view_get (void)
{
264
	return app->clipboard_sheet_view;
265 266 267
}

CellRegion *
Morten Welinder's avatar
Morten Welinder committed
268
application_clipboard_contents_get (void)
269
{
270
	return app->clipboard_copied_contents;
271 272 273
}

Range const *
Morten Welinder's avatar
Morten Welinder committed
274
application_clipboard_area_get (void)
275 276 277 278 279 280 281
{
	/*
	 * Only return the range if the sheet has been set.
	 * The range will still contain data even after
	 * the clipboard has been cleared so we need to be extra
	 * safe and only return a range if there is a valid selection
	 */
282 283
	if (app->clipboard_sheet_view != NULL)
		return &app->clipboard_cut_range;
284 285
	return NULL;
}
Jody Goldberg's avatar
Jody Goldberg committed
286

Jody Goldberg's avatar
Jody Goldberg committed
287
struct wb_name_closure {
Jody Goldberg's avatar
Jody Goldberg committed
288
	Workbook *wb;
Jody Goldberg's avatar
Jody Goldberg committed
289
	char const *name;
Jody Goldberg's avatar
Jody Goldberg committed
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
};
static gboolean
cb_workbook_name (Workbook * wb, gpointer closure)
{
	struct wb_name_closure *dat = closure;
	if (0 == strcmp (wb->filename, dat->name)) {
		dat->wb = wb;
		return FALSE;
	}
	return TRUE;
}

Workbook *
application_workbook_get_by_name (char const * const name)
{
	struct wb_name_closure close;
	close.wb = NULL;
	close.name = name;
308
	application_workbook_foreach (&cb_workbook_name, &close);
Jody Goldberg's avatar
Jody Goldberg committed
309 310 311 312

	return close.wb;
}

313 314 315 316 317
gboolean
application_workbook_foreach (WorkbookCallback cback, gpointer data)
{
	GList *l;

318
	for (l = app->workbook_list; l; l = l->next){
319 320 321 322 323 324 325 326
		Workbook *wb = l->data;

		if (!(*cback)(wb, data))
			return FALSE;
	}
	return TRUE;
}

Jody Goldberg's avatar
Jody Goldberg committed
327 328 329 330 331
struct wb_index_closure
{
	Workbook *wb;
	int index;	/* 1 based */
};
332

Jody Goldberg's avatar
Jody Goldberg committed
333
static gboolean
Morten Welinder's avatar
Morten Welinder committed
334
cb_workbook_index (G_GNUC_UNUSED Workbook * wb, gpointer closure)
Jody Goldberg's avatar
Jody Goldberg committed
335 336 337 338 339 340 341 342 343 344 345
{
	struct wb_index_closure *dat = closure;
	return (--(dat->index) != 0);
}

Workbook *
application_workbook_get_by_index (int i)
{
	struct wb_index_closure close;
	close.wb = NULL;
	close.index = i;
346
	application_workbook_foreach (&cb_workbook_index, &close);
Jody Goldberg's avatar
Jody Goldberg committed
347 348 349

	return close.wb;
}
350

351
double
352
application_display_dpi_get (gboolean horizontal)
353
{
354
	return horizontal ? gnm_app_prefs->horizontal_dpi : gnm_app_prefs->vertical_dpi;
355 356
}

357
double
358
application_dpi_to_pixels (void)
359
{
360 361
	return MIN (gnm_app_prefs->horizontal_dpi,
		    gnm_app_prefs->vertical_dpi) / 72.;
362 363
}

364 365
/**
 * application_history_get_list:
366
 *
Morten Welinder's avatar
Morten Welinder committed
367
 * creating it if necessary.
368
 *
369 370
 * Return value: the list./
 **/
371 372
GSList const *
application_history_get_list (gboolean force_reload)
373
{
374
        gint max_entries;
375 376 377 378 379 380 381 382 383 384
	GSList const *ptr;
	GSList *res = NULL;

	if (app->history_list != NULL) {
		if (force_reload) {
			GSList *tmp = app->history_list;
			app->history_list = NULL;
			g_slist_free_custom (tmp, g_free);
		} else
			return app->history_list;
385
	}
386

387 388 389 390 391
	max_entries = gnm_app_prefs->file_history_max;
	for (ptr = gnm_app_prefs->file_history_files;
	     ptr != NULL && max_entries-- > 0 ; ptr = ptr->next)
		res = g_slist_prepend (res, g_strdup (ptr->data));
	return app->history_list = g_slist_reverse (res);;
392 393 394 395
}

/**
 * application_history_update_list:
396 397
 * @filename:
 *
398
 * Adds @filename to the application's history of files.
399
 **/
400 401
void
application_history_add (char const *filename)
402
{
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
	char *canonical_name;
        gint max_entries;
	GSList *exists;
	GSList **ptr;

	g_return_if_fail (filename != NULL);

	/* Rudimentary filename canonicalization. */
	if (!g_path_is_absolute (filename)) {
		char *cwd = g_get_current_dir ();
		canonical_name = g_strconcat (cwd, "/", filename, NULL);
		g_free (cwd);
	} else
		canonical_name = g_strdup (filename);

	/* force a reload in case max_entries has changed */
	application_history_get_list (TRUE);
	exists = g_slist_find_custom (app->history_list,
				      canonical_name, g_str_compare);

	if (exists != NULL) {
		/* its already the top of the stack no need to do anything */
		if (exists == app->history_list) {
			g_free (canonical_name);
			return;
Morten Welinder's avatar
Morten Welinder committed
428
		}
429 430 431
		/* remove the other instance */
		g_free (exists->data);
		app->history_list = g_slist_remove (app->history_list, exists->data);
432 433
	}

434
	app->history_list = g_slist_prepend (app->history_list, canonical_name);
435

436
	/* clip the list if it is too long */
437
	max_entries = gnm_app_prefs->file_history_max;
438 439 440 441 442 443
	ptr = &(app->history_list);
	while (*ptr != NULL && max_entries-- > 0)
		ptr = &((*ptr)->next);
	if (*ptr != NULL) {
		g_slist_free_custom (*ptr, g_free);
		*ptr = NULL;
444 445
	}

446
	g_object_notify (G_OBJECT (app), "file-history-list");
447 448
	gnm_gconf_set_file_history_files (
		g_string_slist_copy (app->history_list));
449
	gnm_conf_sync ();
450 451
}

452 453 454
gboolean application_use_auto_complete	  (void) { return gnm_app_prefs->auto_complete; }
gboolean application_live_scrolling	  (void) { return gnm_app_prefs->live_scrolling; }
int	 application_auto_expr_recalc_lag (void) { return gnm_app_prefs->recalc_lag; }
455 456

GConfClient *
Morten Welinder's avatar
Morten Welinder committed
457
application_get_gconf_client (void)
458
{
459
	if (!app->gconf_client) {
460
		app->gconf_client = gconf_client_get_default ();
461 462 463 464
		gconf_client_add_dir (app->gconf_client, "/apps/gnumeric",
				      GCONF_CLIENT_PRELOAD_RECURSIVE,
				      NULL);
	}
Morten Welinder's avatar
Morten Welinder committed
465
	return app->gconf_client;
466 467
}

Morten Welinder's avatar
Morten Welinder committed
468 469 470
void
application_release_gconf_client (void)
{
471 472
	if (app->gconf_client) {
		gconf_client_remove_dir (app->gconf_client,
473
					 "/apps/gnumeric", NULL);
474
		g_object_unref (G_OBJECT (app->gconf_client));
475
	}
476
	app->gconf_client = NULL;
477
}
478

Morten Welinder's avatar
Morten Welinder committed
479 480 481 482 483 484 485 486 487 488
/*
 * Get a named pixbuf.
 */
GdkPixbuf *
application_get_pixbuf (const char *name)
{
	return g_hash_table_lookup (app->named_pixbufs, name);
}


Morten Welinder's avatar
Morten Welinder committed
489
gpointer
490 491
application_get_pref_dialog (void)
{
Morten Welinder's avatar
Morten Welinder committed
492
	return app->pref_dialog;
493 494
}

Morten Welinder's avatar
Morten Welinder committed
495
void
496 497
application_set_pref_dialog (gpointer dialog)
{
498
	app->pref_dialog = dialog;
499 500
}

Morten Welinder's avatar
Morten Welinder committed
501
void
502
application_release_pref_dialog (void)
Morten Welinder's avatar
Morten Welinder committed
503
{
504 505 506 507
	if (app->pref_dialog)
		gtk_widget_destroy (app->pref_dialog);
}

Morten Welinder's avatar
Morten Welinder committed
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
static void
gnumeric_application_setup_pixbufs (GnumericApplication *app)
{
	static struct {
		guchar const   *scalable_data;
		gchar const    *name;
	} const entry [] = {
		{ gnm_cursor_cross, "cursor_cross" },
		{ gnm_bucket, "bucket" },
		{ gnm_font, "font" }
	};
	unsigned int ui;

	for (ui = 0; ui < G_N_ELEMENTS (entry); ui++) {
		GdkPixbuf *pixbuf = gdk_pixbuf_new_from_inline
			(-1, entry[ui].scalable_data, FALSE, NULL);
		g_hash_table_insert (app->named_pixbufs,
				     (char *)entry[ui].name,
				     pixbuf);
	}
}

530 531 532
static void
gnumeric_application_setup_icons (void)
{
Morten Welinder's avatar
Morten Welinder committed
533
	static struct {
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
		guchar const   *scalable_data;
		guchar const   *sized_data;
		gchar const    *stock_id;
	} const entry [] = {
		{ gnm_column_add_24,			gnm_column_add_16,		"Gnumeric_ColumnAdd" },
		{ gnm_column_delete_24,			gnm_column_delete_16,		"Gnumeric_ColumnDelete" },
		{ gnm_column_size_24,			gnm_column_size_16,		"Gnumeric_ColumnSize" },
		{ gnm_column_hide_24,			gnm_column_hide_16,		"Gnumeric_ColumnHide" },
		{ gnm_column_unhide_24,			gnm_column_unhide_16,		"Gnumeric_ColumnUnhide" },
		{ gnm_row_add_24,			gnm_row_add_16,			"Gnumeric_RowAdd" },
		{ gnm_row_delete_24,			gnm_row_delete_16,		"Gnumeric_RowDelete" },
		{ gnm_row_size_24,			gnm_row_size_16,		"Gnumeric_RowSize" },
		{ gnm_row_hide_24,			gnm_row_hide_16,		"Gnumeric_RowHide" },
		{ gnm_row_unhide_24,			gnm_row_unhide_16,		"Gnumeric_RowUnhide" },

		{ gnm_group_24,				gnm_group_16,			"Gnumeric_Group" },
		{ gnm_ungroup_24,			gnm_ungroup_16,			"Gnumeric_Ungroup" },
		{ gnm_show_detail_24,			gnm_show_detail_16,		"Gnumeric_ShowDetail" },
		{ gnm_hide_detail_24,			gnm_hide_detail_16,		"Gnumeric_HideDetail" },

		{ gnm_graph_guru_24,			gnm_graph_guru_16,		"Gnumeric_GraphGuru" },
		{ gnm_insert_component_24,		gnm_insert_component_16,	"Gnumeric_InsertComponent" },
		{ gnm_insert_shaped_component_24,	gnm_insert_shaped_component_16,	"Gnumeric_InsertShapedComponent" },

		{ gnm_center_across_selection_24,	gnm_center_across_selection_16,	"Gnumeric_CenterAcrossSelection" },
		{ gnm_merge_cells_24,			gnm_merge_cells_16,		"Gnumeric_MergeCells" },
		{ gnm_split_cells_24,			gnm_split_cells_16,		"Gnumeric_SplitCells" },

		{ NULL,					gnm_comment_add_16,		"Gnumeric_CommentAdd" },
		{ NULL,					gnm_comment_delete_16,		"Gnumeric_CommentDelete" },
		{ NULL,					gnm_comment_edit_16,		"Gnumeric_CommentEdit" },

		{ gnm_add_decimals,			NULL,				"Gnumeric_FormatAddPrecision" },
		{ gnm_remove_decimals,			NULL,				"Gnumeric_FormatRemovePrecision" },
		{ gnm_money,				NULL,				"Gnumeric_FormatAsMoney" },
		{ gnm_percent,				NULL,				"Gnumeric_FormatAsPercent" },
		{ gnm_thousand,				NULL,				"Gnumeric_FormatThousandSeparator" },

		{ gnm_auto,				NULL,				"Gnumeric_AutoSum" },
		{ gnm_equal,				NULL,				"Gnumeric_Equal" },
Jody Goldberg's avatar
Jody Goldberg committed
574
		{ gnm_formula_guru_24,			gnm_formula_guru_16,		"Gnumeric_FormulaGuru" },
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
		{ gnm_insert_image_24,			gnm_insert_image_16,		"Gnumeric_InsertImage" },
		{ gnm_bucket,				NULL,				"Gnumeric_Bucket" },
		{ gnm_font,				NULL,				"Gnumeric_Font" },
		{ gnm_expr_entry,			NULL,				"Gnumeric_ExprEntry" },

		{ gnm_object_arrow_24,			NULL,				"Gnumeric_ObjectArrow" },
		{ gnm_object_ellipse_24,		NULL,				"Gnumeric_ObjectEllipse" },
		{ gnm_object_line_24,			NULL,				"Gnumeric_ObjectLine" },
		{ gnm_object_rectangle_24,		NULL,				"Gnumeric_ObjectRectangle" },

		{ gnm_object_button_24,			NULL,				"Gnumeric_ObjectButton" },
		{ gnm_object_checkbox_24,		NULL,				"Gnumeric_ObjectCheckbox" },
		{ gnm_object_combo_24,			NULL,				"Gnumeric_ObjectCombo" },
		{ gnm_object_frame_24,			NULL,				"Gnumeric_ObjectFrame" },
		{ gnm_object_label_24,			NULL,				"Gnumeric_ObjectLabel" },
		{ gnm_object_list_24,			NULL,				"Gnumeric_ObjectList" },
Jody Goldberg's avatar
Jody Goldberg committed
591
		{ gnm_object_radiobutton_24,		NULL,				"Gnumeric_ObjectRadioButton" },
592
		{ gnm_object_scrollbar_24,		NULL,				"Gnumeric_ObjectScrollbar" },
Jody Goldberg's avatar
Jody Goldberg committed
593
		{ gnm_object_spinbutton_24,		NULL,				"Gnumeric_ObjectSpinButton" },
594

595
		{ gnm_pivottable_24,	                gnm_pivottable_16,		"Gnumeric_PivotTable" },
Jody Goldberg's avatar
Jody Goldberg committed
596 597
		{ gnm_protection_yes,	                NULL,				"Gnumeric_Protection_Yes" },
		{ gnm_protection_no,       		NULL,				"Gnumeric_Protection_No" },
598
		{ gnm_protection_yes_48,	        NULL,				"Gnumeric_Protection_Yes_Dialog" },
Jody Goldberg's avatar
Jody Goldberg committed
599 600 601 602

		{ gnm_link_add_24,			gnm_link_add_16,		"Gnumeric_Link_Add" },
		{ NULL,					gnm_link_delete_16,		"Gnumeric_Link_Delete" },
		{ NULL,					gnm_link_edit_16,		"Gnumeric_Link_Edit" },
Jody Goldberg's avatar
Jody Goldberg committed
603 604 605 606
		{ gnm_link_external_24,			gnm_link_external_16,		"Gnumeric_Link_External" },
		{ gnm_link_internal_24,			gnm_link_internal_16,		"Gnumeric_Link_Internal" },
		{ gnm_link_email_24,			gnm_link_email_16,		"Gnumeric_Link_EMail" },
		{ gnm_link_url_24,			gnm_link_url_16,		"Gnumeric_Link_URL" },
607
	};
Morten Welinder's avatar
Morten Welinder committed
608 609 610 611 612 613 614 615 616 617 618 619
	static gboolean done = FALSE;

	if (!done) {
		unsigned int ui = 0;
		GtkIconFactory *factory = gtk_icon_factory_new ();
		for (ui = 0; ui < G_N_ELEMENTS (entry) ; ui++)
			add_icon (factory, entry[ui].scalable_data,
				  entry[ui].sized_data, entry[ui].stock_id);
		gtk_icon_factory_add_default (factory);
		g_object_unref (G_OBJECT (factory));
		done = TRUE;
	}
620 621 622
}

static void
623
gnumeric_application_finalize (GObject *obj)
624
{
625 626 627 628 629
	GnumericApplication *application = GNUMERIC_APPLICATION (obj);

	g_slist_foreach (application->history_list, (GFunc)g_free, NULL);
	g_slist_free (application->history_list);
	application->history_list = NULL;
Morten Welinder's avatar
Morten Welinder committed
630
	g_hash_table_destroy (application->named_pixbufs);
631
	app = NULL;
632
	G_OBJECT_CLASS (parent_klass)->finalize (obj);
633 634 635
}

static void
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650
gnumeric_application_get_property (GObject *obj, guint param_id,
				   GValue *value, GParamSpec *pspec)
{
	GnumericApplication *application = GNUMERIC_APPLICATION (obj);
	switch (param_id) {
	case APPLICATION_PROP_FILE_HISTORY_LIST:
		g_value_set_pointer (value, application->history_list);
		break;
	default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec);
		 break;
	}
}

static void
gnumeric_application_class_init (GObjectClass *gobject_klass)
651
{
652
	parent_klass = g_type_class_peek_parent (gobject_klass);
653 654

	/* Object class method overrides */
655 656 657
	gobject_klass->finalize = gnumeric_application_finalize;
	gobject_klass->get_property = gnumeric_application_get_property;
	g_object_class_install_property (gobject_klass, APPLICATION_PROP_FILE_HISTORY_LIST,
658
		g_param_spec_pointer ("file-history-list", "File History List",
659 660
			"A GSlist of filenames that have been read recently",
			G_PARAM_READABLE));
661

662 663 664 665 666
	signals [WORKBOOK_ADDED] = g_signal_new ("workbook_added",
		GNUMERIC_APPLICATION_TYPE,
		G_SIGNAL_RUN_LAST,
		G_STRUCT_OFFSET (GnumericApplicationClass, workbook_added),
		(GSignalAccumulator) NULL, NULL,
Jody Goldberg's avatar
Jody Goldberg committed
667
		gnm__VOID__OBJECT,
668 669 670 671 672 673 674
		G_TYPE_NONE,
		1, WORKBOOK_TYPE);
	signals [WORKBOOK_REMOVED] = g_signal_new ("workbook_removed",
		GNUMERIC_APPLICATION_TYPE,
		G_SIGNAL_RUN_LAST,
		G_STRUCT_OFFSET (GnumericApplicationClass, workbook_removed),
		(GSignalAccumulator) NULL, NULL,
675
		gnm__VOID__POINTER,
676
		G_TYPE_NONE,
Jody Goldberg's avatar
Jody Goldberg committed
677
		1, G_TYPE_POINTER);
678 679 680 681 682 683 684
	signals [CLIPBOARD_MODIFIED] = g_signal_new ("clipboard_modified",
		GNUMERIC_APPLICATION_TYPE,
		G_SIGNAL_RUN_LAST,
		G_STRUCT_OFFSET (GnumericApplicationClass, clipboard_modified),
		(GSignalAccumulator) NULL, NULL,
		gnm__VOID__VOID,
		G_TYPE_NONE,
685
		0);
686 687 688 689 690 691 692 693 694 695
}

static void
gnumeric_application_init (GObject *obj)
{
	GnumericApplication *gnm_app = GNUMERIC_APPLICATION (obj);

	gnm_app->clipboard_copied_contents = NULL;
	gnm_app->clipboard_sheet_view = NULL;

696
	gnm_app->gconf_client = NULL;
697

698 699
	gnm_app->workbook_list = NULL;

Morten Welinder's avatar
Morten Welinder committed
700 701 702 703 704 705 706
	gnm_app->named_pixbufs = g_hash_table_new_full (g_str_hash, g_str_equal,
							NULL,
							(GDestroyNotify)g_object_unref);

	gnumeric_application_setup_pixbufs (gnm_app);
	gnumeric_application_setup_icons ();

707
	app = gnm_app;
708 709
}

Jody Goldberg's avatar
Jody Goldberg committed
710 711 712
GSF_CLASS (GnumericApplication, gnumeric_application,
	   gnumeric_application_class_init, gnumeric_application_init,
	   G_TYPE_OBJECT);