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 data->attachments = priv->attachments; /* TODO: copy and free ? */
1075 data->priority_flags = priv->priority_flags;
1080 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1082 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1085 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1093 g_free (data->subject);
1094 g_free (data->plain_body);
1095 g_free (data->html_body);
1096 g_free (data->account_name);
1098 if (data->draft_msg != NULL) {
1099 g_object_unref (data->draft_msg);
1100 data->draft_msg = NULL;
1103 g_list_foreach (data->attachments, (GFunc)g_free, NULL);
1104 g_list_free (data->attachments);
1106 /* TODO: Free data->attachments? */
1108 g_slice_free (MsgData, data);
1112 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1115 ModestMsgEditWindowPrivate *priv = NULL;
1116 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1118 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1120 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1122 return MODEST_MSG_EDIT_FORMAT_HTML;
1124 return MODEST_MSG_EDIT_FORMAT_TEXT;
1128 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1129 ModestMsgEditFormat format)
1131 ModestMsgEditWindowPrivate *priv;
1133 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1134 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1137 case MODEST_MSG_EDIT_FORMAT_HTML:
1138 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1140 case MODEST_MSG_EDIT_FORMAT_TEXT:
1141 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1144 g_return_if_reached ();
1148 ModestMsgEditFormatState *
1149 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1151 ModestMsgEditFormatState *format_state = NULL;
1152 ModestMsgEditWindowPrivate *priv;
1153 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1155 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1156 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1158 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1160 format_state = g_new0 (ModestMsgEditFormatState, 1);
1161 format_state->bold = buffer_format->bold&0x1;
1162 format_state->italics = buffer_format->italic&0x1;
1163 format_state->bullet = buffer_format->bullet&0x1;
1164 format_state->color = buffer_format->color;
1165 format_state->font_size = buffer_format->font_size;
1166 format_state->font_family = wp_get_font_name (buffer_format->font);
1167 format_state->justification = buffer_format->justification;
1168 g_free (buffer_format);
1170 return format_state;
1175 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1176 const ModestMsgEditFormatState *format_state)
1178 ModestMsgEditWindowPrivate *priv;
1179 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1180 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1181 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1182 g_return_if_fail (format_state != NULL);
1184 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1185 gtk_widget_grab_focus (priv->msg_body);
1186 buffer_format->bold = (format_state->bold != FALSE);
1187 buffer_format->italic = (format_state->italics != FALSE);
1188 buffer_format->color = format_state->color;
1189 buffer_format->font_size = format_state->font_size;
1190 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1191 buffer_format->justification = format_state->justification;
1192 buffer_format->bullet = format_state->bullet;
1194 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1196 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1197 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1198 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1199 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1200 buffer_format->cs.font = (buffer_format->font != current_format->font);
1201 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1202 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1204 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1205 if (buffer_format->cs.bold) {
1206 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1208 if (buffer_format->cs.italic) {
1209 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1211 if (buffer_format->cs.color) {
1212 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1214 if (buffer_format->cs.font_size) {
1215 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1217 if (buffer_format->cs.justification) {
1218 switch (buffer_format->justification) {
1219 case GTK_JUSTIFY_LEFT:
1220 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1222 case GTK_JUSTIFY_CENTER:
1223 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1225 case GTK_JUSTIFY_RIGHT:
1226 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1233 if (buffer_format->cs.font) {
1234 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1236 if (buffer_format->cs.bullet) {
1237 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1239 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1240 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1242 g_free (current_format);
1247 toggle_action_set_active_block_notify (GtkToggleAction *action,
1250 GSList *proxies = NULL;
1252 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1253 proxies != NULL; proxies = g_slist_next (proxies)) {
1254 GtkWidget *widget = (GtkWidget *) proxies->data;
1255 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1258 gtk_toggle_action_set_active (action, value);
1260 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1261 proxies != NULL; proxies = g_slist_next (proxies)) {
1262 GtkWidget *widget = (GtkWidget *) proxies->data;
1263 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1268 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1270 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1272 ModestWindowPrivate *parent_priv;
1273 ModestMsgEditWindowPrivate *priv;
1274 GtkWidget *new_size_menuitem;
1275 GtkWidget *new_font_menuitem;
1277 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1278 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1280 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1281 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1282 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1283 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1285 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1286 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1287 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1290 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1292 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1293 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1295 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1296 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1298 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1299 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1301 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1302 G_CALLBACK (modest_msg_edit_window_color_button_change),
1304 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1305 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1306 G_CALLBACK (modest_msg_edit_window_color_button_change),
1309 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1310 buffer_format->font_size))->data);
1311 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1315 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1316 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1317 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1319 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1320 G_CALLBACK (modest_msg_edit_window_size_change),
1322 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1323 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1324 G_CALLBACK (modest_msg_edit_window_size_change),
1328 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1329 buffer_format->font))->data);
1330 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1334 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1335 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1336 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1338 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1339 G_CALLBACK (modest_msg_edit_window_font_change),
1341 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1342 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1343 G_CALLBACK (modest_msg_edit_window_font_change),
1347 g_free (buffer_format);
1353 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1356 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1357 ModestMsgEditWindowPrivate *priv;
1358 GtkWidget *dialog = NULL;
1360 const GdkColor *new_color = NULL;
1362 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1363 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1365 #ifdef MODEST_HILDON_VERSION_0
1366 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1367 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1369 dialog = hildon_color_chooser_new ();
1370 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1371 #endif /*MODEST_HILDON_VERSION_0*/
1372 g_free (buffer_format);
1374 response = gtk_dialog_run (GTK_DIALOG (dialog));
1376 case GTK_RESPONSE_OK: {
1377 #ifdef MODEST_HILDON_VERSION_0
1378 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1381 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1383 #endif /*MODEST_HILDON_VERSION_0*/
1390 gtk_widget_destroy (dialog);
1392 if (new_color != NULL)
1393 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1398 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1401 ModestMsgEditWindowPrivate *priv;
1402 GtkWidget *dialog = NULL;
1404 GdkColor *old_color = NULL;
1405 const GdkColor *new_color = NULL;
1407 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1408 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1410 #ifdef MODEST_HILDON_VERSION_0
1411 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1412 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1414 dialog = hildon_color_chooser_new ();
1415 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1416 #endif /*MODEST_HILDON_VERSION_9*/
1418 response = gtk_dialog_run (GTK_DIALOG (dialog));
1420 case GTK_RESPONSE_OK: {
1421 #ifdef MODEST_HILDON_VERSION_0
1422 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1425 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1427 #endif /*MODEST_HILDON_VERSION_0*/
1433 gtk_widget_destroy (dialog);
1435 if (new_color != NULL)
1436 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1442 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1445 ModestMsgEditWindowPrivate *priv;
1446 GtkWidget *dialog = NULL;
1448 GSList *uris = NULL;
1449 GSList *uri_node = NULL;
1451 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1453 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1454 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1455 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1457 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1459 response = gtk_dialog_run (GTK_DIALOG (dialog));
1461 case GTK_RESPONSE_OK:
1462 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1467 gtk_widget_destroy (dialog);
1469 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1471 GnomeVFSHandle *handle = NULL;
1472 GnomeVFSResult result;
1473 GtkTextIter position;
1474 GtkTextMark *insert_mark;
1476 uri = (const gchar *) uri_node->data;
1477 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1478 if (result == GNOME_VFS_OK) {
1479 GdkPixbufLoader *loader;
1481 GnomeVFSFileInfo info;
1482 gchar *filename, *basename;
1483 TnyMimePart *mime_part;
1486 const gchar *mime_type = NULL;
1488 filename = g_filename_from_uri (uri, NULL, NULL);
1489 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1491 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1493 mime_part = tny_platform_factory_new_mime_part
1494 (modest_runtime_get_platform_factory ());
1495 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1497 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1499 content_id = g_strdup_printf ("%d", priv->last_cid);
1500 tny_mime_part_set_content_id (mime_part, content_id);
1501 g_free (content_id);
1504 basename = g_path_get_basename (filename);
1505 tny_mime_part_set_filename (mime_part, basename);
1508 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1509 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1511 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1512 gtk_widget_show_all (priv->attachments_caption);
1513 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1516 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1517 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1518 unsigned char read_buffer[128];
1520 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1521 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1524 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1525 g_object_ref (pixbuf);
1526 gdk_pixbuf_loader_close (loader, NULL);
1527 g_object_unref (loader);
1529 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1530 GdkPixbuf *new_pixbuf;
1532 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1533 gdk_pixbuf_get_width (pixbuf);
1534 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1535 g_object_unref (pixbuf);
1536 pixbuf = new_pixbuf;
1539 if (pixbuf != NULL) {
1540 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1541 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1542 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1551 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1554 ModestMsgEditWindowPrivate *priv;
1555 GtkWidget *dialog = NULL;
1557 GSList *uris = NULL;
1560 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1562 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1563 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1565 response = gtk_dialog_run (GTK_DIALOG (dialog));
1567 case GTK_RESPONSE_OK:
1568 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1573 gtk_widget_destroy (dialog);
1575 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1577 GnomeVFSHandle *handle = NULL;
1578 GnomeVFSResult result;
1580 uri = (const gchar *) uri_node->data;
1581 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1582 if (result == GNOME_VFS_OK) {
1583 TnyMimePart *mime_part;
1585 const gchar *mime_type = NULL;
1589 GnomeVFSFileInfo info;
1591 filename = g_filename_from_uri (uri, NULL, NULL);
1593 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1594 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1595 mime_part = tny_platform_factory_new_mime_part
1596 (modest_runtime_get_platform_factory ());
1597 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1599 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1601 content_id = g_strdup_printf ("%d", priv->last_cid);
1602 tny_mime_part_set_content_id (mime_part, content_id);
1603 g_free (content_id);
1606 basename = g_path_get_basename (filename);
1607 tny_mime_part_set_filename (mime_part, basename);
1610 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1611 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1613 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1614 gtk_widget_show_all (priv->attachments_caption);
1615 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1620 g_slist_foreach (uris, (GFunc) g_free, NULL);
1621 g_slist_free (uris);
1625 modest_msg_edit_window_attach_file_noninteractive (
1626 ModestMsgEditWindow *window,
1627 const gchar *file_uri)
1630 ModestMsgEditWindowPrivate *priv;
1632 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1634 if (file_uri && strlen(file_uri)) {
1637 /* TODO: We should probably try to use only the URI,
1638 * instead of using a filename.
1640 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1642 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1645 file_id = g_open (filename, O_RDONLY, 0);
1646 if (file_id != -1) {
1647 TnyMimePart *mime_part;
1649 const gchar *mime_type;
1652 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1653 mime_type = gnome_vfs_get_mime_type(filename);
1655 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1657 mime_part = tny_platform_factory_new_mime_part
1658 (modest_runtime_get_platform_factory ());
1659 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1661 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1663 content_id = g_strdup_printf ("%d", priv->last_cid);
1664 tny_mime_part_set_content_id (mime_part, content_id);
1665 g_free (content_id);
1668 basename = g_path_get_basename (filename);
1669 tny_mime_part_set_filename (mime_part, basename);
1672 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1673 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1675 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1676 gtk_widget_show_all (priv->attachments_caption);
1677 } else if (file_id == -1) {
1679 g_warning("file to be attached does not exist: %s", filename);
1687 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1690 ModestMsgEditWindowPrivate *priv;
1691 gboolean clean_list = FALSE;
1693 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1694 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1696 if (att_list == NULL) {
1697 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1701 if (att_list == NULL) {
1702 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1704 GtkWidget *confirmation_dialog = NULL;
1705 gboolean dialog_response;
1707 gchar *message = NULL;
1708 const gchar *filename = NULL;
1710 if (att_list->next == NULL) {
1711 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1715 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1716 att_list->next == NULL), filename);
1717 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1719 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1720 gtk_widget_destroy (confirmation_dialog);
1721 if (!dialog_response) {
1723 g_list_free (att_list);
1726 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1728 for (node = att_list; node != NULL; node = g_list_next (node)) {
1729 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1730 const gchar *att_id;
1731 priv->attachments = g_list_remove (priv->attachments, mime_part);
1733 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1735 if (priv->attachments == NULL)
1736 gtk_widget_hide (priv->attachments_caption);
1737 att_id = tny_mime_part_get_content_id (mime_part);
1739 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1741 g_object_unref (mime_part);
1742 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1747 g_list_free (att_list);
1751 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1754 ModestMsgEditWindowPrivate *priv;
1755 GdkColor *new_color;
1756 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1758 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1759 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1762 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1764 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1766 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1768 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1773 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1776 ModestMsgEditWindowPrivate *priv;
1777 gint new_size_index;
1778 ModestMsgEditWindow *window;
1781 window = MODEST_MSG_EDIT_WINDOW (userdata);
1782 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1783 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1785 if (gtk_check_menu_item_get_active (menu_item)) {
1787 WPTextBufferFormat format;
1789 memset (&format, 0, sizeof (format));
1790 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1792 label = gtk_bin_get_child (GTK_BIN (menu_item));
1794 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1795 format.cs.font_size = TRUE;
1796 format.cs.text_position = TRUE;
1797 format.cs.font = TRUE;
1798 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1799 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1801 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1802 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1803 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1805 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1806 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1807 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1813 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1816 ModestMsgEditWindowPrivate *priv;
1817 gint new_font_index;
1818 ModestMsgEditWindow *window;
1821 window = MODEST_MSG_EDIT_WINDOW (userdata);
1822 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1823 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1825 if (gtk_check_menu_item_get_active (menu_item)) {
1828 label = gtk_bin_get_child (GTK_BIN (menu_item));
1830 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1832 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1833 (gpointer) new_font_index))
1834 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1836 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1837 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1838 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1844 modest_msg_edit_window_set_zoom (ModestWindow *window,
1847 ModestMsgEditWindowPrivate *priv;
1848 ModestWindowPrivate *parent_priv;
1849 GtkRadioAction *zoom_radio_action;
1851 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1853 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1854 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1855 priv->zoom_level = zoom;
1856 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1858 /* Zoom level menu options should be updated with the current zoom level */
1859 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1860 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1861 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1862 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1863 /* FIXME: Not availible before Gtk 2.10 */
1865 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1870 modest_msg_edit_window_get_zoom (ModestWindow *window)
1872 ModestMsgEditWindowPrivate *priv;
1874 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1876 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1877 return priv->zoom_level;
1881 zoom_allowed (ModestMsgEditWindow *window)
1885 focus = gtk_window_get_focus (GTK_WINDOW (window));
1886 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1890 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1892 ModestWindowPrivate *parent_priv;
1893 GtkRadioAction *zoom_radio_action;
1894 GSList *group, *node;
1896 /* First we check if the text view is focused. If not, zooming is not allowed */
1897 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1898 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1902 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1903 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1904 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1906 group = gtk_radio_action_get_group (zoom_radio_action);
1908 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1909 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1913 for (node = group; node != NULL; node = g_slist_next (node)) {
1914 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1915 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1923 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1925 ModestWindowPrivate *parent_priv;
1926 GtkRadioAction *zoom_radio_action;
1927 GSList *group, *node;
1929 /* First we check if the text view is focused. If not, zooming is not allowed */
1930 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1931 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1935 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1936 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1937 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1939 group = gtk_radio_action_get_group (zoom_radio_action);
1941 for (node = group; node != NULL; node = g_slist_next (node)) {
1942 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1943 if (node->next != NULL) {
1944 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1947 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1955 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1957 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1958 ModestWindowPrivate *parent_priv;
1959 ModestWindowMgr *mgr;
1960 gboolean is_fullscreen;
1961 GtkAction *fs_toggle_action;
1964 mgr = modest_runtime_get_window_mgr ();
1965 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1967 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1969 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1970 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1971 if (is_fullscreen != active)
1972 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1980 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1982 ModestWindowPrivate *parent_priv;
1983 GtkAction *fs_toggle_action;
1986 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1988 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1989 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1990 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1994 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1997 ModestMsgEditWindowPrivate *priv = NULL;
1998 const gchar *recipients;
1999 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2001 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2002 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2003 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2004 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2005 gtk_widget_show (priv->cc_caption);
2007 gtk_widget_hide (priv->cc_caption);
2008 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2012 modest_msg_edit_window_show_bcc (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->bcc_caption, TRUE);
2021 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2022 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2023 gtk_widget_show (priv->bcc_caption);
2025 gtk_widget_hide (priv->bcc_caption);
2026 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2030 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2031 ModestRecptEditor *editor)
2033 ModestMsgEditWindowPrivate *priv;
2035 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2036 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2037 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2039 if (editor == NULL) {
2040 GtkWidget *view_focus;
2041 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2043 /* This code should be kept in sync with ModestRecptEditor. The
2044 textview inside the recpt editor is the one that really gets the
2045 focus. As it's inside a scrolled window, and this one inside the
2046 hbox recpt editor inherits from, we'll need to go up in the
2047 hierarchy to know if the text view is part of the recpt editor
2048 or if it's a different text entry */
2050 if (gtk_widget_get_parent (view_focus)) {
2051 GtkWidget *first_parent;
2053 first_parent = gtk_widget_get_parent (view_focus);
2054 if (gtk_widget_get_parent (first_parent) &&
2055 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2056 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2061 editor = MODEST_RECPT_EDITOR (priv->to_field);
2065 modest_address_book_select_addresses (editor);
2070 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2072 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2074 modest_msg_edit_window_open_addressbook (window, NULL);
2078 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2079 gboolean show_toolbar)
2081 ModestWindowPrivate *parent_priv;
2083 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2084 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2086 /* FIXME: we can not just use the code of
2087 modest_msg_edit_window_setup_toolbar because it has a
2088 mixture of both initialization and creation code. */
2091 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2093 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2097 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2098 TnyHeaderFlags priority_flags)
2100 ModestMsgEditWindowPrivate *priv;
2101 ModestWindowPrivate *parent_priv;
2103 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2105 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2106 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2107 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2109 if (priv->priority_flags != priority_flags) {
2110 GtkAction *priority_action = NULL;
2112 priv->priority_flags = priority_flags;
2114 switch (priority_flags) {
2115 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2116 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2117 gtk_widget_show (priv->priority_icon);
2118 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2119 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2121 case TNY_HEADER_FLAG_LOW_PRIORITY:
2122 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2123 gtk_widget_show (priv->priority_icon);
2124 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2125 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2128 gtk_widget_hide (priv->priority_icon);
2129 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2130 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2133 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2134 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2139 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2142 ModestMsgEditWindowPrivate *priv;
2143 ModestWindowPrivate *parent_priv;
2144 gint current_format;
2146 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2148 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2149 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2151 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2152 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2154 if (current_format != file_format) {
2155 switch (file_format) {
2156 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2157 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2159 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2163 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2164 response = gtk_dialog_run (GTK_DIALOG (dialog));
2165 gtk_widget_destroy (dialog);
2166 if (response == GTK_RESPONSE_OK) {
2167 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2169 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2170 toggle_action_set_active_block_notify (action, TRUE);
2175 update_dimmed (window);
2180 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2183 ModestMsgEditWindowPrivate *priv;
2184 WPTextBufferFormat oldfmt, fmt;
2185 gint old_position = 0;
2189 GdkColor *color = NULL;
2190 gboolean bold, bold_set, italic, italic_set;
2191 gboolean underline, underline_set;
2192 gboolean strikethrough, strikethrough_set;
2193 gboolean position_set;
2194 gboolean font_size_set, font_set, color_set;
2197 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2198 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2200 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2202 /* First we get the currently selected font information */
2203 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2204 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2206 switch (oldfmt.text_position) {
2207 case TEXT_POSITION_NORMAL:
2210 case TEXT_POSITION_SUPERSCRIPT:
2218 g_object_set (G_OBJECT (dialog),
2219 "bold", oldfmt.bold != FALSE,
2220 "bold-set", !oldfmt.cs.bold,
2221 "underline", oldfmt.underline != FALSE,
2222 "underline-set", !oldfmt.cs.underline,
2223 "italic", oldfmt.italic != FALSE,
2224 "italic-set", !oldfmt.cs.italic,
2225 "strikethrough", oldfmt.strikethrough != FALSE,
2226 "strikethrough-set", !oldfmt.cs.strikethrough,
2227 "color", &oldfmt.color,
2228 "color-set", !oldfmt.cs.color,
2229 "size", wp_font_size[oldfmt.font_size],
2230 "size-set", !oldfmt.cs.font_size,
2231 "position", old_position,
2232 "position-set", !oldfmt.cs.text_position,
2233 "family", wp_get_font_name (oldfmt.font),
2234 "family-set", !oldfmt.cs.font,
2237 gtk_widget_show_all (dialog);
2238 response = gtk_dialog_run (GTK_DIALOG (dialog));
2239 if (response == GTK_RESPONSE_OK) {
2241 g_object_get( dialog,
2243 "bold-set", &bold_set,
2244 "underline", &underline,
2245 "underline-set", &underline_set,
2247 "italic-set", &italic_set,
2248 "strikethrough", &strikethrough,
2249 "strikethrough-set", &strikethrough_set,
2251 "color-set", &color_set,
2253 "size-set", &font_size_set,
2254 "family", &font_name,
2255 "family-set", &font_set,
2256 "position", &position,
2257 "position-set", &position_set,
2262 if (response == GTK_RESPONSE_OK) {
2263 memset(&fmt, 0, sizeof(fmt));
2269 fmt.italic = italic;
2270 fmt.cs.italic = TRUE;
2272 if (underline_set) {
2273 fmt.underline = underline;
2274 fmt.cs.underline = TRUE;
2276 if (strikethrough_set) {
2277 fmt.strikethrough = strikethrough;
2278 fmt.cs.strikethrough = TRUE;
2283 ? TEXT_POSITION_NORMAL
2284 : ( ( position == 1 )
2285 ? TEXT_POSITION_SUPERSCRIPT
2286 : TEXT_POSITION_SUBSCRIPT );
2287 fmt.cs.text_position = TRUE;
2291 fmt.cs.color = TRUE;
2294 fmt.font = wp_get_font_index(font_name,
2299 if (font_size_set) {
2300 fmt.font_size = wp_get_font_size_index(
2301 font_size, DEFAULT_FONT_SIZE);
2302 fmt.cs.font_size = TRUE;
2304 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2306 gtk_widget_destroy (dialog);
2308 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2312 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2314 ModestMsgEditWindowPrivate *priv;
2316 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2317 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2319 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2321 update_dimmed (window);
2326 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2328 ModestMsgEditWindowPrivate *priv;
2330 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2331 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2333 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2335 update_dimmed (window);
2340 update_dimmed (ModestMsgEditWindow *window)
2342 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2343 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2347 gboolean editor_focused;
2349 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2350 editor_focused = gtk_widget_is_focus (priv->msg_body);
2352 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2353 gtk_action_set_sensitive (action, rich_text && editor_focused);
2354 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2355 gtk_action_set_sensitive (action, rich_text && editor_focused);
2356 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2357 gtk_action_set_sensitive (action, rich_text && editor_focused);
2358 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2359 gtk_action_set_sensitive (action, rich_text && editor_focused);
2360 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2361 gtk_action_set_sensitive (action, rich_text && editor_focused);
2362 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2363 gtk_action_set_sensitive (action, rich_text && editor_focused);
2364 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2365 gtk_action_set_sensitive (action, rich_text && editor_focused);
2366 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2367 gtk_action_set_sensitive (action, rich_text && editor_focused);
2368 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2369 gtk_action_set_sensitive (action, rich_text && editor_focused);
2370 widget = priv->font_color_button;
2371 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2372 widget = priv->font_size_toolitem;
2373 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2374 widget = priv->font_face_toolitem;
2375 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2379 setup_insensitive_handlers (ModestMsgEditWindow *window)
2381 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2382 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2385 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2386 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2387 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2388 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2390 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2391 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2392 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2393 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2394 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2395 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2396 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2397 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2398 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2399 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2400 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2401 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2402 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2403 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2404 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2405 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2406 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2407 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2408 widget = priv->font_color_button;
2409 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2410 widget = priv->font_size_toolitem;
2411 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2412 widget = priv->font_face_toolitem;
2413 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2415 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2416 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2417 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2418 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2420 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2421 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (paste_insensitive_press), window);
2422 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2423 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (copy_insensitive_press), window);
2427 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2429 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2432 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2433 gtk_action_set_sensitive (action, can_undo);
2437 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2439 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2442 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2443 gtk_action_set_sensitive (action, can_redo);
2447 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2450 GtkTextIter match_start, match_end;
2452 if (image_id == NULL)
2455 gtk_text_buffer_get_start_iter (buffer, &iter);
2457 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2458 GSList *tags = gtk_text_iter_get_tags (&match_start);
2460 for (node = tags; node != NULL; node = g_slist_next (node)) {
2461 GtkTextTag *tag = (GtkTextTag *) node->data;
2462 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2463 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2464 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2466 offset = gtk_text_iter_get_offset (&match_start);
2467 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2468 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2472 gtk_text_iter_forward_char (&iter);
2477 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2479 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2480 GtkTextIter real_start, real_end;
2481 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2483 if (gtk_text_iter_compare (start, end) > 0) {
2487 real_start = *start;
2491 GSList *tags = gtk_text_iter_get_tags (&real_start);
2493 for (node = tags; node != NULL; node = g_slist_next (node)) {
2494 GtkTextTag *tag = (GtkTextTag *) node->data;
2495 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2496 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2498 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2500 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2503 } while (gtk_text_iter_forward_char (&real_start)&&
2504 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2508 msg_body_focus (GtkWidget *focus,
2509 GdkEventFocus *event,
2513 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2518 recpt_field_changed (GtkTextBuffer *buffer,
2519 ModestMsgEditWindow *editor)
2521 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2522 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2523 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2524 gboolean dim = FALSE;
2527 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2528 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2529 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2531 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2532 gtk_text_buffer_get_char_count (cc_buffer) +
2533 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2535 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2536 gtk_action_set_sensitive (action, !dim);
2537 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2538 gtk_action_set_sensitive (action, !dim);
2542 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2544 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2548 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2550 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2554 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2556 ModestWindowPrivate *parent_priv;
2557 ModestMsgEditWindowPrivate *priv;
2558 GList *selected_attachments = NULL;
2559 gint n_att_selected = 0;
2561 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2562 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2564 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2565 n_att_selected = g_list_length (selected_attachments);
2566 g_list_free (selected_attachments);
2568 if (n_att_selected > 1)
2569 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2570 else if (n_att_selected == 0)
2571 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2573 hildon_banner_show_information (NULL, NULL, _("mail_ib_unable_to_purge_attachments"));
2577 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2579 gboolean rich_text, editor_focused;
2581 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2582 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2583 editor_focused = gtk_widget_is_focus (priv->msg_body);
2586 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2587 else if (!editor_focused)
2588 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2592 reset_modified (ModestMsgEditWindow *editor)
2594 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2595 GtkTextBuffer *buffer;
2597 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2598 gtk_text_buffer_set_modified (buffer, FALSE);
2599 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2600 gtk_text_buffer_set_modified (buffer, FALSE);
2601 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2602 gtk_text_buffer_set_modified (buffer, FALSE);
2603 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2607 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2609 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2610 GtkTextBuffer *buffer;
2612 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2613 if (gtk_text_buffer_get_modified (buffer))
2615 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2616 if (gtk_text_buffer_get_modified (buffer))
2618 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2619 if (gtk_text_buffer_get_modified (buffer))
2621 if (gtk_text_buffer_get_modified (priv->text_buffer))
2628 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2630 ModestMsgEditWindowPrivate *priv = NULL;
2632 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2633 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2635 /* check if there's no recipient added */
2636 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2637 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2638 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2639 /* no recipient contents, then select contacts */
2640 modest_msg_edit_window_open_addressbook (window, NULL);
2644 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2646 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2648 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2651 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2658 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2659 ModestMsgEditWindow *window)
2661 modest_msg_edit_window_attach_file (window);
2665 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2667 ModestMsgEditWindow *window)
2669 ModestWindowPrivate *parent_priv;
2670 ModestMsgEditWindowPrivate *priv;
2674 GList *selected_attachments = NULL;
2675 gint n_att_selected = 0;
2677 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2678 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2679 selection = gtk_clipboard_wait_for_text (clipboard);
2680 focused = gtk_window_get_focus (GTK_WINDOW (window));
2682 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2683 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2684 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2685 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2687 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2688 n_att_selected = g_list_length (selected_attachments);
2689 g_list_free (selected_attachments);
2691 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2692 gtk_action_set_sensitive (action, n_att_selected == 1);
2695 update_paste_dimming (window);
2699 update_window_title (ModestMsgEditWindow *window)
2701 ModestMsgEditWindowPrivate *priv = NULL;
2702 const gchar *subject;
2704 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2705 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2706 if (subject == NULL || subject[0] == '\0')
2707 subject = _("mail_va_new_email");
2709 gtk_window_set_title (GTK_WINDOW (window), subject);
2714 subject_field_changed (GtkEditable *editable,
2715 ModestMsgEditWindow *window)
2717 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2718 update_window_title (window);
2719 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2723 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2726 ModestMsgEditWindowPrivate *priv = NULL;
2728 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2729 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2731 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2733 gtk_widget_show_all (priv->find_toolbar);
2734 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2736 gtk_widget_hide_all (priv->find_toolbar);
2737 gtk_widget_grab_focus (priv->msg_body);
2743 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2745 GtkTextIter *match_start,
2746 GtkTextIter *match_end)
2748 GtkTextIter end_iter;
2749 gchar *str_casefold;
2752 gchar *range_casefold;
2755 gboolean result = FALSE;
2762 gtk_text_iter_forward_to_end (&end_iter);
2764 str_casefold = g_utf8_casefold (str, -1);
2765 str_chars_n = strlen (str);
2767 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2768 range_casefold = g_utf8_casefold (range_text, -1);
2769 range_chars_n = strlen (range_casefold);
2771 if (range_chars_n < str_chars_n) {
2772 g_free (str_casefold);
2773 g_free (range_text);
2774 g_free (range_casefold);
2778 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2779 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2780 if (!g_utf8_collate (range_subtext, str_casefold)) {
2781 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2783 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2784 match_start, match_end, NULL);
2785 g_free (found_text);
2787 g_free (range_subtext);
2791 g_free (str_casefold);
2792 g_free (range_text);
2793 g_free (range_casefold);
2800 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2801 ModestMsgEditWindow *window)
2803 gchar *current_search = NULL;
2804 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2806 GtkTextIter selection_start, selection_end;
2807 GtkTextIter match_start, match_end;
2808 gboolean continue_search = FALSE;
2810 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2811 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2812 g_free (current_search);
2813 g_free (priv->last_search);
2814 priv->last_search = NULL;
2815 /* Information banner about empty search */
2816 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2820 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2821 continue_search = TRUE;
2823 g_free (priv->last_search);
2824 priv->last_search = g_strdup (current_search);
2827 if (continue_search) {
2828 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2829 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2830 &match_start, &match_end);
2832 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2834 GtkTextIter buffer_start;
2835 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2836 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2837 &match_start, &match_end);
2839 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2842 /* Mark as selected the string found in search */
2844 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2845 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2847 g_free (priv->last_search);
2848 priv->last_search = NULL;
2850 g_free (current_search);
2854 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2855 ModestMsgEditWindow *window)
2857 GtkToggleAction *toggle;
2858 ModestWindowPrivate *parent_priv;
2859 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2861 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2862 gtk_toggle_action_set_active (toggle, FALSE);
2867 update_paste_dimming (ModestMsgEditWindow *window)
2869 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2870 GtkAction *action = NULL;
2871 GtkClipboard *clipboard = NULL;
2875 focused = gtk_window_get_focus (GTK_WINDOW (window));
2877 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2878 active = gtk_clipboard_wait_is_text_available (clipboard);
2881 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2885 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2886 gtk_action_set_sensitive (action, active);
2891 paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2893 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (editor));
2895 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2896 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
2898 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
2903 copy_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2905 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_copy"));
2911 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2913 ModestMsgEditWindow *window)
2915 update_paste_dimming (window);
2919 update_select_all_dimming (ModestMsgEditWindow *window)
2922 gboolean dimmed = FALSE;
2924 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2926 focused = gtk_window_get_focus (GTK_WINDOW (window));
2927 if (GTK_IS_ENTRY (focused)) {
2928 const gchar *current_text;
2929 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2930 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2931 } else if (GTK_IS_TEXT_VIEW (focused)) {
2932 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2933 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2934 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2937 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2938 gtk_action_set_sensitive (action, !dimmed);
2942 update_zoom_dimming (ModestMsgEditWindow *window)
2945 gboolean dimmed = FALSE;
2947 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2949 focused = gtk_window_get_focus (GTK_WINDOW (window));
2950 dimmed = ! WP_IS_TEXT_VIEW (focused);
2951 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2952 gtk_action_set_sensitive (action, !dimmed);
2956 edit_menu_activated (GtkAction *action,
2959 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2961 update_select_all_dimming (window);
2964 view_menu_activated (GtkAction *action,
2967 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2969 update_zoom_dimming (window);
2973 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2975 ModestMsgEditWindowPrivate *priv;
2977 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2982 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2985 ModestMsgEditWindowPrivate *priv;
2987 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);