1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
6
* Copyright (C) 2010 Free Software Foundation, Inc.
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.
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.
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/>.
24
#include <glib/gi18n.h>
27
#include "file-utils.h"
31
#define FR_SERVICE_NAME "org.gnome.FileRoller"
32
#define FR_SERVICE_PATH "/org/gnome/FileRoller"
35
static const char introspection_xml[] =
37
" <interface name='org.gnome.ArchiveManager'>"
42
* Returns the supported archive types for a specific action.
47
* Can be one of the following values:
48
* *) create: create an archive that can contain many files.
49
* *) create_single_file: create an archive that can contain a single file.
50
* *) extract: extract the content of an archive.
55
* The supported archive types described as an array of hash tables,
56
* where each hash table has the following keys:
57
* *) mime-type: the mime type relative to the archive type.
58
* *) default-extension: the extension to use for newly created archives.
59
* *) description: a human readable description of the archive type.
62
" <method name='GetSupportedTypes'>"
63
" <arg name='action' type='s' direction='in'/>"
64
" <arg name='types' type='aa{ss}' direction='out'/>"
70
* Adds the specified files to an archive. If the archive already
71
* exists the archive is updated.
78
* The files to add to the archive, as an array of URIs.
79
* @use_progress_dialog:
80
* Whether to show the progress dialog.
83
" <method name='AddToArchive'>"
84
" <arg name='archive' type='s' direction='in'/>"
85
" <arg name='files' type='as' direction='in'/>"
86
" <arg name='use_progress_dialog' type='b' direction='in'/>"
92
* Compresses a series of files in an archive. The user is asked to
93
* enter an archive name, archive type and other options. In this case
94
* it's used the same dialog used by the "Compress..." command from the
95
* Nautilus context menu.
96
* If the user chooses an existing archive, the archive is updated.
101
* The files to add to the archive, as an array of URIs.
103
* An optional destination, if not specified the folder of the first
104
* file in @files is used.
105
* @use_progress_dialog:
106
* Whether to show the progress dialog.
109
" <method name='Compress'>"
110
" <arg name='files' type='as' direction='in'/>"
111
" <arg name='destination' type='s' direction='in'/>"
112
" <arg name='use_progress_dialog' type='b' direction='in'/>"
118
* Extract an archive in a specified location.
123
* The archive to extract.
125
* The location where to extract the archive.
126
* @use_progress_dialog:
127
* Whether to show the progress dialog.
130
" <method name='Extract'>"
131
" <arg name='archive' type='s' direction='in'/>"
132
" <arg name='destination' type='s' direction='in'/>"
133
" <arg name='use_progress_dialog' type='b' direction='in'/>"
139
* Extract an archive in a specified location.
144
* The archive to extract.
145
* @use_progress_dialog:
146
* Whether to show the progress dialog.
149
" <method name='ExtractHere'>"
150
" <arg name='archive' type='s' direction='in'/>"
151
" <arg name='use_progress_dialog' type='b' direction='in'/>"
160
* number from 0.0 to 100.0 that indicates the percentage of
161
* completion of the operation.
163
* text message that describes the current operation.
166
" <signal name='Progress'>"
167
" <arg name='fraction' type='d'/>"
168
" <arg name='details' type='s'/>"
174
static GDBusNodeInfo *introspection_data = NULL;
178
window_ready_cb (GtkWidget *widget,
183
g_dbus_method_invocation_return_value ((GDBusMethodInvocation *) user_data, NULL);
185
g_dbus_method_invocation_return_error ((GDBusMethodInvocation *) user_data,
194
window_progress_cb (FrWindow *window,
199
GDBusConnection *connection = user_data;
201
g_dbus_connection_emit_signal (connection,
204
"org.gnome.ArchiveManager",
206
g_variant_new ("(ds)",
216
handle_method_call (GDBusConnection *connection,
218
const char *object_path,
219
const char *interface_name,
220
const char *method_name,
221
GVariant *parameters,
222
GDBusMethodInvocation *invocation,
225
update_registered_commands_capabilities ();
227
if (g_strcmp0 (method_name, "GetSupportedTypes") == 0) {
229
int *supported_types = NULL;
231
g_variant_get (parameters, "(s)", &action);
233
if (g_strcmp0 (action, "create") == 0) {
234
supported_types = save_type;
236
else if (g_strcmp0 (action, "create_single_file") == 0) {
237
supported_types = single_file_save_type;
239
else if (g_strcmp0 (action, "extract") == 0) {
240
supported_types = open_type;
243
if (supported_types == NULL) {
244
g_dbus_method_invocation_return_error (invocation,
246
G_IO_ERROR_INVALID_ARGUMENT,
247
"Action not valid %s, valid values are: create, create_single_file, extract",
251
GVariantBuilder builder;
254
g_variant_builder_init (&builder, G_VARIANT_TYPE ("(aa{ss})"));
255
g_variant_builder_open (&builder, G_VARIANT_TYPE ("aa{ss}"));
256
for (i = 0; supported_types[i] != -1; i++) {
257
g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{ss}"));
258
g_variant_builder_add (&builder, "{ss}",
260
mime_type_desc[supported_types[i]].mime_type);
261
g_variant_builder_add (&builder, "{ss}",
263
mime_type_desc[supported_types[i]].default_ext);
264
g_variant_builder_add (&builder, "{ss}",
266
_(mime_type_desc[supported_types[i]].name));
267
g_variant_builder_close (&builder);
269
g_variant_builder_close (&builder);
271
g_dbus_method_invocation_return_value (invocation, g_variant_builder_end (&builder));
276
else if (g_strcmp0 (method_name, "AddToArchive") == 0) {
279
gboolean use_progress_dialog;
281
GList *file_list = NULL;
284
g_variant_get (parameters, "(s^asb)", &archive, &files, &use_progress_dialog);
286
for (i = 0; files[i] != NULL; i++)
287
file_list = g_list_prepend (file_list, files[i]);
288
file_list = g_list_reverse (file_list);
290
window = fr_window_new ();
291
fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
293
g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
294
g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
296
fr_window_new_batch (FR_WINDOW (window));
297
fr_window_set_batch__add (FR_WINDOW (window), archive, file_list);
298
fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
299
fr_window_start_batch (FR_WINDOW (window));
305
else if (g_strcmp0 (method_name, "Compress") == 0) {
308
gboolean use_progress_dialog;
310
GList *file_list = NULL;
313
g_variant_get (parameters, "(^assb)", &files, &destination, &use_progress_dialog);
315
for (i = 0; files[i] != NULL; i++)
316
file_list = g_list_prepend (file_list, files[i]);
317
file_list = g_list_reverse (file_list);
319
if ((destination == NULL) || (strcmp (destination, "") == 0))
320
destination = remove_level_from_path (file_list->data);
322
window = fr_window_new ();
323
fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
324
fr_window_set_default_dir (FR_WINDOW (window), destination, TRUE);
326
g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
327
g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
329
fr_window_new_batch (FR_WINDOW (window));
330
fr_window_set_batch__add (FR_WINDOW (window), NULL, 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));
334
g_free (destination);
338
else if (g_strcmp0 (method_name, "Extract") == 0) {
341
gboolean use_progress_dialog;
344
g_variant_get (parameters, "(ssb)", &archive, &destination, &use_progress_dialog);
346
window = fr_window_new ();
347
fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
348
if ((destination != NULL) & (strcmp (destination, "") != 0))
349
fr_window_set_default_dir (FR_WINDOW (window), destination, TRUE);
351
g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
352
g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
354
fr_window_new_batch (FR_WINDOW (window));
355
fr_window_set_batch__extract (FR_WINDOW (window), archive, destination);
356
fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
357
fr_window_start_batch (FR_WINDOW (window));
359
g_free (destination);
364
else if (g_strcmp0 (method_name, "ExtractHere") == 0) {
366
gboolean use_progress_dialog;
369
g_variant_get (parameters, "(sb)", &archive, &use_progress_dialog);
371
window = fr_window_new ();
372
fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog);
374
g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection);
375
g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation);
377
fr_window_new_batch (FR_WINDOW (window));
378
fr_window_set_batch__extract_here (FR_WINDOW (window), archive);
379
fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
380
fr_window_start_batch (FR_WINDOW (window));
389
static const GDBusInterfaceVTable interface_vtable = {
391
NULL, /* handle_get_property */
392
NULL /* handle_set_property */
397
on_bus_acquired (GDBusConnection *connection,
401
guint registration_id;
403
registration_id = g_dbus_connection_register_object (connection,
405
introspection_data->interfaces[0],
408
NULL, /* user_data_free_func */
409
NULL); /* GError** */
410
g_assert (registration_id > 0);
417
on_name_acquired (GDBusConnection *connection,
425
on_name_lost (GDBusConnection *connection,
434
main (int argc, char *argv[])
436
GOptionContext *context = NULL;
437
GError *error = NULL;
440
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
441
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
442
textdomain (GETTEXT_PACKAGE);
444
context = g_option_context_new (N_("- Create and modify an archive"));
445
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
446
g_option_context_add_group (context, gtk_get_option_group (TRUE));
448
if (! g_option_context_parse (context, &argc, &argv, &error)) {
449
g_critical ("Failed to parse arguments: %s", error->message);
450
g_error_free (error);
451
g_option_context_free (context);
455
g_option_context_free (context);
457
g_set_application_name (_("File Roller"));
458
gtk_window_set_default_icon_name ("file-roller");
460
gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (),
461
PKG_DATA_DIR G_DIR_SEPARATOR_S "icons");
463
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
464
g_assert (introspection_data != NULL);
466
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
468
G_BUS_NAME_OWNER_FLAGS_NONE,
477
g_bus_unown_name (owner_id);
478
g_dbus_node_info_unref (introspection_data);