[file-roller: 52/123] added a command line option to notify the archive creation



commit 51796b7c232a05c568fa7a0ed2dedf709273baba
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sat Jul 21 18:13:12 2012 +0200

    added a command line option to notify the archive creation
    
    When passing --notify as command line argument, after the creation of an
    archive, a dialog will be displayed to confirm the successful completion of
    the operation allowing the user to open the archive if he wants to.  If the
    progress dialog has lost the focus the notification will be shown using the
    desktop notification system (if compiled with libnotify).
    
    This option is used when creating archives from the Nautilus context menu
    command.

 configure.ac                   |   26 ++++++-
 nautilus/Makefile.am           |    3 +-
 nautilus/nautilus-fileroller.c |    4 +-
 src/Makefile.am                |   10 ++-
 src/fr-archive.c               |    7 +-
 src/fr-window.c                |  167 +++++++++++++++++++++++++++++++++++++---
 src/fr-window.h                |    2 +
 src/main.c                     |   33 +++++---
 8 files changed, 216 insertions(+), 36 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 030ccc8..b731a0c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -31,6 +31,7 @@ GIO_REQUIRED=2.25.5
 GTK_REQUIRED=3.4.0
 NAUTILUS_REQUIRED=2.22.2
 JSON_GLIB_REQUIRED=0.14.0
+LIBNOTIFY_REQUIRED=0.4.3
 
 AC_SUBST(GLIB_REQUIRED)
 AC_SUBST(GIO_REQUIRED)
@@ -161,7 +162,29 @@ if test "x$enable_packagekit" != "xno"; then
 	AC_DEFINE(ENABLE_PACKAGEKIT, 1, [define to enable PackageKit installer])
 fi
 
-dnl ******************************
+dnl ===========================================================================
+dnl
+dnl libnotify
+dnl
+AC_ARG_ENABLE(notification,[AC_HELP_STRING([--enable-notification],[enable operation completion notification [default=yes]])],, [enable_notification="yes"])
+AM_CONDITIONAL(ENABLE_NOTIFICATION, test "x$enable_notification" = xyes)
+
+LIBNOTIFY_LIBS=""
+LIBNOTIFY_CFLAGS=""
+if test x"$enable_notification" = xyes; then
+   AC_MSG_CHECKING(for notification support)
+
+   if pkg-config --atleast-version=$LIBNOTIFY_REQUIRED libnotify; then
+      LIBNOTIFY_LIBS=`pkg-config --libs libnotify`
+      LIBNOTIFY_CFLAGS=`pkg-config --cflags libnotify`
+      AC_DEFINE(ENABLE_NOTIFICATION, 1, [Have libnotify])
+   else
+      enable_notification=no
+   fi
+fi
+AC_MSG_RESULT($enable_notification)
+AC_SUBST(LIBNOTIFY_LIBS)
+AC_SUBST(LIBNOTIFY_CFLAGS)
 
 dnl ******************************
 
@@ -268,4 +291,5 @@ Configuration:
 	PackageKit support      : ${enable_packagekit}
 	Use libmagic            : ${enable_magic}
 	JSON support            : ${enable_json_glib}
+	Enable notification     : ${enable_notification}
 "
diff --git a/nautilus/Makefile.am b/nautilus/Makefile.am
index 72c09a6..ad0c23d 100644
--- a/nautilus/Makefile.am
+++ b/nautilus/Makefile.am
@@ -6,7 +6,8 @@ INCLUDES =						\
 	$(DISABLE_DEPRECATED)				\
 	$(NAUTILUS_CFLAGS)				\
 	$(FR_CFLAGS)					\
-	$(JSON_GLIB_CFLAGS)
+	$(JSON_GLIB_CFLAGS)				\
+	$(LIBNOTIFY_CFLAGS)
 
 nautilus_extensiondir=$(NAUTILUS_EXTENSION_DIR)
 
diff --git a/nautilus/nautilus-fileroller.c b/nautilus/nautilus-fileroller.c
index ef77e2a..2017600 100644
--- a/nautilus/nautilus-fileroller.c
+++ b/nautilus/nautilus-fileroller.c
@@ -121,7 +121,9 @@ add_callback (NautilusMenuItem *item,
 	dir = g_path_get_dirname (uri);
 
 	cmd = g_string_new ("file-roller");
-	g_string_append_printf (cmd," --default-dir=%s --add", g_shell_quote (dir));
+	g_string_append (cmd, " --notify");
+	g_string_append_printf (cmd," --default-dir=%s", g_shell_quote (dir));
+	g_string_append (cmd," --add");
 
 	g_free (dir);
 	g_free (uri);
diff --git a/src/Makefile.am b/src/Makefile.am
index d5ca098..d7dd438 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -41,7 +41,8 @@ INCLUDES =						\
 	-DAPPLICATIONS_DIR=\"$(applications_dir)\"	\
 	$(DISABLE_DEPRECATED)				\
 	$(FR_CFLAGS)					\
-	$(JSON_GLIB_CFLAGS)
+	$(JSON_GLIB_CFLAGS)				\
+	$(LIBNOTIFY_CFLAGS)
 
 BUILT_SOURCES =			\
 	fr-marshal.c		\
@@ -90,6 +91,8 @@ COMMON_SOURCES = 			\
 	fr-archive.h			\
 	fr-command.c			\
 	fr-command.h			\
+	fr-command-7z.c			\
+	fr-command-7z.h			\
 	fr-command-ace.c		\
 	fr-command-ace.h		\
 	fr-command-alz.c		\
@@ -124,8 +127,6 @@ COMMON_SOURCES = 			\
 	fr-command-lrzip.h		\
 	fr-command-zoo.c		\
 	fr-command-zoo.h		\
-	fr-command-7z.c			\
-	fr-command-7z.h			\
 	fr-error.c			\
 	fr-error.h			\
 	fr-init.c			\
@@ -206,7 +207,8 @@ file_roller_SOURCES = 			\
 file_roller_LDADD =					\
 	$(top_builddir)/copy-n-paste/libeggsmclient.la	\
 	$(FR_LIBS)					\
-	$(JSON_GLIB_LIBS)
+	$(JSON_GLIB_LIBS)				\
+	$(LIBNOTIFY_LIBS)
 
 if ENABLE_MAGIC
 file_roller_LDADD += $(MAGIC_LIBS)
diff --git a/src/fr-archive.c b/src/fr-archive.c
index b23785d..19f24f1 100644
--- a/src/fr-archive.c
+++ b/src/fr-archive.c
@@ -728,10 +728,9 @@ open_archive_stream_ready_cb (GObject      *source_object,
 			mime_type = get_mime_type_from_filename (open_data->file);
 			archive = create_archive_to_load_archive (open_data->file, mime_type);
 			if (archive == NULL) {
-				error = g_error_new (FR_ERROR,
-						     FR_ERROR_UNSUPPORTED_FORMAT,
-						     "%s",
-						     _("Archive type not supported."));
+				error = g_error_new_literal (FR_ERROR,
+						     	     FR_ERROR_UNSUPPORTED_FORMAT,
+						     	     _("Archive type not supported."));
 				load_data_complete_with_error (open_data, error);
 				return;
 			}
diff --git a/src/fr-window.c b/src/fr-window.c
index 14f9ede..8f4b903 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -29,7 +29,9 @@
 #include <gdk/gdk.h>
 #include <gdk/gdkkeysyms.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
-
+#ifdef ENABLE_NOTIFICATION
+#  include <libnotify/notify.h>
+#endif
 #include "actions.h"
 #include "dlg-batch-add.h"
 #include "dlg-delete.h"
@@ -292,6 +294,7 @@ struct _FrWindowPrivate {
 	gboolean         asked_for_password;
 	gboolean         ask_to_open_destination_after_extraction;
 	gboolean         destroy_with_error_dialog;
+	gboolean         quit_with_progress_dialog;
 
 	FrBatchAction    current_batch_action;
 
@@ -327,6 +330,7 @@ struct _FrWindowPrivate {
 
 	gboolean         stoppable;
 	gboolean         closing;
+	gboolean         notify;
 
 	FrClipboardData *clipboard_data;
 	FrClipboardData *copy_data;
@@ -2175,6 +2179,14 @@ location_entry_key_press_event_cb (GtkWidget   *widget,
 }
 
 
+static void
+_fr_window_close_after_notification (FrWindow *window)
+{
+	fr_window_set_current_batch_action (window, FR_BATCH_ACTION_QUIT, NULL, NULL);
+	fr_window_restart_current_batch_action (window);
+}
+
+
 static gboolean
 real_close_progress_dialog (gpointer data)
 {
@@ -2188,6 +2200,9 @@ real_close_progress_dialog (gpointer data)
 	if (window->priv->progress_dialog != NULL)
 		gtk_widget_hide (window->priv->progress_dialog);
 
+	if (window->priv->batch_mode && window->priv->quit_with_progress_dialog)
+		_fr_window_close_after_notification (window);
+
 	return FALSE;
 }
 
@@ -2247,7 +2262,10 @@ open_folder (GtkWindow  *parent,
 	if (folder == NULL)
 		return;
 
-	if (! gtk_show_uri (gtk_window_get_screen (parent), folder, GDK_CURRENT_TIME, &error)) {
+	if (! gtk_show_uri (parent != NULL ? gtk_window_get_screen (parent) : NULL,
+			    folder,
+			    GDK_CURRENT_TIME, &error))
+	{
 		GtkWidget *d;
 		char      *utf8_name;
 		char      *message;
@@ -2864,6 +2882,14 @@ fr_window_destroy_with_error_dialog (FrWindow *window)
 }
 
 
+void
+fr_window_set_notify (FrWindow   *window,
+		      gboolean    notify)
+{
+	window->priv->notify = notify;
+}
+
+
 static void
 _handle_archive_operation_error (FrWindow  *window,
 				 FrArchive *archive,
@@ -3056,11 +3082,6 @@ _archive_operation_completed (FrWindow *window,
 			fr_window_remove_from_recent_list (window, window->priv->archive_uri);
 			fr_window_archive_close (window);
 		}
-		else {
-			fr_window_add_to_recent_list (window, window->priv->archive_uri);
-			if (! window->priv->batch_mode)
-				gtk_window_present (GTK_WINDOW (window));
-		}
 		break;
 
 	case FR_ACTION_LISTING_CONTENT:
@@ -3124,13 +3145,17 @@ _archive_operation_completed (FrWindow *window,
 		g_free (window->priv->archive_uri);
 		window->priv->archive_uri = g_file_get_uri (fr_archive_get_file (window->archive));
 
+		if (window->priv->notify) {
+			g_free (window->priv->convert_data.new_file);
+			window->priv->convert_data.new_file = g_strdup (window->priv->archive_uri);
+		}
+
 		if (error == NULL) {
 			if (window->priv->archive_new)
 				window->priv->archive_new = FALSE;
 			fr_window_add_to_recent_list (window, window->priv->archive_uri);
 		}
 
-		close_progress_dialog (window, FALSE);
 		if (! window->priv->batch_mode && ! operation_canceled) {
 			fr_window_archive_reload (window);
 			return;
@@ -6236,6 +6261,93 @@ fr_window_archive_reload (FrWindow *window)
 /**/
 
 
+#ifdef ENABLE_NOTIFICATION
+
+
+static void
+notification_closed_cb  (NotifyNotification *notification,
+			gpointer            user_data)
+{
+	_fr_window_close_after_notification (FR_WINDOW (user_data));
+}
+
+
+static void
+notify_action_open_archive_cb (NotifyNotification *notification,
+			       char               *action,
+			       gpointer            user_data)
+{
+	FrWindow  *window = user_data;
+	GtkWidget *new_window;
+
+	new_window = fr_window_new ();
+	gtk_widget_show (new_window);
+
+	fr_window_archive_open (FR_WINDOW (new_window),
+				window->priv->convert_data.new_file,
+				GTK_WINDOW (new_window));
+}
+
+
+static void
+_fr_window_notify_creation_complete (FrWindow *window)
+{
+	char               *title;
+	char               *basename;
+	char               *message;
+	NotifyNotification *notification;
+	gboolean            notification_supports_actions;
+	GList              *caps;
+
+	title = get_action_description (window->priv->action, window->priv->pd_last_archive);
+	basename = _g_uri_display_basename (window->priv->convert_data.new_file);
+	message = g_strdup_printf (_("Archive \"%s\" created successfully"), basename);
+	notification = notify_notification_new (window->priv->batch_title, message, "file-roller");
+
+	g_signal_connect (notification,
+			  "closed",
+			  G_CALLBACK (notification_closed_cb),
+			  window);
+
+	notification_supports_actions = FALSE;
+	caps = notify_get_server_caps ();
+	if (caps != NULL) {
+		notification_supports_actions = g_list_find_custom (caps, "actions", (GCompareFunc) strcmp) != NULL;
+		_g_string_list_free (caps);
+	}
+
+	if (notification_supports_actions) {
+		notify_notification_add_action (notification,
+						"document-open-symbolic",
+						_("Open"),
+						notify_action_open_archive_cb,
+						window,
+						NULL);
+		/*notify_notification_set_hint (notification,
+					      "action-icons",
+					      g_variant_new_boolean (TRUE));*/
+	}
+
+	notify_notification_show (notification, NULL);
+	g_free (message);
+	g_free (basename);
+	g_free (title);
+}
+
+
+#else
+
+
+static void
+_fr_window_notify_creation_complete (FrWindow *window)
+{
+	_fr_window_close_after_notification (window);
+}
+
+
+#endif
+
+
 static void
 archive_add_files_ready_cb (GObject      *source_object,
 			    GAsyncResult *result,
@@ -6243,10 +6355,40 @@ archive_add_files_ready_cb (GObject      *source_object,
 {
 	FrWindow *window = user_data;
 	GError   *error = NULL;
+	gboolean  notify;
+
+	/* get here the value because the window can be destroy after calling
+	 * _archive_operation_completed. */
+	notify = window->priv->notify;
 
 	fr_archive_operation_finish (FR_ARCHIVE (source_object), result, &error);
 	_archive_operation_completed (window, FR_ACTION_ADDING_FILES, error);
 
+	if (notify) {
+		GtkWidget *main_window;
+		gboolean   has_system_notification;
+
+		if (window->priv->batch_mode)
+			main_window = window->priv->progress_dialog;
+		else
+			main_window = GTK_WIDGET (window);
+
+#ifdef ENABLE_NOTIFICATION
+		has_system_notification = TRUE;
+#else
+		has_system_notification = FALSE;
+#endif
+
+		if (! has_system_notification || gtk_window_has_toplevel_focus (GTK_WINDOW (main_window))) {
+			window->priv->quit_with_progress_dialog = TRUE;
+			open_progress_dialog_with_open_archive (window);
+		}
+		else {
+			close_progress_dialog (window, TRUE);
+			_fr_window_notify_creation_complete (window);
+		}
+	}
+
 	_g_error_free (error);
 }
 
@@ -9048,8 +9190,10 @@ fr_window_exec_batch_action (FrWindow      *window,
 			       0,
 			       NULL);
 
-		if ((window->priv->progress_dialog != NULL) && (gtk_widget_get_parent (window->priv->progress_dialog) != GTK_WIDGET (window)))
+		if ((window->priv->progress_dialog != NULL) && (gtk_widget_get_parent (window->priv->progress_dialog) != GTK_WIDGET (window))) {
 			gtk_widget_destroy (window->priv->progress_dialog);
+			window->priv->progress_dialog = NULL;
+		}
 		gtk_widget_destroy (GTK_WIDGET (window));
 		break;
 
@@ -9120,10 +9264,9 @@ fr_window_exec_current_batch_action (FrWindow *window)
 {
 	FrBatchAction *action;
 
-	if (window->priv->batch_action == NULL) {
-		window->priv->batch_mode = FALSE;
+	if (window->priv->batch_action == NULL)
 		return;
-	}
+
 	action = (FrBatchAction *) window->priv->batch_action->data;
 	fr_window_exec_batch_action (window, action);
 }
diff --git a/src/fr-window.h b/src/fr-window.h
index 6e24a18..33c9e2e 100644
--- a/src/fr-window.h
+++ b/src/fr-window.h
@@ -306,6 +306,8 @@ void            fr_window_set_batch__add               (FrWindow      *window,
 						        const char    *archive,
 						        GList         *file_list);
 void            fr_window_destroy_with_error_dialog    (FrWindow      *window);
+void            fr_window_set_notify                   (FrWindow      *window,
+							gboolean       notify);
 
 /**/
 
diff --git a/src/main.c b/src/main.c
index bbafb02..c4a656d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -31,6 +31,9 @@
 #include <glib/gprintf.h>
 #include <glib.h>
 #include <gio/gio.h>
+#ifdef ENABLE_NOTIFICATION
+#  include <libnotify/notify.h>
+#endif
 #include "actions.h"
 #ifdef USE_SMCLIENT
 #  include "eggsmclient.h"
@@ -56,6 +59,7 @@ static int          arg_extract_here = FALSE;
 static char        *arg_default_dir = NULL;
 static gboolean     arg_version = FALSE;
 static gboolean     arg_service = FALSE;
+static gboolean     arg_notify = FALSE;
 static const char  *program_argv0 = NULL; /* argv[0] from main(); used as the command to restart the program */
 
 
@@ -88,6 +92,9 @@ static const GOptionEntry options[] = {
 	  N_("Create destination folder without asking confirmation"),
 	  NULL },
 
+	{ "notify", '\0', 0, G_OPTION_ARG_NONE, &arg_notify,
+	  N_("Use the notification system to notify the operation completion"), NULL },
+
 	{ "service", '\0', 0, G_OPTION_ARG_NONE, &arg_service,
 	  N_("Start as a service"), NULL },
 
@@ -578,6 +585,11 @@ fr_application_init (FrApplication *self)
 	gtk_window_set_default_icon_name ("file-roller");
 #endif
 
+#ifdef ENABLE_NOTIFICATION
+	if (! notify_init (g_get_application_name ()))
+                g_warning ("Cannot initialize notification system.");
+#endif /* ENABLE_NOTIFICATION */
+
 	self->owner_id = 0;
 	self->introspection_data = NULL;
 }
@@ -734,10 +746,11 @@ fr_application_command_line (GApplication            *application,
 
 		fr_window_new_batch (FR_WINDOW (window), _("Compress"));
 		fr_window_set_batch__add (FR_WINDOW (window), add_to_uri, file_list);
-		fr_window_append_batch_action (FR_WINDOW (window),
-					       FR_BATCH_ACTION_QUIT,
-					       NULL,
-					       NULL);
+
+		if (! arg_notify)
+			fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
+		else
+			fr_window_set_notify (FR_WINDOW (window), TRUE);
 		fr_window_start_batch (FR_WINDOW (window));
 	}
 	else if ((arg_extract_to != NULL) || (arg_extract == 1) || (arg_extract_here == 1)) {
@@ -759,18 +772,12 @@ fr_application_command_line (GApplication            *application,
 
 			archive_uri = _g_uri_get_from_command_line (archive);
 			if (arg_extract_here == 1)
-				fr_window_set_batch__extract_here (FR_WINDOW (window),
-								   archive_uri);
+				fr_window_set_batch__extract_here (FR_WINDOW (window), archive_uri);
 			else
-				fr_window_set_batch__extract (FR_WINDOW (window),
-							      archive_uri,
-							      extract_to_uri);
+				fr_window_set_batch__extract (FR_WINDOW (window), archive_uri, extract_to_uri);
 			g_free (archive_uri);
 		}
-		fr_window_append_batch_action (FR_WINDOW (window),
-					       FR_BATCH_ACTION_QUIT,
-					       NULL,
-					       NULL);
+		fr_window_append_batch_action (FR_WINDOW (window), FR_BATCH_ACTION_QUIT, NULL, NULL);
 
 		fr_window_start_batch (FR_WINDOW (window));
 	}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]