[gnome-user-share] Bug 558244 - Enabling gnome-user-share requires changing preference in capplet



commit c2014b9d7d07c4cca781c60804f2eae796f75fed
Author: Bastien Nocera <hadess hadess net>
Date:   Tue Sep 8 17:26:35 2009 +0100

    Bug 558244 - Enabling gnome-user-share requires changing preference in capplet
    
    Add a cluebar to the Public and Downloads folders, to allow launching
    the sharing preferences.

 configure.in             |    8 ++
 po/POTFILES.in           |    2 +
 src/Makefile.am          |   12 ++
 src/nautilus-share-bar.c |  226 +++++++++++++++++++++++++++++++++++
 src/nautilus-share-bar.h |   61 ++++++++++
 src/share-extension.c    |  292 ++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 601 insertions(+), 0 deletions(-)
---
diff --git a/configure.in b/configure.in
index 573d07e..0e2d7b5 100644
--- a/configure.in
+++ b/configure.in
@@ -127,6 +127,14 @@ AC_ARG_WITH([modules-path],
 MODULES_PATH=$with_modules_path
 AC_SUBST(MODULES_PATH)
 
+dnl===========================================================================
+dnl Check for nautilus for the share bar
+
+PKG_CHECK_MODULES(EXTENSION,
+		   libnautilus-extension)
+NAUTILUSDIR=`pkg-config --variable=extensiondir libnautilus-extension`
+AC_SUBST(NAUTILUSDIR)
+
 dnl ==========================================================================
 
 dnl Turn on the additional warnings last, so -Werror doesn't affect other tests.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6f7bdec..c094fe0 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,6 +4,8 @@ data/desktop_gnome_file_sharing.schemas.in
 [type: gettext/glade]data/file-share-properties.ui
 data/gnome-user-share-properties.desktop.in
 data/gnome-user-share.desktop.in.in
+src/nautilus-share-bar.c
+src/share-extension.c
 src/file-share-properties.c
 src/http.c
 src/obexpush.c
diff --git a/src/Makefile.am b/src/Makefile.am
index fa673d2..fa7aa0a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,6 +26,7 @@ INCLUDES=	\
 	-DHTTPD_MODULES_PATH=\""$(MODULES_PATH)"\"	\
 	-I$(top_srcdir) 				\
 	-I$(top_builddir) 				\
+	$(EXTENSION_CFLAGS)				\
 	$(USER_SHARE_CFLAGS)				\
 	$(USER_SHARE_CONFIG_CFLAGS)			\
 	$(X_CFLAGS)
@@ -56,6 +57,17 @@ gnome_file_share_properties_SOURCES =	\
 gnome_file_share_properties_LDADD = \
 	$(USER_SHARE_CONFIG_LIBS)
 
+nautilus_extensiondir = $(NAUTILUSDIR)
+nautilus_extension_LTLIBRARIES = libnautilus-share-extension.la
+
+libnautilus_share_extension_la_SOURCES =         \
+	nautilus-share-bar.c                     \
+	nautilus-share-bar.h                     \
+	share-extension.c                        \
+	$(NULL)
+
+libnautilus_share_extension_la_LIBADD = $(EXTENSION_LIBS)
+libnautilus_share_extension_la_LDFLAGS = -avoid-version -module -no-undefined
 
 EXTRA_DIST = marshal.list
 
diff --git a/src/nautilus-share-bar.c b/src/nautilus-share-bar.c
new file mode 100644
index 0000000..bed6281
--- /dev/null
+++ b/src/nautilus-share-bar.c
@@ -0,0 +1,226 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <mccann jhu edu>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: William Jon McCann <mccann jhu edu>
+ *
+ */
+
+#include "config.h"
+
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include "nautilus-share-bar.h"
+
+static void nautilus_share_bar_finalize   (GObject *object);
+
+#define NAUTILUS_SHARE_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NAUTILUS_TYPE_SHARE_BAR, NautilusShareBarPrivate))
+
+struct NautilusShareBarPrivate
+{
+        GtkTooltips *tooltips;
+        GtkWidget   *button;
+        GtkWidget   *label;
+        char        *str;
+};
+
+enum {
+	PROP_0,
+	PROP_LABEL
+};
+
+enum {
+       ACTIVATE,
+       LAST_SIGNAL
+};
+
+static guint           signals [LAST_SIGNAL] = { 0, };
+
+G_DEFINE_TYPE (NautilusShareBar, nautilus_share_bar, GTK_TYPE_HBOX)
+
+GtkWidget *
+nautilus_share_bar_get_button (NautilusShareBar *bar)
+{
+        GtkWidget *button;
+
+        g_return_val_if_fail (bar != NULL, NULL);
+
+        button = bar->priv->button;
+
+        return button;
+}
+
+static void
+nautilus_share_bar_set_property (GObject            *object,
+                                guint               prop_id,
+                                const GValue       *value,
+                                GParamSpec         *pspec)
+{
+        NautilusShareBar *self;
+
+        self = NAUTILUS_SHARE_BAR (object);
+
+        switch (prop_id) {
+	case PROP_LABEL: {
+		char *str;
+		g_free (self->priv->str);
+		str = g_strdup_printf ("<i>%s</i>", g_value_get_string (value));
+		gtk_label_set_markup (GTK_LABEL (self->priv->label), str);
+		self->priv->str = g_value_dup_string (value);
+		break;
+	}
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+nautilus_share_bar_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+        NautilusShareBar *self;
+
+        self = NAUTILUS_SHARE_BAR (object);
+
+        switch (prop_id) {
+	case PROP_LABEL:
+		g_value_set_string (value, self->priv->str);
+		break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+nautilus_share_bar_class_init (NautilusShareBarClass *klass)
+{
+        GObjectClass   *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->finalize     = nautilus_share_bar_finalize;
+        object_class->get_property = nautilus_share_bar_get_property;
+        object_class->set_property = nautilus_share_bar_set_property;
+
+        g_type_class_add_private (klass, sizeof (NautilusShareBarPrivate));
+
+        g_object_class_install_property (G_OBJECT_CLASS(klass),
+					 PROP_LABEL, g_param_spec_string ("label",
+									  "label", "The widget's main label", NULL, G_PARAM_READWRITE));
+
+
+        signals [ACTIVATE] = g_signal_new ("activate",
+                                           G_TYPE_FROM_CLASS (klass),
+                                           G_SIGNAL_RUN_LAST,
+                                           G_STRUCT_OFFSET (NautilusShareBarClass, activate),
+                                           NULL, NULL,
+                                           g_cclosure_marshal_VOID__VOID,
+                                           G_TYPE_NONE, 0);
+
+}
+
+static void
+button_clicked_cb (GtkWidget       *button,
+                   NautilusShareBar *bar)
+{
+        g_signal_emit (bar, signals [ACTIVATE], 0);
+}
+
+static void
+nautilus_share_bar_init (NautilusShareBar *bar)
+{
+	GtkWidget   *label;
+        GtkWidget   *hbox;
+        GtkWidget   *vbox;
+        GtkWidget   *image;
+        char        *hint;
+
+        bar->priv = NAUTILUS_SHARE_BAR_GET_PRIVATE (bar);
+
+        bar->priv->tooltips = gtk_tooltips_new ();
+        g_object_ref (bar->priv->tooltips);
+        gtk_object_sink (GTK_OBJECT (bar->priv->tooltips));
+
+        hbox = GTK_WIDGET (bar);
+
+        vbox = gtk_vbox_new (FALSE, 6);
+        gtk_widget_show (vbox);
+        gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+
+        label = gtk_label_new (_("Personal File Sharing"));
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        gtk_widget_show (label);
+        gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+
+        bar->priv->label = gtk_label_new ("");
+        hint = g_strdup_printf ("<i>%s</i>", "");
+        gtk_label_set_markup (GTK_LABEL (bar->priv->label), hint);
+        gtk_misc_set_alignment (GTK_MISC (bar->priv->label), 0.0, 0.5);
+        gtk_widget_show (bar->priv->label);
+        gtk_box_pack_start (GTK_BOX (vbox), bar->priv->label, TRUE, TRUE, 0);
+
+        bar->priv->button = gtk_button_new_with_label (_("Launch Preferences"));
+        gtk_widget_show (bar->priv->button);
+        gtk_box_pack_end (GTK_BOX (hbox), bar->priv->button, FALSE, FALSE, 0);
+
+        image = gtk_image_new_from_icon_name ("folder-remote", GTK_ICON_SIZE_BUTTON);
+        gtk_widget_show (image);
+        gtk_button_set_image (GTK_BUTTON (bar->priv->button), image);
+
+        g_signal_connect (bar->priv->button, "clicked",
+                          G_CALLBACK (button_clicked_cb),
+                          bar);
+
+        gtk_tooltips_set_tip (GTK_TOOLTIPS (bar->priv->tooltips),
+                              bar->priv->button,
+                              _("Launch Personal File Sharing Preferences"),
+                              NULL);
+}
+
+static void
+nautilus_share_bar_finalize (GObject *object)
+{
+        NautilusShareBar *bar;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (NAUTILUS_IS_SHARE_BAR (object));
+
+        bar = NAUTILUS_SHARE_BAR (object);
+
+        g_return_if_fail (bar->priv != NULL);
+
+        if (bar->priv->tooltips != NULL) {
+                g_object_unref (bar->priv->tooltips);
+        }
+
+        G_OBJECT_CLASS (nautilus_share_bar_parent_class)->finalize (object);
+}
+
+GtkWidget *
+nautilus_share_bar_new (const char *label)
+{
+        GObject *result;
+
+        result = g_object_new (NAUTILUS_TYPE_SHARE_BAR,
+			       "label", label,
+                               NULL);
+
+        return GTK_WIDGET (result);
+}
diff --git a/src/nautilus-share-bar.h b/src/nautilus-share-bar.h
new file mode 100644
index 0000000..b7fb1fd
--- /dev/null
+++ b/src/nautilus-share-bar.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2005 William Jon McCann <mccann jhu edu>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors: William Jon McCann <mccann jhu edu>
+ *
+ */
+
+#ifndef __NAUTILUS_SHARE_BAR_H
+#define __NAUTILUS_SHARE_BAR_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define NAUTILUS_TYPE_SHARE_BAR         (nautilus_share_bar_get_type ())
+#define NAUTILUS_SHARE_BAR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_SHARE_BAR, NautilusShareBar))
+#define NAUTILUS_SHARE_BAR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), NAUTILUS_TYPE_SHARE_BAR, NautilusShareBarClass))
+#define NAUTILUS_IS_SHARE_BAR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_SHARE_BAR))
+#define NAUTILUS_IS_SHARE_BAR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), NAUTILUS_TYPE_SHARE_BAR))
+#define NAUTILUS_SHARE_BAR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NAUTILUS_TYPE_SHARE_BAR, NautilusShareBarClass))
+
+typedef struct NautilusShareBarPrivate NautilusShareBarPrivate;
+
+typedef struct
+{
+        GtkHBox                 box;
+
+        NautilusShareBarPrivate *priv;
+} NautilusShareBar;
+
+typedef struct
+{
+        GtkHBoxClass            parent_class;
+
+	void (* activate) (NautilusShareBar *bar);
+
+} NautilusShareBarClass;
+
+GType       nautilus_share_bar_get_type          (void);
+GtkWidget  *nautilus_share_bar_new               (const char *label);
+
+GtkWidget  *nautilus_share_bar_get_button        (NautilusShareBar *bar);
+
+G_END_DECLS
+
+#endif /* __GS_SHARE_BAR_H */
diff --git a/src/share-extension.c b/src/share-extension.c
new file mode 100644
index 0000000..036ecd3
--- /dev/null
+++ b/src/share-extension.c
@@ -0,0 +1,292 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8 -*-
+ *
+ * Copyright (C) 2003 Novell, Inc.
+ * Copyright (C) 2003-2004 Red Hat, Inc.
+ * Copyright (C) 2005 William Jon McCann <mccann jhu edu>
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <libnautilus-extension/nautilus-menu-provider.h>
+#include <libnautilus-extension/nautilus-location-widget-provider.h>
+
+#include "nautilus-share-bar.h"
+
+#define NAUTILUS_TYPE_SHARE  (nautilus_share_get_type ())
+#define NAUTILUS_SHARE(o)    (G_TYPE_CHECK_INSTANCE_CAST ((o), NAUTILUS_TYPE_SHARE, NautilusShare))
+#define NAUTILUS_IS_SHARE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NAUTILUS_TYPE_SHARE))
+
+typedef struct _NautilusSharePrivate NautilusSharePrivate;
+
+typedef struct
+{
+        GObject              parent_slot;
+        NautilusSharePrivate *priv;
+} NautilusShare;
+
+typedef struct
+{
+        GObjectClass parent_slot;
+} NautilusShareClass;
+
+#define NAUTILUS_SHARE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NAUTILUS_TYPE_SHARE, NautilusSharePrivate))
+
+struct _NautilusSharePrivate
+{
+        GSList       *widget_list;
+};
+
+static GType nautilus_share_get_type      (void);
+static void  nautilus_share_register_type (GTypeModule *module);
+
+static GObjectClass *parent_class;
+
+
+static void
+launch_process (char **argv, GtkWindow *parent)
+{
+        GError *error;
+        GtkWidget *dialog;
+
+        error = NULL;
+        if (!g_spawn_async (NULL,
+                            argv, NULL,
+                            0,
+                            NULL, NULL,
+                            NULL,
+                            &error)) {
+
+
+                dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING,
+						 GTK_BUTTONS_OK, _("Unable to launch the Personal File Sharing preferences"));
+
+                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
+
+                gtk_dialog_run (GTK_DIALOG (dialog));
+                gtk_widget_destroy (dialog);
+
+                g_error_free (error);
+        }
+}
+
+static void
+launch_prefs_on_window (GtkWindow *window)
+{
+        char *argv [2];
+
+        argv [0] = g_build_filename (BINDIR, "gnome-file-share-properties", NULL);
+        argv [1] = NULL;
+
+        launch_process (argv, window);
+
+        g_free (argv [0]);
+}
+
+static void
+bar_activated_cb (NautilusShareBar *bar,
+                  gpointer         data)
+{
+        launch_prefs_on_window (GTK_WINDOW (data));
+}
+
+static void
+destroyed_callback (GtkWidget    *widget,
+                    NautilusShare *share)
+{
+        share->priv->widget_list = g_slist_remove (share->priv->widget_list, widget);
+}
+
+static void
+add_widget (NautilusShare *share,
+              GtkWidget    *widget)
+{
+        share->priv->widget_list = g_slist_prepend (share->priv->widget_list, widget);
+
+        g_signal_connect (widget, "destroy",
+                          G_CALLBACK (destroyed_callback),
+                          share);
+}
+
+static GtkWidget *
+nautilus_share_get_location_widget (NautilusLocationWidgetProvider *iface,
+                                   const char                     *uri,
+                                   GtkWidget                      *window)
+{
+	GFile         *file;
+	GtkWidget     *bar;
+	NautilusShare *share;
+	guint          i;
+	gboolean       enable = FALSE;
+	const GUserDirectory special_dirs[] = { G_USER_DIRECTORY_PUBLIC_SHARE, G_USER_DIRECTORY_DOWNLOAD };
+	gboolean is_dir[] = { FALSE, FALSE };
+
+	file = g_file_new_for_uri (uri);
+
+	for (i = 0; i < G_N_ELEMENTS (special_dirs); i++) {
+		const char *path;
+
+		path = g_get_user_special_dir (special_dirs[i]);
+		if (path != NULL) {
+			GFile *dir;
+			dir = g_file_new_for_path (path);
+			if (g_file_equal (dir, file)) {
+				enable = TRUE;
+				is_dir[i] = TRUE;
+			}
+			g_object_unref (dir);
+		}
+	}
+
+	if (enable == FALSE)
+		return NULL;
+
+	share = NAUTILUS_SHARE (iface);
+
+	if (is_dir[0] != FALSE && is_dir[1] != FALSE) {
+		bar = nautilus_share_bar_new (_("You can share files from this folder and receive files to it"));
+	} else if (is_dir[0] != FALSE) {
+		bar = nautilus_share_bar_new (_("You can share files from this folder over the network and Bluetooth"));
+	} else {
+		bar = nautilus_share_bar_new (_("You can receive files over Bluetooth into this folder"));
+	}
+
+	add_widget (share, nautilus_share_bar_get_button (NAUTILUS_SHARE_BAR (bar)));
+
+	g_signal_connect (bar, "activate",
+			  G_CALLBACK (bar_activated_cb),
+			  window);
+
+	gtk_widget_show (bar);
+
+	g_object_unref (file);
+
+        return bar;
+}
+
+static void
+nautilus_share_location_widget_provider_iface_init (NautilusLocationWidgetProviderIface *iface)
+{
+        iface->get_widget = nautilus_share_get_location_widget;
+}
+
+static void
+nautilus_share_instance_init (NautilusShare *share)
+{
+        share->priv = NAUTILUS_SHARE_GET_PRIVATE (share);
+}
+
+static void
+nautilus_share_finalize (GObject *object)
+{
+        NautilusShare *share;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (NAUTILUS_IS_SHARE (object));
+
+        share = NAUTILUS_SHARE (object);
+
+        g_return_if_fail (share->priv != NULL);
+
+        if (share->priv->widget_list != NULL) {
+                g_slist_free (share->priv->widget_list);
+        }
+
+        G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+nautilus_share_class_init (NautilusShareClass *klass)
+{
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+        parent_class = g_type_class_peek_parent (klass);
+
+        object_class->finalize = nautilus_share_finalize;
+
+        g_type_class_add_private (klass, sizeof (NautilusSharePrivate));
+}
+
+static GType share_type = 0;
+
+static GType
+nautilus_share_get_type (void)
+{
+        return share_type;
+}
+
+static void
+nautilus_share_register_type (GTypeModule *module)
+{
+        static const GTypeInfo info = {
+                sizeof (NautilusShareClass),
+                (GBaseInitFunc) NULL,
+                (GBaseFinalizeFunc) NULL,
+                (GClassInitFunc) nautilus_share_class_init,
+                NULL,
+                NULL,
+                sizeof (NautilusShare),
+                0,
+                (GInstanceInitFunc) nautilus_share_instance_init,
+        };
+
+        static const GInterfaceInfo location_widget_provider_iface_info = {
+                (GInterfaceInitFunc) nautilus_share_location_widget_provider_iface_init,
+                NULL,
+                NULL
+        };
+
+        share_type = g_type_module_register_type (module,
+                                                 G_TYPE_OBJECT,
+                                                 "NautilusShare",
+                                                 &info, 0);
+
+        g_type_module_add_interface (module,
+                                     share_type,
+                                     NAUTILUS_TYPE_LOCATION_WIDGET_PROVIDER,
+                                     &location_widget_provider_iface_info);
+}
+
+void
+nautilus_module_initialize (GTypeModule *module)
+{
+        nautilus_share_register_type (module);
+        bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
+        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+}
+
+void
+nautilus_module_shutdown (void)
+{
+}
+
+void
+nautilus_module_list_types (const GType **types,
+                            int          *num_types)
+{
+        static GType type_list [1];
+
+        type_list[0] = NAUTILUS_TYPE_SHARE;
+
+        *types = type_list;
+        *num_types = 1;
+}



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