~ubuntu-branches/ubuntu/saucy/file-roller/saucy-proposed

1.8.1 by Andreas Henriksson
Import upstream version 3.7.92
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3
/*
4
 *  File-Roller
5
 *
6
 *  Copyright (C) 2012 Free Software Foundation, Inc.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
23
#include <config.h>
24
#include <string.h>
25
#include <sys/types.h>
26
#include <signal.h>
27
#include <stdlib.h>
28
#include <glib/gi18n.h>
29
#include <glib/gprintf.h>
30
#ifdef ENABLE_NOTIFICATION
31
#  include <libnotify/notify.h>
32
#endif
33
#include "app-menu.h"
34
#ifdef USE_SMCLIENT
35
#  include "eggsmclient.h"
36
#endif
37
#include "eggdesktopfile.h"
38
#include "file-utils.h"
39
#include "fr-application.h"
40
#include "fr-init.h"
41
#include "glib-utils.h"
42
#include "gtk-utils.h"
43
44
45
#define ORG_GNOME_ARCHIVEMANAGER_XML "/org/gnome/FileRoller/../data/org.gnome.ArchiveManager1.xml"
46
#define SERVICE_TIMEOUT 10
47
48
49
gint                ForceDirectoryCreation;
50
static char       **remaining_args;
51
static char        *arg_add_to = NULL;
52
static int          arg_add = FALSE;
53
static char        *arg_extract_to = NULL;
54
static int          arg_extract = FALSE;
55
static int          arg_extract_here = FALSE;
56
static char        *arg_default_dir = NULL;
57
static gboolean     arg_version = FALSE;
58
static gboolean     arg_service = FALSE;
59
static gboolean     arg_notify = FALSE;
60
static const char  *program_argv0 = NULL; /* argv[0] from main(); used as the command to restart the program */
61
62
63
static const GOptionEntry options[] = {
64
	{ "add-to", 'a', 0, G_OPTION_ARG_STRING, &arg_add_to,
65
	  N_("Add files to the specified archive and quit the program"),
66
	  N_("ARCHIVE") },
67
68
	{ "add", 'd', 0, G_OPTION_ARG_NONE, &arg_add,
69
	  N_("Add files asking the name of the archive and quit the program"),
70
	  NULL },
71
72
	{ "extract-to", 'e', 0, G_OPTION_ARG_STRING, &arg_extract_to,
73
	  N_("Extract archives to the specified folder and quit the program"),
74
	  N_("FOLDER") },
75
76
	{ "extract", 'f', 0, G_OPTION_ARG_NONE, &arg_extract,
77
	  N_("Extract archives asking the destination folder and quit the program"),
78
	  NULL },
79
80
	{ "extract-here", 'h', 0, G_OPTION_ARG_NONE, &arg_extract_here,
81
	  N_("Extract the contents of the archives in the archive folder and quit the program"),
82
	  NULL },
83
84
	{ "default-dir", '\0', 0, G_OPTION_ARG_STRING, &arg_default_dir,
85
	  N_("Default folder to use for the '--add' and '--extract' commands"),
86
	  N_("FOLDER") },
87
88
	{ "force", '\0', 0, G_OPTION_ARG_NONE, &ForceDirectoryCreation,
89
	  N_("Create destination folder without asking confirmation"),
90
	  NULL },
91
92
	{ "notify", '\0', 0, G_OPTION_ARG_NONE, &arg_notify,
93
	  N_("Use the notification system to notify the operation completion"), NULL },
94
95
	{ "service", '\0', 0, G_OPTION_ARG_NONE, &arg_service,
96
	  N_("Start as a service"), NULL },
97
98
	{ "version", 'v', 0, G_OPTION_ARG_NONE, &arg_version,
99
	  N_("Show version"), NULL },
100
101
	{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining_args,
102
	  NULL,
103
	  NULL },
104
105
	{ NULL }
106
};
107
108
109
/* -- session management -- */
110
111
112
#ifdef USE_SMCLIENT
113
114
115
static void
116
client_save_state (EggSMClient *client,
117
		   GKeyFile    *state,
118
		   gpointer     user_data)
119
{
120
	/* discard command is automatically set by EggSMClient */
121
122
	GApplication *application;
123
	const char   *argv[2] = { NULL };
124
	guint         i;
125
126
	/* restart command */
127
	argv[0] = program_argv0;
128
	argv[1] = NULL;
129
130
	egg_sm_client_set_restart_command (client, 1, argv);
131
132
	/* state */
133
	application = g_application_get_default ();
134
	if (application != NULL) {
135
		GList *window;
136
137
		for (window = gtk_application_get_windows (GTK_APPLICATION (application)), i = 0;
138
		     window != NULL;
139
		     window = window->next, i++)
140
		{
141
			FrWindow *session = window->data;
142
			gchar    *key;
143
144
			key = g_strdup_printf ("archive%d", i);
145
			if ((session->archive == NULL) || (fr_archive_get_file (session->archive) == NULL)) {
146
				g_key_file_set_string (state, "Session", key, "");
147
			}
148
			else {
149
				gchar *uri;
150
151
				uri = g_file_get_uri (fr_archive_get_file (session->archive));
152
				g_key_file_set_string (state, "Session", key, uri);
153
				g_free (uri);
154
			}
155
			g_free (key);
156
		}
157
	}
158
159
	g_key_file_set_integer (state, "Session", "archives", i);
160
}
161
162
163
static void
164
client_quit_cb (EggSMClient *client,
165
		gpointer     data)
166
{
167
	gtk_main_quit ();
168
}
169
170
171
static void
172
fr_restore_session (EggSMClient *client)
173
{
174
	GKeyFile *state = NULL;
175
	guint i;
176
177
	state = egg_sm_client_get_state_file (client);
178
179
	i = g_key_file_get_integer (state, "Session", "archives", NULL);
180
181
	for (; i > 0; i--) {
182
		GtkWidget *window;
183
		char      *key;
184
		char      *uri;
185
186
		key = g_strdup_printf ("archive%d", i);
187
		uri = g_key_file_get_string (state, "Session", key, NULL);
188
189
		window = fr_window_new ();
190
		if (strlen (uri) > 0) {
191
			GFile *file;
192
193
			file = g_file_new_for_uri (uri);
194
			fr_window_archive_open (FR_WINDOW (window), file, GTK_WINDOW (window));
195
196
			g_object_unref (file);
197
		}
198
199
		g_free (uri);
200
		g_free (key);
201
	}
202
}
203
204
205
#endif /* USE_SMCLIENT */
206
207
208
/* -- service -- */
209
210
211
static void
212
window_ready_cb (GtkWidget *widget,
213
		 GError    *error,
214
		 gpointer   user_data)
215
{
216
	if (error == NULL)
217
		g_dbus_method_invocation_return_value ((GDBusMethodInvocation *) user_data, NULL);
218
	else
219
		g_dbus_method_invocation_return_error ((GDBusMethodInvocation *) user_data,
220
						       error->domain,
221
						       error->code,
222
						       "%s",
223
						       error->message);
224
}
225
226
227
static gboolean
228
window_progress_cb (FrWindow *window,
229
		    double    fraction,
230
		    char     *details,
231
		    gpointer  user_data)
232
{
233
	GDBusConnection *connection = user_data;
234
235
	g_dbus_connection_emit_signal (connection,
236
				       NULL,
237
				       "org/gnome/ArchiveManager1",
238
				       "org.gnome.ArchiveManager1",
239
				       "Progress",
240
				       g_variant_new ("(ds)",
241
						      fraction,
242
						      details),
243
				       NULL);
244
245
	return TRUE;
246
}
247
248
249
static void
250
handle_method_call (GDBusConnection       *connection,
251
		    const char            *sender,
252
		    const char            *object_path,
253
		    const char            *interface_name,
254
		    const char            *method_name,
255
		    GVariant              *parameters,
256
		    GDBusMethodInvocation *invocation,
257
		    gpointer               user_data)
258
{
259
	update_registered_archives_capabilities ();
260
261
	if (g_strcmp0 (method_name, "GetSupportedTypes") == 0) {
262
		char *action;
263
		int  *supported_types = NULL;
264
265
		g_variant_get (parameters, "(s)", &action);
266
267
		if (g_strcmp0 (action, "create") == 0) {
268
			supported_types = save_type;
269
		}
270
		else if (g_strcmp0 (action, "create_single_file") == 0) {
271
			supported_types = single_file_save_type;
272
		}
273
		else if (g_strcmp0 (action, "extract") == 0) {
274
			supported_types = open_type;
275
		}
276
277
		if (supported_types == NULL) {
278
			g_dbus_method_invocation_return_error (invocation,
279
							       G_IO_ERROR,
280
							       G_IO_ERROR_INVALID_ARGUMENT,
281
							       "Invalid action '%s', valid values are: create, create_single_file, extract",
282
							       action);
283
		}
284
		else {
285
			GVariantBuilder builder;
286
			int             i;
287
288
			g_variant_builder_init (&builder, G_VARIANT_TYPE ("(aa{ss})"));
289
			g_variant_builder_open (&builder, G_VARIANT_TYPE ("aa{ss}"));
290
			for (i = 0; supported_types[i] != -1; i++) {
291
				g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{ss}"));
292
				g_variant_builder_add (&builder, "{ss}",
293
						       "mime-type",
294
						       mime_type_desc[supported_types[i]].mime_type);
295
				g_variant_builder_add (&builder, "{ss}",
296
						       "default-extension",
297
						       mime_type_desc[supported_types[i]].default_ext);
298
				g_variant_builder_close (&builder);
299
			}
300
			g_variant_builder_close (&builder);
301
302
			g_dbus_method_invocation_return_value (invocation, g_variant_builder_end (&builder));
303
		}
304
305
		g_free (action);
306
	}
307
	else if (g_strcmp0 (method_name, "AddToArchive") == 0) {
308
		char       *archive_uri;
309
		char      **files;
310
		gboolean    use_progress_dialog;
311
		int         i;
312
		GFile      *file;
313
		GList      *file_list = NULL;
314
		GtkWidget  *window;
315
316
		g_variant_get (parameters, "(s^asb)", &archive_uri, &files, &use_progress_dialog);
317
318
		file = g_file_new_for_uri (archive_uri);
319
		for (i = 0; files[i] != NULL; i++)
320
			file_list = g_list_prepend (file_list, g_file_new_for_uri (files[i]));
321
		file_list = g_list_reverse (file_list);
322
323
		window = fr_window_new ();
324
		fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
325
326
		g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
327
		g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
328
329
		fr_window_new_batch (FR_WINDOW (window), _("Compress"));
330
		fr_window_set_batch__add (FR_WINDOW (window), file, file_list);
331
		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
332
		fr_window_start_batch (FR_WINDOW (window));
333
334
		g_object_unref (file);
335
		_g_object_list_unref (file_list);
336
		g_free (archive_uri);
337
	}
338
	else if (g_strcmp0 (method_name, "Compress") == 0) {
339
		char      **files;
340
		char       *destination_uri;
341
		gboolean    use_progress_dialog;
342
		int         i;
343
		GList      *file_list = NULL;
344
		GFile      *destination;
345
		GtkWidget  *window;
346
347
		g_variant_get (parameters, "(^assb)", &files, &destination_uri, &use_progress_dialog);
348
349
		if ((destination_uri != NULL) && (strcmp (destination_uri, "") != 0))
350
			destination = g_file_new_for_uri (destination_uri);
351
		else
352
			destination = g_file_get_parent (G_FILE (file_list->data));
353
354
		for (i = 0; files[i] != NULL; i++)
355
			file_list = g_list_prepend (file_list, g_file_new_for_uri (files[i]));
356
		file_list = g_list_reverse (file_list);
357
358
		window = fr_window_new ();
359
		fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
360
		fr_window_set_default_dir (FR_WINDOW (window), destination, TRUE);
361
362
		g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
363
		g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
364
365
		fr_window_new_batch (FR_WINDOW (window), _("Extract archive"));
366
		fr_window_set_batch__add (FR_WINDOW (window), NULL, file_list);
367
		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
368
		fr_window_start_batch (FR_WINDOW (window));
369
370
		_g_object_list_unref (file_list);
371
		g_object_unref (destination);
372
		g_free (destination_uri);
373
	}
374
	else if (g_strcmp0 (method_name, "Extract") == 0) {
375
		char      *archive_uri;
376
		char      *destination_uri;
377
		gboolean   use_progress_dialog;
378
		GtkWidget *window;
379
		GFile     *archive;
380
		GFile     *destination;
381
382
		g_variant_get (parameters, "(ssb)", &archive_uri, &destination_uri, &use_progress_dialog);
383
384
		archive = g_file_new_for_uri (archive_uri);
385
		destination = g_file_new_for_uri (destination_uri);
386
387
		window = fr_window_new ();
388
		fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
389
		if ((destination_uri != NULL) & (strcmp (destination_uri, "") != 0)) {
390
			GFile *file;
391
392
			file = g_file_new_for_uri (destination_uri);
393
			fr_window_set_default_dir (FR_WINDOW (window), file, TRUE);
394
395
			g_object_unref (file);
396
		}
397
398
		g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
399
		g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
400
401
		fr_window_new_batch (FR_WINDOW (window), _("Extract archive"));
402
		fr_window_set_batch__extract (FR_WINDOW (window), archive, destination);
403
		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
404
		fr_window_start_batch (FR_WINDOW (window));
405
406
		g_object_unref (archive);
407
		g_object_unref (destination);
408
		g_free (destination_uri);
409
		g_free (archive_uri);
410
	}
411
	else if (g_strcmp0 (method_name, "ExtractHere") == 0) {
412
		char      *uri;
413
		GFile     *archive;
414
		gboolean   use_progress_dialog;
415
		GtkWidget *window;
416
417
		g_variant_get (parameters, "(sb)", &uri, &use_progress_dialog);
418
419
		archive = g_file_new_for_uri (uri);
420
421
		window = fr_window_new ();
422
		fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
423
424
		g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
425
		g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
426
427
		fr_window_new_batch (FR_WINDOW (window), _("Extract archive"));
428
		fr_window_set_batch__extract_here (FR_WINDOW (window), archive);
429
		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
430
		fr_window_start_batch (FR_WINDOW (window));
431
432
		g_object_unref (archive);
433
		g_free (uri);
434
	}
435
}
436
437
438
static const GDBusInterfaceVTable interface_vtable = {
439
	handle_method_call,
440
	NULL, 			/* handle_get_property */
441
	NULL 			/* handle_set_property */
442
};
443
444
445
/* -- main application -- */
446
447
448
G_DEFINE_TYPE (FrApplication, fr_application, GTK_TYPE_APPLICATION)
449
450
451
struct _FrApplicationPrivate {
452
	GDBusNodeInfo *introspection_data;
453
	guint          owner_id;
454
	GSettings     *listing_settings;
455
	GSettings     *ui_settings;
456
};
457
458
459
static void
460
fr_application_finalize (GObject *object)
461
{
462
	FrApplication *self = FR_APPLICATION (object);
463
464
	if (self->priv->introspection_data != NULL)
465
		g_dbus_node_info_unref (self->priv->introspection_data);
466
	if (self->priv->owner_id != 0)
467
		g_bus_unown_name (self->priv->owner_id);
468
	_g_object_unref (self->priv->listing_settings);
469
	_g_object_unref (self->priv->ui_settings);
470
471
	release_data ();
472
473
        G_OBJECT_CLASS (fr_application_parent_class)->finalize (object);
474
}
475
476
477
static void
478
on_bus_acquired_for_archive_manager (GDBusConnection *connection,
479
				     const char      *name,
480
				     gpointer         user_data)
481
{
482
	FrApplication *self = user_data;
483
	guint          registration_id;
484
	GError        *error = NULL;
485
486
	registration_id = g_dbus_connection_register_object (connection,
487
							     "/org/gnome/ArchiveManager1",
488
							     self->priv->introspection_data->interfaces[0],
489
							     &interface_vtable,
490
							     NULL,
491
							     NULL,  /* user_data_free_func */
492
							     &error); /* GError** */
493
	if (registration_id == 0) {
494
		g_error ("%s", error->message);
495
		g_clear_error (&error);
496
	}
497
}
498
499
500
static gboolean
501
service_timeout_cb (gpointer user_data)
502
{
503
	g_application_release (G_APPLICATION (user_data));
504
	return FALSE;
505
}
506
507
508
static void
509
fr_application_register_archive_manager_service (FrApplication *self)
510
{
511
	gsize         size;
512
	guchar       *buffer;
513
	GInputStream *stream;
514
	gsize         bytes_read;
515
	GError       *error = NULL;
516
517
	g_application_hold (G_APPLICATION (self));
518
519
	g_resources_get_info (ORG_GNOME_ARCHIVEMANAGER_XML, 0, &size, NULL, NULL);
520
	buffer = g_new (guchar, size + 1);
521
	stream = g_resources_open_stream (ORG_GNOME_ARCHIVEMANAGER_XML, 0, NULL);
522
	if (g_input_stream_read_all (stream, buffer, size, &bytes_read, NULL, NULL)) {
523
		buffer[bytes_read] = '\0';
524
525
		self->priv->introspection_data = g_dbus_node_info_new_for_xml ((gchar *) buffer, &error);
526
		if (self->priv->introspection_data != NULL) {
527
			self->priv->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
528
							 "org.gnome.ArchiveManager1",
529
							 G_BUS_NAME_OWNER_FLAGS_NONE,
530
							 on_bus_acquired_for_archive_manager,
531
							 NULL /*on_name_acquired*/,
532
							 NULL /*on_name_lost*/,
533
							 self,
534
							 NULL);
535
		}
536
		else {
537
			g_warning ("%s", error->message);
538
			g_clear_error (&error);
539
		}
540
	}
541
542
	g_timeout_add_seconds (SERVICE_TIMEOUT, service_timeout_cb, self);
543
544
	g_free (buffer);
545
}
546
547
548
static void
549
fr_application_startup (GApplication *application)
550
{
551
	G_APPLICATION_CLASS (fr_application_parent_class)->startup (application);
552
553
	fr_application_register_archive_manager_service (FR_APPLICATION (application));
554
	initialize_data ();
555
	initialize_app_menu (application);
556
}
557
558
559
static GOptionContext *
560
fr_application_create_option_context (void)
561
{
562
	GOptionContext *context;
563
	static gsize    initialized = FALSE;
564
565
	context = g_option_context_new (N_("- Create and modify an archive"));
566
	g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
567
	g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
568
	g_option_context_set_ignore_unknown_options (context, TRUE);
569
570
	if (g_once_init_enter (&initialized)) {
571
		g_option_context_add_group (context, gtk_get_option_group (TRUE));
572
#ifdef USE_SMCLIENT
573
		g_option_context_add_group (context, egg_sm_client_get_option_group ());
574
#endif
575
		g_once_init_leave (&initialized, TRUE);
576
	}
577
578
	return context;
579
}
580
581
582
static int
583
fr_application_command_line_finished (GApplication *application,
584
				      int           status)
585
{
586
	if (status == EXIT_SUCCESS)
587
		gdk_notify_startup_complete ();
588
589
	/* reset arguments */
590
591
	remaining_args = NULL;
592
	arg_add_to = NULL;
593
	arg_add = FALSE;
594
	arg_extract_to = NULL;
595
	arg_extract = FALSE;
596
	arg_extract_here = FALSE;
597
	arg_default_dir = NULL;
598
	arg_version = FALSE;
599
600
	return status;
601
}
602
603
604
static int
605
fr_application_command_line (GApplication            *application,
606
                             GApplicationCommandLine *command_line)
607
{
608
	char           **argv;
609
	int              argc;
610
	GOptionContext  *context;
611
	GError          *error = NULL;
612
	GFile           *extraction_destination = NULL;
613
	GFile           *add_to_archive = NULL;
614
	GFile           *default_directory = NULL;
615
616
	argv = g_application_command_line_get_arguments (command_line, &argc);
617
618
	/* parse command line options */
619
620
	context = fr_application_create_option_context ();
621
	if (! g_option_context_parse (context, &argc, &argv, &error)) {
622
		g_critical ("Failed to parse arguments: %s", error->message);
623
		g_error_free (error);
624
		g_option_context_free (context);
625
626
		return fr_application_command_line_finished (application, EXIT_FAILURE);
627
	}
628
	g_option_context_free (context);
629
630
	/* restore the session */
631
632
#ifdef USE_SMCLIENT
633
	{
634
		EggSMClient *client;
635
636
		client = egg_sm_client_get ();
637
		g_signal_connect (client,
638
				  "save_state",
639
				  G_CALLBACK (client_save_state),
640
				  NULL);
641
		g_signal_connect (client,
642
				  "quit",
643
				  G_CALLBACK (client_quit_cb),
644
				  NULL);
645
		if (egg_sm_client_is_resumed (client)) {
646
			fr_restore_session (client);
647
			return fr_application_command_line_finished (application, EXIT_SUCCESS);
648
		}
649
	}
650
#endif
651
652
	if (remaining_args == NULL) { /* No archive specified. */
653
		if (! arg_service)
654
			gtk_widget_show (fr_window_new ());
655
		return fr_application_command_line_finished (application, EXIT_SUCCESS);
656
	}
657
658
	if (arg_extract_to != NULL)
1.7.6 by Jeremy Bicha
Import upstream version 3.9.90
659
		extraction_destination = g_application_command_line_create_file_for_arg (command_line, arg_extract_to);
1.8.1 by Andreas Henriksson
Import upstream version 3.7.92
660
661
	if (arg_add_to != NULL)
1.7.6 by Jeremy Bicha
Import upstream version 3.9.90
662
		add_to_archive = g_application_command_line_create_file_for_arg (command_line, arg_add_to);
1.8.1 by Andreas Henriksson
Import upstream version 3.7.92
663
664
	if (arg_default_dir != NULL)
1.7.6 by Jeremy Bicha
Import upstream version 3.9.90
665
		default_directory = g_application_command_line_create_file_for_arg (command_line, arg_default_dir);
1.8.1 by Andreas Henriksson
Import upstream version 3.7.92
666
667
	if ((arg_add_to != NULL) || (arg_add == 1)) { /* Add files to an archive */
668
		GtkWidget   *window;
669
		GList       *file_list;
670
		const char  *filename;
671
		int          i = 0;
672
673
		window = fr_window_new ();
674
675
		if (default_directory != NULL)
676
			fr_window_set_default_dir (FR_WINDOW (window), default_directory, TRUE);
677
678
		file_list = NULL;
679
		while ((filename = remaining_args[i++]) != NULL)
1.7.6 by Jeremy Bicha
Import upstream version 3.9.90
680
			file_list = g_list_prepend (file_list, g_application_command_line_create_file_for_arg (command_line, filename));
1.8.1 by Andreas Henriksson
Import upstream version 3.7.92
681
		file_list = g_list_reverse (file_list);
682
683
		fr_window_new_batch (FR_WINDOW (window), _("Compress"));
684
		fr_window_set_batch__add (FR_WINDOW (window), add_to_archive, file_list);
685
686
		if (! arg_notify)
687
			fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
688
		else
689
			fr_window_set_notify (FR_WINDOW (window), TRUE);
690
		fr_window_start_batch (FR_WINDOW (window));
691
692
		_g_object_list_unref (file_list);
693
	}
694
	else if ((arg_extract_to != NULL) || (arg_extract == 1) || (arg_extract_here == 1)) {
695
696
		/* Extract all archives. */
697
698
		GtkWidget  *window;
699
		const char *archive;
700
		int         i = 0;
701
702
		window = fr_window_new ();
703
704
		if (default_directory != NULL)
705
			fr_window_set_default_dir (FR_WINDOW (window), default_directory, TRUE);
706
707
		fr_window_new_batch (FR_WINDOW (window), _("Extract archive"));
708
		while ((archive = remaining_args[i++]) != NULL) {
709
			GFile *file;
710
1.7.6 by Jeremy Bicha
Import upstream version 3.9.90
711
			file = g_application_command_line_create_file_for_arg (command_line, archive);
1.8.1 by Andreas Henriksson
Import upstream version 3.7.92
712
			if (arg_extract_here == 1)
713
				fr_window_set_batch__extract_here (FR_WINDOW (window), file);
714
			else
715
				fr_window_set_batch__extract (FR_WINDOW (window), file, extraction_destination);
716
717
			g_object_unref (file);
718
		}
719
		if (! arg_notify)
720
			fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
721
		else
722
			fr_window_set_notify (FR_WINDOW (window), TRUE);
723
724
		fr_window_start_batch (FR_WINDOW (window));
725
	}
726
	else { /* Open each archive in a window */
727
		const char *filename = NULL;
728
729
		int i = 0;
730
		while ((filename = remaining_args[i++]) != NULL) {
731
			GtkWidget *window;
732
			GFile     *file;
733
734
			window = fr_window_new ();
735
			gtk_widget_show (window);
736
1.7.6 by Jeremy Bicha
Import upstream version 3.9.90
737
			file = g_application_command_line_create_file_for_arg (command_line, filename);
1.8.1 by Andreas Henriksson
Import upstream version 3.7.92
738
			fr_window_archive_open (FR_WINDOW (window), file, GTK_WINDOW (window));
739
740
			g_object_unref (file);
741
		}
742
	}
743
744
	_g_object_unref (default_directory);
745
	_g_object_unref (add_to_archive);
746
	_g_object_unref (extraction_destination);
747
748
	return fr_application_command_line_finished (application, EXIT_SUCCESS);
749
}
750
751
752
static gboolean
753
fr_application_local_command_line (GApplication   *application,
754
                                   char         ***arguments,
755
                                   int            *exit_status)
756
{
757
        char           **local_argv;
758
        int              local_argc;
759
        GOptionContext  *context;
760
        GError          *error = NULL;
761
        gboolean         handled_locally = FALSE;
762
763
        local_argv = g_strdupv (*arguments);
764
        local_argc = g_strv_length (local_argv);
765
766
        program_argv0 = local_argv[0];
767
        *exit_status = 0;
768
769
        context = fr_application_create_option_context ();
770
        g_option_context_set_ignore_unknown_options (context, TRUE);
771
	if (! g_option_context_parse (context, &local_argc, &local_argv, &error)) {
772
		*exit_status = EXIT_FAILURE;
773
		g_critical ("Failed to parse arguments: %s", error->message);
774
                g_clear_error (&error);
775
                handled_locally = TRUE;
776
	}
777
778
	if (arg_version) {
779
		g_printf ("%s %s, Copyright © 2001-2012 Free Software Foundation, Inc.\n", PACKAGE_NAME, PACKAGE_VERSION);
780
		handled_locally = TRUE;
781
	}
782
783
	g_option_context_free (context);
784
        g_strfreev (local_argv);
785
786
        return handled_locally;
787
}
788
789
790
static void
791
fr_application_activate (GApplication *application)
792
{
793
	GList *link;
794
795
	for (link = gtk_application_get_windows (GTK_APPLICATION (application));
796
	     link != NULL;
797
	     link = link->next)
798
	{
799
		if (! fr_window_is_batch_mode (FR_WINDOW (link->data)))
800
			gtk_widget_show (GTK_WIDGET (link->data));
801
	}
802
803
	gdk_notify_startup_complete ();
804
}
805
806
807
static void
808
fr_application_class_init (FrApplicationClass *klass)
809
{
810
	GObjectClass      *object_class;
811
	GApplicationClass *application_class;
812
813
	g_type_class_add_private (klass, sizeof (FrApplicationPrivate));
814
815
	object_class = G_OBJECT_CLASS (klass);
816
	object_class->finalize = fr_application_finalize;
817
818
	application_class = G_APPLICATION_CLASS (klass);
819
	application_class->startup = fr_application_startup;
820
	application_class->command_line = fr_application_command_line;
821
	application_class->local_command_line = fr_application_local_command_line;
822
	application_class->activate = fr_application_activate;
823
}
824
825
826
static void
827
fr_application_init (FrApplication *self)
828
{
829
#ifdef GDK_WINDOWING_X11
830
	egg_set_desktop_file (APPLICATIONS_DIR "/file-roller.desktop");
831
#else
832
	/* manually set name and icon */
833
	g_set_application_name (_("File Roller"));
834
	gtk_window_set_default_icon_name ("file-roller");
835
#endif
836
837
#ifdef ENABLE_NOTIFICATION
838
	if (! notify_init (g_get_application_name ()))
839
                g_warning ("Cannot initialize notification system.");
840
#endif /* ENABLE_NOTIFICATION */
841
842
	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, FR_TYPE_APPLICATION, FrApplicationPrivate);
843
	self->priv->owner_id = 0;
844
	self->priv->introspection_data = NULL;
845
	self->priv->listing_settings = g_settings_new (FILE_ROLLER_SCHEMA_LISTING);
846
	self->priv->ui_settings = g_settings_new (FILE_ROLLER_SCHEMA_UI);
847
}
848
849
850
GtkApplication *
851
fr_application_new (void)
852
{
853
        return g_object_new (fr_application_get_type (),
854
                             "application-id", "org.gnome.FileRoller",
855
                             "flags", G_APPLICATION_FLAGS_NONE,
856
                             NULL);
857
}
858
859
860
GSettings *
861
fr_application_get_settings (FrApplication *app,
862
			     const char    *schema)
863
{
864
	if (strcmp (schema, FILE_ROLLER_SCHEMA_LISTING) == 0)
865
		return app->priv->listing_settings;
866
	else if (strcmp (schema, FILE_ROLLER_SCHEMA_UI) == 0)
867
		return app->priv->ui_settings;
868
	else
869
		return NULL;
870
}