From 58727dbb22ceeaf950ba7931fd516b112689b5a6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 30 Oct 2010 14:23:01 -0400 Subject: Kill mail_append_mail(). Use e_mail_folder_append_message() instead. --- plugins/templates/templates.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 815ee69882..bca45f040f 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -31,6 +31,7 @@ #include +#include #include #include #include @@ -710,7 +711,10 @@ got_message_draft_cb (EMsgComposer *composer, camel_message_info_set_flags ( info, CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_DRAFT, ~0); - mail_append_mail (folder, message, info, NULL, composer); + /* FIXME No async callback, so... hope for the best? */ + e_mail_folder_append_message ( + folder, message, info, G_PRIORITY_DEFAULT, + NULL, (GAsyncReadyCallback) NULL, NULL); g_object_unref (message); } -- cgit v1.2.3 From 1182cdfec8e5986e36ac6bc4f4fa9ba32599d7d5 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 3 Dec 2010 15:36:40 -0600 Subject: Avoid a crash when building templates menu. --- plugins/templates/templates.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index bca45f040f..625c70245b 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -618,6 +618,11 @@ build_template_menus_recurse (GtkUIManager *ui_manager, /* FIXME Not passing a GCancellable or GError here. */ template = camel_folder_get_message_sync ( folder, uid, NULL, NULL); + + /* FIXME Do something more intelligent with errors. */ + if (template == NULL) + continue; + g_object_ref (template); action_label = -- cgit v1.2.3 From 824a754c584da12cce2032c85dc49207d469dbb4 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 6 Jan 2011 15:52:23 +0100 Subject: Bug #633854 - [templates] Crash in build_template_menus_recurse --- plugins/templates/templates.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 625c70245b..9b664bbe55 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -567,10 +567,10 @@ build_template_menus_recurse (GtkUIManager *ui_manager, gchar *path; guint ii; + folder_name = folder_info->name; /* FIXME Not passing a GCancellable or GError here. */ folder = camel_store_get_folder_sync ( store, folder_info->full_name, 0, NULL, NULL); - folder_name = camel_folder_get_name (folder); action_name = g_strdup_printf ( "templates-menu-%d", *action_count); @@ -603,9 +603,15 @@ build_template_menus_recurse (GtkUIManager *ui_manager, path, action_count, merge_id, folder_info->child, message_folder, message_uid); + if (!folder) { + g_free (path); + folder_info = folder_info->next; + continue; + } + /* Get the UIDs for this folder and add them to the menu. */ uids = camel_folder_get_uids (folder); - for (ii = 0; ii < uids->len; ii++) { + for (ii = 0; uids && ii < uids->len; ii++) { CamelMimeMessage *template; const gchar *uid = uids->pdata[ii], *muid; guint32 flags; @@ -666,8 +672,9 @@ build_template_menus_recurse (GtkUIManager *ui_manager, g_object_unref (action); g_free (action_name); } - camel_folder_free_uids (folder, uids); + camel_folder_free_uids (folder, uids); + g_object_unref (folder); g_free (path); folder_info = folder_info->next; -- cgit v1.2.3 From c36bd27fa84fec81ad40032c0dce07051d73f04c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 19 Jan 2011 14:56:35 +0100 Subject: Bug #634403 - Mails Label popup menu is not updated properly --- plugins/templates/templates.c | 1 + 1 file changed, 1 insertion(+) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 9b664bbe55..3e3bb49195 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -780,6 +780,7 @@ update_actions_cb (EShellView *shell_view) gtk_ui_manager_remove_ui (ui_manager, merge_id); e_action_group_remove_all_actions (action_group); + gtk_ui_manager_ensure_update (ui_manager); if (!plugin_enabled) return; -- cgit v1.2.3 From a4e2599f950cd2379a18a4c39cd27f87f090d492 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 14 Feb 2011 19:15:36 +0100 Subject: Fix few memory leaks --- plugins/templates/templates.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 3e3bb49195..fd8f8021f7 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -629,8 +629,6 @@ build_template_menus_recurse (GtkUIManager *ui_manager, if (template == NULL) continue; - g_object_ref (template); - action_label = camel_mime_message_get_subject (template); if (action_label == NULL || *action_label == '\0') -- cgit v1.2.3 From 2abbff465156c62c0825190a4408fe92b4d55bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Wed, 27 Apr 2011 17:10:14 +0200 Subject: Bug #641845 - Add default expansion variables to templates plugin Users can read values from original message in the template by $ORIG[header] and with a special value $ORIG[body]. --- plugins/templates/templates.c | 545 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 448 insertions(+), 97 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index fd8f8021f7..9fded58413 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -84,6 +84,10 @@ static void value_cell_edited_callback (GtkCellRendererText *cell, gchar *path_ static gboolean clue_foreach_check_isempty (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, UIData *ui); +static void templates_folder_msg_changed_cb (CamelFolder *folder, + CamelFolderChangeInfo *change_info, + EShellWindow *shell_window); + static gboolean plugin_enabled; static void @@ -465,46 +469,325 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) return hbox; } +/* Case insensitive version of strstr */ +static gchar * +strstr_nocase (const gchar* haystack, const gchar *needle) +{ +/* When _GNU_SOURCE is available, use the nonstandard extension of libc */ +#ifdef _GNU_SOURCE + g_return_val_if_fail (haystack, NULL); + g_return_Val_if_fail (needle, NULL); + + return strcasestr (haystack, needle) +#else +/* Otherwise convert both, haystack and needle to lowercase and use good old strstr */ + gchar *l_haystack; + gchar *l_needle; + gchar *pos; + + g_return_val_if_fail (haystack, NULL); + g_return_val_if_fail (needle, NULL); + + l_haystack = g_ascii_strdown (haystack, -1); + l_needle = g_ascii_strdown (needle, -1); + pos = strstr (l_haystack, l_needle); + + /* Get actual position of the needle in the haystack instead of l_haystack or + leave it NULL */ + if (pos) + pos = (gchar *)(haystack + (pos - l_haystack)); + + g_free (l_haystack); + g_free (l_needle); + + return pos; +#endif +} + +/* Replaces $ORIG[variable] in given template by given replacement from the original message */ +static void +replace_template_variable (GString *text, const gchar *variable, const gchar *replacement) +{ + const gchar *p, *next; + GString *str; + gint find_len; + gchar *find; + + g_return_if_fail (text != NULL); + g_return_if_fail (variable != NULL); + g_return_if_fail (*variable); + + find = g_strconcat ("$ORIG[", variable, "]", NULL); + + find_len = strlen (find); + str = g_string_new (""); + p = text->str; + while (next = strstr_nocase (p, find), next) { + if (p < next) + g_string_append_len (str, p, next - p); + if (replacement && *replacement) + g_string_append (str, replacement); + p = next + find_len; + } + g_string_append (str, p); + + g_string_assign (text, str->str); + + g_string_free (str, TRUE); + g_free (find); +} + +static void +replace_email_addresses (GString *template, CamelInternetAddress *internet_address, const gchar *variable) +{ + gint address_index = 0; + GString *emails = g_string_new (""); + const gchar *address_name, *address_email; + + g_return_if_fail (template); + g_return_if_fail (internet_address); + g_return_if_fail (variable); + + while (camel_internet_address_get (internet_address, address_index, &address_name, &address_email)) { + gchar *address = camel_internet_address_format_address (address_name, address_email); + + if (address_index > 0) + g_string_append_printf (emails, ", %s", address); + else + g_string_append_printf (emails, "%s", address); + + address_index++; + g_free (address); + } + replace_template_variable (template, variable, emails->str); + g_string_free (emails, TRUE); +} + +static CamelMimePart* +fill_template (CamelMimeMessage *message, CamelMimePart *template) +{ + struct _camel_header_raw *header; + CamelContentType *ct; + CamelStream *stream; + CamelMimePart *return_part; + CamelMimePart *message_part = NULL; + CamelDataWrapper *dw; + + CamelInternetAddress *internet_address; + + GString *template_body; + GByteArray *byte_array; + + gint i; + gboolean message_html, template_html; + + ct = camel_mime_part_get_content_type (template); + template_html = ct && camel_content_type_is (ct, "text", "html"); + + message_html = FALSE; + /* When template is html, then prefer HTML part of the original message. Otherwise go for plaintext */ + dw = camel_medium_get_content (CAMEL_MEDIUM (message)); + if (CAMEL_IS_MULTIPART (dw)) { + CamelMultipart *multipart = CAMEL_MULTIPART (dw); + + for (i = 0; i < camel_multipart_get_number (multipart); i++) { + CamelMimePart *part = camel_multipart_get_part (multipart, i); + CamelContentType *ct = camel_mime_part_get_content_type (part); + + if (!ct) + continue; + + if (camel_content_type_is (ct, "text", "html") && template_html) { + message_part = camel_multipart_get_part (multipart, i); + message_html = TRUE; + break; + } else if (camel_content_type_is (ct, "text", "plain") && message_html == FALSE) { + message_part = camel_multipart_get_part (multipart, i); + } + } + } else + message_part = CAMEL_MIME_PART (message); + + /* Get content of the template */ + stream = camel_stream_mem_new (); + camel_data_wrapper_decode_to_stream_sync (camel_medium_get_content (CAMEL_MEDIUM (template)), stream, NULL, NULL); + camel_stream_flush (stream, NULL, NULL); + byte_array = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (stream)); + template_body = g_string_new_len ((gchar *) byte_array->data, byte_array->len); + g_object_unref (stream); + + /* Replace all $ORIG[header_name] by respective values */ + header = CAMEL_MIME_PART (message)->headers; + while (header) { + if (g_ascii_strncasecmp (header->name, "content-", 8) != 0 && + g_ascii_strncasecmp (header->name, "to", 2) != 0 && + g_ascii_strncasecmp (header->name, "cc", 2) != 0 && + g_ascii_strncasecmp (header->name, "bcc", 3) != 0 && + g_ascii_strncasecmp (header->name, "from", 4) != 0 && + g_ascii_strncasecmp (header->name, "subject", 7) != 0) + replace_template_variable (template_body, header->name, header->value); + + header = header->next; + } + + /* Now manually replace the *subject* header. The header->value for subject header could be + base64 encoded, so let camel_mime_message to decode it for us if needed */ + replace_template_variable (template_body, "subject", camel_mime_message_get_subject (message)); + + /* Replace TO and FROM modifiers. */ + internet_address = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_TO); + replace_email_addresses (template_body, internet_address, "to"); + + internet_address = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_CC); + replace_email_addresses (template_body, internet_address, "cc"); + + internet_address = camel_mime_message_get_recipients (message, CAMEL_RECIPIENT_TYPE_BCC); + replace_email_addresses (template_body, internet_address, "bcc"); + + internet_address = camel_mime_message_get_from (message); + replace_email_addresses (template_body, internet_address, "from"); + + /* Now extract body of the original message and replace the $ORIG[body] modifier in template */ + if (message_part && strstr_nocase (template_body->str, "$ORIG[body]")) { + GString *message_body; + + stream = camel_stream_mem_new (); + camel_data_wrapper_decode_to_stream_sync (camel_medium_get_content (CAMEL_MEDIUM (message_part)), stream, NULL, NULL); + camel_stream_flush (stream, NULL, NULL); + byte_array = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (stream)); + message_body = g_string_new_len ((gchar*)byte_array->data, byte_array->len); + g_object_unref (stream); + + if (template_html && !message_html) { + gchar *html = camel_text_to_html (message_body->str, CAMEL_MIME_FILTER_TOHTML_CONVERT_NL | + CAMEL_MIME_FILTER_TOHTML_CONVERT_SPACES | + CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | + CAMEL_MIME_FILTER_TOHTML_MARK_CITATION | + CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES, 0); + g_string_assign (message_body, html); + g_free (html); + } else if (!template_html && message_html) { + g_string_prepend (message_body, "
");
+			g_string_append (message_body, "
"); + } /* Other cases should not occur. And even if they happen to do, there's nothing we can really do about it */ + + replace_template_variable (template_body, "body", message_body->str); + g_string_free (message_body, TRUE); + } else { + replace_template_variable (template_body, "body", ""); + } + + return_part = camel_mime_part_new (); + + if (template_html) + camel_mime_part_set_content (return_part, template_body->str, template_body->len, "text/html"); + else + camel_mime_part_set_content (return_part, template_body->str, template_body->len, "text/plain"); + + g_string_free (template_body, TRUE); + + return return_part; +} + static void create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *message, gpointer data) { - GtkAction *action = data; - CamelMimeMessage *new, *template; + CamelMimeMessage *new; + CamelMimeMessage *template = CAMEL_MIME_MESSAGE (data); + CamelMultipart *new_multipart; + CamelContentType *new_content_type = NULL; + CamelDataWrapper *dw; struct _camel_header_raw *header; - CamelStream *mem; EShell *shell; + gint i; + + CamelMimePart *template_part = NULL; + CamelMimePart *out_part = NULL; - g_return_if_fail (data != NULL); + g_return_if_fail (template != NULL); g_return_if_fail (message != NULL); /* FIXME Pass this in somehow. */ shell = e_shell_get_default (); folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_TEMPLATES); - template = g_object_get_data (G_OBJECT (action), "template"); - /* The new message we are creating */ new = camel_mime_message_new (); + new_multipart = camel_multipart_new (); + camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (new_multipart), "multipart/alternative"); + camel_multipart_set_boundary (new_multipart, NULL); + + dw = camel_medium_get_content (CAMEL_MEDIUM (template)); + /* If template is a multipart, then try to use HTML. When no HTML part is available, use plaintext. Every other + add as an attachment */ + if (CAMEL_IS_MULTIPART (dw)) { + for (i = 0; i < camel_multipart_get_number (CAMEL_MULTIPART (dw)); i++) { + CamelMimePart *part = camel_multipart_get_part (CAMEL_MULTIPART (dw), i); + CamelContentType *ct = camel_mime_part_get_content_type (part); + + if (ct && camel_content_type_is (ct, "text", "html")) { + new_content_type = ct; + template_part = camel_multipart_get_part (CAMEL_MULTIPART (dw), i); + } else if (ct && camel_content_type_is (ct, "text", "plain") && new_content_type == NULL) { + new_content_type = ct; + template_part = camel_multipart_get_part (CAMEL_MULTIPART (dw), i); + } else { + /* Copy any other parts (attachments...) to the output message */ + camel_mime_part_set_disposition (part, "attachment"); + camel_multipart_add_part (new_multipart, part); + } + } + } else { + CamelContentType *ct = camel_mime_part_get_content_type (CAMEL_MIME_PART (template)); - /* make the exact copy of the template message, with all - its attachments and message structure */ - mem = camel_stream_mem_new (); - camel_data_wrapper_write_to_stream_sync ( - CAMEL_DATA_WRAPPER (template), mem, NULL, NULL); - camel_stream_reset (mem, NULL); - camel_data_wrapper_construct_from_stream_sync ( - CAMEL_DATA_WRAPPER (new), mem, NULL, NULL); - g_object_unref (mem); + if (ct && (camel_content_type_is (ct, "text", "html") || + camel_content_type_is (ct, "text", "plain"))) { + template_part = CAMEL_MIME_PART (template); + new_content_type = ct; + } + } + + /* Here replace all the modifiers in template body by values from message and return the newly created part */ + out_part = fill_template (message, template_part); + + /* Assigning part directly to mime_message causes problem with "Content-type" header displaying + in the HTML message (camel parsing bug?) */ + camel_multipart_add_part (new_multipart, out_part); + g_object_unref (out_part); + camel_medium_set_content (CAMEL_MEDIUM (new), CAMEL_DATA_WRAPPER (new_multipart)); /* Add the headers from the message we are replying to, so CC and that - * stuff is preserved. */ - header = ((CamelMimePart *)message)->headers; + stuff is preserved. Also replace any $ORIG[header-name] modifiers ignoring + 'content-*' headers */ + header = CAMEL_MIME_PART (message)->headers; while (header) { if (g_ascii_strncasecmp (header->name, "content-", 8) != 0) { - camel_medium_add_header ((CamelMedium *) new, - header->name, - header->value); + + /* Some special handling of the 'subject' header */ + if (g_ascii_strncasecmp (header->name, "subject", 7) == 0) { + GString *subject = g_string_new (camel_mime_message_get_subject (template)); + + /* Now replace all possible $ORIG[]s in the subject line by values from original message */ + struct _camel_header_raw *m_header = CAMEL_MIME_PART (message)->headers; + while (m_header) { + if (g_ascii_strncasecmp (m_header->name, "content-", 8) != 0 && + g_ascii_strncasecmp (m_header->name, "subject", 7) !=0) + replace_template_variable (subject, m_header->name, m_header->value); + + m_header = m_header->next; + } + /* Now replace $ORIG[subject] variable, handling possible base64 encryption */ + replace_template_variable (subject, "subject", + camel_mime_message_get_subject (message)); + header->value = g_strdup (subject->str); + g_string_free (subject, TRUE); + } + + camel_medium_add_header (CAMEL_MEDIUM (new), + header->name, + header->value); } + header = header->next; } @@ -522,38 +805,55 @@ create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *mes /* Create the composer */ em_utils_edit_message (shell, folder, new); + g_object_unref (template); + g_object_unref (new_multipart); g_object_unref (new); } static void action_reply_with_template_cb (GtkAction *action, - const gchar *message_uid) + EShellView *shell_view) { - CamelFolder *folder; + CamelFolder *folder, *template_folder; + EShellContent *shell_content; + EMailReader *reader; + GPtrArray *uids; + const gchar *uid; + CamelMimeMessage *template; - g_return_if_fail (message_uid != NULL); + shell_content = e_shell_view_get_shell_content (shell_view); + reader = E_MAIL_READER (shell_content); + folder = e_mail_reader_get_folder (reader); + uids = e_mail_reader_get_selected_uids (reader); - folder = CAMEL_FOLDER (g_object_get_data (G_OBJECT (action), "message_folder")); - g_return_if_fail (folder != NULL); + if (!uids->len || !folder) + return; g_object_ref (G_OBJECT (action)); - mail_get_message (folder, message_uid, create_new_message, action, mail_msg_unordered_push); + template_folder = g_object_get_data (G_OBJECT (action), "template-folder"); + uid = g_object_get_data (G_OBJECT (action), "template-uid"); + template = camel_folder_get_message_sync (template_folder, uid, NULL, NULL); + + mail_get_message (folder, uids->pdata[0], create_new_message, + (gpointer)template, mail_msg_unordered_push); g_object_unref (G_OBJECT (action)); + + em_utils_uids_free (uids); } static void build_template_menus_recurse (GtkUIManager *ui_manager, - GtkActionGroup *action_group, + GtkActionGroup *action_group, const gchar *menu_path, guint *action_count, guint merge_id, CamelFolderInfo *folder_info, - CamelFolder *message_folder, - const gchar *message_uid) + EShellView *shell_view) { CamelStore *store; + EShellWindow *shell_window = e_shell_view_get_shell_window (shell_view); store = e_mail_local_get_store (); @@ -591,6 +891,12 @@ build_template_menus_recurse (GtkUIManager *ui_manager, ui_manager, merge_id, menu_path, action_name, action_name, GTK_UI_MANAGER_MENU, FALSE); + /* Disconnect previous connection to avoid possible multiple calls because + folder is a persistent structure */ + g_signal_handlers_disconnect_by_func (folder, G_CALLBACK (templates_folder_msg_changed_cb), shell_window); + g_signal_connect (folder, "changed", + G_CALLBACK (templates_folder_msg_changed_cb), shell_window); + path = g_strdup_printf ("%s/%s", menu_path, action_name); g_object_unref (action); @@ -601,7 +907,7 @@ build_template_menus_recurse (GtkUIManager *ui_manager, build_template_menus_recurse ( ui_manager, action_group, path, action_count, merge_id, - folder_info->child, message_folder, message_uid); + folder_info->child, shell_view); if (!folder) { g_free (path); @@ -613,7 +919,7 @@ build_template_menus_recurse (GtkUIManager *ui_manager, uids = camel_folder_get_uids (folder); for (ii = 0; uids && ii < uids->len; ii++) { CamelMimeMessage *template; - const gchar *uid = uids->pdata[ii], *muid; + const gchar *uid = uids->pdata[ii]; guint32 flags; /* If the UIDs is marked for deletion, skip it. */ @@ -641,25 +947,14 @@ build_template_menus_recurse (GtkUIManager *ui_manager, action = gtk_action_new ( action_name, action_label, NULL, NULL); - muid = camel_pstring_strdup (message_uid); - g_object_ref (message_folder); - - g_object_set_data_full ( - G_OBJECT (action), "message_uid", (gpointer) muid, - (GDestroyNotify) camel_pstring_free); - - g_object_set_data_full ( - G_OBJECT (action), "message_folder", message_folder, - (GDestroyNotify) g_object_unref); + g_object_set_data(G_OBJECT (action), "template-uid", (gpointer) uid); - g_object_set_data_full ( - G_OBJECT (action), "template", template, - (GDestroyNotify) g_object_unref); + g_object_set_data(G_OBJECT (action), "template-folder", folder); g_signal_connect ( action, "activate", G_CALLBACK (action_reply_with_template_cb), - (gpointer) muid); + shell_view); gtk_action_group_add_action (action_group, action); @@ -669,6 +964,7 @@ build_template_menus_recurse (GtkUIManager *ui_manager, g_object_unref (action); g_free (action_name); + g_object_unref (template); } camel_folder_free_uids (folder, uids); @@ -750,52 +1046,28 @@ static GtkActionEntry composer_entries[] = { }; static void -update_actions_cb (EShellView *shell_view) +build_menu (EShellWindow *shell_window, + GtkActionGroup *action_group) { - EShellContent *shell_content; - EShellWindow *shell_window; - GtkActionGroup *action_group; - GtkUIManager *ui_manager; - CamelFolderInfo *folder_info; - CamelFolder *templates_folder; + EShellView *shell_view; CamelFolder *folder; CamelStore *store; - EMailReader *reader; - GPtrArray *uids; - const gchar *full_name; - guint action_count = 0; + CamelFolderInfo *folder_info; + GtkUIManager *ui_manager; guint merge_id; - gpointer data; - - shell_content = e_shell_view_get_shell_content (shell_view); - shell_window = e_shell_view_get_shell_window (shell_view); + guint action_count = 0; + const gchar *full_name; ui_manager = e_shell_window_get_ui_manager (shell_window); - action_group = e_lookup_action_group (ui_manager, "templates"); - data = g_object_get_data (G_OBJECT (action_group), "merge-id"); - merge_id = GPOINTER_TO_UINT (data); - g_return_if_fail (merge_id > 0); + shell_view = e_shell_window_get_shell_view (shell_window, "mail"); - gtk_ui_manager_remove_ui (ui_manager, merge_id); - e_action_group_remove_all_actions (action_group); - gtk_ui_manager_ensure_update (ui_manager); - - if (!plugin_enabled) - return; - - reader = E_MAIL_READER (shell_content); - folder = e_mail_reader_get_folder (reader); - uids = e_mail_reader_get_selected_uids (reader); - - if (uids->len != 1) - goto exit; + merge_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (action_group), "merge-id")); /* Now recursively build template submenus in the pop-up menu. */ - store = e_mail_local_get_store (); - templates_folder = e_mail_local_get_folder ( + folder = e_mail_local_get_folder ( E_MAIL_LOCAL_FOLDER_TEMPLATES); - full_name = camel_folder_get_full_name (templates_folder); + full_name = camel_folder_get_full_name (folder); /* FIXME Not passing a GCancellable or GError here. */ folder_info = camel_store_get_folder_info_sync ( @@ -807,11 +1079,32 @@ update_actions_cb (EShellView *shell_view) ui_manager, action_group, "/mail-message-popup/mail-message-templates", &action_count, merge_id, folder_info, - folder, uids->pdata[0]); + shell_view); camel_store_free_folder_info (store, folder_info); -exit: - em_utils_uids_free (uids); +} + +static void +update_actions_cb (EShellView *shell_view, GtkActionGroup *action_group) +{ + GList *list; + gint length; + + if (!plugin_enabled) + return; + + list = gtk_action_group_list_actions (action_group); + length = g_list_length (list); + + if (!length) { + EShellWindow *shell_window = e_shell_view_get_shell_window (shell_view); + build_menu (shell_window, action_group); + } + + gtk_action_group_set_sensitive (action_group, TRUE); + gtk_action_group_set_visible (action_group, TRUE); + + g_list_free (list); } gboolean @@ -831,31 +1124,89 @@ init_composer_actions (GtkUIManager *ui_manager, } static void -mail_shell_view_created_cb (EShellWindow *shell_window, - EShellView *shell_view) +rebuild_template_menu (EShellWindow *shell_window) +{ + GtkUIManager *ui_manager; + GtkActionGroup *action_group; + guint merge_id; + + ui_manager = e_shell_window_get_ui_manager (shell_window); + + action_group = e_lookup_action_group (ui_manager, "templates"); + merge_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (action_group), "merge-id")); + + gtk_ui_manager_remove_ui (ui_manager, merge_id); + e_action_group_remove_all_actions (action_group); + gtk_ui_manager_ensure_update (ui_manager); + + build_menu (shell_window, action_group); +} + +static void +templates_folder_msg_changed_cb (CamelFolder *folder, + CamelFolderChangeInfo *change_info, + EShellWindow *shell_window) { - g_signal_connect ( - shell_view, "update-actions", - G_CALLBACK (update_actions_cb), NULL); + rebuild_template_menu (shell_window); } -gboolean -init_shell_actions (GtkUIManager *ui_manager, - EShellWindow *shell_window) +static void +templates_folder_changed_cb (CamelStore *store, + CamelFolderInfo *folder_info, + EShellWindow *shell_window) { - EShellView *shell_view; + if (folder_info->full_name && strstr (folder_info->full_name, _("Templates")) != NULL) + rebuild_template_menu (shell_window); +} + +static void +templates_folder_renamed_cb (CamelStore *store, + const gchar *old_name, + CamelFolderInfo *folder_info, + EShellWindow *shell_window) +{ + if (folder_info->full_name && strstr (folder_info->full_name, _("Templates")) != NULL) + rebuild_template_menu (shell_window); +} + +static void +mail_shell_view_created_cb (EShellWindow *shell_window, + EShellView *shell_view) +{ + GtkUIManager *ui_manager; GtkActionGroup *action_group; + CamelFolder *folder; + CamelStore *store; guint merge_id; - /* This is where we keep dynamically-built menu items. */ + ui_manager = e_shell_window_get_ui_manager (shell_window); e_shell_window_add_action_group (shell_window, "templates"); action_group = e_lookup_action_group (ui_manager, "templates"); - merge_id = gtk_ui_manager_new_merge_id (ui_manager); + g_object_set_data (G_OBJECT (action_group), "merge-id", + GUINT_TO_POINTER (merge_id)); - g_object_set_data ( - G_OBJECT (action_group), "merge-id", - GUINT_TO_POINTER (merge_id)); + folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_TEMPLATES); + store = e_mail_local_get_store (); + + g_signal_connect (folder, "changed", + G_CALLBACK (templates_folder_msg_changed_cb), shell_window); + g_signal_connect (store, "folder-created", + G_CALLBACK (templates_folder_changed_cb), shell_window); + g_signal_connect (store, "folder-deleted", + G_CALLBACK (templates_folder_changed_cb), shell_window); + g_signal_connect (store, "folder-renamed", + G_CALLBACK (templates_folder_renamed_cb), shell_window); + + g_signal_connect (shell_view, "update-actions", + G_CALLBACK (update_actions_cb), action_group); +} + +gboolean +init_shell_actions (GtkUIManager *ui_manager, + EShellWindow *shell_window) +{ + EShellView *shell_view; /* Be careful not to instantiate the mail view ourselves. */ shell_view = e_shell_window_peek_shell_view (shell_window, "mail"); -- cgit v1.2.3 From 708ce51377b358304b19efd271c6b5005fea1866 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 7 May 2011 10:29:37 -0400 Subject: Adapt to CamelFolderInfo.name -> display_name. --- plugins/templates/templates.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 9fded58413..aa43d4921b 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -862,12 +862,12 @@ build_template_menus_recurse (GtkUIManager *ui_manager, GPtrArray *uids; GtkAction *action; const gchar *action_label; - const gchar *folder_name; + const gchar *display_name; gchar *action_name; gchar *path; guint ii; - folder_name = folder_info->name; + display_name = folder_info->display_name; /* FIXME Not passing a GCancellable or GError here. */ folder = camel_store_get_folder_sync ( store, folder_info->full_name, 0, NULL, NULL); @@ -877,10 +877,10 @@ build_template_menus_recurse (GtkUIManager *ui_manager, *action_count = *action_count + 1; /* To avoid having a Templates dir, we ignore the top level */ - if (g_str_has_suffix (folder_name, "Templates")) + if (g_str_has_suffix (display_name, "Templates")) action_label = _("Templates"); else - action_label = folder_name; + action_label = display_name; action = gtk_action_new ( action_name, action_label, NULL, NULL); -- cgit v1.2.3 From 578214584caa7805edca09b27e2306dc31d80fb6 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 7 May 2011 12:22:36 -0400 Subject: Whitespace and coding style cleanups. --- plugins/templates/templates.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index aa43d4921b..b97926adfe 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -471,7 +471,7 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) /* Case insensitive version of strstr */ static gchar * -strstr_nocase (const gchar* haystack, const gchar *needle) +strstr_nocase (const gchar * haystack, const gchar *needle) { /* When _GNU_SOURCE is available, use the nonstandard extension of libc */ #ifdef _GNU_SOURCE @@ -606,7 +606,7 @@ fill_template (CamelMimeMessage *message, CamelMimePart *template) } } } else - message_part = CAMEL_MIME_PART (message); + message_part = CAMEL_MIME_PART (message); /* Get content of the template */ stream = camel_stream_mem_new (); @@ -655,7 +655,7 @@ fill_template (CamelMimeMessage *message, CamelMimePart *template) camel_data_wrapper_decode_to_stream_sync (camel_medium_get_content (CAMEL_MEDIUM (message_part)), stream, NULL, NULL); camel_stream_flush (stream, NULL, NULL); byte_array = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (stream)); - message_body = g_string_new_len ((gchar*)byte_array->data, byte_array->len); + message_body = g_string_new_len ((gchar *)byte_array->data, byte_array->len); g_object_unref (stream); if (template_html && !message_html) { @@ -742,7 +742,7 @@ create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *mes if (ct && (camel_content_type_is (ct, "text", "html") || camel_content_type_is (ct, "text", "plain"))) { - template_part = CAMEL_MIME_PART (template); + template_part = CAMEL_MIME_PART (template); new_content_type = ct; } } @@ -1144,8 +1144,8 @@ rebuild_template_menu (EShellWindow *shell_window) static void templates_folder_msg_changed_cb (CamelFolder *folder, - CamelFolderChangeInfo *change_info, - EShellWindow *shell_window) + CamelFolderChangeInfo *change_info, + EShellWindow *shell_window) { rebuild_template_menu (shell_window); } -- cgit v1.2.3 From 54da4fc09cf226fdb59b9f0c70555e2e57dc1f91 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sun, 8 May 2011 13:24:42 -0400 Subject: Coding style cleanups. --- plugins/templates/templates.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index b97926adfe..6f287c3168 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -655,7 +655,7 @@ fill_template (CamelMimeMessage *message, CamelMimePart *template) camel_data_wrapper_decode_to_stream_sync (camel_medium_get_content (CAMEL_MEDIUM (message_part)), stream, NULL, NULL); camel_stream_flush (stream, NULL, NULL); byte_array = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (stream)); - message_body = g_string_new_len ((gchar *)byte_array->data, byte_array->len); + message_body = g_string_new_len ((gchar *) byte_array->data, byte_array->len); g_object_unref (stream); if (template_html && !message_html) { @@ -836,7 +836,7 @@ action_reply_with_template_cb (GtkAction *action, template = camel_folder_get_message_sync (template_folder, uid, NULL, NULL); mail_get_message (folder, uids->pdata[0], create_new_message, - (gpointer)template, mail_msg_unordered_push); + (gpointer) template, mail_msg_unordered_push); g_object_unref (G_OBJECT (action)); -- cgit v1.2.3 From 6693730cc102ae3af1e4a641df2048fa8bf3d39b Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 11 May 2011 11:12:53 -0400 Subject: Add a 'message_uid' param to em_utils_edit_message(). So we can remove the internal edit_message() function and do the work directly in em_utils_edit_message(). --- plugins/templates/templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 6f287c3168..48a3b9e5a7 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -803,7 +803,7 @@ create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *mes camel_mime_message_get_recipients (template, CAMEL_RECIPIENT_TYPE_BCC)); /* Create the composer */ - em_utils_edit_message (shell, folder, new); + em_utils_edit_message (shell, folder, new, uid); g_object_unref (template); g_object_unref (new_multipart); -- cgit v1.2.3 From 1a75a7d808c45cbc2c3c4b0cc6b750ef4002ed8e Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 12 May 2011 19:00:09 -0400 Subject: Miscellaneous cleanups. --- plugins/templates/templates.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 48a3b9e5a7..5fa60175b9 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -812,45 +812,54 @@ create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *mes static void action_reply_with_template_cb (GtkAction *action, - EShellView *shell_view) + EShellView *shell_view) { CamelFolder *folder, *template_folder; EShellContent *shell_content; + CamelMimeMessage *template; EMailReader *reader; GPtrArray *uids; - const gchar *uid; - CamelMimeMessage *template; + const gchar *message_uid; + const gchar *template_uid; shell_content = e_shell_view_get_shell_content (shell_view); reader = E_MAIL_READER (shell_content); + folder = e_mail_reader_get_folder (reader); + g_return_if_fail (CAMEL_IS_FOLDER (folder)); + uids = e_mail_reader_get_selected_uids (reader); + g_return_if_fail (uids != NULL && uids->len == 1); + message_uid = g_ptr_array_index (uids, 0); - if (!uids->len || !folder) - return; + g_object_ref (action); - g_object_ref (G_OBJECT (action)); + template_folder = g_object_get_data ( + G_OBJECT (action), "template-folder"); + template_uid = g_object_get_data ( + G_OBJECT (action), "template-uid"); - template_folder = g_object_get_data (G_OBJECT (action), "template-folder"); - uid = g_object_get_data (G_OBJECT (action), "template-uid"); - template = camel_folder_get_message_sync (template_folder, uid, NULL, NULL); + /* FIXME This blocks. */ + template = camel_folder_get_message_sync ( + template_folder, template_uid, NULL, NULL); - mail_get_message (folder, uids->pdata[0], create_new_message, + mail_get_message ( + folder, message_uid, create_new_message, (gpointer) template, mail_msg_unordered_push); - g_object_unref (G_OBJECT (action)); + g_object_unref (action); em_utils_uids_free (uids); } static void build_template_menus_recurse (GtkUIManager *ui_manager, - GtkActionGroup *action_group, + GtkActionGroup *action_group, const gchar *menu_path, guint *action_count, guint merge_id, CamelFolderInfo *folder_info, - EShellView *shell_view) + EShellView *shell_view) { CamelStore *store; EShellWindow *shell_window = e_shell_view_get_shell_window (shell_view); -- cgit v1.2.3 From 696ccbe4f83654bd41dc60ca821da36e5dbe2c52 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 12 May 2011 22:41:49 -0400 Subject: Reimplement part of the "templates" plugin. Now uses camel_folder_get_message(). --- plugins/templates/templates.c | 151 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 132 insertions(+), 19 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 5fa60175b9..052ca898c5 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -48,6 +48,17 @@ #define GCONF_KEY_TEMPLATE_PLACEHOLDERS "/apps/evolution/mail/template_placeholders" +typedef struct _AsyncContext AsyncContext; + +struct _AsyncContext { + EActivity *activity; + EMailReader *reader; + CamelMimeMessage *message; + CamelFolder *template_folder; + gchar *message_uid; + gchar *template_message_uid; +}; + typedef struct { GConfClient *gconf; GtkWidget *treeview; @@ -90,6 +101,27 @@ static void templates_folder_msg_changed_cb (CamelFolder *folder, static gboolean plugin_enabled; +static void +async_context_free (AsyncContext *context) +{ + if (context->activity != NULL) + g_object_unref (context->activity); + + if (context->reader != NULL) + g_object_unref (context->reader); + + if (context->message != NULL) + g_object_unref (context->message); + + if (context->template_folder != NULL) + g_object_unref (context->template_folder); + + g_free (context->message_uid); + g_free (context->template_message_uid); + + g_slice_free (AsyncContext, context); +} + static void selection_changed (GtkTreeSelection *selection, UIData *ui) { @@ -690,25 +722,54 @@ fill_template (CamelMimeMessage *message, CamelMimePart *template) } static void -create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *message, gpointer data) +create_new_message (CamelFolder *folder, + GAsyncResult *result, + AsyncContext *context) { + EAlertSink *alert_sink; CamelMimeMessage *new; - CamelMimeMessage *template = CAMEL_MIME_MESSAGE (data); + CamelMimeMessage *message; + CamelMimeMessage *template; CamelMultipart *new_multipart; CamelContentType *new_content_type = NULL; CamelDataWrapper *dw; struct _camel_header_raw *header; + EMailBackend *backend; EShell *shell; + const gchar *message_uid; gint i; + GError *error = NULL; CamelMimePart *template_part = NULL; CamelMimePart *out_part = NULL; - g_return_if_fail (template != NULL); - g_return_if_fail (message != NULL); + alert_sink = e_activity_get_alert_sink (context->activity); + + template = camel_folder_get_message_finish (folder, result, &error); + + if (e_activity_handle_cancellation (context->activity, error)) { + g_warn_if_fail (template == NULL); + async_context_free (context); + g_error_free (error); + return; + + } else if (error != NULL) { + g_warn_if_fail (template == NULL); + e_alert_submit ( + alert_sink, "mail:no-retrieve-message", + error->message, NULL); + async_context_free (context); + g_error_free (error); + return; + } + + g_return_if_fail (CAMEL_IS_MIME_MESSAGE (template)); - /* FIXME Pass this in somehow. */ - shell = e_shell_get_default (); + message = context->message; + message_uid = context->message_uid; + + backend = e_mail_reader_get_backend (context->reader); + shell = e_shell_backend_get_shell (E_SHELL_BACKEND (backend)); folder = e_mail_local_get_folder (E_MAIL_LOCAL_FOLDER_TEMPLATES); @@ -803,24 +864,73 @@ create_new_message (CamelFolder *folder, const gchar *uid, CamelMimeMessage *mes camel_mime_message_get_recipients (template, CAMEL_RECIPIENT_TYPE_BCC)); /* Create the composer */ - em_utils_edit_message (shell, folder, new, uid); + em_utils_edit_message (shell, folder, new, message_uid); g_object_unref (template); g_object_unref (new_multipart); g_object_unref (new); + + async_context_free (context); +} + +static void +template_got_source_message (CamelFolder *folder, + GAsyncResult *result, + AsyncContext *context) +{ + EAlertSink *alert_sink; + GCancellable *cancellable; + CamelMimeMessage *message; + GError *error = NULL; + + alert_sink = e_activity_get_alert_sink (context->activity); + cancellable = e_activity_get_cancellable (context->activity); + + message = camel_folder_get_message_finish (folder, result, &error); + + if (e_activity_handle_cancellation (context->activity, error)) { + g_warn_if_fail (message == NULL); + async_context_free (context); + g_error_free (error); + return; + + } else if (error != NULL) { + g_warn_if_fail (message == NULL); + e_alert_submit ( + alert_sink, "mail:no-retrieve-message", + error->message, NULL); + async_context_free (context); + g_error_free (error); + return; + } + + g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); + + context->message = message; + + /* Now fetch the template message. */ + + camel_folder_get_message ( + context->template_folder, + context->template_message_uid, + G_PRIORITY_DEFAULT, cancellable, + (GAsyncReadyCallback) create_new_message, + context); } static void action_reply_with_template_cb (GtkAction *action, EShellView *shell_view) { + EActivity *activity; + AsyncContext *context; + GCancellable *cancellable; CamelFolder *folder, *template_folder; EShellContent *shell_content; - CamelMimeMessage *template; EMailReader *reader; GPtrArray *uids; const gchar *message_uid; - const gchar *template_uid; + const gchar *template_message_uid; shell_content = e_shell_view_get_shell_content (shell_view); reader = E_MAIL_READER (shell_content); @@ -832,22 +942,25 @@ action_reply_with_template_cb (GtkAction *action, g_return_if_fail (uids != NULL && uids->len == 1); message_uid = g_ptr_array_index (uids, 0); - g_object_ref (action); - template_folder = g_object_get_data ( G_OBJECT (action), "template-folder"); - template_uid = g_object_get_data ( + template_message_uid = g_object_get_data ( G_OBJECT (action), "template-uid"); - /* FIXME This blocks. */ - template = camel_folder_get_message_sync ( - template_folder, template_uid, NULL, NULL); + activity = e_mail_reader_new_activity (reader); + cancellable = e_activity_get_cancellable (activity); - mail_get_message ( - folder, message_uid, create_new_message, - (gpointer) template, mail_msg_unordered_push); + context = g_slice_new0 (AsyncContext); + context->activity = activity; + context->reader = g_object_ref (reader); + context->template_folder = g_object_ref (template_folder); + context->message_uid = g_strdup (message_uid); + context->template_message_uid = g_strdup (template_message_uid); - g_object_unref (action); + camel_folder_get_message ( + folder, message_uid, G_PRIORITY_DEFAULT, + cancellable, (GAsyncReadyCallback) + template_got_source_message, context); em_utils_uids_free (uids); } -- cgit v1.2.3 From c24038c4f62f37b89d1bda9542ca5ccc843d4ea0 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 27 May 2011 15:23:07 +0200 Subject: Bug #646109 - Fix use of include to make sure translations work --- plugins/templates/templates.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 052ca898c5..57efaba1c5 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -22,6 +22,10 @@ * */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include -- cgit v1.2.3 From 7132d0f0c2b8494b3962792cd77ce3fcb5313687 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 28 May 2011 10:18:56 -0400 Subject: Including directly is rarely needed. --- plugins/templates/templates.c | 1 - 1 file changed, 1 deletion(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 57efaba1c5..71343e8536 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -27,7 +27,6 @@ #endif #include -#include #include #include -- cgit v1.2.3 From 777c1cbd40eb63365f2c28e38f6a93beb2d1c9d1 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 16 Aug 2011 11:25:56 -0400 Subject: Coding style and whitespace cleanup. --- plugins/templates/templates.c | 115 ++++++++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 43 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 71343e8536..f68cfc1b26 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -126,7 +126,8 @@ async_context_free (AsyncContext *context) } static void -selection_changed (GtkTreeSelection *selection, UIData *ui) +selection_changed (GtkTreeSelection *selection, + UIData *ui) { GtkTreeModel *model; GtkTreeIter iter; @@ -186,7 +187,10 @@ commit_changes (UIData *ui) } static void -clue_check_isempty (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, UIData *ui) +clue_check_isempty (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + UIData *ui) { GtkTreeSelection *selection; gchar *keyword = NULL; @@ -216,7 +220,10 @@ clue_check_isempty (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, U } static gboolean -clue_foreach_check_isempty (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, UIData *ui) +clue_foreach_check_isempty (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + UIData *ui) { gboolean valid; @@ -238,9 +245,9 @@ clue_foreach_check_isempty (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter static void key_cell_edited_callback (GtkCellRendererText *cell, - gchar *path_string, - gchar *new_text, - UIData *ui) + gchar *path_string, + gchar *new_text, + UIData *ui) { GtkTreeModel *model; GtkTreeIter iter; @@ -259,9 +266,9 @@ key_cell_edited_callback (GtkCellRendererText *cell, static void value_cell_edited_callback (GtkCellRendererText *cell, - gchar *path_string, - gchar *new_text, - UIData *ui) + gchar *path_string, + gchar *new_text, + UIData *ui) { GtkTreeModel *model; GtkTreeIter iter; @@ -280,7 +287,8 @@ value_cell_edited_callback (GtkCellRendererText *cell, } static void -clue_add_clicked (GtkButton *button, UIData *ui) +clue_add_clicked (GtkButton *button, + UIData *ui) { GtkTreeModel *model; GtkTreeIter iter; @@ -310,11 +318,14 @@ clue_add_clicked (GtkButton *button, UIData *ui) } /* We have done our job, connect back to the signal */ - g_signal_connect(G_OBJECT(model), "row-changed", G_CALLBACK(clue_check_isempty), ui); + g_signal_connect ( + model, "row-changed", + G_CALLBACK (clue_check_isempty), ui); } static void -clue_remove_clicked (GtkButton *button, UIData *ui) +clue_remove_clicked (GtkButton *button, + UIData *ui) { GtkTreeSelection *selection; GtkTreeModel *model; @@ -357,7 +368,8 @@ clue_remove_clicked (GtkButton *button, UIData *ui) } static void -clue_edit_clicked (GtkButton *button, UIData *ui) +clue_edit_clicked (GtkButton *button, + UIData *ui) { GtkTreeSelection *selection; GtkTreeModel *model; @@ -449,33 +461,43 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) renderer_key = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (ui->treeview), -1, _("Keywords"), renderer_key, "text", CLUE_KEYWORD_COLUMN, NULL); - g_object_set (G_OBJECT (renderer_key), "editable", TRUE, NULL); - g_signal_connect(renderer_key, "edited", (GCallback) key_cell_edited_callback, ui); + g_object_set (renderer_key, "editable", TRUE, NULL); + g_signal_connect (renderer_key, "edited", (GCallback) key_cell_edited_callback, ui); renderer_value = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (ui->treeview), -1, _("Values"), renderer_value, "text", CLUE_VALUE_COLUMN, NULL); - g_object_set (G_OBJECT (renderer_value), "editable", TRUE, NULL); - g_signal_connect(renderer_value, "edited", (GCallback) value_cell_edited_callback, ui); + g_object_set (renderer_value, "editable", TRUE, NULL); + g_signal_connect (renderer_value, "edited", (GCallback) value_cell_edited_callback, ui); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (ui->treeview)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); - g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (selection_changed), ui); + g_signal_connect ( + selection, "changed", + G_CALLBACK (selection_changed), ui); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (ui->treeview), TRUE); ui->clue_add = clue_add; - g_signal_connect (G_OBJECT (ui->clue_add), "clicked", G_CALLBACK (clue_add_clicked), ui); + g_signal_connect ( + ui->clue_add, "clicked", + G_CALLBACK (clue_add_clicked), ui); ui->clue_remove = clue_remove; - g_signal_connect (G_OBJECT (ui->clue_remove), "clicked", G_CALLBACK (clue_remove_clicked), ui); + g_signal_connect ( + ui->clue_remove, "clicked", + G_CALLBACK (clue_remove_clicked), ui); gtk_widget_set_sensitive (ui->clue_remove, FALSE); ui->clue_edit = clue_edit; - g_signal_connect (G_OBJECT (ui->clue_edit), "clicked", G_CALLBACK (clue_edit_clicked), ui); + g_signal_connect ( + ui->clue_edit, "clicked", + G_CALLBACK (clue_edit_clicked), ui); gtk_widget_set_sensitive (ui->clue_edit, FALSE); model = gtk_tree_view_get_model (GTK_TREE_VIEW (ui->treeview)); - g_signal_connect(G_OBJECT(model), "row-changed", G_CALLBACK(clue_check_isempty), ui); + g_signal_connect ( + model, "row-changed", + G_CALLBACK (clue_check_isempty), ui); /* Populate tree view with values from gconf */ clue_list = gconf_client_get_list ( gconf, GCONF_KEY_TEMPLATE_PLACEHOLDERS, GCONF_VALUE_STRING, NULL ); @@ -506,7 +528,8 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) /* Case insensitive version of strstr */ static gchar * -strstr_nocase (const gchar * haystack, const gchar *needle) +strstr_nocase (const gchar *haystack, + const gchar *needle) { /* When _GNU_SOURCE is available, use the nonstandard extension of libc */ #ifdef _GNU_SOURCE @@ -528,7 +551,7 @@ strstr_nocase (const gchar * haystack, const gchar *needle) pos = strstr (l_haystack, l_needle); /* Get actual position of the needle in the haystack instead of l_haystack or - leave it NULL */ + * leave it NULL */ if (pos) pos = (gchar *)(haystack + (pos - l_haystack)); @@ -541,7 +564,9 @@ strstr_nocase (const gchar * haystack, const gchar *needle) /* Replaces $ORIG[variable] in given template by given replacement from the original message */ static void -replace_template_variable (GString *text, const gchar *variable, const gchar *replacement) +replace_template_variable (GString *text, + const gchar *variable, + const gchar *replacement) { const gchar *p, *next; GString *str; @@ -573,7 +598,9 @@ replace_template_variable (GString *text, const gchar *variable, const gchar *re } static void -replace_email_addresses (GString *template, CamelInternetAddress *internet_address, const gchar *variable) +replace_email_addresses (GString *template, + CamelInternetAddress *internet_address, + const gchar *variable) { gint address_index = 0; GString *emails = g_string_new (""); @@ -598,8 +625,9 @@ replace_email_addresses (GString *template, CamelInternetAddress *internet_addre g_string_free (emails, TRUE); } -static CamelMimePart* -fill_template (CamelMimeMessage *message, CamelMimePart *template) +static CamelMimePart * +fill_template (CamelMimeMessage *message, + CamelMimePart *template) { struct _camel_header_raw *header; CamelContentType *ct; @@ -666,7 +694,7 @@ fill_template (CamelMimeMessage *message, CamelMimePart *template) } /* Now manually replace the *subject* header. The header->value for subject header could be - base64 encoded, so let camel_mime_message to decode it for us if needed */ + * base64 encoded, so let camel_mime_message to decode it for us if needed */ replace_template_variable (template_body, "subject", camel_mime_message_get_subject (message)); /* Replace TO and FROM modifiers. */ @@ -783,7 +811,7 @@ create_new_message (CamelFolder *folder, dw = camel_medium_get_content (CAMEL_MEDIUM (template)); /* If template is a multipart, then try to use HTML. When no HTML part is available, use plaintext. Every other - add as an attachment */ + * add as an attachment */ if (CAMEL_IS_MULTIPART (dw)) { for (i = 0; i < camel_multipart_get_number (CAMEL_MULTIPART (dw)); i++) { CamelMimePart *part = camel_multipart_get_part (CAMEL_MULTIPART (dw), i); @@ -815,14 +843,14 @@ create_new_message (CamelFolder *folder, out_part = fill_template (message, template_part); /* Assigning part directly to mime_message causes problem with "Content-type" header displaying - in the HTML message (camel parsing bug?) */ + * in the HTML message (camel parsing bug?) */ camel_multipart_add_part (new_multipart, out_part); g_object_unref (out_part); camel_medium_set_content (CAMEL_MEDIUM (new), CAMEL_DATA_WRAPPER (new_multipart)); /* Add the headers from the message we are replying to, so CC and that - stuff is preserved. Also replace any $ORIG[header-name] modifiers ignoring - 'content-*' headers */ + * stuff is preserved. Also replace any $ORIG[header-name] modifiers ignoring + * 'content-*' headers */ header = CAMEL_MIME_PART (message)->headers; while (header) { if (g_ascii_strncasecmp (header->name, "content-", 8) != 0) { @@ -1017,7 +1045,7 @@ build_template_menus_recurse (GtkUIManager *ui_manager, action_name, GTK_UI_MANAGER_MENU, FALSE); /* Disconnect previous connection to avoid possible multiple calls because - folder is a persistent structure */ + * folder is a persistent structure */ g_signal_handlers_disconnect_by_func (folder, G_CALLBACK (templates_folder_msg_changed_cb), shell_window); g_signal_connect (folder, "changed", G_CALLBACK (templates_folder_msg_changed_cb), shell_window); @@ -1172,7 +1200,7 @@ static GtkActionEntry composer_entries[] = { static void build_menu (EShellWindow *shell_window, - GtkActionGroup *action_group) + GtkActionGroup *action_group) { EShellView *shell_view; CamelFolder *folder; @@ -1210,7 +1238,8 @@ build_menu (EShellWindow *shell_window, } static void -update_actions_cb (EShellView *shell_view, GtkActionGroup *action_group) +update_actions_cb (EShellView *shell_view, + GtkActionGroup *action_group) { GList *list; gint length; @@ -1269,16 +1298,16 @@ rebuild_template_menu (EShellWindow *shell_window) static void templates_folder_msg_changed_cb (CamelFolder *folder, - CamelFolderChangeInfo *change_info, - EShellWindow *shell_window) + CamelFolderChangeInfo *change_info, + EShellWindow *shell_window) { rebuild_template_menu (shell_window); } static void templates_folder_changed_cb (CamelStore *store, - CamelFolderInfo *folder_info, - EShellWindow *shell_window) + CamelFolderInfo *folder_info, + EShellWindow *shell_window) { if (folder_info->full_name && strstr (folder_info->full_name, _("Templates")) != NULL) rebuild_template_menu (shell_window); @@ -1286,9 +1315,9 @@ templates_folder_changed_cb (CamelStore *store, static void templates_folder_renamed_cb (CamelStore *store, - const gchar *old_name, - CamelFolderInfo *folder_info, - EShellWindow *shell_window) + const gchar *old_name, + CamelFolderInfo *folder_info, + EShellWindow *shell_window) { if (folder_info->full_name && strstr (folder_info->full_name, _("Templates")) != NULL) rebuild_template_menu (shell_window); -- cgit v1.2.3 From 202cf6bfef9e43abf58f803eb66dce226d508d01 Mon Sep 17 00:00:00 2001 From: Rodrigo Moya Date: Wed, 2 Nov 2011 17:29:14 +0100 Subject: Migrate template plugin to GSettings --- plugins/templates/templates.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index f68cfc1b26..b3e112edb5 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -30,8 +30,6 @@ #include #include -#include - #include #include @@ -49,7 +47,7 @@ #include -#define GCONF_KEY_TEMPLATE_PLACEHOLDERS "/apps/evolution/mail/template_placeholders" +#define KEY_TEMPLATE_PLACEHOLDERS "template-placeholders" typedef struct _AsyncContext AsyncContext; @@ -63,7 +61,7 @@ struct _AsyncContext { }; typedef struct { - GConfClient *gconf; + GSettings *settings; GtkWidget *treeview; GtkWidget *clue_add; GtkWidget *clue_edit; @@ -149,7 +147,7 @@ destroy_ui_data (gpointer data) if (!ui) return; - g_object_unref (ui->gconf); + g_object_unref (ui->settings); g_free (ui); } @@ -157,13 +155,15 @@ static void commit_changes (UIData *ui) { GtkTreeModel *model = NULL; - GSList *clue_list = NULL; + GVariantBuilder b; GtkTreeIter iter; gboolean valid; + GVariant *v; model = gtk_tree_view_get_model (GTK_TREE_VIEW (ui->treeview)); valid = gtk_tree_model_get_iter_first (model, &iter); + g_variant_builder_init (&b, G_VARIANT_TYPE ("as")); while (valid) { gchar *keyword, *value; gchar *key; @@ -175,15 +175,14 @@ commit_changes (UIData *ui) if ((keyword) && (value) && (g_utf8_strlen (g_strstrip (keyword), -1) > 0) && (g_utf8_strlen (g_strstrip (value), -1) > 0)) { key = g_strdup_printf("%s=%s", keyword, value); - clue_list = g_slist_append (clue_list, key); + g_variant_builder_add (&b, "s", key); } valid = gtk_tree_model_iter_next (model, &iter); } - gconf_client_set_list (ui->gconf, GCONF_KEY_TEMPLATE_PLACEHOLDERS, GCONF_VALUE_STRING, clue_list, NULL); - - g_slist_foreach (clue_list, (GFunc) g_free, NULL); - g_slist_free (clue_list); + v = g_variant_builder_end (&b); + g_settings_set_value (ui->settings, CONF_KEY_TEMPLATE_PLACEHOLDERS, v); + g_variant_unref (v); } static void @@ -396,9 +395,9 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) GtkCellRenderer *renderer_key, *renderer_value; GtkTreeSelection *selection; GtkTreeIter iter; - GConfClient *gconf = gconf_client_get_default (); GtkWidget *hbox; - GSList *clue_list = NULL, *list; + gchar **clue_list; + gint i; GtkTreeModel *model; GtkWidget *templates_configuration_box; GtkWidget *clue_container; @@ -450,7 +449,7 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) gtk_container_add (GTK_CONTAINER (vbuttonbox2), clue_remove); gtk_widget_set_can_default (clue_remove, TRUE); - ui->gconf = gconf_client_get_default (); + ui->settings = g_settings_new ("org.gnome.evolution.eplugin.templates"); ui->treeview = clue_treeview; @@ -499,19 +498,18 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) model, "row-changed", G_CALLBACK (clue_check_isempty), ui); - /* Populate tree view with values from gconf */ - clue_list = gconf_client_get_list ( gconf, GCONF_KEY_TEMPLATE_PLACEHOLDERS, GCONF_VALUE_STRING, NULL ); + /* Populate tree view with values from GSettings */ + clue_list = g_settings_get_strv (ui->settings, CONF_KEY_TEMPLATE_PLACEHOLDERS); - for (list = clue_list; list; list = g_slist_next (list)) { - gchar **temp = g_strsplit (list->data, "=", 2); + for (i = 0; clue_list[i] != NULL; i++) { + gchar **temp = g_strsplit (clue_list[i], "=", 2); gtk_list_store_append (ui->store, &iter); gtk_list_store_set (ui->store, &iter, CLUE_KEYWORD_COLUMN, temp[0], CLUE_VALUE_COLUMN, temp[1], -1); g_strfreev (temp); } if (clue_list) { - g_slist_foreach (clue_list, (GFunc) g_free, NULL); - g_slist_free (clue_list); + g_strfreev (clue_list); } /* Add the list here */ -- cgit v1.2.3 From 925b03c373fc79ccd56ab718a0ab97ab92c06115 Mon Sep 17 00:00:00 2001 From: Rodrigo Moya Date: Wed, 9 Nov 2011 12:35:00 +0100 Subject: Make it fully build --- plugins/templates/templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index b3e112edb5..4010eb7d5a 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -47,7 +47,7 @@ #include -#define KEY_TEMPLATE_PLACEHOLDERS "template-placeholders" +#define CONF_KEY_TEMPLATE_PLACEHOLDERS "template-placeholders" typedef struct _AsyncContext AsyncContext; -- cgit v1.2.3 From 2e60b6a4a21105bb4a1e2badd1be51b3e684d165 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 22 Nov 2011 17:53:07 -0500 Subject: Tweak GSettings schemas. - Don't use the term "eplugin" for modules. - Use the term "plugin" instead of "eplugin" for plugins. - Split SpamAssassin settings into a separate schema. --- plugins/templates/templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 4010eb7d5a..593e5ec73d 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -449,7 +449,7 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) gtk_container_add (GTK_CONTAINER (vbuttonbox2), clue_remove); gtk_widget_set_can_default (clue_remove, TRUE); - ui->settings = g_settings_new ("org.gnome.evolution.eplugin.templates"); + ui->settings = g_settings_new ("org.gnome.evolution.plugin.templates"); ui->treeview = clue_treeview; -- cgit v1.2.3 From e64d6fe05c30c2cc1d7625a202afba3ba2da07cd Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 22 Nov 2011 18:22:14 -0500 Subject: Miscellaneous cleanups. --- plugins/templates/templates.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/templates/templates.c') diff --git a/plugins/templates/templates.c b/plugins/templates/templates.c index 593e5ec73d..d8921bcb11 100644 --- a/plugins/templates/templates.c +++ b/plugins/templates/templates.c @@ -396,7 +396,7 @@ e_plugin_lib_get_configure_widget (EPlugin *epl) GtkTreeSelection *selection; GtkTreeIter iter; GtkWidget *hbox; - gchar **clue_list; + gchar **clue_list; gint i; GtkTreeModel *model; GtkWidget *templates_configuration_box; -- cgit v1.2.3