[evolution-patches] patch for 'Subscribe/Unsubscribe Folder' operation in exchange component
- From: shakti <shprasad novell com>
- To: evolution-patches lists ximian com
- Subject: [evolution-patches] patch for 'Subscribe/Unsubscribe Folder' operation in exchange component
- Date: Thu, 07 Jul 2005 11:48:38 +0530
Hi,
I am sending a patch for 'Subscribe/Unsubscribe Folder' of exchange
component. Please review it.
I have created a menu-item named 'Subscribe to other user's Folder' in
'Folder' menu. Also, if a folder is subscribed, the right click of that
folder will display a menu-item named 'Unsubscribe Folder' which will
remove the subscribed folder.
I have attached 2 patches 1) for e-d-s changes and 2) for changes in
evolution/plugins/.
Please have a look at the patches.
Thanks,
Shakti
? Makefile
? Makefile.in
? exchange-folder-subscription.c
? exchange-folder-subscription.h
? exchange-folder.c
? org-gnome-exchange-operations.eplug
? org-gnome-folder-subscription.xml
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/plugins/exchange-operations/Makefile.am,v
retrieving revision 1.3
diff -u -p -r1.3 Makefile.am
--- Makefile.am 1 Jul 2005 10:06:24 -0000 1.3
+++ Makefile.am 7 Jul 2005 05:49:22 -0000
@@ -10,7 +10,7 @@ INCLUDES = -I . \
@EVO_PLUGIN_RULE@
-plugin_DATA = org-gnome-exchange-operations.eplug
+plugin_DATA = org-gnome-exchange-operations.eplug org-gnome-folder-subscription.xml
plugin_LTLIBRARIES = liborg-gnome-exchange-operations.la
liborg_gnome_exchange_operations_la_SOURCES = \
@@ -22,7 +22,10 @@ liborg_gnome_exchange_operations_la_SOUR
exchange-contacts.c \
exchange-change-password.c \
exchange-change-password.h \
- exchange-account-setup.c
+ exchange-account-setup.c \
+ exchange-folder-subscription.c \
+ exchange-folder-subscription.h \
+ exchange-folder.c
liborg_gnome_exchange_operations_la_LIBADD = \
$(top_builddir)/e-util/libeutil.la \
@@ -39,5 +42,6 @@ glade_DATA = \
EXTRA_DIST = \
org-gnome-exchange-operations.eplug.in \
+ org-gnome-folder-subscription.xml \
$(glade_DATA)
Index: exchange-account-setup.c
===================================================================
RCS file: /cvs/gnome/evolution/plugins/exchange-operations/exchange-account-setup.c,v
retrieving revision 1.6
diff -u -p -r1.6 exchange-account-setup.c
--- exchange-account-setup.c 1 Jul 2005 10:06:24 -0000 1.6
+++ exchange-account-setup.c 7 Jul 2005 05:49:23 -0000
@@ -124,7 +124,7 @@ btn_chpass_clicked (GtkButton *button, g
}
new_password = exchange_get_new_password (old_password, TRUE);
g_print ("Current password is \"%s\"\n", old_password);
- exchange_account_set_password (account, old_password, new_password);
+ //exchange_account_set_password (account, old_password, new_password);
g_free (old_password);
g_free (new_password);
Index: org-gnome-exchange-operations.eplug.in
===================================================================
RCS file: /cvs/gnome/evolution/plugins/exchange-operations/org-gnome-exchange-operations.eplug.in,v
retrieving revision 1.1
diff -u -p -r1.1 org-gnome-exchange-operations.eplug.in
--- org-gnome-exchange-operations.eplug.in 13 Jun 2005 12:39:20 -0000 1.1
+++ org-gnome-exchange-operations.eplug.in 7 Jul 2005 05:49:25 -0000
@@ -8,6 +8,7 @@
name="Exchange Operations">
<author name="Sushma Rai" email="rsushma novell com"/>
<author name="Praveen Kumar" email="kpraveen novell com"/>
+ <author name="Shakti Sen" email="shprasad novell com"/>
<description>A plugin that handles a collection of Exchange account specific operations and features.</description>
<hook class="org.gnome.evolution.mail.config:1.0">
@@ -70,6 +71,33 @@
factory="e_exchange_contacts_pcontacts"/>
</group>
</hook>
+ <hook class="org.gnome.evolution.mail.bonobomenu:1.0">
+ <menu id="org.gnome.evolution.mail.browser" target="select">
+ <ui file="@PLUGINDIR@/org-gnome-folder-subscription.xml"/>
+ <item
+ type="item"
+ verb="FolderSubscription"
+ path="/commands/FolderSubscription"
+ enable="all"
+ activate="org_gnome_folder_subscription"/>
+ </menu>
+ </hook>
+ <hook class="org.gnome.evolution.calendar.popup:1.0">
+ <menu id="org.gnome.evolution.calendar.source.popup" target="source" factory="org_gnome_check_subscribed">
+ </menu>
+ </hook>
+ <hook class="org.gnome.evolution.calendar.popup:1.0">
+ <menu id="org.gnome.evolution.tasks.source.popup" target="source" factory="org_gnome_check_subscribed">
+ </menu>
+ </hook>
+ <hook class="org.gnome.evolution.addressbook.popup:1.0">
+ <menu id="org.gnome.evolution.addressbook.source.popup" target="source" factory="org_gnome_check_address_book_subscribed">
+ </menu>
+ </hook>
+ <hook class="org.gnome.evolution.mail.popup:1.0">
+ <menu id="org.gnome.evolution.mail.foldertree.popup" target="folder" factory = "org_gnome_check_inbox_subscribed">
+ </menu>
+ </hook>
</e-plugin>
</e-plugin-list>
--- /dev/null 2004-08-25 23:04:59.000000000 +0530
+++ exchange-folder-subscription.c 2005-07-07 11:12:01.177558482 +0530
@@ -0,0 +1,229 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Shakti Sen <shprasad novell com>
+ * Copyright (C) 2005 Novell, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <glade/glade-xml.h>
+#include <gtk/gtk.h>
+#include <exchange/e-folder.h>
+#include <exchange-account.h>
+#include <exchange-hierarchy.h>
+#include "exchange-hierarchy-foreign.h"
+#include <exchange/e2k-types.h>
+#include <exchange/exchange-types.h>
+#include <e2k-propnames.h>
+#include <libedataserver/e-xml-hash-utils.h>
+#include <libedataserverui/e-name-selector.h>
+#include "exchange-config-listener.h"
+
+
+static void
+user_response (ENameSelectorDialog *name_selector_dialog, gint response, gpointer data)
+{
+ gtk_widget_hide (GTK_WIDGET (name_selector_dialog));
+}
+
+static void
+user_clicked (GtkWidget *button, ENameSelector *name_selector)
+{
+ ENameSelectorDialog *name_selector_dialog;
+
+ name_selector_dialog = e_name_selector_peek_dialog (name_selector);
+ gtk_window_set_modal (GTK_WINDOW (name_selector_dialog), TRUE);
+ gtk_widget_show (GTK_WIDGET (name_selector_dialog));
+}
+
+
+static GtkWidget *
+setup_name_selector (GladeXML *glade_xml, ENameSelector **name_selector_ret)
+{
+ ENameSelector *name_selector;
+ ENameSelectorModel *name_selector_model;
+ ENameSelectorDialog *name_selector_dialog;
+ GtkWidget *placeholder;
+ GtkWidget *widget;
+ GtkWidget *button;
+
+ placeholder = glade_xml_get_widget (glade_xml, "user-picker-placeholder");
+ g_assert (GTK_IS_CONTAINER (placeholder));
+
+ name_selector = e_name_selector_new ();
+
+ name_selector_model = e_name_selector_peek_model (name_selector);
+ /* FIXME Limit to one user */
+ e_name_selector_model_add_section (name_selector_model, "User", "User", NULL);
+
+ /* Listen for responses whenever the dialog is shown */
+ name_selector_dialog = e_name_selector_peek_dialog (name_selector);
+ g_signal_connect (name_selector_dialog, "response",
+ G_CALLBACK (user_response), name_selector);
+
+ widget = GTK_WIDGET (e_name_selector_peek_section_entry (name_selector, "User"));
+ gtk_widget_show (widget);
+
+ button = glade_xml_get_widget (glade_xml, "button-user");
+ g_signal_connect (button, "clicked", G_CALLBACK (user_clicked), name_selector);
+ gtk_box_pack_start (GTK_BOX (placeholder), widget, TRUE, TRUE, 6);
+ *name_selector_ret = name_selector;
+
+ return widget;
+}
+
+static void
+setup_folder_name_combo (GladeXML *glade_xml)
+{
+ GtkWidget *combo;
+ GList *string_list;
+ char *strings[] = {
+ "Calendar",
+ "Inbox",
+ "Contacts",
+ "Tasks",
+ 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 void
+folder_name_entry_changed_callback (GtkEditable *editable,
+ void *data)
+{
+ GtkDialog *dialog = GTK_DIALOG (data);
+ const char *folder_name_text = gtk_entry_get_text (GTK_ENTRY (editable));
+
+ if (*folder_name_text == '\0')
+ gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, FALSE);
+ else
+ gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, TRUE);
+}
+
+static void
+setup_server_option_menu (GladeXML *glade_xml, gchar *mail_account)
+{
+ GtkWidget *widget;
+ GtkWidget *menu;
+ GtkWidget *menu_item;
+
+ widget = glade_xml_get_widget (glade_xml, "server-option-menu");
+ g_return_if_fail (GTK_IS_OPTION_MENU (widget));
+
+ menu = gtk_menu_new ();
+ gtk_widget_show (menu);
+
+ menu_item = gtk_menu_item_new_with_label (mail_account);
+
+ gtk_widget_show (menu_item);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
+
+
+ gtk_option_menu_set_menu (GTK_OPTION_MENU (widget), menu);
+
+ /* FIXME: Default to the current storage in the shell view. */
+}
+
+
+gboolean
+create_folder_subscription_dialog (gchar *mail_account, gchar **user_email_address_ret, gchar **folder_name_ret)
+{
+ ENameSelector *name_selector;
+ GladeXML *glade_xml;
+ GtkWidget *dialog;
+ GtkWidget *name_selector_widget;
+ GtkWidget *folder_name_entry;
+ char *user_email_address = NULL;
+ int response;
+ EDestinationStore *destination_store;
+ GList *destinations;
+ EDestination *destination;
+ gchar *temp;
+
+
+ glade_xml = glade_xml_new (CONNECTOR_GLADEDIR "/e-foreign-folder-dialog.glade",
+ NULL, NULL);
+ g_return_val_if_fail (glade_xml != NULL, FALSE);
+
+ dialog = glade_xml_get_widget (glade_xml, "dialog");
+ g_return_val_if_fail (dialog != NULL, FALSE);
+
+ name_selector_widget = setup_name_selector (glade_xml, &name_selector);
+ setup_server_option_menu (glade_xml, mail_account);
+ setup_folder_name_combo (glade_xml);
+ folder_name_entry = glade_xml_get_widget (glade_xml, "folder-name-entry");
+
+ /* Connect the callback to set the OK button insensitive when there is
+ no text in the folder_name_entry. Notice that we put a value there
+ by default so the OK button is sensitive by default. */
+ g_signal_connect (folder_name_entry, "changed",
+ G_CALLBACK (folder_name_entry_changed_callback), dialog);
+
+ while (TRUE) {
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ if (response == GTK_RESPONSE_CANCEL) {
+ gtk_widget_destroy (dialog);
+ g_object_unref (name_selector);
+ return FALSE;
+ }
+ destination_store = e_name_selector_entry_peek_destination_store (E_NAME_SELECTOR_ENTRY (GTK_ENTRY (name_selector_widget)));
+ destinations = e_destination_store_list_destinations (destination_store);
+ if (!destinations) {
+ gtk_widget_destroy (dialog);
+ g_object_unref (name_selector);
+ return FALSE;
+ }
+ destination = destinations->data;
+ user_email_address = g_strdup (e_destination_get_email (destination));
+ g_list_free (destinations);
+
+ if (user_email_address != NULL && *user_email_address != '\0')
+ break;
+
+ /* It would be nice to insensitivize the OK button appropriately instead of doing this, but unfortunately we can't do this for the
+ Bonobo control. */
+ e_notice (dialog, GTK_MESSAGE_ERROR, ("Please select a user."));
+
+
+ }
+ gtk_widget_show_all (dialog);
+
+ if (user_email_address)
+ *user_email_address_ret = user_email_address;
+ *folder_name_ret = g_strdup (gtk_entry_get_text (GTK_ENTRY (folder_name_entry)));
+
+ gtk_widget_destroy (dialog);
+ g_object_unref (name_selector);
+ return TRUE;
+
+}
+
--- /dev/null 2004-08-25 23:04:59.000000000 +0530
+++ exchange-folder.c 2005-07-07 11:18:57.066971802 +0530
@@ -0,0 +1,417 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Shakti Sen <shprasad novell com>
+ * Copyright (C) 2005 Novell, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gtk/gtkdialog.h>
+#include <gconf/gconf-client.h>
+#include <exchange-hierarchy.h>
+#include <calendar/gui/e-cal-popup.h>
+#include <mail/em-popup.h>
+#include <mail/em-menu.h>
+#include "exchange-operations.h"
+#include "addressbook/gui/widgets/eab-popup.h"
+
+
+void org_gnome_folder_subscription (EPlugin *ep, EMMenuTargetSelect *target);
+void org_gnome_check_subscribed (EPlugin *ep, ECalPopupTargetSource *target);
+void org_gnome_folder_unsubscribe (EPlugin *ep, EPopupItem *p, void *data);
+void org_gnome_check_address_book_subscribed (EPlugin *ep, EABPopupTargetSource *target);
+void org_gnome_folder_ab_unsubscribe (EPlugin *ep, EPopupItem *p, void *data);
+void org_gnome_check_inbox_subscribed (EPlugin *ep, EMPopupTargetFolder *target);
+void org_gnome_folder_inbox_unsubscribe (EPlugin *ep, EPopupItem *p, void *data);
+void popup_free (EPopup *ep, GSList *items, void *data);
+void popup_inbox_free (EPopup *ep, GSList *items, void *data);
+void popup_ab_free (EPopup *ep, GSList *items, void *data);
+
+#define CONF_KEY_SELECTED_CAL_SOURCES "/apps/evolution/calendar/display/selected_calendars"
+
+
+static EPopupItem popup_inbox_items[] = {
+ { E_POPUP_ITEM, "29.inbox_unsubscribe", N_("Unsubscribe Folder..."), org_gnome_folder_inbox_unsubscribe, NULL, "stock_new-dir", 0, EM_POPUP_FOLDER_INFERIORS }
+};
+
+void
+popup_inbox_free (EPopup *ep, GSList *items, void *data)
+{
+ g_slist_free (items);
+}
+
+void
+org_gnome_folder_inbox_unsubscribe (EPlugin *ep, EPopupItem *p, void *data)
+{
+ // To be done:
+}
+
+void
+org_gnome_check_inbox_subscribed (EPlugin *ep, EMPopupTargetFolder *target)
+{
+ GSList *menus = NULL;
+ int i = 0;
+ GSList *accounts, *acc;
+ ExchangeAccount *account = NULL;
+ gchar *path = NULL;
+ gchar *sub_folder = NULL;
+
+ accounts = exchange_config_listener_get_accounts (exchange_global_config_listener);
+ for (acc = accounts; acc; acc = acc->next) {
+ account = acc->data;
+ }
+
+ path = g_strdup_printf (target->uri + strlen ("exchange://") + strlen (account->account_filename));
+ sub_folder = strchr (path, '@');
+
+ if (!sub_folder)
+ return;
+
+ for (i = 0; i < sizeof (popup_inbox_items) / sizeof (popup_inbox_items[0]); i++)
+ menus = g_slist_prepend (menus, &popup_inbox_items[i]);
+
+ e_popup_add_items (target->target.popup, menus, NULL, popup_inbox_free, target);
+ g_free (path);
+}
+
+static EPopupItem popup_items[] = {
+ { E_POPUP_ITEM, "29.calendar_unsubscribe", N_("Unsubscribe Folder..."), org_gnome_folder_unsubscribe, NULL, "stock_new-dir", 0, EM_POPUP_FOLDER_INFERIORS }
+};
+
+void
+popup_free (EPopup *ep, GSList *items, void *data)
+{
+ g_slist_free (items);
+}
+
+static EPopupItem popup_ab_items[] = {
+ { E_POPUP_ITEM, "29.address_book_unsubscribe", N_("Unsubscribe Folder..."), org_gnome_folder_ab_unsubscribe, NULL, "stock_new-dir", 0, EM_POPUP_FOLDER_INFERIORS }
+};
+
+void
+popup_ab_free (EPopup *ep, GSList *items, void *data)
+{
+ g_slist_free (items);
+}
+
+void
+org_gnome_check_address_book_subscribed (EPlugin *ep, EABPopupTargetSource *target)
+{
+ GSList *menus = NULL;
+ int i = 0;
+ ESource *source = NULL;
+ gchar *uri = NULL;
+ gchar *path = NULL;
+ char *sub_folder = NULL;
+ GSList *accounts, *acc;
+ ExchangeAccount *account = NULL;
+
+ accounts = exchange_config_listener_get_accounts (exchange_global_config_listener);
+ for (acc = accounts; acc; acc = acc->next) {
+ account = acc->data;
+ }
+
+ source = e_source_selector_peek_primary_selection (target->selector);
+ uri = e_source_get_uri (source);
+ path = g_strdup_printf (uri + strlen ("exchange://") + strlen (account->account_filename));
+ sub_folder = strchr (path, '@');
+
+ if (!sub_folder)
+ return;
+
+ for (i = 0; i < sizeof (popup_ab_items) / sizeof (popup_ab_items[0]); i++)
+ menus = g_slist_prepend (menus, &popup_ab_items[i]);
+
+ e_popup_add_items (target->target.popup, menus, NULL, popup_ab_free, target);
+ g_free (path);
+
+}
+
+void
+org_gnome_check_subscribed (EPlugin *ep, ECalPopupTargetSource *target)
+{
+ GSList *menus = NULL;
+ int i = 0;
+ ESource *source = NULL;
+ gchar *ruri = NULL;
+ gchar *path = NULL;
+ char *sub_folder = NULL;
+ GSList *accounts, *acc;
+ ExchangeAccount *account = NULL;
+
+ accounts = exchange_config_listener_get_accounts (exchange_global_config_listener);
+ for (acc = accounts; acc; acc = acc->next) {
+ account = acc->data;
+ }
+
+ source = e_source_selector_peek_primary_selection (target->selector);
+ ruri = e_source_peek_relative_uri (source);
+ path = g_strdup_printf (ruri + strlen (account->account_filename));
+ sub_folder = strchr (path, '@');
+
+ if (!sub_folder)
+ return;
+
+ for (i = 0; i < sizeof (popup_items) / sizeof (popup_items[0]); i++)
+ menus = g_slist_prepend (menus, &popup_items[i]);
+
+ e_popup_add_items (target->target.popup, menus, NULL, popup_free, target);
+ g_free (path);
+}
+
+static void
+unsubscribe_dialog_ab_response (GtkDialog *dialog, int response, gpointer data)
+{
+
+ if (response == GTK_RESPONSE_OK) {
+ GSList *accounts, *acc;
+ ExchangeAccount *account = NULL;
+ gchar *path = NULL;
+ gchar *uri = NULL;
+ const char *source_uid = NULL;
+ GConfClient *client;
+ ESourceGroup *source_group = NULL;
+ ESource *source = NULL;
+ EABPopupTargetSource *target = data;
+
+ client = gconf_client_get_default ();
+
+ accounts = exchange_config_listener_get_accounts (exchange_global_config_listener);
+ for (acc = accounts; acc; acc = acc->next) {
+ account = acc->data;
+ }
+ source = e_source_selector_peek_primary_selection (target->selector);
+ uri = e_source_get_uri (source);
+ path = g_strdup_printf (uri + strlen ("exchange://") + strlen (account->account_filename));
+ source_uid = e_source_peek_uid (source);
+
+ exchange_account_remove_shared_folder (account, path);
+
+ source_group = e_source_peek_group (source);
+ e_source_group_remove_source_by_uid (source_group, source_uid);
+ g_free (path);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ }
+ if (response == GTK_RESPONSE_CANCEL)
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ if (response == GTK_RESPONSE_DELETE_EVENT)
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+unsubscribe_dialog_response (GtkDialog *dialog, int response, gpointer data)
+{
+
+ if (response == GTK_RESPONSE_OK) {
+ GSList *accounts, *acc;
+ GSList *ids, *node_to_be_deleted;
+ ExchangeAccount *account = NULL;
+ gchar *path = NULL;
+ gchar *ruri = NULL;
+ const char *source_uid = NULL;
+ GConfClient *client;
+ ESourceGroup *source_group = NULL;
+ ESource *source = NULL;
+ ECalPopupTargetSource *target = data;
+
+ client = gconf_client_get_default ();
+
+ accounts = exchange_config_listener_get_accounts (exchange_global_config_listener);
+ for (acc = accounts; acc; acc = acc->next) {
+ account = acc->data;
+ }
+ source = e_source_selector_peek_primary_selection (target->selector);
+ ruri = e_source_peek_relative_uri (source);
+ source_uid = e_source_peek_uid (source);
+
+ path = g_strdup_printf (ruri + strlen (account->account_filename));
+ exchange_account_remove_shared_folder (account, path);
+ ids = gconf_client_get_list (client,
+ CONF_KEY_SELECTED_CAL_SOURCES,
+ GCONF_VALUE_STRING, NULL);
+ if (ids) {
+ node_to_be_deleted = g_slist_find_custom (
+ ids,
+ source_uid,
+ (GCompareFunc) strcmp);
+ if (node_to_be_deleted) {
+ g_free (node_to_be_deleted->data);
+ ids = g_slist_delete_link (ids,
+ node_to_be_deleted);
+ gconf_client_set_list (client,
+ CONF_KEY_SELECTED_CAL_SOURCES,
+ GCONF_VALUE_STRING, ids, NULL);
+ }
+ g_slist_foreach (ids, (GFunc) g_free, NULL);
+ g_slist_free (ids);
+ }
+
+ source_group = e_source_peek_group (source);
+ e_source_group_remove_source_by_uid (source_group, source_uid);
+ g_free (path);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ }
+ if (response == GTK_RESPONSE_CANCEL)
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ if (response == GTK_RESPONSE_DELETE_EVENT)
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+void
+org_gnome_folder_ab_unsubscribe (EPlugin *ep, EPopupItem *p, void *data)
+{
+ GtkWidget *dialog = NULL;
+ EABPopupTargetSource *target = data;
+ ESource *source = NULL;
+ GSList *accounts, *acc;
+ ExchangeAccount *account = NULL;
+ gchar *title = NULL;
+ gchar *displayed_folder_name = NULL;
+ gint response;
+
+ accounts = exchange_config_listener_get_accounts (exchange_global_config_listener);
+ for (acc = accounts; acc; acc = acc->next) {
+ account = acc->data;
+ }
+
+ source = e_source_selector_peek_primary_selection (target->selector);
+ displayed_folder_name = e_source_peek_name (source);
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE,
+ _("Really unsubscribe from folder \"%s\"?"),
+ displayed_folder_name);
+
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_OK);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 6);
+
+ title = g_strdup_printf (_("Unsubscribe from \"%s\""), displayed_folder_name);
+ gtk_window_set_title (GTK_WINDOW (dialog), title);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ g_free (title);
+ g_free (displayed_folder_name);
+
+ gtk_widget_show (dialog);
+ unsubscribe_dialog_ab_response (dialog, response, data);
+}
+void
+org_gnome_folder_unsubscribe (EPlugin *ep, EPopupItem *p, void *data)
+{
+ GtkWidget *dialog = NULL;
+ ECalPopupTargetSource *target = data;
+ ESource *source = NULL;
+ GSList *accounts, *acc;
+ ExchangeAccount *account = NULL;
+ gchar *title = NULL;
+ gchar *displayed_folder_name = NULL;
+ gint response;
+
+ accounts = exchange_config_listener_get_accounts (exchange_global_config_listener);
+ for (acc = accounts; acc; acc = acc->next) {
+ account = acc->data;
+ }
+
+ source = e_source_selector_peek_primary_selection (target->selector);
+ displayed_folder_name = e_source_peek_name (source);
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE,
+ _("Really unsubscribe from folder \"%s\"?"),
+ displayed_folder_name);
+
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_REMOVE, GTK_RESPONSE_OK);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 6);
+
+ title = g_strdup_printf (_("Unsubscribe from \"%s\""), displayed_folder_name);
+ gtk_window_set_title (GTK_WINDOW (dialog), title);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ g_free (title);
+ g_free (displayed_folder_name);
+
+ gtk_widget_show (dialog);
+ unsubscribe_dialog_response (dialog, response, data);
+}
+
+
+void
+org_gnome_folder_subscription (EPlugin *ep, EMMenuTargetSelect *target)
+{
+ GSList *accounts, *acc;
+ ExchangeAccount *account = NULL;
+ EFolder *folder = NULL;
+ ExchangeHierarchy *hier;
+ ExchangeAccountFolderResult result;
+ gchar *folder_display_name = NULL;
+ gchar *folder_type = NULL;
+ gchar *physical_uri = NULL;
+ gchar *user_email_address = NULL, *storage_name, *folder_name = NULL;
+
+ accounts = exchange_config_listener_get_accounts (exchange_global_config_listener);
+ for (acc = accounts; acc; acc = acc->next) {
+ account = acc->data;
+ }
+
+ create_folder_subscription_dialog (account->account_name, &user_email_address, &folder_name);
+
+ if (user_email_address && folder_name)
+ result = exchange_account_discover_shared_folder (account, user_email_address, folder_name, &folder);
+
+ if (!folder) {
+ return;
+ }
+
+ hier = e_folder_exchange_get_hierarchy (folder);
+ folder_display_name = g_strdup_printf ("%s's %s", hier->owner_name, folder_name);
+ folder_type = e_folder_get_type_string (folder);
+ physical_uri = e_folder_get_physical_uri (folder);
+ if (!(strcmp (folder_type, "calendar")) ||
+ !(strcmp (folder_type, "calendar/public"))) {
+ add_folder_esource (account, EXCHANGE_CALENDAR_FOLDER, folder_display_name, physical_uri);
+ }
+ else if (!(strcmp (folder_type, "tasks")) ||
+ !(strcmp (folder_type, "tasks/public"))) {
+ add_folder_esource (account, EXCHANGE_TASKS_FOLDER, folder_display_name, physical_uri);
+ }
+ else if (!(strcmp (folder_type, "contacts")) ||
+ !(strcmp (folder_type, "contacts/public")) ||
+ !(strcmp (folder_type, "contacts/ldap"))) {
+ add_folder_esource (account, EXCHANGE_CONTACTS_FOLDER, folder_display_name, physical_uri);
+}
+
+g_free (folder_display_name);
+exchange_account_open_folder (account, g_strdup_printf ("/%s", user_email_address));
+}
+
--- /dev/null 2004-08-25 23:04:59.000000000 +0530
+++ org-gnome-folder-subscription.xml 2005-07-05 17:59:30.150635192 +0530
@@ -0,0 +1,17 @@
+<Root>
+ <commands>
+ <cmd name="FolderSubscription" _label="Subscribe to Other User's Folder"
+ _tip="Subscribe to Other User's Folder"/>
+ </commands>
+
+ <menu>
+ <placeholder name="FolderPlaceholder">
+ <submenu name="Folder">
+ <placeholder name="MessagesInFolder">
+ <separator f="" name="emaillist5"/>
+ <menuitem name="FolderSubscription" verb=""/>
+ </placeholder>
+ </submenu>
+ </placeholder>
+ </menu>
+</Root>
? Makefile
? Makefile.am-bak
? Makefile.in
? e-shell-marshal.c
? e-shell-marshal.h
? exchange-hierarchy-foreign.c
? exchange-hierarchy-foreign.h
? libexchange-storage-1.2.pc
? libexchange-storage.pc
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/exchange/storage/Makefile.am,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile.am
--- Makefile.am 22 Jun 2005 11:35:09 -0000 1.6
+++ Makefile.am 7 Jul 2005 06:08:44 -0000
@@ -38,6 +38,8 @@ libexchange_storage_1_2_la_SOURCES =
exchange-folder-size.h \
exchange-hierarchy-favorites.c \
exchange-hierarchy-favorites.h \
+ exchange-hierarchy-foreign.c \
+ exchange-hierarchy-foreign.h \
exchange-hierarchy-gal.c \
exchange-hierarchy-gal.h \
exchange-hierarchy-somedav.c \
@@ -90,6 +92,7 @@ libexchange_storageinclude_HEADERS =
exchange-hierarchy.h \
exchange-hierarchy-somedav.h \
exchange-hierarchy-webdav.h \
+ exchange-hierarchy-foreign.h \
exchange-oof.h \
exchange-types.h
Index: exchange-account.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/servers/exchange/storage/exchange-account.c,v
retrieving revision 1.3
diff -u -p -r1.3 exchange-account.c
--- exchange-account.c 28 Jun 2005 08:27:14 -0000 1.3
+++ exchange-account.c 7 Jul 2005 06:08:45 -0000
@@ -31,6 +31,7 @@
#include "exchange-hierarchy-webdav.h"
#include "exchange-hierarchy-favorites.h"
// SURF :#include "exchange-hierarchy-foreign.h"
+#include "exchange-hierarchy-foreign.h"
#include "exchange-hierarchy-gal.h"
//#include "exchange-constants.h"
#include "e-folder-exchange.h"
@@ -592,14 +593,11 @@ get_hierarchy_for (ExchangeAccount *acco
internal_uri_prefix = exchange_account_get_foreign_uri (account, entry,
NULL);
-#if 0
-SURF : This should move to plugins.
hier = exchange_hierarchy_foreign_new (account, hierarchy_name,
physical_uri_prefix,
internal_uri_prefix,
entry->display_name,
entry->email, source);
-#endif
g_free (hierarchy_name);
g_free (physical_uri_prefix);
g_free (internal_uri_prefix);
@@ -635,8 +633,7 @@ exchange_account_discover_shared_folder
hier = g_hash_table_lookup (account->priv->foreign_hierarchies, email);
if (hier) {
g_free (email);
- // SURF : return exchange_hierarchy_foreign_add_folder (hier, folder_name, folder);
- return EXCHANGE_ACCOUNT_FOLDER_OK;
+ return exchange_hierarchy_foreign_add_folder (hier, folder_name, folder);
}
dd.user = user;
@@ -669,8 +666,7 @@ exchange_account_discover_shared_folder
}
hier = get_hierarchy_for (account, entry);
- // SURF : return exchange_hierarchy_foreign_add_folder (hier, folder_name, folder);
- return EXCHANGE_ACCOUNT_FOLDER_OK;
+ return exchange_hierarchy_foreign_add_folder (hier, folder_name, folder);
}
void
@@ -719,11 +715,8 @@ exchange_account_remove_shared_folder (E
if (!get_folder (account, path, &folder, &hier))
return EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST;
-#if 0
-SURF :
if (!EXCHANGE_IS_HIERARCHY_FOREIGN (hier))
return EXCHANGE_ACCOUNT_FOLDER_UNSUPPORTED_OPERATION;
-#endif
return exchange_hierarchy_remove_folder (hier, folder);
}
@@ -1294,8 +1287,6 @@ setup_account_hierarchies (ExchangeAccou
g_free (phys_uri_prefix);
/* Other users' folders */
-#if 0
-SURF :
d = opendir (account->storage_dir);
if (d) {
while ((dent = readdir (d))) {
@@ -1312,7 +1303,6 @@ SURF :
}
closedir (d);
}
-#endif
/* Scan the personal and favorite folders so we can resolve references
* to the Calendar, Contacts, etc even if the tree isn't
--- /dev/null 2004-08-25 23:04:59.000000000 +0530
+++ exchange-hierarchy-foreign.c 2005-07-07 11:37:19.534655012 +0530
@@ -0,0 +1,592 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* Copyright (C) 2002-2004 Novell, 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.
+ */
+
+/* ExchangeHierarchyForeign: class for a hierarchy consisting of a
+ * selected subset of folders from another user's mailbox.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "exchange-hierarchy-foreign.h"
+#include "exchange-account.h"
+#include "e-folder-exchange.h"
+#include "e2k-propnames.h"
+#include "e2k-uri.h"
+#include "e2k-utils.h"
+//#include "exchange-config-listener.h"
+#include "exchange-types.h"
+#include "e2k-types.h"
+
+#include <libedataserver/e-xml-hash-utils.h>
+#include <libedataserver/e-source-list.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+struct _ExchangeHierarchyForeignPrivate {
+ GMutex *hide_private_lock;
+ gboolean checked_hide_private;
+};
+
+extern const char *exchange_localfreebusy_path;
+
+#define PARENT_TYPE EXCHANGE_TYPE_HIERARCHY_SOMEDAV
+static ExchangeHierarchySomeDAVClass *parent_class = NULL;
+
+static GPtrArray *get_hrefs (ExchangeHierarchySomeDAV *hsd);
+static ExchangeAccountFolderResult create_folder (ExchangeHierarchy *hier,
+ EFolder *parent,
+ const char *name,
+ const char *type);
+static ExchangeAccountFolderResult remove_folder (ExchangeHierarchy *hier,
+ EFolder *folder);
+static ExchangeAccountFolderResult scan_subtree (ExchangeHierarchy *hier,
+ EFolder *folder,
+ gboolean offline);
+static void finalize (GObject *object);
+
+static void
+class_init (GObjectClass *object_class)
+{
+ ExchangeHierarchyClass *hierarchy_class =
+ EXCHANGE_HIERARCHY_CLASS (object_class);
+ ExchangeHierarchySomeDAVClass *somedav_class =
+ EXCHANGE_HIERARCHY_SOMEDAV_CLASS (object_class);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ /* virtual method override */
+ object_class->finalize = finalize;
+
+ hierarchy_class->create_folder = create_folder;
+ hierarchy_class->remove_folder = remove_folder;
+ hierarchy_class->scan_subtree = scan_subtree;
+
+ somedav_class->get_hrefs = get_hrefs;
+}
+
+static void
+init (GObject *object)
+{
+ ExchangeHierarchyForeign *hfor = EXCHANGE_HIERARCHY_FOREIGN (object);
+ ExchangeHierarchy *hier = EXCHANGE_HIERARCHY (object);
+
+ hfor->priv = g_new0 (ExchangeHierarchyForeignPrivate, 1);
+ hfor->priv->hide_private_lock = g_mutex_new ();
+ hier->hide_private_items = TRUE;
+}
+
+static void
+finalize (GObject *object)
+{
+ ExchangeHierarchyForeign *hfor = EXCHANGE_HIERARCHY_FOREIGN (object);
+
+ g_mutex_free (hfor->priv->hide_private_lock);
+ g_free (hfor->priv);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+E2K_MAKE_TYPE (exchange_hierarchy_foreign, ExchangeHierarchyForeign, class_init, init, PARENT_TYPE)
+
+static const char *privacy_props[] = {
+ PR_DELEGATES_ENTRYIDS,
+ PR_DELEGATES_SEE_PRIVATE,
+};
+static const int n_privacy_props = sizeof (privacy_props) / sizeof (privacy_props[0]);
+
+static void
+check_hide_private (ExchangeHierarchy *hier)
+{
+ ExchangeHierarchyForeign *hfor = EXCHANGE_HIERARCHY_FOREIGN (hier);
+ E2kContext *ctx;
+ E2kHTTPStatus status;
+ E2kResult *results;
+ int nresults, i;
+ GPtrArray *entryids, *privflags;
+ GByteArray *entryid;
+ const char *my_dn, *delegate_dn;
+ char *uri;
+
+ g_mutex_lock (hfor->priv->hide_private_lock);
+
+ if (hfor->priv->checked_hide_private) {
+ g_mutex_unlock (hfor->priv->hide_private_lock);
+ return;
+ }
+
+ uri = e2k_uri_concat (hier->account->home_uri,
+ "NON_IPM_SUBTREE/Freebusy%20Data/LocalFreebusy.EML");
+ ctx = exchange_account_get_context (hier->account);
+
+ status = e2k_context_propfind (ctx, NULL, uri,
+ privacy_props, n_privacy_props,
+ &results, &nresults);
+ g_free (uri);
+
+ hfor->priv->checked_hide_private = TRUE;
+
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status) || nresults == 0) {
+ g_mutex_unlock (hfor->priv->hide_private_lock);
+ return;
+ }
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (results[0].status) ||
+ !results[0].props || nresults > 1) {
+ e2k_results_free (results, nresults);
+ g_mutex_unlock (hfor->priv->hide_private_lock);
+ return;
+ }
+
+ entryids = e2k_properties_get_prop (results[0].props,
+ PR_DELEGATES_ENTRYIDS);
+ privflags = e2k_properties_get_prop (results[0].props,
+ PR_DELEGATES_SEE_PRIVATE);
+ if (entryids && privflags) {
+ my_dn = hier->account->legacy_exchange_dn;
+ for (i = 0; i < entryids->len && i < privflags->len; i++) {
+ entryid = entryids->pdata[i];
+ delegate_dn = e2k_entryid_to_dn (entryid);
+
+ if (delegate_dn &&
+ !g_ascii_strcasecmp (delegate_dn, my_dn) &&
+ privflags->pdata[i] &&
+ atoi (privflags->pdata[i]))
+ hier->hide_private_items = FALSE;
+ break;
+ }
+ }
+
+ e2k_results_free (results, nresults);
+ g_mutex_unlock (hfor->priv->hide_private_lock);
+}
+
+static void
+remove_all_cb (ExchangeHierarchy *hier, EFolder *folder, gpointer user_data)
+{
+ exchange_hierarchy_removed_folder (hier, folder);
+}
+
+static void
+hierarchy_foreign_cleanup (ExchangeHierarchy *hier)
+{
+ char *mf_path;
+
+ exchange_hierarchy_webdav_offline_scan_subtree (hier, remove_all_cb,
+ NULL);
+
+ mf_path = e_folder_exchange_get_storage_file (hier->toplevel, "hierarchy.xml");
+ unlink (mf_path);
+ g_free (mf_path);
+
+ exchange_hierarchy_removed_folder (hier, hier->toplevel);
+}
+
+static const char *folder_props[] = {
+ E2K_PR_EXCHANGE_FOLDER_CLASS,
+ E2K_PR_HTTPMAIL_UNREAD_COUNT,
+ E2K_PR_DAV_DISPLAY_NAME,
+ PR_ACCESS
+};
+static const int n_folder_props = sizeof (folder_props) / sizeof (folder_props[0]);
+
+static ExchangeAccountFolderResult
+find_folder (ExchangeHierarchy *hier, const char *uri, EFolder **folder_out)
+{
+ ExchangeHierarchyWebDAV *hwd = EXCHANGE_HIERARCHY_WEBDAV (hier);
+ E2kContext *ctx = exchange_account_get_context (hier->account);
+ E2kHTTPStatus status;
+ E2kResult *results;
+ int nresults;
+ EFolder *folder;
+ const char *access;
+ int offline;
+
+ status = e2k_context_propfind (ctx, NULL, uri,
+ folder_props, n_folder_props,
+ &results, &nresults);
+ if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status))
+ return exchange_hierarchy_webdav_status_to_folder_result (status);
+ if (nresults == 0)
+ return EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST;
+
+ access = e2k_properties_get_prop (results[0].props, PR_ACCESS);
+ if (!access || !atoi (access))
+ return EXCHANGE_ACCOUNT_FOLDER_PERMISSION_DENIED;
+
+ folder = exchange_hierarchy_webdav_parse_folder (hwd, hier->toplevel,
+ &results[0]);
+ e2k_results_free (results, nresults);
+
+ if (!folder)
+ return EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST;
+
+ exchange_hierarchy_new_folder (hier, folder);
+
+ if (folder_out)
+ *folder_out = folder;
+ else
+ g_object_unref (folder);
+ return EXCHANGE_ACCOUNT_FOLDER_OK;
+}
+
+static struct {
+ const char *name, *prop;
+} std_folders[] = {
+ { N_("Calendar"), E2K_PR_STD_FOLDER_CALENDAR },
+ { N_("Contacts"), E2K_PR_STD_FOLDER_CONTACTS },
+ { N_("Deleted Items"), E2K_PR_STD_FOLDER_DELETED_ITEMS },
+ { N_("Drafts"), E2K_PR_STD_FOLDER_DRAFTS },
+ { N_("Inbox"), E2K_PR_STD_FOLDER_INBOX },
+ { N_("Journal"), E2K_PR_STD_FOLDER_JOURNAL },
+ { N_("Notes"), E2K_PR_STD_FOLDER_NOTES },
+ { N_("Outbox"), E2K_PR_STD_FOLDER_OUTBOX },
+ { N_("Sent Items"), E2K_PR_STD_FOLDER_SENT_ITEMS },
+ { N_("Tasks"), E2K_PR_STD_FOLDER_TASKS }
+};
+const static int n_std_folders = sizeof (std_folders) / sizeof (std_folders[0]);
+static ExchangeAccountFolderResult
+create_internal (ExchangeHierarchy *hier, EFolder *parent,
+ const char *name, const char *type, EFolder **folder_out)
+{
+ ExchangeAccountFolderResult result;
+ char *literal_uri = NULL, *standard_uri = NULL;
+ const char *home_uri;
+ int i;
+ int offline;
+
+ /* For now, no nesting */
+ if (parent != hier->toplevel || strchr (name + 1, '/'))
+ return EXCHANGE_ACCOUNT_FOLDER_GENERIC_ERROR;
+
+ check_hide_private (hier);
+
+ home_uri = e_folder_exchange_get_internal_uri (hier->toplevel);
+ literal_uri = e2k_uri_concat (home_uri, name);
+ if (exchange_account_get_folder (hier->account, literal_uri)) {
+ g_free (literal_uri);
+ if (exchange_hierarchy_is_empty (hier))
+ hierarchy_foreign_cleanup (hier);
+ return EXCHANGE_ACCOUNT_FOLDER_ALREADY_EXISTS;
+ }
+
+ for (i = 0; i < n_std_folders; i++) {
+ if (g_ascii_strcasecmp (std_folders[i].name, name) != 0 &&
+ g_utf8_collate (_(std_folders[i].name), name) != 0)
+ continue;
+
+ standard_uri = exchange_account_get_standard_uri_for (
+ hier->account, home_uri, std_folders[i].prop);
+ if (!standard_uri)
+ break;
+ if (!strcmp (literal_uri, standard_uri)) {
+ g_free (standard_uri);
+ standard_uri = NULL;
+ break;
+ }
+
+ if (exchange_account_get_folder (hier->account, standard_uri)) {
+ g_free (standard_uri);
+ g_free (literal_uri);
+ if (exchange_hierarchy_is_empty (hier))
+ hierarchy_foreign_cleanup (hier);
+ return EXCHANGE_ACCOUNT_FOLDER_ALREADY_EXISTS;
+ }
+
+ break;
+ }
+
+ result = find_folder (hier, literal_uri, folder_out);
+ if (result == EXCHANGE_ACCOUNT_FOLDER_DOES_NOT_EXIST && standard_uri)
+ result = find_folder (hier, standard_uri, folder_out);
+
+ g_free (literal_uri);
+ g_free (standard_uri);
+
+ /* If the hierarchy is now empty, then we must have just been
+ * created but then the add failed. So remove it again.
+ */
+ if (exchange_hierarchy_is_empty (hier))
+ hierarchy_foreign_cleanup (hier);
+
+ return result;
+}
+
+
+static ExchangeAccountFolderResult
+create_folder (ExchangeHierarchy *hier, EFolder *parent,
+ const char *name, const char *type)
+{
+ return create_internal (hier, parent, name, type, NULL);
+}
+
+static ExchangeAccountFolderResult
+remove_folder (ExchangeHierarchy *hier, EFolder *folder)
+{
+ const char *folder_type, *physical_uri;
+
+ /* Temp Fix for remove fav folders. see #59168 */
+ /* remove ESources */
+ folder_type = e_folder_get_type_string (folder);
+ physical_uri = e_folder_get_physical_uri (folder);
+
+ if (strcmp (folder_type, "calendar") == 0) {
+ remove_folder_esource (hier->account,
+ EXCHANGE_CALENDAR_FOLDER,
+ physical_uri);
+ }
+ else if (strcmp (folder_type, "tasks") == 0) {
+ remove_folder_esource (hier->account,
+ EXCHANGE_TASKS_FOLDER,
+ physical_uri);
+ }
+ else if (strcmp (folder_type, "contacts") == 0) {
+ remove_folder_esource (hier->account,
+ EXCHANGE_CONTACTS_FOLDER,
+ physical_uri);
+ }
+
+ if (folder != hier->toplevel)
+ exchange_hierarchy_removed_folder (hier, folder);
+
+ if (folder == hier->toplevel || exchange_hierarchy_is_empty (hier))
+ hierarchy_foreign_cleanup (hier);
+
+ return EXCHANGE_ACCOUNT_FOLDER_OK;
+}
+
+static ExchangeAccountFolderResult
+scan_subtree (ExchangeHierarchy *hier, EFolder *folder, gboolean offline)
+{
+ ExchangeAccountFolderResult folder_result;
+
+ check_hide_private (hier);
+
+ folder_result = EXCHANGE_HIERARCHY_CLASS (parent_class)->scan_subtree (hier, folder, offline);
+
+ if (exchange_hierarchy_is_empty (hier))
+ hierarchy_foreign_cleanup (hier);
+
+ return folder_result;
+}
+
+static void
+add_href (ExchangeHierarchy *hier, EFolder *folder, gpointer hrefs)
+{
+ char *uri = g_strdup (e_folder_exchange_get_internal_uri (folder));
+
+ g_ptr_array_add (hrefs, (gpointer) uri);
+}
+
+static GPtrArray *
+get_hrefs (ExchangeHierarchySomeDAV *hsd)
+{
+ GPtrArray *hrefs;
+
+ hrefs = g_ptr_array_new ();
+ exchange_hierarchy_webdav_offline_scan_subtree (EXCHANGE_HIERARCHY (hsd), add_href, hrefs);
+ return hrefs;
+}
+
+/**
+ * exchange_hierarchy_foreign_add_folder:
+ * @hier: the hierarchy
+ * @folder_name: the name of the folder to add
+ * @folder: on successful return, the created folder
+ *
+ * Adds a new folder to @hier.
+ *
+ * Return value: the folder result.
+ **/
+ExchangeAccountFolderResult
+exchange_hierarchy_foreign_add_folder (ExchangeHierarchy *hier,
+ const char *folder_name,
+ EFolder **folder)
+{
+ ExchangeAccountFolderResult result;
+ const char *folder_type = NULL;
+ const char *physical_uri = NULL;
+ char *new_folder_name;
+
+ result = create_internal (hier, hier->toplevel, folder_name, NULL, folder);
+#if 0
+ if (result == EXCHANGE_ACCOUNT_FOLDER_OK) {
+ // Add the esources
+ folder_type = e_folder_get_type_string (*folder);
+ physical_uri = e_folder_get_physical_uri (*folder);
+ new_folder_name = g_strdup_printf("%s's %s",
+ hier->owner_name, folder_name);
+
+ if (!(strcmp (folder_type, "calendar")) ||
+ !(strcmp (folder_type, "calendar/public"))) {
+ add_folder_esource (hier->account,
+ EXCHANGE_CALENDAR_FOLDER,
+ new_folder_name,
+ physical_uri);
+ }
+ else if (!(strcmp (folder_type, "tasks")) ||
+ !(strcmp (folder_type, "tasks/public"))) {
+ add_folder_esource (hier->account,
+ EXCHANGE_TASKS_FOLDER,
+ new_folder_name,
+ physical_uri);
+ }
+ else if (!(strcmp (folder_type, "contacts")) ||
+ !(strcmp (folder_type, "contacts/public")) ||
+ !(strcmp (folder_type, "contacts/ldap"))) {
+ add_folder_esource (hier->account,
+ EXCHANGE_CONTACTS_FOLDER,
+ new_folder_name,
+ physical_uri);
+ }
+ g_free (new_folder_name);
+ }
+#endif
+ return result;
+}
+
+static ExchangeHierarchy *
+hierarchy_foreign_new (ExchangeAccount *account,
+ const char *hierarchy_name,
+ const char *physical_uri_prefix,
+ const char *internal_uri_prefix,
+ const char *owner_name,
+ const char *owner_email,
+ const char *source_uri)
+{
+ ExchangeHierarchyForeign *hfor;
+
+ g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), NULL);
+
+ hfor = g_object_new (EXCHANGE_TYPE_HIERARCHY_FOREIGN, NULL);
+
+ exchange_hierarchy_webdav_construct (EXCHANGE_HIERARCHY_WEBDAV (hfor),
+ account,
+ EXCHANGE_HIERARCHY_FOREIGN,
+ hierarchy_name,
+ physical_uri_prefix,
+ internal_uri_prefix,
+ owner_name, owner_email,
+ source_uri,
+ FALSE);
+
+ return EXCHANGE_HIERARCHY (hfor);
+}
+
+/**
+ * exchange_hierarchy_foreign_new:
+ * @account: an #ExchangeAccount
+ * @hierarchy_name: the name of the hierarchy
+ * @physical_uri_prefix: the prefix of physical URIs in this hierarchy
+ * @internal_uri_prefix: the prefix of internal (http) URIs in this hierarchy
+ * @owner_name: display name of the owner of the hierarchy
+ * @owner_email: email address of the owner of the hierarchy
+ * @source_uri: evolution-mail source uri for the hierarchy
+ *
+ * Creates a new (initially empty) hierarchy for another user's
+ * folders.
+ *
+ * Return value: the new hierarchy.
+ **/
+ExchangeHierarchy *
+exchange_hierarchy_foreign_new (ExchangeAccount *account,
+ const char *hierarchy_name,
+ const char *physical_uri_prefix,
+ const char *internal_uri_prefix,
+ const char *owner_name,
+ const char *owner_email,
+ const char *source_uri)
+{
+ ExchangeHierarchy *hier;
+ char *mf_path;
+ GHashTable *props;
+ xmlDoc *doc;
+
+ g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), NULL);
+
+ hier = hierarchy_foreign_new (account, hierarchy_name,
+ physical_uri_prefix,
+ internal_uri_prefix,
+ owner_name, owner_email,
+ source_uri);
+
+ props = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (props, "name", (char *)hierarchy_name);
+ g_hash_table_insert (props, "physical_uri_prefix",
+ (char *)physical_uri_prefix);
+ g_hash_table_insert (props, "internal_uri_prefix",
+ (char *)internal_uri_prefix);
+ g_hash_table_insert (props, "owner_name", (char *)owner_name);
+ g_hash_table_insert (props, "owner_email", (char *)owner_email);
+ g_hash_table_insert (props, "source_uri", (char *)source_uri);
+
+ mf_path = e_folder_exchange_get_storage_file (hier->toplevel, "hierarchy.xml");
+ doc = e_xml_from_hash (props, E_XML_HASH_TYPE_PROPERTY,
+ "foreign-hierarchy");
+ xmlSaveFile (mf_path, doc);
+ g_hash_table_destroy (props);
+ g_free (mf_path);
+ xmlFreeDoc (doc);
+
+ return hier;
+}
+
+/**
+ * exchange_hierarchy_foreign_new_from_dir:
+ * @account: an #ExchangeAccount
+ * @folder_path: pathname to a directory containing a hierarchy.xml file
+ *
+ * Recreates a new hierarchy from saved values.
+ *
+ * Return value: the new hierarchy.
+ **/
+ExchangeHierarchy *
+exchange_hierarchy_foreign_new_from_dir (ExchangeAccount *account,
+ const char *folder_path)
+{
+ ExchangeHierarchy *hier;
+ char *mf_path;
+ GHashTable *props;
+ xmlDoc *doc;
+
+ g_return_val_if_fail (EXCHANGE_IS_ACCOUNT (account), NULL);
+ g_return_val_if_fail (folder_path != NULL, NULL);
+
+ mf_path = g_build_filename (folder_path, "hierarchy.xml", NULL);
+ doc = xmlParseFile (mf_path);
+ g_free (mf_path);
+ if (!doc)
+ return NULL;
+
+ props = e_xml_to_hash (doc, E_XML_HASH_TYPE_PROPERTY);
+ xmlFreeDoc (doc);
+
+ hier = hierarchy_foreign_new (account,
+ g_hash_table_lookup (props, "name"),
+ g_hash_table_lookup (props, "physical_uri_prefix"),
+ g_hash_table_lookup (props, "internal_uri_prefix"),
+ g_hash_table_lookup (props, "owner_name"),
+ g_hash_table_lookup (props, "owner_email"),
+ g_hash_table_lookup (props, "source_uri"));
+
+ e_xml_destroy_hash (props);
+ return hier;
+}
--- /dev/null 2004-08-25 23:04:59.000000000 +0530
+++ exchange-hierarchy-foreign.h 2005-07-05 18:11:41.081780546 +0530
@@ -0,0 +1,56 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* Copyright (C) 2001-2004 Novell, Inc. */
+
+#ifndef __EXCHANGE_HIERARCHY_FOREIGN_H__
+#define __EXCHANGE_HIERARCHY_FOREIGN_H__
+
+#include "exchange-hierarchy-somedav.h"
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#define EXCHANGE_TYPE_HIERARCHY_FOREIGN (exchange_hierarchy_foreign_get_type ())
+#define EXCHANGE_HIERARCHY_FOREIGN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EXCHANGE_TYPE_HIERARCHY_FOREIGN, ExchangeHierarchyForeign))
+#define EXCHANGE_HIERARCHY_FOREIGN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EXCHANGE_TYPE_HIERARCHY_FOREIGN, ExchangeHierarchyForeignClass))
+#define EXCHANGE_IS_HIERARCHY_FOREIGN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EXCHANGE_TYPE_HIERARCHY_FOREIGN))
+#define EXCHANGE_IS_HIERARCHY_FOREIGN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EXCHANGE_TYPE_HIERARCHY_FOREIGN))
+
+typedef struct _ExchangeHierarchyForeignPrivate ExchangeHierarchyForeignPrivate;
+
+struct _ExchangeHierarchyForeign {
+ ExchangeHierarchySomeDAV parent;
+
+ ExchangeHierarchyForeignPrivate *priv;
+};
+
+struct _ExchangeHierarchyForeignClass {
+ ExchangeHierarchySomeDAVClass parent_class;
+
+};
+
+typedef struct _ExchangeHierarchyForeignClass ExchangeHierarchyForeignClass;
+typedef struct _ExchangeHierarchyForeign ExchangeHierarchyForeign;
+
+GType exchange_hierarchy_foreign_get_type (void);
+
+ExchangeHierarchy *exchange_hierarchy_foreign_new (ExchangeAccount *account,
+ const char *hierarchy_name,
+ const char *physical_uri_prefix,
+ const char *internal_uri_prefix,
+ const char *owner_name,
+ const char *owner_email,
+ const char *source_uri);
+ExchangeHierarchy *exchange_hierarchy_foreign_new_from_dir (ExchangeAccount *account,
+ const char *folder_path);
+
+ExchangeAccountFolderResult exchange_hierarchy_foreign_add_folder (ExchangeHierarchy *hier,
+ const char *folder_name,
+ EFolder **folder);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __EXCHANGE_HIERARCHY_FOREIGN_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]