[Commits] [SCM] claws branch, master, updated. 3.11.1-230-g53c39d9

charles at claws-mail.org charles at claws-mail.org
Fri Jul 17 07:22:49 CEST 2015


The branch, master has been updated
       via  53c39d90ebd1dbe46677c6edd14809b157a87f9a (commit)
       via  7af42c87bcc37e66ca181a969b3ba113d1267059 (commit)
       via  ec59ae0c2ec01bd13082d5f210924164aa9240bc (commit)
       via  f6bce6ab85f6285550894ccd30b1cba412e0c6e7 (commit)
       via  81acf6b893d9889646b7161a39a549c323d137d9 (commit)
       via  367d6a780ea707df1ab4ce9da7201598bc1718ad (commit)
       via  dde1c4531b1dd320bc893c5af2d9f7cc20308879 (commit)
       via  ee7810602425708a35aaab44e973ba9f12538573 (commit)
       via  dc1d2b4ed5c5c7582275a5b4addbd894ef8a856c (commit)
       via  32924ce7e82afbe83ffa9087fa56694825c6d0ef (commit)
      from  99738a91f6c2ca14fb8feeef9be42904556cf97f (commit)

Summary of changes:
 src/plugins/managesieve/managesieve.c   |  139 ++++++++++++++++---------------
 src/plugins/managesieve/managesieve.h   |    5 +-
 src/plugins/managesieve/sieve_editor.c  |   90 +++++++++++++++++---
 src/plugins/managesieve/sieve_editor.h  |    8 ++
 src/plugins/managesieve/sieve_manager.c |  129 +++++++++++++++-------------
 src/plugins/managesieve/sieve_manager.h |    2 +
 6 files changed, 235 insertions(+), 138 deletions(-)


- Log -----------------------------------------------------------------
commit 53c39d90ebd1dbe46677c6edd14809b157a87f9a
Author: Charles Lehner <cel at celehner.com>
Date:   Fri Jul 17 01:04:38 2015 -0400

    managesieve: add newly created scripts to manager window list

diff --git a/src/plugins/managesieve/sieve_editor.c b/src/plugins/managesieve/sieve_editor.c
index dc89f7f..e085dcb 100644
--- a/src/plugins/managesieve/sieve_editor.c
+++ b/src/plugins/managesieve/sieve_editor.c
@@ -41,6 +41,7 @@
 #include "mainwindow.h"
 #include "message_search.h"
 #include "managesieve.h"
+#include "sieve_manager.h"
 #include "sieve_editor.h"
 
 GSList *editors = NULL;
@@ -348,6 +349,13 @@ static void got_data_saved(SieveSession *session, gboolean abort,
 		if (result->code == SIEVE_CODE_NONE) {
 			result->description = _("Script saved successfully.");
 		}
+
+		if (page->is_new) {
+			/* notify manager windows of newly created script */
+			page->is_new = FALSE;
+			sieve_manager_script_created(session,
+					page->script_name);
+		}
 	}
 	sieve_editor_update_status(page, result);
 }
diff --git a/src/plugins/managesieve/sieve_editor.h b/src/plugins/managesieve/sieve_editor.h
index bac8eea..60d3d86 100644
--- a/src/plugins/managesieve/sieve_editor.h
+++ b/src/plugins/managesieve/sieve_editor.h
@@ -38,6 +38,7 @@ struct SieveEditorPage
 	gboolean	first_line;
 	gboolean	modified;
 	gboolean	closing;
+	gboolean	is_new;
 
 	/* callback for failure to load the script */
 	sieve_session_cb_fn on_load_error;
diff --git a/src/plugins/managesieve/sieve_manager.c b/src/plugins/managesieve/sieve_manager.c
index 65e6dbf..8a786e0 100644
--- a/src/plugins/managesieve/sieve_manager.c
+++ b/src/plugins/managesieve/sieve_manager.c
@@ -163,6 +163,7 @@ static void filter_add(GtkWidget *widget, SieveManagerPage *page)
 			(sieve_session_cb_fn)filter_got_load_error, page);
 	} else {
 		editor = sieve_editor_new(session, filter_name);
+		editor->is_new = TRUE;
 		sieve_editor_show(editor);
 	}
 }
@@ -808,3 +809,14 @@ void sieve_manager_show()
 	manager_pages = g_slist_prepend(manager_pages, page);
 	gtk_widget_show_all(page->window);
 }
+
+void sieve_manager_script_created(SieveSession *session, const gchar *name)
+{
+	SieveManagerPage *page;
+	SieveScript script = {.name = (gchar *)name};
+	GSList *cur;
+
+	manager_sessions_foreach(cur, session, page) {
+		filters_list_insert_filter(page, &script);
+	}
+}
diff --git a/src/plugins/managesieve/sieve_manager.h b/src/plugins/managesieve/sieve_manager.h
index 9665bb8..58f08f0 100644
--- a/src/plugins/managesieve/sieve_manager.h
+++ b/src/plugins/managesieve/sieve_manager.h
@@ -38,5 +38,7 @@ struct SieveManagerPage
 
 void sieve_manager_show(void);
 void sieve_manager_done(SieveManagerPage *page);
+void sieve_manager_script_created(SieveSession *session,
+		const gchar *filter_name);
 
 #endif /* SIEVE_MANAGER_H */

commit 7af42c87bcc37e66ca181a969b3ba113d1267059
Author: Charles Lehner <cel at celehner.com>
Date:   Fri Jul 17 00:01:15 2015 -0400

    managesieve: if new script name is in use, open existing script
    
    This is better than opening a blank script which will overwrite the existing
    one when it is saved

diff --git a/src/plugins/managesieve/sieve_manager.c b/src/plugins/managesieve/sieve_manager.c
index b6d92c1..65e6dbf 100644
--- a/src/plugins/managesieve/sieve_manager.c
+++ b/src/plugins/managesieve/sieve_manager.c
@@ -59,6 +59,7 @@ typedef struct {
 	gchar *filter_name;
 } CommandDataName;
 
+static void filter_got_load_error(SieveSession *session, gpointer data);
 static void account_changed(GtkWidget *widget, SieveManagerPage *page);
 static void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page);
 static gboolean sieve_manager_deleted(GtkWidget *widget, GdkEvent *event,
@@ -145,6 +146,7 @@ static gchar *filters_list_get_selected_filter(GtkWidget *list_view)
 static void filter_add(GtkWidget *widget, SieveManagerPage *page)
 {
 	SieveSession *session = page->active_session;
+	SieveEditorPage *editor;
 	if (!session)
 		return;
 	gchar *filter_name = input_dialog(_("Add Sieve script"),
@@ -152,7 +154,17 @@ static void filter_add(GtkWidget *widget, SieveManagerPage *page)
 	if (!filter_name || !filter_name[0])
 		return;
 
-	sieve_editor_show(sieve_editor_new(session, filter_name));
+	editor = sieve_editor_get(session, filter_name);
+	if (editor) {
+		/* TODO: show error that filter already exists */
+		sieve_editor_present(editor);
+		g_free(filter_name);
+		sieve_editor_load(editor,
+			(sieve_session_cb_fn)filter_got_load_error, page);
+	} else {
+		editor = sieve_editor_new(session, filter_name);
+		sieve_editor_show(editor);
+	}
 }
 
 static void filter_got_load_error(SieveSession *session, gpointer data)

commit ec59ae0c2ec01bd13082d5f210924164aa9240bc
Author: Charles Lehner <cel at celehner.com>
Date:   Fri Jul 17 00:41:00 2015 -0400

    managesieve: let refresh button always be sensitive
    
    When the session is disconnected, refresh can be clicked to try to reconnect.
    
    This partially reverts commit 7c2dd3d976388c353632ea0c3199ccdd3e214530.

diff --git a/src/plugins/managesieve/sieve_manager.c b/src/plugins/managesieve/sieve_manager.c
index fab6703..b6d92c1 100644
--- a/src/plugins/managesieve/sieve_manager.c
+++ b/src/plugins/managesieve/sieve_manager.c
@@ -603,7 +603,7 @@ static SieveManagerPage *sieve_manager_page_new()
 {
 	SieveManagerPage *page;
 	GtkWidget *window;
-	GtkWidget *hbox, *vbox, *vbox_buttons;
+	GtkWidget *hbox, *vbox, *vbox_allbuttons, *vbox_buttons;
 	GtkWidget *accounts_menu;
 	GtkWidget *label;
 	GtkWidget *scrolledwin;
@@ -702,9 +702,13 @@ static SieveManagerPage *sieve_manager_page_new()
 
 	/* Buttons */
 
+	vbox_allbuttons = gtk_vbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), vbox_allbuttons, FALSE, FALSE, 0);
+
+	/* buttons that depend on there being a connection */
 	vbox_buttons = gtk_vbox_new (FALSE, 8);
 	gtk_widget_set_sensitive(vbox_buttons, FALSE);
-	gtk_box_pack_start (GTK_BOX (hbox), vbox_buttons, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox_allbuttons), vbox_buttons, FALSE, FALSE, 0);
 
 	/* new */
 	btn = gtk_button_new_from_stock(GTK_STOCK_NEW);
@@ -732,7 +736,7 @@ static SieveManagerPage *sieve_manager_page_new()
 
 	/* refresh */
 	btn = gtk_button_new_from_stock(GTK_STOCK_REFRESH);
-	gtk_box_pack_end (GTK_BOX (vbox_buttons), btn, FALSE, FALSE, 0);
+	gtk_box_pack_end (GTK_BOX (vbox_allbuttons), btn, FALSE, FALSE, 0);
 	g_signal_connect (G_OBJECT(btn), "clicked",
 			G_CALLBACK (account_changed), page);
 

commit f6bce6ab85f6285550894ccd30b1cba412e0c6e7
Author: Charles Lehner <cel at celehner.com>
Date:   Fri Jul 17 00:00:53 2015 -0400

    managesieve: remove unused function sieve_session_add_script

diff --git a/src/plugins/managesieve/managesieve.c b/src/plugins/managesieve/managesieve.c
index 5042328..9170c05 100644
--- a/src/plugins/managesieve/managesieve.c
+++ b/src/plugins/managesieve/managesieve.c
@@ -976,15 +976,6 @@ void sieve_session_list_scripts(SieveSession *session,
 	sieve_queue_send(session, SIEVE_LISTSCRIPTS, msg, cb, data);
 }
 
-void sieve_session_add_script(SieveSession *session, const gchar *filter_name,
-		sieve_session_data_cb_fn cb, gpointer data)
-{
-/*
-	gchar *msg = g_strdup("LISTSCRIPTS");
-	sieve_queue_send(session, SIEVE_LISTSCRIPTS, msg, cb, data);
-*/
-}
-
 void sieve_session_set_active_script(SieveSession *session,
 		const gchar *filter_name,
 		sieve_session_data_cb_fn cb, gpointer data)
diff --git a/src/plugins/managesieve/managesieve.h b/src/plugins/managesieve/managesieve.h
index 068f8bb..908ffa4 100644
--- a/src/plugins/managesieve/managesieve.h
+++ b/src/plugins/managesieve/managesieve.h
@@ -172,8 +172,6 @@ void sieve_session_handle_status(SieveSession *session,
 		gpointer data);
 void sieve_session_list_scripts(SieveSession *session,
 		sieve_session_data_cb_fn got_script_name_cb, gpointer data);
-void sieve_session_add_script(SieveSession *session, const gchar *filter_name,
-		sieve_session_data_cb_fn cb, gpointer data);
 void sieve_session_set_active_script(SieveSession *session,
 		const gchar *filter_name,
 		sieve_session_data_cb_fn cb, gpointer data);
diff --git a/src/plugins/managesieve/sieve_manager.c b/src/plugins/managesieve/sieve_manager.c
index 9d49d4f..fab6703 100644
--- a/src/plugins/managesieve/sieve_manager.c
+++ b/src/plugins/managesieve/sieve_manager.c
@@ -153,10 +153,6 @@ static void filter_add(GtkWidget *widget, SieveManagerPage *page)
 		return;
 
 	sieve_editor_show(sieve_editor_new(session, filter_name));
-	/*
-	sieve_session_add_script(session, filter_name
-			(sieve_session_data_cb_fn)filter_added, (gpointer)page);
-			*/
 }
 
 static void filter_got_load_error(SieveSession *session, gpointer data)

commit 81acf6b893d9889646b7161a39a549c323d137d9
Author: Charles Lehner <cel at celehner.com>
Date:   Thu Jul 16 23:51:00 2015 -0400

    managesieve: don't reset status while appending text

diff --git a/src/plugins/managesieve/sieve_editor.c b/src/plugins/managesieve/sieve_editor.c
index 66dd6ea..dc89f7f 100644
--- a/src/plugins/managesieve/sieve_editor.c
+++ b/src/plugins/managesieve/sieve_editor.c
@@ -54,6 +54,7 @@ gboolean sieve_editor_search_string_backward(void *obj,
 	const gchar *str, gboolean case_sens);
 static void sieve_editor_save_cb(GtkAction *action, SieveEditorPage *page);
 static void sieve_editor_check_cb(GtkAction *action, SieveEditorPage *page);
+static void sieve_editor_changed_cb(GtkTextBuffer *, SieveEditorPage *page);
 static void sieve_editor_revert_cb(GtkAction *action, SieveEditorPage *page);
 static void sieve_editor_close_cb(GtkAction *action, SieveEditorPage *page);
 static void sieve_editor_undo_cb(GtkAction *action, SieveEditorPage *page);
@@ -113,14 +114,19 @@ void sieve_editor_append_text(SieveEditorPage *page, gchar *text, gint len)
 {
 	GtkTextBuffer *buffer;
 	GtkTextIter iter;
-	gboolean was_modified = page->modified;
 
-	undo_block(page->undostruct);
 	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(page->text));
+
+	g_signal_handlers_block_by_func(G_OBJECT(buffer),
+			 G_CALLBACK(sieve_editor_changed_cb), page);
+
+	undo_block(page->undostruct);
 	gtk_text_buffer_get_end_iter(buffer, &iter);
 	gtk_text_buffer_insert(buffer, &iter, text, len);
 	undo_unblock(page->undostruct);
-	sieve_editor_set_modified(page, was_modified);
+
+	g_signal_handlers_unblock_by_func(G_OBJECT(buffer),
+			 G_CALLBACK(sieve_editor_changed_cb), page);
 }
 
 static gint sieve_editor_get_text(SieveEditorPage *page, gchar **text)

commit 367d6a780ea707df1ab4ce9da7201598bc1718ad
Author: Charles Lehner <cel at celehner.com>
Date:   Thu Jul 16 21:34:02 2015 -0400

    managesieve: discard manager window's callbacks when it closes

diff --git a/src/plugins/managesieve/sieve_manager.c b/src/plugins/managesieve/sieve_manager.c
index 42e7911..9d49d4f 100644
--- a/src/plugins/managesieve/sieve_manager.c
+++ b/src/plugins/managesieve/sieve_manager.c
@@ -60,7 +60,9 @@ typedef struct {
 } CommandDataName;
 
 static void account_changed(GtkWidget *widget, SieveManagerPage *page);
-void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page);
+static void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page);
+static gboolean sieve_manager_deleted(GtkWidget *widget, GdkEvent *event,
+		SieveManagerPage *page);
 static void filter_set_active(SieveManagerPage *page, gchar *filter_name);
 gboolean filter_find_by_name (GtkTreeModel *model, GtkTreeIter *iter,
 		gchar *filter_name);
@@ -634,6 +636,8 @@ static SieveManagerPage *sieve_manager_page_new()
 			G_CALLBACK (manager_key_pressed), page);
 	g_signal_connect (G_OBJECT(window), "size_allocate",
 			 G_CALLBACK (size_allocate_cb), NULL);
+	g_signal_connect (G_OBJECT(window), "delete_event",
+			 G_CALLBACK (sieve_manager_deleted), page);
 
 	if (!geometry.min_height) {
 		geometry.min_width = 350;
@@ -766,7 +770,14 @@ static SieveManagerPage *sieve_manager_page_new()
 	return page;
 }
 
-void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page)
+static gboolean sieve_manager_deleted(GtkWidget *widget, GdkEvent *event,
+		SieveManagerPage *page)
+{
+	sieve_manager_done(page);
+	return FALSE;
+}
+
+static void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page)
 {
 	sieve_manager_done(page);
 }
@@ -774,6 +785,7 @@ void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page)
 void sieve_manager_done(SieveManagerPage *page)
 {
 	manager_pages = g_slist_remove(manager_pages, page);
+	sieve_sessions_discard_callbacks(page);
 	gtk_widget_destroy(page->window);
 	g_free(page);
 }

commit dde1c4531b1dd320bc893c5af2d9f7cc20308879
Author: Charles Lehner <cel at celehner.com>
Date:   Thu Jul 16 21:16:26 2015 -0400

    managesieve: consolidate popping send queue
    
    - send a queued command when the ready state is entered
    - always free a command when it is done

diff --git a/src/plugins/managesieve/managesieve.c b/src/plugins/managesieve/managesieve.c
index 111e4a0..5042328 100644
--- a/src/plugins/managesieve/managesieve.c
+++ b/src/plugins/managesieve/managesieve.c
@@ -296,7 +296,7 @@ static gint sieve_auth(SieveSession *session)
 	if (!session->use_auth) {
 		session->state = SIEVE_READY;
 		sieve_connected(session, TRUE);
-		return sieve_pop_send_queue(session);
+		return SE_OK;
 	}
 
 	session->state = SIEVE_AUTH;
@@ -403,6 +403,11 @@ static gint sieve_pop_send_queue(SieveSession *session)
 	SieveCommand *cmd;
 	GSList *send_queue = session->send_queue;
 
+	if (session->current_cmd) {
+		command_free(session->current_cmd);
+		session->current_cmd = NULL;
+	}
+
 	if (!send_queue)
 		return SE_OK;
 
@@ -412,8 +417,6 @@ static gint sieve_pop_send_queue(SieveSession *session)
 
 	log_send(session, cmd);
 	session->state = cmd->next_state;
-	if (session->current_cmd)
-		command_free(session->current_cmd);
 	session->current_cmd = cmd;
 	if (session_send_msg(SESSION(session), SESSION_SEND, cmd->msg) < 0)
 		return SE_ERROR;
@@ -528,7 +531,7 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 {
 	SieveSession *sieve_session = SIEVE_SESSION(session);
 	SieveResult result;
-	gint ret = 0;
+	gint ret = SE_OK;
 
 	switch (sieve_session->state) {
 	case SIEVE_GETSCRIPT_DATA:
@@ -581,7 +584,6 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 			} else {
 				sieve_session->state = SIEVE_READY;
 				sieve_connected(sieve_session, TRUE);
-				ret = sieve_pop_send_queue(sieve_session);
 			}
 		} else {
 			/* got a capability */
@@ -604,7 +606,6 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 		}
 		sieve_session->tls_init_done = TRUE;
 		sieve_session->state = SIEVE_CAPABILITIES;
-		ret = SE_OK;
 #endif
 		break;
 	case SIEVE_AUTH:
@@ -626,7 +627,6 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 			sieve_session->authenticated = TRUE;
 			sieve_session->state = SIEVE_READY;
 			sieve_connected(sieve_session, TRUE);
-			ret = sieve_pop_send_queue(sieve_session);
 		}
 		break;
 	case SIEVE_NOOP:
@@ -640,14 +640,12 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 			/* got an error. probably not authenticated. */
 			command_cb(sieve_session->current_cmd, NULL);
 			sieve_session->state = SIEVE_READY;
-			ret = sieve_pop_send_queue(sieve_session);
 		} else if (response_is_ok(msg)) {
 			/* end of list */
 			sieve_session->state = SIEVE_READY;
 			sieve_session->error = SE_OK;
 			command_cb(sieve_session->current_cmd,
 					(gpointer)&(SieveScript){0});
-			ret = sieve_pop_send_queue(sieve_session);
 		} else {
 			/* got a script name */
 			SieveScript script;
@@ -659,7 +657,6 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 
 			command_cb(sieve_session->current_cmd,
 					(gpointer)&script);
-			ret = SE_OK;
 		}
 		break;
 	case SIEVE_RENAMESCRIPT:
@@ -694,7 +691,6 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 			/* account for newline */
 			sieve_session->octets_remaining = result.octets + 1;
 		}
-		ret = SE_OK;
 		break;
 	case SIEVE_GETSCRIPT_DATA:
 		if (sieve_session->octets_remaining > 0) {
@@ -706,7 +702,6 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 		} else {
 			log_warning(LOG_PROTOCOL, _("error occurred on SIEVE session\n"));
 		}
-		ret = SE_OK;
 		break;
 	case SIEVE_PUTSCRIPT:
 		parse_response((gchar *)msg, &result);
@@ -716,7 +711,6 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 			sieve_session->state = SIEVE_READY;
 		}
 		sieve_session_putscript_cb(sieve_session, &result);
-		ret = SE_OK;
 		break;
 	case SIEVE_PUTSCRIPT_DATA:
 		if (!msg[0]) {
@@ -729,7 +723,6 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 			result.description = (gchar *)msg;
 			sieve_session_putscript_cb(sieve_session, &result);
 		}
-		ret = SE_OK;
 		break;
 	case SIEVE_DELETESCRIPT:
 		parse_response((gchar *)msg, &result);
@@ -757,9 +750,12 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 		return -1;
 	}
 
-	if (ret == SE_OK)
+	if (ret == SE_OK && sieve_session->state == SIEVE_READY)
+		ret = sieve_pop_send_queue(sieve_session);
+
+	if (ret == SE_OK) {
 		return session_recv_msg(session);
-	else if (ret == SE_AUTHFAIL) {
+	} else if (ret == SE_AUTHFAIL) {
 		sieve_error(sieve_session, _("Auth failed"));
 		sieve_session->state = SIEVE_ERROR;
 		sieve_session->error = SE_ERROR;

commit ee7810602425708a35aaab44e973ba9f12538573
Author: Charles Lehner <cel at celehner.com>
Date:   Thu Jul 16 21:15:45 2015 -0400

    managesieve: fix connecting with TLS not available

diff --git a/src/plugins/managesieve/managesieve.c b/src/plugins/managesieve/managesieve.c
index 323c52d..111e4a0 100644
--- a/src/plugins/managesieve/managesieve.c
+++ b/src/plugins/managesieve/managesieve.c
@@ -570,7 +570,7 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 					sieve_session->state = SIEVE_ERROR;
 				} else {
 					log_warning(LOG_PROTOCOL, "Sieve: continuing without TLS\n");
-					sieve_session->state = SIEVE_CAPABILITIES;
+					sieve_session->state = SIEVE_READY;
 				}
 				break;
 			}

commit dc1d2b4ed5c5c7582275a5b4addbd894ef8a856c
Author: Charles Lehner <cel at celehner.com>
Date:   Thu Jul 9 03:24:02 2015 -0400

    managesieve: allow script loading to be interrupted
    
    Prevent use after free when an editor window is closed while loading
    
    Uses string "Loading..." which is already translated

diff --git a/src/plugins/managesieve/sieve_editor.c b/src/plugins/managesieve/sieve_editor.c
index eedd3e7..66dd6ea 100644
--- a/src/plugins/managesieve/sieve_editor.c
+++ b/src/plugins/managesieve/sieve_editor.c
@@ -625,8 +625,6 @@ MENUITEM_ADDUI_MANAGER(ui_manager, "/Menu/Filter", "Revert", "Filter/Revert", GT
 	undo_set_change_state_func(undostruct, &sieve_editor_undo_state_changed,
 			page);
 
-	gtk_widget_show_all(window);
-
 	page->window = window;
 	page->ui_manager = ui_manager;
 	page->text = text;
@@ -661,6 +659,11 @@ void sieve_editor_present(SieveEditorPage *page)
 	gtk_window_present(GTK_WINDOW(page->window));
 }
 
+void sieve_editor_show(SieveEditorPage *page)
+{
+	gtk_widget_show_all(GTK_WIDGET(page->window));
+}
+
 static void sieve_editor_set_modified(SieveEditorPage *page,
 		gboolean modified)
 {
@@ -680,3 +683,49 @@ static void sieve_editor_set_modified(SieveEditorPage *page,
 		sieve_editor_set_status_icon(page, NULL);
 	}
 }
+
+static void got_data_loading(SieveSession *session, gboolean aborted,
+		gchar *contents, SieveEditorPage *page)
+{
+	if (aborted)
+		return;
+	if (contents == NULL) {
+		/* end of data */
+		sieve_editor_set_status(page, "");
+		return;
+	}
+	if (contents == (void *)-1) {
+		/* error */
+		if (page->first_line) {
+			/* no data. show error in manager window */
+			if (page->on_load_error)
+				page->on_load_error(session, page->on_load_error_data);
+		} else {
+			/* partial failure. show error in editor window */
+			sieve_editor_set_status(page, _("Unable to get script contents"));
+			sieve_editor_set_status_icon(page, GTK_STOCK_DIALOG_ERROR);
+		}
+		return;
+	}
+
+	if (page->first_line) {
+		page->first_line = FALSE;
+		sieve_editor_show(page);
+	} else {
+		sieve_editor_append_text(page, "\n", 1);
+	}
+	sieve_editor_append_text(page, contents, strlen(contents));
+}
+
+/* load the script for this editor */
+void sieve_editor_load(SieveEditorPage *page,
+		sieve_session_cb_fn on_load_error, gpointer load_error_data)
+{
+	page->first_line = TRUE;
+	page->on_load_error = on_load_error;
+	page->on_load_error_data = load_error_data;
+	sieve_editor_set_status(page, _("Loading..."));
+	sieve_editor_set_status_icon(page, NULL);
+	sieve_session_get_script(page->session, page->script_name,
+			(sieve_session_data_cb_fn)got_data_loading, page);
+}
diff --git a/src/plugins/managesieve/sieve_editor.h b/src/plugins/managesieve/sieve_editor.h
index 4925a54..bac8eea 100644
--- a/src/plugins/managesieve/sieve_editor.h
+++ b/src/plugins/managesieve/sieve_editor.h
@@ -38,12 +38,19 @@ struct SieveEditorPage
 	gboolean	first_line;
 	gboolean	modified;
 	gboolean	closing;
+
+	/* callback for failure to load the script */
+	sieve_session_cb_fn on_load_error;
+	gpointer on_load_error_data;
 };
 
 SieveEditorPage *sieve_editor_new(SieveSession *session, gchar *script_name);
 SieveEditorPage *sieve_editor_get(SieveSession *session, gchar *script_name);
+void sieve_editor_load(SieveEditorPage *page,
+		sieve_session_cb_fn on_load_error, gpointer load_error_data);
 void sieve_editor_append_text(SieveEditorPage *page, gchar *text, gint len);
 void sieve_editor_close(SieveEditorPage *page);
+void sieve_editor_show(SieveEditorPage *page);
 void sieve_editor_present(SieveEditorPage *page);
 
 #endif /* SIEVE_EDITOR_H */
diff --git a/src/plugins/managesieve/sieve_manager.c b/src/plugins/managesieve/sieve_manager.c
index 400a671..42e7911 100644
--- a/src/plugins/managesieve/sieve_manager.c
+++ b/src/plugins/managesieve/sieve_manager.c
@@ -59,13 +59,6 @@ typedef struct {
 	gchar *filter_name;
 } CommandDataName;
 
-typedef struct {
-	SieveManagerPage *page;
-	gchar *filter_name;
-	SieveEditorPage *editor_page;
-	gboolean first_line;
-} CommandDataGetScript;
-
 static void account_changed(GtkWidget *widget, SieveManagerPage *page);
 void sieve_manager_close(GtkWidget *widget, SieveManagerPage *page);
 static void filter_set_active(SieveManagerPage *page, gchar *filter_name);
@@ -157,46 +150,28 @@ static void filter_add(GtkWidget *widget, SieveManagerPage *page)
 	if (!filter_name || !filter_name[0])
 		return;
 
-	sieve_editor_new(session, filter_name);
+	sieve_editor_show(sieve_editor_new(session, filter_name));
 	/*
 	sieve_session_add_script(session, filter_name
 			(sieve_session_data_cb_fn)filter_added, (gpointer)page);
 			*/
 }
 
-static void filter_got_data(SieveSession *session, gboolean abort,
-		gchar *contents, CommandDataGetScript *cmd_data)
+static void filter_got_load_error(SieveSession *session, gpointer data)
 {
-	SieveManagerPage *page = cmd_data->page;
-	SieveEditorPage *editor;
+	SieveManagerPage *page = data;
 
-	if (abort || !contents) {
-		g_free(cmd_data->filter_name);
-		g_free(cmd_data);
-		return;
-	} else if (contents == (void *)-1) {
-		got_session_error(session, _("Unable to get script contents"), page);
-		return;
-	}
-
-	if (cmd_data->first_line) {
-		cmd_data->first_line = FALSE;
-		editor = sieve_editor_new(session, cmd_data->filter_name);
-		cmd_data->editor_page = editor;
-	} else {
-		editor = cmd_data->editor_page;
-		sieve_editor_append_text(editor, "\n", 1);
-	}
-	sieve_editor_append_text(editor, contents, strlen(contents));
+	got_session_error(session, _("Unable to get script contents"), page);
 }
 
 static void filter_edit(GtkWidget *widget, SieveManagerPage *page)
 {
 	SieveEditorPage *editor;
-	CommandDataGetScript *cmd_data;
 	SieveSession *session = page->active_session;
+
 	if (!session)
 		return;
+
 	gchar *filter_name = filters_list_get_selected_filter(page->filters_list);
 	if (!filter_name)
 		return;
@@ -205,13 +180,9 @@ static void filter_edit(GtkWidget *widget, SieveManagerPage *page)
 	if (editor) {
 		sieve_editor_present(editor);
 	} else {
-		cmd_data = g_new0(CommandDataGetScript, 1);
-		cmd_data->first_line = TRUE;
-		cmd_data->filter_name = filter_name;
-		cmd_data->page = page;
-
-		sieve_session_get_script(session, filter_name,
-			(sieve_session_data_cb_fn)filter_got_data, cmd_data);
+		editor = sieve_editor_new(session, filter_name);
+		sieve_editor_load(editor,
+			(sieve_session_cb_fn)filter_got_load_error, page);
 	}
 }
 

commit 32924ce7e82afbe83ffa9087fa56694825c6d0ef
Author: Charles Lehner <cel at celehner.com>
Date:   Thu Jul 16 20:06:47 2015 -0400

    managesieve: fix command aborting and discarding
    
    - Add "aborted" callback argument to indicate command is cancelled
    - Add helper function for issuing command callbacks

diff --git a/src/plugins/managesieve/managesieve.c b/src/plugins/managesieve/managesieve.c
index a6d7bbb..323c52d 100644
--- a/src/plugins/managesieve/managesieve.c
+++ b/src/plugins/managesieve/managesieve.c
@@ -39,6 +39,9 @@ GSList *sessions = NULL;
 static void sieve_session_destroy(Session *session);
 static gint sieve_pop_send_queue(SieveSession *session);
 static void sieve_session_reset(SieveSession *session);
+static void command_free(SieveCommand *cmd);
+static void command_abort(SieveCommand *cmd);
+static void command_cb(SieveCommand *cmd, gpointer result);
 
 void sieve_sessions_close()
 {
@@ -48,34 +51,55 @@ void sieve_sessions_close()
 	}
 }
 
-void noop_data_cb_fn(SieveSession *session, gpointer cb_data,
-		gpointer user_data)
-{
-	/* noop */
-}
-
 /* remove all command callbacks with a given data pointer */
 void sieve_sessions_discard_callbacks(gpointer user_data)
 {
 	GSList *item;
 	GSList *queue;
+	GSList *prev = NULL;
 	SieveSession *session;
 	SieveCommand *cmd;
 
 	for (item = sessions; item; item = item->next) {
 		session = (SieveSession *)item->data;
 		cmd = session->current_cmd;
-		if (cmd && cmd->data == user_data)
-			cmd->cb = noop_data_cb_fn;
+		/* abort current command handler */
+		if (cmd && cmd->data == user_data) {
+			command_abort(cmd);
+			session->current_cmd = NULL;
+		}
+		/* abort queued command handlers */
 		for (queue = session->send_queue; queue; queue = queue->next) {
-			cmd = (SieveCommand *)item->data;
-			if (cmd && cmd->data == user_data)
-				cmd->cb = noop_data_cb_fn;
+			cmd = (SieveCommand *)queue->data;
+			if (cmd && cmd->data == user_data) {
+				if (prev)
+					prev->next = queue->next;
+				else
+					session->send_queue = NULL;
+				command_abort(cmd);
+				g_slist_free_1(queue);
+			} else {
+				prev = queue;
+			}
 		}
 	}
 }
 
-void command_free(SieveCommand *cmd) {
+static void command_cb(SieveCommand *cmd, gpointer result)
+{
+	if (cmd)
+		cmd->cb(cmd->session, FALSE, result, cmd->data);
+}
+
+static void command_abort(SieveCommand *cmd)
+{
+	cmd->cb(cmd->session, TRUE, NULL, cmd->data);
+	g_free(cmd->msg);
+	g_free(cmd);
+}
+
+static void command_free(SieveCommand *cmd)
+{
 	g_free(cmd->msg);
 	g_free(cmd);
 }
@@ -319,7 +343,7 @@ static void sieve_session_putscript_cb(SieveSession *session, SieveResult *resul
 		result->description = desc;
 	}
 	/* pass along the callback */
-	session->current_cmd->cb(session, result, session->current_cmd->data);
+	command_cb(session->current_cmd, result);
 }
 
 static inline gboolean response_is_ok(const char *msg)
@@ -614,17 +638,15 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 	case SIEVE_LISTSCRIPTS:
 		if (response_is_no(msg)) {
 			/* got an error. probably not authenticated. */
-			sieve_session->current_cmd->cb(sieve_session, NULL,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, NULL);
 			sieve_session->state = SIEVE_READY;
 			ret = sieve_pop_send_queue(sieve_session);
 		} else if (response_is_ok(msg)) {
 			/* end of list */
 			sieve_session->state = SIEVE_READY;
 			sieve_session->error = SE_OK;
-			sieve_session->current_cmd->cb(sieve_session,
-					(gpointer)&(SieveScript){0},
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd,
+					(gpointer)&(SieveScript){0});
 			ret = sieve_pop_send_queue(sieve_session);
 		} else {
 			/* got a script name */
@@ -635,19 +657,17 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 			script.active = (script_status &&
 					strcasecmp(script_status, "active") == 0);
 
-			sieve_session->current_cmd->cb(sieve_session, (gpointer)&script,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd,
+					(gpointer)&script);
 			ret = SE_OK;
 		}
 		break;
 	case SIEVE_RENAMESCRIPT:
 		if (response_is_no(msg)) {
 			/* error */
-			sieve_session->current_cmd->cb(sieve_session, NULL,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, NULL);
 		} else if (response_is_ok(msg)) {
-			sieve_session->current_cmd->cb(sieve_session, (void*)TRUE,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, (void*)TRUE);
 		} else {
 			log_warning(LOG_PROTOCOL, _("error occurred on SIEVE session\n"));
 		}
@@ -656,11 +676,9 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 	case SIEVE_SETACTIVE:
 		if (response_is_no(msg)) {
 			/* error */
-			sieve_session->current_cmd->cb(sieve_session, NULL,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, NULL);
 		} else if (response_is_ok(msg)) {
-			sieve_session->current_cmd->cb(sieve_session, (void*)TRUE,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, (void*)TRUE);
 		} else {
 			log_warning(LOG_PROTOCOL, _("error occurred on SIEVE session\n"));
 		}
@@ -668,8 +686,7 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 		break;
 	case SIEVE_GETSCRIPT:
 		if (response_is_no(msg)) {
-			sieve_session->current_cmd->cb(sieve_session, (void *)-1,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, (void *)-1);
 			sieve_session->state = SIEVE_READY;
 		} else {
 			parse_response((gchar *)msg, &result);
@@ -681,14 +698,11 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 		break;
 	case SIEVE_GETSCRIPT_DATA:
 		if (sieve_session->octets_remaining > 0) {
-			sieve_session->current_cmd->cb(sieve_session,
-					(gchar *)msg,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, (gchar *)msg);
 			sieve_session->octets_remaining -= strlen(msg) + 1;
 		} else if (response_is_ok(msg)) {
 			sieve_session->state = SIEVE_READY;
-			sieve_session->current_cmd->cb(sieve_session, NULL,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, NULL);
 		} else {
 			log_warning(LOG_PROTOCOL, _("error occurred on SIEVE session\n"));
 		}
@@ -720,11 +734,10 @@ static gint sieve_session_recv_msg(Session *session, const gchar *msg)
 	case SIEVE_DELETESCRIPT:
 		parse_response((gchar *)msg, &result);
 		if (!result.success) {
-			sieve_session->current_cmd->cb(sieve_session, result.description,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd,
+					result.description);
 		} else {
-			sieve_session->current_cmd->cb(sieve_session, NULL,
-					sieve_session->current_cmd->data);
+			command_cb(sieve_session->current_cmd, NULL);
 		}
 		sieve_session->state = SIEVE_READY;
 		break;
@@ -791,8 +804,10 @@ static void sieve_session_destroy(Session *session)
 	SieveSession *sieve_session = SIEVE_SESSION(session);
 	g_free(sieve_session->pass);
 	if (sieve_session->current_cmd)
-		command_free(sieve_session->current_cmd);
+		command_abort(sieve_session->current_cmd);
 	sessions = g_slist_remove(sessions, (gconstpointer)session);
+	g_slist_free_full(sieve_session->send_queue,
+			(GDestroyNotify)command_abort);
 }
 
 static void sieve_connect_finished(Session *session, gboolean success)
@@ -834,7 +849,7 @@ static void sieve_session_reset(SieveSession *session)
 	SieveAccountConfig *config = sieve_prefs_account_get_config(account);
 	gboolean reuse_auth = (config->auth == SIEVEAUTH_REUSE);
 
-	g_slist_free_full(session->send_queue, (GDestroyNotify)command_free);
+	g_slist_free_full(session->send_queue, (GDestroyNotify)command_abort);
 
 	session_disconnect(SESSION(session));
 
@@ -921,6 +936,7 @@ static void sieve_queue_send(SieveSession *session, SieveState next_state,
 {
 	gboolean queue = FALSE;
 	SieveCommand *cmd = g_new0(SieveCommand, 1);
+	cmd->session = session;
 	cmd->next_state = next_state;
 	cmd->msg = msg;
 	cmd->data = data;
@@ -980,7 +996,7 @@ void sieve_session_set_active_script(SieveSession *session,
 	gchar *msg = g_strdup_printf("SETACTIVE \"%s\"",
 			filter_name ? filter_name : "");
 	if (!msg) {
-		cb(session, (void*)FALSE, data);
+		cb(session, FALSE, (void*)FALSE, data);
 		return;
 	}
 
diff --git a/src/plugins/managesieve/managesieve.h b/src/plugins/managesieve/managesieve.h
index c150d4a..068f8bb 100644
--- a/src/plugins/managesieve/managesieve.h
+++ b/src/plugins/managesieve/managesieve.h
@@ -98,7 +98,7 @@ typedef enum {
 
 typedef void (*sieve_session_cb_fn) (SieveSession *session, gpointer data);
 typedef void (*sieve_session_data_cb_fn) (SieveSession *session,
-		gpointer cb_data, gpointer user_data);
+		gboolean aborted, gpointer cb_data, gpointer user_data);
 typedef void (*sieve_session_error_cb_fn) (SieveSession *session,
 		const gchar *msg, gpointer user_data);
 typedef void (*sieve_session_connected_cb_fn) (SieveSession *session,
@@ -140,6 +140,7 @@ struct SieveSession
 };
 
 struct SieveCommand {
+	SieveSession *session;
 	SieveState next_state;
 	gchar *msg;
 	sieve_session_data_cb_fn cb;
diff --git a/src/plugins/managesieve/sieve_editor.c b/src/plugins/managesieve/sieve_editor.c
index a6be14f..eedd3e7 100644
--- a/src/plugins/managesieve/sieve_editor.c
+++ b/src/plugins/managesieve/sieve_editor.c
@@ -266,9 +266,12 @@ static void sieve_editor_search(SieveEditorPage *page)
 
 /* Actions */
 
-static void got_data_reverting(SieveSession *session, gchar *contents,
+static void got_data_reverting(SieveSession *session, gboolean abort,
+		gchar *contents,
 		SieveEditorPage *page)
 {
+	if (abort)
+		return;
 	if (contents == NULL) {
 		/* end of data */
 		undo_unblock(page->undostruct);
@@ -324,9 +327,11 @@ static void sieve_editor_revert_cb(GtkAction *action, SieveEditorPage *page)
 		sieve_editor_revert(page);
 }
 
-static void got_data_saved(SieveSession *session, SieveResult *result,
-		SieveEditorPage *page)
+static void got_data_saved(SieveSession *session, gboolean abort,
+		SieveResult *result, SieveEditorPage *page)
 {
+	if (abort)
+		return;
 	if (result->has_status && result->success) {
 		sieve_editor_set_modified(page, FALSE);
 		if (page->closing) {
@@ -362,9 +367,11 @@ static void sieve_editor_find_cb(GtkAction *action, SieveEditorPage *page)
 	sieve_editor_search(page);
 }
 
-static void got_data_checked(SieveSession *session, SieveResult *result,
-		SieveEditorPage *page)
+static void got_data_checked(SieveSession *session, gboolean abort,
+		SieveResult *result, SieveEditorPage *page)
 {
+	if (abort)
+		return;
 	sieve_editor_update_status(page, result);
 }
 
diff --git a/src/plugins/managesieve/sieve_manager.c b/src/plugins/managesieve/sieve_manager.c
index 9e89bad..400a671 100644
--- a/src/plugins/managesieve/sieve_manager.c
+++ b/src/plugins/managesieve/sieve_manager.c
@@ -164,13 +164,13 @@ static void filter_add(GtkWidget *widget, SieveManagerPage *page)
 			*/
 }
 
-static void filter_got_data(SieveSession *session, gchar *contents,
-		CommandDataGetScript *cmd_data)
+static void filter_got_data(SieveSession *session, gboolean abort,
+		gchar *contents, CommandDataGetScript *cmd_data)
 {
 	SieveManagerPage *page = cmd_data->page;
 	SieveEditorPage *editor;
 
-	if (!contents) {
+	if (abort || !contents) {
 		g_free(cmd_data->filter_name);
 		g_free(cmd_data);
 		return;
@@ -215,13 +215,14 @@ static void filter_edit(GtkWidget *widget, SieveManagerPage *page)
 	}
 }
 
-static void filter_renamed(SieveSession *session, gboolean success,
-		CommandDataRename *data)
+static void filter_renamed(SieveSession *session, gboolean abort,
+		gboolean success, CommandDataRename *data)
 {
 	SieveManagerPage *page = data->page;
 	GSList *cur;
 
-	if (!success) {
+	if (abort) {
+	} else if (!success) {
 		got_session_error(session, "Unable to rename script", page);
 	} else {
 		manager_sessions_foreach(cur, session, page) {
@@ -261,13 +262,14 @@ static void filter_rename(GtkWidget *widget, SieveManagerPage *page)
 			(sieve_session_data_cb_fn)filter_renamed, (gpointer)cmd_data);
 }
 
-static void filter_activated(SieveSession *session, gboolean success,
-		CommandDataName *cmd_data)
+static void filter_activated(SieveSession *session, gboolean abort,
+		gboolean success, CommandDataName *cmd_data)
 {
 	SieveManagerPage *page = cmd_data->page;
 	GSList *cur;
 
-	if (!success) {
+	if (abort) {
+	} else if (!success) {
 		got_session_error(session, "Unable to set active script", page);
 	} else {
 		manager_sessions_foreach(cur, session, page) {
@@ -292,13 +294,15 @@ static void sieve_set_active_filter(SieveManagerPage *page, gchar *filter_name)
 			(sieve_session_data_cb_fn)filter_activated, cmd_data);
 }
 
-static void filter_deleted(SieveSession *session, const gchar *err_msg,
+static void filter_deleted(SieveSession *session, gboolean abort,
+		const gchar *err_msg,
 		CommandDataName *cmd_data)
 {
 	SieveManagerPage *page = cmd_data->page;
 	GSList *cur;
 
-	if (err_msg) {
+	if (abort) {
+	} else if (err_msg) {
 		got_session_error(session, err_msg, page);
 	} else {
 		manager_sessions_foreach(cur, session, page) {
@@ -550,6 +554,8 @@ static void size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation)
 static void got_session_error(SieveSession *session, const gchar *msg,
 		SieveManagerPage *page)
 {
+	if (!g_slist_find(manager_pages, page))
+		return;
 	if (page->active_session != session)
 		return;
 	gtk_label_set_text(GTK_LABEL(page->status_text), msg);
@@ -575,9 +581,11 @@ static void sieve_manager_on_connected(SieveSession *session,
 	}
 }
 
-static void got_filter_listed(SieveSession *session, SieveScript *script,
-		SieveManagerPage *page)
+static void got_filter_listed(SieveSession *session, gboolean abort,
+		SieveScript *script, SieveManagerPage *page)
 {
+	if (abort)
+		return;
 	if (!script) {
 		got_session_error(session, "Unable to list scripts", page);
 		return;

-----------------------------------------------------------------------


hooks/post-receive
-- 
Claws Mail


More information about the Commits mailing list