main.c 23.4 KB
Newer Older
Paolo Bacchilega's avatar
Paolo Bacchilega committed
1 2 3 4 5
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  GThumb
 *
6
 *  Copyright (C) 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
Paolo Bacchilega's avatar
Paolo Bacchilega committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 *  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., 59 Temple Street #330, Boston, MA 02111-1307, USA.
 */

#include <config.h>
24
#include <gnome.h>
Paolo Bacchilega's avatar
Paolo Bacchilega committed
25 26
#include <glade/glade.h>
#include <libgnomeui/gnome-window-icon.h>
Paolo Bacchilega's avatar
Paolo Bacchilega committed
27
#include <libgnomeui/gnome-ui-init.h>
Paolo Bacchilega's avatar
Paolo Bacchilega committed
28 29
#include <libgnomevfs/gnome-vfs-init.h>
#include <libgnomevfs/gnome-vfs-utils.h>
30
#include <libbonobo.h>
Paolo Bacchilega's avatar
Paolo Bacchilega committed
31 32

#include "catalog.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
33 34
#include "comments.h"
#include "main.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
35 36
#include "file-utils.h"
#include "gconf-utils.h"
37
#include "gtk-utils.h"
38
#include "gth-application.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
39
#include "gth-browser.h"
40
#include "gth-browser-actions-callbacks.h"
41
#include "gth-dir-list.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
42 43
#include "gth-image-list.h"
#include "gth-viewer.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
44
#include "gthumb-init.h"
45
#include "gthumb-stock.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
46
#include "image-viewer.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
47
#include "pixbuf-utils.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
48 49
#include "preferences.h"
#include "typedefs.h"
50

51
#include "icons/pixbufs.h"
Paolo Bacchilega's avatar
Paolo Bacchilega committed
52

53 54 55 56 57 58 59 60 61 62 63 64
typedef enum {
	ICON_NAME_DIRECTORY,
	ICON_NAME_HARDDISK,
	ICON_NAME_HOME,
	ICON_NAME_DESKTOP,
	ICON_NAMES
} IconName;

static char*icon_mime_name[ICON_NAMES] = { "gnome-fs-directory",
					   "gnome-dev-harddisk",
					   "gnome-fs-home",
					   "gnome-fs-desktop" };
65

Paolo Bacchilega's avatar
Paolo Bacchilega committed
66 67 68 69 70 71 72 73 74 75 76
GthMonitor  *monitor = NULL;
char       **file_urls, **dir_urls;
int          n_file_urls, n_dir_urls;
int          StartInFullscreen = FALSE;
int          StartSlideshow = FALSE;
int          ViewFirstImage = FALSE;
int          HideSidebar = FALSE;
gboolean     ExitAll = FALSE;
char        *ImageToDisplay = NULL;
gboolean     FirstStart = TRUE;
gboolean     ImportPhotos = FALSE;
77
gboolean     UseViewer = FALSE;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
78

79
static gboolean        view_comline_catalog = FALSE;
80
static gboolean        view_single_image = FALSE;
81
static GdkPixbuf      *icon_pixbuf[ICON_NAMES] = { 0 };
82
static GtkWidget      *first_window = NULL;
83
static GnomeIconTheme *icon_theme = NULL;
84
static BonoboObject   *gth_application = NULL;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
85 86

struct poptOption options[] = {
87
	{ "fullscreen", 'f', POPT_ARG_NONE, &StartInFullscreen, 0,
Paolo Bacchilega's avatar
Paolo Bacchilega committed
88 89
	  N_("Start in fullscreen mode"),
	  0 },
90
	{ "slideshow", 's', POPT_ARG_NONE, &StartSlideshow, 0,
Paolo Bacchilega's avatar
Paolo Bacchilega committed
91 92
	  N_("Automatically start a slideshow"),
	  0 },
93 94 95
	{ "import-photos", '\0', POPT_ARG_NONE, &ImportPhotos, 0,
	  N_("Automatically import digital camera photos"),
	  0 },
96 97 98
	{ "viewer", '\0', POPT_ARG_NONE, &UseViewer, 0,
	  "Use the viewer mode to view single images",
	  0 },
Paolo Bacchilega's avatar
Paolo Bacchilega committed
99 100 101 102
	{ NULL, '\0', 0, NULL, 0 }
};


103 104 105 106
static void
init_icon_pixbufs (void)
{
	int i;
107
	for (i = 0; i < ICON_NAMES; i++)
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
		icon_pixbuf[i] = NULL;
}


static void
free_icon_pixbufs (void)
{
	int i;
	for (i = 0; i < ICON_NAMES; i++)
		if (icon_pixbuf[i] != NULL) {
			g_object_unref (icon_pixbuf[i]);
			icon_pixbuf[i] = NULL;
		}
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
124
static void
125
theme_changed_cb (GnomeIconTheme *theme,
Paolo Bacchilega's avatar
Paolo Bacchilega committed
126
		  gpointer        data)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
127
{
128
	free_icon_pixbufs ();
Paolo Bacchilega's avatar
Paolo Bacchilega committed
129
	all_windows_notify_update_icon_theme ();
Paolo Bacchilega's avatar
Paolo Bacchilega committed
130 131 132 133
}


static void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
134
create_default_categories_if_needed (void)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
135 136
{
	Bookmarks *categories;
137
	char      *default_categories[] = { N_("Holidays"),
Paolo Bacchilega's avatar
Paolo Bacchilega committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
					    N_("Temporary"),
					    N_("Screenshots"),
					    N_("Science"),
					    N_("Favourite"),
					    N_("Important"),
					    N_("GNOME"),
					    N_("Games"),
					    N_("Party"),
					    N_("Birthday"),
					    N_("Astronomy"),
					    N_("Family"),
					    NULL };
	int        i;
	char      *path;

	path = g_strconcat (g_get_home_dir (),
			    "/",
			    RC_CATEGORIES_FILE,
			    NULL);
	if (path_is_file (path)) {
		g_free (path);
		return;
	}
	g_free (path);

	categories = bookmarks_new (RC_CATEGORIES_FILE);
164
	for (i = 0; default_categories[i] != NULL; i++)
165
		bookmarks_add (categories, _(default_categories[i]), TRUE, TRUE);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
166 167 168 169 170
	bookmarks_write_to_disk (categories);
	bookmarks_free (categories);
}


171 172 173
static void
convert_old_comment (char     *real_file,
		     char     *rc_file,
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
		     gpointer  data)
{
	char *comment_file;
	char *comment_dir;

	comment_file = comments_get_comment_filename (real_file, TRUE, TRUE);
	comment_dir = remove_level_from_path (comment_file);
	ensure_dir_exists (comment_dir, 0755);

	file_copy (rc_file, comment_file);

	g_free (comment_dir);
	g_free (comment_file);
}


static void
convert_to_new_comment_system (void)
{
	if (!eel_gconf_get_boolean (PREF_MIGRATE_COMMENT_SYSTEM, TRUE))
		return;
	g_print ("converting comment system...");
	visit_rc_directory_sync (RC_COMMENTS_DIR,
				 COMMENT_EXT,
				 "",
				 TRUE,
				 convert_old_comment,
				 NULL);
	g_print ("done.");
	eel_gconf_set_boolean (PREF_MIGRATE_COMMENT_SYSTEM, FALSE);
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
207 208 209 210 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
/* SM support */


/* argv[0] from main(); used as the command to restart the program */
static const char *program_argv0 = NULL;

/* The master client we use for SM */
static GnomeClient *master_client = NULL;


static void
save_session (GnomeClient *client)
{
	const char  *prefix;
	GList       *scan;
	int          i = 0;

	prefix = gnome_client_get_config_prefix (client);
	gnome_config_push_prefix (prefix);

	for (scan = gth_window_get_window_list (); scan; scan = scan->next) {
		GthWindow  *window = scan->data;
		char       *uri = NULL;
		const char *location;
		char       *key;

		if (GTH_IS_VIEWER (window)) {
			location = gth_window_get_image_filename (window);
			if (location == NULL)
				continue;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
237
			uri = get_uri_from_path (location);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
238 239 240 241 242 243 244 245 246

		} else {
			GthBrowser *browser = (GthBrowser*) window;

			switch (gth_browser_get_sidebar_content (browser)) {
			case GTH_SIDEBAR_DIR_LIST:
				location = gth_browser_get_current_directory (browser);
				if (location == NULL)
					continue;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
247
				uri = get_uri_from_path (location);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
248
				break;
249

Paolo Bacchilega's avatar
Paolo Bacchilega committed
250 251 252 253
			case GTH_SIDEBAR_CATALOG_LIST:
				location = gth_browser_get_current_catalog (browser);
				if (location == NULL)
					continue;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
254
				uri = get_uri_from_path (location);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
255
				break;
256

Paolo Bacchilega's avatar
Paolo Bacchilega committed
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
			default:
				break;
			}
		}

		if (uri == NULL)
			continue;

		key = g_strdup_printf ("Session/location%d", i);
		gnome_config_set_string (key, uri);

		g_free (uri);
		g_free (key);

		i++;
	}

	gnome_config_set_int ("Session/locations", i);

	gnome_config_pop_prefix ();
	gnome_config_sync ();
}


/* save_yourself handler for the master client */
static gboolean
client_save_yourself_cb (GnomeClient *client,
			 gint phase,
			 GnomeSaveStyle save_style,
			 gboolean shutdown,
			 GnomeInteractStyle interact_style,
			 gboolean fast,
			 gpointer data)
{
	const char *prefix;
	char       *argv[4] = { NULL };

	save_session (client);

	prefix = gnome_client_get_config_prefix (client);

	/* Tell the session manager how to discard this save */

	argv[0] = "rm";
	argv[1] = "-rf";
	argv[2] = gnome_config_get_real_path (prefix);
	argv[3] = NULL;
	gnome_client_set_discard_command (client, 3, argv);

	/* Tell the session manager how to clone or restart this instance */

	argv[0] = (char *) program_argv0;
	argv[1] = NULL; /* "--debug-session"; */
310

Paolo Bacchilega's avatar
Paolo Bacchilega committed
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
	gnome_client_set_clone_command (client, 1, argv);
	gnome_client_set_restart_command (client, 1, argv);

	return TRUE;
}


/* die handler for the master client */
static void
client_die_cb (GnomeClient *client, gpointer data)
{
	if (! client->save_yourself_emitted)
		save_session (client);

	gtk_main_quit ();
}


static void
init_session (const char *argv0)
{
	if (master_client != NULL)
		return;

	program_argv0 = argv0;

	master_client = gnome_master_client ();

	g_signal_connect (master_client, "save_yourself",
			  G_CALLBACK (client_save_yourself_cb),
			  NULL);

	g_signal_connect (master_client, "die",
			  G_CALLBACK (client_die_cb),
			  NULL);
}


static gboolean
session_is_restored (void)
{
	gboolean restored;
353

Paolo Bacchilega's avatar
Paolo Bacchilega committed
354 355 356 357 358 359 360 361 362
	if (! master_client)
		return FALSE;

	restored = (gnome_client_get_flags (master_client) & GNOME_CLIENT_RESTORED) != 0;

	return restored;
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
363
/* Initialize application data. */
364
static void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
365 366 367 368 369 370 371 372
initialize_data (poptContext pctx)
{
	const char **argv;
	int          argc;
	char        *current_dir;
	char        *path;
	int          i;

373
	convert_to_new_comment_system ();
Paolo Bacchilega's avatar
Paolo Bacchilega committed
374
	create_default_categories_if_needed ();
375

Paolo Bacchilega's avatar
Paolo Bacchilega committed
376 377
	eel_gconf_monitor_add ("/apps/gthumb");

Paolo Bacchilega's avatar
Paolo Bacchilega committed
378
	monitor = gth_monitor_new ();
Paolo Bacchilega's avatar
Paolo Bacchilega committed
379

380
	/* Icon theme */
Paolo Bacchilega's avatar
Paolo Bacchilega committed
381

382 383 384 385 386 387 388
	icon_theme = gnome_icon_theme_new ();
	gnome_icon_theme_set_allow_svg (icon_theme, TRUE);
	g_signal_connect (icon_theme,
			  "changed",
			  G_CALLBACK (theme_changed_cb),
			  NULL);

389 390
	/* Default windows icon */

391
	init_icon_pixbufs ();
392
	g_set_application_name (_("gThumb"));
393
	gtk_window_set_default_icon_name ("gthumb");
394 395 396

	/**/

397
	init_session ("gthumb");
398
	if (session_is_restored ())
399 400
		return;

Paolo Bacchilega's avatar
Paolo Bacchilega committed
401 402 403 404 405 406 407
	/* Parse command line arguments. */

	argv = poptGetArgs (pctx);

	if (argv == NULL)
		return;

408
	for (argc = 0; argv[argc] != NULL; argc++)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
409 410 411 412 413
		;

	if (argc == 0)
		return;

414 415
	file_urls = g_new0 (char*, argc);
	dir_urls = g_new0 (char*, argc);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
416 417 418 419 420 421

	n_file_urls = 0;
	n_dir_urls = 0;

	current_dir = g_get_current_dir ();
	for (i = 0; i < argc; i++) {
Paolo Bacchilega's avatar
Paolo Bacchilega committed
422 423
		char     *tmp1, *tmp2;
		gboolean  is_dir;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
424 425

		if (! g_path_is_absolute (argv[i]))
Paolo Bacchilega's avatar
Paolo Bacchilega committed
426
			tmp1 = g_strconcat (current_dir, "/", argv[i], NULL);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
427
		else
Paolo Bacchilega's avatar
Paolo Bacchilega committed
428 429
			tmp1 = g_strdup (argv[i]);

430
		tmp2 = remove_special_dirs_from_path (tmp1);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
431 432 433 434 435 436 437

		if (! g_path_is_absolute (tmp2))
			path = g_strconcat (current_dir, "/", tmp2, NULL);
		else {
			path = tmp2;
			tmp2 = NULL;
		}
438

Paolo Bacchilega's avatar
Paolo Bacchilega committed
439 440
		g_free (tmp1);
		g_free (tmp2);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
441 442 443 444 445 446 447 448 449 450 451

		if (path_is_dir (path))
			is_dir = TRUE;
		else if (path_is_file (path))
			is_dir = FALSE;
		else {
			g_free (path);
			continue;
		}

		if (is_dir) {
Paolo Bacchilega's avatar
Paolo Bacchilega committed
452
			dir_urls[n_dir_urls++] = get_uri_from_path (path);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
453 454 455 456 457
			g_free (path);
		} else
			file_urls[n_file_urls++] = path;
	}

458 459 460 461
	if ((n_file_urls == 1) && (file_urls[0] != NULL)) {
		view_single_image = TRUE;

	} else if (n_file_urls > 1) {
Paolo Bacchilega's avatar
Paolo Bacchilega committed
462 463
		/* Create a catalog with the command line list. */
		Catalog *catalog;
464
		char    *catalog_path;
465
		char    *catalog_name, *catalog_name_utf8;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
466 467 468

		catalog = catalog_new ();

469 470 471
		catalog_name_utf8 = g_strconcat (_("Command Line"),
						 CATALOG_EXT,
						 NULL);
472
		catalog_name = g_filename_from_utf8 (catalog_name_utf8, -1, 0, 0, 0);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
473 474
		catalog_path = get_catalog_full_path (catalog_name);
		g_free (catalog_name);
475
		g_free (catalog_name_utf8);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
476 477 478 479

		catalog_set_path (catalog, catalog_path);
		g_free (catalog_path);

480
		for (i = 0; i < n_file_urls; i++)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
481 482 483 484 485 486 487 488 489 490 491 492 493
			catalog_add_item (catalog, file_urls[i]);

		catalog_write_to_disk (catalog, NULL);
		catalog_free (catalog);

		view_comline_catalog = TRUE;
	}

	g_free (current_dir);
}


/* Free application data. */
494
static void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
495
release_data (void)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
496
{
497 498 499
	if (gth_application != NULL)
                bonobo_object_unref (gth_application);

500
	free_icon_pixbufs ();
Paolo Bacchilega's avatar
Paolo Bacchilega committed
501

502 503
	g_object_unref (icon_theme);

Paolo Bacchilega's avatar
Paolo Bacchilega committed
504 505 506 507 508
	if (monitor != NULL) {
		g_object_unref (monitor);
		monitor = NULL;
	}

Paolo Bacchilega's avatar
Paolo Bacchilega committed
509 510 511 512 513
	preferences_release ();
	eel_global_client_free ();
}


514
static void
515 516 517 518
open_viewer_window (const char               *uri,
		    gboolean                  use_factory,
		    GNOME_GThumb_Application  app,
		    CORBA_Environment        *env)
519 520 521
{
	GtkWidget *current_window;

522 523 524 525 526 527 528
	if (use_factory) {
		if (uri == NULL)
			uri = "";
		GNOME_GThumb_Application_open_viewer (app, uri, env);
		return;
	}

529 530 531 532 533 534 535
	current_window = gth_viewer_new (uri);
	gtk_widget_show (current_window);
	if (first_window == NULL)
		first_window = current_window;
}


536
static void
537
open_browser_window (const char               *uri,
538 539 540 541
		     gboolean                  show_window,
		     gboolean                  use_factory,
		     GNOME_GThumb_Application  app,
		     CORBA_Environment        *env)
542 543 544
{
	GtkWidget *current_window;

545 546 547 548 549 550 551
	if (use_factory) {
		if (uri == NULL)
			uri = "";
		GNOME_GThumb_Application_open_browser (app, uri, env);
		return;
	}

552 553 554 555 556 557 558 559
	current_window = gth_browser_new (uri);
	if (show_window)
		gtk_widget_show (current_window);
	if (first_window == NULL)
		first_window = current_window;
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
560
static void
561 562 563
load_session (gboolean                  use_factory,
	      GNOME_GThumb_Application  app,
	      CORBA_Environment        *env)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
564 565
{
	int i, n;
566

Paolo Bacchilega's avatar
Paolo Bacchilega committed
567 568 569 570 571 572 573 574 575 576
	gnome_config_push_prefix (gnome_client_get_config_prefix (master_client));

	n = gnome_config_get_int ("Session/locations");
	for (i = 0; i < n; i++) {
		char *key;
		char *location;

		key = g_strdup_printf ("Session/location%d", i);
		location = gnome_config_get_string (key);

Paolo Bacchilega's avatar
Paolo Bacchilega committed
577
		if (uri_scheme_is_file (location) && path_is_file (location))
578
			open_viewer_window (location, use_factory, app, env);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
579
		else
580
			open_browser_window (location, TRUE, use_factory, app, env);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
581 582 583 584 585 586 587 588 589

		g_free (location);
		g_free (key);
	}

	gnome_config_pop_prefix ();
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
590
/* Create the windows. */
591
static void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
592
prepare_app (void)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
593
{
594 595 596 597
	CORBA_Object              factory;
	gboolean                  use_factory = FALSE;
	CORBA_Environment         env;
	GNOME_GThumb_Application  app;
598
	int                       i;
599

600 601 602 603 604 605 606 607 608 609
	factory = bonobo_activation_activate_from_id ("OAFIID:GNOME_GThumb_Application_Factory",
                                                      Bonobo_ACTIVATION_FLAG_EXISTING_ONLY,
                                                      NULL, NULL);

	if (factory != NULL) {
		use_factory = TRUE;
		CORBA_exception_init (&env);
		app = bonobo_activation_activate_from_id ("OAFIID:GNOME_GThumb_Application", 0, NULL, &env);
	}

Paolo Bacchilega's avatar
Paolo Bacchilega committed
610
	if (session_is_restored ()) {
611
		load_session (use_factory, app, &env);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
612 613 614
		return;
	}

615
	if (ImportPhotos) {
616 617 618 619
		if (use_factory)
			GNOME_GThumb_Application_import_photos (app, &env);
		else
			gth_browser_activate_action_file_camera_import (NULL, NULL);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
620

621 622
	} else if (! view_comline_catalog
	    && (n_dir_urls == 0)
623
	    && (n_file_urls == 0)) {
624
		open_browser_window (NULL, TRUE, use_factory, app, &env);
625 626

	} else if (view_single_image) {
627 628 629 630 631 632 633 634 635
		if (use_factory && eel_gconf_get_boolean (PREF_SINGLE_WINDOW, FALSE))
			GNOME_GThumb_Application_load_image (app, file_urls[0], &env);
		else {
			if (UseViewer)
				open_viewer_window (file_urls[0], use_factory, app, &env);
			else
				open_browser_window (file_urls[0], TRUE, use_factory, app, &env);
		}

636
	} else if (view_comline_catalog) {
Paolo Bacchilega's avatar
Paolo Bacchilega committed
637 638 639 640
		char *catalog_uri;
		char *catalog_path;
		char *catalog_name;

641 642 643
		ViewFirstImage = TRUE;
		HideSidebar = TRUE;

Paolo Bacchilega's avatar
Paolo Bacchilega committed
644 645 646 647
		catalog_name = g_strconcat (_("Command Line"), CATALOG_EXT, NULL);
		catalog_path = get_catalog_full_path (catalog_name);
		catalog_uri = g_strconcat ("catalog://", catalog_path, NULL);

648
		open_browser_window (catalog_uri, TRUE, use_factory, app, &env);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
649

650 651 652
		g_free (catalog_name);
		g_free (catalog_path);
		g_free (catalog_uri);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
653 654 655
	}

	for (i = 0; i < n_dir_urls; i++) {
Paolo Bacchilega's avatar
Paolo Bacchilega committed
656
		/* Go to the specified directory. */
657
		open_browser_window (dir_urls[i], TRUE, use_factory, app, &env);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
	}

	/* Free urls. */

	if (n_file_urls > 0) {
		for (i = 0; i < n_file_urls; i++)
			g_free (file_urls[i]);
		g_free (file_urls);
	}

	if (n_dir_urls > 0) {
		for (i = 0; i < n_dir_urls; i++)
			g_free (dir_urls[i]);
		g_free (dir_urls);
	}
673 674 675 676 677 678 679 680 681 682

	/**/

	if (use_factory) {
		bonobo_object_release_unref (app, &env);
		CORBA_exception_free (&env);
		gdk_notify_startup_complete ();
		exit (0);
	} else
		gth_application = gth_application_new (gdk_screen_get_default ());
Paolo Bacchilega's avatar
Paolo Bacchilega committed
683
}
Paolo Bacchilega's avatar
Paolo Bacchilega committed
684 685


686 687
int
main (int   argc,
Paolo Bacchilega's avatar
Paolo Bacchilega committed
688 689 690 691 692 693 694 695 696 697 698
      char *argv[])
{
	GnomeProgram *program;
	GValue        value = { 0 };
	poptContext   pctx;

	bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	program = gnome_program_init ("gthumb", VERSION,
699
				      LIBGNOMEUI_MODULE,
Paolo Bacchilega's avatar
Paolo Bacchilega committed
700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
				      argc, argv,
				      GNOME_PARAM_POPT_TABLE, options,
				      GNOME_PARAM_HUMAN_READABLE_NAME, _("gThumb"),
				      GNOME_PARAM_APP_PREFIX, GTHUMB_PREFIX,
				      GNOME_PARAM_APP_SYSCONFDIR, GTHUMB_SYSCONFDIR,
				      GNOME_PARAM_APP_DATADIR, GTHUMB_DATADIR,
				      GNOME_PARAM_APP_LIBDIR, GTHUMB_LIBDIR,
				      NULL);

	if (! g_thread_supported ()) {
		g_thread_init (NULL);
		gdk_threads_init ();
	}

	g_object_get_property (G_OBJECT (program),
			       GNOME_PARAM_POPT_CONTEXT,
			       g_value_init (&value, G_TYPE_POINTER));

	pctx = g_value_get_pointer (&value);
	glade_gnome_init ();
	gthumb_init ();
	initialize_data (pctx);
	poptFreeContext (pctx);
	prepare_app ();

	gtk_main ();

	release_data ();
	return 0;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
729 730 731
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
732 733 734
/**/


735
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
736
all_windows_update_catalog_list (void)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
737
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
738
	gth_monitor_notify_reload_catalogs (monitor);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
739 740 741
}


742
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
743
all_windows_notify_update_bookmarks (void)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
744
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
745
	gth_monitor_notify_update_bookmarks (monitor);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
746 747 748
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
749 750 751
void
all_windows_notify_cat_files_created (const char *catalog_path,
				      GList      *list)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
752
{
753 754 755
	gth_monitor_notify_update_cat_files (monitor,
					     catalog_path,
					     GTH_MONITOR_EVENT_CREATED,
Paolo Bacchilega's avatar
Paolo Bacchilega committed
756
					     list);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
757 758 759
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
760 761 762
void
all_windows_notify_cat_files_deleted (const char *catalog_path,
				      GList      *list)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
763
{
764 765 766
	gth_monitor_notify_update_cat_files (monitor,
					     catalog_path,
					     GTH_MONITOR_EVENT_DELETED,
Paolo Bacchilega's avatar
Paolo Bacchilega committed
767
					     list);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
768 769 770
}


771
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
772
all_windows_notify_files_created (GList *list)
773
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
774
	gth_monitor_notify_update_files (monitor, GTH_MONITOR_EVENT_CREATED, list);
775 776 777
}


778
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
779
all_windows_notify_files_deleted (GList *list)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
780
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
781
	gth_monitor_notify_update_files (monitor, GTH_MONITOR_EVENT_DELETED, list);
782 783 784
}


785
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
786
all_windows_notify_files_changed (GList *list)
787
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
788
	gth_monitor_notify_update_files (monitor, GTH_MONITOR_EVENT_CHANGED, list);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
789 790 791
}


792
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
793 794 795
all_windows_notify_file_rename (const gchar *old_name,
				const gchar *new_name)
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
796
	gth_monitor_notify_file_renamed (monitor, old_name, new_name);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
797 798 799 800
}


void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
801 802
all_windows_notify_files_rename (GList *old_names,
				 GList *new_names)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
803 804 805 806 807 808 809
{
	GList *o_scan, *n_scan;

	for (o_scan = old_names, n_scan = new_names; o_scan && n_scan;) {
		const char *old_name = o_scan->data;
		const char *new_name = n_scan->data;

Paolo Bacchilega's avatar
Paolo Bacchilega committed
810
		gth_monitor_notify_file_renamed (monitor, old_name, new_name);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
811
		all_windows_notify_file_rename (old_name, new_name);
812

Paolo Bacchilega's avatar
Paolo Bacchilega committed
813 814 815 816 817 818
		o_scan = o_scan->next;
		n_scan = n_scan->next;
	}
}


819
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
820 821 822
all_windows_notify_directory_rename (const gchar *old_name,
				     const gchar *new_name)
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
823
	gth_monitor_notify_directory_renamed (monitor, old_name, new_name);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
824 825 826
}


827
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
828
all_windows_notify_directory_delete (const char *path)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
829
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
830
	gth_monitor_notify_update_directory (monitor, path, GTH_MONITOR_EVENT_DELETED);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
831 832 833
}


834
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
835
all_windows_notify_directory_new (const char *path)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
836
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
837
	gth_monitor_notify_update_directory (monitor, path, GTH_MONITOR_EVENT_CREATED);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
838 839 840 841
}


void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
842 843
all_windows_notify_catalog_rename (const char *old_name,
				   const char *new_name)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
844
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
845
	gth_monitor_notify_catalog_renamed (monitor, old_name, new_name);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
846 847 848
}


849 850 851
void
all_windows_notify_catalog_new (const gchar *path)
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
852
	gth_monitor_notify_update_catalog (monitor, path, GTH_MONITOR_EVENT_CREATED);
853 854 855
}


Paolo Bacchilega's avatar
Paolo Bacchilega committed
856 857 858
void
all_windows_notify_catalog_delete (const gchar *path)
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
859
	gth_monitor_notify_update_catalog (monitor, path, GTH_MONITOR_EVENT_DELETED);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
860 861 862
}


863 864 865 866 867 868 869
void
all_windows_notify_catalog_reordered (const gchar *path)
{
	gth_monitor_notify_update_catalog (monitor, path, GTH_MONITOR_EVENT_CHANGED);
}


870
void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
871
all_windows_notify_update_metadata (const gchar *filename)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
872
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
873
	gth_monitor_notify_update_metadata (monitor, filename);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
874 875 876 877
}


void
Paolo Bacchilega's avatar
Paolo Bacchilega committed
878
all_windows_notify_update_icon_theme (void)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
879
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
880
	gth_monitor_notify_update_icon_theme (monitor);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
881 882 883
}


884
gboolean
Paolo Bacchilega's avatar
Paolo Bacchilega committed
885
all_windows_remove_monitor (void)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
886
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
887
	gth_monitor_pause (monitor);
888
	return FALSE;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
889 890 891
}


892
gboolean
Paolo Bacchilega's avatar
Paolo Bacchilega committed
893
all_windows_add_monitor (void)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
894
{
Paolo Bacchilega's avatar
Paolo Bacchilega committed
895
	gth_monitor_resume (monitor);
896
	return FALSE;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
897 898 899
}


900 901 902
static GdkPixbuf *
get_fs_icon (IconName icon_name,
	     double   icon_size)
Paolo Bacchilega's avatar
Paolo Bacchilega committed
903
{
904 905 906 907 908 909 910 911 912 913 914 915
	GdkPixbuf *pixbuf = NULL;
	gboolean   scale = TRUE;

	/*
	if (icon_pixbuf[icon_name] != NULL) {
		g_object_ref (icon_pixbuf[icon_name]);
		return icon_pixbuf[icon_name];
	}

	icon_pixbuf[icon_name] = create_pixbuf (icon_theme,
						icon_mime_name[icon_name],
						icon_size);
916

917 918
	return icon_pixbuf[icon_name];
	*/
Paolo Bacchilega's avatar
Paolo Bacchilega committed
919

920 921 922 923
	if (icon_pixbuf[icon_name] == NULL) {
		const GnomeIconData *icon_data;
		int                  base_size;
		char                *icon_path;
924

925
		icon_path = gnome_icon_theme_lookup_icon (icon_theme,
926
							  icon_mime_name[icon_name],
927
							  icon_size,
928 929
							  &icon_data,
							  &base_size);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
930 931

		if (icon_path == NULL) {
932 933 934
			icon_pixbuf[icon_name] = gdk_pixbuf_new_from_inline (-1,
									     dir_16_rgba,
									     FALSE,
935
									     NULL);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
936 937
			scale = FALSE;
		} else {
938
			icon_pixbuf[icon_name] = gdk_pixbuf_new_from_file (icon_path,
939
									   NULL);
Paolo Bacchilega's avatar
Paolo Bacchilega committed
940 941 942 943 944 945 946
			g_free (icon_path);
		}
	}

	/* Scale keeping aspect ratio. */

 	if (! scale) {
947 948
		g_object_ref (icon_pixbuf[icon_name]);
		return icon_pixbuf[icon_name];
Paolo Bacchilega's avatar
Paolo Bacchilega committed
949
	}
950 951

	if (icon_pixbuf[icon_name] != NULL) {
952
		int w, h;
953

954 955
		w = gdk_pixbuf_get_width (icon_pixbuf[icon_name]);
		h = gdk_pixbuf_get_height (icon_pixbuf[icon_name]);
956
		if (scale_keepping_ratio (&w, &h, icon_size, icon_size))
957
			pixbuf = gdk_pixbuf_scale_simple (icon_pixbuf[icon_name],
958 959 960 961
							  w,
							  h,
							  GDK_INTERP_BILINEAR);
		else {
962
			pixbuf = icon_pixbuf[icon_name];
963 964
			g_object_ref (pixbuf);
		}
Paolo Bacchilega's avatar
Paolo Bacchilega committed
965 966 967 968
	}

	return pixbuf;
}
969 970


971 972 973 974 975 976 977
GdkPixbuf *
get_folder_pixbuf (double icon_size)
{
	return get_fs_icon (ICON_NAME_DIRECTORY, icon_size);
}


978
int
979
get_folder_pixbuf_size_for_list (GtkWidget *widget)
980 981 982 983
{
	int icon_width, icon_height;

	gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
984 985 986 987 988 989 990 991 992 993 994 995 996
                                           GTK_ICON_SIZE_SMALL_TOOLBAR,
                                           &icon_width, &icon_height);
	return MAX (icon_width, icon_height);
}


int
get_folder_pixbuf_size_for_menu (GtkWidget *widget)
{
	int icon_width, icon_height;

	gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
                                           GTK_ICON_SIZE_MENU,
997 998 999
                                           &icon_width, &icon_height);
	return MAX (icon_width, icon_height);
}
1000 1001 1002 1003 1004 1005 1006 1007


gboolean
folder_is_film (const char *folder)
{
	CommentData *cdata;
	gboolean     film = FALSE;

Paolo Bacchilega's avatar
Paolo Bacchilega committed
1008
	folder = remove_scheme_from_uri (folder);
1009

1010
	cdata = comments_load_comment (folder, FALSE);
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
	if (cdata != NULL) {
		int i;
		for (i = 0; i < cdata->keywords_n; i++)
			if (g_utf8_collate (cdata->keywords[i], _("Film")) == 0) {
				film = TRUE;
				break;
			}
		comment_data_free (cdata);
	}

	return film;
}
1023 1024 1025 1026 1027 1028 1029


G_CONST_RETURN char *
get_stock_id_for_uri (const char *uri)
{
	const char *stock_id;

1030
	if (strcmp (uri, g_get_home_dir ()) == 0)
1031
		stock_id = GTK_STOCK_HOME;
1032
	else if (strcmp (uri, get_home_uri ()) == 0)
1033 1034 1035
		stock_id = GTK_STOCK_HOME;
	else if (folder_is_film (uri))
		stock_id = GTHUMB_STOCK_FILM;
1036
	else if (uri_scheme_is_catalog (uri))
1037
		stock_id = GTHUMB_STOCK_CATALOG;
1038
	else if (uri_scheme_is_search (uri))
1039 1040 1041 1042 1043 1044
		stock_id = GTHUMB_STOCK_SEARCH;
	else
		stock_id = GTK_STOCK_OPEN;

	return stock_id;
}
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055


GdkPixbuf *
get_icon_for_uri (GtkWidget  *widget,
		  const char *uri)
{
	const char *stock_id = NULL;
	int         menu_size;

	menu_size = get_folder_pixbuf_size_for_list (widget);

1056
	if (strcmp (uri, g_get_home_dir ()) == 0)
1057
		return get_fs_icon (ICON_NAME_HOME, menu_size);
1058
	else if (strcmp (uri, get_home_uri ()) == 0)
1059 1060
		return get_fs_icon (ICON_NAME_HOME, menu_size);

1061
	if ((strcmp (uri, "file://") == 0) || (strcmp (uri, "/") == 0))
1062 1063 1064 1065
		return get_fs_icon (ICON_NAME_HARDDISK, menu_size);

	if (folder_is_film (uri))
		stock_id = GTHUMB_STOCK_FILM;
Paolo Bacchilega's avatar
Paolo Bacchilega committed
1066 1067 1068 1069 1070 1071
	else if (uri_scheme_is_catalog (uri)) {
		if (file_extension_is (uri, CATALOG_EXT))
			stock_id = GTHUMB_STOCK_CATALOG;
		else
			stock_id = GTHUMB_STOCK_LIBRARY;
	}
1072
	else if (uri_scheme_is_search (uri))
1073 1074 1075
		stock_id = GTHUMB_STOCK_SEARCH;

	if (stock_id != NULL)
1076
		return gtk_widget_render_icon (widget, stock_id, GTK_ICON_SIZE_MENU, NULL);
1077 1078 1079
	else
		return get_fs_icon (ICON_NAME_DIRECTORY, menu_size);
}