[evolution-kolab/ek-wip-gui: 143/143] Bug #675764 - "Kolab Folder Properties" from addressbook context menu crashes Evolution



commit 865e6bf01f4108fe513df8bf4622f8cbba9084bb
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Fri May 11 16:58:58 2012 +0200

    Bug #675764 - "Kolab Folder Properties" from addressbook context menu crashes Evolution
    
    * clicking the "Kolab Folder Properties" context menu
      entry of any PIM SideShell Kolab node resulted in a
      crash due to a missing differentiation between mail
      and PIM SideShells
    * added that differentiation to the plugin UI code
    * fixed a typo in the *.eplug.xml file which led
      to the context menu entry not being shown for
      notes
    * made UI error handling somewhat more robust by
      returning with a warning instead of barfing hard
      via an assertion failure in several places
    * added an utility function to libekolab/ for
      getting the protocol part from an (ESource) URI

 src/eplugin/e-kolab-plugin-ui.c       |  181 +++++++++++++++++++++++++--------
 src/eplugin/org-gnome-kolab.eplug.xml |    2 +-
 src/libekolab/kolab-util-backend.c    |   19 ++++
 src/libekolab/kolab-util-backend.h    |    1 +
 4 files changed, 157 insertions(+), 46 deletions(-)
---
diff --git a/src/eplugin/e-kolab-plugin-ui.c b/src/eplugin/e-kolab-plugin-ui.c
index 2db1008..06285e6 100644
--- a/src/eplugin/e-kolab-plugin-ui.c
+++ b/src/eplugin/e-kolab-plugin-ui.c
@@ -44,6 +44,7 @@
 #include <mail/em-folder-tree.h>
 
 #include <libekolab/kolab-data-imap-account.h>
+#include <libekolab/kolab-util-backend.h>
 #include <libekolabutil/kolab-util-camel.h>
 
 #include "e-kolab-folder-metadata.h"
@@ -208,10 +209,47 @@ kolab_folder_prop_ui_response_cb (GObject *dialog,
 /*----------------------------------------------------------------------------*/
 /* internal statics (UI) */
 
+static gboolean
+kolab_plugin_ui_get_selected_source (EShellView *shell_view,
+                                     ESource **selected_source)
+{
+	ESource *source = NULL;
+	gchar *uri = NULL;
+	EShellSidebar *shell_sidebar = NULL;
+	ESourceSelector *selector = NULL;
+
+	g_return_val_if_fail (shell_view != NULL, FALSE);
+	g_return_val_if_fail (selected_source == NULL || *selected_source == NULL, FALSE);
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	g_return_val_if_fail (shell_sidebar != NULL, FALSE);
+
+	g_object_get (shell_sidebar, "selector", &selector, NULL);
+	g_return_val_if_fail (selector != NULL, FALSE);
+
+	source = e_source_selector_peek_primary_selection (selector);
+	uri = source ? e_source_get_uri (source) : NULL;
+	/* check whether we have a Kolab ESource selected */
+	if (uri && g_str_has_prefix (uri, KOLAB_CAMEL_URI_PREFIX))
+		source = g_object_ref (source);
+	else
+		source = NULL;
+
+	g_free (uri);
+	g_object_unref (selector);
+
+	if (selected_source)
+		*selected_source = source;
+	else if (source)
+		g_object_unref (source);
+
+	return source != NULL;
+}
+
 static gchar*
-kolab_plugin_ui_get_selected_path (EShellView *shell_view,
-                                   gboolean *is_kolab_account_node,
-                                   gboolean *is_kolab_folder_node)
+kolab_plugin_ui_path_from_mail_view (EShellView *shell_view,
+                                     gboolean *is_kolab_account_node,
+                                     gboolean *is_kolab_folder_node)
 {
 	EShellSidebar *shell_sidebar = NULL;
 	EMFolderTree *folder_tree = NULL;
@@ -240,6 +278,81 @@ kolab_plugin_ui_get_selected_path (EShellView *shell_view,
 	return selected_path;
 }
 
+static gchar*
+kolab_plugin_ui_path_from_pim_view (EShellView *shell_view,
+                                    gboolean *is_kolab_account_node,
+                                    gboolean *is_kolab_folder_node)
+{
+	gchar *selected_path = NULL;
+	ESource *source = NULL;
+	gboolean is_source = FALSE;
+	gchar *uri = NULL;
+	gchar *proto = NULL;
+
+	g_assert (E_IS_SHELL_VIEW (shell_view));
+
+	*is_kolab_account_node = FALSE;
+	*is_kolab_folder_node = FALSE;
+
+	is_source = kolab_plugin_ui_get_selected_source (shell_view,
+	                                                 &source);
+	if (! is_source)
+		goto exit;
+
+	uri = e_source_get_uri (source);
+	if (uri == NULL)
+		goto exit;
+
+	proto = kolab_util_backend_get_protocol_from_uri (uri);
+	if (g_strcmp0 (proto, KOLAB_CAMEL_PROVIDER_PROTOCOL) != 0) {
+		g_warning ("%s()[%u] got wrong protocol '%s'",
+		           __func__, __LINE__, proto);
+		goto exit;
+	}
+
+	selected_path = kolab_util_backend_get_relative_path_from_uri (uri);
+	if (selected_path == NULL)
+		g_warning ("%s()[%u] selected path is NULL", __func__, __LINE__);
+	*is_kolab_folder_node = TRUE;
+
+ exit:
+	if (uri != NULL)
+		g_free (uri);
+	if (proto != NULL)
+		g_free (proto);
+
+	return selected_path;
+}
+
+static gchar*
+kolab_plugin_ui_get_selected_path (EShellView *shell_view,
+                                   gboolean *is_kolab_account_node,
+                                   gboolean *is_kolab_folder_node)
+{
+	gchar *selected_path = NULL;
+	const gchar *view_name = NULL;
+
+	g_assert (E_IS_SHELL_VIEW (shell_view));
+
+	/* TODO find a cleaner solution for this.
+	 *
+	 * Since it seems we cannot directly check for
+	 * the EShellView subtype, we use the view name
+	 * property to tell the types apart...
+	 */
+	view_name = e_shell_view_get_name (shell_view);
+
+	if (g_strcmp0 (view_name, "mail") == 0)
+		selected_path = kolab_plugin_ui_path_from_mail_view (shell_view,
+		                                                     is_kolab_account_node,
+		                                                     is_kolab_folder_node);
+	else
+		selected_path = kolab_plugin_ui_path_from_pim_view (shell_view,
+		                                                    is_kolab_account_node,
+		                                                    is_kolab_folder_node);
+	return selected_path;
+}
+
 static GtkWidget*
 kolab_plugin_ui_selected_folder_widget (GtkAction *action,
                                         EShellView *shell_view)
@@ -256,8 +369,10 @@ kolab_plugin_ui_selected_folder_widget (GtkAction *action,
 	foldername = kolab_plugin_ui_get_selected_path (shell_view,
 	                                                &is_kolab_account_node,
 	                                                &is_kolab_folder_node);
-	g_assert (!is_kolab_account_node);
-	g_assert (is_kolab_folder_node);
+
+	g_return_val_if_fail (foldername != NULL, NULL);
+	g_return_val_if_fail (!is_kolab_account_node, NULL);
+	g_return_val_if_fail (is_kolab_folder_node, NULL);
 
 	label = gtk_label_new (NULL);
 	labeltext = g_strconcat ("<b>", _("Selected Folder"), ": </b>", foldername, NULL);
@@ -280,6 +395,22 @@ kolab_plugin_ui_action_kolab_properties_cb (GtkAction *action,
 
 	uidata = kolab_folder_prop_ui_data_new ();
 
+	uidata->widgets->selected_folder =
+		kolab_plugin_ui_selected_folder_widget (action, shell_view);
+	if (uidata->widgets->selected_folder == NULL) {
+		/* TODO this should not happen.
+		 *
+		 * If the selected folder is NULL here, it means
+		 * it is no Kolab folder node. There should not
+		 * be a context menu entry in this case in the
+		 * first place.
+		 */
+		g_warning ("%s()[%u]: Selected folder is no Kolab folder node",
+		           __func__, __LINE__);
+		kolab_folder_prop_ui_data_free (uidata);
+		return;
+	}
+
 	uidata->widgets->dialog =
 		gtk_dialog_new_with_buttons (_("Edit Kolab Folder Properties..."),
 		                             NULL, /* parent */
@@ -289,9 +420,6 @@ kolab_plugin_ui_action_kolab_properties_cb (GtkAction *action,
 		                             NULL);
 	gtk_window_set_resizable (GTK_WINDOW (uidata->widgets->dialog), FALSE);
 
-	uidata->widgets->selected_folder =
-		kolab_plugin_ui_selected_folder_widget (action, shell_view);
-
 	uidata->meta_ui_data = e_kolab_folder_metadata_ui_new ();
 	uidata->perm_ui_data = e_kolab_folder_permissions_ui_new ();
 	/* FIXME get account data here */
@@ -341,43 +469,6 @@ kolab_plugin_ui_action_kolab_properties_cb (GtkAction *action,
 	gtk_widget_show (uidata->widgets->dialog);
 }
 
-static gboolean
-kolab_plugin_ui_get_selected_source (EShellView *shell_view,
-                                     ESource **selected_source)
-{
-	ESource *source;
-	gchar *uri = NULL;
-	EShellSidebar *shell_sidebar;
-	ESourceSelector *selector = NULL;
-
-	g_return_val_if_fail (shell_view != NULL, FALSE);
-	g_return_val_if_fail (selected_source == NULL || *selected_source == NULL, FALSE);
-
-	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
-	g_return_val_if_fail (shell_sidebar != NULL, FALSE);
-
-	g_object_get (shell_sidebar, "selector", &selector, NULL);
-	g_return_val_if_fail (selector != NULL, FALSE);
-
-	source = e_source_selector_peek_primary_selection (selector);
-	uri = source ? e_source_get_uri (source) : NULL;
-	/* check whether we have a Kolab ESource selected */
-	if (uri && g_str_has_prefix (uri, KOLAB_CAMEL_URI_PREFIX))
-		source = g_object_ref (source);
-	else
-		source = NULL;
-
-	g_free (uri);
-	g_object_unref (selector);
-
-	if (selected_source)
-		*selected_source = source;
-	else if (source)
-		g_object_unref (source);
-
-	return source != NULL;
-}
-
 static void
 kolab_plugin_ui_enable_actions (GtkActionGroup *action_group,
                                 const GtkActionEntry *entries,
diff --git a/src/eplugin/org-gnome-kolab.eplug.xml b/src/eplugin/org-gnome-kolab.eplug.xml
index d27fffd..fa062eb 100644
--- a/src/eplugin/org-gnome-kolab.eplug.xml
+++ b/src/eplugin/org-gnome-kolab.eplug.xml
@@ -64,7 +64,7 @@
       <ui-manager id="org.gnome.evolution.memos" callback="e_kolab_plugin_init_memos">
 	<popup name="memo-list-popup">
 	  <placeholder name="memo-list-popup-actions">
-	    <menuitem action="kolab-memo-folder-properties" />
+	    <menuitem action="kolab-memos-folder-properties" />
 	  </placeholder>
 	</popup>
       </ui-manager>
diff --git a/src/libekolab/kolab-util-backend.c b/src/libekolab/kolab-util-backend.c
index b354a90..ebaa043 100644
--- a/src/libekolab/kolab-util-backend.c
+++ b/src/libekolab/kolab-util-backend.c
@@ -147,6 +147,25 @@ kolab_util_backend_get_relative_path_from_uri (const gchar *uri)
 	return path;
 } /* kolab_util_backend_get_relative_path_from_uri () */
 
+gchar*
+kolab_util_backend_get_protocol_from_uri (const gchar *uri)
+{
+	CamelURL *c_url = NULL;
+	gchar *proto = NULL;
+	GError *tmp_err = NULL;
+
+	c_url = camel_url_new (uri, &tmp_err);
+	if (c_url == NULL) {
+		g_warning ("%s()[%u] error: %s", __func__, __LINE__, tmp_err->message);
+		g_error_free (tmp_err);
+		return NULL;
+	}
+	proto = g_strdup (c_url->protocol);
+	camel_url_free (c_url);
+
+	return proto;
+}
+
 static gint
 kolab_util_misc_generic_integer_from_property (const gchar *prop_str,
                                                gint DEFAULT_VALUE)
diff --git a/src/libekolab/kolab-util-backend.h b/src/libekolab/kolab-util-backend.h
index a1be082..4b4ae7f 100644
--- a/src/libekolab/kolab-util-backend.h
+++ b/src/libekolab/kolab-util-backend.h
@@ -79,6 +79,7 @@ gchar* kolab_util_backend_sourcename_new_from_foldername (const gchar *foldernam
 gchar* kolab_util_backend_foldername_new_from_sourcename (const gchar *sourcename, GError **err);
 
 gchar *kolab_util_backend_get_relative_path_from_uri (const gchar *uri);
+gchar *kolab_util_backend_get_protocol_from_uri (const gchar *uri);
 KolabSyncStrategyID kolab_util_misc_sync_value_from_property (const gchar *sync_prop);
 KolabTLSVariantID kolab_util_misc_tls_variant_from_property (const gchar *tls_variant);
 KolabReqPkcs11 kolab_util_misc_req_pkcs11_from_property (const gchar *req_pkcs11_prop);



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