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);
128 /* list my signals */
135 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
136 struct _ModestMsgEditWindowPrivate {
138 GtkWidget *header_box;
140 ModestPairList *from_field_protos;
141 GtkWidget *from_field;
145 GtkWidget *bcc_field;
146 GtkWidget *subject_field;
147 GtkWidget *attachments_view;
148 GtkWidget *priority_icon;
149 GtkWidget *add_attachment_button;
151 GtkWidget *cc_caption;
152 GtkWidget *bcc_caption;
153 GtkWidget *attachments_caption;
155 GtkTextBuffer *text_buffer;
157 GtkWidget *font_size_toolitem;
158 GtkWidget *font_face_toolitem;
159 GtkWidget *font_color_button;
160 GSList *font_items_group;
161 GtkWidget *font_tool_button_label;
162 GSList *size_items_group;
163 GtkWidget *size_tool_button_label;
165 GtkWidget *find_toolbar;
172 TnyHeaderFlags priority_flags;
176 gulong clipboard_change_handler_id;
181 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
182 MODEST_TYPE_MSG_EDIT_WINDOW, \
183 ModestMsgEditWindowPrivate))
185 static GtkWindowClass *parent_class = NULL;
187 /* uncomment the following if you have defined any signals */
188 /* static guint signals[LAST_SIGNAL] = {0}; */
191 modest_msg_edit_window_get_type (void)
193 static GType my_type = 0;
195 static const GTypeInfo my_info = {
196 sizeof(ModestMsgEditWindowClass),
197 NULL, /* base init */
198 NULL, /* base finalize */
199 (GClassInitFunc) modest_msg_edit_window_class_init,
200 NULL, /* class finalize */
201 NULL, /* class data */
202 sizeof(ModestMsgEditWindow),
204 (GInstanceInitFunc) modest_msg_edit_window_init,
207 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
208 "ModestMsgEditWindow",
211 wp_text_buffer_library_init ();
217 save_state (ModestWindow *self)
219 modest_widget_memory_save (modest_runtime_get_conf(),
220 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
225 restore_settings (ModestMsgEditWindow *self)
227 modest_widget_memory_restore (modest_runtime_get_conf(),
228 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
233 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
235 GObjectClass *gobject_class;
236 ModestWindowClass *modest_window_class;
237 gobject_class = (GObjectClass*) klass;
238 modest_window_class = (ModestWindowClass*) klass;
240 parent_class = g_type_class_peek_parent (klass);
241 gobject_class->finalize = modest_msg_edit_window_finalize;
243 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
244 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
245 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
246 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
247 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
249 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
251 modest_window_class->save_state_func = save_state;
255 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
257 ModestMsgEditWindowPrivate *priv;
258 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
260 priv->msg_body = NULL;
261 priv->from_field = NULL;
262 priv->to_field = NULL;
263 priv->cc_field = NULL;
264 priv->bcc_field = NULL;
265 priv->subject_field = NULL;
266 priv->attachments = NULL;
268 priv->zoom_level = 1.0;
270 priv->cc_caption = NULL;
271 priv->bcc_caption = NULL;
273 priv->priority_flags = 0;
275 priv->find_toolbar = NULL;
277 priv->draft_msg = NULL;
278 priv->clipboard_change_handler_id = 0;
282 /* FIXME: this is a dup from the one in gtk/ */
285 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
287 static ModestPairList*
288 get_transports (void)
290 GSList *transports = NULL;
292 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
293 GSList *accounts = modest_account_mgr_account_names (account_mgr,
294 TRUE /* only enabled accounts. */);
296 GSList *cursor = accounts;
298 gchar *account_name = cursor->data;
299 gchar *from_string = NULL;
301 from_string = modest_account_mgr_get_from_string (account_mgr,
305 if (from_string && account_name) {
306 gchar *name = account_name;
307 ModestPair *pair = modest_pair_new ((gpointer) name,
308 (gpointer) from_string , TRUE);
309 transports = g_slist_prepend (transports, pair);
312 cursor = cursor->next;
314 g_slist_free (accounts); /* only free the accounts, not the elements,
315 * because they are used in the pairlist */
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;
564 TnyHeaderFlags priority_flags;
566 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
567 g_return_if_fail (TNY_IS_MSG (msg));
569 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
571 header = tny_msg_get_header (msg);
572 to = tny_header_get_to (header);
573 cc = tny_header_get_cc (header);
574 bcc = tny_header_get_bcc (header);
575 subject = tny_header_get_subject (header);
576 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
579 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
581 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
583 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
585 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
586 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
589 update_window_title (self);
591 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
592 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
593 body = modest_tny_msg_get_body (msg, TRUE);
595 if ((body == NULL)||(body[0] == '\0')) {
597 body = modest_text_utils_convert_to_html ("");
599 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
600 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
603 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
606 /* Get the default format required from configuration */
607 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
608 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
611 /* Set the default focus depending on having already a To: field or not */
612 if ((!to)||(*to == '\0')) {
613 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
615 gtk_widget_grab_focus (priv->msg_body);
618 /* TODO: lower priority, select in the From: combo to the
619 value that comes from msg <- not sure, should it be
622 /* Add attachments to the view */
623 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
624 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
625 if (priv->attachments == NULL) {
626 gtk_widget_hide (priv->attachments_caption);
628 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
629 gtk_widget_show_all (priv->attachments_caption);
632 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
633 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
635 reset_modified (self);
637 update_dimmed (self);
638 text_buffer_can_undo (priv->text_buffer, FALSE, self);
640 priv->draft_msg = msg;
644 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
647 GList *item_children, *node;
648 GtkWidget *bin_child;
650 bin_child = gtk_bin_get_child (GTK_BIN(item));
652 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
654 for (node = item_children; node != NULL; node = g_list_next (node)) {
655 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
656 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
659 g_list_free (item_children);
663 menu_tool_button_dont_expand (GtkMenuToolButton *item)
666 GList *item_children, *node;
668 box = gtk_bin_get_child (GTK_BIN (item));
669 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
670 item_children = gtk_container_get_children (GTK_CONTAINER (box));
672 for (node = item_children; node != NULL; node = g_list_next (node)) {
673 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
674 if (GTK_IS_TOGGLE_BUTTON (node->data))
675 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
676 else if (GTK_IS_BUTTON (node->data))
677 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
679 g_list_free (item_children);
684 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
686 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
687 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
688 GtkWidget *placeholder;
689 GtkWidget *tool_item;
694 GtkWidget *sizes_menu;
695 GtkWidget *fonts_menu;
696 GSList *radio_group = NULL;
701 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
702 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
704 /* should we hide the toolbar? */
705 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
706 gtk_widget_hide (parent_priv->toolbar);
708 /* Font color placeholder */
709 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
710 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
713 tool_item = GTK_WIDGET (gtk_tool_item_new ());
714 priv->font_color_button = hildon_color_button_new ();
715 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
716 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
717 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
718 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
719 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
720 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
721 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
723 /* Font size and face placeholder */
724 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
725 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
727 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
728 priv->size_tool_button_label = gtk_label_new (NULL);
729 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
730 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
731 size_text,"</span>", NULL);
732 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
734 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
735 sizes_menu = gtk_menu_new ();
736 priv->size_items_group = NULL;
738 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
739 GtkWidget *size_menu_item;
741 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
742 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
743 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
744 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
745 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
746 gtk_widget_show (size_menu_item);
748 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
752 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
753 GtkWidget *item = (GtkWidget *) node->data;
754 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
758 priv->size_items_group = g_slist_reverse (priv->size_items_group);
759 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
760 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
761 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
762 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
763 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
764 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
765 priv->font_size_toolitem = tool_item;
768 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
769 priv->font_tool_button_label = gtk_label_new (NULL);
770 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
771 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
773 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
774 fonts_menu = gtk_menu_new ();
775 priv->font_items_group = NULL;
777 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
778 GtkWidget *font_menu_item;
779 GtkWidget *child_label;
781 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
782 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
783 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
784 wp_get_font_name (font_index), "</span>", NULL);
785 gtk_label_set_markup (GTK_LABEL (child_label), markup);
788 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
789 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
790 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
791 gtk_widget_show (font_menu_item);
793 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
796 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
797 GtkWidget *item = (GtkWidget *) node->data;
798 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
801 priv->font_items_group = g_slist_reverse (priv->font_items_group);
802 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
803 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
804 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
805 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
806 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
807 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
808 priv->font_face_toolitem = tool_item;
810 /* Set expand and homogeneous for remaining items */
811 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
812 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
813 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
814 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
815 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
816 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
817 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
818 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
819 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
827 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
830 ModestWindowPrivate *parent_priv;
831 ModestMsgEditWindowPrivate *priv;
832 GtkActionGroup *action_group;
833 GError *error = NULL;
834 GdkPixbuf *window_icon = NULL;
837 gboolean prefer_formatted;
839 ModestPair *account_pair = NULL;
841 g_return_val_if_fail (msg, NULL);
842 g_return_val_if_fail (account_name, NULL);
844 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
846 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
847 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
849 parent_priv->ui_manager = gtk_ui_manager_new();
850 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
851 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
853 /* Add common actions */
854 gtk_action_group_add_actions (action_group,
855 modest_msg_edit_action_entries,
856 G_N_ELEMENTS (modest_msg_edit_action_entries),
858 gtk_action_group_add_toggle_actions (action_group,
859 modest_msg_edit_toggle_action_entries,
860 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
862 gtk_action_group_add_radio_actions (action_group,
863 modest_msg_edit_alignment_radio_action_entries,
864 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
866 G_CALLBACK (modest_ui_actions_on_change_justify),
868 gtk_action_group_add_radio_actions (action_group,
869 modest_msg_edit_zoom_action_entries,
870 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
872 G_CALLBACK (modest_ui_actions_on_change_zoom),
874 gtk_action_group_add_radio_actions (action_group,
875 modest_msg_edit_priority_action_entries,
876 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
878 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
880 gtk_action_group_add_radio_actions (action_group,
881 modest_msg_edit_file_format_action_entries,
882 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
883 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
884 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
886 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
887 g_object_unref (action_group);
889 /* Load the UI definition */
890 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
893 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
894 g_clear_error (&error);
897 /* Add accelerators */
898 gtk_window_add_accel_group (GTK_WINDOW (obj),
899 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
902 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
903 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
906 init_window (MODEST_MSG_EDIT_WINDOW(obj));
908 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
910 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
912 g_signal_connect (G_OBJECT(obj), "delete-event",
913 G_CALLBACK(on_delete_event), obj);
915 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
917 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
919 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
921 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
922 if (account_pair != NULL)
923 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
925 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
927 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
929 /* Set window icon */
930 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
931 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
933 /* Dim at start clipboard actions */
934 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
935 gtk_action_set_sensitive (action, FALSE);
936 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
937 gtk_action_set_sensitive (action, FALSE);
939 /* set initial state of cc and bcc */
940 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
941 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
942 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
943 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
944 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
945 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
947 /* Setup the file format */
948 conf = modest_runtime_get_conf ();
949 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
951 g_clear_error (&error);
952 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
954 file_format = (prefer_formatted) ?
955 MODEST_FILE_FORMAT_FORMATTED_TEXT :
956 MODEST_FILE_FORMAT_PLAIN_TEXT;
957 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
959 return (ModestWindow*) obj;
963 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
965 GString **string_buffer = (GString **) user_data;
967 *string_buffer = g_string_append (*string_buffer, buffer);
973 * @result: A new string which should be freed with g_free().
976 get_formatted_data (ModestMsgEditWindow *edit_window)
978 ModestMsgEditWindowPrivate *priv;
979 GString *string_buffer = g_string_new ("");
981 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
983 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
985 return g_string_free (string_buffer, FALSE);
990 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
993 const gchar *account_name;
994 ModestMsgEditWindowPrivate *priv;
996 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
998 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1000 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1001 g_return_val_if_fail (account_name, NULL);
1004 /* don't free these (except from) */
1005 data = g_slice_new0 (MsgData);
1006 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1008 data->account_name = g_strdup (account_name);
1009 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1010 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1011 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1012 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1013 if (priv->draft_msg) {
1014 data->draft_msg = g_object_ref (priv->draft_msg);
1016 data->draft_msg = NULL;
1019 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1021 gtk_text_buffer_get_bounds (buf, &b, &e);
1022 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1024 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1025 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1027 data->html_body = NULL;
1029 data->attachments = priv->attachments; /* TODO: copy and free ? */
1030 data->priority_flags = priv->priority_flags;
1035 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1037 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1040 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1048 g_free (data->subject);
1049 g_free (data->plain_body);
1050 g_free (data->html_body);
1051 if (data->draft_msg != NULL) {
1052 g_object_unref (data->draft_msg);
1053 data->draft_msg = NULL;
1055 g_free (data->account_name);
1057 /* TODO: Free data->attachments? */
1059 g_slice_free (MsgData, data);
1063 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1066 ModestMsgEditWindowPrivate *priv = NULL;
1067 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1069 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1071 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1073 return MODEST_MSG_EDIT_FORMAT_HTML;
1075 return MODEST_MSG_EDIT_FORMAT_TEXT;
1079 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1080 ModestMsgEditFormat format)
1082 ModestMsgEditWindowPrivate *priv;
1084 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1085 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1088 case MODEST_MSG_EDIT_FORMAT_HTML:
1089 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1091 case MODEST_MSG_EDIT_FORMAT_TEXT:
1092 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1095 g_return_if_reached ();
1099 ModestMsgEditFormatState *
1100 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1102 ModestMsgEditFormatState *format_state = NULL;
1103 ModestMsgEditWindowPrivate *priv;
1104 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1106 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1107 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1109 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1111 format_state = g_new0 (ModestMsgEditFormatState, 1);
1112 format_state->bold = buffer_format->bold&0x1;
1113 format_state->italics = buffer_format->italic&0x1;
1114 format_state->bullet = buffer_format->bullet&0x1;
1115 format_state->color = buffer_format->color;
1116 format_state->font_size = buffer_format->font_size;
1117 format_state->font_family = wp_get_font_name (buffer_format->font);
1118 format_state->justification = buffer_format->justification;
1119 g_free (buffer_format);
1121 return format_state;
1126 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1127 const ModestMsgEditFormatState *format_state)
1129 ModestMsgEditWindowPrivate *priv;
1130 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1131 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1132 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1133 g_return_if_fail (format_state != NULL);
1135 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1136 gtk_widget_grab_focus (priv->msg_body);
1137 buffer_format->bold = (format_state->bold != FALSE);
1138 buffer_format->italic = (format_state->italics != FALSE);
1139 buffer_format->color = format_state->color;
1140 buffer_format->font_size = format_state->font_size;
1141 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1142 buffer_format->justification = format_state->justification;
1143 buffer_format->bullet = format_state->bullet;
1145 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1147 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1148 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1149 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1150 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1151 buffer_format->cs.font = (buffer_format->font != current_format->font);
1152 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1153 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1155 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1156 if (buffer_format->cs.bold) {
1157 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1159 if (buffer_format->cs.italic) {
1160 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1162 if (buffer_format->cs.color) {
1163 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1165 if (buffer_format->cs.font_size) {
1166 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1168 if (buffer_format->cs.justification) {
1169 switch (buffer_format->justification) {
1170 case GTK_JUSTIFY_LEFT:
1171 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1173 case GTK_JUSTIFY_CENTER:
1174 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1176 case GTK_JUSTIFY_RIGHT:
1177 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1184 if (buffer_format->cs.font) {
1185 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1187 if (buffer_format->cs.bullet) {
1188 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1190 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1191 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1193 g_free (current_format);
1198 toggle_action_set_active_block_notify (GtkToggleAction *action,
1201 GSList *proxies = NULL;
1203 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1204 proxies != NULL; proxies = g_slist_next (proxies)) {
1205 GtkWidget *widget = (GtkWidget *) proxies->data;
1206 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1209 gtk_toggle_action_set_active (action, value);
1211 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1212 proxies != NULL; proxies = g_slist_next (proxies)) {
1213 GtkWidget *widget = (GtkWidget *) proxies->data;
1214 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1219 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1221 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1223 ModestWindowPrivate *parent_priv;
1224 ModestMsgEditWindowPrivate *priv;
1225 GtkWidget *new_size_menuitem;
1226 GtkWidget *new_font_menuitem;
1228 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1229 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1231 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1232 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1233 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1234 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1236 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1237 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1238 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1241 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1243 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1244 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1246 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1247 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1249 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1250 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1252 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1253 G_CALLBACK (modest_msg_edit_window_color_button_change),
1255 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1256 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1257 G_CALLBACK (modest_msg_edit_window_color_button_change),
1260 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1261 buffer_format->font_size))->data);
1262 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1266 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1267 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1268 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1270 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1271 G_CALLBACK (modest_msg_edit_window_size_change),
1273 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1274 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1275 G_CALLBACK (modest_msg_edit_window_size_change),
1279 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1280 buffer_format->font))->data);
1281 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1285 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1286 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1287 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1289 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1290 G_CALLBACK (modest_msg_edit_window_font_change),
1292 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1293 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1294 G_CALLBACK (modest_msg_edit_window_font_change),
1298 g_free (buffer_format);
1304 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1307 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1308 ModestMsgEditWindowPrivate *priv;
1309 GtkWidget *dialog = NULL;
1311 const GdkColor *new_color = NULL;
1313 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1314 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1316 #ifdef MODEST_HILDON_VERSION_0
1317 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1318 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1320 dialog = hildon_color_chooser_new ();
1321 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1322 #endif /*MODEST_HILDON_VERSION_0*/
1323 g_free (buffer_format);
1325 response = gtk_dialog_run (GTK_DIALOG (dialog));
1327 case GTK_RESPONSE_OK: {
1328 #ifdef MODEST_HILDON_VERSION_0
1329 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1332 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1334 #endif /*MODEST_HILDON_VERSION_0*/
1341 gtk_widget_destroy (dialog);
1343 if (new_color != NULL)
1344 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1349 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1352 ModestMsgEditWindowPrivate *priv;
1353 GtkWidget *dialog = NULL;
1355 GdkColor *old_color = NULL;
1356 const GdkColor *new_color = NULL;
1358 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1359 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1361 #ifdef MODEST_HILDON_VERSION_0
1362 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1363 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1365 dialog = hildon_color_chooser_new ();
1366 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1367 #endif /*MODEST_HILDON_VERSION_9*/
1369 response = gtk_dialog_run (GTK_DIALOG (dialog));
1371 case GTK_RESPONSE_OK: {
1372 #ifdef MODEST_HILDON_VERSION_0
1373 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1376 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1378 #endif /*MODEST_HILDON_VERSION_0*/
1384 gtk_widget_destroy (dialog);
1386 if (new_color != NULL)
1387 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1392 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1395 ModestMsgEditWindowPrivate *priv;
1396 GtkWidget *dialog = NULL;
1398 gchar *filename = NULL;
1400 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1402 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1404 response = gtk_dialog_run (GTK_DIALOG (dialog));
1406 case GTK_RESPONSE_OK:
1407 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1412 gtk_widget_destroy (dialog);
1415 GdkPixbuf *pixbuf = NULL;
1416 GtkTextIter position;
1417 GtkTextMark *insert_mark;
1419 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1422 GdkPixbufFormat *pixbuf_format;
1424 image_file_id = g_open (filename, O_RDONLY, 0);
1425 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1426 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1427 TnyMimePart *image_part;
1428 TnyStream *image_stream;
1434 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1435 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1436 mime_type = mime_types[0];
1438 mime_type = "image/unknown";
1440 image_part = tny_platform_factory_new_mime_part
1441 (modest_runtime_get_platform_factory ());
1442 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1444 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1445 g_strfreev (mime_types);
1447 content_id = g_strdup_printf ("%d", priv->last_cid);
1448 tny_mime_part_set_content_id (image_part, content_id);
1449 g_free (content_id);
1452 basename = g_path_get_basename (filename);
1453 tny_mime_part_set_filename (image_part, basename);
1456 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1457 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1458 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1459 priv->attachments = g_list_prepend (priv->attachments, image_part);
1460 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1462 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1463 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1464 gtk_widget_show_all (priv->attachments_caption);
1465 } else if (image_file_id == -1) {
1466 close (image_file_id);
1475 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1478 ModestMsgEditWindowPrivate *priv;
1479 GtkWidget *dialog = NULL;
1481 gchar *uri = NULL, *filename = NULL;
1483 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1485 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1487 response = gtk_dialog_run (GTK_DIALOG (dialog));
1489 case GTK_RESPONSE_OK:
1490 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1491 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1496 gtk_widget_destroy (dialog);
1500 GnomeVFSHandle *handle = NULL;
1501 GnomeVFSResult result;
1503 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1504 if (result == GNOME_VFS_OK) {
1505 TnyMimePart *mime_part;
1507 const gchar *mime_type = NULL;
1510 GnomeVFSFileInfo info;
1512 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1513 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1514 mime_part = tny_platform_factory_new_mime_part
1515 (modest_runtime_get_platform_factory ());
1516 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1518 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1520 content_id = g_strdup_printf ("%d", priv->last_cid);
1521 tny_mime_part_set_content_id (mime_part, content_id);
1522 g_free (content_id);
1525 basename = g_path_get_basename (filename);
1526 tny_mime_part_set_filename (mime_part, basename);
1529 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1530 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1532 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1533 gtk_widget_show_all (priv->attachments_caption);
1534 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1541 modest_msg_edit_window_attach_file_noninteractive (
1542 ModestMsgEditWindow *window,
1543 const gchar *file_uri)
1546 ModestMsgEditWindowPrivate *priv;
1548 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1553 /* TODO: We should probably try to use only the URI,
1554 * instead of using a filename.
1556 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1558 g_warning("%s: g_filename_from_uri(%s) failed.\n", __FUNCTION__, file_uri);
1561 file_id = g_open (filename, O_RDONLY, 0);
1562 if (file_id != -1) {
1563 TnyMimePart *mime_part;
1565 const gchar *mime_type;
1569 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1570 mime_part = tny_platform_factory_new_mime_part
1571 (modest_runtime_get_platform_factory ());
1572 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1574 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1576 content_id = g_strdup_printf ("%d", priv->last_cid);
1577 tny_mime_part_set_content_id (mime_part, content_id);
1578 g_free (content_id);
1581 basename = g_path_get_basename (filename);
1582 tny_mime_part_set_filename (mime_part, basename);
1585 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1586 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1588 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1589 gtk_widget_show_all (priv->attachments_caption);
1590 } else if (file_id == -1) {
1592 g_warning("file to be attached does not exist: %s", filename);
1600 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1603 ModestMsgEditWindowPrivate *priv;
1604 gboolean clean_list = FALSE;
1606 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1607 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1609 if (att_list == NULL) {
1610 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1614 if (att_list == NULL) {
1615 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1617 GtkWidget *confirmation_dialog = NULL;
1618 gboolean dialog_response;
1620 gchar *message = NULL;
1621 const gchar *filename = NULL;
1623 if (att_list->next == NULL) {
1624 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1628 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1629 att_list->next == NULL), filename);
1630 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1632 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1633 gtk_widget_destroy (confirmation_dialog);
1634 if (!dialog_response) {
1636 g_list_free (att_list);
1639 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1641 for (node = att_list; node != NULL; node = g_list_next (node)) {
1642 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1643 const gchar *att_id;
1644 priv->attachments = g_list_remove (priv->attachments, mime_part);
1646 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1648 if (priv->attachments == NULL)
1649 gtk_widget_hide (priv->attachments_caption);
1650 att_id = tny_mime_part_get_content_id (mime_part);
1652 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1654 g_object_unref (mime_part);
1655 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1660 g_list_free (att_list);
1664 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1667 ModestMsgEditWindowPrivate *priv;
1668 GdkColor *new_color;
1669 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1671 #ifdef MODEST_HILDON_VERSION_0
1672 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1675 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1677 #endif /*MODEST_HILDON_VERSION_0*/
1679 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1681 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1686 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1689 ModestMsgEditWindowPrivate *priv;
1690 gint new_size_index;
1691 ModestMsgEditWindow *window;
1694 window = MODEST_MSG_EDIT_WINDOW (userdata);
1695 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1696 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1698 if (gtk_check_menu_item_get_active (menu_item)) {
1700 WPTextBufferFormat format;
1702 memset (&format, 0, sizeof (format));
1703 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1705 label = gtk_bin_get_child (GTK_BIN (menu_item));
1707 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1708 format.cs.font_size = TRUE;
1709 format.cs.text_position = TRUE;
1710 format.cs.font = TRUE;
1711 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1712 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1714 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1715 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1716 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1718 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1719 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1720 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1726 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1729 ModestMsgEditWindowPrivate *priv;
1730 gint new_font_index;
1731 ModestMsgEditWindow *window;
1734 window = MODEST_MSG_EDIT_WINDOW (userdata);
1735 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1736 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1738 if (gtk_check_menu_item_get_active (menu_item)) {
1741 label = gtk_bin_get_child (GTK_BIN (menu_item));
1743 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1745 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1746 (gpointer) new_font_index))
1747 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1749 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1750 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1751 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1757 modest_msg_edit_window_set_zoom (ModestWindow *window,
1760 ModestMsgEditWindowPrivate *priv;
1762 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1764 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1765 priv->zoom_level = zoom;
1766 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1770 modest_msg_edit_window_get_zoom (ModestWindow *window)
1772 ModestMsgEditWindowPrivate *priv;
1774 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1776 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1777 return priv->zoom_level;
1781 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1783 ModestWindowPrivate *parent_priv;
1784 GtkRadioAction *zoom_radio_action;
1785 GSList *group, *node;
1787 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1788 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1789 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1791 group = gtk_radio_action_get_group (zoom_radio_action);
1793 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1794 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1798 for (node = group; node != NULL; node = g_slist_next (node)) {
1799 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1800 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1808 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1810 ModestWindowPrivate *parent_priv;
1811 GtkRadioAction *zoom_radio_action;
1812 GSList *group, *node;
1814 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1815 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1816 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1818 group = gtk_radio_action_get_group (zoom_radio_action);
1820 for (node = group; node != NULL; node = g_slist_next (node)) {
1821 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1822 if (node->next != NULL) {
1823 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1826 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1834 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1836 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1837 ModestWindowPrivate *parent_priv;
1838 ModestWindowMgr *mgr;
1839 gboolean is_fullscreen;
1840 GtkAction *fs_toggle_action;
1843 mgr = modest_runtime_get_window_mgr ();
1844 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1846 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1848 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1849 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1850 if (is_fullscreen != active)
1851 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1859 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1861 ModestWindowPrivate *parent_priv;
1862 GtkAction *fs_toggle_action;
1865 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1867 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1868 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1869 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1873 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1876 ModestMsgEditWindowPrivate *priv = NULL;
1877 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1879 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1880 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1882 gtk_widget_show (priv->cc_caption);
1884 gtk_widget_hide (priv->cc_caption);
1885 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1889 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1892 ModestMsgEditWindowPrivate *priv = NULL;
1893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1895 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1896 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1898 gtk_widget_show (priv->bcc_caption);
1900 gtk_widget_hide (priv->bcc_caption);
1901 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1905 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1906 ModestRecptEditor *editor)
1908 ModestMsgEditWindowPrivate *priv;
1910 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1911 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1912 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1914 if (editor == NULL) {
1915 GtkWidget *view_focus;
1916 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1918 /* This code should be kept in sync with ModestRecptEditor. The
1919 textview inside the recpt editor is the one that really gets the
1920 focus. As it's inside a scrolled window, and this one inside the
1921 hbox recpt editor inherits from, we'll need to go up in the
1922 hierarchy to know if the text view is part of the recpt editor
1923 or if it's a different text entry */
1925 if (gtk_widget_get_parent (view_focus)) {
1926 GtkWidget *first_parent;
1928 first_parent = gtk_widget_get_parent (view_focus);
1929 if (gtk_widget_get_parent (first_parent) &&
1930 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1931 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1936 editor = MODEST_RECPT_EDITOR (priv->to_field);
1940 modest_address_book_select_addresses (editor);
1945 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1947 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1949 modest_msg_edit_window_open_addressbook (window, NULL);
1953 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1954 gboolean show_toolbar)
1956 ModestWindowPrivate *parent_priv;
1958 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1959 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1961 /* FIXME: we can not just use the code of
1962 modest_msg_edit_window_setup_toolbar because it has a
1963 mixture of both initialization and creation code. */
1966 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1968 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1972 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1973 TnyHeaderFlags priority_flags)
1975 ModestMsgEditWindowPrivate *priv;
1976 ModestWindowPrivate *parent_priv;
1978 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1980 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1981 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1982 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1984 if (priv->priority_flags != priority_flags) {
1985 GtkAction *priority_action = NULL;
1987 priv->priority_flags = priority_flags;
1989 switch (priority_flags) {
1990 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1991 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1992 gtk_widget_show (priv->priority_icon);
1993 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1994 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
1996 case TNY_HEADER_FLAG_LOW_PRIORITY:
1997 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1998 gtk_widget_show (priv->priority_icon);
1999 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2000 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2003 gtk_widget_hide (priv->priority_icon);
2004 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2005 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2008 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2009 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2014 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2017 ModestMsgEditWindowPrivate *priv;
2018 gint current_format;
2020 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2022 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2024 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2025 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2027 if (current_format != file_format) {
2028 switch (file_format) {
2029 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2030 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2032 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2036 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2037 response = gtk_dialog_run (GTK_DIALOG (dialog));
2038 gtk_widget_destroy (dialog);
2039 if (response == GTK_RESPONSE_OK)
2040 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2044 update_dimmed (window);
2049 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2052 ModestMsgEditWindowPrivate *priv;
2053 WPTextBufferFormat oldfmt, fmt;
2054 gint old_position = 0;
2058 GdkColor *color = NULL;
2059 gboolean bold, bold_set, italic, italic_set;
2060 gboolean underline, underline_set;
2061 gboolean strikethrough, strikethrough_set;
2062 gboolean position_set;
2063 gboolean font_size_set, font_set, color_set;
2066 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2067 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2069 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2071 /* First we get the currently selected font information */
2072 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2073 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2075 switch (oldfmt.text_position) {
2076 case TEXT_POSITION_NORMAL:
2079 case TEXT_POSITION_SUPERSCRIPT:
2087 g_object_set (G_OBJECT (dialog),
2088 "bold", oldfmt.bold != FALSE,
2089 "bold-set", !oldfmt.cs.bold,
2090 "underline", oldfmt.underline != FALSE,
2091 "underline-set", !oldfmt.cs.underline,
2092 "italic", oldfmt.italic != FALSE,
2093 "italic-set", !oldfmt.cs.italic,
2094 "strikethrough", oldfmt.strikethrough != FALSE,
2095 "strikethrough-set", !oldfmt.cs.strikethrough,
2096 "color", &oldfmt.color,
2097 "color-set", !oldfmt.cs.color,
2098 "size", wp_font_size[oldfmt.font_size],
2099 "size-set", !oldfmt.cs.font_size,
2100 "position", old_position,
2101 "position-set", !oldfmt.cs.text_position,
2102 "family", wp_get_font_name (oldfmt.font),
2103 "family-set", !oldfmt.cs.font,
2106 gtk_widget_show_all (dialog);
2107 response = gtk_dialog_run (GTK_DIALOG (dialog));
2108 if (response == GTK_RESPONSE_OK) {
2110 g_object_get( dialog,
2112 "bold-set", &bold_set,
2113 "underline", &underline,
2114 "underline-set", &underline_set,
2116 "italic-set", &italic_set,
2117 "strikethrough", &strikethrough,
2118 "strikethrough-set", &strikethrough_set,
2120 "color-set", &color_set,
2122 "size-set", &font_size_set,
2123 "family", &font_name,
2124 "family-set", &font_set,
2125 "position", &position,
2126 "position-set", &position_set,
2131 if (response == GTK_RESPONSE_OK) {
2132 memset(&fmt, 0, sizeof(fmt));
2138 fmt.italic = italic;
2139 fmt.cs.italic = TRUE;
2141 if (underline_set) {
2142 fmt.underline = underline;
2143 fmt.cs.underline = TRUE;
2145 if (strikethrough_set) {
2146 fmt.strikethrough = strikethrough;
2147 fmt.cs.strikethrough = TRUE;
2152 ? TEXT_POSITION_NORMAL
2153 : ( ( position == 1 )
2154 ? TEXT_POSITION_SUPERSCRIPT
2155 : TEXT_POSITION_SUBSCRIPT );
2156 fmt.cs.text_position = TRUE;
2160 fmt.cs.color = TRUE;
2163 fmt.font = wp_get_font_index(font_name,
2168 if (font_size_set) {
2169 fmt.font_size = wp_get_font_size_index(
2170 font_size, DEFAULT_FONT_SIZE);
2171 fmt.cs.font_size = TRUE;
2173 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2175 gtk_widget_destroy (dialog);
2177 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2181 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2183 ModestMsgEditWindowPrivate *priv;
2185 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2186 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2188 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2190 update_dimmed (window);
2195 update_dimmed (ModestMsgEditWindow *window)
2197 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2198 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2202 gboolean editor_focused;
2204 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2205 editor_focused = gtk_widget_is_focus (priv->msg_body);
2207 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2208 gtk_action_set_sensitive (action, rich_text && editor_focused);
2209 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2210 gtk_action_set_sensitive (action, rich_text && editor_focused);
2211 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2212 gtk_action_set_sensitive (action, rich_text && editor_focused);
2213 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2214 gtk_action_set_sensitive (action, rich_text && editor_focused);
2215 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2216 gtk_action_set_sensitive (action, rich_text && editor_focused);
2217 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2218 gtk_action_set_sensitive (action, rich_text && editor_focused);
2219 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2220 gtk_action_set_sensitive (action, rich_text && editor_focused);
2221 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2222 gtk_action_set_sensitive (action, rich_text && editor_focused);
2223 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2224 gtk_action_set_sensitive (action, rich_text && editor_focused);
2225 widget = priv->font_color_button;
2226 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2227 widget = priv->font_size_toolitem;
2228 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2229 widget = priv->font_face_toolitem;
2230 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2234 setup_insensitive_handlers (ModestMsgEditWindow *window)
2236 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2237 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2240 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2241 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2242 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2243 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2245 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2246 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2247 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2248 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2249 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2250 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2251 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2252 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2253 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2254 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2255 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2256 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2257 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2258 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2259 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2260 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2261 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2262 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2263 widget = priv->font_color_button;
2264 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2265 widget = priv->font_size_toolitem;
2266 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2267 widget = priv->font_face_toolitem;
2268 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2273 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2275 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2278 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2279 gtk_action_set_sensitive (action, can_undo);
2283 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2286 GtkTextIter match_start, match_end;
2288 if (image_id == NULL)
2291 gtk_text_buffer_get_start_iter (buffer, &iter);
2293 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2294 GSList *tags = gtk_text_iter_get_tags (&match_start);
2296 for (node = tags; node != NULL; node = g_slist_next (node)) {
2297 GtkTextTag *tag = (GtkTextTag *) node->data;
2298 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2299 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2300 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2302 offset = gtk_text_iter_get_offset (&match_start);
2303 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2304 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2308 gtk_text_iter_forward_char (&iter);
2313 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2315 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2316 GtkTextIter real_start, real_end;
2317 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2319 if (gtk_text_iter_compare (start, end) > 0) {
2323 real_start = *start;
2327 GSList *tags = gtk_text_iter_get_tags (&real_start);
2329 for (node = tags; node != NULL; node = g_slist_next (node)) {
2330 GtkTextTag *tag = (GtkTextTag *) node->data;
2331 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2332 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2334 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2336 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2339 } while (gtk_text_iter_forward_char (&real_start)&&
2340 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2344 msg_body_focus (GtkWidget *focus,
2345 GdkEventFocus *event,
2349 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2354 recpt_field_changed (GtkTextBuffer *buffer,
2355 ModestMsgEditWindow *editor)
2357 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2358 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2359 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2360 gboolean dim = FALSE;
2363 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2364 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2365 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2367 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2368 gtk_text_buffer_get_char_count (cc_buffer) +
2369 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2371 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2372 gtk_action_set_sensitive (action, !dim);
2373 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2374 gtk_action_set_sensitive (action, !dim);
2378 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2380 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2384 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2386 gboolean rich_text, editor_focused;
2388 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2389 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2390 editor_focused = gtk_widget_is_focus (priv->msg_body);
2393 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2394 else if (!editor_focused)
2395 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2399 reset_modified (ModestMsgEditWindow *editor)
2401 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2402 GtkTextBuffer *buffer;
2404 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2405 gtk_text_buffer_set_modified (buffer, FALSE);
2406 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2407 gtk_text_buffer_set_modified (buffer, FALSE);
2408 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2409 gtk_text_buffer_set_modified (buffer, FALSE);
2410 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2414 is_modified (ModestMsgEditWindow *editor)
2416 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2417 GtkTextBuffer *buffer;
2419 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2420 if (gtk_text_buffer_get_modified (buffer))
2422 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2423 if (gtk_text_buffer_get_modified (buffer))
2425 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2426 if (gtk_text_buffer_get_modified (buffer))
2428 if (gtk_text_buffer_get_modified (priv->text_buffer))
2435 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2437 ModestMsgEditWindowPrivate *priv = NULL;
2439 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2440 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2442 /* check if there's no recipient added */
2443 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2444 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2445 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2446 /* no recipient contents, then select contacts */
2447 modest_msg_edit_window_open_addressbook (window, NULL);
2451 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2453 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2455 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2458 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2465 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2466 ModestMsgEditWindow *window)
2468 modest_msg_edit_window_attach_file (window);
2472 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2474 ModestMsgEditWindow *window)
2476 ModestWindowPrivate *parent_priv;
2481 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2482 selection = gtk_clipboard_wait_for_text (clipboard);
2483 focused = gtk_window_get_focus (GTK_WINDOW (window));
2485 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2486 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2487 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2488 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2492 update_window_title (ModestMsgEditWindow *window)
2494 ModestMsgEditWindowPrivate *priv = NULL;
2495 const gchar *subject;
2497 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2498 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2499 if (subject == NULL || subject[0] == '\0')
2500 subject = _("mail_va_new_email");
2502 gtk_window_set_title (GTK_WINDOW (window), subject);
2507 subject_field_changed (GtkEditable *editable,
2508 ModestMsgEditWindow *window)
2510 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2511 update_window_title (window);
2512 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2516 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2519 ModestMsgEditWindowPrivate *priv = NULL;
2521 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2522 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2524 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2526 gtk_widget_show_all (priv->find_toolbar);
2527 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2529 gtk_widget_hide_all (priv->find_toolbar);
2530 gtk_widget_grab_focus (priv->msg_body);
2536 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2537 ModestMsgEditWindow *window)
2539 gchar *current_search = NULL;
2540 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2542 GtkTextIter selection_start, selection_end;
2543 GtkTextIter match_start, match_end;
2545 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2546 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2547 g_free (current_search);
2551 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2552 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2554 GtkTextIter buffer_start;
2555 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2556 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2559 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2560 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2562 /* TODO: warning about non succesful search */
2564 g_free (current_search);
2568 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2569 ModestMsgEditWindow *window)
2571 GtkToggleAction *toggle;
2572 ModestWindowPrivate *parent_priv;
2573 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2575 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2576 gtk_toggle_action_set_active (toggle, FALSE);