/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Engrampa * * Copyright (C) 2010 Free Software Foundation, Inc. * * 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, see . */ #include #include #include #include #include #include "file-utils.h" #include "fr-init.h" #define FR_SERVICE_NAME "org.mate.Engrampa" #define FR_SERVICE_PATH "/org/mate/Engrampa" static const char introspection_xml[] = "" " " /** * GetSupportedTypes: * * Returns the supported archive types for a specific action. * * Input arguments: * * @action: * Can be one of the following values: * *) create: create an archive that can contain many files. * *) create_single_file: create an archive that can contain a single file. * *) extract: extract the content of an archive. * * Output arguments: * * @types: * The supported archive types described as an array of hash tables, * where each hash table has the following keys: * *) mime-type: the mime type relative to the archive type. * *) default-extension: the extension to use for newly created archives. * *) description: a human readable description of the archive type. */ " " " " " " " " /** * AddToArchive: * * Adds the specified files to an archive. If the archive already * exists the archive is updated. * * Input arguments: * * @archive: * The archive URI. * @files: * The files to add to the archive, as an array of URIs. * @use_progress_dialog: * Whether to show the progress dialog. */ " " " " " " " " " " /** * Compress: * * Compresses a series of files in an archive. The user is asked to * enter an archive name, archive type and other options. In this case * it's used the same dialog used by the "Compress..." command from the * Nautilus context menu. * If the user chooses an existing archive, the archive is updated. * * Input arguments: * * @files: * The files to add to the archive, as an array of URIs. * @destination: * An optional destination, if not specified the folder of the first * file in @files is used. * @use_progress_dialog: * Whether to show the progress dialog. */ " " " " " " " " " " /** * Extract: * * Extract an archive in a specified location. * * Input arguments: * * @archive: * The archive to extract. * @destination: * The location where to extract the archive. * @use_progress_dialog: * Whether to show the progress dialog. */ " " " " " " " " " " /** * ExtractHere: * * Extract an archive in a specified location. * * Input arguments: * * @archive: * The archive to extract. * @use_progress_dialog: * Whether to show the progress dialog. */ " " " " " " " " /** * Progress (signal) * * Arguments: * * @fraction: * number from 0.0 to 100.0 that indicates the percentage of * completion of the operation. * @details: * text message that describes the current operation. */ " " " " " " " " " " ""; static GDBusNodeInfo *introspection_data = NULL; static void window_ready_cb (GtkWidget *widget, GError *error, gpointer user_data) { if (error == NULL) g_dbus_method_invocation_return_value ((GDBusMethodInvocation *) user_data, NULL); else g_dbus_method_invocation_return_error ((GDBusMethodInvocation *) user_data, error->domain, error->code, "%s", error->message); } static gboolean window_progress_cb (FrWindow *window, double fraction, char *details, gpointer user_data) { GDBusConnection *connection = user_data; g_dbus_connection_emit_signal (connection, NULL, FR_SERVICE_PATH, "org.mate.ArchiveManager", "Progress", g_variant_new ("(ds)", fraction, details), NULL); return TRUE; } static void handle_method_call (GDBusConnection *connection, const char *sender, const char *object_path, const char *interface_name, const char *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { update_registered_commands_capabilities (); if (g_strcmp0 (method_name, "GetSupportedTypes") == 0) { char *action; int *supported_types = NULL; g_variant_get (parameters, "(s)", &action); if (g_strcmp0 (action, "create") == 0) { supported_types = save_type; } else if (g_strcmp0 (action, "create_single_file") == 0) { supported_types = single_file_save_type; } else if (g_strcmp0 (action, "extract") == 0) { supported_types = open_type; } if (supported_types == NULL) { g_dbus_method_invocation_return_error (invocation, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, "Action not valid %s, valid values are: create, create_single_file, extract", action); } else { GVariantBuilder builder; int i; g_variant_builder_init (&builder, G_VARIANT_TYPE ("(aa{ss})")); g_variant_builder_open (&builder, G_VARIANT_TYPE ("aa{ss}")); for (i = 0; supported_types[i] != -1; i++) { g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{ss}")); g_variant_builder_add (&builder, "{ss}", "mime-type", mime_type_desc[supported_types[i]].mime_type); g_variant_builder_add (&builder, "{ss}", "default-extension", mime_type_desc[supported_types[i]].default_ext); g_variant_builder_add (&builder, "{ss}", "description", _(mime_type_desc[supported_types[i]].name)); g_variant_builder_close (&builder); } g_variant_builder_close (&builder); g_dbus_method_invocation_return_value (invocation, g_variant_builder_end (&builder)); } g_free (action); } else if (g_strcmp0 (method_name, "AddToArchive") == 0) { char *archive; char **files; gboolean use_progress_dialog; int i; GList *file_list = NULL; GtkWidget *window; g_variant_get (parameters, "(s^asb)", &archive, &files, &use_progress_dialog); for (i = 0; files[i] != NULL; i++) file_list = g_list_prepend (file_list, files[i]); file_list = g_list_reverse (file_list); window = fr_window_new (); fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog); g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection); g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation); fr_window_new_batch (FR_WINDOW (window), _("Compress")); fr_window_set_batch__add (FR_WINDOW (window), archive, file_list); fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL); fr_window_start_batch (FR_WINDOW (window)); g_free (archive); gtk_main (); } else if (g_strcmp0 (method_name, "Compress") == 0) { char **files; char *destination; gboolean use_progress_dialog; int i; GList *file_list = NULL; GtkWidget *window; g_variant_get (parameters, "(^assb)", &files, &destination, &use_progress_dialog); for (i = 0; files[i] != NULL; i++) file_list = g_list_prepend (file_list, files[i]); file_list = g_list_reverse (file_list); if ((destination == NULL) || (strcmp (destination, "") == 0)) destination = remove_level_from_path (file_list->data); window = fr_window_new (); fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog); fr_window_set_default_dir (FR_WINDOW (window), destination, TRUE); g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection); g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation); fr_window_new_batch (FR_WINDOW (window), _("Extract archive")); fr_window_set_batch__add (FR_WINDOW (window), NULL, file_list); fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL); fr_window_start_batch (FR_WINDOW (window)); g_free (destination); gtk_main (); } else if (g_strcmp0 (method_name, "Extract") == 0) { char *archive; char *destination; gboolean use_progress_dialog; GtkWidget *window; g_variant_get (parameters, "(ssb)", &archive, &destination, &use_progress_dialog); window = fr_window_new (); fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog); if ((destination != NULL) && (strcmp (destination, "") != 0)) fr_window_set_default_dir (FR_WINDOW (window), destination, TRUE); g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection); g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation); fr_window_new_batch (FR_WINDOW (window), _("Extract archive")); fr_window_set_batch__extract (FR_WINDOW (window), archive, destination); fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL); fr_window_start_batch (FR_WINDOW (window)); g_free (destination); g_free (archive); gtk_main (); } else if (g_strcmp0 (method_name, "ExtractHere") == 0) { char *archive; gboolean use_progress_dialog; GtkWidget *window; g_variant_get (parameters, "(sb)", &archive, &use_progress_dialog); window = fr_window_new (); fr_window_use_progress_dialog (FR_WINDOW (window), use_progress_dialog); g_signal_connect (window, "progress", G_CALLBACK (window_progress_cb), connection); g_signal_connect (window, "ready", G_CALLBACK (window_ready_cb), invocation); fr_window_new_batch (FR_WINDOW (window), _("Extract archive")); fr_window_set_batch__extract_here (FR_WINDOW (window), archive); fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL); fr_window_start_batch (FR_WINDOW (window)); g_free (archive); gtk_main (); } } static const GDBusInterfaceVTable interface_vtable = { handle_method_call, NULL, /* handle_get_property */ NULL /* handle_set_property */ }; static void on_bus_acquired (GDBusConnection *connection, const char *name, gpointer user_data) { guint registration_id; registration_id = g_dbus_connection_register_object (connection, FR_SERVICE_PATH, introspection_data->interfaces[0], &interface_vtable, NULL, NULL, /* user_data_free_func */ NULL); /* GError** */ g_assert (registration_id > 0); initialize_data (); } static void on_name_acquired (GDBusConnection *connection, const char *name, gpointer user_data) { } static void on_name_lost (GDBusConnection *connection, const char *name, gpointer user_data) { gtk_main_quit (); } int main (int argc, char *argv[]) { GOptionContext *context = NULL; GError *error = NULL; guint owner_id; bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); context = g_option_context_new (N_("- Create and modify an archive")); g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); g_option_context_add_group (context, gtk_get_option_group (TRUE)); if (! g_option_context_parse (context, &argc, &argv, &error)) { g_critical ("Failed to parse arguments: %s", error->message); g_error_free (error); g_option_context_free (context); return EXIT_FAILURE; } g_option_context_free (context); g_set_application_name (_("Engrampa")); gtk_window_set_default_icon_name ("engrampa"); gtk_icon_theme_append_search_path (gtk_icon_theme_get_default (), PKG_DATA_DIR G_DIR_SEPARATOR_S "icons"); introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); g_assert (introspection_data != NULL); owner_id = g_bus_own_name (G_BUS_TYPE_SESSION, FR_SERVICE_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, on_name_acquired, on_name_lost, NULL, NULL); gtk_main (); g_bus_unown_name (owner_id); g_dbus_node_info_unref (introspection_data); return 0; }