[file-roller] use file-roller as service as well, renamed the interface as org.gnome.ArchiveManager1
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [file-roller] use file-roller as service as well, renamed the interface as org.gnome.ArchiveManager1
- Date: Tue, 19 Jun 2012 18:42:13 +0000 (UTC)
commit d02e500fc20450234d53d11d9f078e40d82d31aa
Author: Paolo Bacchilega <paobac src gnome org>
Date: Tue Jun 19 19:21:17 2012 +0200
use file-roller as service as well, renamed the interface as org.gnome.ArchiveManager1
Removed file-roller-server as separate executable that implements the D-Bus
interface, added a --service option to file-roller to act as a service. Renamed
the D-Bus interface as org.gnome.ArchiveManager1. Moved the interface
description in an external file and save it in memory with GResource.
data/Makefile.am | 3 +-
data/org.gnome.ArchiveManager1.xml | 102 +++++++
data/org.gnome.FileRoller.service.in | 4 +-
po/POTFILES.in | 1 -
src/Makefile.am | 8 -
src/file-roller.gresource.xml | 3 +-
src/main.c | 322 +++++++++++++++++++++--
src/server.c | 481 ----------------------------------
src/test-server.c | 10 +-
9 files changed, 421 insertions(+), 513 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 9ac225a..04a1117 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -13,7 +13,7 @@ servicedir = $(datadir)/dbus-1/services
service_in_files = org.gnome.FileRoller.service.in
service_DATA = $(service_in_files:.service.in=.service)
$(service_DATA): $(service_in_files) Makefile
- $(AM_V_GEN) $(SED) -e "s|\ libexecdir\@|$(libexecdir)|" $< > $@
+ $(AM_V_GEN) $(SED) -e "s|\ bindir\@|$(bindir)|" $< > $@
gsettingsschema_in_files = org.gnome.FileRoller.gschema.xml.in
gsettings_SCHEMAS = $(gsettingsschema_in_files:.xml.in=.xml)
@@ -41,6 +41,7 @@ update-cache:
EXTRA_DIST = \
file-roller.convert \
+ org.gnome.ArchiveManager1.xml \
packages.match.in \
packages.match \
$(desktop_in_in_files) \
diff --git a/data/org.gnome.ArchiveManager1.xml b/data/org.gnome.ArchiveManager1.xml
new file mode 100644
index 0000000..bccf43b
--- /dev/null
+++ b/data/org.gnome.ArchiveManager1.xml
@@ -0,0 +1,102 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <!-- org.gnome.ArchiveManager1:
+ @short_description: Create and extract compressed archives
+
+ This D-Bus interface is used to create and extract compressed archives.
+ -->
+ <interface name="org.gnome.ArchiveManager1">
+
+ <!--
+ GetSupportedTypes:
+ @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.
+ @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.
+
+ Returns the supported archive types for a specific action.
+ -->
+ <method name="GetSupportedTypes">
+ <arg name="action" type="s" direction="in"/>
+ <arg name="types" type="aa{ss}" direction="out"/>
+ </method>
+
+ <!--
+ AddToArchive:
+ @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.
+
+ Adds the specified files to an archive. If the archive already
+ exists the archive is updated.
+ -->
+ <method name="AddToArchive">
+ <arg name="archive" type="s" direction="in"/>
+ <arg name="files" type="as" direction="in"/>
+ <arg name="use_progress_dialog" type="b" direction="in"/>
+ </method>
+
+ <!--
+ Compress:
+ @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.
+
+ 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.
+ -->
+ <method name="Compress">
+ <arg name="files" type="as" direction="in"/>
+ <arg name="destination" type="s" direction="in"/>
+ <arg name="use_progress_dialog" type="b" direction="in"/>
+ </method>
+
+ <!--
+ Extract:
+ @archive: The archive to extract.
+ @destination: The location where to extract the archive.
+ @use_progress_dialog: Whether to show the progress dialog.
+
+ Extract an archive in a specified location.
+ -->
+ <method name="Extract">
+ <arg name="archive" type="s" direction="in"/>
+ <arg name="destination" type="s" direction="in"/>
+ <arg name="use_progress_dialog" type="b" direction="in"/>
+ </method>
+
+ <!--
+ ExtractHere:
+ @archive: The archive to extract.
+ @use_progress_dialog: Whether to show the progress dialog.
+
+ Extract an archive in the archive's folder.
+ -->
+ <method name="ExtractHere">
+ <arg name="archive" type="s" direction="in"/>
+ <arg name="use_progress_dialog" type="b" direction="in"/>
+ </method>
+
+ <!--
+ Progress:
+ @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.
+ -->
+ <signal name="Progress">
+ <arg name="fraction" type="d"/>
+ <arg name="details" type="s"/>
+ </signal>
+
+ </interface>
+</node>
diff --git a/data/org.gnome.FileRoller.service.in b/data/org.gnome.FileRoller.service.in
index b68b646..f36fc0e 100644
--- a/data/org.gnome.FileRoller.service.in
+++ b/data/org.gnome.FileRoller.service.in
@@ -1,3 +1,3 @@
[D-BUS Service]
-Name=org.gnome.FileRoller
-Exec= libexecdir@/file-roller-server
+Name=org.gnome.ArchiveManager1
+Exec= bindir@/file-roller --service
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0957459..f5b64bf 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -119,7 +119,6 @@ src/preferences.c
src/preferences.h
src/rar-utils.c
src/rar-utils.h
-src/server.c
src/test-server.c
src/typedefs.h
[type: gettext/glade]src/ui/add-options.ui
diff --git a/src/Makefile.am b/src/Makefile.am
index e48b433..f5ff984 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,7 +1,6 @@
SUBDIRS = commands sh ui
bin_PROGRAMS = file-roller
-libexec_PROGRAMS = file-roller-server
noinst_PROGRAMS = test-server
if MKDTEMP_MISSING
@@ -207,13 +206,6 @@ if ENABLE_MAGIC
file_roller_LDADD += $(MAGIC_LIBS)
endif
-file_roller_server_SOURCES = \
- $(COMMON_SOURCES) \
- server.c
-
-file_roller_server_LDADD = \
- $(file_roller_LDADD)
-
test_server_SOURCES = test-server.c
test_server_FLAGS = $(FR_CFLAGS)
test_server_LDADD = $(FR_LIBS)
diff --git a/src/file-roller.gresource.xml b/src/file-roller.gresource.xml
index a0f771a..3bfeecb 100644
--- a/src/file-roller.gresource.xml
+++ b/src/file-roller.gresource.xml
@@ -11,5 +11,6 @@
<file compressed="true">ui/password.ui</file>
<file compressed="true">ui/properties.ui</file>
<file compressed="true">ui/update.ui</file>
+ <file compressed="true">../data/org.gnome.ArchiveManager1.xml</file>
</gresource>
-</gresources>
\ No newline at end of file
+</gresources>
diff --git a/src/main.c b/src/main.c
index 0f08f26..2735c4a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -36,23 +36,26 @@
# include "eggsmclient.h"
#endif
#include "eggdesktopfile.h"
+#include "file-utils.h"
#include "fr-init.h"
#include "gtk-utils.h"
-gint ForceDirectoryCreation;
+#define ORG_GNOME_ARCHIVEMANAGER_XML "/org/gnome/FileRoller/../data/org.gnome.ArchiveManager1.xml"
-static char **remaining_args;
-static char *arg_add_to = NULL;
-static int arg_add = FALSE;
-static char *arg_extract_to = NULL;
-static int arg_extract = FALSE;
-static int arg_extract_here = FALSE;
-static char *arg_default_url = NULL;
-static gboolean arg_version = FALSE;
-/* argv[0] from main(); used as the command to restart the program */
-static const char *program_argv0 = NULL;
+gint ForceDirectoryCreation;
+static char **remaining_args;
+static char *arg_add_to = NULL;
+static int arg_add = FALSE;
+static char *arg_extract_to = NULL;
+static int arg_extract = FALSE;
+static int arg_extract_here = FALSE;
+static char *arg_default_url = NULL;
+static gboolean arg_version = FALSE;
+static gboolean arg_service = FALSE;
+static const char *program_argv0 = NULL; /* argv[0] from main(); used as the command to restart the program */
+
static const GOptionEntry options[] = {
{ "add-to", 'a', 0, G_OPTION_ARG_STRING, &arg_add_to,
@@ -83,6 +86,9 @@ static const GOptionEntry options[] = {
N_("Create destination folder without asking confirmation"),
NULL },
+ { "service", 'v', 0, G_OPTION_ARG_NONE, &arg_service,
+ N_("Start as a service"), NULL },
+
{ "version", 'v', 0, G_OPTION_ARG_NONE, &arg_version,
N_("Show version"), NULL },
@@ -159,6 +165,9 @@ initialize_app_menu (GApplication *application)
}
+/* -- session management -- */
+
+
#ifdef USE_SMCLIENT
@@ -248,27 +257,303 @@ fr_restore_session (EggSMClient *client)
#endif /* USE_SMCLIENT */
+/* -- service -- */
+
+
+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,
+ "org/gnome/ArchiveManager1",
+ "org.gnome.ArchiveManager1",
+ "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,
+ "Invalid action '%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);
+ }
+ 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);
+ }
+ 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);
+ }
+ 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);
+ }
+}
+
+
+static const GDBusInterfaceVTable interface_vtable = {
+ handle_method_call,
+ NULL, /* handle_get_property */
+ NULL /* handle_set_property */
+};
+
+
/* -- main application -- */
-typedef GtkApplication FrApplication;
+typedef struct {
+ GtkApplication __parent;
+ GDBusNodeInfo *introspection_data;
+ guint owner_id;
+} FrApplication;
+
typedef GtkApplicationClass FrApplicationClass;
static gpointer fr_application_parent_class;
G_DEFINE_TYPE (FrApplication, fr_application, GTK_TYPE_APPLICATION)
+#define FR_APPLICATION(x) ((FrApplication *)(x))
static void
fr_application_finalize (GObject *object)
{
+ FrApplication *self = FR_APPLICATION (object);
+
+ if (self->introspection_data != NULL)
+ g_dbus_node_info_unref (self->introspection_data);
+ if (self->owner_id != 0)
+ g_bus_unown_name (self->owner_id);
+
G_OBJECT_CLASS (fr_application_parent_class)->finalize (object);
}
static void
-fr_application_init (FrApplication *app)
+on_bus_acquired_for_archive_manager (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
+{
+ FrApplication *self = user_data;
+ guint registration_id;
+ GError *error = NULL;
+
+ registration_id = g_dbus_connection_register_object (connection,
+ "/org/gnome/ArchiveManager1",
+ self->introspection_data->interfaces[0],
+ &interface_vtable,
+ NULL,
+ NULL, /* user_data_free_func */
+ &error); /* GError** */
+ if (registration_id == 0) {
+ g_error ("%s", error->message);
+ g_clear_error (&error);
+ }
+}
+
+
+static void
+fr_application_register_archive_manager_service (FrApplication *self)
+{
+ gsize size;
+ guchar *buffer;
+ GInputStream *stream;
+
+ g_resources_get_info (ORG_GNOME_ARCHIVEMANAGER_XML, 0, &size, NULL, NULL);
+ buffer = g_new (guchar, size);
+ stream = g_resources_open_stream (ORG_GNOME_ARCHIVEMANAGER_XML, 0, NULL);
+ g_input_stream_read_all (stream, buffer, size, NULL, NULL, NULL);
+
+ self->introspection_data = g_dbus_node_info_new_for_xml ((gchar *) buffer, NULL);
+ self->owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
+ "org.gnome.ArchiveManager1",
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus_acquired_for_archive_manager,
+ NULL /*on_name_acquired*/,
+ NULL /*on_name_lost*/,
+ self,
+ NULL);
+
+ g_free (buffer);
+}
+
+
+static void
+fr_application_init (FrApplication *self)
{
#ifdef GDK_WINDOWING_X11
egg_set_desktop_file (APPLICATIONS_DIR "/file-roller.desktop");
@@ -277,6 +562,9 @@ fr_application_init (FrApplication *app)
g_set_application_name (_("File Roller"));
gtk_window_set_default_icon_name ("file-roller");
#endif
+
+ self->owner_id = 0;
+ self->introspection_data = NULL;
}
@@ -285,6 +573,7 @@ fr_application_startup (GApplication *application)
{
G_APPLICATION_CLASS (fr_application_parent_class)->startup (application);
+ fr_application_register_archive_manager_service (FR_APPLICATION (application));
initialize_data ();
initialize_app_menu (application);
}
@@ -397,7 +686,8 @@ fr_application_command_line (GApplication *application,
#endif
if (remaining_args == NULL) { /* No archive specified. */
- gtk_widget_show (fr_window_new ());
+ if (! arg_service)
+ gtk_widget_show (fr_window_new ());
return fr_application_command_line_finished (application, EXIT_SUCCESS);
}
@@ -566,8 +856,8 @@ static GtkApplication *
fr_application_new (void)
{
return g_object_new (fr_application_get_type (),
- "application-id", "org.gnome.file-roller",
- "flags", G_APPLICATION_FLAGS_NONE,
+ "application-id", "org.gnome.FileRoller",
+ "flags", G_APPLICATION_IS_SERVICE,
NULL);
}
diff --git a/src/test-server.c b/src/test-server.c
index 726844b..b0fc4db 100644
--- a/src/test-server.c
+++ b/src/test-server.c
@@ -148,9 +148,9 @@ main (int argc, char *argv[])
proxy = g_dbus_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE,
NULL,
- "org.gnome.FileRoller",
- "/org/gnome/FileRoller",
- "org.gnome.ArchiveManager",
+ "org.gnome.ArchiveManager1",
+ "/org/gnome/ArchiveManager1",
+ "org.gnome.ArchiveManager1",
NULL,
&error);
@@ -266,6 +266,10 @@ main (int argc, char *argv[])
#endif
}
+ else {
+ g_error ("%s\n", error->message);
+ g_clear_error (&error);
+ }
}
loop = g_main_loop_new (NULL, FALSE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]