/* * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) version 3. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with the program; if not, see * * * Authors: * Vivek Jain * * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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); static void create_shared_folder(EPopup *ep, EPopupItem *p, gpointer data); static void popup_free (EPopup *ep, GSList *items, gpointer data); 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); if (!account){ return; } 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 { MailMsg base; /* input data */ CamelStore *store; gchar *full_name; gchar *parent; gchar *name; /* output data */ CamelFolderInfo *fi; /* callback data */ void (* done) (struct _EMCreateFolder *m, gpointer user_data); gpointer user_data; }; static gchar * create_folder_desc (struct _EMCreateFolder *m) { return g_strdup_printf (_("Creating folder `%s'"), m->full_name); } static void create_folder_exec (struct _EMCreateFolder *m) { 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, &m->base.ex))) { if (camel_store_supports_subscriptions (m->store)) camel_store_subscribe_folder (m->store, m->full_name, &m->base.ex); } } static void create_folder_done (struct _EMCreateFolder *m) { 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 _EMCreateFolder *m) { 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 MailMsgInfo create_folder_info = { sizeof (struct _EMCreateFolder), (MailMsgDescFunc) create_folder_desc, (MailMsgExecFunc) create_folder_exec, (MailMsgDoneFunc) create_folder_done, (MailMsgFreeFunc) create_folder_free }; static void new_folder_created_cb (struct _EMCreateFolder *m, gpointer 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 gchar *full_name, void (* done) (struct _EMCreateFolder *m, gpointer user_data), gpointer user_data) { gchar *name, *namebuf = NULL; struct _EMCreateFolder *m; const gchar *parent; gint id; namebuf = g_strdup (full_name); if (!(name = strrchr (namebuf, '/'))) { name = namebuf; parent = ""; } else { *name++ = '\0'; parent = namebuf; } m = mail_msg_new (&create_folder_info); 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->base.seq; mail_msg_unordered_push (m); return id; } static void users_dialog_response(GtkWidget *dialog, gint response, struct ShareInfo *ssi) { struct _EMFolderTreeModelStoreInfo *si; EMFolderSelector *emfs = ssi->emfs; const gchar *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; /* ensures vfolder is running */ vfolder_load_storage (); 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, gint response, EMFolderTreeModel *model) { GtkWidget *users_dialog; GtkWidget *w; struct ShareInfo *ssi; const gchar *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 ; } static EPopupItem popup_items[] = { { E_POPUP_ITEM, (gchar *) "20.emc.001", (gchar *) N_("New _Shared Folder..."), create_shared_folder, NULL, (gchar *) "folder-new", 0, EM_POPUP_FOLDER_INFERIORS } }; static void popup_free (EPopup *ep, GSList *items, gpointer data) { g_slist_free (items); } void org_gnome_create_option(EPlugin *ep, EMPopupTargetFolder *t) { GSList *menus = NULL; gint i = 0; static gint first = 0; if (! g_strrstr (t->uri, "groupwise://")) return ; /* for translation*/ if (!first) { popup_items[0].label = _(popup_items[0].label); } first++; for (i = 0; i < sizeof (popup_items) / sizeof (popup_items[0]); i++) menus = g_slist_prepend (menus, &popup_items[i]); e_popup_add_items (t->target.popup, menus, NULL, popup_free, NULL); } static void create_shared_folder(EPopup *ep, EPopupItem *p, gpointer data) { EMFolderTreeModel *model; EMFolderTree *folder_tree; GtkWidget *dialog ; gchar *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 *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; /* This is kind of bad..but we don't have types for all these folders.*/ if ( !( strcmp (folder_name, "Mailbox") && strcmp (folder_name, "Calendar") && strcmp (folder_name, "Contacts") && strcmp (folder_name, "Documents") && strcmp (folder_name, "Authored") && strcmp (folder_name, "Default Library") && strcmp (folder_name, "Work In Progress") && strcmp (folder_name, "Cabinet") && strcmp (folder_name, "Sent Items") && strcmp (folder_name, "Trash") && strcmp (folder_name, "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 gchar *uri, *property_value, *server_name, *user, *port; gchar *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")) { gchar *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, const gchar *fname) { GList *container_list = NULL; gchar *id = NULL; gchar *name; gchar **names; gint 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; }