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-tny-folder.h"
59 #include "modest-address-book.h"
60 #include "modest-text-utils.h"
61 #include <tny-simple-list.h>
62 #include <wptextview.h>
63 #include <wptextbuffer.h>
64 #include "modest-scroll-area.h"
66 #include "modest-hildon-includes.h"
67 #ifdef MODEST_HAVE_HILDON0_WIDGETS
68 #include <hildon-widgets/hildon-color-chooser.h>
70 #include "widgets/modest-msg-edit-window-ui.h"
71 #ifdef MODEST_HAVE_HILDON0_WIDGETS
72 #include <libgnomevfs/gnome-vfs-mime-utils.h>
74 #include <libgnomevfs/gnome-vfs-mime.h>
76 #include "modest-maemo-utils.h"
79 #define DEFAULT_FONT_SIZE 3
80 #define DEFAULT_FONT 2
81 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
82 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
83 #define DEFAULT_MAIN_VBOX_SPACING 6
84 #define SUBJECT_MAX_LENGTH 1000
85 #define IMAGE_MAX_WIDTH 640
87 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
88 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
89 static void modest_msg_edit_window_finalize (GObject *obj);
91 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
92 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
93 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
94 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
95 static void remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
96 static void zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
97 static void paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
98 static void copy_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
99 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
100 static void reset_modified (ModestMsgEditWindow *editor);
102 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
103 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
104 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
105 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
106 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
107 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
108 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
110 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
112 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
114 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
115 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
116 GdkEventWindowState *event,
118 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
119 ModestRecptEditor *editor);
120 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
121 ModestMsgEditWindow *window);
123 /* ModestWindow methods implementation */
124 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
125 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
126 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
127 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
128 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
129 gboolean show_toolbar);
130 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
132 ModestMsgEditWindow *window);
133 static void modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
135 ModestMsgEditWindow *window);
136 static void update_window_title (ModestMsgEditWindow *window);
137 static void update_dimmed (ModestMsgEditWindow *window);
138 static void update_paste_dimming (ModestMsgEditWindow *window);
139 static void update_select_all_dimming (ModestMsgEditWindow *window);
140 static void update_zoom_dimming (ModestMsgEditWindow *window);
143 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
144 ModestMsgEditWindow *window);
145 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
146 ModestMsgEditWindow *window);
147 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
149 GtkTextIter *match_start,
150 GtkTextIter *match_end);
154 /* static gboolean */
155 /* on_key_pressed (GtkWidget *self, */
156 /* GdkEventKey *event, */
157 /* gpointer user_data); */
159 static void edit_menu_activated (GtkAction *action,
161 static void view_menu_activated (GtkAction *action,
164 /* list my signals */
171 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
172 struct _ModestMsgEditWindowPrivate {
174 GtkWidget *header_box;
176 ModestPairList *from_field_protos;
177 GtkWidget *from_field;
181 GtkWidget *bcc_field;
182 GtkWidget *subject_field;
183 GtkWidget *attachments_view;
184 GtkWidget *priority_icon;
185 GtkWidget *add_attachment_button;
187 GtkWidget *cc_caption;
188 GtkWidget *bcc_caption;
189 GtkWidget *attachments_caption;
191 GtkTextBuffer *text_buffer;
193 GtkWidget *font_size_toolitem;
194 GtkWidget *font_face_toolitem;
195 GtkWidget *font_color_button;
196 GSList *font_items_group;
197 GtkWidget *font_tool_button_label;
198 GSList *size_items_group;
199 GtkWidget *size_tool_button_label;
201 GtkWidget *find_toolbar;
205 GtkWidget *scroll_area;
210 TnyHeaderFlags priority_flags;
214 gulong clipboard_change_handler_id;
215 gulong system_clipboard_change_handler_id;
221 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
222 MODEST_TYPE_MSG_EDIT_WINDOW, \
223 ModestMsgEditWindowPrivate))
225 static GtkWindowClass *parent_class = NULL;
227 /* uncomment the following if you have defined any signals */
228 /* static guint signals[LAST_SIGNAL] = {0}; */
231 modest_msg_edit_window_get_type (void)
233 static GType my_type = 0;
235 static const GTypeInfo my_info = {
236 sizeof(ModestMsgEditWindowClass),
237 NULL, /* base init */
238 NULL, /* base finalize */
239 (GClassInitFunc) modest_msg_edit_window_class_init,
240 NULL, /* class finalize */
241 NULL, /* class data */
242 sizeof(ModestMsgEditWindow),
244 (GInstanceInitFunc) modest_msg_edit_window_init,
247 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
248 "ModestMsgEditWindow",
251 wp_text_buffer_library_init ();
257 save_state (ModestWindow *self)
259 modest_widget_memory_save (modest_runtime_get_conf(),
260 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
265 restore_settings (ModestMsgEditWindow *self)
267 modest_widget_memory_restore (modest_runtime_get_conf(),
268 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
273 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
275 GObjectClass *gobject_class;
276 ModestWindowClass *modest_window_class;
277 gobject_class = (GObjectClass*) klass;
278 modest_window_class = (ModestWindowClass*) klass;
280 parent_class = g_type_class_peek_parent (klass);
281 gobject_class->finalize = modest_msg_edit_window_finalize;
283 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
284 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
285 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
286 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
287 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
288 modest_window_class->save_state_func = save_state;
290 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
296 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
298 ModestMsgEditWindowPrivate *priv;
299 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
301 priv->msg_body = NULL;
302 priv->from_field = NULL;
303 priv->to_field = NULL;
304 priv->cc_field = NULL;
305 priv->bcc_field = NULL;
306 priv->subject_field = NULL;
307 priv->attachments = NULL;
309 priv->zoom_level = 1.0;
311 priv->cc_caption = NULL;
312 priv->bcc_caption = NULL;
314 priv->priority_flags = 0;
316 priv->find_toolbar = NULL;
317 priv->last_search = NULL;
319 priv->draft_msg = NULL;
320 priv->clipboard_change_handler_id = 0;
321 priv->system_clipboard_change_handler_id = 0;
326 /* FIXME: this is a dup from the one in gtk/ */
329 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
331 static ModestPairList*
332 get_transports (void)
334 GSList *transports = NULL;
336 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
337 GSList *accounts = modest_account_mgr_account_names (account_mgr,
338 TRUE /* only enabled accounts. */);
340 GSList *cursor = accounts;
342 gchar *account_name = cursor->data;
343 gchar *from_string = NULL;
345 from_string = modest_account_mgr_get_from_string (account_mgr,
349 if (from_string && account_name) {
350 gchar *name = account_name;
351 ModestPair *pair = modest_pair_new ((gpointer) name,
352 (gpointer) from_string , TRUE);
353 transports = g_slist_prepend (transports, pair);
356 cursor = cursor->next;
358 g_slist_free (accounts); /* only free the accounts, not the elements,
359 * because they are used in the pairlist */
365 init_window (ModestMsgEditWindow *obj)
367 GtkWidget *from_caption, *to_caption, *subject_caption;
368 GtkWidget *main_vbox;
369 ModestMsgEditWindowPrivate *priv;
371 GtkSizeGroup *size_group;
373 GtkWidget *subject_box;
374 GtkWidget *attachment_icon;
375 GtkWidget *window_box;
377 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
379 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
381 /* Note: This ModestPairList* must exist for as long as the combo
382 * that uses it, because the ModestComboBox uses the ID opaquely,
383 * so it can't know how to manage its memory. */
384 priv->from_field_protos = get_transports ();
386 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
388 priv->to_field = modest_recpt_editor_new ();
389 priv->cc_field = modest_recpt_editor_new ();
390 priv->bcc_field = modest_recpt_editor_new ();
391 subject_box = gtk_hbox_new (FALSE, 0);
392 priv->priority_icon = gtk_image_new ();
393 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
394 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
395 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
396 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
397 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
398 priv->add_attachment_button = gtk_button_new ();
399 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
400 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
401 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
402 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
403 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
404 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
405 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
406 priv->attachments_view = modest_attachments_view_new (NULL);
408 priv->header_box = gtk_vbox_new (FALSE, 0);
410 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
411 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
412 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
413 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
414 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
415 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
416 g_object_unref (size_group);
418 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
419 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
420 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
421 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
422 gtk_size_group_add_widget (size_group, priv->subject_field);
423 gtk_size_group_add_widget (size_group, priv->attachments_view);
424 g_object_unref (size_group);
426 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
427 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
428 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
429 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
430 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
431 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
432 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
435 priv->msg_body = wp_text_view_new ();
436 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
437 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
438 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
439 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
440 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
441 gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
443 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
445 priv->find_toolbar = hildon_find_toolbar_new (NULL);
446 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
448 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
450 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
451 G_CALLBACK (text_buffer_refresh_attributes), obj);
452 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
453 G_CALLBACK (text_buffer_delete_range), obj);
454 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
455 G_CALLBACK (text_buffer_can_undo), obj);
456 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
457 G_CALLBACK (text_buffer_can_redo), obj);
458 g_signal_connect (G_OBJECT (obj), "window-state-event",
459 G_CALLBACK (modest_msg_edit_window_window_state_event),
461 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
462 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
463 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
464 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
465 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
466 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
468 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
469 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
471 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
472 G_CALLBACK (msg_body_focus), obj);
473 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
474 G_CALLBACK (msg_body_focus), obj);
475 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
476 "changed", G_CALLBACK (recpt_field_changed), obj);
477 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
478 "changed", G_CALLBACK (recpt_field_changed), obj);
479 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
480 "changed", G_CALLBACK (recpt_field_changed), obj);
481 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
482 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
484 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
485 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
487 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
488 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
489 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
491 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
493 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
494 frame = gtk_frame_new (NULL);
495 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
497 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
498 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
499 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
501 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
502 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
503 gtk_widget_hide (priv->cc_caption);
505 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
506 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
507 gtk_widget_hide (priv->bcc_caption);
510 window_box = gtk_vbox_new (FALSE, 0);
511 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
512 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
513 gtk_container_add (GTK_CONTAINER(obj), window_box);
514 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
515 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
518 TODO: scroll_area was never instantiated.
519 Stop building without warnings-as-errors. murrayc.
520 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
521 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
524 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
525 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
526 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
527 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
533 modest_msg_edit_window_finalize (GObject *obj)
535 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
537 if (priv->clipboard_change_handler_id > 0) {
538 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
539 priv->clipboard_change_handler_id = 0;
542 if (priv->system_clipboard_change_handler_id > 0) {
543 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
544 priv->system_clipboard_change_handler_id);
545 priv->system_clipboard_change_handler_id = 0;
548 if (priv->draft_msg != NULL) {
549 g_object_unref (priv->draft_msg);
550 priv->draft_msg = NULL;
553 /* This had to stay alive for as long as the combobox that used it: */
554 modest_pair_list_free (priv->from_field_protos);
556 G_OBJECT_CLASS(parent_class)->finalize (obj);
560 menubar_to_menu (GtkUIManager *ui_manager)
562 GtkWidget *main_menu;
566 /* Create new main menu */
567 main_menu = gtk_menu_new();
569 /* Get the menubar from the UI manager */
570 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
572 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
576 menu = GTK_WIDGET (iter->data);
577 gtk_widget_reparent(menu, main_menu);
579 iter = g_list_next (iter);
586 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
589 const gchar *to, *cc, *bcc, *subject;
591 ModestMsgEditWindowPrivate *priv;
593 TnyHeaderFlags priority_flags;
594 TnyFolder *msg_folder;
596 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
597 g_return_if_fail (TNY_IS_MSG (msg));
599 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
601 header = tny_msg_get_header (msg);
602 to = tny_header_get_to (header);
603 cc = tny_header_get_cc (header);
604 bcc = tny_header_get_bcc (header);
605 subject = tny_header_get_subject (header);
606 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
609 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
611 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
612 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
613 gtk_widget_show (priv->cc_caption);
614 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
615 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
616 gtk_widget_hide (priv->cc_caption);
619 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
620 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
621 gtk_widget_show (priv->bcc_caption);
622 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
623 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
624 gtk_widget_hide (priv->bcc_caption);
627 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
628 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
631 update_window_title (self);
633 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
634 body = modest_tny_msg_get_body (msg, TRUE);
636 if ((body == NULL)||(body[0] == '\0')) {
638 body = modest_text_utils_convert_to_html ("");
640 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
641 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
644 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
647 /* Get the default format required from configuration */
648 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
649 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
652 /* Set the default focus depending on having already a To: field or not */
653 if ((!to)||(*to == '\0')) {
654 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
656 gtk_widget_grab_focus (priv->msg_body);
659 /* TODO: lower priority, select in the From: combo to the
660 value that comes from msg <- not sure, should it be
663 /* Add attachments to the view */
664 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
665 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
666 if (priv->attachments == NULL) {
667 gtk_widget_hide (priv->attachments_caption);
669 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
670 gtk_widget_show_all (priv->attachments_caption);
673 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
674 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
676 reset_modified (self);
678 update_dimmed (self);
679 text_buffer_can_undo (priv->text_buffer, FALSE, self);
680 text_buffer_can_redo (priv->text_buffer, FALSE, self);
682 /* we should set a reference to the incoming message if it is a draft */
683 msg_folder = tny_msg_get_folder (msg);
685 if (modest_tny_folder_is_local_folder (msg_folder) &&
686 modest_tny_folder_get_local_folder_type (msg_folder) == TNY_FOLDER_TYPE_DRAFTS)
687 priv->draft_msg = g_object_ref(msg);
688 g_object_unref (msg_folder);
693 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
696 GList *item_children, *node;
697 GtkWidget *bin_child;
699 bin_child = gtk_bin_get_child (GTK_BIN(item));
701 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
703 for (node = item_children; node != NULL; node = g_list_next (node)) {
704 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
705 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
708 g_list_free (item_children);
712 menu_tool_button_dont_expand (GtkMenuToolButton *item)
715 GList *item_children, *node;
717 box = gtk_bin_get_child (GTK_BIN (item));
718 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
719 item_children = gtk_container_get_children (GTK_CONTAINER (box));
721 for (node = item_children; node != NULL; node = g_list_next (node)) {
722 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
723 if (GTK_IS_TOGGLE_BUTTON (node->data))
724 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
725 else if (GTK_IS_BUTTON (node->data))
726 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
728 g_list_free (item_children);
733 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
735 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
736 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
737 GtkWidget *placeholder;
738 GtkWidget *tool_item;
743 GtkWidget *sizes_menu;
744 GtkWidget *fonts_menu;
745 GSList *radio_group = NULL;
750 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
751 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
753 /* should we hide the toolbar? */
754 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
755 gtk_widget_hide (parent_priv->toolbar);
757 /* Font color placeholder */
758 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
759 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
762 tool_item = GTK_WIDGET (gtk_tool_item_new ());
763 priv->font_color_button = hildon_color_button_new ();
764 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
765 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
766 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
767 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
768 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
769 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
770 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
772 /* Font size and face placeholder */
773 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
774 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
776 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
777 priv->size_tool_button_label = gtk_label_new (NULL);
778 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
779 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
780 size_text,"</span>", NULL);
781 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
783 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
784 sizes_menu = gtk_menu_new ();
785 priv->size_items_group = NULL;
787 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
788 GtkWidget *size_menu_item;
790 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
791 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
792 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
793 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
794 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
795 gtk_widget_show (size_menu_item);
797 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
801 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
802 GtkWidget *item = (GtkWidget *) node->data;
803 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
807 priv->size_items_group = g_slist_reverse (priv->size_items_group);
808 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
809 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
810 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
811 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
812 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
813 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
814 priv->font_size_toolitem = tool_item;
817 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
818 priv->font_tool_button_label = gtk_label_new (NULL);
819 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
820 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
822 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
823 fonts_menu = gtk_menu_new ();
824 priv->font_items_group = NULL;
826 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
827 GtkWidget *font_menu_item;
828 GtkWidget *child_label;
830 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
831 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
832 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
833 wp_get_font_name (font_index), "</span>", NULL);
834 gtk_label_set_markup (GTK_LABEL (child_label), markup);
837 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
838 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
839 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
840 gtk_widget_show (font_menu_item);
842 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
845 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
846 GtkWidget *item = (GtkWidget *) node->data;
847 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
850 priv->font_items_group = g_slist_reverse (priv->font_items_group);
851 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
852 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
853 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
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 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
857 priv->font_face_toolitem = tool_item;
859 /* Set expand and homogeneous for remaining items */
860 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
861 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
862 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
863 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
864 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
865 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
866 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
867 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
868 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
876 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
879 ModestWindowPrivate *parent_priv;
880 ModestMsgEditWindowPrivate *priv;
881 GtkActionGroup *action_group;
882 GError *error = NULL;
883 GdkPixbuf *window_icon = NULL;
886 gboolean prefer_formatted;
888 ModestPair *account_pair = NULL;
890 g_return_val_if_fail (msg, NULL);
891 g_return_val_if_fail (account_name, NULL);
893 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
895 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
896 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
898 parent_priv->ui_manager = gtk_ui_manager_new();
899 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
900 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
902 /* Add common actions */
903 gtk_action_group_add_actions (action_group,
904 modest_msg_edit_action_entries,
905 G_N_ELEMENTS (modest_msg_edit_action_entries),
907 gtk_action_group_add_toggle_actions (action_group,
908 modest_msg_edit_toggle_action_entries,
909 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
911 gtk_action_group_add_radio_actions (action_group,
912 modest_msg_edit_alignment_radio_action_entries,
913 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
915 G_CALLBACK (modest_ui_actions_on_change_justify),
917 gtk_action_group_add_radio_actions (action_group,
918 modest_msg_edit_zoom_action_entries,
919 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
921 G_CALLBACK (modest_ui_actions_on_change_zoom),
923 gtk_action_group_add_radio_actions (action_group,
924 modest_msg_edit_priority_action_entries,
925 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
927 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
929 gtk_action_group_add_radio_actions (action_group,
930 modest_msg_edit_file_format_action_entries,
931 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
932 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
933 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
935 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
936 g_object_unref (action_group);
938 /* Load the UI definition */
939 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
942 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
943 g_clear_error (&error);
946 /* Add accelerators */
947 gtk_window_add_accel_group (GTK_WINDOW (obj),
948 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
951 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
952 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
955 init_window (MODEST_MSG_EDIT_WINDOW(obj));
957 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
959 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
961 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
963 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
965 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
966 if (account_pair != NULL)
967 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
969 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
971 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
973 /* Set window icon */
974 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
975 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
977 /* Dim at start clipboard actions */
978 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
979 gtk_action_set_sensitive (action, FALSE);
980 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
981 gtk_action_set_sensitive (action, FALSE);
982 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
983 gtk_action_set_sensitive (action, FALSE);
985 /* Update select all */
986 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
987 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
988 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
989 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
990 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
992 /* set initial state of cc and bcc */
993 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
994 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
995 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
996 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
997 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
998 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
1000 /* Setup the file format */
1001 conf = modest_runtime_get_conf ();
1002 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
1004 g_clear_error (&error);
1005 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
1007 file_format = (prefer_formatted) ?
1008 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1009 MODEST_FILE_FORMAT_PLAIN_TEXT;
1010 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1012 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1014 return (ModestWindow*) obj;
1018 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1020 GString **string_buffer = (GString **) user_data;
1022 *string_buffer = g_string_append (*string_buffer, buffer);
1028 * @result: A new string which should be freed with g_free().
1031 get_formatted_data (ModestMsgEditWindow *edit_window)
1033 ModestMsgEditWindowPrivate *priv;
1034 GString *string_buffer = g_string_new ("");
1036 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1038 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1040 return g_string_free (string_buffer, FALSE);
1045 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1048 const gchar *account_name;
1049 ModestMsgEditWindowPrivate *priv;
1051 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1053 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1055 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1056 g_return_val_if_fail (account_name, NULL);
1059 /* don't free these (except from) */
1060 data = g_slice_new0 (MsgData);
1061 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1063 data->account_name = g_strdup (account_name);
1064 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1065 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1066 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1067 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1068 if (priv->draft_msg) {
1069 data->draft_msg = g_object_ref (priv->draft_msg);
1071 data->draft_msg = NULL;
1074 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1076 gtk_text_buffer_get_bounds (buf, &b, &e);
1077 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1079 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1080 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1082 data->html_body = NULL;
1084 /* deep-copy the data */
1085 GList *cursor = priv->attachments;
1086 data->attachments = NULL;
1088 if (!(TNY_IS_MIME_PART(cursor->data))) {
1089 g_warning ("strange data in attachment list");
1092 data->attachments = g_list_append (data->attachments,
1093 g_object_ref (cursor->data));
1094 cursor = g_list_next (cursor);
1097 data->priority_flags = priv->priority_flags;
1104 unref_gobject (GObject *obj, gpointer data)
1106 if (!G_IS_OBJECT(obj))
1108 g_object_unref (obj);
1112 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1115 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1123 g_free (data->subject);
1124 g_free (data->plain_body);
1125 g_free (data->html_body);
1126 g_free (data->account_name);
1128 if (data->draft_msg != NULL) {
1129 g_object_unref (data->draft_msg);
1130 data->draft_msg = NULL;
1133 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1134 g_list_free (data->attachments);
1136 g_slice_free (MsgData, data);
1140 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1143 ModestMsgEditWindowPrivate *priv = NULL;
1144 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1146 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1148 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1150 return MODEST_MSG_EDIT_FORMAT_HTML;
1152 return MODEST_MSG_EDIT_FORMAT_TEXT;
1156 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1157 ModestMsgEditFormat format)
1159 ModestMsgEditWindowPrivate *priv;
1161 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1162 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1165 case MODEST_MSG_EDIT_FORMAT_HTML:
1166 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1168 case MODEST_MSG_EDIT_FORMAT_TEXT:
1169 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1172 g_return_if_reached ();
1176 ModestMsgEditFormatState *
1177 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1179 ModestMsgEditFormatState *format_state = NULL;
1180 ModestMsgEditWindowPrivate *priv;
1181 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1183 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1184 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1186 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1188 format_state = g_new0 (ModestMsgEditFormatState, 1);
1189 format_state->bold = buffer_format->bold&0x1;
1190 format_state->italics = buffer_format->italic&0x1;
1191 format_state->bullet = buffer_format->bullet&0x1;
1192 format_state->color = buffer_format->color;
1193 format_state->font_size = buffer_format->font_size;
1194 format_state->font_family = wp_get_font_name (buffer_format->font);
1195 format_state->justification = buffer_format->justification;
1196 g_free (buffer_format);
1198 return format_state;
1203 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1204 const ModestMsgEditFormatState *format_state)
1206 ModestMsgEditWindowPrivate *priv;
1207 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1208 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1209 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1210 g_return_if_fail (format_state != NULL);
1212 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1213 gtk_widget_grab_focus (priv->msg_body);
1214 buffer_format->bold = (format_state->bold != FALSE);
1215 buffer_format->italic = (format_state->italics != FALSE);
1216 buffer_format->color = format_state->color;
1217 buffer_format->font_size = format_state->font_size;
1218 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1219 buffer_format->justification = format_state->justification;
1220 buffer_format->bullet = format_state->bullet;
1222 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1224 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1225 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1226 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1227 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1228 buffer_format->cs.font = (buffer_format->font != current_format->font);
1229 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1230 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1232 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1233 if (buffer_format->cs.bold) {
1234 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1236 if (buffer_format->cs.italic) {
1237 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1239 if (buffer_format->cs.color) {
1240 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1242 if (buffer_format->cs.font_size) {
1243 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1245 if (buffer_format->cs.justification) {
1246 switch (buffer_format->justification) {
1247 case GTK_JUSTIFY_LEFT:
1248 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1250 case GTK_JUSTIFY_CENTER:
1251 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1253 case GTK_JUSTIFY_RIGHT:
1254 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1261 if (buffer_format->cs.font) {
1262 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1264 if (buffer_format->cs.bullet) {
1265 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1267 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1268 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1270 g_free (current_format);
1275 toggle_action_set_active_block_notify (GtkToggleAction *action,
1278 GSList *proxies = NULL;
1280 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1281 proxies != NULL; proxies = g_slist_next (proxies)) {
1282 GtkWidget *widget = (GtkWidget *) proxies->data;
1283 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1286 gtk_toggle_action_set_active (action, value);
1288 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1289 proxies != NULL; proxies = g_slist_next (proxies)) {
1290 GtkWidget *widget = (GtkWidget *) proxies->data;
1291 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1296 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1298 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1300 ModestWindowPrivate *parent_priv;
1301 ModestMsgEditWindowPrivate *priv;
1302 GtkWidget *new_size_menuitem;
1303 GtkWidget *new_font_menuitem;
1305 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1306 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1308 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1309 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1310 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1311 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1313 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1314 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1315 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1318 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1320 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1321 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1323 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1324 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1326 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1327 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1329 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1330 G_CALLBACK (modest_msg_edit_window_color_button_change),
1332 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1333 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1334 G_CALLBACK (modest_msg_edit_window_color_button_change),
1337 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1338 buffer_format->font_size))->data);
1339 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1343 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1344 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1345 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1347 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1348 G_CALLBACK (modest_msg_edit_window_size_change),
1350 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1351 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1352 G_CALLBACK (modest_msg_edit_window_size_change),
1356 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1357 buffer_format->font))->data);
1358 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1362 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1363 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1364 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1366 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1367 G_CALLBACK (modest_msg_edit_window_font_change),
1369 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1370 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1371 G_CALLBACK (modest_msg_edit_window_font_change),
1375 g_free (buffer_format);
1381 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1384 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1385 ModestMsgEditWindowPrivate *priv;
1386 GtkWidget *dialog = NULL;
1388 const GdkColor *new_color = NULL;
1390 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1391 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1393 #ifdef MODEST_HILDON_VERSION_0
1394 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1395 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1397 dialog = hildon_color_chooser_new ();
1398 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1399 #endif /*MODEST_HILDON_VERSION_0*/
1400 g_free (buffer_format);
1402 response = gtk_dialog_run (GTK_DIALOG (dialog));
1404 case GTK_RESPONSE_OK: {
1405 #ifdef MODEST_HILDON_VERSION_0
1406 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1409 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1411 #endif /*MODEST_HILDON_VERSION_0*/
1418 gtk_widget_destroy (dialog);
1420 if (new_color != NULL)
1421 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1426 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1429 ModestMsgEditWindowPrivate *priv;
1430 GtkWidget *dialog = NULL;
1432 GdkColor *old_color = NULL;
1433 const GdkColor *new_color = NULL;
1435 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1436 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1438 #ifdef MODEST_HILDON_VERSION_0
1439 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1440 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1442 dialog = hildon_color_chooser_new ();
1443 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1444 #endif /*MODEST_HILDON_VERSION_9*/
1446 response = gtk_dialog_run (GTK_DIALOG (dialog));
1448 case GTK_RESPONSE_OK: {
1449 #ifdef MODEST_HILDON_VERSION_0
1450 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1453 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1455 #endif /*MODEST_HILDON_VERSION_0*/
1461 gtk_widget_destroy (dialog);
1463 if (new_color != NULL)
1464 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1470 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1473 ModestMsgEditWindowPrivate *priv;
1474 GtkWidget *dialog = NULL;
1476 GSList *uris = NULL;
1477 GSList *uri_node = NULL;
1479 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1481 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1482 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1483 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1485 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1487 response = gtk_dialog_run (GTK_DIALOG (dialog));
1489 case GTK_RESPONSE_OK:
1490 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1495 gtk_widget_destroy (dialog);
1497 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1499 GnomeVFSHandle *handle = NULL;
1500 GnomeVFSResult result;
1501 GtkTextIter position;
1502 GtkTextMark *insert_mark;
1504 uri = (const gchar *) uri_node->data;
1505 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1506 if (result == GNOME_VFS_OK) {
1507 GdkPixbufLoader *loader;
1509 GnomeVFSFileInfo info;
1510 gchar *filename, *basename;
1511 TnyMimePart *mime_part;
1514 const gchar *mime_type = NULL;
1516 filename = g_filename_from_uri (uri, NULL, NULL);
1517 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1519 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1521 mime_part = tny_platform_factory_new_mime_part
1522 (modest_runtime_get_platform_factory ());
1523 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1525 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1527 content_id = g_strdup_printf ("%d", priv->last_cid);
1528 tny_mime_part_set_content_id (mime_part, content_id);
1529 g_free (content_id);
1532 basename = g_path_get_basename (filename);
1533 tny_mime_part_set_filename (mime_part, basename);
1536 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1537 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1539 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1540 gtk_widget_show_all (priv->attachments_caption);
1541 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1544 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1545 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1546 unsigned char read_buffer[128];
1548 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1549 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1552 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1553 g_object_ref (pixbuf);
1554 gdk_pixbuf_loader_close (loader, NULL);
1555 g_object_unref (loader);
1557 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1558 GdkPixbuf *new_pixbuf;
1560 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1561 gdk_pixbuf_get_width (pixbuf);
1562 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1563 g_object_unref (pixbuf);
1564 pixbuf = new_pixbuf;
1567 if (pixbuf != NULL) {
1568 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1569 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1570 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1579 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1582 ModestMsgEditWindowPrivate *priv;
1583 GtkWidget *dialog = NULL;
1585 GSList *uris = NULL;
1588 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1590 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1591 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1593 response = gtk_dialog_run (GTK_DIALOG (dialog));
1595 case GTK_RESPONSE_OK:
1596 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1601 gtk_widget_destroy (dialog);
1603 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1605 GnomeVFSHandle *handle = NULL;
1606 GnomeVFSResult result;
1608 uri = (const gchar *) uri_node->data;
1609 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1610 if (result == GNOME_VFS_OK) {
1611 TnyMimePart *mime_part;
1613 const gchar *mime_type = NULL;
1617 GnomeVFSFileInfo info;
1619 filename = g_filename_from_uri (uri, NULL, NULL);
1621 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1622 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1623 mime_part = tny_platform_factory_new_mime_part
1624 (modest_runtime_get_platform_factory ());
1625 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1627 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1629 content_id = g_strdup_printf ("%d", priv->last_cid);
1630 tny_mime_part_set_content_id (mime_part, content_id);
1631 g_free (content_id);
1634 basename = g_path_get_basename (filename);
1635 tny_mime_part_set_filename (mime_part, basename);
1638 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1639 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1641 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1642 gtk_widget_show_all (priv->attachments_caption);
1643 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1648 g_slist_foreach (uris, (GFunc) g_free, NULL);
1649 g_slist_free (uris);
1653 modest_msg_edit_window_attach_file_noninteractive (
1654 ModestMsgEditWindow *window,
1655 const gchar *file_uri)
1658 ModestMsgEditWindowPrivate *priv;
1660 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1662 if (file_uri && strlen(file_uri)) {
1665 /* TODO: We should probably try to use only the URI,
1666 * instead of using a filename.
1668 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1670 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1673 file_id = g_open (filename, O_RDONLY, 0);
1674 if (file_id != -1) {
1675 TnyMimePart *mime_part;
1677 const gchar *mime_type;
1680 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1681 mime_type = gnome_vfs_get_mime_type(filename);
1683 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1685 mime_part = tny_platform_factory_new_mime_part
1686 (modest_runtime_get_platform_factory ());
1687 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1689 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1691 content_id = g_strdup_printf ("%d", priv->last_cid);
1692 tny_mime_part_set_content_id (mime_part, content_id);
1693 g_free (content_id);
1696 basename = g_path_get_basename (filename);
1697 tny_mime_part_set_filename (mime_part, basename);
1700 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1701 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1703 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1704 gtk_widget_show_all (priv->attachments_caption);
1705 } else if (file_id == -1) {
1707 g_warning("file to be attached does not exist: %s", filename);
1715 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1718 ModestMsgEditWindowPrivate *priv;
1719 gboolean clean_list = FALSE;
1721 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1722 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1724 if (att_list == NULL) {
1725 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1729 if (att_list == NULL) {
1730 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1732 GtkWidget *confirmation_dialog = NULL;
1733 gboolean dialog_response;
1735 gchar *message = NULL;
1736 const gchar *filename = NULL;
1738 if (att_list->next == NULL) {
1739 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1743 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1744 att_list->next == NULL), filename);
1745 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1747 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1748 gtk_widget_destroy (confirmation_dialog);
1749 if (!dialog_response) {
1751 g_list_free (att_list);
1754 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1756 for (node = att_list; node != NULL; node = g_list_next (node)) {
1757 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1758 const gchar *att_id;
1759 priv->attachments = g_list_remove (priv->attachments, mime_part);
1761 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1763 if (priv->attachments == NULL)
1764 gtk_widget_hide (priv->attachments_caption);
1765 att_id = tny_mime_part_get_content_id (mime_part);
1767 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1769 g_object_unref (mime_part);
1770 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1775 g_list_free (att_list);
1779 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1782 ModestMsgEditWindowPrivate *priv;
1783 GdkColor *new_color;
1784 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1786 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1787 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1790 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1792 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1794 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1796 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1801 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1804 ModestMsgEditWindowPrivate *priv;
1805 gint new_size_index;
1806 ModestMsgEditWindow *window;
1809 window = MODEST_MSG_EDIT_WINDOW (userdata);
1810 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1811 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1813 if (gtk_check_menu_item_get_active (menu_item)) {
1815 WPTextBufferFormat format;
1817 memset (&format, 0, sizeof (format));
1818 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1820 label = gtk_bin_get_child (GTK_BIN (menu_item));
1822 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1823 format.cs.font_size = TRUE;
1824 format.cs.text_position = TRUE;
1825 format.cs.font = TRUE;
1826 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1827 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1829 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1830 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1831 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1833 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1834 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1835 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1841 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1844 ModestMsgEditWindowPrivate *priv;
1845 gint new_font_index;
1846 ModestMsgEditWindow *window;
1849 window = MODEST_MSG_EDIT_WINDOW (userdata);
1850 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1851 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1853 if (gtk_check_menu_item_get_active (menu_item)) {
1856 label = gtk_bin_get_child (GTK_BIN (menu_item));
1858 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1860 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1861 (gpointer) new_font_index))
1862 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1864 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1865 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1866 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1872 modest_msg_edit_window_set_zoom (ModestWindow *window,
1875 ModestMsgEditWindowPrivate *priv;
1876 ModestWindowPrivate *parent_priv;
1877 GtkRadioAction *zoom_radio_action;
1879 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1881 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1882 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1883 priv->zoom_level = zoom;
1884 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1886 /* Zoom level menu options should be updated with the current zoom level */
1887 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1888 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1889 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1890 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1891 /* FIXME: Not availible before Gtk 2.10 */
1893 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1898 modest_msg_edit_window_get_zoom (ModestWindow *window)
1900 ModestMsgEditWindowPrivate *priv;
1902 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1904 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1905 return priv->zoom_level;
1909 zoom_allowed (ModestMsgEditWindow *window)
1913 focus = gtk_window_get_focus (GTK_WINDOW (window));
1914 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1918 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1920 ModestWindowPrivate *parent_priv;
1921 GtkRadioAction *zoom_radio_action;
1922 GSList *group, *node;
1924 /* First we check if the text view is focused. If not, zooming is not allowed */
1925 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1926 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1930 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1931 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1932 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1934 group = gtk_radio_action_get_group (zoom_radio_action);
1936 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1937 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1941 for (node = group; node != NULL; node = g_slist_next (node)) {
1942 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1943 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1951 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1953 ModestWindowPrivate *parent_priv;
1954 GtkRadioAction *zoom_radio_action;
1955 GSList *group, *node;
1957 /* First we check if the text view is focused. If not, zooming is not allowed */
1958 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1959 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1963 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1964 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1965 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1967 group = gtk_radio_action_get_group (zoom_radio_action);
1969 for (node = group; node != NULL; node = g_slist_next (node)) {
1970 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1971 if (node->next != NULL) {
1972 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1975 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1983 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1985 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1986 ModestWindowPrivate *parent_priv;
1987 ModestWindowMgr *mgr;
1988 gboolean is_fullscreen;
1989 GtkAction *fs_toggle_action;
1992 mgr = modest_runtime_get_window_mgr ();
1993 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1995 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1997 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1998 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1999 if (is_fullscreen != active)
2000 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2008 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2010 ModestWindowPrivate *parent_priv;
2011 GtkAction *fs_toggle_action;
2014 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2016 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2017 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2018 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2022 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2025 ModestMsgEditWindowPrivate *priv = NULL;
2026 const gchar *recipients;
2027 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2029 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2030 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2031 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2032 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2033 gtk_widget_show (priv->cc_caption);
2035 gtk_widget_hide (priv->cc_caption);
2036 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2040 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2043 ModestMsgEditWindowPrivate *priv = NULL;
2044 const gchar *recipients;
2045 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2047 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2048 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2049 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2050 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2051 gtk_widget_show (priv->bcc_caption);
2053 gtk_widget_hide (priv->bcc_caption);
2054 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2058 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2059 ModestRecptEditor *editor)
2061 ModestMsgEditWindowPrivate *priv;
2063 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2064 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2065 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2067 if (editor == NULL) {
2068 GtkWidget *view_focus;
2069 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2071 /* This code should be kept in sync with ModestRecptEditor. The
2072 textview inside the recpt editor is the one that really gets the
2073 focus. As it's inside a scrolled window, and this one inside the
2074 hbox recpt editor inherits from, we'll need to go up in the
2075 hierarchy to know if the text view is part of the recpt editor
2076 or if it's a different text entry */
2078 if (gtk_widget_get_parent (view_focus)) {
2079 GtkWidget *first_parent;
2081 first_parent = gtk_widget_get_parent (view_focus);
2082 if (gtk_widget_get_parent (first_parent) &&
2083 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2084 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2089 editor = MODEST_RECPT_EDITOR (priv->to_field);
2093 modest_address_book_select_addresses (editor);
2098 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2100 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2102 modest_msg_edit_window_open_addressbook (window, NULL);
2106 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2107 gboolean show_toolbar)
2109 ModestWindowPrivate *parent_priv;
2111 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2112 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2114 /* FIXME: we can not just use the code of
2115 modest_msg_edit_window_setup_toolbar because it has a
2116 mixture of both initialization and creation code. */
2119 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2121 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2125 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2126 TnyHeaderFlags priority_flags)
2128 ModestMsgEditWindowPrivate *priv;
2129 ModestWindowPrivate *parent_priv;
2131 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2133 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2134 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2135 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2137 if (priv->priority_flags != priority_flags) {
2138 GtkAction *priority_action = NULL;
2140 priv->priority_flags = priority_flags;
2142 switch (priority_flags) {
2143 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2144 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2145 gtk_widget_show (priv->priority_icon);
2146 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2147 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2149 case TNY_HEADER_FLAG_LOW_PRIORITY:
2150 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2151 gtk_widget_show (priv->priority_icon);
2152 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2153 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2156 gtk_widget_hide (priv->priority_icon);
2157 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2158 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2161 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2162 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2167 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2170 ModestMsgEditWindowPrivate *priv;
2171 ModestWindowPrivate *parent_priv;
2172 gint current_format;
2174 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2176 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2177 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2179 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2180 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2182 if (current_format != file_format) {
2183 switch (file_format) {
2184 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2185 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2187 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2191 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2192 response = gtk_dialog_run (GTK_DIALOG (dialog));
2193 gtk_widget_destroy (dialog);
2194 if (response == GTK_RESPONSE_OK) {
2195 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2197 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2198 toggle_action_set_active_block_notify (action, TRUE);
2203 update_dimmed (window);
2208 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2211 ModestMsgEditWindowPrivate *priv;
2212 WPTextBufferFormat oldfmt, fmt;
2213 gint old_position = 0;
2217 GdkColor *color = NULL;
2218 gboolean bold, bold_set, italic, italic_set;
2219 gboolean underline, underline_set;
2220 gboolean strikethrough, strikethrough_set;
2221 gboolean position_set;
2222 gboolean font_size_set, font_set, color_set;
2225 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2226 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2228 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2230 /* First we get the currently selected font information */
2231 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2232 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2234 switch (oldfmt.text_position) {
2235 case TEXT_POSITION_NORMAL:
2238 case TEXT_POSITION_SUPERSCRIPT:
2246 g_object_set (G_OBJECT (dialog),
2247 "bold", oldfmt.bold != FALSE,
2248 "bold-set", !oldfmt.cs.bold,
2249 "underline", oldfmt.underline != FALSE,
2250 "underline-set", !oldfmt.cs.underline,
2251 "italic", oldfmt.italic != FALSE,
2252 "italic-set", !oldfmt.cs.italic,
2253 "strikethrough", oldfmt.strikethrough != FALSE,
2254 "strikethrough-set", !oldfmt.cs.strikethrough,
2255 "color", &oldfmt.color,
2256 "color-set", !oldfmt.cs.color,
2257 "size", wp_font_size[oldfmt.font_size],
2258 "size-set", !oldfmt.cs.font_size,
2259 "position", old_position,
2260 "position-set", !oldfmt.cs.text_position,
2261 "family", wp_get_font_name (oldfmt.font),
2262 "family-set", !oldfmt.cs.font,
2265 gtk_widget_show_all (dialog);
2266 response = gtk_dialog_run (GTK_DIALOG (dialog));
2267 if (response == GTK_RESPONSE_OK) {
2269 g_object_get( dialog,
2271 "bold-set", &bold_set,
2272 "underline", &underline,
2273 "underline-set", &underline_set,
2275 "italic-set", &italic_set,
2276 "strikethrough", &strikethrough,
2277 "strikethrough-set", &strikethrough_set,
2279 "color-set", &color_set,
2281 "size-set", &font_size_set,
2282 "family", &font_name,
2283 "family-set", &font_set,
2284 "position", &position,
2285 "position-set", &position_set,
2290 if (response == GTK_RESPONSE_OK) {
2291 memset(&fmt, 0, sizeof(fmt));
2297 fmt.italic = italic;
2298 fmt.cs.italic = TRUE;
2300 if (underline_set) {
2301 fmt.underline = underline;
2302 fmt.cs.underline = TRUE;
2304 if (strikethrough_set) {
2305 fmt.strikethrough = strikethrough;
2306 fmt.cs.strikethrough = TRUE;
2311 ? TEXT_POSITION_NORMAL
2312 : ( ( position == 1 )
2313 ? TEXT_POSITION_SUPERSCRIPT
2314 : TEXT_POSITION_SUBSCRIPT );
2315 fmt.cs.text_position = TRUE;
2319 fmt.cs.color = TRUE;
2322 fmt.font = wp_get_font_index(font_name,
2327 if (font_size_set) {
2328 fmt.font_size = wp_get_font_size_index(
2329 font_size, DEFAULT_FONT_SIZE);
2330 fmt.cs.font_size = TRUE;
2332 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2334 gtk_widget_destroy (dialog);
2336 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2340 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2342 ModestMsgEditWindowPrivate *priv;
2344 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2345 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2347 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2349 update_dimmed (window);
2354 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2356 ModestMsgEditWindowPrivate *priv;
2358 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2359 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2361 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2363 update_dimmed (window);
2368 update_dimmed (ModestMsgEditWindow *window)
2370 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2371 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2375 gboolean editor_focused;
2377 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2378 editor_focused = gtk_widget_is_focus (priv->msg_body);
2380 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2381 gtk_action_set_sensitive (action, rich_text && editor_focused);
2382 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2383 gtk_action_set_sensitive (action, rich_text && editor_focused);
2384 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2385 gtk_action_set_sensitive (action, rich_text && editor_focused);
2386 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2387 gtk_action_set_sensitive (action, rich_text && editor_focused);
2388 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2389 gtk_action_set_sensitive (action, rich_text && editor_focused);
2390 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2391 gtk_action_set_sensitive (action, rich_text && editor_focused);
2392 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2393 gtk_action_set_sensitive (action, rich_text && editor_focused);
2394 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2395 gtk_action_set_sensitive (action, rich_text && editor_focused);
2396 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2397 gtk_action_set_sensitive (action, rich_text && editor_focused);
2398 widget = priv->font_color_button;
2399 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2400 widget = priv->font_size_toolitem;
2401 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2402 widget = priv->font_face_toolitem;
2403 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2407 setup_insensitive_handlers (ModestMsgEditWindow *window)
2409 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2410 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2413 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2414 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2415 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2416 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2418 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2419 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2420 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2421 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2422 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2423 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2424 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2425 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2426 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2427 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2428 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2429 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2430 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2431 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2432 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2433 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2434 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2435 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2436 widget = priv->font_color_button;
2437 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2438 widget = priv->font_size_toolitem;
2439 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2440 widget = priv->font_face_toolitem;
2441 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2443 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2444 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2445 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2446 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2448 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2449 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (paste_insensitive_press), window);
2450 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2451 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (copy_insensitive_press), window);
2455 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2457 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2460 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2461 gtk_action_set_sensitive (action, can_undo);
2465 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2467 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2470 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2471 gtk_action_set_sensitive (action, can_redo);
2475 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2478 GtkTextIter match_start, match_end;
2480 if (image_id == NULL)
2483 gtk_text_buffer_get_start_iter (buffer, &iter);
2485 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2486 GSList *tags = gtk_text_iter_get_tags (&match_start);
2488 for (node = tags; node != NULL; node = g_slist_next (node)) {
2489 GtkTextTag *tag = (GtkTextTag *) node->data;
2490 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2491 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2492 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2494 offset = gtk_text_iter_get_offset (&match_start);
2495 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2496 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2500 gtk_text_iter_forward_char (&iter);
2505 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2507 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2508 GtkTextIter real_start, real_end;
2509 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2511 if (gtk_text_iter_compare (start, end) > 0) {
2515 real_start = *start;
2519 GSList *tags = gtk_text_iter_get_tags (&real_start);
2521 for (node = tags; node != NULL; node = g_slist_next (node)) {
2522 GtkTextTag *tag = (GtkTextTag *) node->data;
2523 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2524 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2526 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2528 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2531 } while (gtk_text_iter_forward_char (&real_start)&&
2532 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2536 msg_body_focus (GtkWidget *focus,
2537 GdkEventFocus *event,
2541 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2546 recpt_field_changed (GtkTextBuffer *buffer,
2547 ModestMsgEditWindow *editor)
2549 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2550 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2551 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2552 gboolean dim = FALSE;
2555 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2556 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2557 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2559 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2560 gtk_text_buffer_get_char_count (cc_buffer) +
2561 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2563 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2564 gtk_action_set_sensitive (action, !dim);
2565 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2566 gtk_action_set_sensitive (action, !dim);
2570 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2572 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2576 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2578 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2582 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2584 ModestWindowPrivate *parent_priv;
2585 ModestMsgEditWindowPrivate *priv;
2586 GList *selected_attachments = NULL;
2587 gint n_att_selected = 0;
2589 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2590 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2592 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2593 n_att_selected = g_list_length (selected_attachments);
2594 g_list_free (selected_attachments);
2596 if (n_att_selected > 1)
2597 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2598 else if (n_att_selected == 0)
2599 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2601 hildon_banner_show_information (NULL, NULL, _("mail_ib_unable_to_purge_attachments"));
2605 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2607 gboolean rich_text, editor_focused;
2609 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2610 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2611 editor_focused = gtk_widget_is_focus (priv->msg_body);
2614 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2615 else if (!editor_focused)
2616 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2620 reset_modified (ModestMsgEditWindow *editor)
2622 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2623 GtkTextBuffer *buffer;
2625 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2626 gtk_text_buffer_set_modified (buffer, FALSE);
2627 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2628 gtk_text_buffer_set_modified (buffer, FALSE);
2629 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2630 gtk_text_buffer_set_modified (buffer, FALSE);
2631 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2635 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2637 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2638 GtkTextBuffer *buffer;
2640 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2641 if (gtk_text_buffer_get_modified (buffer))
2643 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2644 if (gtk_text_buffer_get_modified (buffer))
2646 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2647 if (gtk_text_buffer_get_modified (buffer))
2649 if (gtk_text_buffer_get_modified (priv->text_buffer))
2656 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2658 ModestMsgEditWindowPrivate *priv = NULL;
2660 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2661 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2663 /* check if there's no recipient added */
2664 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2665 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2666 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2667 /* no recipient contents, then select contacts */
2668 modest_msg_edit_window_open_addressbook (window, NULL);
2672 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2674 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2676 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2679 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2686 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2687 ModestMsgEditWindow *window)
2689 modest_msg_edit_window_attach_file (window);
2693 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2695 ModestMsgEditWindow *window)
2697 ModestWindowPrivate *parent_priv;
2698 ModestMsgEditWindowPrivate *priv;
2700 gboolean has_selection;
2702 GList *selected_attachments = NULL;
2703 gint n_att_selected = 0;
2705 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2706 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2707 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2708 focused = gtk_window_get_focus (GTK_WINDOW (window));
2710 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2711 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2712 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2713 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2715 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2716 n_att_selected = g_list_length (selected_attachments);
2717 g_list_free (selected_attachments);
2719 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2720 gtk_action_set_sensitive (action, n_att_selected == 1);
2722 update_paste_dimming (window);
2726 update_window_title (ModestMsgEditWindow *window)
2728 ModestMsgEditWindowPrivate *priv = NULL;
2729 const gchar *subject;
2731 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2732 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2733 if (subject == NULL || subject[0] == '\0')
2734 subject = _("mail_va_new_email");
2736 gtk_window_set_title (GTK_WINDOW (window), subject);
2741 subject_field_changed (GtkEditable *editable,
2742 ModestMsgEditWindow *window)
2744 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2745 update_window_title (window);
2746 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2750 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2753 ModestMsgEditWindowPrivate *priv = NULL;
2755 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2756 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2758 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2760 gtk_widget_show_all (priv->find_toolbar);
2761 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2763 gtk_widget_hide_all (priv->find_toolbar);
2764 gtk_widget_grab_focus (priv->msg_body);
2770 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2772 GtkTextIter *match_start,
2773 GtkTextIter *match_end)
2775 GtkTextIter end_iter;
2776 gchar *str_casefold;
2779 gchar *range_casefold;
2782 gboolean result = FALSE;
2789 gtk_text_iter_forward_to_end (&end_iter);
2791 str_casefold = g_utf8_casefold (str, -1);
2792 str_chars_n = strlen (str);
2794 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2795 range_casefold = g_utf8_casefold (range_text, -1);
2796 range_chars_n = strlen (range_casefold);
2798 if (range_chars_n < str_chars_n) {
2799 g_free (str_casefold);
2800 g_free (range_text);
2801 g_free (range_casefold);
2805 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2806 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2807 if (!g_utf8_collate (range_subtext, str_casefold)) {
2808 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2810 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2811 match_start, match_end, NULL);
2812 g_free (found_text);
2814 g_free (range_subtext);
2818 g_free (str_casefold);
2819 g_free (range_text);
2820 g_free (range_casefold);
2827 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2828 ModestMsgEditWindow *window)
2830 gchar *current_search = NULL;
2831 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2833 GtkTextIter selection_start, selection_end;
2834 GtkTextIter match_start, match_end;
2835 gboolean continue_search = FALSE;
2837 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2838 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2839 g_free (current_search);
2840 g_free (priv->last_search);
2841 priv->last_search = NULL;
2842 /* Information banner about empty search */
2843 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2847 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2848 continue_search = TRUE;
2850 g_free (priv->last_search);
2851 priv->last_search = g_strdup (current_search);
2854 if (continue_search) {
2855 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2856 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2857 &match_start, &match_end);
2859 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2861 GtkTextIter buffer_start;
2862 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2863 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2864 &match_start, &match_end);
2866 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2869 /* Mark as selected the string found in search */
2871 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2872 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2874 g_free (priv->last_search);
2875 priv->last_search = NULL;
2877 g_free (current_search);
2881 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2882 ModestMsgEditWindow *window)
2884 GtkToggleAction *toggle;
2885 ModestWindowPrivate *parent_priv;
2886 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2888 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2889 gtk_toggle_action_set_active (toggle, FALSE);
2894 update_paste_dimming (ModestMsgEditWindow *window)
2896 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2897 GtkAction *action = NULL;
2898 GtkClipboard *clipboard = NULL;
2902 focused = gtk_window_get_focus (GTK_WINDOW (window));
2904 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2905 active = gtk_clipboard_wait_is_text_available (clipboard);
2908 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2912 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2913 gtk_action_set_sensitive (action, active);
2918 paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2920 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (editor));
2922 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2923 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
2925 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
2930 copy_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2932 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_copy"));
2938 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2940 ModestMsgEditWindow *window)
2942 update_paste_dimming (window);
2946 update_select_all_dimming (ModestMsgEditWindow *window)
2949 gboolean dimmed = FALSE;
2951 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2953 focused = gtk_window_get_focus (GTK_WINDOW (window));
2954 if (GTK_IS_ENTRY (focused)) {
2955 const gchar *current_text;
2956 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2957 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2958 } else if (GTK_IS_TEXT_VIEW (focused)) {
2959 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2960 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2961 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2964 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2965 gtk_action_set_sensitive (action, !dimmed);
2969 update_zoom_dimming (ModestMsgEditWindow *window)
2972 gboolean dimmed = FALSE;
2974 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2976 focused = gtk_window_get_focus (GTK_WINDOW (window));
2977 dimmed = ! WP_IS_TEXT_VIEW (focused);
2978 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2979 gtk_action_set_sensitive (action, !dimmed);
2983 edit_menu_activated (GtkAction *action,
2986 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2988 update_select_all_dimming (window);
2991 view_menu_activated (GtkAction *action,
2994 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2996 update_zoom_dimming (window);
3000 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3002 ModestMsgEditWindowPrivate *priv;
3004 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3009 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3012 ModestMsgEditWindowPrivate *priv;
3014 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);