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 #ifdef MODEST_HAVE_HILDON0_WIDGETS
67 #include <hildon-widgets/hildon-color-chooser.h>
69 #include "widgets/modest-msg-edit-window-ui.h"
70 #ifdef MODEST_HAVE_HILDON0_WIDGETS
71 #include <libgnomevfs/gnome-vfs-mime-utils.h>
73 #include <libgnomevfs/gnome-vfs-mime.h>
75 #include "modest-maemo-utils.h"
78 #define DEFAULT_FONT_SIZE 3
79 #define DEFAULT_FONT 2
80 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
81 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
82 #define DEFAULT_MAIN_VBOX_SPACING 6
83 #define SUBJECT_MAX_LENGTH 1000
84 #define IMAGE_MAX_WIDTH 640
86 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
87 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
88 static void modest_msg_edit_window_finalize (GObject *obj);
90 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
91 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
92 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
93 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
94 static void remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
95 static void zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
96 static void paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
97 static void copy_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
98 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
99 static void reset_modified (ModestMsgEditWindow *editor);
101 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
102 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
103 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
104 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
105 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
106 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
107 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
109 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
111 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
113 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
114 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
115 GdkEventWindowState *event,
117 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
118 ModestRecptEditor *editor);
119 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
120 ModestMsgEditWindow *window);
122 /* ModestWindow methods implementation */
123 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
124 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
125 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
126 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
127 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
128 gboolean show_toolbar);
129 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
131 ModestMsgEditWindow *window);
132 static void modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
134 ModestMsgEditWindow *window);
135 static void update_window_title (ModestMsgEditWindow *window);
136 static void update_dimmed (ModestMsgEditWindow *window);
137 static void update_paste_dimming (ModestMsgEditWindow *window);
138 static void update_select_all_dimming (ModestMsgEditWindow *window);
139 static void update_zoom_dimming (ModestMsgEditWindow *window);
142 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
143 ModestMsgEditWindow *window);
144 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
145 ModestMsgEditWindow *window);
146 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
148 GtkTextIter *match_start,
149 GtkTextIter *match_end);
153 /* static gboolean */
154 /* on_key_pressed (GtkWidget *self, */
155 /* GdkEventKey *event, */
156 /* gpointer user_data); */
158 static void edit_menu_activated (GtkAction *action,
160 static void view_menu_activated (GtkAction *action,
163 /* list my signals */
170 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
171 struct _ModestMsgEditWindowPrivate {
173 GtkWidget *header_box;
175 ModestPairList *from_field_protos;
176 GtkWidget *from_field;
180 GtkWidget *bcc_field;
181 GtkWidget *subject_field;
182 GtkWidget *attachments_view;
183 GtkWidget *priority_icon;
184 GtkWidget *add_attachment_button;
186 GtkWidget *cc_caption;
187 GtkWidget *bcc_caption;
188 GtkWidget *attachments_caption;
190 GtkTextBuffer *text_buffer;
192 GtkWidget *font_size_toolitem;
193 GtkWidget *font_face_toolitem;
194 GtkWidget *font_color_button;
195 GSList *font_items_group;
196 GtkWidget *font_tool_button_label;
197 GSList *size_items_group;
198 GtkWidget *size_tool_button_label;
200 GtkWidget *find_toolbar;
204 GtkWidget *scroll_area;
209 TnyHeaderFlags priority_flags;
213 gulong clipboard_change_handler_id;
214 gulong system_clipboard_change_handler_id;
220 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
221 MODEST_TYPE_MSG_EDIT_WINDOW, \
222 ModestMsgEditWindowPrivate))
224 static GtkWindowClass *parent_class = NULL;
226 /* uncomment the following if you have defined any signals */
227 /* static guint signals[LAST_SIGNAL] = {0}; */
230 modest_msg_edit_window_get_type (void)
232 static GType my_type = 0;
234 static const GTypeInfo my_info = {
235 sizeof(ModestMsgEditWindowClass),
236 NULL, /* base init */
237 NULL, /* base finalize */
238 (GClassInitFunc) modest_msg_edit_window_class_init,
239 NULL, /* class finalize */
240 NULL, /* class data */
241 sizeof(ModestMsgEditWindow),
243 (GInstanceInitFunc) modest_msg_edit_window_init,
246 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
247 "ModestMsgEditWindow",
250 wp_text_buffer_library_init ();
256 save_state (ModestWindow *self)
258 modest_widget_memory_save (modest_runtime_get_conf(),
259 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
264 restore_settings (ModestMsgEditWindow *self)
266 modest_widget_memory_restore (modest_runtime_get_conf(),
267 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
272 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
274 GObjectClass *gobject_class;
275 ModestWindowClass *modest_window_class;
276 gobject_class = (GObjectClass*) klass;
277 modest_window_class = (ModestWindowClass*) klass;
279 parent_class = g_type_class_peek_parent (klass);
280 gobject_class->finalize = modest_msg_edit_window_finalize;
282 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
283 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
284 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
285 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
286 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
287 modest_window_class->save_state_func = save_state;
289 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
295 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
297 ModestMsgEditWindowPrivate *priv;
298 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
300 priv->msg_body = NULL;
301 priv->from_field = NULL;
302 priv->to_field = NULL;
303 priv->cc_field = NULL;
304 priv->bcc_field = NULL;
305 priv->subject_field = NULL;
306 priv->attachments = NULL;
308 priv->zoom_level = 1.0;
310 priv->cc_caption = NULL;
311 priv->bcc_caption = NULL;
313 priv->priority_flags = 0;
315 priv->find_toolbar = NULL;
316 priv->last_search = NULL;
318 priv->draft_msg = NULL;
319 priv->clipboard_change_handler_id = 0;
320 priv->system_clipboard_change_handler_id = 0;
325 /* FIXME: this is a dup from the one in gtk/ */
328 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
330 static ModestPairList*
331 get_transports (void)
333 GSList *transports = NULL;
335 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
336 GSList *accounts = modest_account_mgr_account_names (account_mgr,
337 TRUE /* only enabled accounts. */);
339 GSList *cursor = accounts;
341 gchar *account_name = cursor->data;
342 gchar *from_string = NULL;
344 from_string = modest_account_mgr_get_from_string (account_mgr,
348 if (from_string && account_name) {
349 gchar *name = account_name;
350 ModestPair *pair = modest_pair_new ((gpointer) name,
351 (gpointer) from_string , TRUE);
352 transports = g_slist_prepend (transports, pair);
355 cursor = cursor->next;
357 g_slist_free (accounts); /* only free the accounts, not the elements,
358 * because they are used in the pairlist */
364 init_window (ModestMsgEditWindow *obj)
366 GtkWidget *from_caption, *to_caption, *subject_caption;
367 GtkWidget *main_vbox;
368 ModestMsgEditWindowPrivate *priv;
370 GtkSizeGroup *size_group;
372 GtkWidget *subject_box;
373 GtkWidget *attachment_icon;
374 GtkWidget *window_box;
376 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
378 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
380 /* Note: This ModestPairList* must exist for as long as the combo
381 * that uses it, because the ModestComboBox uses the ID opaquely,
382 * so it can't know how to manage its memory. */
383 priv->from_field_protos = get_transports ();
385 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
387 priv->to_field = modest_recpt_editor_new ();
388 priv->cc_field = modest_recpt_editor_new ();
389 priv->bcc_field = modest_recpt_editor_new ();
390 subject_box = gtk_hbox_new (FALSE, 0);
391 priv->priority_icon = gtk_image_new ();
392 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
393 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
394 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
395 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
396 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
397 priv->add_attachment_button = gtk_button_new ();
398 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
399 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
400 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
401 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
402 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
403 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
404 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
405 priv->attachments_view = modest_attachments_view_new (NULL);
407 priv->header_box = gtk_vbox_new (FALSE, 0);
409 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
410 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
411 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
412 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
413 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
414 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
415 g_object_unref (size_group);
417 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
418 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
419 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
420 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
421 gtk_size_group_add_widget (size_group, priv->subject_field);
422 gtk_size_group_add_widget (size_group, priv->attachments_view);
423 g_object_unref (size_group);
425 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
426 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
427 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
428 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
429 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
430 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
431 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
434 priv->msg_body = wp_text_view_new ();
435 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
436 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
437 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
438 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
439 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
440 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
442 priv->find_toolbar = hildon_find_toolbar_new (NULL);
443 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
445 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
447 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
448 G_CALLBACK (text_buffer_refresh_attributes), obj);
449 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
450 G_CALLBACK (text_buffer_delete_range), obj);
451 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
452 G_CALLBACK (text_buffer_can_undo), obj);
453 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
454 G_CALLBACK (text_buffer_can_redo), obj);
455 g_signal_connect (G_OBJECT (obj), "window-state-event",
456 G_CALLBACK (modest_msg_edit_window_window_state_event),
458 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
459 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
460 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
461 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
462 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
463 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
465 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
466 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
468 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
469 G_CALLBACK (msg_body_focus), obj);
470 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
471 G_CALLBACK (msg_body_focus), obj);
472 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
473 "changed", G_CALLBACK (recpt_field_changed), obj);
474 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
475 "changed", G_CALLBACK (recpt_field_changed), obj);
476 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
477 "changed", G_CALLBACK (recpt_field_changed), obj);
478 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
479 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
481 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
482 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
484 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
485 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
486 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
488 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
490 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
491 frame = gtk_frame_new (NULL);
492 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
494 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
495 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
496 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
498 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
499 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
500 gtk_widget_hide (priv->cc_caption);
502 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
503 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
504 gtk_widget_hide (priv->bcc_caption);
507 window_box = gtk_vbox_new (FALSE, 0);
508 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
509 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
510 gtk_container_add (GTK_CONTAINER(obj), window_box);
511 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
512 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
515 TODO: scroll_area was never instantiated.
516 Stop building without warnings-as-errors. murrayc.
517 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
518 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
521 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
522 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
523 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
524 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
530 modest_msg_edit_window_finalize (GObject *obj)
532 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
534 if (priv->clipboard_change_handler_id > 0) {
535 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
536 priv->clipboard_change_handler_id = 0;
539 if (priv->system_clipboard_change_handler_id > 0) {
540 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
541 priv->system_clipboard_change_handler_id);
542 priv->system_clipboard_change_handler_id = 0;
545 if (priv->draft_msg != NULL) {
546 g_object_unref (priv->draft_msg);
547 priv->draft_msg = NULL;
550 /* This had to stay alive for as long as the combobox that used it: */
551 modest_pair_list_free (priv->from_field_protos);
553 G_OBJECT_CLASS(parent_class)->finalize (obj);
557 menubar_to_menu (GtkUIManager *ui_manager)
559 GtkWidget *main_menu;
563 /* Create new main menu */
564 main_menu = gtk_menu_new();
566 /* Get the menubar from the UI manager */
567 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
569 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
573 menu = GTK_WIDGET (iter->data);
574 gtk_widget_reparent(menu, main_menu);
576 iter = g_list_next (iter);
583 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
586 const gchar *to, *cc, *bcc, *subject;
588 ModestMsgEditWindowPrivate *priv;
590 TnyHeaderFlags priority_flags;
592 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
593 g_return_if_fail (TNY_IS_MSG (msg));
595 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
597 header = tny_msg_get_header (msg);
598 to = tny_header_get_to (header);
599 cc = tny_header_get_cc (header);
600 bcc = tny_header_get_bcc (header);
601 subject = tny_header_get_subject (header);
602 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
605 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
607 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
608 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
609 gtk_widget_show (priv->cc_caption);
610 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
611 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
612 gtk_widget_hide (priv->cc_caption);
615 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
616 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
617 gtk_widget_show (priv->bcc_caption);
618 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
619 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
620 gtk_widget_hide (priv->bcc_caption);
623 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
624 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
627 update_window_title (self);
629 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
630 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
631 body = modest_tny_msg_get_body (msg, TRUE);
633 if ((body == NULL)||(body[0] == '\0')) {
635 body = modest_text_utils_convert_to_html ("");
637 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
638 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
641 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
644 /* Get the default format required from configuration */
645 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
646 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
649 /* Set the default focus depending on having already a To: field or not */
650 if ((!to)||(*to == '\0')) {
651 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
653 gtk_widget_grab_focus (priv->msg_body);
656 /* TODO: lower priority, select in the From: combo to the
657 value that comes from msg <- not sure, should it be
660 /* Add attachments to the view */
661 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
662 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
663 if (priv->attachments == NULL) {
664 gtk_widget_hide (priv->attachments_caption);
666 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
667 gtk_widget_show_all (priv->attachments_caption);
670 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
671 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
673 reset_modified (self);
675 update_dimmed (self);
676 text_buffer_can_undo (priv->text_buffer, FALSE, self);
677 text_buffer_can_redo (priv->text_buffer, FALSE, self);
679 priv->draft_msg = g_object_ref(msg);
683 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
686 GList *item_children, *node;
687 GtkWidget *bin_child;
689 bin_child = gtk_bin_get_child (GTK_BIN(item));
691 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
693 for (node = item_children; node != NULL; node = g_list_next (node)) {
694 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
695 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
698 g_list_free (item_children);
702 menu_tool_button_dont_expand (GtkMenuToolButton *item)
705 GList *item_children, *node;
707 box = gtk_bin_get_child (GTK_BIN (item));
708 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
709 item_children = gtk_container_get_children (GTK_CONTAINER (box));
711 for (node = item_children; node != NULL; node = g_list_next (node)) {
712 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
713 if (GTK_IS_TOGGLE_BUTTON (node->data))
714 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
715 else if (GTK_IS_BUTTON (node->data))
716 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
718 g_list_free (item_children);
723 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
725 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
726 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
727 GtkWidget *placeholder;
728 GtkWidget *tool_item;
733 GtkWidget *sizes_menu;
734 GtkWidget *fonts_menu;
735 GSList *radio_group = NULL;
740 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
741 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
743 /* should we hide the toolbar? */
744 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
745 gtk_widget_hide (parent_priv->toolbar);
747 /* Font color placeholder */
748 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
749 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
752 tool_item = GTK_WIDGET (gtk_tool_item_new ());
753 priv->font_color_button = hildon_color_button_new ();
754 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
755 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
756 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
757 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
758 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
759 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
760 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
762 /* Font size and face placeholder */
763 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
764 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
766 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
767 priv->size_tool_button_label = gtk_label_new (NULL);
768 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
769 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
770 size_text,"</span>", NULL);
771 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
773 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
774 sizes_menu = gtk_menu_new ();
775 priv->size_items_group = NULL;
777 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
778 GtkWidget *size_menu_item;
780 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
781 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
782 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
783 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
784 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
785 gtk_widget_show (size_menu_item);
787 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
791 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
792 GtkWidget *item = (GtkWidget *) node->data;
793 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
797 priv->size_items_group = g_slist_reverse (priv->size_items_group);
798 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_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_size_toolitem = tool_item;
807 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
808 priv->font_tool_button_label = gtk_label_new (NULL);
809 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
810 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
812 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
813 fonts_menu = gtk_menu_new ();
814 priv->font_items_group = NULL;
816 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
817 GtkWidget *font_menu_item;
818 GtkWidget *child_label;
820 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
821 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
822 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
823 wp_get_font_name (font_index), "</span>", NULL);
824 gtk_label_set_markup (GTK_LABEL (child_label), markup);
827 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
828 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
829 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
830 gtk_widget_show (font_menu_item);
832 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
835 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
836 GtkWidget *item = (GtkWidget *) node->data;
837 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
840 priv->font_items_group = g_slist_reverse (priv->font_items_group);
841 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
842 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
843 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
844 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
845 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
846 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
847 priv->font_face_toolitem = tool_item;
849 /* Set expand and homogeneous for remaining items */
850 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
851 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
852 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
853 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
854 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
855 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
856 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
857 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
858 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
866 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
869 ModestWindowPrivate *parent_priv;
870 ModestMsgEditWindowPrivate *priv;
871 GtkActionGroup *action_group;
872 GError *error = NULL;
873 GdkPixbuf *window_icon = NULL;
876 gboolean prefer_formatted;
878 ModestPair *account_pair = NULL;
880 g_return_val_if_fail (msg, NULL);
881 g_return_val_if_fail (account_name, NULL);
883 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
885 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
886 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
888 parent_priv->ui_manager = gtk_ui_manager_new();
889 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
890 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
892 /* Add common actions */
893 gtk_action_group_add_actions (action_group,
894 modest_msg_edit_action_entries,
895 G_N_ELEMENTS (modest_msg_edit_action_entries),
897 gtk_action_group_add_toggle_actions (action_group,
898 modest_msg_edit_toggle_action_entries,
899 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
901 gtk_action_group_add_radio_actions (action_group,
902 modest_msg_edit_alignment_radio_action_entries,
903 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
905 G_CALLBACK (modest_ui_actions_on_change_justify),
907 gtk_action_group_add_radio_actions (action_group,
908 modest_msg_edit_zoom_action_entries,
909 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
911 G_CALLBACK (modest_ui_actions_on_change_zoom),
913 gtk_action_group_add_radio_actions (action_group,
914 modest_msg_edit_priority_action_entries,
915 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
917 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
919 gtk_action_group_add_radio_actions (action_group,
920 modest_msg_edit_file_format_action_entries,
921 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
922 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
923 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
925 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
926 g_object_unref (action_group);
928 /* Load the UI definition */
929 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
932 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
933 g_clear_error (&error);
936 /* Add accelerators */
937 gtk_window_add_accel_group (GTK_WINDOW (obj),
938 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
941 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
942 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
945 init_window (MODEST_MSG_EDIT_WINDOW(obj));
947 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
949 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
951 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
953 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
955 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
956 if (account_pair != NULL)
957 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
959 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
961 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
963 /* Set window icon */
964 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
965 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
967 /* Dim at start clipboard actions */
968 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
969 gtk_action_set_sensitive (action, FALSE);
970 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
971 gtk_action_set_sensitive (action, FALSE);
972 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
973 gtk_action_set_sensitive (action, FALSE);
975 /* Update select all */
976 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
977 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
978 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
979 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
980 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
982 /* set initial state of cc and bcc */
983 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
984 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
985 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
986 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
987 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
988 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
990 /* Setup the file format */
991 conf = modest_runtime_get_conf ();
992 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
994 g_clear_error (&error);
995 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
997 file_format = (prefer_formatted) ?
998 MODEST_FILE_FORMAT_FORMATTED_TEXT :
999 MODEST_FILE_FORMAT_PLAIN_TEXT;
1000 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1002 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1004 return (ModestWindow*) obj;
1008 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1010 GString **string_buffer = (GString **) user_data;
1012 *string_buffer = g_string_append (*string_buffer, buffer);
1018 * @result: A new string which should be freed with g_free().
1021 get_formatted_data (ModestMsgEditWindow *edit_window)
1023 ModestMsgEditWindowPrivate *priv;
1024 GString *string_buffer = g_string_new ("");
1026 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1028 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1030 return g_string_free (string_buffer, FALSE);
1035 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1038 const gchar *account_name;
1039 ModestMsgEditWindowPrivate *priv;
1041 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1043 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1045 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1046 g_return_val_if_fail (account_name, NULL);
1049 /* don't free these (except from) */
1050 data = g_slice_new0 (MsgData);
1051 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1053 data->account_name = g_strdup (account_name);
1054 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1055 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1056 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1057 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1058 if (priv->draft_msg) {
1059 data->draft_msg = g_object_ref (priv->draft_msg);
1061 data->draft_msg = NULL;
1064 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1066 gtk_text_buffer_get_bounds (buf, &b, &e);
1067 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1069 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1070 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1072 data->html_body = NULL;
1074 /* deep-copy the data */
1075 GList *cursor = priv->attachments;
1076 data->attachments = NULL;
1078 data->attachments = g_list_append (data->attachments,
1079 g_strdup ((gchar*)cursor->data));
1080 cursor = g_list_next (cursor);
1084 data->priority_flags = priv->priority_flags;
1089 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1091 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1094 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1102 g_free (data->subject);
1103 g_free (data->plain_body);
1104 g_free (data->html_body);
1105 g_free (data->account_name);
1107 if (data->draft_msg != NULL) {
1108 g_object_unref (data->draft_msg);
1109 data->draft_msg = NULL;
1112 g_list_foreach (data->attachments, (GFunc)g_free, NULL);
1113 g_list_free (data->attachments);
1115 g_slice_free (MsgData, data);
1119 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1122 ModestMsgEditWindowPrivate *priv = NULL;
1123 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1125 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1127 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1129 return MODEST_MSG_EDIT_FORMAT_HTML;
1131 return MODEST_MSG_EDIT_FORMAT_TEXT;
1135 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1136 ModestMsgEditFormat format)
1138 ModestMsgEditWindowPrivate *priv;
1140 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1141 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1144 case MODEST_MSG_EDIT_FORMAT_HTML:
1145 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1147 case MODEST_MSG_EDIT_FORMAT_TEXT:
1148 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1151 g_return_if_reached ();
1155 ModestMsgEditFormatState *
1156 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1158 ModestMsgEditFormatState *format_state = NULL;
1159 ModestMsgEditWindowPrivate *priv;
1160 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1162 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1163 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1165 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1167 format_state = g_new0 (ModestMsgEditFormatState, 1);
1168 format_state->bold = buffer_format->bold&0x1;
1169 format_state->italics = buffer_format->italic&0x1;
1170 format_state->bullet = buffer_format->bullet&0x1;
1171 format_state->color = buffer_format->color;
1172 format_state->font_size = buffer_format->font_size;
1173 format_state->font_family = wp_get_font_name (buffer_format->font);
1174 format_state->justification = buffer_format->justification;
1175 g_free (buffer_format);
1177 return format_state;
1182 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1183 const ModestMsgEditFormatState *format_state)
1185 ModestMsgEditWindowPrivate *priv;
1186 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1187 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1188 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1189 g_return_if_fail (format_state != NULL);
1191 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1192 gtk_widget_grab_focus (priv->msg_body);
1193 buffer_format->bold = (format_state->bold != FALSE);
1194 buffer_format->italic = (format_state->italics != FALSE);
1195 buffer_format->color = format_state->color;
1196 buffer_format->font_size = format_state->font_size;
1197 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1198 buffer_format->justification = format_state->justification;
1199 buffer_format->bullet = format_state->bullet;
1201 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1203 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1204 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1205 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1206 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1207 buffer_format->cs.font = (buffer_format->font != current_format->font);
1208 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1209 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1211 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1212 if (buffer_format->cs.bold) {
1213 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1215 if (buffer_format->cs.italic) {
1216 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1218 if (buffer_format->cs.color) {
1219 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1221 if (buffer_format->cs.font_size) {
1222 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1224 if (buffer_format->cs.justification) {
1225 switch (buffer_format->justification) {
1226 case GTK_JUSTIFY_LEFT:
1227 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1229 case GTK_JUSTIFY_CENTER:
1230 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1232 case GTK_JUSTIFY_RIGHT:
1233 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1240 if (buffer_format->cs.font) {
1241 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1243 if (buffer_format->cs.bullet) {
1244 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1246 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1247 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1249 g_free (current_format);
1254 toggle_action_set_active_block_notify (GtkToggleAction *action,
1257 GSList *proxies = NULL;
1259 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1260 proxies != NULL; proxies = g_slist_next (proxies)) {
1261 GtkWidget *widget = (GtkWidget *) proxies->data;
1262 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1265 gtk_toggle_action_set_active (action, value);
1267 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1268 proxies != NULL; proxies = g_slist_next (proxies)) {
1269 GtkWidget *widget = (GtkWidget *) proxies->data;
1270 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1275 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1277 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1279 ModestWindowPrivate *parent_priv;
1280 ModestMsgEditWindowPrivate *priv;
1281 GtkWidget *new_size_menuitem;
1282 GtkWidget *new_font_menuitem;
1284 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1285 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1287 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1288 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1289 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1290 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1292 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1293 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1294 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1297 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1299 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1300 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1302 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1303 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1305 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1306 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1308 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1309 G_CALLBACK (modest_msg_edit_window_color_button_change),
1311 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1312 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1313 G_CALLBACK (modest_msg_edit_window_color_button_change),
1316 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1317 buffer_format->font_size))->data);
1318 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1322 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1323 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1324 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1326 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1327 G_CALLBACK (modest_msg_edit_window_size_change),
1329 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1330 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1331 G_CALLBACK (modest_msg_edit_window_size_change),
1335 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1336 buffer_format->font))->data);
1337 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1341 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1342 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1343 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1345 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1346 G_CALLBACK (modest_msg_edit_window_font_change),
1348 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1349 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1350 G_CALLBACK (modest_msg_edit_window_font_change),
1354 g_free (buffer_format);
1360 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1363 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1364 ModestMsgEditWindowPrivate *priv;
1365 GtkWidget *dialog = NULL;
1367 const GdkColor *new_color = NULL;
1369 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1370 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1372 #ifdef MODEST_HILDON_VERSION_0
1373 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1374 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1376 dialog = hildon_color_chooser_new ();
1377 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1378 #endif /*MODEST_HILDON_VERSION_0*/
1379 g_free (buffer_format);
1381 response = gtk_dialog_run (GTK_DIALOG (dialog));
1383 case GTK_RESPONSE_OK: {
1384 #ifdef MODEST_HILDON_VERSION_0
1385 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1388 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1390 #endif /*MODEST_HILDON_VERSION_0*/
1397 gtk_widget_destroy (dialog);
1399 if (new_color != NULL)
1400 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1405 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1408 ModestMsgEditWindowPrivate *priv;
1409 GtkWidget *dialog = NULL;
1411 GdkColor *old_color = NULL;
1412 const GdkColor *new_color = NULL;
1414 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1415 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1417 #ifdef MODEST_HILDON_VERSION_0
1418 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1419 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1421 dialog = hildon_color_chooser_new ();
1422 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1423 #endif /*MODEST_HILDON_VERSION_9*/
1425 response = gtk_dialog_run (GTK_DIALOG (dialog));
1427 case GTK_RESPONSE_OK: {
1428 #ifdef MODEST_HILDON_VERSION_0
1429 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1432 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1434 #endif /*MODEST_HILDON_VERSION_0*/
1440 gtk_widget_destroy (dialog);
1442 if (new_color != NULL)
1443 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1449 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1452 ModestMsgEditWindowPrivate *priv;
1453 GtkWidget *dialog = NULL;
1455 GSList *uris = NULL;
1456 GSList *uri_node = NULL;
1458 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1460 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1461 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1462 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1464 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1466 response = gtk_dialog_run (GTK_DIALOG (dialog));
1468 case GTK_RESPONSE_OK:
1469 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1474 gtk_widget_destroy (dialog);
1476 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1478 GnomeVFSHandle *handle = NULL;
1479 GnomeVFSResult result;
1480 GtkTextIter position;
1481 GtkTextMark *insert_mark;
1483 uri = (const gchar *) uri_node->data;
1484 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1485 if (result == GNOME_VFS_OK) {
1486 GdkPixbufLoader *loader;
1488 GnomeVFSFileInfo info;
1489 gchar *filename, *basename;
1490 TnyMimePart *mime_part;
1493 const gchar *mime_type = NULL;
1495 filename = g_filename_from_uri (uri, NULL, NULL);
1496 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1498 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1500 mime_part = tny_platform_factory_new_mime_part
1501 (modest_runtime_get_platform_factory ());
1502 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1504 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1506 content_id = g_strdup_printf ("%d", priv->last_cid);
1507 tny_mime_part_set_content_id (mime_part, content_id);
1508 g_free (content_id);
1511 basename = g_path_get_basename (filename);
1512 tny_mime_part_set_filename (mime_part, basename);
1515 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1516 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1518 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1519 gtk_widget_show_all (priv->attachments_caption);
1520 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1523 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1524 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1525 unsigned char read_buffer[128];
1527 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1528 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1531 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1532 g_object_ref (pixbuf);
1533 gdk_pixbuf_loader_close (loader, NULL);
1534 g_object_unref (loader);
1536 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1537 GdkPixbuf *new_pixbuf;
1539 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1540 gdk_pixbuf_get_width (pixbuf);
1541 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1542 g_object_unref (pixbuf);
1543 pixbuf = new_pixbuf;
1546 if (pixbuf != NULL) {
1547 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1548 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1549 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1558 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1561 ModestMsgEditWindowPrivate *priv;
1562 GtkWidget *dialog = NULL;
1564 GSList *uris = NULL;
1567 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1569 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1570 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1572 response = gtk_dialog_run (GTK_DIALOG (dialog));
1574 case GTK_RESPONSE_OK:
1575 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1580 gtk_widget_destroy (dialog);
1582 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1584 GnomeVFSHandle *handle = NULL;
1585 GnomeVFSResult result;
1587 uri = (const gchar *) uri_node->data;
1588 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1589 if (result == GNOME_VFS_OK) {
1590 TnyMimePart *mime_part;
1592 const gchar *mime_type = NULL;
1596 GnomeVFSFileInfo info;
1598 filename = g_filename_from_uri (uri, NULL, NULL);
1600 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1601 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1602 mime_part = tny_platform_factory_new_mime_part
1603 (modest_runtime_get_platform_factory ());
1604 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1606 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1608 content_id = g_strdup_printf ("%d", priv->last_cid);
1609 tny_mime_part_set_content_id (mime_part, content_id);
1610 g_free (content_id);
1613 basename = g_path_get_basename (filename);
1614 tny_mime_part_set_filename (mime_part, basename);
1617 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1618 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1620 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1621 gtk_widget_show_all (priv->attachments_caption);
1622 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1627 g_slist_foreach (uris, (GFunc) g_free, NULL);
1628 g_slist_free (uris);
1632 modest_msg_edit_window_attach_file_noninteractive (
1633 ModestMsgEditWindow *window,
1634 const gchar *file_uri)
1637 ModestMsgEditWindowPrivate *priv;
1639 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1641 if (file_uri && strlen(file_uri)) {
1644 /* TODO: We should probably try to use only the URI,
1645 * instead of using a filename.
1647 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1649 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1652 file_id = g_open (filename, O_RDONLY, 0);
1653 if (file_id != -1) {
1654 TnyMimePart *mime_part;
1656 const gchar *mime_type;
1659 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1660 mime_type = gnome_vfs_get_mime_type(filename);
1662 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1664 mime_part = tny_platform_factory_new_mime_part
1665 (modest_runtime_get_platform_factory ());
1666 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1668 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1670 content_id = g_strdup_printf ("%d", priv->last_cid);
1671 tny_mime_part_set_content_id (mime_part, content_id);
1672 g_free (content_id);
1675 basename = g_path_get_basename (filename);
1676 tny_mime_part_set_filename (mime_part, basename);
1679 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1680 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1682 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1683 gtk_widget_show_all (priv->attachments_caption);
1684 } else if (file_id == -1) {
1686 g_warning("file to be attached does not exist: %s", filename);
1694 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1697 ModestMsgEditWindowPrivate *priv;
1698 gboolean clean_list = FALSE;
1700 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1701 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1703 if (att_list == NULL) {
1704 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1708 if (att_list == NULL) {
1709 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1711 GtkWidget *confirmation_dialog = NULL;
1712 gboolean dialog_response;
1714 gchar *message = NULL;
1715 const gchar *filename = NULL;
1717 if (att_list->next == NULL) {
1718 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1722 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1723 att_list->next == NULL), filename);
1724 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1726 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1727 gtk_widget_destroy (confirmation_dialog);
1728 if (!dialog_response) {
1730 g_list_free (att_list);
1733 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1735 for (node = att_list; node != NULL; node = g_list_next (node)) {
1736 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1737 const gchar *att_id;
1738 priv->attachments = g_list_remove (priv->attachments, mime_part);
1740 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1742 if (priv->attachments == NULL)
1743 gtk_widget_hide (priv->attachments_caption);
1744 att_id = tny_mime_part_get_content_id (mime_part);
1746 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1748 g_object_unref (mime_part);
1749 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1754 g_list_free (att_list);
1758 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1761 ModestMsgEditWindowPrivate *priv;
1762 GdkColor *new_color;
1763 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1765 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1766 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1769 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1771 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1773 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1775 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1780 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1783 ModestMsgEditWindowPrivate *priv;
1784 gint new_size_index;
1785 ModestMsgEditWindow *window;
1788 window = MODEST_MSG_EDIT_WINDOW (userdata);
1789 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1790 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1792 if (gtk_check_menu_item_get_active (menu_item)) {
1794 WPTextBufferFormat format;
1796 memset (&format, 0, sizeof (format));
1797 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1799 label = gtk_bin_get_child (GTK_BIN (menu_item));
1801 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1802 format.cs.font_size = TRUE;
1803 format.cs.text_position = TRUE;
1804 format.cs.font = TRUE;
1805 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1806 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1808 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1809 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1810 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1812 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1813 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1814 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1820 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1823 ModestMsgEditWindowPrivate *priv;
1824 gint new_font_index;
1825 ModestMsgEditWindow *window;
1828 window = MODEST_MSG_EDIT_WINDOW (userdata);
1829 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1830 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1832 if (gtk_check_menu_item_get_active (menu_item)) {
1835 label = gtk_bin_get_child (GTK_BIN (menu_item));
1837 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1839 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1840 (gpointer) new_font_index))
1841 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1843 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1844 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1845 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1851 modest_msg_edit_window_set_zoom (ModestWindow *window,
1854 ModestMsgEditWindowPrivate *priv;
1855 ModestWindowPrivate *parent_priv;
1856 GtkRadioAction *zoom_radio_action;
1858 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1860 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1861 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1862 priv->zoom_level = zoom;
1863 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1865 /* Zoom level menu options should be updated with the current zoom level */
1866 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1867 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1868 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1869 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1870 /* FIXME: Not availible before Gtk 2.10 */
1872 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1877 modest_msg_edit_window_get_zoom (ModestWindow *window)
1879 ModestMsgEditWindowPrivate *priv;
1881 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1883 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1884 return priv->zoom_level;
1888 zoom_allowed (ModestMsgEditWindow *window)
1892 focus = gtk_window_get_focus (GTK_WINDOW (window));
1893 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1897 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1899 ModestWindowPrivate *parent_priv;
1900 GtkRadioAction *zoom_radio_action;
1901 GSList *group, *node;
1903 /* First we check if the text view is focused. If not, zooming is not allowed */
1904 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1905 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1909 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1910 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1911 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1913 group = gtk_radio_action_get_group (zoom_radio_action);
1915 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1916 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1920 for (node = group; node != NULL; node = g_slist_next (node)) {
1921 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1922 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1930 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1932 ModestWindowPrivate *parent_priv;
1933 GtkRadioAction *zoom_radio_action;
1934 GSList *group, *node;
1936 /* First we check if the text view is focused. If not, zooming is not allowed */
1937 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1938 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1942 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1943 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1944 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1946 group = gtk_radio_action_get_group (zoom_radio_action);
1948 for (node = group; node != NULL; node = g_slist_next (node)) {
1949 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1950 if (node->next != NULL) {
1951 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1954 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1962 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1964 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1965 ModestWindowPrivate *parent_priv;
1966 ModestWindowMgr *mgr;
1967 gboolean is_fullscreen;
1968 GtkAction *fs_toggle_action;
1971 mgr = modest_runtime_get_window_mgr ();
1972 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1974 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1976 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1977 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1978 if (is_fullscreen != active)
1979 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1987 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1989 ModestWindowPrivate *parent_priv;
1990 GtkAction *fs_toggle_action;
1993 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1995 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1996 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1997 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2001 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2004 ModestMsgEditWindowPrivate *priv = NULL;
2005 const gchar *recipients;
2006 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2008 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2009 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2010 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2011 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2012 gtk_widget_show (priv->cc_caption);
2014 gtk_widget_hide (priv->cc_caption);
2015 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2019 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2022 ModestMsgEditWindowPrivate *priv = NULL;
2023 const gchar *recipients;
2024 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2026 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2027 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2028 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2029 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2030 gtk_widget_show (priv->bcc_caption);
2032 gtk_widget_hide (priv->bcc_caption);
2033 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2037 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2038 ModestRecptEditor *editor)
2040 ModestMsgEditWindowPrivate *priv;
2042 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2043 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2044 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2046 if (editor == NULL) {
2047 GtkWidget *view_focus;
2048 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2050 /* This code should be kept in sync with ModestRecptEditor. The
2051 textview inside the recpt editor is the one that really gets the
2052 focus. As it's inside a scrolled window, and this one inside the
2053 hbox recpt editor inherits from, we'll need to go up in the
2054 hierarchy to know if the text view is part of the recpt editor
2055 or if it's a different text entry */
2057 if (gtk_widget_get_parent (view_focus)) {
2058 GtkWidget *first_parent;
2060 first_parent = gtk_widget_get_parent (view_focus);
2061 if (gtk_widget_get_parent (first_parent) &&
2062 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2063 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2068 editor = MODEST_RECPT_EDITOR (priv->to_field);
2072 modest_address_book_select_addresses (editor);
2077 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2079 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2081 modest_msg_edit_window_open_addressbook (window, NULL);
2085 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2086 gboolean show_toolbar)
2088 ModestWindowPrivate *parent_priv;
2090 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2091 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2093 /* FIXME: we can not just use the code of
2094 modest_msg_edit_window_setup_toolbar because it has a
2095 mixture of both initialization and creation code. */
2098 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2100 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2104 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2105 TnyHeaderFlags priority_flags)
2107 ModestMsgEditWindowPrivate *priv;
2108 ModestWindowPrivate *parent_priv;
2110 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2112 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2113 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2114 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2116 if (priv->priority_flags != priority_flags) {
2117 GtkAction *priority_action = NULL;
2119 priv->priority_flags = priority_flags;
2121 switch (priority_flags) {
2122 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2123 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2124 gtk_widget_show (priv->priority_icon);
2125 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2126 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2128 case TNY_HEADER_FLAG_LOW_PRIORITY:
2129 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2130 gtk_widget_show (priv->priority_icon);
2131 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2132 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2135 gtk_widget_hide (priv->priority_icon);
2136 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2137 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2140 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2141 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2146 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2149 ModestMsgEditWindowPrivate *priv;
2150 ModestWindowPrivate *parent_priv;
2151 gint current_format;
2153 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2155 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2156 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2158 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2159 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2161 if (current_format != file_format) {
2162 switch (file_format) {
2163 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2164 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2166 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2170 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2171 response = gtk_dialog_run (GTK_DIALOG (dialog));
2172 gtk_widget_destroy (dialog);
2173 if (response == GTK_RESPONSE_OK) {
2174 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2176 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2177 toggle_action_set_active_block_notify (action, TRUE);
2182 update_dimmed (window);
2187 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2190 ModestMsgEditWindowPrivate *priv;
2191 WPTextBufferFormat oldfmt, fmt;
2192 gint old_position = 0;
2196 GdkColor *color = NULL;
2197 gboolean bold, bold_set, italic, italic_set;
2198 gboolean underline, underline_set;
2199 gboolean strikethrough, strikethrough_set;
2200 gboolean position_set;
2201 gboolean font_size_set, font_set, color_set;
2204 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2205 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2207 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2209 /* First we get the currently selected font information */
2210 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2211 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2213 switch (oldfmt.text_position) {
2214 case TEXT_POSITION_NORMAL:
2217 case TEXT_POSITION_SUPERSCRIPT:
2225 g_object_set (G_OBJECT (dialog),
2226 "bold", oldfmt.bold != FALSE,
2227 "bold-set", !oldfmt.cs.bold,
2228 "underline", oldfmt.underline != FALSE,
2229 "underline-set", !oldfmt.cs.underline,
2230 "italic", oldfmt.italic != FALSE,
2231 "italic-set", !oldfmt.cs.italic,
2232 "strikethrough", oldfmt.strikethrough != FALSE,
2233 "strikethrough-set", !oldfmt.cs.strikethrough,
2234 "color", &oldfmt.color,
2235 "color-set", !oldfmt.cs.color,
2236 "size", wp_font_size[oldfmt.font_size],
2237 "size-set", !oldfmt.cs.font_size,
2238 "position", old_position,
2239 "position-set", !oldfmt.cs.text_position,
2240 "family", wp_get_font_name (oldfmt.font),
2241 "family-set", !oldfmt.cs.font,
2244 gtk_widget_show_all (dialog);
2245 response = gtk_dialog_run (GTK_DIALOG (dialog));
2246 if (response == GTK_RESPONSE_OK) {
2248 g_object_get( dialog,
2250 "bold-set", &bold_set,
2251 "underline", &underline,
2252 "underline-set", &underline_set,
2254 "italic-set", &italic_set,
2255 "strikethrough", &strikethrough,
2256 "strikethrough-set", &strikethrough_set,
2258 "color-set", &color_set,
2260 "size-set", &font_size_set,
2261 "family", &font_name,
2262 "family-set", &font_set,
2263 "position", &position,
2264 "position-set", &position_set,
2269 if (response == GTK_RESPONSE_OK) {
2270 memset(&fmt, 0, sizeof(fmt));
2276 fmt.italic = italic;
2277 fmt.cs.italic = TRUE;
2279 if (underline_set) {
2280 fmt.underline = underline;
2281 fmt.cs.underline = TRUE;
2283 if (strikethrough_set) {
2284 fmt.strikethrough = strikethrough;
2285 fmt.cs.strikethrough = TRUE;
2290 ? TEXT_POSITION_NORMAL
2291 : ( ( position == 1 )
2292 ? TEXT_POSITION_SUPERSCRIPT
2293 : TEXT_POSITION_SUBSCRIPT );
2294 fmt.cs.text_position = TRUE;
2298 fmt.cs.color = TRUE;
2301 fmt.font = wp_get_font_index(font_name,
2306 if (font_size_set) {
2307 fmt.font_size = wp_get_font_size_index(
2308 font_size, DEFAULT_FONT_SIZE);
2309 fmt.cs.font_size = TRUE;
2311 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2313 gtk_widget_destroy (dialog);
2315 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2319 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2321 ModestMsgEditWindowPrivate *priv;
2323 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2324 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2326 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2328 update_dimmed (window);
2333 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2335 ModestMsgEditWindowPrivate *priv;
2337 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2338 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2340 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2342 update_dimmed (window);
2347 update_dimmed (ModestMsgEditWindow *window)
2349 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2350 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2354 gboolean editor_focused;
2356 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2357 editor_focused = gtk_widget_is_focus (priv->msg_body);
2359 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2360 gtk_action_set_sensitive (action, rich_text && editor_focused);
2361 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2362 gtk_action_set_sensitive (action, rich_text && editor_focused);
2363 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2364 gtk_action_set_sensitive (action, rich_text && editor_focused);
2365 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2366 gtk_action_set_sensitive (action, rich_text && editor_focused);
2367 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2368 gtk_action_set_sensitive (action, rich_text && editor_focused);
2369 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2370 gtk_action_set_sensitive (action, rich_text && editor_focused);
2371 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2372 gtk_action_set_sensitive (action, rich_text && editor_focused);
2373 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2374 gtk_action_set_sensitive (action, rich_text && editor_focused);
2375 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2376 gtk_action_set_sensitive (action, rich_text && editor_focused);
2377 widget = priv->font_color_button;
2378 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2379 widget = priv->font_size_toolitem;
2380 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2381 widget = priv->font_face_toolitem;
2382 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2386 setup_insensitive_handlers (ModestMsgEditWindow *window)
2388 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2389 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2392 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2393 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2394 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2395 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2397 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2398 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2399 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2400 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2401 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2402 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2403 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2404 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2405 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2406 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2407 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2408 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2409 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2410 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2411 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2412 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2413 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2414 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2415 widget = priv->font_color_button;
2416 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2417 widget = priv->font_size_toolitem;
2418 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2419 widget = priv->font_face_toolitem;
2420 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2422 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2423 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2424 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2425 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2427 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2428 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (paste_insensitive_press), window);
2429 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2430 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (copy_insensitive_press), window);
2434 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2436 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2439 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2440 gtk_action_set_sensitive (action, can_undo);
2444 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2446 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2449 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2450 gtk_action_set_sensitive (action, can_redo);
2454 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2457 GtkTextIter match_start, match_end;
2459 if (image_id == NULL)
2462 gtk_text_buffer_get_start_iter (buffer, &iter);
2464 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2465 GSList *tags = gtk_text_iter_get_tags (&match_start);
2467 for (node = tags; node != NULL; node = g_slist_next (node)) {
2468 GtkTextTag *tag = (GtkTextTag *) node->data;
2469 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2470 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2471 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2473 offset = gtk_text_iter_get_offset (&match_start);
2474 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2475 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2479 gtk_text_iter_forward_char (&iter);
2484 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2486 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2487 GtkTextIter real_start, real_end;
2488 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2490 if (gtk_text_iter_compare (start, end) > 0) {
2494 real_start = *start;
2498 GSList *tags = gtk_text_iter_get_tags (&real_start);
2500 for (node = tags; node != NULL; node = g_slist_next (node)) {
2501 GtkTextTag *tag = (GtkTextTag *) node->data;
2502 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2503 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2505 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2507 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2510 } while (gtk_text_iter_forward_char (&real_start)&&
2511 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2515 msg_body_focus (GtkWidget *focus,
2516 GdkEventFocus *event,
2520 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2525 recpt_field_changed (GtkTextBuffer *buffer,
2526 ModestMsgEditWindow *editor)
2528 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2529 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2530 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2531 gboolean dim = FALSE;
2534 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2535 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2536 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2538 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2539 gtk_text_buffer_get_char_count (cc_buffer) +
2540 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2542 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2543 gtk_action_set_sensitive (action, !dim);
2544 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2545 gtk_action_set_sensitive (action, !dim);
2549 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2551 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2555 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2557 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2561 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2563 ModestWindowPrivate *parent_priv;
2564 ModestMsgEditWindowPrivate *priv;
2565 GList *selected_attachments = NULL;
2566 gint n_att_selected = 0;
2568 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2569 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2571 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2572 n_att_selected = g_list_length (selected_attachments);
2573 g_list_free (selected_attachments);
2575 if (n_att_selected > 1)
2576 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2577 else if (n_att_selected == 0)
2578 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2580 hildon_banner_show_information (NULL, NULL, _("mail_ib_unable_to_purge_attachments"));
2584 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2586 gboolean rich_text, editor_focused;
2588 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2589 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2590 editor_focused = gtk_widget_is_focus (priv->msg_body);
2593 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2594 else if (!editor_focused)
2595 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2599 reset_modified (ModestMsgEditWindow *editor)
2601 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2602 GtkTextBuffer *buffer;
2604 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2605 gtk_text_buffer_set_modified (buffer, FALSE);
2606 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2607 gtk_text_buffer_set_modified (buffer, FALSE);
2608 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2609 gtk_text_buffer_set_modified (buffer, FALSE);
2610 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2614 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2616 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2617 GtkTextBuffer *buffer;
2619 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2620 if (gtk_text_buffer_get_modified (buffer))
2622 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2623 if (gtk_text_buffer_get_modified (buffer))
2625 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2626 if (gtk_text_buffer_get_modified (buffer))
2628 if (gtk_text_buffer_get_modified (priv->text_buffer))
2635 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2637 ModestMsgEditWindowPrivate *priv = NULL;
2639 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2640 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2642 /* check if there's no recipient added */
2643 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2644 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2645 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2646 /* no recipient contents, then select contacts */
2647 modest_msg_edit_window_open_addressbook (window, NULL);
2651 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2653 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2655 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2658 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2665 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2666 ModestMsgEditWindow *window)
2668 modest_msg_edit_window_attach_file (window);
2672 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2674 ModestMsgEditWindow *window)
2676 ModestWindowPrivate *parent_priv;
2677 ModestMsgEditWindowPrivate *priv;
2681 GList *selected_attachments = NULL;
2682 gint n_att_selected = 0;
2684 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2685 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2686 selection = gtk_clipboard_wait_for_text (clipboard);
2687 focused = gtk_window_get_focus (GTK_WINDOW (window));
2689 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2690 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2691 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2692 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2694 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2695 n_att_selected = g_list_length (selected_attachments);
2696 g_list_free (selected_attachments);
2698 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2699 gtk_action_set_sensitive (action, n_att_selected == 1);
2702 update_paste_dimming (window);
2706 update_window_title (ModestMsgEditWindow *window)
2708 ModestMsgEditWindowPrivate *priv = NULL;
2709 const gchar *subject;
2711 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2712 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2713 if (subject == NULL || subject[0] == '\0')
2714 subject = _("mail_va_new_email");
2716 gtk_window_set_title (GTK_WINDOW (window), subject);
2721 subject_field_changed (GtkEditable *editable,
2722 ModestMsgEditWindow *window)
2724 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2725 update_window_title (window);
2726 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2730 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2733 ModestMsgEditWindowPrivate *priv = NULL;
2735 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2736 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2738 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2740 gtk_widget_show_all (priv->find_toolbar);
2741 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2743 gtk_widget_hide_all (priv->find_toolbar);
2744 gtk_widget_grab_focus (priv->msg_body);
2750 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2752 GtkTextIter *match_start,
2753 GtkTextIter *match_end)
2755 GtkTextIter end_iter;
2756 gchar *str_casefold;
2759 gchar *range_casefold;
2762 gboolean result = FALSE;
2769 gtk_text_iter_forward_to_end (&end_iter);
2771 str_casefold = g_utf8_casefold (str, -1);
2772 str_chars_n = strlen (str);
2774 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2775 range_casefold = g_utf8_casefold (range_text, -1);
2776 range_chars_n = strlen (range_casefold);
2778 if (range_chars_n < str_chars_n) {
2779 g_free (str_casefold);
2780 g_free (range_text);
2781 g_free (range_casefold);
2785 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2786 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2787 if (!g_utf8_collate (range_subtext, str_casefold)) {
2788 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2790 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2791 match_start, match_end, NULL);
2792 g_free (found_text);
2794 g_free (range_subtext);
2798 g_free (str_casefold);
2799 g_free (range_text);
2800 g_free (range_casefold);
2807 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2808 ModestMsgEditWindow *window)
2810 gchar *current_search = NULL;
2811 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2813 GtkTextIter selection_start, selection_end;
2814 GtkTextIter match_start, match_end;
2815 gboolean continue_search = FALSE;
2817 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2818 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2819 g_free (current_search);
2820 g_free (priv->last_search);
2821 priv->last_search = NULL;
2822 /* Information banner about empty search */
2823 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2827 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2828 continue_search = TRUE;
2830 g_free (priv->last_search);
2831 priv->last_search = g_strdup (current_search);
2834 if (continue_search) {
2835 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2836 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2837 &match_start, &match_end);
2839 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2841 GtkTextIter buffer_start;
2842 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2843 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2844 &match_start, &match_end);
2846 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2849 /* Mark as selected the string found in search */
2851 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2852 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2854 g_free (priv->last_search);
2855 priv->last_search = NULL;
2857 g_free (current_search);
2861 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2862 ModestMsgEditWindow *window)
2864 GtkToggleAction *toggle;
2865 ModestWindowPrivate *parent_priv;
2866 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2868 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2869 gtk_toggle_action_set_active (toggle, FALSE);
2874 update_paste_dimming (ModestMsgEditWindow *window)
2876 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2877 GtkAction *action = NULL;
2878 GtkClipboard *clipboard = NULL;
2882 focused = gtk_window_get_focus (GTK_WINDOW (window));
2884 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2885 active = gtk_clipboard_wait_is_text_available (clipboard);
2888 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2892 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2893 gtk_action_set_sensitive (action, active);
2898 paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2900 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (editor));
2902 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2903 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
2905 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
2910 copy_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2912 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_copy"));
2918 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2920 ModestMsgEditWindow *window)
2922 update_paste_dimming (window);
2926 update_select_all_dimming (ModestMsgEditWindow *window)
2929 gboolean dimmed = FALSE;
2931 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2933 focused = gtk_window_get_focus (GTK_WINDOW (window));
2934 if (GTK_IS_ENTRY (focused)) {
2935 const gchar *current_text;
2936 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2937 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2938 } else if (GTK_IS_TEXT_VIEW (focused)) {
2939 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2940 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2941 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2944 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2945 gtk_action_set_sensitive (action, !dimmed);
2949 update_zoom_dimming (ModestMsgEditWindow *window)
2952 gboolean dimmed = FALSE;
2954 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2956 focused = gtk_window_get_focus (GTK_WINDOW (window));
2957 dimmed = ! WP_IS_TEXT_VIEW (focused);
2958 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2959 gtk_action_set_sensitive (action, !dimmed);
2963 edit_menu_activated (GtkAction *action,
2966 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2968 update_select_all_dimming (window);
2971 view_menu_activated (GtkAction *action,
2974 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2976 update_zoom_dimming (window);
2980 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2982 ModestMsgEditWindowPrivate *priv;
2984 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2989 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2992 ModestMsgEditWindowPrivate *priv;
2994 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);