From ea8c94879c991cf1e09a53ae51e89a0f0715a9e1 Mon Sep 17 00:00:00 2001
From: Ettore Perazzoli <ettore@src.gnome.org>
Date: Fri, 10 May 2002 17:28:57 +0000
Subject: New. New.

* e-shell-shared-folder-picker-dialog.c: New.
* e-shell-shared-folder-picker-dialog.h: New.

svn path=/trunk/; revision=16748
---
 shell/e-shell-shared-folder-picker-dialog.c | 472 ++++++++++++++++++++++++++++
 1 file changed, 472 insertions(+)
 create mode 100644 shell/e-shell-shared-folder-picker-dialog.c

(limited to 'shell/e-shell-shared-folder-picker-dialog.c')

diff --git a/shell/e-shell-shared-folder-picker-dialog.c b/shell/e-shell-shared-folder-picker-dialog.c
new file mode 100644
index 0000000000..02ce56f98e
--- /dev/null
+++ b/shell/e-shell-shared-folder-picker-dialog.c
@@ -0,0 +1,472 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-shell-shared-folder-picker-dialog.c - Implementation for the shared folder
+ * picker dialog.
+ *
+ * Copyright (C) 2002 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * Author: Ettore Perazzoli <ettore@ximian.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-shell-shared-folder-picker-dialog.h"
+
+#include "e-corba-storage.h"
+#include "evolution-storage-listener.h"
+
+#include "Evolution-Addressbook-SelectNames.h"
+
+#include <gal/widgets/e-gui-utils.h>
+
+#include <libgnomeui/gnome-stock.h>
+#include <libgnomeui/gnome-dialog.h>
+#include <libgnome/gnome-i18n.h>
+#include <glade/glade.h>
+
+#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-listener.h>
+#include <bonobo/bonobo-widget.h>
+
+#include <gtk/gtk.h>
+
+
+/* Dialog creation and handling.  */
+
+static void
+setup_folder_name_combo (GladeXML *glade_xml)
+{
+	GtkWidget *combo;
+	GList *string_list;
+	char *strings[] = {
+		"Calendar",
+		"Inbox",
+		"Contacts",
+		NULL
+		/* FIXME: Should these be translated?  */
+	};
+	int i;
+
+	combo = glade_xml_get_widget (glade_xml, "folder-name-combo");
+	g_assert (GTK_IS_COMBO (combo));
+
+	string_list = NULL;
+	for (i = 0; strings[i] != NULL; i ++)
+		string_list = g_list_append (string_list, strings[i]);
+	gtk_combo_set_popdown_strings (GTK_COMBO (combo), string_list);
+	g_list_free (string_list);
+
+	gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (combo)->entry), "Calendar");
+}
+
+static GtkWidget *
+setup_name_selector (GladeXML *glade_xml)
+{
+	GNOME_Evolution_Addressbook_SelectNames corba_iface;
+	Bonobo_Control control;
+	CORBA_Environment ev;
+	GtkWidget *placeholder;
+	GtkWidget *control_widget;
+
+	placeholder = glade_xml_get_widget (glade_xml, "user-picker-placeholder");
+	g_assert (GTK_IS_CONTAINER (placeholder));
+
+	CORBA_exception_init (&ev);
+
+	corba_iface = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Addressbook_SelectNames",
+					    0, NULL, &ev);
+	if (corba_iface == CORBA_OBJECT_NIL || BONOBO_EX (&ev)) {
+		g_warning ("Cannot activate SelectNames -- %s", BONOBO_EX_ID (&ev));
+		CORBA_exception_free (&ev);
+		return CORBA_OBJECT_NIL;
+	}
+
+	GNOME_Evolution_Addressbook_SelectNames_addSectionWithLimit (corba_iface, "User", "User", 1, &ev);
+	if (BONOBO_EX (&ev)) {
+		g_warning ("Cannot add SelectNames section -- %s", BONOBO_EX_ID (&ev));
+		goto err;
+	}
+
+	control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection (corba_iface, "User", &ev);
+	if (BONOBO_EX (&ev)) {
+		g_warning ("Cannot get SelectNames section -- %s", BONOBO_EX_ID (&ev));
+		goto err;
+	}
+
+	control_widget = bonobo_widget_new_control_from_objref (control, CORBA_OBJECT_NIL);
+	gtk_container_add (GTK_CONTAINER (placeholder), control_widget);
+	gtk_widget_show (control_widget);
+
+	CORBA_exception_free (&ev);
+	return control_widget;
+
+ err:
+	Bonobo_Unknown_unref (corba_iface, &ev);
+	CORBA_exception_free (&ev);
+	return NULL;
+}
+
+static void
+server_option_menu_item_activate_callback (GtkMenuItem *menu_item,
+					   void *data)
+{
+	char **storage_name_return;
+
+	storage_name_return = (char **) data;
+	if (*storage_name_return != NULL)
+		g_free (*storage_name_return);
+
+	*storage_name_return = g_strdup ((const char *) gtk_object_get_data (GTK_OBJECT (menu_item),
+									     "storage_name"));
+}
+
+static void
+setup_server_option_menu (EShell *shell,
+			  GladeXML *glade_xml,
+			  char **storage_name_return)
+{
+	GList *storages;
+	GList *p;
+	GtkWidget *widget;
+	GtkWidget *menu;
+
+	widget = glade_xml_get_widget (glade_xml, "server-option-menu");
+	g_assert (GTK_IS_OPTION_MENU (widget));
+
+	menu = gtk_menu_new ();
+	gtk_widget_show (menu);
+
+	*storage_name_return = NULL;
+	storages = e_storage_set_get_storage_list (e_shell_get_storage_set (shell));
+	for (p = storages; p != NULL; p = p->next) {
+		GNOME_Evolution_Storage storage_iface;
+		CORBA_boolean has_shared_folders;
+		CORBA_Environment ev;
+
+		/* FIXME FIXME FIXME.
+
+		OK, this sucks.  Only CORBA storages can be used as shared
+		folder servers.  Eventually, there will only be CORBA
+		storages so the special case will go away automatically.  For
+		the time being, we are left with this ugliness, but it makes
+		my life easier.  */
+
+		if (! E_IS_CORBA_STORAGE (p->data))
+			continue;
+
+		CORBA_exception_init (&ev);
+
+		storage_iface = e_corba_storage_get_corba_objref (E_CORBA_STORAGE (p->data));
+		g_assert (storage_iface != CORBA_OBJECT_NIL);
+
+		has_shared_folders = GNOME_Evolution_Storage__get_hasSharedFolders (storage_iface, &ev);
+		if (! BONOBO_EX (&ev) && has_shared_folders) {
+			GtkWidget *menu_item;
+			const char *storage_name;
+
+			storage_name = e_storage_get_name (E_STORAGE (p->data));
+
+			menu_item = gtk_menu_item_new_with_label (storage_name);
+			gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
+					    GTK_SIGNAL_FUNC (server_option_menu_item_activate_callback),
+					    storage_name_return);
+			gtk_object_set_data_full (GTK_OBJECT (menu_item), "storage_name",
+						  g_strdup (storage_name), g_free);
+
+			gtk_widget_show (menu_item);
+			gtk_menu_append (GTK_MENU (menu), menu_item);
+
+			if (*storage_name_return == NULL)
+				*storage_name_return = g_strdup (storage_name);
+		}
+		
+		CORBA_exception_free (&ev);
+	}
+
+	gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu);
+
+	/* FIXME: Default to the current storage in the shell view.  */
+}
+
+static gboolean
+show_dialog (EShell *shell,
+	     EShellView *parent,
+	     char **user_email_address_return,
+	     char **storage_name_return,
+	     char **folder_name_return)
+{
+	GladeXML *glade_xml;
+	GtkWidget *dialog;
+	GtkWidget *name_selector_widget;
+	GtkWidget *folder_name_entry;
+	int button_num;
+
+	glade_xml = glade_xml_new (EVOLUTION_GLADEDIR "/e-shell-shared-folder-picker-dialog.glade",
+				   NULL);
+	g_assert (glade_xml != NULL);
+
+	name_selector_widget = setup_name_selector (glade_xml);
+	if (name_selector_widget == NULL)
+		return FALSE;
+
+	setup_server_option_menu (shell, glade_xml, storage_name_return);
+	setup_folder_name_combo (glade_xml);
+
+	dialog = glade_xml_get_widget (glade_xml, "dialog");
+	g_assert (dialog != NULL);
+
+	gnome_dialog_close_hides (GNOME_DIALOG (dialog), TRUE);
+
+	button_num = gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
+	if (button_num == 1) {	/* Cancel */
+		g_free (*storage_name_return);
+		*storage_name_return = NULL;
+		gtk_widget_destroy (dialog);
+		return FALSE;
+	}
+
+	bonobo_widget_get_property (BONOBO_WIDGET (name_selector_widget),
+				    "text", user_email_address_return,
+				    NULL);
+
+	folder_name_entry = glade_xml_get_widget (glade_xml, "folder-name-entry");
+	*folder_name_return = g_strdup (gtk_entry_get_text (GTK_ENTRY (folder_name_entry)));
+
+	gtk_widget_destroy (dialog);
+	return TRUE;
+}
+
+
+/* Discovery process.  */
+
+struct _DiscoveryData {
+	GtkWidget *dialog;
+	EStorage *storage;
+	char *user;
+	char *folder_name;
+};
+typedef struct _DiscoveryData DiscoveryData;
+
+static int
+progress_bar_timeout_callback (void *data)
+{
+	GtkAdjustment *adjustment;
+	float value;
+
+	adjustment = GTK_PROGRESS (data)->adjustment;
+	value = adjustment->value + 1;
+	if (value > adjustment->upper)
+		value = adjustment->lower;
+
+	gtk_progress_set_value (GTK_PROGRESS (data), value);
+
+	return TRUE;
+}
+
+static void
+progress_bar_destroy_callback (GtkObject *object,
+			       void *data)
+{
+	int timeout_id;
+
+	timeout_id = GPOINTER_TO_INT (data);
+	g_source_remove (timeout_id);
+}
+
+static int
+progress_dialog_close_callback (GnomeDialog *dialog,
+				void *data)
+{
+	/* Don't allow the dialog to be closed through the window manager close
+	   command.  */
+	return TRUE;
+}
+
+static GtkWidget *
+show_progress_dialog (EShell *shell,
+		      EStorage *storage,
+		      const char *user_email_address,
+		      const char *folder_name)
+{
+	GtkWidget *dialog;
+	GtkWidget *label;
+	GtkWidget *progress_bar;
+	int progress_bar_timeout_id;
+	char *text;
+
+	dialog = gnome_dialog_new (_("Opening Folder"), GNOME_STOCK_BUTTON_CANCEL, NULL);
+	gtk_widget_set_usize (dialog, 300, -1);
+	gtk_window_set_policy (GTK_WINDOW (dialog), FALSE, FALSE, FALSE);
+
+	gtk_signal_connect (GTK_OBJECT (dialog), "close",
+			    GTK_SIGNAL_FUNC (progress_dialog_close_callback), NULL);
+
+	text = g_strdup_printf (_("Opening Folder \"%s\""), folder_name);
+	label = gtk_label_new (text);
+	gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, FALSE, TRUE, 0);
+	g_free (text);
+
+	text = g_strdup_printf (_("in \"%s\" ..."), e_storage_get_name (storage));
+	label = gtk_label_new (text);
+	gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, FALSE, TRUE, 0);
+	g_free (text);
+
+	progress_bar = gtk_progress_bar_new ();
+	gtk_progress_set_activity_mode (GTK_PROGRESS (progress_bar), TRUE);
+	gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), progress_bar, FALSE, TRUE, 0);
+
+	progress_bar_timeout_id = g_timeout_add (50, progress_bar_timeout_callback, progress_bar);
+	gtk_signal_connect (GTK_OBJECT (progress_bar), "destroy",
+			    GTK_SIGNAL_FUNC (progress_bar_destroy_callback),
+			    GINT_TO_POINTER (progress_bar_timeout_id));
+
+	gtk_widget_show_all (dialog);
+	return dialog;
+}
+
+static void
+cleanup_discovery (DiscoveryData *discovery_data)
+{
+	if (discovery_data->dialog != NULL)
+		gtk_widget_destroy (discovery_data->dialog);
+
+	g_free (discovery_data->user);
+	g_free (discovery_data->folder_name);
+	g_free (discovery_data);
+}
+
+static void
+storage_destroyed_callback (GtkObject *object,
+			    void *data)
+{
+	DiscoveryData *discovery_data;
+
+	discovery_data = (DiscoveryData *) data;
+	cleanup_discovery (discovery_data);
+
+	/* FIXME: Should we signal the user when this happens?  I.e. when the
+	   storage dies for some reason before the folder is discovered.  */
+}
+
+static void
+shared_folder_discovery_listener_callback (BonoboListener *listener,
+					   char *event_name,
+					   CORBA_any *value,
+					   CORBA_Environment *ev,
+					   void *data)
+{
+	GNOME_Evolution_Storage_DiscoverSharedFolderResult *result;
+	DiscoveryData *discovery_data;
+
+	discovery_data = (DiscoveryData *) data;
+	result = (GNOME_Evolution_Storage_DiscoverSharedFolderResult *) value->_value;
+
+	cleanup_discovery (discovery_data);
+
+	/* FIXME: The folder has been discovered; do something here, i.e. show
+	   the folder.  */
+
+	e_notice (NULL, GNOME_MESSAGE_BOX_INFO,
+		  "Found folder\n%s\n%s\n%s",
+		  result->storagePath, result->physicalURI, result->type);
+}
+
+static void
+discover_folder (EShell *shell,
+		 EShellView *parent,
+		 const char *user_email_address,
+		 const char *storage_name,
+		 const char *folder_name)
+{
+	EStorageSet *storage_set;
+	EStorage *storage;
+	GtkWidget *dialog;
+	BonoboListener *listener;
+	GNOME_Evolution_Storage corba_iface;
+	CORBA_Environment ev;
+	DiscoveryData *discovery_data;
+
+	discovery_data = NULL;
+	dialog = NULL;
+
+	CORBA_exception_init (&ev);
+
+	storage_set = e_shell_get_storage_set (shell);
+	if (storage_set == NULL)
+		goto error;
+
+	storage = e_storage_set_get_storage (storage_set, storage_name);
+	if (storage == NULL || ! E_IS_CORBA_STORAGE (storage))
+		goto error;
+
+	dialog = show_progress_dialog (shell, storage, user_email_address, folder_name);
+
+	discovery_data = g_new (DiscoveryData, 1);
+	discovery_data->dialog           = dialog;
+	discovery_data->storage          = storage;
+	discovery_data->user             = g_strdup (user_email_address);
+	discovery_data->folder_name      = g_strdup (folder_name);
+
+	gtk_signal_connect (GTK_OBJECT (storage), "destroy",
+			    GTK_SIGNAL_FUNC (storage_destroyed_callback), discovery_data);
+
+	listener = bonobo_listener_new (shared_folder_discovery_listener_callback, discovery_data);
+
+	corba_iface = e_corba_storage_get_corba_objref (E_CORBA_STORAGE (storage));
+	GNOME_Evolution_Storage_asyncDiscoverSharedFolder (corba_iface,
+							   user_email_address, folder_name,
+							   BONOBO_OBJREF (listener),
+							   &ev);
+	if (BONOBO_EX (&ev))
+		goto error;
+
+	CORBA_exception_free (&ev);
+
+	return;
+
+ error:
+	if (discovery_data != NULL)
+		cleanup_discovery (discovery_data);
+
+	/* FIXME: Be more verbose?  */
+	e_notice (NULL, GNOME_MESSAGE_BOX_ERROR,
+		  _("Cannot find open the specified shared folder."));
+
+	CORBA_exception_free (&ev);
+}
+
+
+void
+e_shell_show_shared_folder_picker_dialog (EShell *shell,
+					  EShellView *parent)
+{
+	char *user_email_address;
+	char *storage_name;
+	char *folder_name;
+
+	g_return_if_fail (E_IS_SHELL (shell));
+
+	if (! show_dialog (shell, parent, &user_email_address, &storage_name, &folder_name))
+		return;
+
+	discover_folder (shell, parent, user_email_address, storage_name, folder_name);
+
+	g_free (user_email_address);
+	g_free (storage_name);
+	g_free (folder_name);
+}
-- 
cgit