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 if (!(TNY_IS_MIME_PART(cursor->data))) {
1079 g_warning ("strange data in attachment list");
1082 data->attachments = g_list_append (data->attachments,
1083 g_object_ref (cursor->data));
1084 cursor = g_list_next (cursor);
1087 data->priority_flags = priv->priority_flags;
1094 unref_gobject (GObject *obj, gpointer data)
1096 if (!G_IS_OBJECT(obj))
1098 g_object_unref (obj);
1102 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1105 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1113 g_free (data->subject);
1114 g_free (data->plain_body);
1115 g_free (data->html_body);
1116 g_free (data->account_name);
1118 if (data->draft_msg != NULL) {
1119 g_object_unref (data->draft_msg);
1120 data->draft_msg = NULL;
1123 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1124 g_list_free (data->attachments);
1126 g_slice_free (MsgData, data);
1130 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1133 ModestMsgEditWindowPrivate *priv = NULL;
1134 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1136 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1138 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1140 return MODEST_MSG_EDIT_FORMAT_HTML;
1142 return MODEST_MSG_EDIT_FORMAT_TEXT;
1146 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1147 ModestMsgEditFormat format)
1149 ModestMsgEditWindowPrivate *priv;
1151 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1152 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1155 case MODEST_MSG_EDIT_FORMAT_HTML:
1156 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1158 case MODEST_MSG_EDIT_FORMAT_TEXT:
1159 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1162 g_return_if_reached ();
1166 ModestMsgEditFormatState *
1167 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1169 ModestMsgEditFormatState *format_state = NULL;
1170 ModestMsgEditWindowPrivate *priv;
1171 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1173 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1174 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1176 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1178 format_state = g_new0 (ModestMsgEditFormatState, 1);
1179 format_state->bold = buffer_format->bold&0x1;
1180 format_state->italics = buffer_format->italic&0x1;
1181 format_state->bullet = buffer_format->bullet&0x1;
1182 format_state->color = buffer_format->color;
1183 format_state->font_size = buffer_format->font_size;
1184 format_state->font_family = wp_get_font_name (buffer_format->font);
1185 format_state->justification = buffer_format->justification;
1186 g_free (buffer_format);
1188 return format_state;
1193 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1194 const ModestMsgEditFormatState *format_state)
1196 ModestMsgEditWindowPrivate *priv;
1197 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1198 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1199 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1200 g_return_if_fail (format_state != NULL);
1202 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1203 gtk_widget_grab_focus (priv->msg_body);
1204 buffer_format->bold = (format_state->bold != FALSE);
1205 buffer_format->italic = (format_state->italics != FALSE);
1206 buffer_format->color = format_state->color;
1207 buffer_format->font_size = format_state->font_size;
1208 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1209 buffer_format->justification = format_state->justification;
1210 buffer_format->bullet = format_state->bullet;
1212 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1214 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1215 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1216 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1217 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1218 buffer_format->cs.font = (buffer_format->font != current_format->font);
1219 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1220 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1222 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1223 if (buffer_format->cs.bold) {
1224 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1226 if (buffer_format->cs.italic) {
1227 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1229 if (buffer_format->cs.color) {
1230 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1232 if (buffer_format->cs.font_size) {
1233 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1235 if (buffer_format->cs.justification) {
1236 switch (buffer_format->justification) {
1237 case GTK_JUSTIFY_LEFT:
1238 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1240 case GTK_JUSTIFY_CENTER:
1241 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1243 case GTK_JUSTIFY_RIGHT:
1244 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1251 if (buffer_format->cs.font) {
1252 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1254 if (buffer_format->cs.bullet) {
1255 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1257 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1258 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1260 g_free (current_format);
1265 toggle_action_set_active_block_notify (GtkToggleAction *action,
1268 GSList *proxies = NULL;
1270 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1271 proxies != NULL; proxies = g_slist_next (proxies)) {
1272 GtkWidget *widget = (GtkWidget *) proxies->data;
1273 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1276 gtk_toggle_action_set_active (action, value);
1278 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1279 proxies != NULL; proxies = g_slist_next (proxies)) {
1280 GtkWidget *widget = (GtkWidget *) proxies->data;
1281 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1286 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1288 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1290 ModestWindowPrivate *parent_priv;
1291 ModestMsgEditWindowPrivate *priv;
1292 GtkWidget *new_size_menuitem;
1293 GtkWidget *new_font_menuitem;
1295 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1296 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1298 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1299 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1300 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1301 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1303 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1304 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1305 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1308 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1310 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1311 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1313 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1314 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1316 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1317 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1319 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1320 G_CALLBACK (modest_msg_edit_window_color_button_change),
1322 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1323 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1324 G_CALLBACK (modest_msg_edit_window_color_button_change),
1327 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1328 buffer_format->font_size))->data);
1329 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1333 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1334 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1335 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1337 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1338 G_CALLBACK (modest_msg_edit_window_size_change),
1340 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1341 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1342 G_CALLBACK (modest_msg_edit_window_size_change),
1346 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1347 buffer_format->font))->data);
1348 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1352 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1353 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1354 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1356 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1357 G_CALLBACK (modest_msg_edit_window_font_change),
1359 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1360 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1361 G_CALLBACK (modest_msg_edit_window_font_change),
1365 g_free (buffer_format);
1371 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1374 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1375 ModestMsgEditWindowPrivate *priv;
1376 GtkWidget *dialog = NULL;
1378 const GdkColor *new_color = NULL;
1380 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1381 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1383 #ifdef MODEST_HILDON_VERSION_0
1384 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1385 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1387 dialog = hildon_color_chooser_new ();
1388 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1389 #endif /*MODEST_HILDON_VERSION_0*/
1390 g_free (buffer_format);
1392 response = gtk_dialog_run (GTK_DIALOG (dialog));
1394 case GTK_RESPONSE_OK: {
1395 #ifdef MODEST_HILDON_VERSION_0
1396 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1399 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1401 #endif /*MODEST_HILDON_VERSION_0*/
1408 gtk_widget_destroy (dialog);
1410 if (new_color != NULL)
1411 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1416 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1419 ModestMsgEditWindowPrivate *priv;
1420 GtkWidget *dialog = NULL;
1422 GdkColor *old_color = NULL;
1423 const GdkColor *new_color = NULL;
1425 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1426 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1428 #ifdef MODEST_HILDON_VERSION_0
1429 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1430 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1432 dialog = hildon_color_chooser_new ();
1433 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1434 #endif /*MODEST_HILDON_VERSION_9*/
1436 response = gtk_dialog_run (GTK_DIALOG (dialog));
1438 case GTK_RESPONSE_OK: {
1439 #ifdef MODEST_HILDON_VERSION_0
1440 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1443 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1445 #endif /*MODEST_HILDON_VERSION_0*/
1451 gtk_widget_destroy (dialog);
1453 if (new_color != NULL)
1454 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1460 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1463 ModestMsgEditWindowPrivate *priv;
1464 GtkWidget *dialog = NULL;
1466 GSList *uris = NULL;
1467 GSList *uri_node = NULL;
1469 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1471 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1472 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1473 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1475 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1477 response = gtk_dialog_run (GTK_DIALOG (dialog));
1479 case GTK_RESPONSE_OK:
1480 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1485 gtk_widget_destroy (dialog);
1487 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1489 GnomeVFSHandle *handle = NULL;
1490 GnomeVFSResult result;
1491 GtkTextIter position;
1492 GtkTextMark *insert_mark;
1494 uri = (const gchar *) uri_node->data;
1495 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1496 if (result == GNOME_VFS_OK) {
1497 GdkPixbufLoader *loader;
1499 GnomeVFSFileInfo info;
1500 gchar *filename, *basename;
1501 TnyMimePart *mime_part;
1504 const gchar *mime_type = NULL;
1506 filename = g_filename_from_uri (uri, NULL, NULL);
1507 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1509 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1511 mime_part = tny_platform_factory_new_mime_part
1512 (modest_runtime_get_platform_factory ());
1513 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1515 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1517 content_id = g_strdup_printf ("%d", priv->last_cid);
1518 tny_mime_part_set_content_id (mime_part, content_id);
1519 g_free (content_id);
1522 basename = g_path_get_basename (filename);
1523 tny_mime_part_set_filename (mime_part, basename);
1526 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1527 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1529 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1530 gtk_widget_show_all (priv->attachments_caption);
1531 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1534 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1535 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1536 unsigned char read_buffer[128];
1538 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1539 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1542 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1543 g_object_ref (pixbuf);
1544 gdk_pixbuf_loader_close (loader, NULL);
1545 g_object_unref (loader);
1547 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1548 GdkPixbuf *new_pixbuf;
1550 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1551 gdk_pixbuf_get_width (pixbuf);
1552 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1553 g_object_unref (pixbuf);
1554 pixbuf = new_pixbuf;
1557 if (pixbuf != NULL) {
1558 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1559 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1560 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1569 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1572 ModestMsgEditWindowPrivate *priv;
1573 GtkWidget *dialog = NULL;
1575 GSList *uris = NULL;
1578 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1580 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1581 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1583 response = gtk_dialog_run (GTK_DIALOG (dialog));
1585 case GTK_RESPONSE_OK:
1586 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1591 gtk_widget_destroy (dialog);
1593 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1595 GnomeVFSHandle *handle = NULL;
1596 GnomeVFSResult result;
1598 uri = (const gchar *) uri_node->data;
1599 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1600 if (result == GNOME_VFS_OK) {
1601 TnyMimePart *mime_part;
1603 const gchar *mime_type = NULL;
1607 GnomeVFSFileInfo info;
1609 filename = g_filename_from_uri (uri, NULL, NULL);
1611 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1612 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1613 mime_part = tny_platform_factory_new_mime_part
1614 (modest_runtime_get_platform_factory ());
1615 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1617 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1619 content_id = g_strdup_printf ("%d", priv->last_cid);
1620 tny_mime_part_set_content_id (mime_part, content_id);
1621 g_free (content_id);
1624 basename = g_path_get_basename (filename);
1625 tny_mime_part_set_filename (mime_part, basename);
1628 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1629 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1631 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1632 gtk_widget_show_all (priv->attachments_caption);
1633 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1638 g_slist_foreach (uris, (GFunc) g_free, NULL);
1639 g_slist_free (uris);
1643 modest_msg_edit_window_attach_file_noninteractive (
1644 ModestMsgEditWindow *window,
1645 const gchar *file_uri)
1648 ModestMsgEditWindowPrivate *priv;
1650 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1652 if (file_uri && strlen(file_uri)) {
1655 /* TODO: We should probably try to use only the URI,
1656 * instead of using a filename.
1658 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1660 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1663 file_id = g_open (filename, O_RDONLY, 0);
1664 if (file_id != -1) {
1665 TnyMimePart *mime_part;
1667 const gchar *mime_type;
1670 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1671 mime_type = gnome_vfs_get_mime_type(filename);
1673 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1675 mime_part = tny_platform_factory_new_mime_part
1676 (modest_runtime_get_platform_factory ());
1677 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1679 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1681 content_id = g_strdup_printf ("%d", priv->last_cid);
1682 tny_mime_part_set_content_id (mime_part, content_id);
1683 g_free (content_id);
1686 basename = g_path_get_basename (filename);
1687 tny_mime_part_set_filename (mime_part, basename);
1690 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1691 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1693 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1694 gtk_widget_show_all (priv->attachments_caption);
1695 } else if (file_id == -1) {
1697 g_warning("file to be attached does not exist: %s", filename);
1705 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1708 ModestMsgEditWindowPrivate *priv;
1709 gboolean clean_list = FALSE;
1711 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1712 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1714 if (att_list == NULL) {
1715 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1719 if (att_list == NULL) {
1720 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1722 GtkWidget *confirmation_dialog = NULL;
1723 gboolean dialog_response;
1725 gchar *message = NULL;
1726 const gchar *filename = NULL;
1728 if (att_list->next == NULL) {
1729 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1733 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1734 att_list->next == NULL), filename);
1735 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1737 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1738 gtk_widget_destroy (confirmation_dialog);
1739 if (!dialog_response) {
1741 g_list_free (att_list);
1744 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1746 for (node = att_list; node != NULL; node = g_list_next (node)) {
1747 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1748 const gchar *att_id;
1749 priv->attachments = g_list_remove (priv->attachments, mime_part);
1751 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1753 if (priv->attachments == NULL)
1754 gtk_widget_hide (priv->attachments_caption);
1755 att_id = tny_mime_part_get_content_id (mime_part);
1757 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1759 g_object_unref (mime_part);
1760 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1765 g_list_free (att_list);
1769 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1772 ModestMsgEditWindowPrivate *priv;
1773 GdkColor *new_color;
1774 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1776 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1777 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1780 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1782 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1784 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1786 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1791 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1794 ModestMsgEditWindowPrivate *priv;
1795 gint new_size_index;
1796 ModestMsgEditWindow *window;
1799 window = MODEST_MSG_EDIT_WINDOW (userdata);
1800 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1801 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1803 if (gtk_check_menu_item_get_active (menu_item)) {
1805 WPTextBufferFormat format;
1807 memset (&format, 0, sizeof (format));
1808 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1810 label = gtk_bin_get_child (GTK_BIN (menu_item));
1812 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1813 format.cs.font_size = TRUE;
1814 format.cs.text_position = TRUE;
1815 format.cs.font = TRUE;
1816 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1817 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1819 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1820 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1821 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1823 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1824 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1825 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1831 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1834 ModestMsgEditWindowPrivate *priv;
1835 gint new_font_index;
1836 ModestMsgEditWindow *window;
1839 window = MODEST_MSG_EDIT_WINDOW (userdata);
1840 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1841 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1843 if (gtk_check_menu_item_get_active (menu_item)) {
1846 label = gtk_bin_get_child (GTK_BIN (menu_item));
1848 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1850 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1851 (gpointer) new_font_index))
1852 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1854 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1855 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1856 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1862 modest_msg_edit_window_set_zoom (ModestWindow *window,
1865 ModestMsgEditWindowPrivate *priv;
1866 ModestWindowPrivate *parent_priv;
1867 GtkRadioAction *zoom_radio_action;
1869 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1871 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1872 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1873 priv->zoom_level = zoom;
1874 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1876 /* Zoom level menu options should be updated with the current zoom level */
1877 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1878 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1879 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1880 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1881 /* FIXME: Not availible before Gtk 2.10 */
1883 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1888 modest_msg_edit_window_get_zoom (ModestWindow *window)
1890 ModestMsgEditWindowPrivate *priv;
1892 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1894 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1895 return priv->zoom_level;
1899 zoom_allowed (ModestMsgEditWindow *window)
1903 focus = gtk_window_get_focus (GTK_WINDOW (window));
1904 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1908 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1910 ModestWindowPrivate *parent_priv;
1911 GtkRadioAction *zoom_radio_action;
1912 GSList *group, *node;
1914 /* First we check if the text view is focused. If not, zooming is not allowed */
1915 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1916 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1920 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1921 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1922 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1924 group = gtk_radio_action_get_group (zoom_radio_action);
1926 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1927 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1931 for (node = group; node != NULL; node = g_slist_next (node)) {
1932 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1933 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1941 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1943 ModestWindowPrivate *parent_priv;
1944 GtkRadioAction *zoom_radio_action;
1945 GSList *group, *node;
1947 /* First we check if the text view is focused. If not, zooming is not allowed */
1948 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1949 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1953 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1954 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1955 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1957 group = gtk_radio_action_get_group (zoom_radio_action);
1959 for (node = group; node != NULL; node = g_slist_next (node)) {
1960 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1961 if (node->next != NULL) {
1962 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1965 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1973 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1975 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1976 ModestWindowPrivate *parent_priv;
1977 ModestWindowMgr *mgr;
1978 gboolean is_fullscreen;
1979 GtkAction *fs_toggle_action;
1982 mgr = modest_runtime_get_window_mgr ();
1983 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1985 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1987 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1988 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1989 if (is_fullscreen != active)
1990 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1998 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2000 ModestWindowPrivate *parent_priv;
2001 GtkAction *fs_toggle_action;
2004 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2006 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2007 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2008 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2012 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2015 ModestMsgEditWindowPrivate *priv = NULL;
2016 const gchar *recipients;
2017 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2019 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2020 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2021 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2022 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2023 gtk_widget_show (priv->cc_caption);
2025 gtk_widget_hide (priv->cc_caption);
2026 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2030 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2033 ModestMsgEditWindowPrivate *priv = NULL;
2034 const gchar *recipients;
2035 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2037 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2038 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2039 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2040 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2041 gtk_widget_show (priv->bcc_caption);
2043 gtk_widget_hide (priv->bcc_caption);
2044 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2048 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2049 ModestRecptEditor *editor)
2051 ModestMsgEditWindowPrivate *priv;
2053 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2054 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2055 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2057 if (editor == NULL) {
2058 GtkWidget *view_focus;
2059 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2061 /* This code should be kept in sync with ModestRecptEditor. The
2062 textview inside the recpt editor is the one that really gets the
2063 focus. As it's inside a scrolled window, and this one inside the
2064 hbox recpt editor inherits from, we'll need to go up in the
2065 hierarchy to know if the text view is part of the recpt editor
2066 or if it's a different text entry */
2068 if (gtk_widget_get_parent (view_focus)) {
2069 GtkWidget *first_parent;
2071 first_parent = gtk_widget_get_parent (view_focus);
2072 if (gtk_widget_get_parent (first_parent) &&
2073 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2074 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2079 editor = MODEST_RECPT_EDITOR (priv->to_field);
2083 modest_address_book_select_addresses (editor);
2088 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2090 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2092 modest_msg_edit_window_open_addressbook (window, NULL);
2096 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2097 gboolean show_toolbar)
2099 ModestWindowPrivate *parent_priv;
2101 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2102 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2104 /* FIXME: we can not just use the code of
2105 modest_msg_edit_window_setup_toolbar because it has a
2106 mixture of both initialization and creation code. */
2109 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2111 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2115 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2116 TnyHeaderFlags priority_flags)
2118 ModestMsgEditWindowPrivate *priv;
2119 ModestWindowPrivate *parent_priv;
2121 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2123 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2124 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2125 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2127 if (priv->priority_flags != priority_flags) {
2128 GtkAction *priority_action = NULL;
2130 priv->priority_flags = priority_flags;
2132 switch (priority_flags) {
2133 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2134 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2135 gtk_widget_show (priv->priority_icon);
2136 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2137 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2139 case TNY_HEADER_FLAG_LOW_PRIORITY:
2140 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2141 gtk_widget_show (priv->priority_icon);
2142 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2143 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2146 gtk_widget_hide (priv->priority_icon);
2147 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2148 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2151 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2152 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2157 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2160 ModestMsgEditWindowPrivate *priv;
2161 ModestWindowPrivate *parent_priv;
2162 gint current_format;
2164 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2166 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2167 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2169 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2170 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2172 if (current_format != file_format) {
2173 switch (file_format) {
2174 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2175 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2177 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2181 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2182 response = gtk_dialog_run (GTK_DIALOG (dialog));
2183 gtk_widget_destroy (dialog);
2184 if (response == GTK_RESPONSE_OK) {
2185 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2187 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2188 toggle_action_set_active_block_notify (action, TRUE);
2193 update_dimmed (window);
2198 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2201 ModestMsgEditWindowPrivate *priv;
2202 WPTextBufferFormat oldfmt, fmt;
2203 gint old_position = 0;
2207 GdkColor *color = NULL;
2208 gboolean bold, bold_set, italic, italic_set;
2209 gboolean underline, underline_set;
2210 gboolean strikethrough, strikethrough_set;
2211 gboolean position_set;
2212 gboolean font_size_set, font_set, color_set;
2215 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2216 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2218 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2220 /* First we get the currently selected font information */
2221 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2222 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2224 switch (oldfmt.text_position) {
2225 case TEXT_POSITION_NORMAL:
2228 case TEXT_POSITION_SUPERSCRIPT:
2236 g_object_set (G_OBJECT (dialog),
2237 "bold", oldfmt.bold != FALSE,
2238 "bold-set", !oldfmt.cs.bold,
2239 "underline", oldfmt.underline != FALSE,
2240 "underline-set", !oldfmt.cs.underline,
2241 "italic", oldfmt.italic != FALSE,
2242 "italic-set", !oldfmt.cs.italic,
2243 "strikethrough", oldfmt.strikethrough != FALSE,
2244 "strikethrough-set", !oldfmt.cs.strikethrough,
2245 "color", &oldfmt.color,
2246 "color-set", !oldfmt.cs.color,
2247 "size", wp_font_size[oldfmt.font_size],
2248 "size-set", !oldfmt.cs.font_size,
2249 "position", old_position,
2250 "position-set", !oldfmt.cs.text_position,
2251 "family", wp_get_font_name (oldfmt.font),
2252 "family-set", !oldfmt.cs.font,
2255 gtk_widget_show_all (dialog);
2256 response = gtk_dialog_run (GTK_DIALOG (dialog));
2257 if (response == GTK_RESPONSE_OK) {
2259 g_object_get( dialog,
2261 "bold-set", &bold_set,
2262 "underline", &underline,
2263 "underline-set", &underline_set,
2265 "italic-set", &italic_set,
2266 "strikethrough", &strikethrough,
2267 "strikethrough-set", &strikethrough_set,
2269 "color-set", &color_set,
2271 "size-set", &font_size_set,
2272 "family", &font_name,
2273 "family-set", &font_set,
2274 "position", &position,
2275 "position-set", &position_set,
2280 if (response == GTK_RESPONSE_OK) {
2281 memset(&fmt, 0, sizeof(fmt));
2287 fmt.italic = italic;
2288 fmt.cs.italic = TRUE;
2290 if (underline_set) {
2291 fmt.underline = underline;
2292 fmt.cs.underline = TRUE;
2294 if (strikethrough_set) {
2295 fmt.strikethrough = strikethrough;
2296 fmt.cs.strikethrough = TRUE;
2301 ? TEXT_POSITION_NORMAL
2302 : ( ( position == 1 )
2303 ? TEXT_POSITION_SUPERSCRIPT
2304 : TEXT_POSITION_SUBSCRIPT );
2305 fmt.cs.text_position = TRUE;
2309 fmt.cs.color = TRUE;
2312 fmt.font = wp_get_font_index(font_name,
2317 if (font_size_set) {
2318 fmt.font_size = wp_get_font_size_index(
2319 font_size, DEFAULT_FONT_SIZE);
2320 fmt.cs.font_size = TRUE;
2322 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2324 gtk_widget_destroy (dialog);
2326 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2330 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2332 ModestMsgEditWindowPrivate *priv;
2334 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2335 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2337 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2339 update_dimmed (window);
2344 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2346 ModestMsgEditWindowPrivate *priv;
2348 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2349 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2351 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2353 update_dimmed (window);
2358 update_dimmed (ModestMsgEditWindow *window)
2360 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2361 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2365 gboolean editor_focused;
2367 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2368 editor_focused = gtk_widget_is_focus (priv->msg_body);
2370 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2371 gtk_action_set_sensitive (action, rich_text && editor_focused);
2372 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2373 gtk_action_set_sensitive (action, rich_text && editor_focused);
2374 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2375 gtk_action_set_sensitive (action, rich_text && editor_focused);
2376 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2377 gtk_action_set_sensitive (action, rich_text && editor_focused);
2378 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2379 gtk_action_set_sensitive (action, rich_text && editor_focused);
2380 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2381 gtk_action_set_sensitive (action, rich_text && editor_focused);
2382 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2383 gtk_action_set_sensitive (action, rich_text && editor_focused);
2384 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2385 gtk_action_set_sensitive (action, rich_text && editor_focused);
2386 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2387 gtk_action_set_sensitive (action, rich_text && editor_focused);
2388 widget = priv->font_color_button;
2389 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2390 widget = priv->font_size_toolitem;
2391 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2392 widget = priv->font_face_toolitem;
2393 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2397 setup_insensitive_handlers (ModestMsgEditWindow *window)
2399 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2400 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2403 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2404 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2405 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2406 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2408 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2409 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2410 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2411 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2412 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2413 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2414 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2415 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2416 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2417 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2418 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2419 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2420 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2421 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, "/ToolBar/ActionsBold");
2423 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2424 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2425 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2426 widget = priv->font_color_button;
2427 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2428 widget = priv->font_size_toolitem;
2429 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2430 widget = priv->font_face_toolitem;
2431 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2433 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2434 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2435 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2436 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2438 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2439 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (paste_insensitive_press), window);
2440 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2441 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (copy_insensitive_press), window);
2445 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2447 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2450 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2451 gtk_action_set_sensitive (action, can_undo);
2455 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2457 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2460 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2461 gtk_action_set_sensitive (action, can_redo);
2465 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2468 GtkTextIter match_start, match_end;
2470 if (image_id == NULL)
2473 gtk_text_buffer_get_start_iter (buffer, &iter);
2475 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2476 GSList *tags = gtk_text_iter_get_tags (&match_start);
2478 for (node = tags; node != NULL; node = g_slist_next (node)) {
2479 GtkTextTag *tag = (GtkTextTag *) node->data;
2480 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2481 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2482 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2484 offset = gtk_text_iter_get_offset (&match_start);
2485 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2486 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2490 gtk_text_iter_forward_char (&iter);
2495 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2497 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2498 GtkTextIter real_start, real_end;
2499 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2501 if (gtk_text_iter_compare (start, end) > 0) {
2505 real_start = *start;
2509 GSList *tags = gtk_text_iter_get_tags (&real_start);
2511 for (node = tags; node != NULL; node = g_slist_next (node)) {
2512 GtkTextTag *tag = (GtkTextTag *) node->data;
2513 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2514 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2516 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2518 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2521 } while (gtk_text_iter_forward_char (&real_start)&&
2522 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2526 msg_body_focus (GtkWidget *focus,
2527 GdkEventFocus *event,
2531 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2536 recpt_field_changed (GtkTextBuffer *buffer,
2537 ModestMsgEditWindow *editor)
2539 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2540 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2541 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2542 gboolean dim = FALSE;
2545 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2546 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2547 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2549 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2550 gtk_text_buffer_get_char_count (cc_buffer) +
2551 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2553 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2554 gtk_action_set_sensitive (action, !dim);
2555 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2556 gtk_action_set_sensitive (action, !dim);
2560 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2562 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2566 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2568 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2572 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2574 ModestWindowPrivate *parent_priv;
2575 ModestMsgEditWindowPrivate *priv;
2576 GList *selected_attachments = NULL;
2577 gint n_att_selected = 0;
2579 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2580 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2582 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2583 n_att_selected = g_list_length (selected_attachments);
2584 g_list_free (selected_attachments);
2586 if (n_att_selected > 1)
2587 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2588 else if (n_att_selected == 0)
2589 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2591 hildon_banner_show_information (NULL, NULL, _("mail_ib_unable_to_purge_attachments"));
2595 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2597 gboolean rich_text, editor_focused;
2599 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2600 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2601 editor_focused = gtk_widget_is_focus (priv->msg_body);
2604 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2605 else if (!editor_focused)
2606 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2610 reset_modified (ModestMsgEditWindow *editor)
2612 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2613 GtkTextBuffer *buffer;
2615 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2616 gtk_text_buffer_set_modified (buffer, FALSE);
2617 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2618 gtk_text_buffer_set_modified (buffer, FALSE);
2619 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2620 gtk_text_buffer_set_modified (buffer, FALSE);
2621 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2625 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2627 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2628 GtkTextBuffer *buffer;
2630 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2631 if (gtk_text_buffer_get_modified (buffer))
2633 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2634 if (gtk_text_buffer_get_modified (buffer))
2636 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2637 if (gtk_text_buffer_get_modified (buffer))
2639 if (gtk_text_buffer_get_modified (priv->text_buffer))
2646 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2648 ModestMsgEditWindowPrivate *priv = NULL;
2650 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2651 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2653 /* check if there's no recipient added */
2654 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2655 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2656 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2657 /* no recipient contents, then select contacts */
2658 modest_msg_edit_window_open_addressbook (window, NULL);
2662 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2664 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2666 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2669 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2676 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2677 ModestMsgEditWindow *window)
2679 modest_msg_edit_window_attach_file (window);
2683 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2685 ModestMsgEditWindow *window)
2687 ModestWindowPrivate *parent_priv;
2688 ModestMsgEditWindowPrivate *priv;
2692 GList *selected_attachments = NULL;
2693 gint n_att_selected = 0;
2695 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2696 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2697 selection = gtk_clipboard_wait_for_text (clipboard);
2698 focused = gtk_window_get_focus (GTK_WINDOW (window));
2700 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2701 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2702 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2703 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2705 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2706 n_att_selected = g_list_length (selected_attachments);
2707 g_list_free (selected_attachments);
2709 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2710 gtk_action_set_sensitive (action, n_att_selected == 1);
2713 update_paste_dimming (window);
2717 update_window_title (ModestMsgEditWindow *window)
2719 ModestMsgEditWindowPrivate *priv = NULL;
2720 const gchar *subject;
2722 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2723 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2724 if (subject == NULL || subject[0] == '\0')
2725 subject = _("mail_va_new_email");
2727 gtk_window_set_title (GTK_WINDOW (window), subject);
2732 subject_field_changed (GtkEditable *editable,
2733 ModestMsgEditWindow *window)
2735 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2736 update_window_title (window);
2737 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2741 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2744 ModestMsgEditWindowPrivate *priv = NULL;
2746 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2747 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2749 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2751 gtk_widget_show_all (priv->find_toolbar);
2752 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2754 gtk_widget_hide_all (priv->find_toolbar);
2755 gtk_widget_grab_focus (priv->msg_body);
2761 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2763 GtkTextIter *match_start,
2764 GtkTextIter *match_end)
2766 GtkTextIter end_iter;
2767 gchar *str_casefold;
2770 gchar *range_casefold;
2773 gboolean result = FALSE;
2780 gtk_text_iter_forward_to_end (&end_iter);
2782 str_casefold = g_utf8_casefold (str, -1);
2783 str_chars_n = strlen (str);
2785 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2786 range_casefold = g_utf8_casefold (range_text, -1);
2787 range_chars_n = strlen (range_casefold);
2789 if (range_chars_n < str_chars_n) {
2790 g_free (str_casefold);
2791 g_free (range_text);
2792 g_free (range_casefold);
2796 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2797 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2798 if (!g_utf8_collate (range_subtext, str_casefold)) {
2799 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2801 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2802 match_start, match_end, NULL);
2803 g_free (found_text);
2805 g_free (range_subtext);
2809 g_free (str_casefold);
2810 g_free (range_text);
2811 g_free (range_casefold);
2818 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2819 ModestMsgEditWindow *window)
2821 gchar *current_search = NULL;
2822 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2824 GtkTextIter selection_start, selection_end;
2825 GtkTextIter match_start, match_end;
2826 gboolean continue_search = FALSE;
2828 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2829 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2830 g_free (current_search);
2831 g_free (priv->last_search);
2832 priv->last_search = NULL;
2833 /* Information banner about empty search */
2834 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2838 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2839 continue_search = TRUE;
2841 g_free (priv->last_search);
2842 priv->last_search = g_strdup (current_search);
2845 if (continue_search) {
2846 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2847 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2848 &match_start, &match_end);
2850 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2852 GtkTextIter buffer_start;
2853 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2854 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2855 &match_start, &match_end);
2857 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2860 /* Mark as selected the string found in search */
2862 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2863 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2865 g_free (priv->last_search);
2866 priv->last_search = NULL;
2868 g_free (current_search);
2872 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2873 ModestMsgEditWindow *window)
2875 GtkToggleAction *toggle;
2876 ModestWindowPrivate *parent_priv;
2877 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2879 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2880 gtk_toggle_action_set_active (toggle, FALSE);
2885 update_paste_dimming (ModestMsgEditWindow *window)
2887 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2888 GtkAction *action = NULL;
2889 GtkClipboard *clipboard = NULL;
2893 focused = gtk_window_get_focus (GTK_WINDOW (window));
2895 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2896 active = gtk_clipboard_wait_is_text_available (clipboard);
2899 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2903 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2904 gtk_action_set_sensitive (action, active);
2909 paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2911 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (editor));
2913 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2914 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
2916 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
2921 copy_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2923 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_copy"));
2929 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2931 ModestMsgEditWindow *window)
2933 update_paste_dimming (window);
2937 update_select_all_dimming (ModestMsgEditWindow *window)
2940 gboolean dimmed = FALSE;
2942 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2944 focused = gtk_window_get_focus (GTK_WINDOW (window));
2945 if (GTK_IS_ENTRY (focused)) {
2946 const gchar *current_text;
2947 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2948 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2949 } else if (GTK_IS_TEXT_VIEW (focused)) {
2950 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2951 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2952 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2955 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2956 gtk_action_set_sensitive (action, !dimmed);
2960 update_zoom_dimming (ModestMsgEditWindow *window)
2963 gboolean dimmed = FALSE;
2965 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2967 focused = gtk_window_get_focus (GTK_WINDOW (window));
2968 dimmed = ! WP_IS_TEXT_VIEW (focused);
2969 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2970 gtk_action_set_sensitive (action, !dimmed);
2974 edit_menu_activated (GtkAction *action,
2977 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2979 update_select_all_dimming (window);
2982 view_menu_activated (GtkAction *action,
2985 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2987 update_zoom_dimming (window);
2991 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2993 ModestMsgEditWindowPrivate *priv;
2995 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3000 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3003 ModestMsgEditWindowPrivate *priv;
3005 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);