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);
837 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
839 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
840 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
842 parent_priv->ui_manager = gtk_ui_manager_new();
843 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
844 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
846 /* Add common actions */
847 gtk_action_group_add_actions (action_group,
848 modest_msg_edit_action_entries,
849 G_N_ELEMENTS (modest_msg_edit_action_entries),
851 gtk_action_group_add_toggle_actions (action_group,
852 modest_msg_edit_toggle_action_entries,
853 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
855 gtk_action_group_add_radio_actions (action_group,
856 modest_msg_edit_alignment_radio_action_entries,
857 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
859 G_CALLBACK (modest_ui_actions_on_change_justify),
861 gtk_action_group_add_radio_actions (action_group,
862 modest_msg_edit_zoom_action_entries,
863 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
865 G_CALLBACK (modest_ui_actions_on_change_zoom),
867 gtk_action_group_add_radio_actions (action_group,
868 modest_msg_edit_priority_action_entries,
869 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
871 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
873 gtk_action_group_add_radio_actions (action_group,
874 modest_msg_edit_file_format_action_entries,
875 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
876 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
877 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
879 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
880 g_object_unref (action_group);
882 /* Load the UI definition */
883 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
885 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
886 g_clear_error (&error);
889 /* Add accelerators */
890 gtk_window_add_accel_group (GTK_WINDOW (obj),
891 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
894 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
895 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
898 init_window (MODEST_MSG_EDIT_WINDOW(obj));
900 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
902 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
904 g_signal_connect (G_OBJECT(obj), "delete-event",
905 G_CALLBACK(on_delete_event), obj);
907 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
909 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
911 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
913 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
915 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
917 /* Set window icon */
918 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
919 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
921 /* Dim at start clipboard actions */
922 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
923 gtk_action_set_sensitive (action, FALSE);
924 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
925 gtk_action_set_sensitive (action, FALSE);
927 /* set initial state of cc and bcc */
928 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
929 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
930 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
931 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
932 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
933 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
935 /* Setup the file format */
936 conf = modest_runtime_get_conf ();
937 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
939 g_clear_error (&error);
940 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
942 file_format = (prefer_formatted) ?
943 MODEST_FILE_FORMAT_FORMATTED_TEXT :
944 MODEST_FILE_FORMAT_PLAIN_TEXT;
945 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
947 return (ModestWindow*) obj;
951 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
953 GString **string_buffer = (GString **) user_data;
955 *string_buffer = g_string_append (*string_buffer, buffer);
961 * @result: A new string which should be freed with g_free().
964 get_formatted_data (ModestMsgEditWindow *edit_window)
966 ModestMsgEditWindowPrivate *priv;
967 GString *string_buffer = g_string_new ("");
969 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
971 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
973 return g_string_free (string_buffer, FALSE);
978 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
981 const gchar *account_name;
982 ModestMsgEditWindowPrivate *priv;
984 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
986 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
988 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
989 g_return_val_if_fail (account_name, NULL);
992 /* don't free these (except from) */
993 data = g_slice_new0 (MsgData);
994 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
996 data->account_name = g_strdup (account_name);
997 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
998 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
999 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1000 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1001 if (priv->draft_msg) {
1002 data->draft_msg = g_object_ref (priv->draft_msg);
1004 data->draft_msg = NULL;
1007 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1009 gtk_text_buffer_get_bounds (buf, &b, &e);
1010 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1012 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1013 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1015 data->html_body = NULL;
1017 data->attachments = priv->attachments; /* TODO: copy and free ? */
1018 data->priority_flags = priv->priority_flags;
1023 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1025 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1028 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1036 g_free (data->subject);
1037 g_free (data->plain_body);
1038 g_free (data->html_body);
1039 if (data->draft_msg != NULL) {
1040 g_object_unref (data->draft_msg);
1041 data->draft_msg = NULL;
1043 g_free (data->account_name);
1045 /* TODO: Free data->attachments? */
1047 g_slice_free (MsgData, data);
1051 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1054 ModestMsgEditWindowPrivate *priv = NULL;
1055 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1057 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1059 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1061 return MODEST_MSG_EDIT_FORMAT_HTML;
1063 return MODEST_MSG_EDIT_FORMAT_TEXT;
1067 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1068 ModestMsgEditFormat format)
1070 ModestMsgEditWindowPrivate *priv;
1072 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1073 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1076 case MODEST_MSG_EDIT_FORMAT_HTML:
1077 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1079 case MODEST_MSG_EDIT_FORMAT_TEXT:
1080 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1083 g_return_if_reached ();
1087 ModestMsgEditFormatState *
1088 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1090 ModestMsgEditFormatState *format_state = NULL;
1091 ModestMsgEditWindowPrivate *priv;
1092 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1094 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1095 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1097 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1099 format_state = g_new0 (ModestMsgEditFormatState, 1);
1100 format_state->bold = buffer_format->bold&0x1;
1101 format_state->italics = buffer_format->italic&0x1;
1102 format_state->bullet = buffer_format->bullet&0x1;
1103 format_state->color = buffer_format->color;
1104 format_state->font_size = buffer_format->font_size;
1105 format_state->font_family = wp_get_font_name (buffer_format->font);
1106 format_state->justification = buffer_format->justification;
1107 g_free (buffer_format);
1109 return format_state;
1114 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1115 const ModestMsgEditFormatState *format_state)
1117 ModestMsgEditWindowPrivate *priv;
1118 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1119 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1120 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1121 g_return_if_fail (format_state != NULL);
1123 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1124 gtk_widget_grab_focus (priv->msg_body);
1125 buffer_format->bold = (format_state->bold != FALSE);
1126 buffer_format->italic = (format_state->italics != FALSE);
1127 buffer_format->color = format_state->color;
1128 buffer_format->font_size = format_state->font_size;
1129 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1130 buffer_format->justification = format_state->justification;
1131 buffer_format->bullet = format_state->bullet;
1133 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1135 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1136 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1137 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1138 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1139 buffer_format->cs.font = (buffer_format->font != current_format->font);
1140 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1141 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1143 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1144 if (buffer_format->cs.bold) {
1145 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1147 if (buffer_format->cs.italic) {
1148 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1150 if (buffer_format->cs.color) {
1151 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1153 if (buffer_format->cs.font_size) {
1154 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1156 if (buffer_format->cs.justification) {
1157 switch (buffer_format->justification) {
1158 case GTK_JUSTIFY_LEFT:
1159 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1161 case GTK_JUSTIFY_CENTER:
1162 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1164 case GTK_JUSTIFY_RIGHT:
1165 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1172 if (buffer_format->cs.font) {
1173 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1175 if (buffer_format->cs.bullet) {
1176 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1178 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1179 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1181 g_free (current_format);
1186 toggle_action_set_active_block_notify (GtkToggleAction *action,
1189 GSList *proxies = NULL;
1191 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1192 proxies != NULL; proxies = g_slist_next (proxies)) {
1193 GtkWidget *widget = (GtkWidget *) proxies->data;
1194 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1197 gtk_toggle_action_set_active (action, value);
1199 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1200 proxies != NULL; proxies = g_slist_next (proxies)) {
1201 GtkWidget *widget = (GtkWidget *) proxies->data;
1202 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1207 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1209 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1211 ModestWindowPrivate *parent_priv;
1212 ModestMsgEditWindowPrivate *priv;
1213 GtkWidget *new_size_menuitem;
1214 GtkWidget *new_font_menuitem;
1216 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1217 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1219 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1220 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1221 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1222 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1224 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1225 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1226 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1229 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1231 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1232 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1234 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1235 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1237 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1238 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1240 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1241 G_CALLBACK (modest_msg_edit_window_color_button_change),
1243 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1244 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1245 G_CALLBACK (modest_msg_edit_window_color_button_change),
1248 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1249 buffer_format->font_size))->data);
1250 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1254 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1255 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1256 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1258 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1259 G_CALLBACK (modest_msg_edit_window_size_change),
1261 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1262 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1263 G_CALLBACK (modest_msg_edit_window_size_change),
1267 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1268 buffer_format->font))->data);
1269 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1273 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1274 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1275 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1277 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1278 G_CALLBACK (modest_msg_edit_window_font_change),
1280 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1281 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1282 G_CALLBACK (modest_msg_edit_window_font_change),
1286 g_free (buffer_format);
1292 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1295 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1296 ModestMsgEditWindowPrivate *priv;
1297 GtkWidget *dialog = NULL;
1299 const GdkColor *new_color = NULL;
1301 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1302 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1304 #ifdef MODEST_HILDON_VERSION_0
1305 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1306 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1308 dialog = hildon_color_chooser_new ();
1309 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1310 #endif /*MODEST_HILDON_VERSION_0*/
1311 g_free (buffer_format);
1313 response = gtk_dialog_run (GTK_DIALOG (dialog));
1315 case GTK_RESPONSE_OK: {
1316 #ifdef MODEST_HILDON_VERSION_0
1317 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1320 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1322 #endif /*MODEST_HILDON_VERSION_0*/
1329 gtk_widget_destroy (dialog);
1331 if (new_color != NULL)
1332 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1337 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1340 ModestMsgEditWindowPrivate *priv;
1341 GtkWidget *dialog = NULL;
1343 GdkColor *old_color = NULL;
1344 const GdkColor *new_color = NULL;
1346 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1347 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1349 #ifdef MODEST_HILDON_VERSION_0
1350 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1351 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1353 dialog = hildon_color_chooser_new ();
1354 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1355 #endif /*MODEST_HILDON_VERSION_9*/
1357 response = gtk_dialog_run (GTK_DIALOG (dialog));
1359 case GTK_RESPONSE_OK: {
1360 #ifdef MODEST_HILDON_VERSION_0
1361 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1364 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1366 #endif /*MODEST_HILDON_VERSION_0*/
1372 gtk_widget_destroy (dialog);
1374 if (new_color != NULL)
1375 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1380 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1383 ModestMsgEditWindowPrivate *priv;
1384 GtkWidget *dialog = NULL;
1386 gchar *filename = NULL;
1388 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1390 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1392 response = gtk_dialog_run (GTK_DIALOG (dialog));
1394 case GTK_RESPONSE_OK:
1395 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1400 gtk_widget_destroy (dialog);
1403 GdkPixbuf *pixbuf = NULL;
1404 GtkTextIter position;
1405 GtkTextMark *insert_mark;
1407 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1410 GdkPixbufFormat *pixbuf_format;
1412 image_file_id = g_open (filename, O_RDONLY, 0);
1413 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1414 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1415 TnyMimePart *image_part;
1416 TnyStream *image_stream;
1422 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1423 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1424 mime_type = mime_types[0];
1426 mime_type = "image/unknown";
1428 image_part = tny_platform_factory_new_mime_part
1429 (modest_runtime_get_platform_factory ());
1430 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1432 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1433 g_strfreev (mime_types);
1435 content_id = g_strdup_printf ("%d", priv->last_cid);
1436 tny_mime_part_set_content_id (image_part, content_id);
1437 g_free (content_id);
1440 basename = g_path_get_basename (filename);
1441 tny_mime_part_set_filename (image_part, basename);
1444 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1445 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1446 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1447 priv->attachments = g_list_prepend (priv->attachments, image_part);
1448 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1450 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1451 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1452 gtk_widget_show_all (priv->attachments_caption);
1453 } else if (image_file_id == -1) {
1454 close (image_file_id);
1463 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1466 ModestMsgEditWindowPrivate *priv;
1467 GtkWidget *dialog = NULL;
1469 gchar *uri = NULL, *filename = NULL;
1471 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1473 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1475 response = gtk_dialog_run (GTK_DIALOG (dialog));
1477 case GTK_RESPONSE_OK:
1478 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1479 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1484 gtk_widget_destroy (dialog);
1488 GnomeVFSHandle *handle = NULL;
1489 GnomeVFSResult result;
1491 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1492 if (result == GNOME_VFS_OK) {
1493 TnyMimePart *mime_part;
1495 const gchar *mime_type = NULL;
1498 GnomeVFSFileInfo info;
1500 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1501 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1502 mime_part = tny_platform_factory_new_mime_part
1503 (modest_runtime_get_platform_factory ());
1504 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1506 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1508 content_id = g_strdup_printf ("%d", priv->last_cid);
1509 tny_mime_part_set_content_id (mime_part, content_id);
1510 g_free (content_id);
1513 basename = g_path_get_basename (filename);
1514 tny_mime_part_set_filename (mime_part, basename);
1517 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1518 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1520 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1521 gtk_widget_show_all (priv->attachments_caption);
1522 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1529 modest_msg_edit_window_attach_file_noninteractive (
1530 ModestMsgEditWindow *window,
1534 ModestMsgEditWindowPrivate *priv;
1536 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1541 file_id = g_open (filename, O_RDONLY, 0);
1542 if (file_id != -1) {
1543 TnyMimePart *mime_part;
1545 const gchar *mime_type;
1549 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1550 mime_part = tny_platform_factory_new_mime_part
1551 (modest_runtime_get_platform_factory ());
1552 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1554 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1556 content_id = g_strdup_printf ("%d", priv->last_cid);
1557 tny_mime_part_set_content_id (mime_part, content_id);
1558 g_free (content_id);
1561 basename = g_path_get_basename (filename);
1562 tny_mime_part_set_filename (mime_part, basename);
1565 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1566 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1568 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1569 gtk_widget_show_all (priv->attachments_caption);
1570 } else if (file_id == -1) {
1572 g_warning("file to be attached does not exist: %s", filename);
1578 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1581 ModestMsgEditWindowPrivate *priv;
1582 gboolean clean_list = FALSE;
1584 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1585 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1587 if (att_list == NULL) {
1588 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1592 if (att_list == NULL) {
1593 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1595 GtkWidget *confirmation_dialog = NULL;
1596 gboolean dialog_response;
1598 if (att_list->next == NULL) {
1599 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1600 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1601 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1604 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1606 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1607 gtk_widget_destroy (confirmation_dialog);
1608 if (!dialog_response) {
1610 g_list_free (att_list);
1613 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1615 for (node = att_list; node != NULL; node = g_list_next (node)) {
1616 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1617 const gchar *att_id;
1618 priv->attachments = g_list_remove (priv->attachments, mime_part);
1620 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1622 if (priv->attachments == NULL)
1623 gtk_widget_hide (priv->attachments_caption);
1624 att_id = tny_mime_part_get_content_id (mime_part);
1626 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1628 g_object_unref (mime_part);
1629 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1634 g_list_free (att_list);
1638 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1641 ModestMsgEditWindowPrivate *priv;
1642 GdkColor *new_color;
1643 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1645 #ifdef MODEST_HILDON_VERSION_0
1646 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1649 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1651 #endif /*MODEST_HILDON_VERSION_0*/
1653 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1655 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1660 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1663 ModestMsgEditWindowPrivate *priv;
1664 gint new_size_index;
1665 ModestMsgEditWindow *window;
1668 window = MODEST_MSG_EDIT_WINDOW (userdata);
1669 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1670 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1672 if (gtk_check_menu_item_get_active (menu_item)) {
1674 WPTextBufferFormat format;
1676 memset (&format, 0, sizeof (format));
1677 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1679 label = gtk_bin_get_child (GTK_BIN (menu_item));
1681 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1682 format.cs.font_size = TRUE;
1683 format.cs.text_position = TRUE;
1684 format.cs.font = TRUE;
1685 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1686 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1688 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1689 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1690 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1692 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1693 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1694 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1700 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1703 ModestMsgEditWindowPrivate *priv;
1704 gint new_font_index;
1705 ModestMsgEditWindow *window;
1708 window = MODEST_MSG_EDIT_WINDOW (userdata);
1709 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1710 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1712 if (gtk_check_menu_item_get_active (menu_item)) {
1715 label = gtk_bin_get_child (GTK_BIN (menu_item));
1717 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1719 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1720 (gpointer) new_font_index))
1721 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1723 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1724 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1725 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1731 modest_msg_edit_window_set_zoom (ModestWindow *window,
1734 ModestMsgEditWindowPrivate *priv;
1736 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1738 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1739 priv->zoom_level = zoom;
1740 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1744 modest_msg_edit_window_get_zoom (ModestWindow *window)
1746 ModestMsgEditWindowPrivate *priv;
1748 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1750 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1751 return priv->zoom_level;
1755 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1757 ModestWindowPrivate *parent_priv;
1758 GtkRadioAction *zoom_radio_action;
1759 GSList *group, *node;
1761 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1762 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1763 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1765 group = gtk_radio_action_get_group (zoom_radio_action);
1767 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1768 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1772 for (node = group; node != NULL; node = g_slist_next (node)) {
1773 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1774 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1782 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1784 ModestWindowPrivate *parent_priv;
1785 GtkRadioAction *zoom_radio_action;
1786 GSList *group, *node;
1788 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1789 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1790 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1792 group = gtk_radio_action_get_group (zoom_radio_action);
1794 for (node = group; node != NULL; node = g_slist_next (node)) {
1795 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1796 if (node->next != NULL) {
1797 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1800 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1808 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1810 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1811 ModestWindowPrivate *parent_priv;
1812 ModestWindowMgr *mgr;
1813 gboolean is_fullscreen;
1814 GtkAction *fs_toggle_action;
1817 mgr = modest_runtime_get_window_mgr ();
1818 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1820 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1822 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1823 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1824 if (is_fullscreen != active)
1825 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1833 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1835 ModestWindowPrivate *parent_priv;
1836 GtkAction *fs_toggle_action;
1839 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1841 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1842 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1843 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1847 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1850 ModestMsgEditWindowPrivate *priv = NULL;
1851 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1853 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1854 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1856 gtk_widget_show (priv->cc_caption);
1858 gtk_widget_hide (priv->cc_caption);
1859 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1863 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1866 ModestMsgEditWindowPrivate *priv = NULL;
1867 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1869 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1870 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1872 gtk_widget_show (priv->bcc_caption);
1874 gtk_widget_hide (priv->bcc_caption);
1875 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1879 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1880 ModestRecptEditor *editor)
1882 ModestMsgEditWindowPrivate *priv;
1884 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1885 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1886 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1888 if (editor == NULL) {
1889 GtkWidget *view_focus;
1890 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1892 /* This code should be kept in sync with ModestRecptEditor. The
1893 textview inside the recpt editor is the one that really gets the
1894 focus. As it's inside a scrolled window, and this one inside the
1895 hbox recpt editor inherits from, we'll need to go up in the
1896 hierarchy to know if the text view is part of the recpt editor
1897 or if it's a different text entry */
1899 if (gtk_widget_get_parent (view_focus)) {
1900 GtkWidget *first_parent;
1902 first_parent = gtk_widget_get_parent (view_focus);
1903 if (gtk_widget_get_parent (first_parent) &&
1904 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1905 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1910 editor = MODEST_RECPT_EDITOR (priv->to_field);
1914 modest_address_book_select_addresses (editor);
1919 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1921 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1923 modest_msg_edit_window_open_addressbook (window, NULL);
1927 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1928 gboolean show_toolbar)
1930 ModestWindowPrivate *parent_priv;
1932 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1933 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1935 /* FIXME: we can not just use the code of
1936 modest_msg_edit_window_setup_toolbar because it has a
1937 mixture of both initialization and creation code. */
1940 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1942 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1946 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1947 TnyHeaderFlags priority_flags)
1949 ModestMsgEditWindowPrivate *priv;
1951 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1953 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1954 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1956 if (priv->priority_flags != priority_flags) {
1958 priv->priority_flags = priority_flags;
1960 switch (priority_flags) {
1961 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1962 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1963 gtk_widget_show (priv->priority_icon);
1965 case TNY_HEADER_FLAG_LOW_PRIORITY:
1966 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1967 gtk_widget_show (priv->priority_icon);
1970 gtk_widget_hide (priv->priority_icon);
1977 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1980 ModestMsgEditWindowPrivate *priv;
1981 gint current_format;
1983 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1985 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1987 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1988 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1990 if (current_format != file_format) {
1991 switch (file_format) {
1992 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1993 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1995 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1999 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2000 response = gtk_dialog_run (GTK_DIALOG (dialog));
2001 gtk_widget_destroy (dialog);
2002 if (response == GTK_RESPONSE_OK)
2003 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2007 update_dimmed (window);
2012 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2015 ModestMsgEditWindowPrivate *priv;
2016 WPTextBufferFormat oldfmt, fmt;
2017 gint old_position = 0;
2021 GdkColor *color = NULL;
2022 gboolean bold, bold_set, italic, italic_set;
2023 gboolean underline, underline_set;
2024 gboolean strikethrough, strikethrough_set;
2025 gboolean position_set;
2026 gboolean font_size_set, font_set, color_set;
2029 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2030 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2032 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2034 /* First we get the currently selected font information */
2035 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2036 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2038 switch (oldfmt.text_position) {
2039 case TEXT_POSITION_NORMAL:
2042 case TEXT_POSITION_SUPERSCRIPT:
2050 g_object_set (G_OBJECT (dialog),
2051 "bold", oldfmt.bold != FALSE,
2052 "bold-set", !oldfmt.cs.bold,
2053 "underline", oldfmt.underline != FALSE,
2054 "underline-set", !oldfmt.cs.underline,
2055 "italic", oldfmt.italic != FALSE,
2056 "italic-set", !oldfmt.cs.italic,
2057 "strikethrough", oldfmt.strikethrough != FALSE,
2058 "strikethrough-set", !oldfmt.cs.strikethrough,
2059 "color", &oldfmt.color,
2060 "color-set", !oldfmt.cs.color,
2061 "size", wp_font_size[oldfmt.font_size],
2062 "size-set", !oldfmt.cs.font_size,
2063 "position", old_position,
2064 "position-set", !oldfmt.cs.text_position,
2065 "family", wp_get_font_name (oldfmt.font),
2066 "family-set", !oldfmt.cs.font,
2069 gtk_widget_show_all (dialog);
2070 response = gtk_dialog_run (GTK_DIALOG (dialog));
2071 if (response == GTK_RESPONSE_OK) {
2073 g_object_get( dialog,
2075 "bold-set", &bold_set,
2076 "underline", &underline,
2077 "underline-set", &underline_set,
2079 "italic-set", &italic_set,
2080 "strikethrough", &strikethrough,
2081 "strikethrough-set", &strikethrough_set,
2083 "color-set", &color_set,
2085 "size-set", &font_size_set,
2086 "family", &font_name,
2087 "family-set", &font_set,
2088 "position", &position,
2089 "position-set", &position_set,
2094 if (response == GTK_RESPONSE_OK) {
2095 memset(&fmt, 0, sizeof(fmt));
2101 fmt.italic = italic;
2102 fmt.cs.italic = TRUE;
2104 if (underline_set) {
2105 fmt.underline = underline;
2106 fmt.cs.underline = TRUE;
2108 if (strikethrough_set) {
2109 fmt.strikethrough = strikethrough;
2110 fmt.cs.strikethrough = TRUE;
2115 ? TEXT_POSITION_NORMAL
2116 : ( ( position == 1 )
2117 ? TEXT_POSITION_SUPERSCRIPT
2118 : TEXT_POSITION_SUBSCRIPT );
2119 fmt.cs.text_position = TRUE;
2123 fmt.cs.color = TRUE;
2126 fmt.font = wp_get_font_index(font_name,
2131 if (font_size_set) {
2132 fmt.font_size = wp_get_font_size_index(
2133 font_size, DEFAULT_FONT_SIZE);
2134 fmt.cs.font_size = TRUE;
2136 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2138 gtk_widget_destroy (dialog);
2140 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2144 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2146 ModestMsgEditWindowPrivate *priv;
2148 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2149 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2151 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2153 update_dimmed (window);
2158 update_dimmed (ModestMsgEditWindow *window)
2160 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2161 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2165 gboolean editor_focused;
2167 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2168 editor_focused = gtk_widget_is_focus (priv->msg_body);
2170 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2171 gtk_action_set_sensitive (action, rich_text && editor_focused);
2172 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2173 gtk_action_set_sensitive (action, rich_text && editor_focused);
2174 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2175 gtk_action_set_sensitive (action, rich_text && editor_focused);
2176 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2177 gtk_action_set_sensitive (action, rich_text && editor_focused);
2178 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2179 gtk_action_set_sensitive (action, rich_text && editor_focused);
2180 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2181 gtk_action_set_sensitive (action, rich_text && editor_focused);
2182 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2183 gtk_action_set_sensitive (action, rich_text && editor_focused);
2184 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2185 gtk_action_set_sensitive (action, rich_text && editor_focused);
2186 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2187 gtk_action_set_sensitive (action, rich_text && editor_focused);
2188 widget = priv->font_color_button;
2189 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2190 widget = priv->font_size_toolitem;
2191 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2192 widget = priv->font_face_toolitem;
2193 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2197 setup_insensitive_handlers (ModestMsgEditWindow *window)
2199 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2200 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2203 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2204 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2205 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2206 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2208 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2209 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2210 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
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/AlignmentMenu");
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/AlignmentLeftMenu");
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/AlignmentCenterMenu");
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/AlignmentRightMenu");
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/AttachmentsMenu/InsertImageMenu");
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, "/ToolBar/ActionsBold");
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/ActionsItalics");
2225 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2226 widget = priv->font_color_button;
2227 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2228 widget = priv->font_size_toolitem;
2229 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2230 widget = priv->font_face_toolitem;
2231 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2236 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2238 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2241 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2242 gtk_action_set_sensitive (action, can_undo);
2246 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2249 GtkTextIter match_start, match_end;
2251 if (image_id == NULL)
2254 gtk_text_buffer_get_start_iter (buffer, &iter);
2256 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2257 GSList *tags = gtk_text_iter_get_tags (&match_start);
2259 for (node = tags; node != NULL; node = g_slist_next (node)) {
2260 GtkTextTag *tag = (GtkTextTag *) node->data;
2261 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2262 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2263 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2265 offset = gtk_text_iter_get_offset (&match_start);
2266 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2267 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2271 gtk_text_iter_forward_char (&iter);
2276 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2278 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2279 GtkTextIter real_start, real_end;
2280 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2282 if (gtk_text_iter_compare (start, end) > 0) {
2286 real_start = *start;
2290 GSList *tags = gtk_text_iter_get_tags (&real_start);
2292 for (node = tags; node != NULL; node = g_slist_next (node)) {
2293 GtkTextTag *tag = (GtkTextTag *) node->data;
2294 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2295 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2297 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2299 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2302 } while (gtk_text_iter_forward_char (&real_start)&&
2303 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2307 msg_body_focus (GtkWidget *focus,
2308 GdkEventFocus *event,
2312 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2317 recpt_field_changed (GtkTextBuffer *buffer,
2318 ModestMsgEditWindow *editor)
2320 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2321 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2322 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2323 gboolean dim = FALSE;
2326 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2327 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2328 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2330 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2331 gtk_text_buffer_get_char_count (cc_buffer) +
2332 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2334 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2335 gtk_action_set_sensitive (action, !dim);
2336 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2337 gtk_action_set_sensitive (action, !dim);
2341 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2343 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2347 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2349 gboolean rich_text, editor_focused;
2351 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2352 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2353 editor_focused = gtk_widget_is_focus (priv->msg_body);
2356 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2357 else if (!editor_focused)
2358 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2362 reset_modified (ModestMsgEditWindow *editor)
2364 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2365 GtkTextBuffer *buffer;
2367 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2368 gtk_text_buffer_set_modified (buffer, FALSE);
2369 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2370 gtk_text_buffer_set_modified (buffer, FALSE);
2371 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2372 gtk_text_buffer_set_modified (buffer, FALSE);
2373 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2377 is_modified (ModestMsgEditWindow *editor)
2379 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2380 GtkTextBuffer *buffer;
2382 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2383 if (gtk_text_buffer_get_modified (buffer))
2385 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2386 if (gtk_text_buffer_get_modified (buffer))
2388 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2389 if (gtk_text_buffer_get_modified (buffer))
2391 if (gtk_text_buffer_get_modified (priv->text_buffer))
2398 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2400 ModestMsgEditWindowPrivate *priv = NULL;
2402 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2403 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2405 /* check if there's no recipient added */
2406 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2407 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2408 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2409 /* no recipient contents, then select contacts */
2410 modest_msg_edit_window_open_addressbook (window, NULL);
2414 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2416 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2418 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2421 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2428 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2429 ModestMsgEditWindow *window)
2431 modest_msg_edit_window_attach_file (window);
2435 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2437 ModestMsgEditWindow *window)
2439 ModestWindowPrivate *parent_priv;
2444 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2445 selection = gtk_clipboard_wait_for_text (clipboard);
2446 focused = gtk_window_get_focus (GTK_WINDOW (window));
2448 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2449 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2450 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2451 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2455 update_window_title (ModestMsgEditWindow *window)
2457 ModestMsgEditWindowPrivate *priv = NULL;
2458 const gchar *subject;
2460 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2461 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2462 if (subject == NULL || subject[0] == '\0')
2463 subject = _("mail_va_new_email");
2465 gtk_window_set_title (GTK_WINDOW (window), subject);
2470 subject_field_changed (GtkEditable *editable,
2471 ModestMsgEditWindow *window)
2473 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2474 update_window_title (window);
2475 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2479 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2482 ModestMsgEditWindowPrivate *priv = NULL;
2484 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2485 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2487 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2489 gtk_widget_show_all (priv->find_toolbar);
2490 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2492 gtk_widget_hide_all (priv->find_toolbar);
2493 gtk_widget_grab_focus (priv->msg_body);
2499 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2500 ModestMsgEditWindow *window)
2502 gchar *current_search = NULL;
2503 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2505 GtkTextIter selection_start, selection_end;
2506 GtkTextIter match_start, match_end;
2508 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2509 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2510 g_free (current_search);
2514 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2515 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2517 GtkTextIter buffer_start;
2518 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2519 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2522 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2523 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2525 /* TODO: warning about non succesful search */
2527 g_free (current_search);
2531 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2532 ModestMsgEditWindow *window)
2534 GtkToggleAction *toggle;
2535 ModestWindowPrivate *parent_priv;
2536 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2538 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2539 gtk_toggle_action_set_active (toggle, FALSE);