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 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
353 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
354 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
355 priv->add_attachment_button = gtk_button_new ();
356 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
357 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
358 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
359 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
360 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
361 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
362 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
363 priv->attachments_view = modest_attachments_view_new (NULL);
365 priv->header_box = gtk_vbox_new (FALSE, 0);
367 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
368 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
369 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
370 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
371 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
372 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
373 g_object_unref (size_group);
375 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
376 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
377 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
378 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
379 gtk_size_group_add_widget (size_group, priv->subject_field);
380 gtk_size_group_add_widget (size_group, priv->attachments_view);
381 g_object_unref (size_group);
383 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
384 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
385 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
386 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
387 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
388 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
389 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
392 priv->msg_body = wp_text_view_new ();
393 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
394 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
395 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
396 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
397 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
398 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
400 priv->find_toolbar = hildon_find_toolbar_new (NULL);
401 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
403 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
404 G_CALLBACK (text_buffer_refresh_attributes), obj);
405 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
406 G_CALLBACK (text_buffer_delete_range), obj);
407 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
408 G_CALLBACK (text_buffer_can_undo), obj);
409 g_signal_connect (G_OBJECT (obj), "window-state-event",
410 G_CALLBACK (modest_msg_edit_window_window_state_event),
412 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
413 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
414 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
415 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
416 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
417 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
419 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
420 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
422 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
423 G_CALLBACK (msg_body_focus), obj);
424 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
425 G_CALLBACK (msg_body_focus), obj);
426 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
427 "changed", G_CALLBACK (recpt_field_changed), obj);
428 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
429 "changed", G_CALLBACK (recpt_field_changed), obj);
430 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
431 "changed", G_CALLBACK (recpt_field_changed), obj);
432 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
433 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
435 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
436 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
438 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
439 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
440 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
442 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
444 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
445 frame = gtk_frame_new (NULL);
446 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
448 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
449 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
450 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
452 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
453 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
454 gtk_widget_hide (priv->cc_caption);
456 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
457 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
458 gtk_widget_hide (priv->bcc_caption);
461 window_box = gtk_vbox_new (FALSE, 0);
462 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
463 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
464 gtk_container_add (GTK_CONTAINER(obj), window_box);
465 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
466 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
467 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
468 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
470 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
471 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
477 modest_msg_edit_window_finalize (GObject *obj)
479 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
481 if (priv->clipboard_change_handler_id > 0) {
482 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
483 priv->clipboard_change_handler_id = 0;
486 /* This had to stay alive for as long as the combobox that used it: */
487 modest_pair_list_free (priv->from_field_protos);
489 G_OBJECT_CLASS(parent_class)->finalize (obj);
493 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
495 GtkWidget *close_dialog;
496 ModestMsgEditWindowPrivate *priv;
499 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
500 modest_window_save_state (MODEST_WINDOW (self));
501 if (is_modified (self)) {
502 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
503 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
504 gtk_widget_destroy (close_dialog);
506 if (response != GTK_RESPONSE_CANCEL) {
507 modest_ui_actions_on_save_to_drafts (NULL, self);
510 /* /\* remove old message from drafts *\/ */
511 /* if (priv->draft_msg) { */
512 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
513 /* TnyAccount *account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(), */
515 /* TNY_ACCOUNT_TYPE_STORE); */
516 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
517 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
518 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
519 /* tny_folder_remove_msg (folder, header, NULL); */
520 /* g_object_unref (folder); */
521 /* g_object_unref (header); */
522 /* g_object_unref (priv->draft_msg); */
523 /* priv->draft_msg = NULL; */
525 gtk_widget_destroy (GTK_WIDGET (self));
531 menubar_to_menu (GtkUIManager *ui_manager)
533 GtkWidget *main_menu;
537 /* Create new main menu */
538 main_menu = gtk_menu_new();
540 /* Get the menubar from the UI manager */
541 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
543 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
547 menu = GTK_WIDGET (iter->data);
548 gtk_widget_reparent(menu, main_menu);
550 iter = g_list_next (iter);
557 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
560 const gchar *to, *cc, *bcc, *subject;
562 ModestMsgEditWindowPrivate *priv;
565 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
566 g_return_if_fail (TNY_IS_MSG (msg));
568 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
570 header = tny_msg_get_header (msg);
571 to = tny_header_get_to (header);
572 cc = tny_header_get_cc (header);
573 bcc = tny_header_get_bcc (header);
574 subject = tny_header_get_subject (header);
577 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
579 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
581 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
583 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
585 update_window_title (self);
587 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
588 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
589 body = modest_tny_msg_get_body (msg, TRUE);
591 if ((body == NULL)||(body[0] == '\0')) {
593 body = modest_text_utils_convert_to_html ("");
595 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
596 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
599 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
602 /* Get the default format required from configuration */
603 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
604 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
607 /* Set the default focus depending on having already a To: field or not */
608 if ((!to)||(*to == '\0')) {
609 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
611 gtk_widget_grab_focus (priv->msg_body);
614 /* TODO: lower priority, select in the From: combo to the
615 value that comes from msg <- not sure, should it be
618 /* Add attachments to the view */
619 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
620 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
621 if (priv->attachments == NULL) {
622 gtk_widget_hide (priv->attachments_caption);
624 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
625 gtk_widget_show_all (priv->attachments_caption);
628 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
629 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
631 reset_modified (self);
633 update_dimmed (self);
634 text_buffer_can_undo (priv->text_buffer, FALSE, self);
636 priv->draft_msg = msg;
640 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
643 GList *item_children, *node;
644 GtkWidget *bin_child;
646 bin_child = gtk_bin_get_child (GTK_BIN(item));
648 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
650 for (node = item_children; node != NULL; node = g_list_next (node)) {
651 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
652 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
655 g_list_free (item_children);
659 menu_tool_button_dont_expand (GtkMenuToolButton *item)
662 GList *item_children, *node;
664 box = gtk_bin_get_child (GTK_BIN (item));
665 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
666 item_children = gtk_container_get_children (GTK_CONTAINER (box));
668 for (node = item_children; node != NULL; node = g_list_next (node)) {
669 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
670 if (GTK_IS_TOGGLE_BUTTON (node->data))
671 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
672 else if (GTK_IS_BUTTON (node->data))
673 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
675 g_list_free (item_children);
680 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
682 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
683 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
684 GtkWidget *placeholder;
685 GtkWidget *tool_item;
690 GtkWidget *sizes_menu;
691 GtkWidget *fonts_menu;
692 GSList *radio_group = NULL;
697 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
698 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
700 /* should we hide the toolbar? */
701 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
702 gtk_widget_hide (parent_priv->toolbar);
704 /* Font color placeholder */
705 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
706 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
709 tool_item = GTK_WIDGET (gtk_tool_item_new ());
710 priv->font_color_button = hildon_color_button_new ();
711 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
712 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
713 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
714 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
715 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
716 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
717 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
719 /* Font size and face placeholder */
720 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
721 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
723 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
724 priv->size_tool_button_label = gtk_label_new (NULL);
725 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
726 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
727 size_text,"</span>", NULL);
728 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
730 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
731 sizes_menu = gtk_menu_new ();
732 priv->size_items_group = NULL;
734 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
735 GtkWidget *size_menu_item;
737 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
738 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
739 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
740 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
741 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
742 gtk_widget_show (size_menu_item);
744 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
748 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
749 GtkWidget *item = (GtkWidget *) node->data;
750 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
754 priv->size_items_group = g_slist_reverse (priv->size_items_group);
755 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
756 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
757 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
758 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
759 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
760 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
761 priv->font_size_toolitem = tool_item;
764 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
765 priv->font_tool_button_label = gtk_label_new (NULL);
766 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
767 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
769 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
770 fonts_menu = gtk_menu_new ();
771 priv->font_items_group = NULL;
773 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
774 GtkWidget *font_menu_item;
775 GtkWidget *child_label;
777 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
778 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
779 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
780 wp_get_font_name (font_index), "</span>", NULL);
781 gtk_label_set_markup (GTK_LABEL (child_label), markup);
784 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
785 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
786 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
787 gtk_widget_show (font_menu_item);
789 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
792 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
793 GtkWidget *item = (GtkWidget *) node->data;
794 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
797 priv->font_items_group = g_slist_reverse (priv->font_items_group);
798 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
799 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
800 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
801 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
802 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
803 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
804 priv->font_face_toolitem = tool_item;
806 /* Set expand and homogeneous for remaining items */
807 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
808 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
809 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
810 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
811 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
812 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
813 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
814 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
815 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
823 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
826 ModestWindowPrivate *parent_priv;
827 ModestMsgEditWindowPrivate *priv;
828 GtkActionGroup *action_group;
829 GError *error = NULL;
830 GdkPixbuf *window_icon = NULL;
833 gboolean prefer_formatted;
835 ModestPair *account_pair = NULL;
837 g_return_val_if_fail (msg, NULL);
838 g_return_val_if_fail (account_name, NULL);
840 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
842 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
843 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
845 parent_priv->ui_manager = gtk_ui_manager_new();
846 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
847 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
849 /* Add common actions */
850 gtk_action_group_add_actions (action_group,
851 modest_msg_edit_action_entries,
852 G_N_ELEMENTS (modest_msg_edit_action_entries),
854 gtk_action_group_add_toggle_actions (action_group,
855 modest_msg_edit_toggle_action_entries,
856 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
858 gtk_action_group_add_radio_actions (action_group,
859 modest_msg_edit_alignment_radio_action_entries,
860 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
862 G_CALLBACK (modest_ui_actions_on_change_justify),
864 gtk_action_group_add_radio_actions (action_group,
865 modest_msg_edit_zoom_action_entries,
866 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
868 G_CALLBACK (modest_ui_actions_on_change_zoom),
870 gtk_action_group_add_radio_actions (action_group,
871 modest_msg_edit_priority_action_entries,
872 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
874 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
876 gtk_action_group_add_radio_actions (action_group,
877 modest_msg_edit_file_format_action_entries,
878 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
879 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
880 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
882 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
883 g_object_unref (action_group);
885 /* Load the UI definition */
886 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
889 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
890 g_clear_error (&error);
893 /* Add accelerators */
894 gtk_window_add_accel_group (GTK_WINDOW (obj),
895 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
898 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
899 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
902 init_window (MODEST_MSG_EDIT_WINDOW(obj));
904 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
906 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
908 g_signal_connect (G_OBJECT(obj), "delete-event",
909 G_CALLBACK(on_delete_event), obj);
911 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
913 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
915 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
917 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
918 if (account_pair != NULL)
919 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
921 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
923 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
925 /* Set window icon */
926 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
927 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
929 /* Dim at start clipboard actions */
930 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
931 gtk_action_set_sensitive (action, FALSE);
932 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
933 gtk_action_set_sensitive (action, FALSE);
935 /* set initial state of cc and bcc */
936 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
937 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
938 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
939 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
940 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
941 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
943 /* Setup the file format */
944 conf = modest_runtime_get_conf ();
945 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
947 g_clear_error (&error);
948 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
950 file_format = (prefer_formatted) ?
951 MODEST_FILE_FORMAT_FORMATTED_TEXT :
952 MODEST_FILE_FORMAT_PLAIN_TEXT;
953 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
955 return (ModestWindow*) obj;
959 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
961 GString **string_buffer = (GString **) user_data;
963 *string_buffer = g_string_append (*string_buffer, buffer);
969 * @result: A new string which should be freed with g_free().
972 get_formatted_data (ModestMsgEditWindow *edit_window)
974 ModestMsgEditWindowPrivate *priv;
975 GString *string_buffer = g_string_new ("");
977 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
979 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
981 return g_string_free (string_buffer, FALSE);
986 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
989 const gchar *account_name;
990 ModestMsgEditWindowPrivate *priv;
992 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
994 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
996 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
997 g_return_val_if_fail (account_name, NULL);
1000 /* don't free these (except from) */
1001 data = g_slice_new0 (MsgData);
1002 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1004 data->account_name = g_strdup (account_name);
1005 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1006 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1007 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1008 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1009 if (priv->draft_msg) {
1010 data->draft_msg = g_object_ref (priv->draft_msg);
1012 data->draft_msg = NULL;
1015 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1017 gtk_text_buffer_get_bounds (buf, &b, &e);
1018 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1020 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1021 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1023 data->html_body = NULL;
1025 data->attachments = priv->attachments; /* TODO: copy and free ? */
1026 data->priority_flags = priv->priority_flags;
1031 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1033 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1036 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1044 g_free (data->subject);
1045 g_free (data->plain_body);
1046 g_free (data->html_body);
1047 if (data->draft_msg != NULL) {
1048 g_object_unref (data->draft_msg);
1049 data->draft_msg = NULL;
1051 g_free (data->account_name);
1053 /* TODO: Free data->attachments? */
1055 g_slice_free (MsgData, data);
1059 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1062 ModestMsgEditWindowPrivate *priv = NULL;
1063 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1065 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1067 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1069 return MODEST_MSG_EDIT_FORMAT_HTML;
1071 return MODEST_MSG_EDIT_FORMAT_TEXT;
1075 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1076 ModestMsgEditFormat format)
1078 ModestMsgEditWindowPrivate *priv;
1080 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1081 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1084 case MODEST_MSG_EDIT_FORMAT_HTML:
1085 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1087 case MODEST_MSG_EDIT_FORMAT_TEXT:
1088 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1091 g_return_if_reached ();
1095 ModestMsgEditFormatState *
1096 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1098 ModestMsgEditFormatState *format_state = NULL;
1099 ModestMsgEditWindowPrivate *priv;
1100 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1102 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1103 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1105 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1107 format_state = g_new0 (ModestMsgEditFormatState, 1);
1108 format_state->bold = buffer_format->bold&0x1;
1109 format_state->italics = buffer_format->italic&0x1;
1110 format_state->bullet = buffer_format->bullet&0x1;
1111 format_state->color = buffer_format->color;
1112 format_state->font_size = buffer_format->font_size;
1113 format_state->font_family = wp_get_font_name (buffer_format->font);
1114 format_state->justification = buffer_format->justification;
1115 g_free (buffer_format);
1117 return format_state;
1122 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1123 const ModestMsgEditFormatState *format_state)
1125 ModestMsgEditWindowPrivate *priv;
1126 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1127 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1128 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1129 g_return_if_fail (format_state != NULL);
1131 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1132 gtk_widget_grab_focus (priv->msg_body);
1133 buffer_format->bold = (format_state->bold != FALSE);
1134 buffer_format->italic = (format_state->italics != FALSE);
1135 buffer_format->color = format_state->color;
1136 buffer_format->font_size = format_state->font_size;
1137 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1138 buffer_format->justification = format_state->justification;
1139 buffer_format->bullet = format_state->bullet;
1141 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1143 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1144 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1145 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1146 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1147 buffer_format->cs.font = (buffer_format->font != current_format->font);
1148 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1149 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1151 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1152 if (buffer_format->cs.bold) {
1153 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1155 if (buffer_format->cs.italic) {
1156 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1158 if (buffer_format->cs.color) {
1159 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1161 if (buffer_format->cs.font_size) {
1162 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1164 if (buffer_format->cs.justification) {
1165 switch (buffer_format->justification) {
1166 case GTK_JUSTIFY_LEFT:
1167 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1169 case GTK_JUSTIFY_CENTER:
1170 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1172 case GTK_JUSTIFY_RIGHT:
1173 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1180 if (buffer_format->cs.font) {
1181 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1183 if (buffer_format->cs.bullet) {
1184 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1186 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1187 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1189 g_free (current_format);
1194 toggle_action_set_active_block_notify (GtkToggleAction *action,
1197 GSList *proxies = NULL;
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_block_activate_from (GTK_ACTION (action), widget);
1205 gtk_toggle_action_set_active (action, value);
1207 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1208 proxies != NULL; proxies = g_slist_next (proxies)) {
1209 GtkWidget *widget = (GtkWidget *) proxies->data;
1210 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1215 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1217 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1219 ModestWindowPrivate *parent_priv;
1220 ModestMsgEditWindowPrivate *priv;
1221 GtkWidget *new_size_menuitem;
1222 GtkWidget *new_font_menuitem;
1224 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1225 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1227 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1228 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1229 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1230 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1232 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1233 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1234 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1237 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1239 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1240 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1242 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1243 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1245 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1246 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1248 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1249 G_CALLBACK (modest_msg_edit_window_color_button_change),
1251 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1252 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1253 G_CALLBACK (modest_msg_edit_window_color_button_change),
1256 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1257 buffer_format->font_size))->data);
1258 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1262 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1263 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1264 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1266 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1267 G_CALLBACK (modest_msg_edit_window_size_change),
1269 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1270 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1271 G_CALLBACK (modest_msg_edit_window_size_change),
1275 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1276 buffer_format->font))->data);
1277 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1281 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1282 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1283 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1285 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1286 G_CALLBACK (modest_msg_edit_window_font_change),
1288 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1289 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1290 G_CALLBACK (modest_msg_edit_window_font_change),
1294 g_free (buffer_format);
1300 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1303 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1304 ModestMsgEditWindowPrivate *priv;
1305 GtkWidget *dialog = NULL;
1307 const GdkColor *new_color = NULL;
1309 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1310 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1312 #ifdef MODEST_HILDON_VERSION_0
1313 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1314 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1316 dialog = hildon_color_chooser_new ();
1317 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1318 #endif /*MODEST_HILDON_VERSION_0*/
1319 g_free (buffer_format);
1321 response = gtk_dialog_run (GTK_DIALOG (dialog));
1323 case GTK_RESPONSE_OK: {
1324 #ifdef MODEST_HILDON_VERSION_0
1325 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1328 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1330 #endif /*MODEST_HILDON_VERSION_0*/
1337 gtk_widget_destroy (dialog);
1339 if (new_color != NULL)
1340 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1345 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1348 ModestMsgEditWindowPrivate *priv;
1349 GtkWidget *dialog = NULL;
1351 GdkColor *old_color = NULL;
1352 const GdkColor *new_color = NULL;
1354 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1355 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1357 #ifdef MODEST_HILDON_VERSION_0
1358 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1359 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1361 dialog = hildon_color_chooser_new ();
1362 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1363 #endif /*MODEST_HILDON_VERSION_9*/
1365 response = gtk_dialog_run (GTK_DIALOG (dialog));
1367 case GTK_RESPONSE_OK: {
1368 #ifdef MODEST_HILDON_VERSION_0
1369 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1372 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1374 #endif /*MODEST_HILDON_VERSION_0*/
1380 gtk_widget_destroy (dialog);
1382 if (new_color != NULL)
1383 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1388 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1391 ModestMsgEditWindowPrivate *priv;
1392 GtkWidget *dialog = NULL;
1394 gchar *filename = NULL;
1396 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1398 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1400 response = gtk_dialog_run (GTK_DIALOG (dialog));
1402 case GTK_RESPONSE_OK:
1403 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1408 gtk_widget_destroy (dialog);
1411 GdkPixbuf *pixbuf = NULL;
1412 GtkTextIter position;
1413 GtkTextMark *insert_mark;
1415 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1418 GdkPixbufFormat *pixbuf_format;
1420 image_file_id = g_open (filename, O_RDONLY, 0);
1421 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1422 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1423 TnyMimePart *image_part;
1424 TnyStream *image_stream;
1430 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1431 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1432 mime_type = mime_types[0];
1434 mime_type = "image/unknown";
1436 image_part = tny_platform_factory_new_mime_part
1437 (modest_runtime_get_platform_factory ());
1438 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1440 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1441 g_strfreev (mime_types);
1443 content_id = g_strdup_printf ("%d", priv->last_cid);
1444 tny_mime_part_set_content_id (image_part, content_id);
1445 g_free (content_id);
1448 basename = g_path_get_basename (filename);
1449 tny_mime_part_set_filename (image_part, basename);
1452 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1453 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1454 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1455 priv->attachments = g_list_prepend (priv->attachments, image_part);
1456 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1458 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1459 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1460 gtk_widget_show_all (priv->attachments_caption);
1461 } else if (image_file_id == -1) {
1462 close (image_file_id);
1471 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1474 ModestMsgEditWindowPrivate *priv;
1475 GtkWidget *dialog = NULL;
1477 gchar *uri = NULL, *filename = NULL;
1479 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1481 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1483 response = gtk_dialog_run (GTK_DIALOG (dialog));
1485 case GTK_RESPONSE_OK:
1486 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1487 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1492 gtk_widget_destroy (dialog);
1496 GnomeVFSHandle *handle = NULL;
1497 GnomeVFSResult result;
1499 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1500 if (result == GNOME_VFS_OK) {
1501 TnyMimePart *mime_part;
1503 const gchar *mime_type = NULL;
1506 GnomeVFSFileInfo info;
1508 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1509 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1510 mime_part = tny_platform_factory_new_mime_part
1511 (modest_runtime_get_platform_factory ());
1512 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1514 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1516 content_id = g_strdup_printf ("%d", priv->last_cid);
1517 tny_mime_part_set_content_id (mime_part, content_id);
1518 g_free (content_id);
1521 basename = g_path_get_basename (filename);
1522 tny_mime_part_set_filename (mime_part, basename);
1525 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1526 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1528 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1529 gtk_widget_show_all (priv->attachments_caption);
1530 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1537 modest_msg_edit_window_attach_file_noninteractive (
1538 ModestMsgEditWindow *window,
1542 ModestMsgEditWindowPrivate *priv;
1544 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1549 file_id = g_open (filename, O_RDONLY, 0);
1550 if (file_id != -1) {
1551 TnyMimePart *mime_part;
1553 const gchar *mime_type;
1557 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1558 mime_part = tny_platform_factory_new_mime_part
1559 (modest_runtime_get_platform_factory ());
1560 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1562 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1564 content_id = g_strdup_printf ("%d", priv->last_cid);
1565 tny_mime_part_set_content_id (mime_part, content_id);
1566 g_free (content_id);
1569 basename = g_path_get_basename (filename);
1570 tny_mime_part_set_filename (mime_part, basename);
1573 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1574 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1576 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1577 gtk_widget_show_all (priv->attachments_caption);
1578 } else if (file_id == -1) {
1580 g_warning("file to be attached does not exist: %s", filename);
1586 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1589 ModestMsgEditWindowPrivate *priv;
1590 gboolean clean_list = FALSE;
1592 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1593 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1595 if (att_list == NULL) {
1596 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1600 if (att_list == NULL) {
1601 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1603 GtkWidget *confirmation_dialog = NULL;
1604 gboolean dialog_response;
1606 if (att_list->next == NULL) {
1607 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1608 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1609 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1612 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1614 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1615 gtk_widget_destroy (confirmation_dialog);
1616 if (!dialog_response) {
1618 g_list_free (att_list);
1621 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1623 for (node = att_list; node != NULL; node = g_list_next (node)) {
1624 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1625 const gchar *att_id;
1626 priv->attachments = g_list_remove (priv->attachments, mime_part);
1628 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1630 if (priv->attachments == NULL)
1631 gtk_widget_hide (priv->attachments_caption);
1632 att_id = tny_mime_part_get_content_id (mime_part);
1634 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1636 g_object_unref (mime_part);
1637 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1642 g_list_free (att_list);
1646 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1649 ModestMsgEditWindowPrivate *priv;
1650 GdkColor *new_color;
1651 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1653 #ifdef MODEST_HILDON_VERSION_0
1654 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1657 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1659 #endif /*MODEST_HILDON_VERSION_0*/
1661 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1663 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1668 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1671 ModestMsgEditWindowPrivate *priv;
1672 gint new_size_index;
1673 ModestMsgEditWindow *window;
1676 window = MODEST_MSG_EDIT_WINDOW (userdata);
1677 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1678 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1680 if (gtk_check_menu_item_get_active (menu_item)) {
1682 WPTextBufferFormat format;
1684 memset (&format, 0, sizeof (format));
1685 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1687 label = gtk_bin_get_child (GTK_BIN (menu_item));
1689 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1690 format.cs.font_size = TRUE;
1691 format.cs.text_position = TRUE;
1692 format.cs.font = TRUE;
1693 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1694 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1696 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1697 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1698 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1700 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1701 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1702 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1708 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1711 ModestMsgEditWindowPrivate *priv;
1712 gint new_font_index;
1713 ModestMsgEditWindow *window;
1716 window = MODEST_MSG_EDIT_WINDOW (userdata);
1717 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1718 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1720 if (gtk_check_menu_item_get_active (menu_item)) {
1723 label = gtk_bin_get_child (GTK_BIN (menu_item));
1725 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1727 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1728 (gpointer) new_font_index))
1729 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1731 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1732 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1733 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1739 modest_msg_edit_window_set_zoom (ModestWindow *window,
1742 ModestMsgEditWindowPrivate *priv;
1744 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1746 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1747 priv->zoom_level = zoom;
1748 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1752 modest_msg_edit_window_get_zoom (ModestWindow *window)
1754 ModestMsgEditWindowPrivate *priv;
1756 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1758 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1759 return priv->zoom_level;
1763 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1765 ModestWindowPrivate *parent_priv;
1766 GtkRadioAction *zoom_radio_action;
1767 GSList *group, *node;
1769 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1770 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1771 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1773 group = gtk_radio_action_get_group (zoom_radio_action);
1775 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1776 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1780 for (node = group; node != NULL; node = g_slist_next (node)) {
1781 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1782 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1790 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1792 ModestWindowPrivate *parent_priv;
1793 GtkRadioAction *zoom_radio_action;
1794 GSList *group, *node;
1796 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1797 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1798 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1800 group = gtk_radio_action_get_group (zoom_radio_action);
1802 for (node = group; node != NULL; node = g_slist_next (node)) {
1803 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1804 if (node->next != NULL) {
1805 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1808 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1816 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1818 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1819 ModestWindowPrivate *parent_priv;
1820 ModestWindowMgr *mgr;
1821 gboolean is_fullscreen;
1822 GtkAction *fs_toggle_action;
1825 mgr = modest_runtime_get_window_mgr ();
1826 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1828 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1830 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1831 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1832 if (is_fullscreen != active)
1833 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1841 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1843 ModestWindowPrivate *parent_priv;
1844 GtkAction *fs_toggle_action;
1847 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1849 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1850 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1851 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1855 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1858 ModestMsgEditWindowPrivate *priv = NULL;
1859 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1861 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1862 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1864 gtk_widget_show (priv->cc_caption);
1866 gtk_widget_hide (priv->cc_caption);
1867 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1871 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1874 ModestMsgEditWindowPrivate *priv = NULL;
1875 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1877 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1878 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1880 gtk_widget_show (priv->bcc_caption);
1882 gtk_widget_hide (priv->bcc_caption);
1883 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1887 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1888 ModestRecptEditor *editor)
1890 ModestMsgEditWindowPrivate *priv;
1892 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1893 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1894 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1896 if (editor == NULL) {
1897 GtkWidget *view_focus;
1898 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1900 /* This code should be kept in sync with ModestRecptEditor. The
1901 textview inside the recpt editor is the one that really gets the
1902 focus. As it's inside a scrolled window, and this one inside the
1903 hbox recpt editor inherits from, we'll need to go up in the
1904 hierarchy to know if the text view is part of the recpt editor
1905 or if it's a different text entry */
1907 if (gtk_widget_get_parent (view_focus)) {
1908 GtkWidget *first_parent;
1910 first_parent = gtk_widget_get_parent (view_focus);
1911 if (gtk_widget_get_parent (first_parent) &&
1912 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1913 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1918 editor = MODEST_RECPT_EDITOR (priv->to_field);
1922 modest_address_book_select_addresses (editor);
1927 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1929 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1931 modest_msg_edit_window_open_addressbook (window, NULL);
1935 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1936 gboolean show_toolbar)
1938 ModestWindowPrivate *parent_priv;
1940 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1941 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1943 /* FIXME: we can not just use the code of
1944 modest_msg_edit_window_setup_toolbar because it has a
1945 mixture of both initialization and creation code. */
1948 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1950 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1954 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1955 TnyHeaderFlags priority_flags)
1957 ModestMsgEditWindowPrivate *priv;
1959 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1961 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1962 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1964 if (priv->priority_flags != priority_flags) {
1966 priv->priority_flags = priority_flags;
1968 switch (priority_flags) {
1969 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1970 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1971 gtk_widget_show (priv->priority_icon);
1973 case TNY_HEADER_FLAG_LOW_PRIORITY:
1974 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1975 gtk_widget_show (priv->priority_icon);
1978 gtk_widget_hide (priv->priority_icon);
1985 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1988 ModestMsgEditWindowPrivate *priv;
1989 gint current_format;
1991 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1993 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1995 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1996 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1998 if (current_format != file_format) {
1999 switch (file_format) {
2000 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2001 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2003 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2007 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2008 response = gtk_dialog_run (GTK_DIALOG (dialog));
2009 gtk_widget_destroy (dialog);
2010 if (response == GTK_RESPONSE_OK)
2011 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2015 update_dimmed (window);
2020 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2023 ModestMsgEditWindowPrivate *priv;
2024 WPTextBufferFormat oldfmt, fmt;
2025 gint old_position = 0;
2029 GdkColor *color = NULL;
2030 gboolean bold, bold_set, italic, italic_set;
2031 gboolean underline, underline_set;
2032 gboolean strikethrough, strikethrough_set;
2033 gboolean position_set;
2034 gboolean font_size_set, font_set, color_set;
2037 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2038 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2040 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2042 /* First we get the currently selected font information */
2043 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2044 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2046 switch (oldfmt.text_position) {
2047 case TEXT_POSITION_NORMAL:
2050 case TEXT_POSITION_SUPERSCRIPT:
2058 g_object_set (G_OBJECT (dialog),
2059 "bold", oldfmt.bold != FALSE,
2060 "bold-set", !oldfmt.cs.bold,
2061 "underline", oldfmt.underline != FALSE,
2062 "underline-set", !oldfmt.cs.underline,
2063 "italic", oldfmt.italic != FALSE,
2064 "italic-set", !oldfmt.cs.italic,
2065 "strikethrough", oldfmt.strikethrough != FALSE,
2066 "strikethrough-set", !oldfmt.cs.strikethrough,
2067 "color", &oldfmt.color,
2068 "color-set", !oldfmt.cs.color,
2069 "size", wp_font_size[oldfmt.font_size],
2070 "size-set", !oldfmt.cs.font_size,
2071 "position", old_position,
2072 "position-set", !oldfmt.cs.text_position,
2073 "family", wp_get_font_name (oldfmt.font),
2074 "family-set", !oldfmt.cs.font,
2077 gtk_widget_show_all (dialog);
2078 response = gtk_dialog_run (GTK_DIALOG (dialog));
2079 if (response == GTK_RESPONSE_OK) {
2081 g_object_get( dialog,
2083 "bold-set", &bold_set,
2084 "underline", &underline,
2085 "underline-set", &underline_set,
2087 "italic-set", &italic_set,
2088 "strikethrough", &strikethrough,
2089 "strikethrough-set", &strikethrough_set,
2091 "color-set", &color_set,
2093 "size-set", &font_size_set,
2094 "family", &font_name,
2095 "family-set", &font_set,
2096 "position", &position,
2097 "position-set", &position_set,
2102 if (response == GTK_RESPONSE_OK) {
2103 memset(&fmt, 0, sizeof(fmt));
2109 fmt.italic = italic;
2110 fmt.cs.italic = TRUE;
2112 if (underline_set) {
2113 fmt.underline = underline;
2114 fmt.cs.underline = TRUE;
2116 if (strikethrough_set) {
2117 fmt.strikethrough = strikethrough;
2118 fmt.cs.strikethrough = TRUE;
2123 ? TEXT_POSITION_NORMAL
2124 : ( ( position == 1 )
2125 ? TEXT_POSITION_SUPERSCRIPT
2126 : TEXT_POSITION_SUBSCRIPT );
2127 fmt.cs.text_position = TRUE;
2131 fmt.cs.color = TRUE;
2134 fmt.font = wp_get_font_index(font_name,
2139 if (font_size_set) {
2140 fmt.font_size = wp_get_font_size_index(
2141 font_size, DEFAULT_FONT_SIZE);
2142 fmt.cs.font_size = TRUE;
2144 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2146 gtk_widget_destroy (dialog);
2148 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2152 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2154 ModestMsgEditWindowPrivate *priv;
2156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2157 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2159 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2161 update_dimmed (window);
2166 update_dimmed (ModestMsgEditWindow *window)
2168 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2169 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2173 gboolean editor_focused;
2175 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2176 editor_focused = gtk_widget_is_focus (priv->msg_body);
2178 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2179 gtk_action_set_sensitive (action, rich_text && editor_focused);
2180 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2181 gtk_action_set_sensitive (action, rich_text && editor_focused);
2182 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2183 gtk_action_set_sensitive (action, rich_text && editor_focused);
2184 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2185 gtk_action_set_sensitive (action, rich_text && editor_focused);
2186 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2187 gtk_action_set_sensitive (action, rich_text && editor_focused);
2188 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2189 gtk_action_set_sensitive (action, rich_text && editor_focused);
2190 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2191 gtk_action_set_sensitive (action, rich_text && editor_focused);
2192 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2193 gtk_action_set_sensitive (action, rich_text && editor_focused);
2194 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2195 gtk_action_set_sensitive (action, rich_text && editor_focused);
2196 widget = priv->font_color_button;
2197 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2198 widget = priv->font_size_toolitem;
2199 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2200 widget = priv->font_face_toolitem;
2201 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2205 setup_insensitive_handlers (ModestMsgEditWindow *window)
2207 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2208 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2211 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2212 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2213 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2214 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2216 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
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/BulletedListMenu");
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");
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/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
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, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
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, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2227 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2228 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2229 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2230 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2231 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2232 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2233 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2234 widget = priv->font_color_button;
2235 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2236 widget = priv->font_size_toolitem;
2237 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2238 widget = priv->font_face_toolitem;
2239 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2244 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2246 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2249 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2250 gtk_action_set_sensitive (action, can_undo);
2254 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2257 GtkTextIter match_start, match_end;
2259 if (image_id == NULL)
2262 gtk_text_buffer_get_start_iter (buffer, &iter);
2264 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2265 GSList *tags = gtk_text_iter_get_tags (&match_start);
2267 for (node = tags; node != NULL; node = g_slist_next (node)) {
2268 GtkTextTag *tag = (GtkTextTag *) node->data;
2269 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2270 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2271 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2273 offset = gtk_text_iter_get_offset (&match_start);
2274 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2275 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2279 gtk_text_iter_forward_char (&iter);
2284 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2286 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2287 GtkTextIter real_start, real_end;
2288 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2290 if (gtk_text_iter_compare (start, end) > 0) {
2294 real_start = *start;
2298 GSList *tags = gtk_text_iter_get_tags (&real_start);
2300 for (node = tags; node != NULL; node = g_slist_next (node)) {
2301 GtkTextTag *tag = (GtkTextTag *) node->data;
2302 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2303 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2305 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2307 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2310 } while (gtk_text_iter_forward_char (&real_start)&&
2311 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2315 msg_body_focus (GtkWidget *focus,
2316 GdkEventFocus *event,
2320 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2325 recpt_field_changed (GtkTextBuffer *buffer,
2326 ModestMsgEditWindow *editor)
2328 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2329 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2330 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2331 gboolean dim = FALSE;
2334 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2335 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2336 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2338 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2339 gtk_text_buffer_get_char_count (cc_buffer) +
2340 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2342 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2343 gtk_action_set_sensitive (action, !dim);
2344 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2345 gtk_action_set_sensitive (action, !dim);
2349 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2351 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2355 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2357 gboolean rich_text, editor_focused;
2359 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2360 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2361 editor_focused = gtk_widget_is_focus (priv->msg_body);
2364 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2365 else if (!editor_focused)
2366 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2370 reset_modified (ModestMsgEditWindow *editor)
2372 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2373 GtkTextBuffer *buffer;
2375 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2376 gtk_text_buffer_set_modified (buffer, FALSE);
2377 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2378 gtk_text_buffer_set_modified (buffer, FALSE);
2379 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2380 gtk_text_buffer_set_modified (buffer, FALSE);
2381 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2385 is_modified (ModestMsgEditWindow *editor)
2387 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2388 GtkTextBuffer *buffer;
2390 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2391 if (gtk_text_buffer_get_modified (buffer))
2393 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2394 if (gtk_text_buffer_get_modified (buffer))
2396 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2397 if (gtk_text_buffer_get_modified (buffer))
2399 if (gtk_text_buffer_get_modified (priv->text_buffer))
2406 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2408 ModestMsgEditWindowPrivate *priv = NULL;
2410 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2411 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2413 /* check if there's no recipient added */
2414 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2415 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2416 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2417 /* no recipient contents, then select contacts */
2418 modest_msg_edit_window_open_addressbook (window, NULL);
2422 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2424 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2426 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2429 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2436 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2437 ModestMsgEditWindow *window)
2439 modest_msg_edit_window_attach_file (window);
2443 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2445 ModestMsgEditWindow *window)
2447 ModestWindowPrivate *parent_priv;
2452 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2453 selection = gtk_clipboard_wait_for_text (clipboard);
2454 focused = gtk_window_get_focus (GTK_WINDOW (window));
2456 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2457 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2458 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2459 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2463 update_window_title (ModestMsgEditWindow *window)
2465 ModestMsgEditWindowPrivate *priv = NULL;
2466 const gchar *subject;
2468 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2469 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2470 if (subject == NULL || subject[0] == '\0')
2471 subject = _("mail_va_new_email");
2473 gtk_window_set_title (GTK_WINDOW (window), subject);
2478 subject_field_changed (GtkEditable *editable,
2479 ModestMsgEditWindow *window)
2481 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2482 update_window_title (window);
2483 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2487 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2490 ModestMsgEditWindowPrivate *priv = NULL;
2492 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2493 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2495 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2497 gtk_widget_show_all (priv->find_toolbar);
2498 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2500 gtk_widget_hide_all (priv->find_toolbar);
2501 gtk_widget_grab_focus (priv->msg_body);
2507 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2508 ModestMsgEditWindow *window)
2510 gchar *current_search = NULL;
2511 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2513 GtkTextIter selection_start, selection_end;
2514 GtkTextIter match_start, match_end;
2516 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2517 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2518 g_free (current_search);
2522 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2523 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2525 GtkTextIter buffer_start;
2526 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2527 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2530 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2531 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2533 /* TODO: warning about non succesful search */
2535 g_free (current_search);
2539 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2540 ModestMsgEditWindow *window)
2542 GtkToggleAction *toggle;
2543 ModestWindowPrivate *parent_priv;
2544 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2546 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2547 gtk_toggle_action_set_active (toggle, FALSE);