diff options
author | Vivek Jain <jvivek@novell.com> | 2005-05-23 17:44:26 +0800 |
---|---|---|
committer | Jain Vivek <jvivek@src.gnome.org> | 2005-05-23 17:44:26 +0800 |
commit | 128075a77ebc9e1b21a1e50947ee0a5bb4dea8ca (patch) | |
tree | cae972534a1af80836f59d2bdc98c81dbbee9453 | |
parent | b25b709bf7fa81751810567af26ba4e8fe416b3a (diff) | |
download | gsoc2013-evolution-128075a77ebc9e1b21a1e50947ee0a5bb4dea8ca.tar.gz gsoc2013-evolution-128075a77ebc9e1b21a1e50947ee0a5bb4dea8ca.tar.zst gsoc2013-evolution-128075a77ebc9e1b21a1e50947ee0a5bb4dea8ca.zip |
Created a plugin "groupwise-features" which is a consolidation of
23-05-2005 Vivek Jain <jvivek@novell.com>
Created a plugin "groupwise-features" which is a consolidation of
following existing plugins
* groupwise-account-setup
* addressbook-groupwise
* shared-folder
* groupwise-send-options
* groupwise-status-tracking
* send-options
svn path=/trunk/; revision=29400
18 files changed, 4990 insertions, 0 deletions
diff --git a/plugins/groupwise-features/ChangeLog b/plugins/groupwise-features/ChangeLog new file mode 100644 index 0000000000..b0273e2871 --- /dev/null +++ b/plugins/groupwise-features/ChangeLog @@ -0,0 +1,265 @@ +23-05-2005 Vivek Jain <jvivek@novell.com> + + Created a plugin "groupwise-features" which is a consolidation of + following existing plugins + * groupwise-account-setup + * addressbook-groupwise + * shared-folder + * groupwise-send-options + * groupwise-status-tracking + * send-options + +2005-05-16 Not Zed <NotZed@Ximian.com> + + * camel-gw-listener.c: moved e-error to e-util. + +2005-05-16 Not Zed <NotZed@Ximian.com> + + * share-folder-common.c: moved e-error to e-util + + * Makefile.am: error filename changes. + +2005-05-06 Chenthill Palanisamy <pchenthill@novell.com> + + Fixes #273063 + * org-gnome-shared-folder-errors.xml: + * org-gnome-shared-folder-errors.xml.h:Removed the unwanted + tabs and new line characters. + +2005-05-06 Sarfraaz Ahmed <asarfraaz@novell.com> + + * properties.glade : Fixed a typo #273064 + +2005-05-05 Srinivasa Ragavan <sragavan@novell.com> + + * properties.glade : Fixed a typo 272538 + +2005-03-31 Parthasarathi Susarla <sparthasarathi@novell.com> + + * share-folder-common.c:(create_folder): + check the store state, can create a shared + folder only in online mode + Fixes bug 74002 + +2005-03-31 Vivek Jain <jvivek@novell.com> + + **Fixes #74002 + * share-folder-common.c : + (get_cnc): return cnc as NULL if evoluiton is in offline. + (create_folder): return -1 if in offline + +2005-03-31 Vivek Jain <jvivek@novell.com> + + **Fixes #73787 (bugzilla innerweb.novell) + * share-folder.c : + (add_right_clicked) + (edit_right_clicked) + (delete_right_clicked) : use path passed in the callback to get the + current iterator + also including some NULL checks + +2005-03-28 Vivek Jain <jvivek@novell.com> + + **Fixes #73198 + * share-folder-common.c : + (org_gnome_shared_folder_factory): + (create_folder__created) : pass the full name in get_conatiner_id + (get_container_id) : break the full name and start looking for the + name from the top most parent. This will give proper container id + even in the case of the duplicate names at different hierarchies + + +2005-03-18 Vivek Jain <jvivek@novell.com> + + * send-options.h: + * send-options.c: (org_gnome_compose_send_options): replace + X_RETURN_NOTIFY_DECLINE with X_RETURN_NOTIFY_DELETE + +2005-03-18 Vivek Jain <jvivek@novell.com> + + **Fixes #73473 + * send-options.c :(org_gnome_compose_send_options) + user proper entry to calculate the date of reply requested + +2005-03-10 Vivek Jain <jvivek@novell.com> + + **Fixes #73201 + * share-folder-common.c : (org_gnome_shared_folder_factory) + use full_name given by CamelFolder to get the selected folder name + + +2005-03-09 Sankar P <psankar@novell.com> + + * send-options.c: (org_gnome_compose_send_options) + Updated code to add priority to the appropriate header + Fixes the problem of Priority not set in outgoing mails + +2005-03-07 Sivaiah Nallagatla <snallagatla@novell.com> + + * camel-gw-listner.c (add_addressbook_sources) : + don't free container list here. It is chaced in + connection and will be frred later. + + Fixes #72807 + +2005-02-24 Björn Torkelsson <torkel@acc.umu.se> + * org-gnome-shared-folder.eplug.in: Added Groupwise to name. + Fixed description and added author. + Added xml tag. + +2005-02-24 Björn Torkelsson <torkel@acc.umu.se> + + * org-gnome-gw-account-setup.eplug.in: Added author and fixed + description. + +2005-02-23 JP Rosevear <jpr@novell.com> + + * org-gnome-gw-account-setup.eplug.in: add account wizard item + + +2005-02-23 Hans Petter Jansson <hpj@novell.com> + + * camel-gw-listener.c: Include <libedataserverui/e-passwords.h>. + +2005-02-17 Vivek Jain <jvivek@novell.com> + + * share-folder-common.c : (get_cnc): + + use ssl when "always" and "whenever possible" is enabled + changed "soap_ssl" to "use_ssl" + use the default port "7191" instead of "7181" + + 2005-02-16 Not Zed <NotZed@Ximian.com> + + * groupwise-account-setup.c (org_gnome_gw_account_setup): return + NULL, not an invisible, so it doesn't interfere with account + editor. + +2005-02-16 Not Zed <NotZed@Ximian.com> + + * groupwise-account-setup.c (org_gnome_gw_account_setup): return + NULL, not an invisible, so it doesn't interfere with account + editor. + +2005-02-03 Chenthill Palanisamy <pchenthill@novell.com> + + * send-options.c: (add_day_to_time), (send_options_commit), + (org_gnome_compose_send_options):Added functions to destroy + the dialog when the composer is destroyed to solve the crash. + Removed the return statement so that the send options gets + added to the composer headers. Made modification in setting + the values for some headers. + Changing the file name from Changelog to ChangeLog. + +2005-01-28 Sivaiah Nallagatla <snallagatla@novell.com> + + * camel-gw-listner.c (get_address_book_names_from_server) + : Remove leading "%s" in the message. Similar to + #36137 + + * camel-gw-listener.c (add_esource) + (modify_esource) (add_addressbook_sources) : + Don't set offline_sync value taken from camel url + instead set "1" or "0" depending upon offline is enabled + or not + +2005-01-24 Vivek Jain <jvivek@novell.com> + + * properties.glade : changed the layout of the widgets + * share-folder.[ch]: removed the checkbuttons for display of rights + : removed new_list, update_list and remove_list + added users_list + * share-folder.c : removed function (update_list_update) + (share_folder_construct) : added gtk_cell_renderer_toggle for + displaying rights + added one structure SharedUsers to have a single list instead of three + different lists. Made corresponding changes in all functions. + * share-folder-common.c : (new_folder_response): use + gtk_widget_reparent to pack the widget + added two files + * org-gnome-shared-folder-errors.xml + * org-gnome-shared-folder-errors.xml.h : to display error message + * Makefile.am : included error data + +2005-01-21 Sivaiah Nallagatla <snallagtla@novell.com> + + * org-gnome-gw-account-setup.eplug.in : changed + the item type from "item" to "item_table". avoids + some debug spew on the console + +2005-01-20 Sivaiah Nallagatla <snallagatla@novell.com> + + * camel-gw-listener.c: (add_calendar_tasks_sources): + Assiged value to URL. + +2005-01-19 Vivek Jain <jvivek@novell.com> + *install-shared.c + (org_gnome_popup_wizard): fixed a crash, caused by g_free + (install_folder_response): free the memory + +2005-01-18 Vivek Jain <jvivek@novell.com> + *install-shared.c + (org_gnome_popup_wizard): removed unnecessary stuff for the display of + wizard + +2005-01-18 Parthasarathi Susarla <sparthasarathi@novell.com> + + *install-shared.c + (org_gnome_popup_wizard): displays the message without the + mime headers + +2005-01-17 Vivek Jain <jvivek@novell.com> + + *install-shared.c : (org_gnome_popup_wizard): included a condition + (null check) to fix a crash + * shared-folder-common.c :(org_gnome_shared_folder_factory): some + condition checks to avoid the possible crashes + (get_container_id): included code to return top level container id if + folder name is passed as null + +2005-01-15 Sivaiah Nallagatla <snallagatla@novell.com> + + * camel-gw-listner.c : use url->host instead of reading "poa" + parameter everywhere. use "use_ssl" param instead of soap_ssl + We not longer have separate settings for soap as we use soap for mail + now + + +2005-01-13 Vivek Jain <jvivek@novell.com> + + * share-folder.c :changed the function find_node to return user node + corresponding to the mail address given. + (add_clicked): added a condition so that user can't share folder to itself. + (user_selected): modified to display proper rights when owner is selected. + * share-folder-common.c : calling share_folder with a cnc in it. + +2005-01-10 Vivek Jain <jvivek@novell.com> Included + + * install-shared.c : opens up a wizard on reading a shared folder + notification and installs shared folder at the recepient end. + * share-folder-common.c : added + (refresh_folder_tree) : to refresh the folder tree when a folder is shared or + a shared folder is created so that different icons are displayed + (get_cnc): to get a connection + (get_container_id):to get the container id of the folder user selects + * share-folder.c : minor changes to fix the crash + * Makefile.am : including install-shared.c in sources + * org-gnome-shared-folder.eplug.in : added a plugin to the e-plugin list for + the message-read event + +2004-12-17 Sivaiah Nallagatla <snallagatla@novell.com> + + * camel-gw-listner.c (add_esource) : read "soap_ssl" from + the camel url instead of "use_ssl" + +2004-12-15 Vivek Jain <jvivek@novell.com> + + Added (Create a shared folder) functionality in the plugin + * org-gnome-shared-folder.eplug.in : added a plugin in the plugin list + * share-folder-common.c : included functions to create a shared folder + +2004-12-15 Vivek Jain <jvivek@novell.com> + + * shared-folder-common.c : (org_gnome_shared_folder_factory) + * shared-folder.c : some whitespace changes, typecasting widgets, + in (on_add_clicked) removed assigning the rights portion diff --git a/plugins/groupwise-features/Makefile.am b/plugins/groupwise-features/Makefile.am new file mode 100644 index 0000000000..ccda704a68 --- /dev/null +++ b/plugins/groupwise-features/Makefile.am @@ -0,0 +1,49 @@ +INCLUDES = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/camel \ + $(EVOLUTION_MAIL_CFLAGS) \ + $(EVOLUTION_CALENDAR_CFLAGS) \ + $(EVOLUTION_ADDRESSBOOK_CFLAGS) \ + $(CAMEL_GROUPWISE_CFLAGS) \ + -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" + +@EVO_PLUGIN_RULE@ + +plugin_DATA = org-gnome-groupwise-features.eplug org-gnome-compose-send-options.xml +plugin_LTLIBRARIES = liborg-gnome-groupwise-features.la + +liborg_gnome_groupwise_features_la_SOURCES = \ + share-folder-common.c \ + share-folder.c \ + share-folder.h \ + install-shared.c \ + groupwise-account-setup.c \ + camel-gw-listener.c \ + camel-gw-listener.h \ + send-options.c \ + mail-send-options.c \ + mail-send-options.h \ + status-track.c \ + addressbook-groupwise.c + +liborg_gnome_groupwise_features_la_LIBADD= \ + $(EVOLUTION_MAIL_LIBS) \ + $(CAMEL_GROUPWISE_LIBS) \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/widgets/misc/libemiscwidgets.la + + + +liborg_gnome_groupwise_features_la_LDFLAGS = -module -avoid-version + +glade_DATA =properties.glade + +error_DATA = org-gnome-shared-folder.errors.xml +errordir = $(privdatadir)/errors + +EXTRA_DIST = \ + $(error_DATA) \ + $(glade_DATA) \ + org-gnome-compose-send-options.xml \ + org-gnome-groupwise-features.eplug.xml +CLEANFILES = $(BUILT_SOURCES) diff --git a/plugins/groupwise-features/addressbook-groupwise.c b/plugins/groupwise-features/addressbook-groupwise.c new file mode 100644 index 0000000000..1cd1691afb --- /dev/null +++ b/plugins/groupwise-features/addressbook-groupwise.c @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* * + * Copyright (C) 2004 Sivaiah Nallagatla <snallagtla@novell.com> + * + * 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 <gtk/gtklabel.h> +#include <gtk/gtkentry.h> +#include <gtk/gtktable.h> +#include <gtk/gtkspinbutton.h> +#include <gtk/gtkoptionmenu.h> +#include <gtk/gtkmenu.h> +#include <gtk/gtkmenuitem.h> +#include <gtk/gtkhbox.h> +#include <e-util/e-config.h> +#include <addressbook/gui/widgets/eab-config.h> +#include <libedataserver/e-source.h> +#include <libgnome/gnome-i18n.h> +#include <string.h> + +void commit_groupwise_addressbook (EPlugin *epl, EConfigTarget *target); +GtkWidget *e_book_groupwise_dummy (EPlugin *epl, EConfigHookItemFactoryData *data); + +void +commit_groupwise_addressbook (EPlugin *epl, EConfigTarget *target) +{ + EABConfigTargetSource *t = (EABConfigTargetSource *) target; + ESource *source = t->source; + char *uri_text; + ESourceGroup *source_group; + char *relative_uri; + GSList *l; + + uri_text = e_source_get_uri (source); + if (strncmp (uri_text, "groupwise", 9)) { + g_free (uri_text); + + return ; + } + e_source_set_property (source, "auth-domain", "Groupwise"); + relative_uri = g_strconcat (";", e_source_peek_name (source), NULL); + e_source_set_relative_uri (source, relative_uri); + g_free (relative_uri); + + source_group = e_source_peek_group (source); + l = e_source_group_peek_sources(source_group); + if (l && l->data ) { + e_source_set_property(source, "auth", e_source_get_property(l->data, "auth")); + e_source_set_property(source, "user", e_source_get_property(l->data, "user")); + e_source_set_property(source, "use_ssl", e_source_get_property(l->data, "use_ssl")); + e_source_set_property(source, "port", e_source_get_property(l->data, "port")); + } +} + +GtkWidget * +e_book_groupwise_dummy (EPlugin *epl, EConfigHookItemFactoryData *data) +{ + + + return NULL; +} diff --git a/plugins/groupwise-features/camel-gw-listener.c b/plugins/groupwise-features/camel-gw-listener.c new file mode 100644 index 0000000000..48c58f4a48 --- /dev/null +++ b/plugins/groupwise-features/camel-gw-listener.c @@ -0,0 +1,892 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors : + * + * Sivaiah Nallagatla <snallagatla@novell.com> + * + * Copyright 2003, 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 + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "camel-gw-listener.h" +#include <string.h> +#include <camel/camel-i18n.h> +#include <e-gw-connection.h> +#include <libedataserverui/e-passwords.h> +#include "e-util/e-error.h" + +/*stores some info about all currently existing groupwise accounts + list of GwAccountInfo structures */ + +static GList *groupwise_accounts = NULL; + +struct _CamelGwListenerPrivate { + GConfClient *gconf_client; + /* we get notification about mail account changes form this object */ + EAccountList *account_list; +}; + +struct _GwAccountInfo { + char *uid; + char *name; + char *source_url; +}; + +typedef struct _GwAccountInfo GwAccountInfo; + +#define GROUPWISE_URI_PREFIX "groupwise://" +#define GROUPWISE_PREFIX_LENGTH 12 + +#define PARENT_TYPE G_TYPE_OBJECT + +static GObjectClass *parent_class = NULL; + +static void dispose (GObject *object); +static void finalize (GObject *object); + + +static void +camel_gw_listener_class_init (CamelGwListenerClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_ref (PARENT_TYPE); + object_class = G_OBJECT_CLASS (class); + + /* virtual method override */ + object_class->dispose = dispose; + object_class->finalize = finalize; +} + +static void +camel_gw_listener_init (CamelGwListener *config_listener, CamelGwListenerClass *class) +{ + config_listener->priv = g_new0 (CamelGwListenerPrivate, 1); +} + +static void +dispose (GObject *object) +{ + CamelGwListener *config_listener = CAMEL_GW_LISTENER (object); + + g_object_unref (config_listener->priv->gconf_client); + g_object_unref (config_listener->priv->account_list); + + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + CamelGwListener *config_listener = CAMEL_GW_LISTENER (object); + GList *list; + GwAccountInfo *info; + + if (config_listener->priv) { + g_free (config_listener->priv); + } + + for ( list = g_list_first (groupwise_accounts); list ; list = g_list_next (list) ) { + + info = (GwAccountInfo *) (list->data); + + if (info) { + + g_free (info->uid); + g_free (info->name); + g_free (info->source_url); + g_free (info); + } + } + + g_list_free (groupwise_accounts); +} + +/*determines whehter the passed in account is groupwise or not by looking at source url */ + +static gboolean +is_groupwise_account (EAccount *account) +{ + if (account->source->url != NULL) { + return (strncmp (account->source->url, GROUPWISE_URI_PREFIX, GROUPWISE_PREFIX_LENGTH ) == 0); + } else { + return FALSE; + } +} + +/* looks up for an existing groupwise account info in the groupwise_accounts list based on uid */ + +static GwAccountInfo* +lookup_account_info (const char *key) +{ + GList *list; + GwAccountInfo *info ; + int found = 0; + + if (!key) + return NULL; + + info = NULL; + + for (list = g_list_first (groupwise_accounts); list; list = g_list_next (list)) { + info = (GwAccountInfo *) (list->data); + found = (strcmp (info->uid, key) == 0); + if (found) + break; + } + if (found) + return info; + return NULL; +} + +#define CALENDAR_SOURCES "/apps/evolution/calendar/sources" +#define TASKS_SOURCES "/apps/evolution/tasks/sources" +#define SELECTED_CALENDARS "/apps/evolution/calendar/display/selected_calendars" +#define SELECTED_TASKS "/apps/evolution/calendar/tasks/selected_tasks" + +static void +add_esource (const char *conf_key, const char *group_name, const char *source_name, CamelURL *url) +{ + ESourceList *source_list; + ESourceGroup *group; + ESource *source; + GConfClient* client; + GSList *ids, *temp ; + char *source_selection_key; + char *relative_uri; + const char *soap_port; + const char * use_ssl; + const char *poa_address; + const char *offline_sync; + + + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return; + soap_port = camel_url_get_param (url, "soap_port"); + + if (!soap_port || strlen (soap_port) == 0) + soap_port = "7191"; + + use_ssl = camel_url_get_param (url, "use_ssl"); + + + offline_sync = camel_url_get_param (url, "offline_sync"); + + client = gconf_client_get_default(); + source_list = e_source_list_new_for_gconf (client, conf_key); + + group = e_source_group_new (group_name, GROUPWISE_URI_PREFIX); + if (!e_source_list_add_group (source_list, group, -1)) + return; + relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address); + + source = e_source_new (source_name, relative_uri); + e_source_set_property (source, "auth", "1"); + e_source_set_property (source, "username", url->user); + e_source_set_property (source, "port", camel_url_get_param (url, "soap_port")); + e_source_set_property (source, "auth-domain", "Groupwise"); + e_source_set_property (source, "use_ssl", use_ssl); + e_source_set_property (source, "offline_sync", offline_sync ? "1" : "0" ); + e_source_group_add_source (group, source, -1); + e_source_list_sync (source_list, NULL); + + if (!strcmp (conf_key, CALENDAR_SOURCES)) + source_selection_key = SELECTED_CALENDARS; + else if (!strcmp (conf_key, TASKS_SOURCES)) + source_selection_key = SELECTED_TASKS; + else source_selection_key = NULL; + if (source_selection_key) { + ids = gconf_client_get_list (client, source_selection_key , GCONF_VALUE_STRING, NULL); + ids = g_slist_append (ids, g_strdup (e_source_peek_uid (source))); + gconf_client_set_list (client, source_selection_key, GCONF_VALUE_STRING, ids, NULL); + temp = ids; + for (; temp != NULL; temp = g_slist_next (temp)) + g_free (temp->data); + g_slist_free (ids); + } + + g_object_unref (source); + g_object_unref (group); + g_object_unref (source_list); + g_object_unref (client); + g_free (relative_uri); +} + + +static void +remove_esource (const char *conf_key, const char *group_name, char* source_name, const char* relative_uri) +{ + ESourceList *list; + ESourceGroup *group; + ESource *source; + GSList *groups; + GSList *sources; + gboolean found_group; + GConfClient* client; + GSList *ids; + GSList *node_tobe_deleted; + char *source_selection_key; + + client = gconf_client_get_default(); + list = e_source_list_new_for_gconf (client, conf_key); + groups = e_source_list_peek_groups (list); + + found_group = FALSE; + + for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) { + + group = E_SOURCE_GROUP (groups->data); + + if (strcmp (e_source_group_peek_name (group), group_name) == 0 && + strcmp (e_source_group_peek_base_uri (group), GROUPWISE_URI_PREFIX ) == 0) { + + sources = e_source_group_peek_sources (group); + + for( ; sources != NULL; sources = g_slist_next (sources)) { + + source = E_SOURCE (sources->data); + + if (strcmp (e_source_peek_relative_uri (source), relative_uri) == 0) { + + if (!strcmp (conf_key, CALENDAR_SOURCES)) + source_selection_key = SELECTED_CALENDARS; + else if (!strcmp (conf_key, TASKS_SOURCES)) + source_selection_key = SELECTED_TASKS; + else source_selection_key = NULL; + if (source_selection_key) { + ids = gconf_client_get_list (client, source_selection_key , + GCONF_VALUE_STRING, NULL); + node_tobe_deleted = g_slist_find_custom (ids, e_source_peek_uid (source), (GCompareFunc) strcmp); + if (node_tobe_deleted) { + g_free (node_tobe_deleted->data); + ids = g_slist_delete_link (ids, node_tobe_deleted); + } + gconf_client_set_list (client, source_selection_key, + GCONF_VALUE_STRING, ids, NULL); + + } + e_source_list_remove_group (list, group); + e_source_list_sync (list, NULL); + found_group = TRUE; + break; + + } + } + + } + + + } + + g_object_unref (list); + g_object_unref (client); + +} + +/* looks up for e-source with having same info as old_account_info and changes its values passed in new values */ + +static void +modify_esource (const char* conf_key, GwAccountInfo *old_account_info, const char* new_group_name, CamelURL *new_url) +{ + ESourceList *list; + ESourceGroup *group; + ESource *source; + GSList *groups; + GSList *sources; + char *old_relative_uri; + CamelURL *url; + gboolean found_group; + GConfClient* client; + const char *poa_address; + char *new_relative_uri; + const char *new_poa_address; + + url = camel_url_new (old_account_info->source_url, NULL); + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return; + new_poa_address = new_url->host; + + old_relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address); + client = gconf_client_get_default (); + list = e_source_list_new_for_gconf (client, conf_key); + groups = e_source_list_peek_groups (list); + + found_group = FALSE; + + for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) { + + group = E_SOURCE_GROUP (groups->data); + + if (strcmp (e_source_group_peek_name (group), old_account_info->name) == 0 && + strcmp (e_source_group_peek_base_uri (group), GROUPWISE_URI_PREFIX) == 0) { + + sources = e_source_group_peek_sources (group); + + for ( ; sources != NULL; sources = g_slist_next (sources)) { + + source = E_SOURCE (sources->data); + + if (strcmp (e_source_peek_relative_uri (source), old_relative_uri) == 0) { + + new_relative_uri = g_strdup_printf ("%s@%s/", new_url->user, new_poa_address); + e_source_group_set_name (group, new_group_name); + e_source_set_relative_uri (source, new_relative_uri); + e_source_set_property (source, "username", new_url->user); + e_source_set_property (source, "port", camel_url_get_param (new_url,"soap_port")); + e_source_set_property (source, "use_ssl", camel_url_get_param (url, "use_ssl")); + e_source_set_property (source, "offline_sync", camel_url_get_param (url, "offline_sync") ? "1" : "0"); + e_source_list_sync (list, NULL); + found_group = TRUE; + g_free (new_relative_uri); + break; + } + } + } + } + + g_object_unref (list); + g_object_unref (client); + camel_url_free (url); + g_free (old_relative_uri); + + +} +/* add sources for calendar and tasks if the account added is groupwise account + adds the new account info to groupwise_accounts list */ + +static void +add_calendar_tasks_sources (GwAccountInfo *info) +{ + CamelURL *url; + + url = camel_url_new (info->source_url, NULL); + add_esource ("/apps/evolution/calendar/sources", info->name, _("Calendar"), url); + add_esource ("/apps/evolution/tasks/sources", info->name, _("Tasks"), url); + + camel_url_free (url); + + +} + +/* removes calendar and tasks sources if the account removed is groupwise account + removes the the account info from groupwise_account list */ + +static void +remove_calendar_tasks_sources (GwAccountInfo *info) +{ + CamelURL *url; + char *relative_uri; + const char *soap_port; + const char *poa_address; + + url = camel_url_new (info->source_url, NULL); + + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return; + + soap_port = camel_url_get_param (url, "soap_port"); + if (!soap_port || strlen (soap_port) == 0) + soap_port = "7191"; + + relative_uri = g_strdup_printf ("%s@%s/", url->user, poa_address); + remove_esource ("/apps/evolution/calendar/sources", info->name, _("Calendar"), relative_uri); + remove_esource ("/apps/evolution/tasks/sources", info->name, _("Checklist"), relative_uri); + camel_url_free (url); + g_free (relative_uri); + +} + +static GList* +get_addressbook_names_from_server (char *source_url) +{ + char *key; + EGwConnection *cnc; + char *password; + GList *book_list; + int status; + const char *soap_port; + CamelURL *url; + gboolean remember; + char *failed_auth; + char *prompt; + char *password_prompt; + char *uri; + const char *use_ssl; + const char *poa_address; + guint32 flags = E_PASSWORDS_REMEMBER_FOREVER; + + url = camel_url_new (source_url, NULL); + if (url == NULL) { + return NULL; + } + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return NULL; + + soap_port = camel_url_get_param (url, "soap_port"); + if (!soap_port || strlen (soap_port) == 0) + soap_port = "7191"; + use_ssl = camel_url_get_param (url, "use_ssl"); + + key = g_strdup_printf ("groupwise://%s@%s/", url->user, poa_address); + + if (!g_str_equal (use_ssl, "never")) + uri = g_strdup_printf ("https://%s:%s/soap", poa_address, soap_port); + else + uri = g_strdup_printf ("http://%s:%s/soap", poa_address, soap_port); + + failed_auth = ""; + cnc = NULL; + do { + password_prompt = g_strdup_printf (_("Enter password for %s (user %s)"), + poa_address, url->user); + prompt = g_strconcat (failed_auth, password_prompt, NULL); + g_free (password_prompt); + password = e_passwords_ask_password (prompt, "Groupwise", key, prompt, + E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET, &remember, + NULL); + g_free (prompt); + + if (!password) + break; + cnc = e_gw_connection_new (uri, url->user, password); + if (!E_IS_GW_CONNECTION(cnc) && use_ssl && g_str_equal (use_ssl, "when-possible")) { + char *http_uri = g_strconcat ("http://", uri + 8, NULL); + cnc = e_gw_connection_new (http_uri, url->user, password); + g_free (http_uri); + } + failed_auth = _("Failed to authenticate.\n"); + flags |= E_PASSWORDS_REPROMPT; + } while (cnc == NULL); + + if (E_IS_GW_CONNECTION(cnc)) { + book_list = NULL; + status = e_gw_connection_get_address_book_list (cnc, &book_list); + if (status == E_GW_CONNECTION_STATUS_OK) + return book_list; + + + } + e_error_run (NULL, "mail:gw-accountsetup-error", poa_address, NULL); + return NULL; +} + + +static gboolean +add_addressbook_sources (EAccount *account) +{ + CamelURL *url; + ESourceList *list; + ESourceGroup *group; + ESource *source; + char *base_uri; + const char *soap_port; + GList *books_list, *temp_list; + GConfClient* client; + const char* use_ssl; + const char *poa_address; + + + url = camel_url_new (account->source->url, NULL); + if (url == NULL) { + return FALSE; + } + + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return FALSE; + + soap_port = camel_url_get_param (url, "soap_port"); + if (!soap_port || strlen (soap_port) == 0) + soap_port = "7191"; + use_ssl = camel_url_get_param (url, "use_ssl"); + base_uri = g_strdup_printf ("groupwise://%s@%s", url->user, poa_address); + client = gconf_client_get_default (); + list = e_source_list_new_for_gconf (client, "/apps/evolution/addressbook/sources" ); + group = e_source_group_new (account->name, base_uri); + books_list = get_addressbook_names_from_server (account->source->url); + temp_list = books_list; + if (!temp_list) + return FALSE; + for (; temp_list != NULL; temp_list = g_list_next (temp_list)) { + const char *book_name = e_gw_container_get_name (E_GW_CONTAINER(temp_list->data)); + source = e_source_new (book_name, g_strconcat (";",book_name, NULL)); + e_source_set_property (source, "auth", "plain/password"); + e_source_set_property (source, "auth-domain", "Groupwise"); + e_source_set_property (source, "port", soap_port); + e_source_set_property(source, "user", url->user); + e_source_set_property (source, "offline_sync", camel_url_get_param (url, "offline_sync") ? "1" : "0"); + if (!e_gw_container_get_is_writable (E_GW_CONTAINER(temp_list->data))) + e_source_set_property (source, "completion", "true"); + if (e_gw_container_get_is_frequent_contacts (E_GW_CONTAINER(temp_list->data))) + e_source_set_property (source, "completion", "true"); + e_source_set_property (source, "use_ssl", use_ssl); + e_source_group_add_source (group, source, -1); + g_object_unref (source); + } + e_source_list_add_group (list, group, -1); + e_source_list_sync (list, NULL); + g_object_unref (group); + g_object_unref (list); + g_object_unref (client); + g_free (base_uri); + + return TRUE; +} + +static void +modify_addressbook_sources ( EAccount *account, GwAccountInfo *existing_account_info ) +{ + CamelURL *url; + ESourceList *list; + ESourceGroup *group; + GSList *groups; + gboolean found_group; + gboolean delete_group; + char *old_base_uri; + char *new_base_uri; + const char *soap_port; + const char *use_ssl; + GSList *sources; + ESource *source; + GConfClient *client; + const char *poa_address; + + + url = camel_url_new (existing_account_info->source_url, NULL); + if (url == NULL) { + return; + } + + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return; + + old_base_uri = g_strdup_printf ("groupwise://%s@%s", url->user, poa_address); + camel_url_free (url); + + url = camel_url_new (account->source->url, NULL); + if (url == NULL) + return ; + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return; + new_base_uri = g_strdup_printf ("groupwise://%s@%s", url->user, poa_address); + soap_port = camel_url_get_param (url, "soap_port"); + if (!soap_port || strlen (soap_port) == 0) + soap_port = "7191"; + use_ssl = camel_url_get_param (url, "use_ssl"); + + client = gconf_client_get_default (); + list = e_source_list_new_for_gconf (client, "/apps/evolution/addressbook/sources" ); + groups = e_source_list_peek_groups (list); + delete_group = FALSE; + if (strcmp (old_base_uri, new_base_uri) != 0) + delete_group = TRUE; + group = NULL; + found_group = FALSE; + for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) { + + group = E_SOURCE_GROUP (groups->data); + if ( strcmp ( e_source_group_peek_base_uri(group), old_base_uri) == 0 && strcmp (e_source_group_peek_name (group), existing_account_info->name) == 0) { + found_group = TRUE; + if (!delete_group) { + e_source_group_set_name (group, account->name); + sources = e_source_group_peek_sources (group); + for (; sources != NULL; sources = g_slist_next (sources)) { + source = E_SOURCE (sources->data); + e_source_set_property (source, "port", soap_port); + e_source_set_property (source, "use_ssl", use_ssl); + } + + e_source_list_sync (list, NULL); + } + + } + } + if (found_group && delete_group) { + e_source_list_remove_group (list, group); + e_source_list_sync (list, NULL); + g_object_unref (list); + list = NULL; + add_addressbook_sources (account); + } + g_free (old_base_uri); + if (list) + g_object_unref (list); + camel_url_free (url); + g_object_unref (client); + + +} + +static void +remove_addressbook_sources (GwAccountInfo *existing_account_info) +{ + ESourceList *list; + ESourceGroup *group; + GSList *groups; + gboolean found_group; + CamelURL *url; + char *base_uri; + const char *soap_port; + GConfClient *client; + const char *poa_address; + + url = camel_url_new (existing_account_info->source_url, NULL); + if (url == NULL) { + return; + } + + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return; + + soap_port = camel_url_get_param (url, "soap_port"); + if (!soap_port || strlen (soap_port) == 0) + soap_port = "7191"; + base_uri = g_strdup_printf ("groupwise://%s@%s", url->user, poa_address); + client = gconf_client_get_default (); + list = e_source_list_new_for_gconf (client, "/apps/evolution/addressbook/sources" ); + groups = e_source_list_peek_groups (list); + + found_group = FALSE; + + for ( ; groups != NULL && !found_group; groups = g_slist_next (groups)) { + + group = E_SOURCE_GROUP (groups->data); + if ( strcmp ( e_source_group_peek_base_uri (group), base_uri) == 0 && strcmp (e_source_group_peek_name (group), existing_account_info->name) == 0) { + + e_source_list_remove_group (list, group); + e_source_list_sync (list, NULL); + found_group = TRUE; + + } + } + g_object_unref (list); + g_object_unref (client); + g_free (base_uri); + camel_url_free (url); + + +} + + + +static void +account_added (EAccountList *account_listener, EAccount *account) +{ + + GwAccountInfo *info; + gboolean status; + + if (!is_groupwise_account (account)) + return; + + info = g_new0 (GwAccountInfo, 1); + info->uid = g_strdup (account->uid); + info->name = g_strdup (account->name); + info->source_url = g_strdup (account->source->url); + status = add_addressbook_sources (account); + if (status) + add_calendar_tasks_sources (info); + groupwise_accounts = g_list_append (groupwise_accounts, info); + +} + +static void +account_removed (EAccountList *account_listener, EAccount *account) +{ + GwAccountInfo *info; + + if (!is_groupwise_account (account)) + return; + + info = lookup_account_info (account->uid); + if (info == NULL) { + return; + } + + remove_calendar_tasks_sources (info); + remove_addressbook_sources (info); + groupwise_accounts = g_list_remove (groupwise_accounts, info); + g_free (info->uid); + g_free (info->name); + g_free (info->source_url); + g_free (info); + + +} + + +static void +account_changed (EAccountList *account_listener, EAccount *account) +{ + gboolean is_gw_account; + CamelURL *old_url, *new_url; + const char *old_soap_port, *new_soap_port; + GwAccountInfo *existing_account_info; + const char *old_use_ssl, *new_use_ssl; + const char *old_poa_address, *new_poa_address; + + is_gw_account = is_groupwise_account (account); + + existing_account_info = lookup_account_info (account->uid); + + if (existing_account_info == NULL && is_gw_account) { + + if (!account->enabled) + return; + + /* some account of other type is changed to Groupwise */ + account_added (account_listener, account); + + } else if ( existing_account_info != NULL && !is_gw_account) { + + /*Groupwise account is changed to some other type */ + remove_calendar_tasks_sources (existing_account_info); + remove_addressbook_sources (existing_account_info); + groupwise_accounts = g_list_remove (groupwise_accounts, existing_account_info); + g_free (existing_account_info->uid); + g_free (existing_account_info->name); + g_free (existing_account_info->source_url); + g_free (existing_account_info); + + } else if ( existing_account_info != NULL && is_gw_account ) { + + if (!account->enabled) { + account_removed (account_listener, account); + return; + } + + /* some info of groupwise account is changed . update the sources with new info if required */ + old_url = camel_url_new (existing_account_info->source_url, NULL); + old_poa_address = old_url->host; + old_soap_port = camel_url_get_param (old_url, "soap_port"); + old_use_ssl = camel_url_get_param (old_url, "use_ssl"); + new_url = camel_url_new (account->source->url, NULL); + new_poa_address = new_url->host; + if (!new_poa_address || strlen (new_poa_address) ==0) + return; + new_soap_port = camel_url_get_param (new_url, "soap_port"); + if (!new_soap_port || strlen (new_soap_port) == 0) + new_soap_port = "7191"; + + new_use_ssl = camel_url_get_param (new_url, "use_ssl"); + + + if ((old_poa_address && strcmp (old_poa_address, new_poa_address)) + || (old_soap_port && strcmp (old_soap_port, new_soap_port)) + || strcmp (old_url->user, new_url->user) + || strcmp (old_use_ssl, new_use_ssl)) { + + account_removed (account_listener, account); + account_added (account_listener, account); + } else if (strcmp (existing_account_info->name, account->name)) { + + modify_esource ("/apps/evolution/calendar/sources", existing_account_info, account->name, new_url); + modify_esource ("/apps/evolution/tasks/sources", existing_account_info, account->name, new_url); + modify_addressbook_sources (account, existing_account_info); + + } + + g_free (existing_account_info->name); + g_free (existing_account_info->source_url); + existing_account_info->name = g_strdup (account->name); + existing_account_info->source_url = g_strdup (account->source->url); + camel_url_free (old_url); + camel_url_free (new_url); + } + + +} + + + +static void +camel_gw_listener_construct (CamelGwListener *config_listener) +{ + EIterator *iter; + EAccount *account; + GwAccountInfo *info ; + + config_listener->priv->account_list = e_account_list_new (config_listener->priv->gconf_client); + + for ( iter = e_list_get_iterator (E_LIST ( config_listener->priv->account_list) ) ; e_iterator_is_valid (iter); e_iterator_next (iter) ) { + + account = E_ACCOUNT (e_iterator_get (iter)); + if ( is_groupwise_account (account) && account->enabled) { + + info = g_new0 (GwAccountInfo, 1); + info->uid = g_strdup (account->uid); + info->name = g_strdup (account->name); + info->source_url = g_strdup (account->source->url); + groupwise_accounts = g_list_append (groupwise_accounts, info); + + } + + } + g_signal_connect (config_listener->priv->account_list, "account_added", G_CALLBACK (account_added), NULL); + g_signal_connect (config_listener->priv->account_list, "account_changed", G_CALLBACK (account_changed), NULL); + g_signal_connect (config_listener->priv->account_list, "account_removed", G_CALLBACK (account_removed), NULL); + + +} + +GType +camel_gw_listener_get_type (void) +{ + static GType camel_gw_listener_type = 0; + + if (!camel_gw_listener_type) { + static GTypeInfo info = { + sizeof (CamelGwListenerClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) camel_gw_listener_class_init, + NULL, NULL, + sizeof (CamelGwListener), + 0, + (GInstanceInitFunc) camel_gw_listener_init + }; + camel_gw_listener_type = g_type_register_static (PARENT_TYPE, "CamelGwListener", &info, 0); + } + + return camel_gw_listener_type; +} + +CamelGwListener* +camel_gw_listener_new () +{ + CamelGwListener *config_listener; + + config_listener = g_object_new (CAMEL_TYPE_GW_LISTENER, NULL); + config_listener->priv->gconf_client = gconf_client_get_default(); + + camel_gw_listener_construct (config_listener); + + return config_listener; + +} + + diff --git a/plugins/groupwise-features/camel-gw-listener.h b/plugins/groupwise-features/camel-gw-listener.h new file mode 100644 index 0000000000..bf1df856a6 --- /dev/null +++ b/plugins/groupwise-features/camel-gw-listener.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors : + * + * Sivaiah Nallagatla <snallagatla@novell.com> + * + * Copyright 2003, 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 + */ + + +#ifndef CAMEL_GW_LISTENER_H +#define CAMEL_GW_LISTENER_H + + +#include <libedataserver/e-account-list.h> +#include<libedataserver/e-source.h> +#include<libedataserver/e-source-list.h> +#include <camel/camel-url.h> + +G_BEGIN_DECLS + +#define CAMEL_TYPE_GW_LISTENER (camel_gw_listener_get_type ()) +#define CAMEL_GW_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAMEL_TYPE_GW_LISTENER, CamelGwListener)) +#define CAMEL_GW_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CAMEL_TYPE_GW_LISTENER, CamelGWListenerClass)) +#define CAMEL_IS_GWLISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAMEL_TYPE_GW_LISTENER)) +#define CAMEL_IS_GW_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CAMEL_TYPE_GW_LISTENER)) + +typedef struct _CamelGwListener CamelGwListener; +typedef struct _CamelGwListenerClass CamelGwListenerClass; +typedef struct _CamelGwListenerPrivate CamelGwListenerPrivate; +struct _CamelGwListener { + GObject parent; + + CamelGwListenerPrivate *priv; +}; + +struct _CamelGwListenerClass { + GObjectClass parent_class; + + +}; + +GType camel_gw_listener_get_type (void); +CamelGwListener *camel_gw_listener_new (void); + +G_END_DECLS + +#endif + diff --git a/plugins/groupwise-features/groupwise-account-setup.c b/plugins/groupwise-features/groupwise-account-setup.c new file mode 100644 index 0000000000..4ac187f20a --- /dev/null +++ b/plugins/groupwise-features/groupwise-account-setup.c @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Sivaiah Nallagatla <snallagatla@novell.com> + * Copyright (C) 2004 Novell, Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#include "camel-gw-listener.h" +#include <gtk/gtk.h> +#include "mail/em-config.h" + +static CamelGwListener *config_listener = NULL; + +int e_plugin_lib_enable (EPluginLib *ep, int enable); +GtkWidget* org_gnome_gw_account_setup(struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data); + +static void +free_groupwise_listener ( void ) +{ + g_object_unref (config_listener); +} + +int +e_plugin_lib_enable (EPluginLib *ep, int enable) +{ + if (!config_listener) { + config_listener = camel_gw_listener_new (); + g_atexit ( free_groupwise_listener ); + } + + return 0; +} + + +GtkWidget * +org_gnome_gw_account_setup(struct _EPlugin *epl, struct _EConfigHookItemFactoryData *data) +{ + GtkWidget *w; + + if (data->old) + return data->old; + /* FIXME, with new soap camel provider we don't need extra settings in receiving options page, Remove them + from camel-groupwise-provider.c once soap provider is ready and add any groupwise sepcific settings like "add contacts automatically to Frequent contacts folder" here*/ + + return NULL; +} diff --git a/plugins/groupwise-features/install-shared.c b/plugins/groupwise-features/install-shared.c new file mode 100644 index 0000000000..d170182c9f --- /dev/null +++ b/plugins/groupwise-features/install-shared.c @@ -0,0 +1,233 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Vivek Jain <jvivek@novell.com> + * + * Copyright 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <glib.h> +#include <gnome.h> +#include <gtk/gtk.h> +#include <libgnomeui/libgnomeui.h> +#include <libgnome/gnome-i18n.h> +#include <gconf/gconf-client.h> +#include <e-util/e-config.h> +#include <mail/em-config.h> +#include <mail/em-event.h> +#include <mail/mail-component.h> +#include <camel/camel-mime-message.h> +#include <camel/camel-folder.h> +#include <camel/camel-stream.h> +#include <camel/camel-session.h> +#include <camel/camel-stream-mem.h> +#include <camel/camel-data-wrapper.h> +#include <camel/camel-multipart.h> +#include <mail/em-folder-tree.h> +#include <mail/mail-config.h> +#include <mail/em-folder-selector.h> +#include <camel/camel-medium.h> +#include <e-gw-connection.h> +#include <share-folder.h> + +CamelSession *session; +struct AcceptData { + const char *item_id; + EMFolderTreeModel *model; +}; + + +void org_gnome_popup_wizard (EPlugin *ep, EMEventTargetMessage *target); + +static void +install_folder_response (EMFolderSelector *emfs, int response, gpointer *data) +{ + struct AcceptData *accept_data = (struct AcceptData *)data; + EMFolderTreeModel *model; + const char *uri, *path; + int parts = 0; + gchar **names; + gchar *folder_name; + gchar *parent_name; + gchar *container_id,*item_id; + CamelException ex; + CamelStore *store; + CamelFolder *folder; + CamelFolderChangeInfo *changes; + EAccount *account; + CamelProvider *provider; + EGwConnection *cnc; + + if (response == GTK_RESPONSE_CANCEL){ + gtk_widget_destroy (GTK_WIDGET (emfs)); + } else { + model = accept_data->model; + item_id = accept_data->item_id; + uri = em_folder_selector_get_selected_uri (emfs); + path = em_folder_selector_get_selected_path (emfs); + names = g_strsplit (path, "/", -1); + if(names == NULL){ + folder_name = (gchar *)path; + parent_name = NULL; + } else { + while (names [parts]) + parts++; + folder_name = names[parts -1]; + if (parts >= 2) + parent_name = names[parts -2]; + else + parent_name = NULL; + } + camel_exception_init (&ex); + if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) { + camel_exception_clear (&ex); + return; + } + + cnc = get_cnc (store); + if(E_IS_GW_CONNECTION (cnc)) { + container_id = get_container_id (cnc, parent_name); + + if(e_gw_connection_accept_shared_folder (cnc, folder_name, container_id, item_id, NULL) == E_GW_CONNECTION_STATUS_OK) { + + + folder = camel_store_get_folder (store, "Mailbox", 0, NULL); + /*changes = camel_folder_change_info_new (); + camel_folder_change_info_remove_uid (changes, (char *) item_id); + camel_folder_summary_remove_uid (folder->summary, item_id);*/ + //camel_folder_delete_message (folder, item_id); + camel_folder_set_message_flags (folder, item_id, CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED); + camel_folder_summary_touch (folder->summary); + //camel_object_trigger_event (CAMEL_OBJECT (folder), "folder_changed", changes); + uri = camel_url_to_string (((CamelService *) store)->url, CAMEL_URL_HIDE_ALL); + account = mail_config_get_account_by_source_url (uri); + uri = account->source->url; + em_folder_tree_model_remove_store (model, store); + camel_exception_init (&ex); + if (!(provider = camel_provider_get(uri, &ex))) { + camel_exception_clear (&ex); + return; + } + + /* make sure the new store belongs in the tree */ + if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE)) + return; + + em_folder_tree_model_add_store (model, store, account->name); + camel_object_unref (store); + } + } + + g_strfreev(names); + gtk_widget_destroy ((GtkWidget *)emfs); + } + +} + +static void +accept_clicked(GnomeDruidPage *page, GtkWidget *druid, const char *id) +{ + EMFolderTreeModel *model; + EMFolderTree *folder_tree; + GtkWidget *dialog ; + struct AcceptData *accept_data; + char *uri; + accept_data = g_new0(struct AcceptData, 1); + model = mail_component_peek_tree_model (mail_component_peek ()); + folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model); + dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:")); + uri = em_folder_tree_get_selected_uri(folder_tree); + em_folder_selector_set_selected ((EMFolderSelector *) dialog, uri); + g_free(uri); + accept_data->item_id = id; + accept_data->model = model; + g_signal_connect (dialog, "response", G_CALLBACK (install_folder_response), accept_data); + gtk_window_set_title (GTK_WINDOW (dialog), "Install Shared Folder"); + gtk_widget_destroy (druid); + gtk_widget_show (dialog); + +} + +void +org_gnome_popup_wizard (EPlugin *ep, EMEventTargetMessage *target) +{ + const CamelInternetAddress *from_addr = NULL; + const char *name, *item_id; + const char *email; + GtkWidget *window; + GnomeDruid *wizard; + GnomeDruidPageEdge *title_page; + CamelMimeMessage *msg = (CamelMimeMessage *) target->message ; + CamelStreamMem *content ; + CamelDataWrapper *dw ; + CamelMimePart *mime_part ; + CamelMultipart *mp ; + char *notification; + char *start_message; + char *buffer = NULL; + + if (!msg) + return ; + + mime_part = CAMEL_MIME_PART(msg) ; + notification = (char *)camel_medium_get_header (CAMEL_MEDIUM(msg),"X-notification") ; + if (!notification) { + return ; + + } else { + mp = (CamelMultipart *) camel_medium_get_content_object (CAMEL_MEDIUM (msg)) ; + dw = camel_data_wrapper_new () ; + content = (CamelStreamMem *)camel_stream_mem_new(); + if (!mp) + return ; + + if (CAMEL_IS_MULTIPART (mp)) { + mime_part = camel_multipart_get_part (mp, 0) ; + dw = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part)) ; + camel_data_wrapper_write_to_stream(dw, (CamelStream *)content) ; + buffer = g_malloc0 (content->buffer->len+1) ; + buffer = memcpy (buffer, content->buffer->data, content->buffer->len) ; + + } else { + dw = camel_medium_get_content_object (CAMEL_MEDIUM (msg)) ; + camel_data_wrapper_write_to_stream(dw, (CamelStream *)content) ; + buffer = g_malloc0 (content->buffer->len+1) ; + buffer = memcpy (buffer, content->buffer->data, content->buffer->len) ; + } + + from_addr = camel_mime_message_get_from ((CamelMimeMessage *)target->message); + if (camel_internet_address_get (from_addr,0, &name, &email)) { + start_message = g_strconcat (" The User ", "'", name, "'" ," has shared a folder with you\n\n", " Message from ", "'" , name, "'\n\n\n", buffer, "\n\n\n", "Click 'Forward' to install the shared folder\n\n",NULL); + title_page = GNOME_DRUID_PAGE_EDGE (gnome_druid_page_edge_new_with_vals(GNOME_EDGE_START, TRUE, "Install the shared folder", start_message, NULL, NULL, NULL)); + wizard = GNOME_DRUID (gnome_druid_new_with_window ("Shared Folder Installation", NULL, TRUE, (GtkWidget**)(&window))); + gtk_window_set_position (GTK_WINDOW (window) , GTK_WIN_POS_CENTER_ALWAYS); + gnome_druid_append_page(wizard, GNOME_DRUID_PAGE(title_page)); + gtk_widget_show_all (GTK_WIDGET (title_page)); + item_id = camel_mime_message_get_message_id (msg); + g_signal_connect (title_page, "next", G_CALLBACK(accept_clicked), item_id); + } else + g_warning ("Could not get the sender name"); + + g_free (buffer) ; + g_free (start_message) ; + } +} + diff --git a/plugins/groupwise-features/mail-send-options.c b/plugins/groupwise-features/mail-send-options.c new file mode 100644 index 0000000000..905e919ffe --- /dev/null +++ b/plugins/groupwise-features/mail-send-options.c @@ -0,0 +1,150 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Authors: Parthasarathi Susarla <sparthasarathi@novell.com> + * + * Copyright 2004 Novell, Inc. (www.novell.com) + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <string.h> +#include <stdio.h> + +#include <glib.h> +#include <glib/gi18n.h> + +#include "mail-send-options.h" + +#include "mail/em-menu.h" +#include "mail/em-utils.h" + +#include "composer/e-msg-composer.h" +#include "e-util/e-account.h" + +#include "widgets/misc/e-send-options.h" + +static ESendOptionsDialog * dialog = NULL ; + +void org_gnome_compose_send_options (EPlugin *ep, EMMenuTargetWidget *t); + +static time_t +add_day_to_time (time_t time, int days) +{ + struct tm *tm; + + tm = localtime (&time); + tm->tm_mday += days; + tm->tm_isdst = -1; + + return mktime (tm); +} + +static void +send_options_commit (EMsgComposer *comp, gpointer user_data) +{ + if (!user_data && !E_IS_SENDOPTIONS_DIALOG (user_data)) + return; + + if (dialog) { + g_object_unref (dialog); + dialog = NULL; + } +} + +void +org_gnome_compose_send_options (EPlugin *ep, EMMenuTargetWidget *t) +{ + struct _EMenuTarget menu = t->target ; + EMsgComposer *comp = (struct _EMsgComposer *)menu.widget ; + EAccount *account = NULL; + char *temp = NULL; + char *url; + char value [100]; + + account = e_msg_composer_get_preferred_account (comp) ; + url = g_strdup (account->transport->url) ; + temp = strstr (url, "groupwise") ; + if (!temp) { + g_print ("Sorry send options only available for a groupwise account\n") ; + } + g_free (temp) ; + /*disply the send options dialog*/ + if (!dialog) { + g_print ("New dialog\n\n") ; + dialog = e_sendoptions_dialog_new () ; + } + + e_sendoptions_dialog_run (dialog, menu.widget, E_ITEM_MAIL) ; + + if (dialog->data->gopts->reply_enabled) { + if (dialog->data->gopts->reply_convenient) + e_msg_composer_add_header (comp, X_REPLY_CONVENIENT ,"1" ) ; + else if (dialog->data->gopts->reply_within) { + time_t t; + t = add_day_to_time (time (NULL), dialog->data->gopts->reply_within); + strftime (value, 17, "%Y%m%dT%H%M%SZ", gmtime (&t)); + e_msg_composer_add_header (comp, X_REPLY_WITHIN , value) ; + } + } + + if (dialog->data->gopts->expiration_enabled) { + if (dialog->data->gopts->expire_after != 0) { + time_t t; + t = add_day_to_time (time (NULL), dialog->data->gopts->expire_after); + strftime (value, 17, "%Y%m%dT%H%M%SZ", gmtime (&t)); + e_msg_composer_add_header (comp, X_EXPIRE_AFTER, value) ; + } + } + if (dialog->data->gopts->delay_enabled) { + strftime (value, 17, "%Y%m%dT%H%M%SZ", gmtime (&dialog->data->gopts->delay_until)); + e_msg_composer_add_header (comp, X_DELAY_UNTIL, value) ; + } + + /*Status Tracking Options*/ + if (dialog->data->sopts->tracking_enabled) { + temp = g_strdup_printf ("%d",dialog->data->sopts->track_when) ; + e_msg_composer_add_header (comp, X_TRACK_WHEN, temp) ; + g_free (temp) ; + } + + if (dialog->data->sopts->autodelete) { + e_msg_composer_add_header (comp, X_AUTODELETE, "1") ; + } + if (dialog->data->sopts->opened) { + temp = g_strdup_printf ("%d",dialog->data->sopts->opened) ; + e_msg_composer_add_header (comp, X_RETURN_NOTIFY_OPEN, temp) ; + g_free (temp) ; + } + if (dialog->data->sopts->declined) { + temp = g_strdup_printf ("%d",dialog->data->sopts->declined) ; + e_msg_composer_add_header (comp, X_RETURN_NOTIFY_DELETE, temp) ; + g_free (temp) ; + } + + if (dialog->data->gopts->priority) { + temp = g_strdup_printf ("%d",dialog->data->gopts->priority); + e_msg_composer_add_header (comp, X_SEND_OPT_PRIORITY,temp); + g_free (temp); + } + + g_signal_connect (GTK_WIDGET (comp), "destroy", + G_CALLBACK (send_options_commit), dialog); +} + + diff --git a/plugins/groupwise-features/mail-send-options.h b/plugins/groupwise-features/mail-send-options.h new file mode 100644 index 0000000000..0e6ef03ec5 --- /dev/null +++ b/plugins/groupwise-features/mail-send-options.h @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Authors: Parthasarathi Susarla <sparthasarathi@novell.com> + * + * Copyright 2004 Novell, Inc. (www.novell.com) + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef __GW_SEND_OPTIONS__ +#define __GW_SEND_OPTIONS__ + +/*Headers for send options*/ +#define X_SEND_OPTIONS "X-gw-send-options" +/*General Options*/ +#define X_SEND_OPT_PRIORITY "X-gw-send-opt-priority" +#define X_REPLY_CONVENIENT "X-reply-convenient" +#define X_REPLY_WITHIN "X-reply-within" +#define X_EXPIRE_AFTER "X-expire-after" +#define X_DELAY_UNTIL "X-delay-until" + +/*Status Tracking Options*/ +#define X_TRACK_WHEN "X-track-when" +#define X_AUTODELETE "X-auto-delete" +#define X_RETURN_NOTIFY_OPEN "X-return-notify-open" +#define X_RETURN_NOTIFY_DELETE "X-return-notify-delete" + +#endif /*__GW_SEND_OPTIONS__*/ diff --git a/plugins/groupwise-features/org-gnome-compose-send-options.xml b/plugins/groupwise-features/org-gnome-compose-send-options.xml new file mode 100644 index 0000000000..c5947c6a33 --- /dev/null +++ b/plugins/groupwise-features/org-gnome-compose-send-options.xml @@ -0,0 +1,17 @@ +<Root> + <commands> + <cmd name="EPSOSendOptions" _label="Send Options" + _tip="Add Send Options to groupwise messages"/> + </commands> + + <menu> + <submenu name="Insert"> + <placeholder name="Component"> + <separator f="" name="sendoptions1"/> + <menuitem name="EPSOSendOptions" verb=""/> + <separator f="" name="sendoptions2"/> + </placeholder> + </submenu> + + </menu> +</Root> diff --git a/plugins/groupwise-features/org-gnome-groupwise-features.eplug.xml b/plugins/groupwise-features/org-gnome-groupwise-features.eplug.xml new file mode 100644 index 0000000000..504fa39a36 --- /dev/null +++ b/plugins/groupwise-features/org-gnome-groupwise-features.eplug.xml @@ -0,0 +1,107 @@ +<?xml version="1.0"?> +<e-plugin-list> + <e-plugin id="org.gnome.evolution.groupwise_features" type="shlib" _name="Groupwise Features" + location="@PLUGINDIR@/liborg-gnome-groupwise-features.so"> + <author name="Sivaiah Nallagatla" email="snallagatla@novell.com" /> + <author name="Vivek Jain" email="jvivek@novell.com" /> + <author name="Chenthill Palanisamy" email="pchenthill@novell.com"/> + <author name="Parthasarathi Susarla" email="sparthasarathi@novell.com"/> + <_description>A consolidated plugin for the features in Groupwise accounts.</_description> + <hook class="org.gnome.evolution.mail.config:1.0"> + <group id="org.gnome.evolution.mail.config.accountDruid" target="account"> + <item + type="item_table" + path="20.receive_options/30.soapport/50.dummy" + factory="org_gnome_gw_account_setup"/> + </group> + <group id="org.gnome.evolution.mail.config.accountEditor" target="account"> + <item + type="item_table" + path="20.receive_options/30.soapport/50.dummy" + factory="org_gnome_gw_account_setup"/> + </group> + <group id="org.gnome.evolution.mail.config.accountWizard" target="account"> + <item + type="item_table" + path="20.receive_options/30.soapport/50.dummy" + factory="org_gnome_gw_account_setup"/> + </group> + <group id="org.gnome.evolution.mail.folderConfig" target="folder" + check= "shared_folder_check" + commit="shared_folder_commit" + abort ="shared_folder_abort"> + <item + type="page" + path="10.shared" + label="Shared" + factory="org_gnome_shared_folder_factory"/> + </group> + <group id="org.gnome.evolution.mail.config.accountEditor" target="account" + check = "send_options_changed" + commit = "send_options_commit" + abort = "send_options_abort"> + <item + type="section" + path="40.defaults/50.send_options" + label="Send Options" + factory="org_gnome_send_options" /> + </group> + </hook> + <hook class="org.gnome.evolution.mail.events:1.0"> + <event + target="message" + id="message.reading" + type="pass" + handle="org_gnome_popup_wizard"/> + </hook> + <hook class="org.gnome.evolution.mail.popup:1.0"> + <menu id="org.gnome.evolution.mail.foldertree.popup" target="folder"> + <item + type="item" + path="20.emc.00" + label="_New Shared Folder" + activate="org_gnome_create_option" + enable="delete" visible="delete"/> + </menu> + <menu id="org.gnome.evolution.mail.folderview.popup" target="select"> + <item + type="item" + path="21.gw_status_tracking" + label="Track Message Status" + enable="one" + visible="one" + activate="org_gnome_track_status"/> + </menu> + </hook> + <hook class="org.gnome.evolution.addressbook.config:1.0"> + <group + id="com.novell.evolution.addressbook.config.accountEditor" target="source" + commit="commit_groupwise_addressbook"> + <item + type="item" + path="00.general/10.display/00.gw_dummy" + factory="e_book_groupwise_dummy"/> + </group> + <group + id="com.novell.evolution.addressbook.config.accountEditor" target="source" + commit="commit_groupwise_addressbook"> + <item + type="item" + path="00.general/10.display/00.gw_dummy" + factory="e_book_groupwise_dummy"/> + </group> + </hook> + <hook class="org.gnome.evolution.mail.bonobomenu:1.0"> + <menu id="org.gnome.evolution.mail.composer" target="select"> + <ui file="@PLUGINDIR@/org-gnome-compose-send-options.xml"/> + <item + type="item" + verb="EPSOSendOptions" + path="/commands/EPSOSendOptions" + enable="one" + activate="org_gnome_compose_send_options"/> + </menu> + </hook> + </e-plugin> + +</e-plugin-list> diff --git a/plugins/groupwise-features/org-gnome-shared-folder.errors.xml b/plugins/groupwise-features/org-gnome-shared-folder.errors.xml new file mode 100644 index 0000000000..6a1339210f --- /dev/null +++ b/plugins/groupwise-features/org-gnome-shared-folder.errors.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<error-list domain="org.gnome.evolution.mail_shared_folder"> +<error id="invalid-user" type="error"> +<primary>Invalid user</primary> +<secondary> +You cannot share folder with specified user "{0}" +</secondary> +</error> + +<error id="no-user" type="error"> +<primary>Specify User</primary> +<secondary> + You have to specify a user name whom you want to add to the list +</secondary> +</error> + + +</error-list> + diff --git a/plugins/groupwise-features/properties.glade b/plugins/groupwise-features/properties.glade new file mode 100644 index 0000000000..e2fce0be65 --- /dev/null +++ b/plugins/groupwise-features/properties.glade @@ -0,0 +1,860 @@ +<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> +<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd"> + +<glade-interface> +<requires lib="gnome"/> + +<widget class="GtkWindow" id="main_page"> + <property name="title" translatable="yes">Folder Properties</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + + <child> + <widget class="GtkNotebook" id="sharing_props"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="show_tabs">True</property> + <property name="show_border">True</property> + <property name="tab_pos">GTK_POS_TOP</property> + <property name="scrollable">False</property> + <property name="enable_popup">False</property> + + <child> + <widget class="GtkVBox" id="vboxSharing"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkVBox" id="vboxSharingOptions"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkHBox" id="hbox186"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label539"> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox190"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkRadioButton" id="radNotShared"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Not Shared</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkRadioButton" id="radShared"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">_Shared With ...</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + <property name="group">radNotShared</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox194"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkHBox" id="hbox226"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkVBox" id="vbox195"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkHBox" id="hbox227"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label557"> + <property name="visible">True</property> + <property name="label" translatable="yes">Name:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="entry4"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="users"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Users :</b></property> + <property name="use_underline">False</property> + <property name="use_markup">True</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">6</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow4"> + <property name="width_request">282</property> + <property name="height_request">150</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <placeholder/> + </child> + </widget> + <packing> + <property name="padding">6</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkVBox" id="vbox196"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkButton" id="Address"> + <property name="width_request">96</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment6"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox232"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image5"> + <property name="visible">True</property> + <property name="stock">gtk-jump-to</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label563"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Contacts...</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkButton" id="Add"> + <property name="width_request">61</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment4"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox229"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image3"> + <property name="visible">True</property> + <property name="stock">gtk-add</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label561"> + <property name="width_request">29</property> + <property name="visible">True</property> + <property name="label" translatable="yes">_Add</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkButton" id="Remove"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment5"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox230"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image4"> + <property name="visible">True</property> + <property name="stock">gtk-remove</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label562"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Remove</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <placeholder/> + </child> + + <child> + <widget class="GtkButton" id="Notification"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + + <child> + <widget class="GtkAlignment" id="alignment7"> + <property name="visible">True</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xscale">0</property> + <property name="yscale">0</property> + <property name="top_padding">0</property> + <property name="bottom_padding">0</property> + <property name="left_padding">0</property> + <property name="right_padding">0</property> + + <child> + <widget class="GtkHBox" id="hbox233"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">2</property> + + <child> + <widget class="GtkImage" id="image6"> + <property name="visible">True</property> + <property name="stock">gnome-stock-mail-new</property> + <property name="icon_size">4</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label564"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Cutomize notification message</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + </child> + </widget> + </child> + </widget> + <packing> + <property name="padding">11</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + </widget> + <packing> + <property name="tab_expand">False</property> + <property name="tab_fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="lblSharing"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Sharing</property> + <property name="use_underline">True</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_CENTER</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="type">tab</property> + </packing> + </child> + </widget> + </child> +</widget> + +<widget class="GtkWindow" id="window1"> + <property name="visible">True</property> + <property name="title" translatable="yes">Shared Folder Notification</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_CENTER</property> + <property name="modal">False</property> + <property name="resizable">True</property> + <property name="destroy_with_parent">False</property> + <property name="decorated">True</property> + <property name="skip_taskbar_hint">False</property> + <property name="skip_pager_hint">False</property> + <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> + <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> + + <child> + <widget class="GtkVBox" id="vbox191"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkLabel" id="label551"> + <property name="visible">True</property> + <property name="label" translatable="yes">The participants will receive the following notification. +</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_CENTER</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.66</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">1</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox223"> + <property name="height_request">309</property> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">12</property> + + <child> + <widget class="GtkVBox" id="vbox193"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">5</property> + + <child> + <widget class="GtkLabel" id="label553"> + <property name="visible">True</property> + <property name="label" translatable="yes">Subject</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_CENTER</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkEntry" id="entry3"> + <property name="width_request">158</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="visibility">True</property> + <property name="max_length">0</property> + <property name="text" translatable="yes"></property> + <property name="has_frame">True</property> + <property name="invisible_char" translatable="yes">*</property> + <property name="activates_default">False</property> + </widget> + <packing> + <property name="padding">6</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkLabel" id="label554"> + <property name="visible">True</property> + <property name="label" translatable="yes">Message</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_CENTER</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkScrolledWindow" id="scrolledwindow3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property> + <property name="shadow_type">GTK_SHADOW_NONE</property> + <property name="window_placement">GTK_CORNER_TOP_LEFT</property> + + <child> + <widget class="GtkTextView" id="textview1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">True</property> + <property name="overwrite">False</property> + <property name="accepts_tab">True</property> + <property name="justification">GTK_JUSTIFY_LEFT</property> + <property name="wrap_mode">GTK_WRAP_NONE</property> + <property name="cursor_visible">True</property> + <property name="pixels_above_lines">0</property> + <property name="pixels_below_lines">0</property> + <property name="pixels_inside_wrap">0</property> + <property name="left_margin">0</property> + <property name="right_margin">0</property> + <property name="indent">0</property> + <property name="text" translatable="yes"></property> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + + <child> + <widget class="GtkHBox" id="hbox224"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">0</property> + + <child> + <widget class="GtkLabel" id="label555"> + <property name="width_request">248</property> + <property name="visible">True</property> + <property name="label" translatable="yes"></property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.52</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkHButtonBox" id="hbuttonbox2"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + <property name="spacing">6</property> + + <child> + <widget class="GtkButton" id="nCancel"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-cancel</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <signal name="clicked" handler="on_nCancel_clicked" last_modification_time="Tue, 23 Nov 2004 10:56:42 GMT"/> + </widget> + </child> + + <child> + <widget class="GtkButton" id="nOK"> + <property name="visible">True</property> + <property name="can_default">True</property> + <property name="can_focus">True</property> + <property name="label">gtk-ok</property> + <property name="use_stock">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <signal name="clicked" handler="on_nOK_clicked" last_modification_time="Tue, 23 Nov 2004 10:57:50 GMT"/> + </widget> + </child> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + <packing> + <property name="padding">42</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </widget> + </child> +</widget> + +</glade-interface> diff --git a/plugins/groupwise-features/send-options.c b/plugins/groupwise-features/send-options.c new file mode 100644 index 0000000000..f3df4a32e8 --- /dev/null +++ b/plugins/groupwise-features/send-options.c @@ -0,0 +1,557 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Authors: Chenthill Palanisamy (pchenthill@novell.com) + * + * Copyright 2004 Novell, Inc. (www.novell.com) + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <libgnome/gnome-i18n.h> +#include <glade/glade.h> +#include <gtk/gtk.h> +#include "mail/em-account-editor.h" +#include "mail/em-config.h" +#include "e-util/e-account.h" +#include <widgets/misc/e-send-options.h> +#include <mail/em-config.h> +#include <e-gw-connection.h> +#include <camel/camel-url.h> +#include <libecal/e-cal-time-util.h> +#include <libedataserver/e-source-list.h> +#include <libedataserverui/e-passwords.h> + +ESendOptionsDialog *sod = NULL; +GtkWidget *parent; +EGwConnection *n_cnc; +EGwSendOptions *opts = NULL; +gboolean changed = FALSE; +EAccount *account; + +GtkWidget* org_gnome_send_options (EPlugin *epl, EConfigHookItemFactoryData *data); +void send_options_commit (EPlugin *epl, EConfigHookItemFactoryData *data); +void send_options_changed (EPlugin *epl, EConfigHookItemFactoryData *data); +void send_options_abort (EPlugin *epl, EConfigHookItemFactoryData *data); + +static EGwConnection * +get_cnc () +{ + EGwConnection *cnc; + char *uri, *failed_auth, *key, *prompt, *password = NULL; + CamelURL *url; + const char *poa_address, *use_ssl, *soap_port; + gboolean remember; + + url = camel_url_new (account->source->url, NULL); + if (url == NULL) + return NULL; + poa_address = url->host; + if (!poa_address || strlen (poa_address) ==0) + return NULL; + + soap_port = camel_url_get_param (url, "soap_port"); + if (!soap_port || strlen (soap_port) == 0) + soap_port = "7191"; + use_ssl = camel_url_get_param (url, "use_ssl"); + + key = g_strdup_printf ("groupwise://%s@%s/", url->user, poa_address); + + if (!g_str_equal (use_ssl, "never")) + uri = g_strdup_printf ("https://%s:%s/soap", poa_address, soap_port); + else + uri = g_strdup_printf ("http://%s:%s/soap", poa_address, soap_port); + + failed_auth = ""; + cnc = NULL; + + prompt = g_strdup_printf (_("%sEnter password for %s (user %s)"), + failed_auth, poa_address, url->user); + + password = e_passwords_get_password ("Groupwise", key); + if (!password) + password = e_passwords_ask_password (prompt, "Groupwise", key, prompt, + E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET, &remember, NULL); + g_free (prompt); + + cnc = e_gw_connection_new (uri, url->user, password); + if (!E_IS_GW_CONNECTION(cnc) && use_ssl && g_str_equal (use_ssl, "when-possible")) { + char *http_uri = g_strconcat ("http://", uri + 8, NULL); + cnc = e_gw_connection_new (http_uri, url->user, password); + g_free (http_uri); + } + + camel_url_free (url); + return cnc; +} + + +static void +e_send_options_load_general_opts (ESendOptionsGeneral *gopts, EGwSendOptionsGeneral *ggopts) +{ + time_t temp; + + temp = time (NULL); + + gopts->priority = ggopts->priority; + + gopts->reply_enabled = ggopts->reply_enabled; + gopts->reply_convenient = ggopts->reply_convenient; + gopts->reply_within = ggopts->reply_within; + + gopts->expiration_enabled = ggopts->expiration_enabled; + gopts->expire_after = ggopts->expire_after; + + gopts->delay_enabled = ggopts->delay_enabled; + + /* TODO convert int to timet comparing the current day */ + if (ggopts->delay_until) { + gopts->delay_until = time_add_day_with_zone (temp, ggopts->delay_until, NULL); + } else + gopts->delay_until = 0; +} + +static void +e_send_options_load_status_options (ESendOptionsStatusTracking *sopts, EGwSendOptionsStatusTracking *gsopts) +{ + sopts->tracking_enabled = gsopts->tracking_enabled; + sopts->track_when = gsopts->track_when; + + sopts->autodelete = gsopts->autodelete; + + sopts->opened = gsopts->opened; + sopts->accepted = gsopts->accepted; + sopts->declined = gsopts->declined; + sopts->completed = gsopts->completed; +} + +static void +e_send_options_load_default_data (EGwSendOptions *opts, ESendOptionsDialog *sod) +{ + EGwSendOptionsGeneral *ggopts; + EGwSendOptionsStatusTracking *gmopts; + EGwSendOptionsStatusTracking *gcopts; + EGwSendOptionsStatusTracking *gtopts; + + ggopts = e_gw_sendoptions_get_general_options (opts); + gmopts = e_gw_sendoptions_get_status_tracking_options (opts, "mail"); + gcopts = e_gw_sendoptions_get_status_tracking_options (opts, "calendar"); + gtopts = e_gw_sendoptions_get_status_tracking_options (opts, "task"); + + e_send_options_load_general_opts (sod->data->gopts, ggopts); + e_send_options_load_status_options (sod->data->mopts, gmopts); + e_send_options_load_status_options (sod->data->copts, gcopts); + e_send_options_load_status_options (sod->data->topts, gtopts); +} + +static void +e_sendoptions_clicked_cb (GtkWidget *button, gpointer data) +{ + EGwConnectionStatus status; + account = (EAccount *) data; + if (!sod) { + sod = e_sendoptions_dialog_new (); + e_sendoptions_set_global (sod, TRUE); + if (!n_cnc) + n_cnc = get_cnc (); + + if (!n_cnc) { + g_warning ("Send Options: Could not get the connection to the server \n"); + return; + } + + status = e_gw_connection_get_settings (n_cnc, &opts); + if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION) + status = e_gw_connection_get_settings (n_cnc, &opts); + if (status != E_GW_CONNECTION_STATUS_OK) { + g_warning ("Send Options: Could not get the settings from the server"); + return; + } + e_send_options_load_default_data (opts, sod); + } + + if (n_cnc) + e_sendoptions_dialog_run (sod, parent ? parent : NULL, E_ITEM_NONE); + else + return; +} + +GtkWidget * +org_gnome_send_options (EPlugin *epl, EConfigHookItemFactoryData *data) +{ + EMConfigTargetAccount *target_account; + GtkWidget *frame, *button, *label, *vbox; + + target_account = (EMConfigTargetAccount *)data->config->target; + account = target_account->account; + + if(!g_strrstr (account->source->url, "groupwise://")) + return NULL; + + vbox = gtk_vbox_new (FALSE, 0); + frame = gtk_frame_new (""); + label = gtk_frame_get_label_widget (GTK_FRAME (frame)); + gtk_label_set_markup (GTK_LABEL (label), "<b>Send Options</b>"); + button = gtk_button_new_with_label ("Advanced send options"); + gtk_widget_show (button); + + g_signal_connect(button, "clicked", + G_CALLBACK (e_sendoptions_clicked_cb), account); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (data->parent)); + if (!GTK_WIDGET_TOPLEVEL (parent)) + parent = NULL; + + gtk_widget_set_size_request (button, 10, -1); + gtk_box_pack_start (GTK_BOX (vbox), frame, 0, 0, 0); + gtk_container_add (GTK_CONTAINER (frame), button); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); + gtk_widget_show (frame); + gtk_box_set_spacing (GTK_BOX (data->parent), 12); + gtk_box_pack_start (GTK_BOX (data->parent), vbox, FALSE, FALSE, 0); + + return vbox; +} + +static void +send_options_finalize () +{ + if (n_cnc) { + g_object_unref (n_cnc); + n_cnc = NULL; + } + + if (sod) { + g_object_unref (sod); + sod = NULL; + } + + if (opts) { + g_object_unref (opts); + opts = NULL; + } +} + +static void +e_send_options_copy_general_opts (ESendOptionsGeneral *gopts, EGwSendOptionsGeneral *ggopts) +{ + time_t temp; + + temp = time (NULL); + + ggopts->priority = gopts->priority; + + ggopts->reply_enabled = gopts->reply_enabled; + ggopts->reply_convenient = gopts->reply_convenient; + ggopts->reply_within = gopts->reply_within; + + ggopts->expire_after = gopts->expire_after; + + if (gopts->expire_after == 0) { + ggopts->expiration_enabled = FALSE; + gopts->expiration_enabled = FALSE; + } else + ggopts->expiration_enabled = gopts->expiration_enabled; + + ggopts->delay_enabled = gopts->delay_enabled; + + if (gopts->delay_until) { + int diff; + icaltimetype temp, current; + + temp = icaltime_from_timet (gopts->delay_until, 0); + current = icaltime_today (); + diff = temp.day - current.day; + ggopts->delay_until = diff; + } else + ggopts->delay_until = 0; +} + +static void +e_send_options_copy_status_options (ESendOptionsStatusTracking *sopts, EGwSendOptionsStatusTracking *gsopts) +{ + gsopts->tracking_enabled = sopts->tracking_enabled; + gsopts->track_when = sopts->track_when; + + gsopts->autodelete = sopts->autodelete; + + gsopts->opened = sopts->opened; + gsopts->accepted = sopts->accepted; + gsopts->declined = sopts->declined; + gsopts->completed = sopts->completed; +} + +static gboolean +check_status_options_changed (EGwSendOptionsStatusTracking *n_sopts, EGwSendOptionsStatusTracking *o_sopts) +{ + return (!(n_sopts->tracking_enabled == o_sopts->tracking_enabled + && n_sopts->track_when == o_sopts->track_when + && n_sopts->autodelete == o_sopts->autodelete + && n_sopts->opened == o_sopts->opened + && n_sopts->declined == o_sopts->declined + && n_sopts->accepted == o_sopts->accepted + && n_sopts->completed == o_sopts->completed)); + +} + +static gboolean +check_general_changed (EGwSendOptionsGeneral *n_gopts, EGwSendOptionsGeneral *o_gopts) +{ + return (!(n_gopts->priority == o_gopts->priority + && n_gopts->delay_enabled == o_gopts->delay_enabled + && n_gopts->delay_until == o_gopts->delay_until + && n_gopts->reply_enabled == o_gopts->reply_enabled + && n_gopts->reply_convenient == o_gopts->reply_convenient + && n_gopts->reply_within == o_gopts->reply_within + && n_gopts->expiration_enabled == o_gopts->expiration_enabled + && n_gopts->expire_after == o_gopts->expire_after)); +} + +static void +send_options_copy_check_changed (EGwSendOptions *n_opts) +{ + EGwSendOptionsGeneral *ggopts, *o_gopts; + EGwSendOptionsStatusTracking *gmopts, *o_gmopts ; + EGwSendOptionsStatusTracking *gcopts, *o_gcopts; + EGwSendOptionsStatusTracking *gtopts, *o_gtopts; + + ggopts = e_gw_sendoptions_get_general_options (n_opts); + gmopts = e_gw_sendoptions_get_status_tracking_options (n_opts, "mail"); + gcopts = e_gw_sendoptions_get_status_tracking_options (n_opts, "calendar"); + gtopts = e_gw_sendoptions_get_status_tracking_options (n_opts, "task"); + + o_gopts = e_gw_sendoptions_get_general_options (opts); + o_gmopts = e_gw_sendoptions_get_status_tracking_options (opts, "mail"); + o_gcopts = e_gw_sendoptions_get_status_tracking_options (opts, "calendar"); + o_gtopts = e_gw_sendoptions_get_status_tracking_options (opts, "task"); + + e_send_options_copy_general_opts (sod->data->gopts, ggopts); + e_send_options_copy_status_options (sod->data->mopts, gmopts); + e_send_options_copy_status_options (sod->data->copts, gcopts); + e_send_options_copy_status_options (sod->data->topts, gtopts); + + if (check_general_changed (ggopts, o_gopts)) + changed = TRUE; + if (check_status_options_changed (gmopts, o_gmopts)) + changed = TRUE; + if (check_status_options_changed (gcopts, o_gcopts)) + changed = TRUE; + if (check_status_options_changed (gtopts, o_gtopts)) + changed = TRUE; +} + +static ESource * +get_source (ESourceList *list) +{ + GSList *p, *l; + char **temp = g_strsplit (account->source->url, ";", -1); + char *uri = temp [0]; + + + l = e_source_list_peek_groups (list); + + for (p = l; p != NULL; p = p->next) { + char *so_uri; + GSList *r, *s; + ESourceGroup *group = E_SOURCE_GROUP (p->data); + + s = e_source_group_peek_sources (group); + for (r = s; r != NULL; r = r->next) { + ESource *so = E_SOURCE (r->data); + so_uri = e_source_get_uri (so); + + if (so_uri) { + if (!strcmp (so_uri, uri)) { + g_free (so_uri), so_uri = NULL; + return E_SOURCE (r->data); + } + g_free (so_uri), so_uri = NULL; + } + } + } + + g_strfreev (temp); + + return NULL; +} + +static void +add_return_value (EGwSendOptionsReturnNotify track, ESource *source, char *notify) +{ + char *value; + + switch (track) { + case E_GW_RETURN_NOTIFY_MAIL: + value = g_strdup ("mail"); + break; + default: + value = g_strdup ("none"); + } + + e_source_set_property (source, notify, value); + g_free (value), value = NULL; +} + +static void +put_options_in_source (ESource *source, EGwSendOptionsGeneral *gopts, EGwSendOptionsStatusTracking *sopts) +{ + char *value; + const char *val; + icaltimetype tt; + CamelURL *url; + + url = camel_url_new (account->source->url, NULL); + + if (gopts) { + /* priority */ + switch (gopts->priority) { + case E_GW_PRIORITY_HIGH: + value = g_strdup ("high"); + break; + case E_GW_PRIORITY_STANDARD: + value = g_strdup ("standard"); + break; + case E_GW_PRIORITY_LOW: + value = g_strdup ("low"); + break; + default: + value = g_strdup ("undefined"); + } + e_source_set_property (source, "priority", value); + camel_url_set_param (url, "priority", value); + g_free (value), value = NULL; + + /* Reply Requested */ + /*TODO Fill the value if it is not "convinient" */ + if (gopts->reply_enabled) { + if (gopts->reply_convenient) + value = g_strdup ("convinient"); + else + value = g_strdup_printf ("%d",gopts->reply_within); + } else + value = g_strdup ("none"); + e_source_set_property (source, "reply-requested", value); + g_free (value), value = NULL; + + /* Delay delivery */ + if (gopts->delay_enabled) { + tt = icaltime_today (); + icaltime_adjust (&tt, gopts->delay_until, 0, 0, 0); + val = icaltime_as_ical_string (tt); + } else + val = "none"; + e_source_set_property (source, "delay-delivery", val); + + /* Expiration date */ + if (gopts->expiration_enabled) + value = g_strdup_printf ("%d", gopts->expire_after); + else + value = g_strdup ("none"); + e_source_set_property (source, "expiration", value); + g_free (value), value = NULL; + } + + if (sopts) { + /* status tracking */ + if (sopts->tracking_enabled) { + switch (sopts->track_when) { + case E_GW_DELIVERED : + value = g_strdup ("delivered"); + break; + case E_GW_DELIVERED_OPENED: + value = g_strdup ("delivered-opened"); + break; + default: + value = g_strdup ("all"); + } + } else + value = g_strdup ("none"); + e_source_set_property (source, "status-tracking", value); + g_free (value), value = NULL; + + add_return_value (sopts->opened, source, "return-open"); + add_return_value (sopts->accepted, source, "return-accept"); + add_return_value (sopts->declined, source, "return-decline"); + add_return_value (sopts->completed, source, "return-complete"); + } +} + +static void +add_send_options_to_source (EGwSendOptions *n_opts) +{ + GConfClient *gconf = gconf_client_get_default (); + ESource *csource, *tsource; + ESourceList *list; + EGwSendOptionsGeneral *gopts; + EGwSendOptionsStatusTracking *topts, *mopts, *copts; + + list = e_source_list_new_for_gconf (gconf, "/apps/evolution/calendar/sources"); + csource = get_source (list); + + list = e_source_list_new_for_gconf (gconf, "/apps/evolution/tasks/sources"); + tsource = get_source (list); + + gopts = e_gw_sendoptions_get_general_options (n_opts); + mopts = e_gw_sendoptions_get_status_tracking_options (n_opts, "mail"); + copts = e_gw_sendoptions_get_status_tracking_options (n_opts, "calendar"); + topts = e_gw_sendoptions_get_status_tracking_options (n_opts, "task"); + + if (csource) + put_options_in_source (csource, gopts, copts); + + if (tsource) + put_options_in_source (tsource, gopts, topts); + + g_object_unref (gconf); +} + +void +send_options_commit (EPlugin *epl, EConfigHookItemFactoryData *data) +{ + EGwSendOptions *n_opts; + EGwConnectionStatus status = E_GW_CONNECTION_STATUS_OK; + + if (sod) { + n_opts = e_gw_sendoptions_new (); + send_options_copy_check_changed (n_opts); + + if (changed) + status = e_gw_connection_modify_settings (n_cnc, n_opts); + + if (!changed || status != E_GW_CONNECTION_STATUS_OK) { + g_warning (G_STRLOC "Cannot modify Send Options: %s", e_gw_connection_get_error_message (status)); + g_object_unref (n_opts); + n_opts = NULL; + } else + add_send_options_to_source (n_opts); + } + + send_options_finalize (); +} + +void +send_options_changed (EPlugin *epl, EConfigHookItemFactoryData *data) +{ +} + +void +send_options_abort (EPlugin *epl, EConfigHookItemFactoryData *data) +{ + send_options_finalize (); +} + + diff --git a/plugins/groupwise-features/share-folder-common.c b/plugins/groupwise-features/share-folder-common.c new file mode 100644 index 0000000000..388ec39260 --- /dev/null +++ b/plugins/groupwise-features/share-folder-common.c @@ -0,0 +1,494 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Vivek Jain <jvivek@novell.com> + * + * Copyright 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <string.h> +#include <glib.h> +#include <gtk/gtk.h> +#include <libgnome/gnome-i18n.h> +#include <e-util/e-config.h> +#include <mail/em-config.h> +#include <mail/em-popup.h> +#include <mail/em-folder-properties.h> +#include <mail/em-folder-tree.h> +#include <mail/em-folder-selector.h> +#include <mail/mail-mt.h> +#include <mail/mail-component.h> +#include <mail/mail-config.h> +#include <mail/em-vfolder-rule.h> +#include <filter/filter-rule.h> +#include <camel/camel-store.h> +#include <camel/camel-session.h> +#include <camel/camel-store.h> +#include <camel/camel-vee-store.h> +#include <camel/camel-folder.h> +#include <e-gw-container.h> +#include <e-gw-connection.h> +#include <glade/glade.h> +#include <libgnomeui/libgnomeui.h> +#include "share-folder.h" +#define d(x) + +ShareFolder *common = NULL; +CamelSession *session; +struct ShareInfo { + GtkWidget *d; + ShareFolder *sf; + EMFolderTreeModel *model; + EMFolderSelector *emfs; +}; + +GtkWidget * org_gnome_shared_folder_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data); +void org_gnome_create_option(EPlugin *ep, EMPopupTargetFolder *target); +void shared_folder_commit (EPlugin *ep, EConfigTarget *tget); +void shared_folder_abort (EPlugin *ep, EConfigTarget *target); + +static void refresh_folder_tree (EMFolderTreeModel *model, CamelStore *store); + +static void +refresh_folder_tree (EMFolderTreeModel *model, CamelStore *store) +{ + gchar *uri; + EAccount *account; + CamelException ex; + CamelProvider *provider; + + uri = camel_url_to_string (((CamelService *) store)->url, CAMEL_URL_HIDE_ALL); + account = mail_config_get_account_by_source_url (uri); + uri = account->source->url; + em_folder_tree_model_remove_store (model, store); + + camel_exception_init (&ex); + if (!(provider = camel_provider_get(uri, &ex))) { + camel_exception_clear (&ex); + return; + } + if (!(provider->flags & CAMEL_PROVIDER_IS_STORAGE)) + return; + em_folder_tree_model_add_store (model, store, account->name); + //camel_object_unref (store); +} + +void +shared_folder_commit (EPlugin *ep, EConfigTarget *tget) +{ + EMConfigTargetFolder *target = (EMConfigTargetFolder *)tget->config->target; + CamelFolder *folder = target->folder; + CamelStore *store = folder->parent_store; + EMFolderTreeModel *model = mail_component_peek_tree_model (mail_component_peek ()); + if (common) { + share_folder (common); + refresh_folder_tree (model, store); + g_object_run_dispose ((GObject *)common); + common = NULL; + } +} + +void +shared_folder_abort (EPlugin *ep, EConfigTarget *target) +{ + if (common) { + g_object_run_dispose ((GObject *)common); + common = NULL; + } +} + +struct _EMCreateFolder { + struct _mail_msg msg; + + /* input data */ + CamelStore *store; + char *full_name; + char *parent; + char *name; + + /* output data */ + CamelFolderInfo *fi; + + /* callback data */ + void (* done) (struct _EMCreateFolder *m, void *user_data); + void *user_data; +}; + +static char * +create_folder__desc (struct _mail_msg *mm, int done) +{ + struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm; + + return g_strdup_printf (_("Creating folder `%s'"), m->full_name); +} + +static void +create_folder__create (struct _mail_msg *mm) +{ + struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm; + + d(printf ("creating folder parent='%s' name='%s' full_name='%s'\n", m->parent, m->name, m->full_name)); + + if ((m->fi = camel_store_create_folder (m->store, m->parent, m->name, &mm->ex))) { + if (camel_store_supports_subscriptions (m->store)) + camel_store_subscribe_folder (m->store, m->full_name, &mm->ex); + } +} + +static void +create_folder__created (struct _mail_msg *mm) +{ + struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm; + struct ShareInfo *ssi = (struct ShareInfo *) m->user_data; + CamelStore *store = CAMEL_STORE (m->store) ; + EGwConnection *ccnc; + + if (m->done) { + ccnc = get_cnc (store); + if(E_IS_GW_CONNECTION (ccnc)) { + (ssi->sf)->cnc = ccnc; + + (ssi->sf)->container_id = g_strdup (get_container_id ((ssi->sf)->cnc, m->full_name)); + share_folder(ssi->sf); + } + + m->done (m, m->user_data); + } +} + +static void +create_folder__free (struct _mail_msg *mm) +{ + struct _EMCreateFolder *m = (struct _EMCreateFolder *) mm; + + camel_store_free_folder_info (m->store, m->fi); + camel_object_unref (m->store); + g_free (m->full_name); + g_free (m->parent); + g_free (m->name); +} + +static struct _mail_msg_op create_folder_op = { + create_folder__desc, + create_folder__create, + create_folder__created, + create_folder__free, +}; + +static void +new_folder_created_cb (struct _EMCreateFolder *m, void *user_data) +{ + struct ShareInfo *ssi = (struct ShareInfo *) user_data; + EMFolderSelector *emfs = ssi->emfs; + if (m->fi){ + refresh_folder_tree (ssi->model, m->store); + gtk_widget_destroy ((GtkWidget *) emfs); + gtk_widget_destroy ((GtkWidget *) ssi->d); + } + + g_object_unref (emfs); +} + +static int +create_folder (CamelStore *store, const char *full_name, void (* done) (struct _EMCreateFolder *m, void *user_data), void *user_data) +{ + char *name, *namebuf = NULL; + struct _EMCreateFolder *m; + const char *parent; + int id; + + namebuf = g_strdup (full_name); + if (!(name = strrchr (namebuf, '/'))) { + name = namebuf; + parent = ""; + } else { + *name++ = '\0'; + parent = namebuf; + } + + m = mail_msg_new (&create_folder_op, NULL, sizeof (struct _EMCreateFolder)); + camel_object_ref (store); + m->store = store; + m->full_name = g_strdup (full_name); + m->parent = g_strdup (parent); + m->name = g_strdup (name); + m->user_data = (struct ShareInfo *) user_data; + m->done = done; + g_free (namebuf); + id = m->msg.seq; + e_thread_put (mail_thread_new, (EMsg *) m); + + return id; +} + +static void +users_dialog_response(GtkWidget *dialog, int response, struct ShareInfo *ssi) +{ + struct _EMFolderTreeModelStoreInfo *si; + EMFolderSelector *emfs = ssi->emfs; + const char *uri, *path; + CamelException ex; + CamelStore *store; + + if (response != GTK_RESPONSE_OK) { + gtk_widget_destroy ((GtkWidget *) emfs); + gtk_widget_destroy(dialog); + return; + } + + uri = em_folder_selector_get_selected_uri (emfs); + path = em_folder_selector_get_selected_path (emfs); + + d(printf ("Creating new folder: %s (%s)\n", path, uri)); + + camel_exception_init (&ex); + if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) { + camel_exception_clear (&ex); + return; + } + + if (!(si = g_hash_table_lookup ((ssi->model)->store_hash, store))) { + g_assert_not_reached (); + camel_object_unref (store); + return; + } + + if (CAMEL_IS_VEE_STORE(store)) { + EMVFolderRule *rule; + + rule = em_vfolder_rule_new(); + filter_rule_set_name((FilterRule *)rule, path); + vfolder_gui_add_rule(rule); + gtk_widget_destroy((GtkWidget *)emfs); + } else { + g_object_ref (emfs); + ssi->d = dialog; + create_folder (si->store, path, new_folder_created_cb, ssi); + + } + camel_object_unref (store); +} + +static void +new_folder_response (EMFolderSelector *emfs, int response, EMFolderTreeModel *model) +{ + GtkWidget *users_dialog; + GtkWidget *w; + struct ShareInfo *ssi; + const char *uri; + EGwConnection *cnc; + CamelException ex; + CamelStore *store; + + ssi = g_new0(struct ShareInfo, 1); + if (response != GTK_RESPONSE_OK) { + gtk_widget_destroy ((GtkWidget *) emfs); + return; + } + + /* i want store at this point to get cnc not sure proper or not*/ + uri = em_folder_selector_get_selected_uri (emfs); + camel_exception_init (&ex); + if (!(store = (CamelStore *) camel_session_get_service (session, uri, CAMEL_PROVIDER_STORE, &ex))) { + camel_exception_clear (&ex); + return; + } + + cnc = get_cnc (store); + users_dialog = gtk_dialog_new_with_buttons ( + _("Users"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); + w = gtk_label_new_with_mnemonic (_("Enter the users and set permissions")); + gtk_widget_show(w); + gtk_box_pack_start(GTK_BOX (GTK_DIALOG (users_dialog)->vbox), (GtkWidget *) w, TRUE, TRUE, 6); + ssi->sf = share_folder_new (cnc, NULL); + gtk_widget_set_sensitive (GTK_WIDGET ((ssi->sf)->table), TRUE); + ssi->model = model; + ssi->emfs = emfs; + gtk_widget_reparent (GTK_WIDGET ((ssi->sf)->table), GTK_DIALOG (users_dialog)->vbox); + gtk_widget_hide((GtkWidget*) emfs); + gtk_window_resize (GTK_WINDOW (users_dialog), 350, 300); + gtk_widget_show(users_dialog); + g_signal_connect (users_dialog, "response", G_CALLBACK (users_dialog_response), ssi); + + camel_object_unref (store); + return ; + +} + +void +org_gnome_create_option(EPlugin *ep, EMPopupTargetFolder *target) +{ + + EMFolderTreeModel *model; + EMFolderTree *folder_tree; + GtkWidget *dialog ; + char *uri; + + model = mail_component_peek_tree_model (mail_component_peek ()); + folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model); + dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:")); + uri = em_folder_tree_get_selected_uri(folder_tree); + em_folder_selector_set_selected ((EMFolderSelector *) dialog, uri); + g_free(uri); + g_signal_connect (dialog, "response", G_CALLBACK (new_folder_response), model); + gtk_window_set_title (GTK_WINDOW (dialog), "New Shared Folder" ); + gtk_widget_show(dialog); + +} + +GtkWidget * +org_gnome_shared_folder_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data) +{ + + gchar *folderuri = NULL; + gchar *account = NULL; + gchar *id = NULL; + gchar *sub = NULL; + gchar *folder_name = NULL; + EGwConnection *cnc; + ShareFolder *sharing_tab; + EMConfigTargetFolder *target= (EMConfigTargetFolder *)hook_data->config->target; + CamelFolder *folder = target->folder; + + folder_name = g_strdup (folder->full_name); + folderuri = g_strdup(target->uri); + if (folderuri && folder_name) + account = g_strrstr(folderuri, "groupwise"); + else + return NULL; + + sub = g_strrstr (folder_name, "/"); + if (sub) + sub++; + else + sub = folder_name; + + /* This is kind of bad..but we don't have types for all these folders.*/ + + if ( !( strcmp (sub, "Mailbox") && strcmp (sub, "Calendar") && strcmp (sub, "Contacts") && strcmp (sub, "Documents") && strcmp (sub, "Authored") && strcmp (sub, "Default Library") && strcmp (sub, "Work In Progress") && strcmp (sub, "Cabinet") && strcmp (sub, "Sent Items") && strcmp (sub, "Trash") && strcmp (sub, "Checklist"))) { + g_free (folderuri); + return NULL; + } + + if (account) { + CamelStore *store = folder->parent_store; + cnc = get_cnc (store); + + if (E_IS_GW_CONNECTION (cnc)) + id = get_container_id (cnc, folder_name); + else + g_warning("Could not Connnect\n"); + + if (cnc && id) + sharing_tab = share_folder_new (cnc, id); + else + return NULL; + + gtk_notebook_append_page((GtkNotebook *) hook_data->parent, (GtkWidget *) sharing_tab->vbox, gtk_label_new_with_mnemonic N_("Sharing")); + common = sharing_tab; + g_free (folderuri); + return GTK_WIDGET (sharing_tab); + } else + return NULL; +} + +EGwConnection * +get_cnc (CamelStore *store) +{ + EGwConnection *cnc; + const char *uri, *property_value, *server_name, *user, *port; + char *use_ssl; + CamelService *service; + CamelURL *url; + + if (!store) + return NULL; + + service = CAMEL_SERVICE(store); + url = service->url; + server_name = g_strdup (url->host); + user = g_strdup (url->user); + property_value = camel_url_get_param (url, "soap_port"); + use_ssl = g_strdup (camel_url_get_param (url, "use_ssl")); + if(property_value == NULL) + port = g_strdup ("7191"); + else if (strlen(property_value) == 0) + port = g_strdup ("7191"); + else + port = g_strdup (property_value); + + if (use_ssl && !g_str_equal (use_ssl, "never")) + uri = g_strconcat ("https://", server_name, ":", port, "/soap", NULL); + else + uri = g_strconcat ("http://", server_name, ":", port, "/soap", NULL); + + cnc = e_gw_connection_new (uri, user, service->url->passwd); + if (!E_IS_GW_CONNECTION(cnc) && use_ssl && g_str_equal (use_ssl, "when-possible")) { + char *http_uri = g_strconcat ("http://", uri + 8, NULL); + cnc = e_gw_connection_new (http_uri, user, service->url->passwd); + g_free (http_uri); + } + g_free (use_ssl); + use_ssl = NULL; + + return cnc; + +} + +gchar * +get_container_id(EGwConnection *cnc, gchar *fname) +{ + GList *container_list = NULL; + gchar *id = NULL; + gchar *name; + gchar **names; + int i = 0, parts = 0; + + names = g_strsplit (fname, "/", -1); + if(names){ + while (names [parts]) + parts++; + fname = names[i]; + } + + /* get list of containers */ + if (e_gw_connection_get_container_list (cnc, "folders", &(container_list)) == E_GW_CONNECTION_STATUS_OK) { + GList *container = NULL; + + for (container = container_list; container != NULL; container = container->next) { + name = g_strdup (e_gw_container_get_name (container->data)); + /* if Null is passed as name then we return top lavel id*/ + if (fname == NULL) { + id = g_strdup (e_gw_container_get_id (container->data)); + break; + } else if (!strcmp (name, fname)) { + if (i == parts - 1) { + id = g_strdup (e_gw_container_get_id (container->data)); + break; + } else + fname = names[++i]; + } + g_free (name); + } + e_gw_connection_free_container_list (container_list); + if (names) + g_strfreev(names); + } + return id; +} diff --git a/plugins/groupwise-features/share-folder.c b/plugins/groupwise-features/share-folder.c new file mode 100644 index 0000000000..1d43b2b001 --- /dev/null +++ b/plugins/groupwise-features/share-folder.c @@ -0,0 +1,746 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Author: Vivek Jain <jvivek@novell.com> + * + * Copyright 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <glade/glade.h> +#include "share-folder.h" +#include <glib/gmain.h> +#include <gtk/gtktreemodel.h> +#include <gtk/gtkliststore.h> +#include <gtk/gtktreeselection.h> +#include <gtk/gtktreeview.h> +#include <gtk/gtkdialog.h> +#include <gtk/gtkbutton.h> +#include <gtk/gtk.h> +#include <gtk/gtktogglebutton.h> +#include <gtk/gtkcellrenderertoggle.h> +#include <gtk/gtkcellrenderertext.h> +#include <libedataserverui/e-contact-store.h> +#include <libgnomeui/gnome-ui-init.h> +#include <libgnome/gnome-init.h> +#include <e-util/e-error.h> +#include <e-gw-container.h> +#include <e-gw-connection.h> +#define ROOTNODE "vboxSharing" +#define NROOTNODE "vbox191" +#define d(x) + +struct _SharedUser { + EShUsers *user_node; + int flag; +}; +typedef struct _SharedUser SharedUser; + +static void share_folder_class_init (ShareFolderClass *class); +static void share_folder_init (ShareFolder *sf); +static void share_folder_destroy (GtkObject *obj); +static void share_folder_finalise (GObject *obj); +static void free_user_node(EShUsers *user); +static void free_node(SharedUser *user); +static void free_all(ShareFolder *sf); +static SharedUser * find_node(GList *list, gchar *email); +static void free_all(ShareFolder *sf); +static void get_container_list (ShareFolder *sf); +static void user_selected(GtkTreeSelection *selection, ShareFolder *sf); +static void not_shared_clicked (GtkRadioButton *button, ShareFolder *sf); +static void shared_clicked (GtkRadioButton *button, ShareFolder *sf); +static void add_clicked(GtkButton *button, ShareFolder *sf); +static void remove_clicked(GtkButton *button, ShareFolder *sf); +static void not_ok_clicked(GtkButton *button, ShareFolder *sf); +static void not_cancel_clicked(GtkButton *button, GtkWidget *window); +static void not_cancel_clicked(GtkButton *button, GtkWidget *window); +static void share_folder_construct (ShareFolder *sf); +GType share_folder_get_type (void); + +static GtkVBoxClass *parent_class = NULL; + +GType +share_folder_get_type (void) +{ + static GType type = 0; + + if (!type) { + static const GTypeInfo info = { + sizeof (ShareFolderClass), + NULL, NULL, + (GClassInitFunc) share_folder_class_init, + NULL, NULL, + sizeof (ShareFolder), + 0, + (GInstanceInitFunc) share_folder_init + }; + + type = g_type_register_static (gtk_vbox_get_type (), "ShareFolder", &info, 0); + } + + return type; +} + +static void +share_folder_class_init (ShareFolderClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass); + + parent_class = g_type_class_ref (gtk_vbox_get_type ()); + object_class->destroy = share_folder_destroy; + gobject_class->finalize = share_folder_finalise; +} + +static void +share_folder_finalise (GObject *obj) +{ + ShareFolder *sf = (ShareFolder *) obj; + g_object_unref (sf->xml); + free_all(sf); + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + +static void +share_folder_destroy (GtkObject *obj) +{ + + ShareFolder *sf = (ShareFolder *) obj; + free_all (sf); + GTK_OBJECT_CLASS (parent_class)->destroy (obj); +} + +static void +share_folder_init (ShareFolder *sf) +{ + sf->gcontainer = NULL; + sf->users = 0; + sf->flag_for_ok = 0; + sf->shared = FALSE; + sf->container_list = NULL; + sf->users_list = NULL; + sf->sub = "Shared Folder notification"; + sf->message = NULL; +} + +static void +free_user_node(EShUsers *user) +{ + if(user){ + g_free(user->email); + user->email = NULL; + } + return ; +} + +static void +free_node(SharedUser *usr) +{ + EShUsers *user = usr->user_node; + if(user){ + g_free(user->email); + user->email = NULL; + } + return ; +} + +static SharedUser * +find_node(GList *list, gchar *email) +{ + SharedUser *user = NULL; + EShUsers *usr = NULL; + GList *tmp; + gint i ; + + if(list){ + tmp = g_list_first(list); + for(i=0; tmp ; i++) + { + user = tmp->data; + usr = user->user_node; + if(!g_ascii_strcasecmp(usr->email, email)){ + return user; /*if found, it returns that user*/ + } + tmp= g_list_next(tmp); + } + } + return NULL; +} + +static void +free_all (ShareFolder *sf) +{ + if (sf->users_list){ + g_list_foreach (sf->users_list,(GFunc) free_node, NULL); + g_list_free (sf->users_list); + sf->users_list = NULL; + } + + //e_gw_connection_free_container_list (sf->container_list); +} + + +static void +display_container (EGwContainer *container , ShareFolder *sf) +{ + gchar **tail; + gchar *id_shared; + gchar *id_unshared; + gboolean byme = FALSE; + gboolean tome = FALSE; + gchar *email = NULL; + gchar *msg; + GList *user_list = NULL; + EShUsers *user = NULL; + + id_shared = g_strdup(e_gw_container_get_id(container)); + /* this has to be done since id changes after the folder is shared*/ + if( g_str_has_suffix (id_shared, "35")){ + tail = g_strsplit(id_shared, "@", 2); + id_unshared = g_strconcat(tail[0], "@", "13", NULL); + g_strfreev(tail); + } + + if((!g_ascii_strcasecmp(id_unshared, sf->container_id)) || (!g_ascii_strcasecmp(id_shared, sf->container_id)) ){ + sf->gcontainer = container; + byme = e_gw_container_get_is_shared_by_me(container); + tome = e_gw_container_get_is_shared_to_me(container); + if(byme || tome) { + e_gw_container_get_user_list (sf->gcontainer, &user_list); + sf->users = g_list_length (user_list); + if(sf->users != 0) { + sf->is_shared = TRUE; + gtk_toggle_button_set_active((GtkToggleButton *) sf->shared, TRUE); + shared_clicked(sf->shared , sf); + if (tome) { + gtk_widget_set_sensitive (GTK_WIDGET (sf->not_shared), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (sf->add_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (sf->remove), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (sf->add_book), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (sf->notification), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (sf->user_list), FALSE); + email = g_strdup (e_gw_container_get_owner (sf->gcontainer)); + msg = g_strconcat (email, " (Owner)", NULL); + gtk_list_store_append (GTK_LIST_STORE (sf->model), &(sf->iter)); + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 0, msg, -1); + g_free (msg); + g_free (email); + + } else + gtk_widget_set_sensitive (GTK_WIDGET (sf->table), TRUE); +/* I populate the list and set flags to 0 for the existing users*/ + while (user_list) { + SharedUser *shared_user = g_new0 (SharedUser , 1); + gboolean add, edit, delete; + add = edit = delete = FALSE; + user = user_list->data; + shared_user->user_node = user; + shared_user->flag = 0; + email = g_strdup (user->email); + if (user->rights & 0x1) + add = TRUE; + if (user->rights & 0x2) + edit = TRUE; + if (user->rights & 0x4) + delete = TRUE; + + msg = g_strdup_printf ("%s", email); + gtk_list_store_append (GTK_LIST_STORE (sf->model), &(sf->iter)); + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 0, msg, 1, add, 2, edit, 3, delete, -1); + sf->users_list = g_list_append (sf->users_list, shared_user); + g_free (msg); + g_free (email); + msg = NULL; + email = NULL; + user_list = user_list->next; + } + /* i also need to display status*/ + } else { + + gtk_toggle_button_set_active ((GtkToggleButton *) sf->not_shared, TRUE); + not_shared_clicked (sf->not_shared , sf); + } + } + } +} + +static void +get_container_list (ShareFolder *sf) +{ + sf->container_list = NULL; + if (E_IS_GW_CONNECTION (sf->cnc)) { + /* get list of containers */ + if (e_gw_connection_get_container_list (sf->cnc, "folders", &(sf->container_list)) == E_GW_CONNECTION_STATUS_OK) { + GList *container = NULL; + + for (container = sf->container_list; container != NULL; container = container->next) + display_container (E_GW_CONTAINER (container->data), sf); + + } + else + g_warning("Could not get the Container List"); + } +} + + +static void +shared_clicked (GtkRadioButton *button, ShareFolder *sf) +{ + + gtk_widget_set_sensitive (GTK_WIDGET (sf->table) ,TRUE); + sf->flag_for_ok = 0; +} + +static void +not_shared_clicked (GtkRadioButton *button, ShareFolder *sf) +{ + if (!sf->is_shared) { + sf->flag_for_ok = 0; + } else { + sf->flag_for_ok = 2; + } + gtk_widget_set_sensitive (GTK_WIDGET (sf->table), FALSE); + +} + +static void +add_clicked(GtkButton *button, ShareFolder *sf) +{ + const char *email = NULL; + const char *self_email = NULL; + SharedUser *new_user = NULL; + EShUsers *usr = NULL; + gint rights = 0; + gchar *msg = NULL; + EDestinationStore *destination_store; + GList *destinations, *tmp; + ENameSelectorEntry *name_selector_entry; + + name_selector_entry = e_name_selector_peek_section_entry (sf->name_selector, "Add User"); + destination_store = e_name_selector_entry_peek_destination_store (E_NAME_SELECTOR_ENTRY ( + name_selector_entry)); + destinations = e_destination_store_list_destinations (destination_store); + tmp = destinations; + self_email = g_strdup (e_gw_connection_get_user_email (sf->cnc)); + for (; tmp != NULL; tmp = g_list_next (tmp)) { + email = e_destination_get_email (tmp->data); + /* You can't share a folder with yourself*/ + if (g_strrstr (email, "@") == NULL || (!g_ascii_strcasecmp (email , self_email))) + e_error_run (NULL, "org.gnome.evolution.mail_shared_folder:invalid-user",email ,NULL); + else { + if (!g_ascii_strcasecmp (email, "" )) { + e_error_run (NULL, "org.gnome.evolution.mail_shared_folder:no-user",NULL); + + return ; + } + + + /*check whether already exists*/ + if (sf->users_list && email){ + new_user = find_node (sf->users_list, (gchar *)email); + if (new_user) + return ; + + } + usr = g_new0 (EShUsers, 1); + new_user = g_new0 (SharedUser, 1); + usr->email = g_strdup(email); + usr->rights = rights; + new_user->user_node = usr; + new_user->flag = 1; + msg = g_strdup (email); + gtk_list_store_append (GTK_LIST_STORE (sf->model), &(sf->iter)); + + /* have to add code for rights*/ + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 0, msg, -1); + g_free(msg); + sf->users_list = g_list_append (sf->users_list, new_user); + sf->flag_for_ok = 0; + } + } + gtk_entry_set_text (GTK_ENTRY(name_selector_entry), ""); + +} + +static void +remove_clicked(GtkButton *button, ShareFolder *sf) +{ + + SharedUser *usr = NULL; + gchar *email; + + gtk_tree_model_get ((GtkTreeModel *) sf->model, &(sf->iter), 0, &email, -1); + usr = find_node (sf->users_list, email); + if (usr->flag & 0x1) { + sf->users_list = g_list_remove (sf->users_list, usr); + free_node(usr); + } else { + usr->flag = 0; + usr->flag |= 0x4; + } + g_free (email); + gtk_list_store_remove (GTK_LIST_STORE (sf->model), &(sf->iter)); + sf->flag_for_ok = 1; +} + +void +share_folder (ShareFolder *sf) +{ + + GList *new_list = NULL; + GList *update_list = NULL; + GList *remove_list = NULL; + GList *node = NULL; + SharedUser *user = NULL; + + for (node = sf->users_list; node; node = node->next) + { + user = node->data; + if (user->flag & 0x1) + new_list = g_list_append (new_list, user->user_node); + else if (user->flag & 0x2) + update_list = g_list_append (update_list, user->user_node); + else if (user->flag & 0x4) { + remove_list = g_list_append (remove_list, user->user_node); + } + } + + if (E_IS_GW_CONNECTION (sf->cnc)) { + if(sf->flag_for_ok == 2){ /* you have to remove all the users*/ + GList *list = NULL; + + if(new_list){ + g_list_foreach (new_list, (GFunc) free_user_node, NULL); + g_list_free (new_list); + } + if(update_list){ + g_list_foreach (update_list, (GFunc) free_user_node, NULL); + g_list_free (update_list); + } + + new_list = NULL; + if(remove_list){ + g_list_foreach (remove_list,(GFunc) free_user_node, NULL); + g_list_free (remove_list); + } + remove_list = NULL; + if (sf->gcontainer) { + e_gw_container_get_user_list (sf->gcontainer, &list); + remove_list = g_list_copy (list); + + } else { + g_warning("Container is Null"); + } + + + } else { + if (new_list) { + if (e_gw_connection_share_folder (sf->cnc, sf->container_id, new_list, sf->sub, sf->mesg, 0) == E_GW_CONNECTION_STATUS_OK); + } + + if (update_list) { + sf->sub = "Shared Folder rights updated"; + + if (e_gw_connection_share_folder (sf->cnc, sf->container_id, update_list, sf->sub, sf->mesg, 2) == E_GW_CONNECTION_STATUS_OK); + } + } + if (remove_list) { + sf->sub = "Shared Folder removed"; + if (e_gw_connection_share_folder (sf->cnc, sf->container_id, remove_list, sf->sub, sf->mesg, 1) == E_GW_CONNECTION_STATUS_OK); + } + + } +} + +static void +not_ok_clicked(GtkButton *button, ShareFolder *sf) +{ + + gchar *subj = NULL; + gchar *msg = NULL; + GtkTextIter *start, *end; + GtkTextBuffer *buffer; + + buffer = gtk_text_buffer_new (NULL); + start = g_new0 (GtkTextIter, 1); + end = g_new0 (GtkTextIter, 1); + subj = g_strdup (gtk_entry_get_text (sf->subject)); + if (subj) + sf->sub = subj; + buffer = gtk_text_view_get_buffer (sf->message); + gtk_text_buffer_get_start_iter (buffer, start); + gtk_text_buffer_get_end_iter (buffer, end); + msg = gtk_text_buffer_get_text (buffer, start, end, FALSE); + if (msg) + sf->mesg = msg; + gtk_widget_destroy (GTK_WIDGET (sf->window)); + +} + +static void +not_cancel_clicked(GtkButton *button, GtkWidget *window) +{ + gtk_widget_destroy(window); +} + + +static void +notification_clicked(GtkButton *button, ShareFolder *sf) +{ + static GladeXML *xmln; + GtkButton *not_ok; + GtkButton *not_cancel; + GtkWidget *vbox; + + sf->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + xmln = glade_xml_new (EVOLUTION_GLADEDIR "/properties.glade", NROOTNODE , NULL); + vbox = GTK_WIDGET (glade_xml_get_widget (xmln, "vbox191")); + gtk_container_add (GTK_CONTAINER (sf->window), vbox); + sf->subject = GTK_ENTRY (glade_xml_get_widget (xmln, "entry3")); + gtk_entry_set_text(GTK_ENTRY (sf->subject) , sf->sub); + sf->message = GTK_TEXT_VIEW (glade_xml_get_widget (xmln, "textview1")); + not_ok = GTK_BUTTON (glade_xml_get_widget (xmln, "nOK")); + g_signal_connect ((gpointer) not_ok, "clicked", G_CALLBACK (not_ok_clicked), sf); + not_cancel = GTK_BUTTON (glade_xml_get_widget (xmln, "nCancel")); + g_signal_connect ((gpointer) not_cancel, "clicked", G_CALLBACK (not_cancel_clicked), sf->window); + gtk_window_set_title (GTK_WINDOW (sf->window), "Custom Notification"); + gtk_window_set_position (GTK_WINDOW (sf->window) , GTK_WIN_POS_CENTER_ALWAYS); + gtk_window_set_default_size (GTK_WINDOW (sf->window), 100, 200); + gtk_widget_reparent (GTK_WINDOW (sf->window), GTK_DIALOG (sf->vbox)); + gtk_window_set_transient_for (sf->window, GTK_DIALOG(sf->vbox)); + gtk_window_set_modal (sf->window, TRUE); + gtk_window_present (sf->window); + gtk_widget_show_all (sf->window); +} + +static void +addressbook_dialog_response (ENameSelectorDialog *name_selector_dialog, gint response, gpointer user_data) +{ + gtk_widget_hide (GTK_WIDGET (name_selector_dialog)); +} + +static void +addressbook_entry_changed (GtkWidget *entry, gpointer user_data) +{ + +} + +static void +address_button_clicked_cb (GtkButton *button, gpointer data) +{ + ShareFolder *sf = data; + ENameSelectorDialog *name_selector_dialog; + + name_selector_dialog = e_name_selector_peek_dialog (sf->name_selector); + gtk_widget_show (GTK_WIDGET (name_selector_dialog)); +} + + static void +user_selected(GtkTreeSelection *selection, ShareFolder *sf) +{ + + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + if (gtk_tree_selection_get_selected (selection, &(sf->model), &(sf->iter))){ + gtk_widget_set_sensitive (GTK_WIDGET (sf->remove), TRUE); + + } +} + + +static void +add_right_clicked (GtkCellRenderer *renderer, gchar *arg1, ShareFolder *sf ) +{ + gboolean right = FALSE; + SharedUser *usr = NULL; + EShUsers *user = NULL; + char *email = NULL; + GtkTreeSelection *selection = NULL; + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW (sf->user_list)); + gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE); + if (! gtk_tree_selection_get_selected (selection, &(sf->model), &(sf->iter))); + gtk_tree_model_get ((GtkTreeModel *) sf->model, &(sf->iter), 0, &email, 1, &right , -1); + usr = find_node(sf->users_list, email); + if (!usr) + return ; + if(! usr->flag) /* if user was already existing one change the flag to update*/ + usr->flag = usr->flag | 0x2; + user = usr->user_node; + if (!right) { + user->rights |= 0x1; + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 1, TRUE, -1); + } else { + user->rights &= 0x6; + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 1, FALSE, -1); + } + +} + + static void +edit_right_clicked(GtkCellRenderer *renderer, gchar *arg1, ShareFolder *sf ) +{ + gboolean right = FALSE; + SharedUser *usr = NULL; + EShUsers *user = NULL; + char *email = NULL; + gtk_tree_model_get ((GtkTreeModel *) sf->model, &(sf->iter), 0, &email, 2, &right , -1); + usr = find_node(sf->users_list, email); + if(! usr->flag) /* if user was already existing one change the flag to update*/ + usr->flag = usr->flag | 0x2; + user = usr->user_node; + + if (!right) { + user->rights |= 0x2; + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 2, TRUE, -1); + } else { + user->rights &= 0x5; + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 2, FALSE, -1); + } + +} + + static void +delete_right_clicked(GtkCellRenderer *renderer, gchar *arg1, ShareFolder *sf ) +{ + gboolean right = FALSE; + SharedUser *usr = NULL; + EShUsers *user = NULL; + char *email = NULL; + gtk_tree_model_get ((GtkTreeModel *) sf->model, &(sf->iter), 0, &email, 3, &right , -1); + usr = find_node(sf->users_list, email); + if(! usr->flag) /* if user was already existing one change the flag to update*/ + usr->flag = usr->flag | 0x2; + user = usr->user_node; + if (!right) { + user->rights |= 0x4; + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 3, TRUE, -1); + } else { + user->rights &= 0x3; + gtk_list_store_set (GTK_LIST_STORE (sf->model), &(sf->iter), 3, FALSE, -1); + } + +} + +static void +share_folder_construct (ShareFolder *sf) +{ + GladeXML *xml; + ENameSelectorDialog *name_selector_dialog; + ENameSelectorModel *name_selector_model; + ENameSelectorEntry *name_selector_entry; + GtkWidget *box; + + xml = glade_xml_new (EVOLUTION_GLADEDIR "/properties.glade", ROOTNODE, NULL); + sf->xml =xml; + + if (!sf->xml) { + g_warning ("could not get xml"); + } + sf->vbox = GTK_VBOX (glade_xml_get_widget(sf->xml, "vboxSharing")); + sf->table = GTK_WIDGET (glade_xml_get_widget (sf->xml, "vbox194")); + gtk_widget_set_sensitive (GTK_WIDGET (sf->table), FALSE); + + sf->shared = GTK_RADIO_BUTTON (glade_xml_get_widget (sf->xml, "radShared")); + g_signal_connect ((gpointer) sf->shared, "clicked", G_CALLBACK (shared_clicked), sf); + + sf->not_shared = GTK_RADIO_BUTTON (glade_xml_get_widget (sf->xml, "radNotShared")); + g_signal_connect ((gpointer) sf->not_shared, "clicked", G_CALLBACK (not_shared_clicked), sf); + + sf->add_book = GTK_BUTTON (glade_xml_get_widget (sf->xml, "Address")); + gtk_widget_set_sensitive (GTK_WIDGET (sf->add_book), TRUE); + g_signal_connect((GtkWidget *) sf->add_book, "clicked", G_CALLBACK (address_button_clicked_cb), sf); + + sf->name_selector = e_name_selector_new (); + name_selector_dialog = e_name_selector_peek_dialog (sf->name_selector); + g_signal_connect (name_selector_dialog, "response", + G_CALLBACK (addressbook_dialog_response), sf); + + name_selector_model = e_name_selector_peek_model (sf->name_selector); + e_name_selector_model_add_section (name_selector_model, "Add User", "Add User", NULL); + + name_selector_entry = e_name_selector_peek_section_entry (sf->name_selector, "Add User"); + g_signal_connect (name_selector_entry, "changed", + G_CALLBACK (addressbook_entry_changed), sf); + + sf->add_button = GTK_BUTTON (glade_xml_get_widget(sf->xml, "Add")); + g_signal_connect((GtkWidget *) sf->add_button, "clicked", G_CALLBACK (add_clicked), sf); + + sf->remove = GTK_BUTTON(glade_xml_get_widget(sf->xml, "Remove")); + g_signal_connect ((GtkWidget *) sf->remove, "clicked", G_CALLBACK (remove_clicked), sf); + gtk_widget_set_sensitive(GTK_WIDGET (sf->remove), FALSE); + + sf->notification = GTK_BUTTON (glade_xml_get_widget (sf->xml, "Notification")); + g_signal_connect((GtkWidget *) sf->notification, "clicked", G_CALLBACK (notification_clicked), sf); + + sf->name = GTK_ENTRY (glade_xml_get_widget (sf->xml, "entry4")); + /*TODO:connect name and label*/ + gtk_widget_hide (GTK_WIDGET(sf->name)); + box = GTK_WIDGET (glade_xml_get_widget (sf->xml, "hbox227")); + gtk_box_pack_start (GTK_BOX (box), (GtkWidget *) name_selector_entry, TRUE, TRUE, 0); + gtk_widget_show ((GtkWidget *) name_selector_entry); + + sf->scrolled_window = GTK_WIDGET (glade_xml_get_widget (sf->xml,"scrolledwindow4")); + + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sf->scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + sf->model = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); + sf->user_list = gtk_tree_view_new (); + gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sf->scrolled_window), (GtkWidget *)sf->user_list); + gtk_tree_view_set_model (GTK_TREE_VIEW (sf->user_list), GTK_TREE_MODEL (sf->model)); + gtk_widget_show (GTK_WIDGET (sf->user_list)); + + sf->cell = gtk_cell_renderer_text_new (); + sf->column = gtk_tree_view_column_new_with_attributes ("Users", sf->cell, "text", 0, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (sf->user_list), + GTK_TREE_VIEW_COLUMN (sf->column)); + + sf->cell = gtk_cell_renderer_toggle_new (); + sf->column = gtk_tree_view_column_new_with_attributes ("Add ", sf->cell, "active" , 1, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (sf->user_list), + GTK_TREE_VIEW_COLUMN (sf->column)); + g_signal_connect (sf->cell, "toggled", G_CALLBACK (add_right_clicked), sf); + + sf->cell = gtk_cell_renderer_toggle_new (); + sf->column = gtk_tree_view_column_new_with_attributes ("Modify", sf->cell, "active", 2, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (sf->user_list), + GTK_TREE_VIEW_COLUMN (sf->column)); + g_signal_connect (sf->cell, "toggled", G_CALLBACK (edit_right_clicked), sf); + + sf->cell = gtk_cell_renderer_toggle_new (); + sf->column = gtk_tree_view_column_new_with_attributes ("Delete", sf->cell, "active", 3, NULL); + gtk_tree_view_append_column (GTK_TREE_VIEW (sf->user_list), + GTK_TREE_VIEW_COLUMN (sf->column)); + g_signal_connect (sf->cell, "toggled", G_CALLBACK (delete_right_clicked), sf); + + g_signal_connect(gtk_tree_view_get_selection(GTK_TREE_VIEW (sf->user_list)), "changed", G_CALLBACK (user_selected), sf); +} + +ShareFolder * +share_folder_new (EGwConnection *ccnc, gchar *id) +{ + ShareFolder *new; + new = (ShareFolder *) g_object_new (share_folder_get_type (), NULL); + share_folder_construct (new); + new->cnc = ccnc; + new->container_id = id; + if (ccnc && id) + get_container_list(new); + + return (ShareFolder *) new; +} + + diff --git a/plugins/groupwise-features/share-folder.h b/plugins/groupwise-features/share-folder.h new file mode 100644 index 0000000000..ac34ada29c --- /dev/null +++ b/plugins/groupwise-features/share-folder.h @@ -0,0 +1,120 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Vivek Jain <jvivek@novell.com> + * + * Copyright 2002-2003 Ximian, Inc. (www.ximian.com) + * + * 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. + * + */ + +#ifndef __SHARE_FOLDER_H__ +#define __SHARE_FOLDER_H__ + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#include <glib.h> +#include <gtk/gtkvbox.h> +#include <gtk/gtk.h> +#include <camel/camel-store.h> +#include <e-gw-connection.h> +#include <libedataserverui/e-name-selector.h> + +#define _SHARE_FOLDER_TYPE (share_folder_get_type ()) +#define SHARE_FOLDER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SHARE_FOLDER, ShareFolder)) +#define SHARE_FOLDER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SHARE_FOLDER_TYPE, ShareFolder)) +#define IS_SHARE_FOLDER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SHARE_FOLDER_TYPE)) +#define IS_SHARE_FOLDER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SHARE_FOLDER_TYPE)) + +typedef struct _ShareFolder ShareFolder; +typedef struct _ShareFolderClass ShareFolderClass; + +struct _GtkWidget; +struct _GladeXML; +struct _GtkButton; +struct _GtkTreeView; +struct _GtkLabel; +struct _GtkEntry; +struct _GtkWindow; +struct _GtkRadioButton; +struct _GtkListStore; +struct _GtkCellRenderer; +struct _GtkTreeViewColumn; +struct _GtkFrame; +struct _GtkVBox; + +struct _ShareFolder { + GtkVBox parent_object; + + struct _GladeXML *xml; + + /* General tab */ + + /* Default Behavior */ + struct _GtkTreeView *user_list; + struct _GtkTextView *message; + struct _GtkButton *add_button; + struct _GtkButton *remove; + struct _GtkButton *add_book; + struct _GtkButton *notification; + struct _GtkEntry *name; + struct _GtkEntry *subject; + struct _GtkRadioButton *shared; + struct _GtkRadioButton *not_shared; + struct _GtkWidget *scrolled_window; + struct _GtkListStore *model; + struct _GtkCellRenderer *cell; + struct _GtkTreeViewColumn *column; + struct _GtkVBox *vbox; + struct _GtkVBox *table; + struct _GtkWidget *window; + + GList *users_list; + EGwContainer *gcontainer; + gint users; + gboolean byme; + gboolean tome; + gint flag_for_ok; + gchar *email; + gboolean is_shared; + EGwConnection *cnc; + gchar *container_id; + gchar *sub; + gchar *mesg; + GList *container_list; + GtkTreeIter iter; + ENameSelector *name_selector; + +}; + +struct _ShareFolderClass { + GtkVBoxClass parent_class; + +}; + +GType share_folderget_type (void); +struct _ShareFolder * share_folder_new (EGwConnection *ccnc, gchar *id); +void share_folder(struct _ShareFolder *sf); +gchar * get_container_id (EGwConnection *cnc, gchar *fname); +EGwConnection * get_cnc (CamelStore *store); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EM_COMPOSER_PREFS_H__ */ diff --git a/plugins/groupwise-features/status-track.c b/plugins/groupwise-features/status-track.c new file mode 100644 index 0000000000..e4b208a812 --- /dev/null +++ b/plugins/groupwise-features/status-track.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2004 Novell, Inc. + * + * Author(s): Chenthill Palanisamy <pchenthill@novell.com> + * Parthasarathi Susarla <sparthasarathi@novell.com> + * + * 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. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib/gi18n-lib.h> +#include <string.h> +#include <stdio.h> +#include <time.h> +#include <gtk/gtk.h> + +#include "camel/camel-folder.h" +#include "camel/camel-medium.h" +#include "camel/camel-mime-message.h" +#include "mail/em-popup.h" + +#include <e-gw-connection.h> + + +void org_gnome_track_status (void *ep, EMPopupTargetSelect *t) ; +void add_recipient (GtkTable *table, char *recp, int row) ; +int add_detail (GtkTable *table, char *label, char *value, int row) ; + +void +add_recipient (GtkTable *table, char *recp, int row) +{ + GtkWidget *widget ; + + widget = gtk_label_new (recp) ; + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_table_attach (table, widget , 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); +} + +int +add_detail (GtkTable *table, char *label, char *value, int row) +{ + GtkWidget *widget ; + time_t time = e_gw_connection_get_date_from_string (value) ; + char *str = ctime (&time) ; + + str [strlen(str)-1] = '\0' ; + + widget = gtk_label_new (label); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_table_attach (table, widget , 1, 2, row, row + 1, GTK_FILL, 0, 0, 0); + widget = gtk_label_new (str); + gtk_table_attach (table, widget , 2, 3, row, row + 1, GTK_FILL, 0, 0, 0); + row++; + return row ; +} +/* + * The format for the options is: + * 0 1 2 3 4 5 6 7 8 9 + * X-gw-status-opt: /TO/CC/BCC;name;email;delivered;opened;accepted;deleted;declined;completed;undelivered:: + */ +void org_gnome_track_status (void *ep, EMPopupTargetSelect *t) +{ + CamelMimeMessage *msg = NULL ; + const CamelInternetAddress *from ; + const char *namep, *addp ; + + GtkDialog *d ; + GtkTable *table ; + GtkWidget *widget; + GtkScrolledWindow *win; + GtkVBox *vbox; + + time_t time ; + char *time_str ; + + const char *status = NULL ; + char **temp1 = NULL, **temp2 = NULL , **ptr = NULL, *str = NULL ; + + int row = 0; + + /*check if it is a groupwise account*/ + str = strstr (t->uri, "groupwise") ; + if (!str) { + g_warning ("Status tracking available for groupwise account only") ; + return ; + } + str = strstr (t->uri, "Sent Items") ; + if (!str) { + g_warning ("Status tracking available for a sent folder only") ; + return ; + } + + /*Get message*/ + msg = camel_folder_get_message (t->folder, g_ptr_array_index (t->uids, 0), NULL); + if (!msg) { + g_print ("Error!! No message\n") ; + return ; + } + status = camel_medium_get_header ( CAMEL_MEDIUM(msg), "X-gw-status-opt") ; + if (!status) { + g_print ("Error!! No header\n") ; + return ; + } + + /*Create the dialog*/ + d = (GtkDialog *) gtk_dialog_new (); + gtk_dialog_add_button (d, GTK_STOCK_OK, GTK_RESPONSE_OK); + gtk_window_set_title (GTK_WINDOW (d), "Message Status"); + + table = (GtkTable *) gtk_table_new (1, 2, FALSE); + win = (GtkScrolledWindow *) gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG(d)->vbox), GTK_WIDGET (win)); + vbox = (GtkVBox *) gtk_vbox_new (FALSE, 12); + gtk_scrolled_window_add_with_viewport (win, GTK_WIDGET(vbox)); + gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (table), FALSE, TRUE, 0); + gtk_scrolled_window_set_policy (win, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + gtk_table_set_col_spacings (table ,12); + gtk_table_set_row_spacings (table, 6); + + /*Subject*/ + widget = gtk_label_new ("<b>Subject</b> :"); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_table_attach (table, widget , 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); + widget = gtk_label_new (camel_mime_message_get_subject(msg)); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_table_attach (table, widget , 1, 2, row, row + 1, GTK_FILL, 0, 0, 0); + row++; + + /*From*/ + from = camel_mime_message_get_from (msg) ; + camel_internet_address_get (from, 0, &namep, &addp) ; + widget = gtk_label_new ("<b>From</b> :"); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_table_attach (table, widget , 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); + widget = gtk_label_new (namep); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_table_attach (table, widget , 1, 2, row, row + 1, GTK_FILL, 0, 0, 0); + row++; + + /*creation date*/ + time = camel_mime_message_get_date (msg, NULL) ; + time_str = ctime (&time) ; + time_str[strlen(time_str)-1] = '\0' ; + widget = gtk_label_new ("<b>Creation date</b> :"); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_table_attach (table, widget , 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); + widget = gtk_label_new (time_str); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_table_attach (table, widget , 1, 2, row, row + 1, GTK_FILL, 0, 0, 0); + row++; + + /*spacing*/ + widget = gtk_label_new (""); + gtk_table_attach (table, widget, 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); + row++; + + /*Table headers*/ + row = 0; + table = (GtkTable *) gtk_table_new (1, 3, FALSE); + gtk_table_set_col_spacings (table ,12); + gtk_table_set_row_spacings (table, 6); + gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (table), FALSE, TRUE, 0); + widget = gtk_label_new ("<b>Recipients </b>"); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_table_attach (table, widget , 0, 1, row, row + 1, GTK_FILL, 0, 0, 0); + widget = gtk_label_new ("<b>Action</b>"); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_table_attach (table, widget , 1, 2, row, row + 1, GTK_FILL, 0, 0, 0); + widget = gtk_label_new ("<b>Date and Time</b>"); + gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5); + gtk_label_set_use_markup (GTK_LABEL (widget), TRUE); + gtk_table_attach (table, widget , 2, 3, row, row + 1, GTK_FILL, 0, 0, 0); + row++; + + + temp1 = g_strsplit (status, "::", -1) ; + ptr = temp1 ; + str = *ptr ; + while (str) { + temp2 = g_strsplit (str, ";", -1) ; + if (*temp2) { + if (strlen(temp2[0])); + if (strlen(temp2[1])) + add_recipient (table, temp2[1], row) ; + if (strlen(temp2[2])); + if (strlen(temp2[3])) + row = add_detail (table,"delivered" , temp2[3], row) ; + if (strlen(temp2[4])) + row = add_detail (table,"opened" , temp2[3], row) ; + if (strlen(temp2[5])) + row = add_detail (table,"accepted" , temp2[3], row) ; + if (strlen(temp2[6])) + row = add_detail (table,"deleted" , temp2[3], row) ; + if (strlen(temp2[7])) + row = add_detail (table,"declined" , temp2[3], row) ; + if (strlen(temp2[8])) + row = add_detail (table,"completed" , temp2[3], row) ; + if (strlen(temp2[9])) + row = add_detail (table,"undelivered" , temp2[3], row) ; + } + str = *(++ptr) ; + g_strfreev (temp2) ; + } + + /*set size and display the dialog*/ + gtk_widget_set_usize (GTK_WIDGET (win), 400, 300); + gtk_widget_show_all (GTK_WIDGET (d)); + if (gtk_dialog_run (d) == GTK_RESPONSE_OK) + gtk_widget_destroy (GTK_WIDGET (d)); + else + gtk_widget_destroy (GTK_WIDGET (d)); + + + g_strfreev (temp1) ; + +} |