1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-address-book.h"
59 #include "modest-text-utils.h"
60 #include <tny-simple-list.h>
61 #include <wptextview.h>
62 #include <wptextbuffer.h>
63 #include "modest-scroll-area.h"
65 #include "modest-hildon-includes.h"
66 #include "widgets/modest-msg-edit-window-ui.h"
67 #include <libgnomevfs/gnome-vfs-mime.h>
70 #define DEFAULT_FONT_SIZE 3
71 #define DEFAULT_FONT 2
72 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
73 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
74 #define DEFAULT_MAIN_VBOX_SPACING 6
75 #define SUBJECT_MAX_LENGTH 1000
77 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
78 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
79 static void modest_msg_edit_window_finalize (GObject *obj);
81 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
82 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
83 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
84 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
85 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
86 static void reset_modified (ModestMsgEditWindow *editor);
87 static gboolean is_modified (ModestMsgEditWindow *editor);
89 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
90 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
91 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
92 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
93 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
94 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
96 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
98 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
100 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
101 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
102 GdkEventWindowState *event,
104 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
105 ModestRecptEditor *editor);
106 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
107 ModestMsgEditWindow *window);
109 /* ModestWindow methods implementation */
110 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
111 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
112 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
113 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
114 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
115 gboolean show_toolbar);
116 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
118 ModestMsgEditWindow *window);
119 static void update_window_title (ModestMsgEditWindow *window);
120 static void update_dimmed (ModestMsgEditWindow *window);
123 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
124 ModestMsgEditWindow *window);
125 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
126 ModestMsgEditWindow *window);
129 /* list my signals */
136 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
137 struct _ModestMsgEditWindowPrivate {
139 GtkWidget *header_box;
141 ModestPairList *from_field_protos;
142 GtkWidget *from_field;
146 GtkWidget *bcc_field;
147 GtkWidget *subject_field;
148 GtkWidget *attachments_view;
149 GtkWidget *priority_icon;
150 GtkWidget *add_attachment_button;
152 GtkWidget *cc_caption;
153 GtkWidget *bcc_caption;
154 GtkWidget *attachments_caption;
156 GtkTextBuffer *text_buffer;
158 GtkWidget *font_size_toolitem;
159 GtkWidget *font_face_toolitem;
160 GtkWidget *font_color_button;
161 GSList *font_items_group;
162 GtkWidget *font_tool_button_label;
163 GSList *size_items_group;
164 GtkWidget *size_tool_button_label;
166 GtkWidget *find_toolbar;
173 TnyHeaderFlags priority_flags;
177 gulong clipboard_change_handler_id;
182 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
183 MODEST_TYPE_MSG_EDIT_WINDOW, \
184 ModestMsgEditWindowPrivate))
186 static GtkWindowClass *parent_class = NULL;
188 /* uncomment the following if you have defined any signals */
189 /* static guint signals[LAST_SIGNAL] = {0}; */
192 modest_msg_edit_window_get_type (void)
194 static GType my_type = 0;
196 static const GTypeInfo my_info = {
197 sizeof(ModestMsgEditWindowClass),
198 NULL, /* base init */
199 NULL, /* base finalize */
200 (GClassInitFunc) modest_msg_edit_window_class_init,
201 NULL, /* class finalize */
202 NULL, /* class data */
203 sizeof(ModestMsgEditWindow),
205 (GInstanceInitFunc) modest_msg_edit_window_init,
208 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
209 "ModestMsgEditWindow",
212 wp_text_buffer_library_init ();
218 save_state (ModestWindow *self)
220 modest_widget_memory_save (modest_runtime_get_conf(),
221 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
226 restore_settings (ModestMsgEditWindow *self)
228 modest_widget_memory_restore (modest_runtime_get_conf(),
229 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
234 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
236 GObjectClass *gobject_class;
237 ModestWindowClass *modest_window_class;
238 gobject_class = (GObjectClass*) klass;
239 modest_window_class = (ModestWindowClass*) klass;
241 parent_class = g_type_class_peek_parent (klass);
242 gobject_class->finalize = modest_msg_edit_window_finalize;
244 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
245 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
246 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
247 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
248 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
250 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
252 modest_window_class->save_state_func = save_state;
256 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
258 ModestMsgEditWindowPrivate *priv;
259 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
261 priv->msg_body = NULL;
262 priv->from_field = NULL;
263 priv->to_field = NULL;
264 priv->cc_field = NULL;
265 priv->bcc_field = NULL;
266 priv->subject_field = NULL;
267 priv->attachments = NULL;
269 priv->zoom_level = 1.0;
271 priv->cc_caption = NULL;
272 priv->bcc_caption = NULL;
274 priv->priority_flags = 0;
276 priv->find_toolbar = NULL;
278 priv->draft_msg = NULL;
279 priv->clipboard_change_handler_id = 0;
283 /* FIXME: this is a dup from the one in gtk/ */
286 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
288 static ModestPairList*
289 get_transports (void)
291 GSList *transports = NULL;
293 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
294 GSList *accounts = modest_account_mgr_account_names (account_mgr,
295 TRUE /* only enabled accounts. */);
297 GSList *cursor = accounts;
299 gchar *account_name = cursor->data;
300 gchar *from_string = NULL;
302 from_string = modest_account_mgr_get_from_string (account_mgr,
306 if (from_string && account_name) {
307 gchar *name = account_name;
308 ModestPair *pair = modest_pair_new ((gpointer) name,
309 (gpointer) from_string , TRUE);
310 transports = g_slist_prepend (transports, pair);
313 cursor = cursor->next;
315 g_slist_free (accounts); /* only free the accounts, not the elements,
316 * because they are used in the pairlist */
322 init_window (ModestMsgEditWindow *obj)
324 GtkWidget *from_caption, *to_caption, *subject_caption;
325 GtkWidget *main_vbox;
326 ModestMsgEditWindowPrivate *priv;
328 GtkSizeGroup *size_group;
330 GtkWidget *scroll_area;
331 GtkWidget *subject_box;
332 GtkWidget *attachment_icon;
333 GtkWidget *window_box;
335 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
337 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
339 /* Note: This ModestPairList* must exist for as long as the combo
340 * that uses it, because the ModestComboBox uses the ID opaquely,
341 * so it can't know how to manage its memory. */
342 priv->from_field_protos = get_transports ();
344 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
346 priv->to_field = modest_recpt_editor_new ();
347 priv->cc_field = modest_recpt_editor_new ();
348 priv->bcc_field = modest_recpt_editor_new ();
349 subject_box = gtk_hbox_new (FALSE, 0);
350 priv->priority_icon = gtk_image_new ();
351 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
352 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
353 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
354 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
355 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
356 priv->add_attachment_button = gtk_button_new ();
357 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
358 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
359 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
360 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
361 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
362 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
363 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
364 priv->attachments_view = modest_attachments_view_new (NULL);
366 priv->header_box = gtk_vbox_new (FALSE, 0);
368 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
369 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
370 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
371 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
372 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
373 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
374 g_object_unref (size_group);
376 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
377 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
378 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
379 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
380 gtk_size_group_add_widget (size_group, priv->subject_field);
381 gtk_size_group_add_widget (size_group, priv->attachments_view);
382 g_object_unref (size_group);
384 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
385 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
386 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
387 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
388 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
389 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
390 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
393 priv->msg_body = wp_text_view_new ();
394 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
395 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
396 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
397 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
398 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
399 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
401 priv->find_toolbar = hildon_find_toolbar_new (NULL);
402 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
404 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
405 G_CALLBACK (text_buffer_refresh_attributes), obj);
406 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
407 G_CALLBACK (text_buffer_delete_range), obj);
408 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
409 G_CALLBACK (text_buffer_can_undo), obj);
410 g_signal_connect (G_OBJECT (obj), "window-state-event",
411 G_CALLBACK (modest_msg_edit_window_window_state_event),
413 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
414 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
415 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
416 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
417 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
418 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
420 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
421 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
423 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
424 G_CALLBACK (msg_body_focus), obj);
425 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
426 G_CALLBACK (msg_body_focus), obj);
427 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
428 "changed", G_CALLBACK (recpt_field_changed), obj);
429 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
430 "changed", G_CALLBACK (recpt_field_changed), obj);
431 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
432 "changed", G_CALLBACK (recpt_field_changed), obj);
433 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
434 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
436 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
437 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
439 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
440 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
441 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
443 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
445 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
446 frame = gtk_frame_new (NULL);
447 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
449 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
450 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
451 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
453 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
454 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
455 gtk_widget_hide (priv->cc_caption);
457 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
458 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
459 gtk_widget_hide (priv->bcc_caption);
462 window_box = gtk_vbox_new (FALSE, 0);
463 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
464 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
465 gtk_container_add (GTK_CONTAINER(obj), window_box);
466 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
467 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
468 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
469 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
471 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
472 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
478 modest_msg_edit_window_finalize (GObject *obj)
480 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
482 if (priv->clipboard_change_handler_id > 0) {
483 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
484 priv->clipboard_change_handler_id = 0;
487 /* This had to stay alive for as long as the combobox that used it: */
488 modest_pair_list_free (priv->from_field_protos);
490 G_OBJECT_CLASS(parent_class)->finalize (obj);
494 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
496 GtkWidget *close_dialog;
497 ModestMsgEditWindowPrivate *priv;
500 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
501 modest_window_save_state (MODEST_WINDOW (self));
502 if (is_modified (self)) {
503 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
504 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
505 gtk_widget_destroy (close_dialog);
507 if (response != GTK_RESPONSE_CANCEL) {
508 modest_ui_actions_on_save_to_drafts (NULL, self);
511 /* /\* remove old message from drafts *\/ */
512 /* if (priv->draft_msg) { */
513 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
514 /* TnyAccount *account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(), */
516 /* TNY_ACCOUNT_TYPE_STORE); */
517 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
518 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
519 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
520 /* tny_folder_remove_msg (folder, header, NULL); */
521 /* g_object_unref (folder); */
522 /* g_object_unref (header); */
523 /* g_object_unref (priv->draft_msg); */
524 /* priv->draft_msg = NULL; */
526 gtk_widget_destroy (GTK_WIDGET (self));
532 menubar_to_menu (GtkUIManager *ui_manager)
534 GtkWidget *main_menu;
538 /* Create new main menu */
539 main_menu = gtk_menu_new();
541 /* Get the menubar from the UI manager */
542 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
544 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
548 menu = GTK_WIDGET (iter->data);
549 gtk_widget_reparent(menu, main_menu);
551 iter = g_list_next (iter);
558 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
561 const gchar *to, *cc, *bcc, *subject;
563 ModestMsgEditWindowPrivate *priv;
566 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
567 g_return_if_fail (TNY_IS_MSG (msg));
569 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
571 header = tny_msg_get_header (msg);
572 to = tny_header_get_to (header);
573 cc = tny_header_get_cc (header);
574 bcc = tny_header_get_bcc (header);
575 subject = tny_header_get_subject (header);
578 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
580 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
582 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
584 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
586 update_window_title (self);
588 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
589 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
590 body = modest_tny_msg_get_body (msg, TRUE);
592 if ((body == NULL)||(body[0] == '\0')) {
594 body = modest_text_utils_convert_to_html ("");
596 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
597 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
600 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
603 /* Get the default format required from configuration */
604 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
605 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
608 /* Set the default focus depending on having already a To: field or not */
609 if ((!to)||(*to == '\0')) {
610 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
612 gtk_widget_grab_focus (priv->msg_body);
615 /* TODO: lower priority, select in the From: combo to the
616 value that comes from msg <- not sure, should it be
619 /* Add attachments to the view */
620 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
621 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
622 if (priv->attachments == NULL) {
623 gtk_widget_hide (priv->attachments_caption);
625 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
626 gtk_widget_show_all (priv->attachments_caption);
629 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
630 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
632 reset_modified (self);
634 update_dimmed (self);
635 text_buffer_can_undo (priv->text_buffer, FALSE, self);
637 priv->draft_msg = msg;
641 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
644 GList *item_children, *node;
645 GtkWidget *bin_child;
647 bin_child = gtk_bin_get_child (GTK_BIN(item));
649 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
651 for (node = item_children; node != NULL; node = g_list_next (node)) {
652 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
653 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
656 g_list_free (item_children);
660 menu_tool_button_dont_expand (GtkMenuToolButton *item)
663 GList *item_children, *node;
665 box = gtk_bin_get_child (GTK_BIN (item));
666 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
667 item_children = gtk_container_get_children (GTK_CONTAINER (box));
669 for (node = item_children; node != NULL; node = g_list_next (node)) {
670 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
671 if (GTK_IS_TOGGLE_BUTTON (node->data))
672 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
673 else if (GTK_IS_BUTTON (node->data))
674 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
676 g_list_free (item_children);
681 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
683 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
684 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
685 GtkWidget *placeholder;
686 GtkWidget *tool_item;
691 GtkWidget *sizes_menu;
692 GtkWidget *fonts_menu;
693 GSList *radio_group = NULL;
698 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
699 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
701 /* should we hide the toolbar? */
702 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
703 gtk_widget_hide (parent_priv->toolbar);
705 /* Font color placeholder */
706 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
707 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
710 tool_item = GTK_WIDGET (gtk_tool_item_new ());
711 priv->font_color_button = hildon_color_button_new ();
712 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
713 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
714 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
715 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
716 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
717 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
718 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
720 /* Font size and face placeholder */
721 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
722 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
724 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
725 priv->size_tool_button_label = gtk_label_new (NULL);
726 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
727 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
728 size_text,"</span>", NULL);
729 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
731 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
732 sizes_menu = gtk_menu_new ();
733 priv->size_items_group = NULL;
735 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
736 GtkWidget *size_menu_item;
738 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
739 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
740 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
741 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
742 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
743 gtk_widget_show (size_menu_item);
745 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
749 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
750 GtkWidget *item = (GtkWidget *) node->data;
751 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
755 priv->size_items_group = g_slist_reverse (priv->size_items_group);
756 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
757 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
758 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
759 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
760 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
761 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
762 priv->font_size_toolitem = tool_item;
765 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
766 priv->font_tool_button_label = gtk_label_new (NULL);
767 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
768 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
770 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
771 fonts_menu = gtk_menu_new ();
772 priv->font_items_group = NULL;
774 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
775 GtkWidget *font_menu_item;
776 GtkWidget *child_label;
778 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
779 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
780 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
781 wp_get_font_name (font_index), "</span>", NULL);
782 gtk_label_set_markup (GTK_LABEL (child_label), markup);
785 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
786 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
787 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
788 gtk_widget_show (font_menu_item);
790 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
793 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
794 GtkWidget *item = (GtkWidget *) node->data;
795 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
798 priv->font_items_group = g_slist_reverse (priv->font_items_group);
799 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
800 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
801 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
802 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
803 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
804 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
805 priv->font_face_toolitem = tool_item;
807 /* Set expand and homogeneous for remaining items */
808 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
809 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
810 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
811 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
812 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
813 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
814 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
815 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
816 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
824 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
827 ModestWindowPrivate *parent_priv;
828 ModestMsgEditWindowPrivate *priv;
829 GtkActionGroup *action_group;
830 GError *error = NULL;
831 GdkPixbuf *window_icon = NULL;
834 gboolean prefer_formatted;
836 ModestPair *account_pair = NULL;
838 g_return_val_if_fail (msg, NULL);
839 g_return_val_if_fail (account_name, NULL);
841 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
843 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
844 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
846 parent_priv->ui_manager = gtk_ui_manager_new();
847 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
848 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
850 /* Add common actions */
851 gtk_action_group_add_actions (action_group,
852 modest_msg_edit_action_entries,
853 G_N_ELEMENTS (modest_msg_edit_action_entries),
855 gtk_action_group_add_toggle_actions (action_group,
856 modest_msg_edit_toggle_action_entries,
857 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
859 gtk_action_group_add_radio_actions (action_group,
860 modest_msg_edit_alignment_radio_action_entries,
861 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
863 G_CALLBACK (modest_ui_actions_on_change_justify),
865 gtk_action_group_add_radio_actions (action_group,
866 modest_msg_edit_zoom_action_entries,
867 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
869 G_CALLBACK (modest_ui_actions_on_change_zoom),
871 gtk_action_group_add_radio_actions (action_group,
872 modest_msg_edit_priority_action_entries,
873 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
875 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
877 gtk_action_group_add_radio_actions (action_group,
878 modest_msg_edit_file_format_action_entries,
879 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
880 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
881 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
883 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
884 g_object_unref (action_group);
886 /* Load the UI definition */
887 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
890 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
891 g_clear_error (&error);
894 /* Add accelerators */
895 gtk_window_add_accel_group (GTK_WINDOW (obj),
896 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
899 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
900 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
903 init_window (MODEST_MSG_EDIT_WINDOW(obj));
905 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
907 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
909 g_signal_connect (G_OBJECT(obj), "delete-event",
910 G_CALLBACK(on_delete_event), obj);
912 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
914 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
916 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
918 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
919 if (account_pair != NULL)
920 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
922 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
924 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
926 /* Set window icon */
927 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
928 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
930 /* Dim at start clipboard actions */
931 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
932 gtk_action_set_sensitive (action, FALSE);
933 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
934 gtk_action_set_sensitive (action, FALSE);
936 /* set initial state of cc and bcc */
937 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
938 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
939 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
940 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
941 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
942 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
944 /* Setup the file format */
945 conf = modest_runtime_get_conf ();
946 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
948 g_clear_error (&error);
949 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
951 file_format = (prefer_formatted) ?
952 MODEST_FILE_FORMAT_FORMATTED_TEXT :
953 MODEST_FILE_FORMAT_PLAIN_TEXT;
954 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
956 return (ModestWindow*) obj;
960 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
962 GString **string_buffer = (GString **) user_data;
964 *string_buffer = g_string_append (*string_buffer, buffer);
970 * @result: A new string which should be freed with g_free().
973 get_formatted_data (ModestMsgEditWindow *edit_window)
975 ModestMsgEditWindowPrivate *priv;
976 GString *string_buffer = g_string_new ("");
978 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
980 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
982 return g_string_free (string_buffer, FALSE);
987 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
990 const gchar *account_name;
991 ModestMsgEditWindowPrivate *priv;
993 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
995 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
997 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
998 g_return_val_if_fail (account_name, NULL);
1001 /* don't free these (except from) */
1002 data = g_slice_new0 (MsgData);
1003 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1005 data->account_name = g_strdup (account_name);
1006 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1007 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1008 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1009 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1010 if (priv->draft_msg) {
1011 data->draft_msg = g_object_ref (priv->draft_msg);
1013 data->draft_msg = NULL;
1016 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1018 gtk_text_buffer_get_bounds (buf, &b, &e);
1019 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1021 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1022 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1024 data->html_body = NULL;
1026 data->attachments = priv->attachments; /* TODO: copy and free ? */
1027 data->priority_flags = priv->priority_flags;
1032 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1034 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1037 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1045 g_free (data->subject);
1046 g_free (data->plain_body);
1047 g_free (data->html_body);
1048 if (data->draft_msg != NULL) {
1049 g_object_unref (data->draft_msg);
1050 data->draft_msg = NULL;
1052 g_free (data->account_name);
1054 /* TODO: Free data->attachments? */
1056 g_slice_free (MsgData, data);
1060 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1063 ModestMsgEditWindowPrivate *priv = NULL;
1064 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1066 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1068 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1070 return MODEST_MSG_EDIT_FORMAT_HTML;
1072 return MODEST_MSG_EDIT_FORMAT_TEXT;
1076 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1077 ModestMsgEditFormat format)
1079 ModestMsgEditWindowPrivate *priv;
1081 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1082 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1085 case MODEST_MSG_EDIT_FORMAT_HTML:
1086 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1088 case MODEST_MSG_EDIT_FORMAT_TEXT:
1089 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1092 g_return_if_reached ();
1096 ModestMsgEditFormatState *
1097 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1099 ModestMsgEditFormatState *format_state = NULL;
1100 ModestMsgEditWindowPrivate *priv;
1101 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1103 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1104 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1106 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1108 format_state = g_new0 (ModestMsgEditFormatState, 1);
1109 format_state->bold = buffer_format->bold&0x1;
1110 format_state->italics = buffer_format->italic&0x1;
1111 format_state->bullet = buffer_format->bullet&0x1;
1112 format_state->color = buffer_format->color;
1113 format_state->font_size = buffer_format->font_size;
1114 format_state->font_family = wp_get_font_name (buffer_format->font);
1115 format_state->justification = buffer_format->justification;
1116 g_free (buffer_format);
1118 return format_state;
1123 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1124 const ModestMsgEditFormatState *format_state)
1126 ModestMsgEditWindowPrivate *priv;
1127 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1128 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1129 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1130 g_return_if_fail (format_state != NULL);
1132 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1133 gtk_widget_grab_focus (priv->msg_body);
1134 buffer_format->bold = (format_state->bold != FALSE);
1135 buffer_format->italic = (format_state->italics != FALSE);
1136 buffer_format->color = format_state->color;
1137 buffer_format->font_size = format_state->font_size;
1138 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1139 buffer_format->justification = format_state->justification;
1140 buffer_format->bullet = format_state->bullet;
1142 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1144 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1145 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1146 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1147 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1148 buffer_format->cs.font = (buffer_format->font != current_format->font);
1149 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1150 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1152 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1153 if (buffer_format->cs.bold) {
1154 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1156 if (buffer_format->cs.italic) {
1157 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1159 if (buffer_format->cs.color) {
1160 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1162 if (buffer_format->cs.font_size) {
1163 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1165 if (buffer_format->cs.justification) {
1166 switch (buffer_format->justification) {
1167 case GTK_JUSTIFY_LEFT:
1168 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1170 case GTK_JUSTIFY_CENTER:
1171 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1173 case GTK_JUSTIFY_RIGHT:
1174 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1181 if (buffer_format->cs.font) {
1182 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1184 if (buffer_format->cs.bullet) {
1185 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1187 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1188 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1190 g_free (current_format);
1195 toggle_action_set_active_block_notify (GtkToggleAction *action,
1198 GSList *proxies = NULL;
1200 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1201 proxies != NULL; proxies = g_slist_next (proxies)) {
1202 GtkWidget *widget = (GtkWidget *) proxies->data;
1203 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1206 gtk_toggle_action_set_active (action, value);
1208 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1209 proxies != NULL; proxies = g_slist_next (proxies)) {
1210 GtkWidget *widget = (GtkWidget *) proxies->data;
1211 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1216 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1218 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1220 ModestWindowPrivate *parent_priv;
1221 ModestMsgEditWindowPrivate *priv;
1222 GtkWidget *new_size_menuitem;
1223 GtkWidget *new_font_menuitem;
1225 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1226 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1228 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1229 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1230 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1231 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1233 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1234 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1235 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1238 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1240 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1241 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1243 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1244 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1246 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1247 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1249 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1250 G_CALLBACK (modest_msg_edit_window_color_button_change),
1252 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1253 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1254 G_CALLBACK (modest_msg_edit_window_color_button_change),
1257 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1258 buffer_format->font_size))->data);
1259 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1263 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1264 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1265 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1267 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1268 G_CALLBACK (modest_msg_edit_window_size_change),
1270 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1271 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1272 G_CALLBACK (modest_msg_edit_window_size_change),
1276 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1277 buffer_format->font))->data);
1278 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1282 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1283 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1284 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1286 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1287 G_CALLBACK (modest_msg_edit_window_font_change),
1289 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1290 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1291 G_CALLBACK (modest_msg_edit_window_font_change),
1295 g_free (buffer_format);
1301 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1304 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1305 ModestMsgEditWindowPrivate *priv;
1306 GtkWidget *dialog = NULL;
1308 const GdkColor *new_color = NULL;
1310 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1311 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1313 #ifdef MODEST_HILDON_VERSION_0
1314 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1315 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1317 dialog = hildon_color_chooser_new ();
1318 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1319 #endif /*MODEST_HILDON_VERSION_0*/
1320 g_free (buffer_format);
1322 response = gtk_dialog_run (GTK_DIALOG (dialog));
1324 case GTK_RESPONSE_OK: {
1325 #ifdef MODEST_HILDON_VERSION_0
1326 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1329 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1331 #endif /*MODEST_HILDON_VERSION_0*/
1338 gtk_widget_destroy (dialog);
1340 if (new_color != NULL)
1341 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1346 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1349 ModestMsgEditWindowPrivate *priv;
1350 GtkWidget *dialog = NULL;
1352 GdkColor *old_color = NULL;
1353 const GdkColor *new_color = NULL;
1355 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1356 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1358 #ifdef MODEST_HILDON_VERSION_0
1359 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1360 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1362 dialog = hildon_color_chooser_new ();
1363 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1364 #endif /*MODEST_HILDON_VERSION_9*/
1366 response = gtk_dialog_run (GTK_DIALOG (dialog));
1368 case GTK_RESPONSE_OK: {
1369 #ifdef MODEST_HILDON_VERSION_0
1370 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1373 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1375 #endif /*MODEST_HILDON_VERSION_0*/
1381 gtk_widget_destroy (dialog);
1383 if (new_color != NULL)
1384 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1389 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1392 ModestMsgEditWindowPrivate *priv;
1393 GtkWidget *dialog = NULL;
1395 gchar *filename = NULL;
1397 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1399 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1401 response = gtk_dialog_run (GTK_DIALOG (dialog));
1403 case GTK_RESPONSE_OK:
1404 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1409 gtk_widget_destroy (dialog);
1412 GdkPixbuf *pixbuf = NULL;
1413 GtkTextIter position;
1414 GtkTextMark *insert_mark;
1416 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1419 GdkPixbufFormat *pixbuf_format;
1421 image_file_id = g_open (filename, O_RDONLY, 0);
1422 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1423 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1424 TnyMimePart *image_part;
1425 TnyStream *image_stream;
1431 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1432 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1433 mime_type = mime_types[0];
1435 mime_type = "image/unknown";
1437 image_part = tny_platform_factory_new_mime_part
1438 (modest_runtime_get_platform_factory ());
1439 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1441 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1442 g_strfreev (mime_types);
1444 content_id = g_strdup_printf ("%d", priv->last_cid);
1445 tny_mime_part_set_content_id (image_part, content_id);
1446 g_free (content_id);
1449 basename = g_path_get_basename (filename);
1450 tny_mime_part_set_filename (image_part, basename);
1453 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1454 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1455 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1456 priv->attachments = g_list_prepend (priv->attachments, image_part);
1457 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1459 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1460 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1461 gtk_widget_show_all (priv->attachments_caption);
1462 } else if (image_file_id == -1) {
1463 close (image_file_id);
1472 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1475 ModestMsgEditWindowPrivate *priv;
1476 GtkWidget *dialog = NULL;
1478 gchar *uri = NULL, *filename = NULL;
1480 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1482 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1484 response = gtk_dialog_run (GTK_DIALOG (dialog));
1486 case GTK_RESPONSE_OK:
1487 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1488 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1493 gtk_widget_destroy (dialog);
1497 GnomeVFSHandle *handle = NULL;
1498 GnomeVFSResult result;
1500 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1501 if (result == GNOME_VFS_OK) {
1502 TnyMimePart *mime_part;
1504 const gchar *mime_type = NULL;
1507 GnomeVFSFileInfo info;
1509 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1510 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1511 mime_part = tny_platform_factory_new_mime_part
1512 (modest_runtime_get_platform_factory ());
1513 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1515 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1517 content_id = g_strdup_printf ("%d", priv->last_cid);
1518 tny_mime_part_set_content_id (mime_part, content_id);
1519 g_free (content_id);
1522 basename = g_path_get_basename (filename);
1523 tny_mime_part_set_filename (mime_part, basename);
1526 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1527 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1529 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1530 gtk_widget_show_all (priv->attachments_caption);
1531 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1538 modest_msg_edit_window_attach_file_noninteractive (
1539 ModestMsgEditWindow *window,
1543 ModestMsgEditWindowPrivate *priv;
1545 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1550 file_id = g_open (filename, O_RDONLY, 0);
1551 if (file_id != -1) {
1552 TnyMimePart *mime_part;
1554 const gchar *mime_type;
1558 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1559 mime_part = tny_platform_factory_new_mime_part
1560 (modest_runtime_get_platform_factory ());
1561 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1563 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1565 content_id = g_strdup_printf ("%d", priv->last_cid);
1566 tny_mime_part_set_content_id (mime_part, content_id);
1567 g_free (content_id);
1570 basename = g_path_get_basename (filename);
1571 tny_mime_part_set_filename (mime_part, basename);
1574 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1575 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1577 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1578 gtk_widget_show_all (priv->attachments_caption);
1579 } else if (file_id == -1) {
1581 g_warning("file to be attached does not exist: %s", filename);
1587 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1590 ModestMsgEditWindowPrivate *priv;
1591 gboolean clean_list = FALSE;
1593 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1594 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1596 if (att_list == NULL) {
1597 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1601 if (att_list == NULL) {
1602 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1604 GtkWidget *confirmation_dialog = NULL;
1605 gboolean dialog_response;
1607 if (att_list->next == NULL) {
1608 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1609 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1610 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1613 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1615 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1616 gtk_widget_destroy (confirmation_dialog);
1617 if (!dialog_response) {
1619 g_list_free (att_list);
1622 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1624 for (node = att_list; node != NULL; node = g_list_next (node)) {
1625 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1626 const gchar *att_id;
1627 priv->attachments = g_list_remove (priv->attachments, mime_part);
1629 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1631 if (priv->attachments == NULL)
1632 gtk_widget_hide (priv->attachments_caption);
1633 att_id = tny_mime_part_get_content_id (mime_part);
1635 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1637 g_object_unref (mime_part);
1638 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1643 g_list_free (att_list);
1647 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1650 ModestMsgEditWindowPrivate *priv;
1651 GdkColor *new_color;
1652 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1654 #ifdef MODEST_HILDON_VERSION_0
1655 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1658 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1660 #endif /*MODEST_HILDON_VERSION_0*/
1662 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1664 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1669 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1672 ModestMsgEditWindowPrivate *priv;
1673 gint new_size_index;
1674 ModestMsgEditWindow *window;
1677 window = MODEST_MSG_EDIT_WINDOW (userdata);
1678 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1679 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1681 if (gtk_check_menu_item_get_active (menu_item)) {
1683 WPTextBufferFormat format;
1685 memset (&format, 0, sizeof (format));
1686 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1688 label = gtk_bin_get_child (GTK_BIN (menu_item));
1690 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1691 format.cs.font_size = TRUE;
1692 format.cs.text_position = TRUE;
1693 format.cs.font = TRUE;
1694 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1695 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1697 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1698 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1699 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1701 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1702 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1703 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1709 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1712 ModestMsgEditWindowPrivate *priv;
1713 gint new_font_index;
1714 ModestMsgEditWindow *window;
1717 window = MODEST_MSG_EDIT_WINDOW (userdata);
1718 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1719 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1721 if (gtk_check_menu_item_get_active (menu_item)) {
1724 label = gtk_bin_get_child (GTK_BIN (menu_item));
1726 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1728 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1729 (gpointer) new_font_index))
1730 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1732 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1733 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1734 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1740 modest_msg_edit_window_set_zoom (ModestWindow *window,
1743 ModestMsgEditWindowPrivate *priv;
1745 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1747 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1748 priv->zoom_level = zoom;
1749 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1753 modest_msg_edit_window_get_zoom (ModestWindow *window)
1755 ModestMsgEditWindowPrivate *priv;
1757 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1759 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1760 return priv->zoom_level;
1764 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1766 ModestWindowPrivate *parent_priv;
1767 GtkRadioAction *zoom_radio_action;
1768 GSList *group, *node;
1770 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1771 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1772 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1774 group = gtk_radio_action_get_group (zoom_radio_action);
1776 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1777 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1781 for (node = group; node != NULL; node = g_slist_next (node)) {
1782 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1783 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1791 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1793 ModestWindowPrivate *parent_priv;
1794 GtkRadioAction *zoom_radio_action;
1795 GSList *group, *node;
1797 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1798 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1799 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1801 group = gtk_radio_action_get_group (zoom_radio_action);
1803 for (node = group; node != NULL; node = g_slist_next (node)) {
1804 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1805 if (node->next != NULL) {
1806 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1809 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1817 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1819 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1820 ModestWindowPrivate *parent_priv;
1821 ModestWindowMgr *mgr;
1822 gboolean is_fullscreen;
1823 GtkAction *fs_toggle_action;
1826 mgr = modest_runtime_get_window_mgr ();
1827 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1829 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1831 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1832 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1833 if (is_fullscreen != active)
1834 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1842 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1844 ModestWindowPrivate *parent_priv;
1845 GtkAction *fs_toggle_action;
1848 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1850 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1851 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1852 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1856 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1859 ModestMsgEditWindowPrivate *priv = NULL;
1860 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1862 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1863 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1865 gtk_widget_show (priv->cc_caption);
1867 gtk_widget_hide (priv->cc_caption);
1868 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1872 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1875 ModestMsgEditWindowPrivate *priv = NULL;
1876 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1878 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1879 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1881 gtk_widget_show (priv->bcc_caption);
1883 gtk_widget_hide (priv->bcc_caption);
1884 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1888 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1889 ModestRecptEditor *editor)
1891 ModestMsgEditWindowPrivate *priv;
1893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1894 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1895 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1897 if (editor == NULL) {
1898 GtkWidget *view_focus;
1899 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1901 /* This code should be kept in sync with ModestRecptEditor. The
1902 textview inside the recpt editor is the one that really gets the
1903 focus. As it's inside a scrolled window, and this one inside the
1904 hbox recpt editor inherits from, we'll need to go up in the
1905 hierarchy to know if the text view is part of the recpt editor
1906 or if it's a different text entry */
1908 if (gtk_widget_get_parent (view_focus)) {
1909 GtkWidget *first_parent;
1911 first_parent = gtk_widget_get_parent (view_focus);
1912 if (gtk_widget_get_parent (first_parent) &&
1913 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1914 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1919 editor = MODEST_RECPT_EDITOR (priv->to_field);
1923 modest_address_book_select_addresses (editor);
1928 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1930 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1932 modest_msg_edit_window_open_addressbook (window, NULL);
1936 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1937 gboolean show_toolbar)
1939 ModestWindowPrivate *parent_priv;
1941 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1942 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1944 /* FIXME: we can not just use the code of
1945 modest_msg_edit_window_setup_toolbar because it has a
1946 mixture of both initialization and creation code. */
1949 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1951 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1955 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1956 TnyHeaderFlags priority_flags)
1958 ModestMsgEditWindowPrivate *priv;
1960 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1962 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1963 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1965 if (priv->priority_flags != priority_flags) {
1967 priv->priority_flags = priority_flags;
1969 switch (priority_flags) {
1970 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1971 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1972 gtk_widget_show (priv->priority_icon);
1974 case TNY_HEADER_FLAG_LOW_PRIORITY:
1975 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1976 gtk_widget_show (priv->priority_icon);
1979 gtk_widget_hide (priv->priority_icon);
1986 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1989 ModestMsgEditWindowPrivate *priv;
1990 gint current_format;
1992 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1994 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1996 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1997 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1999 if (current_format != file_format) {
2000 switch (file_format) {
2001 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2002 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2004 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2008 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2009 response = gtk_dialog_run (GTK_DIALOG (dialog));
2010 gtk_widget_destroy (dialog);
2011 if (response == GTK_RESPONSE_OK)
2012 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2016 update_dimmed (window);
2021 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2024 ModestMsgEditWindowPrivate *priv;
2025 WPTextBufferFormat oldfmt, fmt;
2026 gint old_position = 0;
2030 GdkColor *color = NULL;
2031 gboolean bold, bold_set, italic, italic_set;
2032 gboolean underline, underline_set;
2033 gboolean strikethrough, strikethrough_set;
2034 gboolean position_set;
2035 gboolean font_size_set, font_set, color_set;
2038 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2039 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2041 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2043 /* First we get the currently selected font information */
2044 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2045 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2047 switch (oldfmt.text_position) {
2048 case TEXT_POSITION_NORMAL:
2051 case TEXT_POSITION_SUPERSCRIPT:
2059 g_object_set (G_OBJECT (dialog),
2060 "bold", oldfmt.bold != FALSE,
2061 "bold-set", !oldfmt.cs.bold,
2062 "underline", oldfmt.underline != FALSE,
2063 "underline-set", !oldfmt.cs.underline,
2064 "italic", oldfmt.italic != FALSE,
2065 "italic-set", !oldfmt.cs.italic,
2066 "strikethrough", oldfmt.strikethrough != FALSE,
2067 "strikethrough-set", !oldfmt.cs.strikethrough,
2068 "color", &oldfmt.color,
2069 "color-set", !oldfmt.cs.color,
2070 "size", wp_font_size[oldfmt.font_size],
2071 "size-set", !oldfmt.cs.font_size,
2072 "position", old_position,
2073 "position-set", !oldfmt.cs.text_position,
2074 "family", wp_get_font_name (oldfmt.font),
2075 "family-set", !oldfmt.cs.font,
2078 gtk_widget_show_all (dialog);
2079 response = gtk_dialog_run (GTK_DIALOG (dialog));
2080 if (response == GTK_RESPONSE_OK) {
2082 g_object_get( dialog,
2084 "bold-set", &bold_set,
2085 "underline", &underline,
2086 "underline-set", &underline_set,
2088 "italic-set", &italic_set,
2089 "strikethrough", &strikethrough,
2090 "strikethrough-set", &strikethrough_set,
2092 "color-set", &color_set,
2094 "size-set", &font_size_set,
2095 "family", &font_name,
2096 "family-set", &font_set,
2097 "position", &position,
2098 "position-set", &position_set,
2103 if (response == GTK_RESPONSE_OK) {
2104 memset(&fmt, 0, sizeof(fmt));
2110 fmt.italic = italic;
2111 fmt.cs.italic = TRUE;
2113 if (underline_set) {
2114 fmt.underline = underline;
2115 fmt.cs.underline = TRUE;
2117 if (strikethrough_set) {
2118 fmt.strikethrough = strikethrough;
2119 fmt.cs.strikethrough = TRUE;
2124 ? TEXT_POSITION_NORMAL
2125 : ( ( position == 1 )
2126 ? TEXT_POSITION_SUPERSCRIPT
2127 : TEXT_POSITION_SUBSCRIPT );
2128 fmt.cs.text_position = TRUE;
2132 fmt.cs.color = TRUE;
2135 fmt.font = wp_get_font_index(font_name,
2140 if (font_size_set) {
2141 fmt.font_size = wp_get_font_size_index(
2142 font_size, DEFAULT_FONT_SIZE);
2143 fmt.cs.font_size = TRUE;
2145 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2147 gtk_widget_destroy (dialog);
2149 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2153 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2155 ModestMsgEditWindowPrivate *priv;
2157 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2158 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2160 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2162 update_dimmed (window);
2167 update_dimmed (ModestMsgEditWindow *window)
2169 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2170 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2174 gboolean editor_focused;
2176 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2177 editor_focused = gtk_widget_is_focus (priv->msg_body);
2179 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2180 gtk_action_set_sensitive (action, rich_text && editor_focused);
2181 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2182 gtk_action_set_sensitive (action, rich_text && editor_focused);
2183 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2184 gtk_action_set_sensitive (action, rich_text && editor_focused);
2185 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2186 gtk_action_set_sensitive (action, rich_text && editor_focused);
2187 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2188 gtk_action_set_sensitive (action, rich_text && editor_focused);
2189 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2190 gtk_action_set_sensitive (action, rich_text && editor_focused);
2191 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2192 gtk_action_set_sensitive (action, rich_text && editor_focused);
2193 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2194 gtk_action_set_sensitive (action, rich_text && editor_focused);
2195 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2196 gtk_action_set_sensitive (action, rich_text && editor_focused);
2197 widget = priv->font_color_button;
2198 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2199 widget = priv->font_size_toolitem;
2200 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2201 widget = priv->font_face_toolitem;
2202 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2206 setup_insensitive_handlers (ModestMsgEditWindow *window)
2208 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2209 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2212 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2213 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2214 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2215 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2217 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2218 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2219 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2220 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2221 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2222 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2223 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2224 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2225 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2226 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2227 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2228 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2229 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2230 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2231 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2232 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2233 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2234 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2235 widget = priv->font_color_button;
2236 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2237 widget = priv->font_size_toolitem;
2238 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2239 widget = priv->font_face_toolitem;
2240 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2245 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2247 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2250 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2251 gtk_action_set_sensitive (action, can_undo);
2255 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2258 GtkTextIter match_start, match_end;
2260 if (image_id == NULL)
2263 gtk_text_buffer_get_start_iter (buffer, &iter);
2265 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2266 GSList *tags = gtk_text_iter_get_tags (&match_start);
2268 for (node = tags; node != NULL; node = g_slist_next (node)) {
2269 GtkTextTag *tag = (GtkTextTag *) node->data;
2270 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2271 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2272 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2274 offset = gtk_text_iter_get_offset (&match_start);
2275 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2276 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2280 gtk_text_iter_forward_char (&iter);
2285 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2287 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2288 GtkTextIter real_start, real_end;
2289 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2291 if (gtk_text_iter_compare (start, end) > 0) {
2295 real_start = *start;
2299 GSList *tags = gtk_text_iter_get_tags (&real_start);
2301 for (node = tags; node != NULL; node = g_slist_next (node)) {
2302 GtkTextTag *tag = (GtkTextTag *) node->data;
2303 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2304 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2306 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2308 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2311 } while (gtk_text_iter_forward_char (&real_start)&&
2312 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2316 msg_body_focus (GtkWidget *focus,
2317 GdkEventFocus *event,
2321 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2326 recpt_field_changed (GtkTextBuffer *buffer,
2327 ModestMsgEditWindow *editor)
2329 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2330 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2331 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2332 gboolean dim = FALSE;
2335 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2336 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2337 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2339 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2340 gtk_text_buffer_get_char_count (cc_buffer) +
2341 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2343 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2344 gtk_action_set_sensitive (action, !dim);
2345 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2346 gtk_action_set_sensitive (action, !dim);
2350 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2352 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2356 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2358 gboolean rich_text, editor_focused;
2360 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2361 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2362 editor_focused = gtk_widget_is_focus (priv->msg_body);
2365 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2366 else if (!editor_focused)
2367 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2371 reset_modified (ModestMsgEditWindow *editor)
2373 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2374 GtkTextBuffer *buffer;
2376 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2377 gtk_text_buffer_set_modified (buffer, FALSE);
2378 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2379 gtk_text_buffer_set_modified (buffer, FALSE);
2380 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2381 gtk_text_buffer_set_modified (buffer, FALSE);
2382 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2386 is_modified (ModestMsgEditWindow *editor)
2388 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2389 GtkTextBuffer *buffer;
2391 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2392 if (gtk_text_buffer_get_modified (buffer))
2394 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2395 if (gtk_text_buffer_get_modified (buffer))
2397 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2398 if (gtk_text_buffer_get_modified (buffer))
2400 if (gtk_text_buffer_get_modified (priv->text_buffer))
2407 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2409 ModestMsgEditWindowPrivate *priv = NULL;
2411 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2412 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2414 /* check if there's no recipient added */
2415 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2416 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2417 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2418 /* no recipient contents, then select contacts */
2419 modest_msg_edit_window_open_addressbook (window, NULL);
2423 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2425 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2427 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2430 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2437 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2438 ModestMsgEditWindow *window)
2440 modest_msg_edit_window_attach_file (window);
2444 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2446 ModestMsgEditWindow *window)
2448 ModestWindowPrivate *parent_priv;
2453 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2454 selection = gtk_clipboard_wait_for_text (clipboard);
2455 focused = gtk_window_get_focus (GTK_WINDOW (window));
2457 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2458 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2459 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2460 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2464 update_window_title (ModestMsgEditWindow *window)
2466 ModestMsgEditWindowPrivate *priv = NULL;
2467 const gchar *subject;
2469 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2470 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2471 if (subject == NULL || subject[0] == '\0')
2472 subject = _("mail_va_new_email");
2474 gtk_window_set_title (GTK_WINDOW (window), subject);
2479 subject_field_changed (GtkEditable *editable,
2480 ModestMsgEditWindow *window)
2482 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2483 update_window_title (window);
2484 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2488 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2491 ModestMsgEditWindowPrivate *priv = NULL;
2493 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2494 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2496 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2498 gtk_widget_show_all (priv->find_toolbar);
2499 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2501 gtk_widget_hide_all (priv->find_toolbar);
2502 gtk_widget_grab_focus (priv->msg_body);
2508 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2509 ModestMsgEditWindow *window)
2511 gchar *current_search = NULL;
2512 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2514 GtkTextIter selection_start, selection_end;
2515 GtkTextIter match_start, match_end;
2517 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2518 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2519 g_free (current_search);
2523 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2524 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2526 GtkTextIter buffer_start;
2527 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2528 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2531 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2532 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2534 /* TODO: warning about non succesful search */
2536 g_free (current_search);
2540 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2541 ModestMsgEditWindow *window)
2543 GtkToggleAction *toggle;
2544 ModestWindowPrivate *parent_priv;
2545 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2547 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2548 gtk_toggle_action_set_active (toggle, FALSE);