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 const 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 = g_strdup (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);
321 init_window (ModestMsgEditWindow *obj)
323 GtkWidget *from_caption, *to_caption, *subject_caption;
324 GtkWidget *main_vbox;
325 ModestMsgEditWindowPrivate *priv;
327 GtkSizeGroup *size_group;
329 GtkWidget *scroll_area;
330 GtkWidget *subject_box;
331 GtkWidget *attachment_icon;
332 GtkWidget *window_box;
334 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
336 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
338 /* Note: This ModestPairList* must exist for as long as the combo
339 * that uses it, because the ModestComboBox uses the ID opaquely,
340 * so it can't know how to manage its memory. */
341 priv->from_field_protos = get_transports ();
343 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
345 priv->to_field = modest_recpt_editor_new ();
346 priv->cc_field = modest_recpt_editor_new ();
347 priv->bcc_field = modest_recpt_editor_new ();
348 subject_box = gtk_hbox_new (FALSE, 0);
349 priv->priority_icon = gtk_image_new ();
350 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
351 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
352 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
353 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
354 priv->add_attachment_button = gtk_button_new ();
355 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
356 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
357 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
358 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
359 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
360 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
361 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
362 priv->attachments_view = modest_attachments_view_new (NULL);
364 priv->header_box = gtk_vbox_new (FALSE, 0);
366 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
367 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
368 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
369 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
370 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
371 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
372 g_object_unref (size_group);
374 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
375 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
376 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
377 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
378 gtk_size_group_add_widget (size_group, priv->subject_field);
379 gtk_size_group_add_widget (size_group, priv->attachments_view);
380 g_object_unref (size_group);
382 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
383 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
384 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
385 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
386 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
387 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
388 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
391 priv->msg_body = wp_text_view_new ();
392 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
393 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
394 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
395 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
396 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
397 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
399 priv->find_toolbar = hildon_find_toolbar_new (NULL);
400 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
402 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
403 G_CALLBACK (text_buffer_refresh_attributes), obj);
404 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
405 G_CALLBACK (text_buffer_delete_range), obj);
406 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
407 G_CALLBACK (text_buffer_can_undo), obj);
408 g_signal_connect (G_OBJECT (obj), "window-state-event",
409 G_CALLBACK (modest_msg_edit_window_window_state_event),
411 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
412 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
413 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
414 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
415 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
416 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
418 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
419 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
421 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
422 G_CALLBACK (msg_body_focus), obj);
423 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
424 G_CALLBACK (msg_body_focus), obj);
425 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
426 "changed", G_CALLBACK (recpt_field_changed), obj);
427 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
428 "changed", G_CALLBACK (recpt_field_changed), obj);
429 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
430 "changed", G_CALLBACK (recpt_field_changed), obj);
431 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
432 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
434 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
435 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
437 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
438 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
439 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
441 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
443 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
444 frame = gtk_frame_new (NULL);
445 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
447 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
448 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
449 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
451 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
452 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
453 gtk_widget_hide (priv->cc_caption);
455 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
456 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
457 gtk_widget_hide (priv->bcc_caption);
460 window_box = gtk_vbox_new (FALSE, 0);
461 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
462 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
463 gtk_container_add (GTK_CONTAINER(obj), window_box);
464 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
465 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
466 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
467 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
469 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
470 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
476 modest_msg_edit_window_finalize (GObject *obj)
478 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
480 if (priv->clipboard_change_handler_id > 0) {
481 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
482 priv->clipboard_change_handler_id = 0;
485 /* This had to stay alive for as long as the combobox that used it: */
486 modest_pair_list_free (priv->from_field_protos);
488 G_OBJECT_CLASS(parent_class)->finalize (obj);
492 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
494 GtkWidget *close_dialog;
495 ModestMsgEditWindowPrivate *priv;
498 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
499 modest_window_save_state (MODEST_WINDOW (self));
500 if (is_modified (self)) {
501 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
502 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
503 gtk_widget_destroy (close_dialog);
505 if (response != GTK_RESPONSE_CANCEL) {
506 modest_ui_actions_on_save_to_drafts (NULL, self);
509 /* /\* remove old message from drafts *\/ */
510 /* if (priv->draft_msg) { */
511 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
512 /* TnyAccount *account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(), */
514 /* TNY_ACCOUNT_TYPE_STORE); */
515 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
516 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
517 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
518 /* tny_folder_remove_msg (folder, header, NULL); */
519 /* g_object_unref (folder); */
520 /* g_object_unref (header); */
521 /* g_object_unref (priv->draft_msg); */
522 /* priv->draft_msg = NULL; */
524 gtk_widget_destroy (GTK_WIDGET (self));
530 menubar_to_menu (GtkUIManager *ui_manager)
532 GtkWidget *main_menu;
536 /* Create new main menu */
537 main_menu = gtk_menu_new();
539 /* Get the menubar from the UI manager */
540 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
542 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
546 menu = GTK_WIDGET (iter->data);
547 gtk_widget_reparent(menu, main_menu);
549 iter = g_list_next (iter);
556 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
559 const gchar *to, *cc, *bcc, *subject;
561 ModestMsgEditWindowPrivate *priv;
564 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
565 g_return_if_fail (TNY_IS_MSG (msg));
567 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
569 header = tny_msg_get_header (msg);
570 to = tny_header_get_to (header);
571 cc = tny_header_get_cc (header);
572 bcc = tny_header_get_bcc (header);
573 subject = tny_header_get_subject (header);
576 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
578 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
580 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
582 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
584 update_window_title (self);
586 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
587 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
588 body = modest_tny_msg_get_body (msg, TRUE);
590 if ((body == NULL)||(body[0] == '\0')) {
592 body = modest_text_utils_convert_to_html ("");
594 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
595 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
598 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
601 /* Get the default format required from configuration */
602 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
603 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
606 /* Set the default focus depending on having already a To: field or not */
607 if ((!to)||(*to == '\0')) {
608 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
610 gtk_widget_grab_focus (priv->msg_body);
613 /* TODO: lower priority, select in the From: combo to the
614 value that comes from msg <- not sure, should it be
617 /* Add attachments to the view */
618 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
619 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
620 if (priv->attachments == NULL) {
621 gtk_widget_hide (priv->attachments_caption);
623 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
624 gtk_widget_show_all (priv->attachments_caption);
627 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
628 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
630 reset_modified (self);
632 update_dimmed (self);
633 text_buffer_can_undo (priv->text_buffer, FALSE, self);
635 priv->draft_msg = msg;
639 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
642 GList *item_children, *node;
643 GtkWidget *bin_child;
645 bin_child = gtk_bin_get_child (GTK_BIN(item));
647 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
649 for (node = item_children; node != NULL; node = g_list_next (node)) {
650 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
651 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
654 g_list_free (item_children);
658 menu_tool_button_dont_expand (GtkMenuToolButton *item)
661 GList *item_children, *node;
663 box = gtk_bin_get_child (GTK_BIN (item));
664 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
665 item_children = gtk_container_get_children (GTK_CONTAINER (box));
667 for (node = item_children; node != NULL; node = g_list_next (node)) {
668 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
669 if (GTK_IS_TOGGLE_BUTTON (node->data))
670 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
671 else if (GTK_IS_BUTTON (node->data))
672 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
674 g_list_free (item_children);
679 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
681 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
682 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
683 GtkWidget *placeholder;
684 GtkWidget *tool_item;
689 GtkWidget *sizes_menu;
690 GtkWidget *fonts_menu;
691 GSList *radio_group = NULL;
696 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
697 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
699 /* should we hide the toolbar? */
700 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
701 gtk_widget_hide (parent_priv->toolbar);
703 /* Font color placeholder */
704 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
705 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
708 tool_item = GTK_WIDGET (gtk_tool_item_new ());
709 priv->font_color_button = hildon_color_button_new ();
710 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
711 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
712 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
713 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
714 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
715 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
716 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
718 /* Font size and face placeholder */
719 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
720 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
722 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
723 priv->size_tool_button_label = gtk_label_new (NULL);
724 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
725 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
726 size_text,"</span>", NULL);
727 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
729 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
730 sizes_menu = gtk_menu_new ();
731 priv->size_items_group = NULL;
733 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
734 GtkWidget *size_menu_item;
736 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
737 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
738 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
739 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
740 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
741 gtk_widget_show (size_menu_item);
743 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
747 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
748 GtkWidget *item = (GtkWidget *) node->data;
749 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
753 priv->size_items_group = g_slist_reverse (priv->size_items_group);
754 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
755 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
756 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
757 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
758 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
759 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
760 priv->font_size_toolitem = tool_item;
763 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
764 priv->font_tool_button_label = gtk_label_new (NULL);
765 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
766 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
768 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
769 fonts_menu = gtk_menu_new ();
770 priv->font_items_group = NULL;
772 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
773 GtkWidget *font_menu_item;
774 GtkWidget *child_label;
776 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
777 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
778 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
779 wp_get_font_name (font_index), "</span>", NULL);
780 gtk_label_set_markup (GTK_LABEL (child_label), markup);
783 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
784 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
785 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
786 gtk_widget_show (font_menu_item);
788 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
791 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
792 GtkWidget *item = (GtkWidget *) node->data;
793 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
796 priv->font_items_group = g_slist_reverse (priv->font_items_group);
797 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
798 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
799 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
800 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
801 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
802 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
803 priv->font_face_toolitem = tool_item;
805 /* Set expand and homogeneous for remaining items */
806 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
807 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
808 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
809 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
810 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
811 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
812 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
813 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
814 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
822 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
825 ModestWindowPrivate *parent_priv;
826 ModestMsgEditWindowPrivate *priv;
827 GtkActionGroup *action_group;
828 GError *error = NULL;
829 GdkPixbuf *window_icon = NULL;
832 gboolean prefer_formatted;
835 g_return_val_if_fail (msg, NULL);
836 g_return_val_if_fail (account_name, NULL);
838 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
840 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
841 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
843 parent_priv->ui_manager = gtk_ui_manager_new();
844 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
845 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
847 /* Add common actions */
848 gtk_action_group_add_actions (action_group,
849 modest_msg_edit_action_entries,
850 G_N_ELEMENTS (modest_msg_edit_action_entries),
852 gtk_action_group_add_toggle_actions (action_group,
853 modest_msg_edit_toggle_action_entries,
854 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
856 gtk_action_group_add_radio_actions (action_group,
857 modest_msg_edit_alignment_radio_action_entries,
858 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
860 G_CALLBACK (modest_ui_actions_on_change_justify),
862 gtk_action_group_add_radio_actions (action_group,
863 modest_msg_edit_zoom_action_entries,
864 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
866 G_CALLBACK (modest_ui_actions_on_change_zoom),
868 gtk_action_group_add_radio_actions (action_group,
869 modest_msg_edit_priority_action_entries,
870 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
872 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
874 gtk_action_group_add_radio_actions (action_group,
875 modest_msg_edit_file_format_action_entries,
876 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
877 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
878 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
880 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
881 g_object_unref (action_group);
883 /* Load the UI definition */
884 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
887 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
888 g_clear_error (&error);
891 /* Add accelerators */
892 gtk_window_add_accel_group (GTK_WINDOW (obj),
893 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
896 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
897 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
900 init_window (MODEST_MSG_EDIT_WINDOW(obj));
902 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
904 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
906 g_signal_connect (G_OBJECT(obj), "delete-event",
907 G_CALLBACK(on_delete_event), obj);
909 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
911 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
913 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
915 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
917 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
919 /* Set window icon */
920 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
921 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
923 /* Dim at start clipboard actions */
924 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
925 gtk_action_set_sensitive (action, FALSE);
926 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
927 gtk_action_set_sensitive (action, FALSE);
929 /* set initial state of cc and bcc */
930 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
931 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
932 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
933 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
934 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
935 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
937 /* Setup the file format */
938 conf = modest_runtime_get_conf ();
939 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
941 g_clear_error (&error);
942 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
944 file_format = (prefer_formatted) ?
945 MODEST_FILE_FORMAT_FORMATTED_TEXT :
946 MODEST_FILE_FORMAT_PLAIN_TEXT;
947 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
949 return (ModestWindow*) obj;
953 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
955 GString **string_buffer = (GString **) user_data;
957 *string_buffer = g_string_append (*string_buffer, buffer);
963 * @result: A new string which should be freed with g_free().
966 get_formatted_data (ModestMsgEditWindow *edit_window)
968 ModestMsgEditWindowPrivate *priv;
969 GString *string_buffer = g_string_new ("");
971 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
973 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
975 return g_string_free (string_buffer, FALSE);
980 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
983 const gchar *account_name;
984 ModestMsgEditWindowPrivate *priv;
986 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
988 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
990 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
991 g_return_val_if_fail (account_name, NULL);
994 /* don't free these (except from) */
995 data = g_slice_new0 (MsgData);
996 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
998 data->account_name = g_strdup (account_name);
999 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1000 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1001 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1002 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1003 if (priv->draft_msg) {
1004 data->draft_msg = g_object_ref (priv->draft_msg);
1006 data->draft_msg = NULL;
1009 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1011 gtk_text_buffer_get_bounds (buf, &b, &e);
1012 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1014 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1015 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1017 data->html_body = NULL;
1019 data->attachments = priv->attachments; /* TODO: copy and free ? */
1020 data->priority_flags = priv->priority_flags;
1025 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1027 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1030 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1038 g_free (data->subject);
1039 g_free (data->plain_body);
1040 g_free (data->html_body);
1041 if (data->draft_msg != NULL) {
1042 g_object_unref (data->draft_msg);
1043 data->draft_msg = NULL;
1045 g_free (data->account_name);
1047 /* TODO: Free data->attachments? */
1049 g_slice_free (MsgData, data);
1053 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1056 ModestMsgEditWindowPrivate *priv = NULL;
1057 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1059 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1061 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1063 return MODEST_MSG_EDIT_FORMAT_HTML;
1065 return MODEST_MSG_EDIT_FORMAT_TEXT;
1069 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1070 ModestMsgEditFormat format)
1072 ModestMsgEditWindowPrivate *priv;
1074 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1075 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1078 case MODEST_MSG_EDIT_FORMAT_HTML:
1079 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1081 case MODEST_MSG_EDIT_FORMAT_TEXT:
1082 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1085 g_return_if_reached ();
1089 ModestMsgEditFormatState *
1090 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1092 ModestMsgEditFormatState *format_state = NULL;
1093 ModestMsgEditWindowPrivate *priv;
1094 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1096 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1097 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1099 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1101 format_state = g_new0 (ModestMsgEditFormatState, 1);
1102 format_state->bold = buffer_format->bold&0x1;
1103 format_state->italics = buffer_format->italic&0x1;
1104 format_state->bullet = buffer_format->bullet&0x1;
1105 format_state->color = buffer_format->color;
1106 format_state->font_size = buffer_format->font_size;
1107 format_state->font_family = wp_get_font_name (buffer_format->font);
1108 format_state->justification = buffer_format->justification;
1109 g_free (buffer_format);
1111 return format_state;
1116 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1117 const ModestMsgEditFormatState *format_state)
1119 ModestMsgEditWindowPrivate *priv;
1120 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1121 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1122 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1123 g_return_if_fail (format_state != NULL);
1125 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1126 gtk_widget_grab_focus (priv->msg_body);
1127 buffer_format->bold = (format_state->bold != FALSE);
1128 buffer_format->italic = (format_state->italics != FALSE);
1129 buffer_format->color = format_state->color;
1130 buffer_format->font_size = format_state->font_size;
1131 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1132 buffer_format->justification = format_state->justification;
1133 buffer_format->bullet = format_state->bullet;
1135 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1137 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1138 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1139 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1140 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1141 buffer_format->cs.font = (buffer_format->font != current_format->font);
1142 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1143 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1145 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1146 if (buffer_format->cs.bold) {
1147 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1149 if (buffer_format->cs.italic) {
1150 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1152 if (buffer_format->cs.color) {
1153 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1155 if (buffer_format->cs.font_size) {
1156 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1158 if (buffer_format->cs.justification) {
1159 switch (buffer_format->justification) {
1160 case GTK_JUSTIFY_LEFT:
1161 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1163 case GTK_JUSTIFY_CENTER:
1164 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1166 case GTK_JUSTIFY_RIGHT:
1167 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1174 if (buffer_format->cs.font) {
1175 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1177 if (buffer_format->cs.bullet) {
1178 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1180 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1181 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1183 g_free (current_format);
1188 toggle_action_set_active_block_notify (GtkToggleAction *action,
1191 GSList *proxies = NULL;
1193 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1194 proxies != NULL; proxies = g_slist_next (proxies)) {
1195 GtkWidget *widget = (GtkWidget *) proxies->data;
1196 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1199 gtk_toggle_action_set_active (action, value);
1201 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1202 proxies != NULL; proxies = g_slist_next (proxies)) {
1203 GtkWidget *widget = (GtkWidget *) proxies->data;
1204 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1209 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1211 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1213 ModestWindowPrivate *parent_priv;
1214 ModestMsgEditWindowPrivate *priv;
1215 GtkWidget *new_size_menuitem;
1216 GtkWidget *new_font_menuitem;
1218 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1219 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1221 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1222 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1223 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1224 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1226 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1227 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1228 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1231 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1233 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1234 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1236 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1237 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1239 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1240 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1242 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1243 G_CALLBACK (modest_msg_edit_window_color_button_change),
1245 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1246 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1247 G_CALLBACK (modest_msg_edit_window_color_button_change),
1250 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1251 buffer_format->font_size))->data);
1252 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1256 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1257 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1258 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1260 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1261 G_CALLBACK (modest_msg_edit_window_size_change),
1263 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1264 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1265 G_CALLBACK (modest_msg_edit_window_size_change),
1269 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1270 buffer_format->font))->data);
1271 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1275 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1276 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1277 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1279 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1280 G_CALLBACK (modest_msg_edit_window_font_change),
1282 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1283 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1284 G_CALLBACK (modest_msg_edit_window_font_change),
1288 g_free (buffer_format);
1294 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1297 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1298 ModestMsgEditWindowPrivate *priv;
1299 GtkWidget *dialog = NULL;
1301 const GdkColor *new_color = NULL;
1303 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1304 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1306 #ifdef MODEST_HILDON_VERSION_0
1307 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1308 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1310 dialog = hildon_color_chooser_new ();
1311 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1312 #endif /*MODEST_HILDON_VERSION_0*/
1313 g_free (buffer_format);
1315 response = gtk_dialog_run (GTK_DIALOG (dialog));
1317 case GTK_RESPONSE_OK: {
1318 #ifdef MODEST_HILDON_VERSION_0
1319 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1322 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1324 #endif /*MODEST_HILDON_VERSION_0*/
1331 gtk_widget_destroy (dialog);
1333 if (new_color != NULL)
1334 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1339 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1342 ModestMsgEditWindowPrivate *priv;
1343 GtkWidget *dialog = NULL;
1345 GdkColor *old_color = NULL;
1346 const GdkColor *new_color = NULL;
1348 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1349 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1351 #ifdef MODEST_HILDON_VERSION_0
1352 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1353 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1355 dialog = hildon_color_chooser_new ();
1356 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1357 #endif /*MODEST_HILDON_VERSION_9*/
1359 response = gtk_dialog_run (GTK_DIALOG (dialog));
1361 case GTK_RESPONSE_OK: {
1362 #ifdef MODEST_HILDON_VERSION_0
1363 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1366 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1368 #endif /*MODEST_HILDON_VERSION_0*/
1374 gtk_widget_destroy (dialog);
1376 if (new_color != NULL)
1377 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1382 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1385 ModestMsgEditWindowPrivate *priv;
1386 GtkWidget *dialog = NULL;
1388 gchar *filename = NULL;
1390 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1392 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1394 response = gtk_dialog_run (GTK_DIALOG (dialog));
1396 case GTK_RESPONSE_OK:
1397 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1402 gtk_widget_destroy (dialog);
1405 GdkPixbuf *pixbuf = NULL;
1406 GtkTextIter position;
1407 GtkTextMark *insert_mark;
1409 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1412 GdkPixbufFormat *pixbuf_format;
1414 image_file_id = g_open (filename, O_RDONLY, 0);
1415 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1416 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1417 TnyMimePart *image_part;
1418 TnyStream *image_stream;
1424 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1425 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1426 mime_type = mime_types[0];
1428 mime_type = "image/unknown";
1430 image_part = tny_platform_factory_new_mime_part
1431 (modest_runtime_get_platform_factory ());
1432 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1434 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1435 g_strfreev (mime_types);
1437 content_id = g_strdup_printf ("%d", priv->last_cid);
1438 tny_mime_part_set_content_id (image_part, content_id);
1439 g_free (content_id);
1442 basename = g_path_get_basename (filename);
1443 tny_mime_part_set_filename (image_part, basename);
1446 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1447 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1448 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1449 priv->attachments = g_list_prepend (priv->attachments, image_part);
1450 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1452 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1453 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1454 gtk_widget_show_all (priv->attachments_caption);
1455 } else if (image_file_id == -1) {
1456 close (image_file_id);
1465 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1468 ModestMsgEditWindowPrivate *priv;
1469 GtkWidget *dialog = NULL;
1471 gchar *uri = NULL, *filename = NULL;
1473 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1475 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1477 response = gtk_dialog_run (GTK_DIALOG (dialog));
1479 case GTK_RESPONSE_OK:
1480 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1481 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1486 gtk_widget_destroy (dialog);
1490 GnomeVFSHandle *handle = NULL;
1491 GnomeVFSResult result;
1493 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1494 if (result == GNOME_VFS_OK) {
1495 TnyMimePart *mime_part;
1497 const gchar *mime_type = NULL;
1500 GnomeVFSFileInfo info;
1502 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1503 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1504 mime_part = tny_platform_factory_new_mime_part
1505 (modest_runtime_get_platform_factory ());
1506 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1508 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1510 content_id = g_strdup_printf ("%d", priv->last_cid);
1511 tny_mime_part_set_content_id (mime_part, content_id);
1512 g_free (content_id);
1515 basename = g_path_get_basename (filename);
1516 tny_mime_part_set_filename (mime_part, basename);
1519 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1520 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1522 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1523 gtk_widget_show_all (priv->attachments_caption);
1524 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1531 modest_msg_edit_window_attach_file_noninteractive (
1532 ModestMsgEditWindow *window,
1536 ModestMsgEditWindowPrivate *priv;
1538 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1543 file_id = g_open (filename, O_RDONLY, 0);
1544 if (file_id != -1) {
1545 TnyMimePart *mime_part;
1547 const gchar *mime_type;
1551 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1552 mime_part = tny_platform_factory_new_mime_part
1553 (modest_runtime_get_platform_factory ());
1554 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1556 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1558 content_id = g_strdup_printf ("%d", priv->last_cid);
1559 tny_mime_part_set_content_id (mime_part, content_id);
1560 g_free (content_id);
1563 basename = g_path_get_basename (filename);
1564 tny_mime_part_set_filename (mime_part, basename);
1567 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1568 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1570 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1571 gtk_widget_show_all (priv->attachments_caption);
1572 } else if (file_id == -1) {
1574 g_warning("file to be attached does not exist: %s", filename);
1580 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1583 ModestMsgEditWindowPrivate *priv;
1584 gboolean clean_list = FALSE;
1586 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1587 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1589 if (att_list == NULL) {
1590 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1594 if (att_list == NULL) {
1595 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1597 GtkWidget *confirmation_dialog = NULL;
1598 gboolean dialog_response;
1600 if (att_list->next == NULL) {
1601 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1602 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1603 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1606 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1608 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1609 gtk_widget_destroy (confirmation_dialog);
1610 if (!dialog_response) {
1612 g_list_free (att_list);
1615 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1617 for (node = att_list; node != NULL; node = g_list_next (node)) {
1618 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1619 const gchar *att_id;
1620 priv->attachments = g_list_remove (priv->attachments, mime_part);
1622 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1624 if (priv->attachments == NULL)
1625 gtk_widget_hide (priv->attachments_caption);
1626 att_id = tny_mime_part_get_content_id (mime_part);
1628 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1630 g_object_unref (mime_part);
1631 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1636 g_list_free (att_list);
1640 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1643 ModestMsgEditWindowPrivate *priv;
1644 GdkColor *new_color;
1645 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1647 #ifdef MODEST_HILDON_VERSION_0
1648 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1651 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1653 #endif /*MODEST_HILDON_VERSION_0*/
1655 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1657 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1662 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1665 ModestMsgEditWindowPrivate *priv;
1666 gint new_size_index;
1667 ModestMsgEditWindow *window;
1670 window = MODEST_MSG_EDIT_WINDOW (userdata);
1671 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1672 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1674 if (gtk_check_menu_item_get_active (menu_item)) {
1676 WPTextBufferFormat format;
1678 memset (&format, 0, sizeof (format));
1679 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1681 label = gtk_bin_get_child (GTK_BIN (menu_item));
1683 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1684 format.cs.font_size = TRUE;
1685 format.cs.text_position = TRUE;
1686 format.cs.font = TRUE;
1687 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1688 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1690 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1691 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1692 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1694 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1695 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1696 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1702 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1705 ModestMsgEditWindowPrivate *priv;
1706 gint new_font_index;
1707 ModestMsgEditWindow *window;
1710 window = MODEST_MSG_EDIT_WINDOW (userdata);
1711 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1712 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1714 if (gtk_check_menu_item_get_active (menu_item)) {
1717 label = gtk_bin_get_child (GTK_BIN (menu_item));
1719 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1721 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1722 (gpointer) new_font_index))
1723 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1725 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1726 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1727 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1733 modest_msg_edit_window_set_zoom (ModestWindow *window,
1736 ModestMsgEditWindowPrivate *priv;
1738 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1740 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1741 priv->zoom_level = zoom;
1742 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1746 modest_msg_edit_window_get_zoom (ModestWindow *window)
1748 ModestMsgEditWindowPrivate *priv;
1750 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1752 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1753 return priv->zoom_level;
1757 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1759 ModestWindowPrivate *parent_priv;
1760 GtkRadioAction *zoom_radio_action;
1761 GSList *group, *node;
1763 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1764 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1765 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1767 group = gtk_radio_action_get_group (zoom_radio_action);
1769 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1770 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1774 for (node = group; node != NULL; node = g_slist_next (node)) {
1775 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1776 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1784 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1786 ModestWindowPrivate *parent_priv;
1787 GtkRadioAction *zoom_radio_action;
1788 GSList *group, *node;
1790 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1791 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1792 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1794 group = gtk_radio_action_get_group (zoom_radio_action);
1796 for (node = group; node != NULL; node = g_slist_next (node)) {
1797 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1798 if (node->next != NULL) {
1799 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1802 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1810 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1812 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1813 ModestWindowPrivate *parent_priv;
1814 ModestWindowMgr *mgr;
1815 gboolean is_fullscreen;
1816 GtkAction *fs_toggle_action;
1819 mgr = modest_runtime_get_window_mgr ();
1820 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1822 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1824 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1825 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1826 if (is_fullscreen != active)
1827 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1835 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1837 ModestWindowPrivate *parent_priv;
1838 GtkAction *fs_toggle_action;
1841 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1843 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1844 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1845 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1849 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1852 ModestMsgEditWindowPrivate *priv = NULL;
1853 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1855 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1856 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1858 gtk_widget_show (priv->cc_caption);
1860 gtk_widget_hide (priv->cc_caption);
1861 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1865 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1868 ModestMsgEditWindowPrivate *priv = NULL;
1869 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1871 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1872 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1874 gtk_widget_show (priv->bcc_caption);
1876 gtk_widget_hide (priv->bcc_caption);
1877 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1881 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1882 ModestRecptEditor *editor)
1884 ModestMsgEditWindowPrivate *priv;
1886 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1887 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1888 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1890 if (editor == NULL) {
1891 GtkWidget *view_focus;
1892 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1894 /* This code should be kept in sync with ModestRecptEditor. The
1895 textview inside the recpt editor is the one that really gets the
1896 focus. As it's inside a scrolled window, and this one inside the
1897 hbox recpt editor inherits from, we'll need to go up in the
1898 hierarchy to know if the text view is part of the recpt editor
1899 or if it's a different text entry */
1901 if (gtk_widget_get_parent (view_focus)) {
1902 GtkWidget *first_parent;
1904 first_parent = gtk_widget_get_parent (view_focus);
1905 if (gtk_widget_get_parent (first_parent) &&
1906 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1907 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1912 editor = MODEST_RECPT_EDITOR (priv->to_field);
1916 modest_address_book_select_addresses (editor);
1921 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1923 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1925 modest_msg_edit_window_open_addressbook (window, NULL);
1929 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1930 gboolean show_toolbar)
1932 ModestWindowPrivate *parent_priv;
1934 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1935 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1937 /* FIXME: we can not just use the code of
1938 modest_msg_edit_window_setup_toolbar because it has a
1939 mixture of both initialization and creation code. */
1942 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1944 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1948 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1949 TnyHeaderFlags priority_flags)
1951 ModestMsgEditWindowPrivate *priv;
1953 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1955 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1956 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1958 if (priv->priority_flags != priority_flags) {
1960 priv->priority_flags = priority_flags;
1962 switch (priority_flags) {
1963 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1964 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1965 gtk_widget_show (priv->priority_icon);
1967 case TNY_HEADER_FLAG_LOW_PRIORITY:
1968 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1969 gtk_widget_show (priv->priority_icon);
1972 gtk_widget_hide (priv->priority_icon);
1979 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1982 ModestMsgEditWindowPrivate *priv;
1983 gint current_format;
1985 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1987 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1989 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1990 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1992 if (current_format != file_format) {
1993 switch (file_format) {
1994 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1995 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1997 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2001 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2002 response = gtk_dialog_run (GTK_DIALOG (dialog));
2003 gtk_widget_destroy (dialog);
2004 if (response == GTK_RESPONSE_OK)
2005 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2009 update_dimmed (window);
2014 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2017 ModestMsgEditWindowPrivate *priv;
2018 WPTextBufferFormat oldfmt, fmt;
2019 gint old_position = 0;
2023 GdkColor *color = NULL;
2024 gboolean bold, bold_set, italic, italic_set;
2025 gboolean underline, underline_set;
2026 gboolean strikethrough, strikethrough_set;
2027 gboolean position_set;
2028 gboolean font_size_set, font_set, color_set;
2031 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2032 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2034 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2036 /* First we get the currently selected font information */
2037 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2038 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2040 switch (oldfmt.text_position) {
2041 case TEXT_POSITION_NORMAL:
2044 case TEXT_POSITION_SUPERSCRIPT:
2052 g_object_set (G_OBJECT (dialog),
2053 "bold", oldfmt.bold != FALSE,
2054 "bold-set", !oldfmt.cs.bold,
2055 "underline", oldfmt.underline != FALSE,
2056 "underline-set", !oldfmt.cs.underline,
2057 "italic", oldfmt.italic != FALSE,
2058 "italic-set", !oldfmt.cs.italic,
2059 "strikethrough", oldfmt.strikethrough != FALSE,
2060 "strikethrough-set", !oldfmt.cs.strikethrough,
2061 "color", &oldfmt.color,
2062 "color-set", !oldfmt.cs.color,
2063 "size", wp_font_size[oldfmt.font_size],
2064 "size-set", !oldfmt.cs.font_size,
2065 "position", old_position,
2066 "position-set", !oldfmt.cs.text_position,
2067 "family", wp_get_font_name (oldfmt.font),
2068 "family-set", !oldfmt.cs.font,
2071 gtk_widget_show_all (dialog);
2072 response = gtk_dialog_run (GTK_DIALOG (dialog));
2073 if (response == GTK_RESPONSE_OK) {
2075 g_object_get( dialog,
2077 "bold-set", &bold_set,
2078 "underline", &underline,
2079 "underline-set", &underline_set,
2081 "italic-set", &italic_set,
2082 "strikethrough", &strikethrough,
2083 "strikethrough-set", &strikethrough_set,
2085 "color-set", &color_set,
2087 "size-set", &font_size_set,
2088 "family", &font_name,
2089 "family-set", &font_set,
2090 "position", &position,
2091 "position-set", &position_set,
2096 if (response == GTK_RESPONSE_OK) {
2097 memset(&fmt, 0, sizeof(fmt));
2103 fmt.italic = italic;
2104 fmt.cs.italic = TRUE;
2106 if (underline_set) {
2107 fmt.underline = underline;
2108 fmt.cs.underline = TRUE;
2110 if (strikethrough_set) {
2111 fmt.strikethrough = strikethrough;
2112 fmt.cs.strikethrough = TRUE;
2117 ? TEXT_POSITION_NORMAL
2118 : ( ( position == 1 )
2119 ? TEXT_POSITION_SUPERSCRIPT
2120 : TEXT_POSITION_SUBSCRIPT );
2121 fmt.cs.text_position = TRUE;
2125 fmt.cs.color = TRUE;
2128 fmt.font = wp_get_font_index(font_name,
2133 if (font_size_set) {
2134 fmt.font_size = wp_get_font_size_index(
2135 font_size, DEFAULT_FONT_SIZE);
2136 fmt.cs.font_size = TRUE;
2138 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2140 gtk_widget_destroy (dialog);
2142 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2146 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2148 ModestMsgEditWindowPrivate *priv;
2150 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2151 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2153 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2155 update_dimmed (window);
2160 update_dimmed (ModestMsgEditWindow *window)
2162 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2163 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2167 gboolean editor_focused;
2169 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2170 editor_focused = gtk_widget_is_focus (priv->msg_body);
2172 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2173 gtk_action_set_sensitive (action, rich_text && editor_focused);
2174 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2175 gtk_action_set_sensitive (action, rich_text && editor_focused);
2176 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2177 gtk_action_set_sensitive (action, rich_text && editor_focused);
2178 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2179 gtk_action_set_sensitive (action, rich_text && editor_focused);
2180 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2181 gtk_action_set_sensitive (action, rich_text && editor_focused);
2182 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2183 gtk_action_set_sensitive (action, rich_text && editor_focused);
2184 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2185 gtk_action_set_sensitive (action, rich_text && editor_focused);
2186 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2187 gtk_action_set_sensitive (action, rich_text && editor_focused);
2188 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2189 gtk_action_set_sensitive (action, rich_text && editor_focused);
2190 widget = priv->font_color_button;
2191 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2192 widget = priv->font_size_toolitem;
2193 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2194 widget = priv->font_face_toolitem;
2195 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2199 setup_insensitive_handlers (ModestMsgEditWindow *window)
2201 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2202 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2205 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2206 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2207 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2208 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2210 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2211 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2212 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2213 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2214 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2215 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2216 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2217 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2218 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2219 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2220 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2221 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2222 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2223 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2224 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2225 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2226 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2227 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2228 widget = priv->font_color_button;
2229 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2230 widget = priv->font_size_toolitem;
2231 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2232 widget = priv->font_face_toolitem;
2233 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2238 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2240 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2243 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2244 gtk_action_set_sensitive (action, can_undo);
2248 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2251 GtkTextIter match_start, match_end;
2253 if (image_id == NULL)
2256 gtk_text_buffer_get_start_iter (buffer, &iter);
2258 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2259 GSList *tags = gtk_text_iter_get_tags (&match_start);
2261 for (node = tags; node != NULL; node = g_slist_next (node)) {
2262 GtkTextTag *tag = (GtkTextTag *) node->data;
2263 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2264 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2265 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2267 offset = gtk_text_iter_get_offset (&match_start);
2268 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2269 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2273 gtk_text_iter_forward_char (&iter);
2278 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2280 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2281 GtkTextIter real_start, real_end;
2282 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2284 if (gtk_text_iter_compare (start, end) > 0) {
2288 real_start = *start;
2292 GSList *tags = gtk_text_iter_get_tags (&real_start);
2294 for (node = tags; node != NULL; node = g_slist_next (node)) {
2295 GtkTextTag *tag = (GtkTextTag *) node->data;
2296 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2297 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2299 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2301 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2304 } while (gtk_text_iter_forward_char (&real_start)&&
2305 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2309 msg_body_focus (GtkWidget *focus,
2310 GdkEventFocus *event,
2314 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2319 recpt_field_changed (GtkTextBuffer *buffer,
2320 ModestMsgEditWindow *editor)
2322 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2323 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2324 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2325 gboolean dim = FALSE;
2328 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2329 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2330 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2332 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2333 gtk_text_buffer_get_char_count (cc_buffer) +
2334 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2336 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2337 gtk_action_set_sensitive (action, !dim);
2338 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2339 gtk_action_set_sensitive (action, !dim);
2343 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2345 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2349 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2351 gboolean rich_text, editor_focused;
2353 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2354 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2355 editor_focused = gtk_widget_is_focus (priv->msg_body);
2358 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2359 else if (!editor_focused)
2360 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2364 reset_modified (ModestMsgEditWindow *editor)
2366 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2367 GtkTextBuffer *buffer;
2369 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2370 gtk_text_buffer_set_modified (buffer, FALSE);
2371 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2372 gtk_text_buffer_set_modified (buffer, FALSE);
2373 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2374 gtk_text_buffer_set_modified (buffer, FALSE);
2375 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2379 is_modified (ModestMsgEditWindow *editor)
2381 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2382 GtkTextBuffer *buffer;
2384 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2385 if (gtk_text_buffer_get_modified (buffer))
2387 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2388 if (gtk_text_buffer_get_modified (buffer))
2390 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2391 if (gtk_text_buffer_get_modified (buffer))
2393 if (gtk_text_buffer_get_modified (priv->text_buffer))
2400 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2402 ModestMsgEditWindowPrivate *priv = NULL;
2404 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2405 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2407 /* check if there's no recipient added */
2408 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2409 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2410 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2411 /* no recipient contents, then select contacts */
2412 modest_msg_edit_window_open_addressbook (window, NULL);
2416 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2418 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2420 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2423 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2430 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2431 ModestMsgEditWindow *window)
2433 modest_msg_edit_window_attach_file (window);
2437 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2439 ModestMsgEditWindow *window)
2441 ModestWindowPrivate *parent_priv;
2446 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2447 selection = gtk_clipboard_wait_for_text (clipboard);
2448 focused = gtk_window_get_focus (GTK_WINDOW (window));
2450 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2451 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2452 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2453 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2457 update_window_title (ModestMsgEditWindow *window)
2459 ModestMsgEditWindowPrivate *priv = NULL;
2460 const gchar *subject;
2462 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2463 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2464 if (subject == NULL || subject[0] == '\0')
2465 subject = _("mail_va_new_email");
2467 gtk_window_set_title (GTK_WINDOW (window), subject);
2472 subject_field_changed (GtkEditable *editable,
2473 ModestMsgEditWindow *window)
2475 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2476 update_window_title (window);
2477 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2481 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2484 ModestMsgEditWindowPrivate *priv = NULL;
2486 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2487 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2489 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2491 gtk_widget_show_all (priv->find_toolbar);
2492 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2494 gtk_widget_hide_all (priv->find_toolbar);
2495 gtk_widget_grab_focus (priv->msg_body);
2501 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2502 ModestMsgEditWindow *window)
2504 gchar *current_search = NULL;
2505 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2507 GtkTextIter selection_start, selection_end;
2508 GtkTextIter match_start, match_end;
2510 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2511 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2512 g_free (current_search);
2516 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2517 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2519 GtkTextIter buffer_start;
2520 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2521 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2524 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2525 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2527 /* TODO: warning about non succesful search */
2529 g_free (current_search);
2533 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2534 ModestMsgEditWindow *window)
2536 GtkToggleAction *toggle;
2537 ModestWindowPrivate *parent_priv;
2538 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2540 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2541 gtk_toggle_action_set_active (toggle, FALSE);