1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-address-book.h"
59 #include "modest-text-utils.h"
60 #include <tny-simple-list.h>
61 #include <wptextview.h>
62 #include <wptextbuffer.h>
63 #include "modest-scroll-area.h"
65 #include "modest-hildon-includes.h"
66 #ifdef MODEST_HAVE_HILDON0_WIDGETS
67 #include <hildon-widgets/hildon-color-chooser.h>
69 #include "widgets/modest-msg-edit-window-ui.h"
70 #ifdef MODEST_HAVE_HILDON0_WIDGETS
71 #include <libgnomevfs/gnome-vfs-mime-utils.h>
73 #include <libgnomevfs/gnome-vfs-mime.h>
75 #include "modest-maemo-utils.h"
78 #define DEFAULT_FONT_SIZE 3
79 #define DEFAULT_FONT 2
80 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
81 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
82 #define DEFAULT_MAIN_VBOX_SPACING 6
83 #define SUBJECT_MAX_LENGTH 1000
84 #define IMAGE_MAX_WIDTH 640
86 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
87 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
88 static void modest_msg_edit_window_finalize (GObject *obj);
90 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
91 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
92 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
93 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
94 static void remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
95 static void zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
96 static void paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
97 static void copy_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
98 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
99 static void reset_modified (ModestMsgEditWindow *editor);
101 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
102 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
103 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
104 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
105 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
106 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
107 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
109 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
111 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
113 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
114 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
115 GdkEventWindowState *event,
117 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
118 ModestRecptEditor *editor);
119 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
120 ModestMsgEditWindow *window);
122 /* ModestWindow methods implementation */
123 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
124 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
125 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
126 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
127 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
128 gboolean show_toolbar);
129 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
131 ModestMsgEditWindow *window);
132 static void modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
134 ModestMsgEditWindow *window);
135 static void update_window_title (ModestMsgEditWindow *window);
136 static void update_dimmed (ModestMsgEditWindow *window);
137 static void update_paste_dimming (ModestMsgEditWindow *window);
138 static void update_select_all_dimming (ModestMsgEditWindow *window);
139 static void update_zoom_dimming (ModestMsgEditWindow *window);
142 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
143 ModestMsgEditWindow *window);
144 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
145 ModestMsgEditWindow *window);
146 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
148 GtkTextIter *match_start,
149 GtkTextIter *match_end);
153 /* static gboolean */
154 /* on_key_pressed (GtkWidget *self, */
155 /* GdkEventKey *event, */
156 /* gpointer user_data); */
158 static void edit_menu_activated (GtkAction *action,
160 static void view_menu_activated (GtkAction *action,
163 /* list my signals */
170 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
171 struct _ModestMsgEditWindowPrivate {
173 GtkWidget *header_box;
175 ModestPairList *from_field_protos;
176 GtkWidget *from_field;
180 GtkWidget *bcc_field;
181 GtkWidget *subject_field;
182 GtkWidget *attachments_view;
183 GtkWidget *priority_icon;
184 GtkWidget *add_attachment_button;
186 GtkWidget *cc_caption;
187 GtkWidget *bcc_caption;
188 GtkWidget *attachments_caption;
190 GtkTextBuffer *text_buffer;
192 GtkWidget *font_size_toolitem;
193 GtkWidget *font_face_toolitem;
194 GtkWidget *font_color_button;
195 GSList *font_items_group;
196 GtkWidget *font_tool_button_label;
197 GSList *size_items_group;
198 GtkWidget *size_tool_button_label;
200 GtkWidget *find_toolbar;
204 GtkWidget *scroll_area;
209 TnyHeaderFlags priority_flags;
213 gulong clipboard_change_handler_id;
214 gulong system_clipboard_change_handler_id;
220 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
221 MODEST_TYPE_MSG_EDIT_WINDOW, \
222 ModestMsgEditWindowPrivate))
224 static GtkWindowClass *parent_class = NULL;
226 /* uncomment the following if you have defined any signals */
227 /* static guint signals[LAST_SIGNAL] = {0}; */
230 modest_msg_edit_window_get_type (void)
232 static GType my_type = 0;
234 static const GTypeInfo my_info = {
235 sizeof(ModestMsgEditWindowClass),
236 NULL, /* base init */
237 NULL, /* base finalize */
238 (GClassInitFunc) modest_msg_edit_window_class_init,
239 NULL, /* class finalize */
240 NULL, /* class data */
241 sizeof(ModestMsgEditWindow),
243 (GInstanceInitFunc) modest_msg_edit_window_init,
246 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
247 "ModestMsgEditWindow",
250 wp_text_buffer_library_init ();
256 save_state (ModestWindow *self)
258 modest_widget_memory_save (modest_runtime_get_conf(),
259 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
264 restore_settings (ModestMsgEditWindow *self)
266 modest_widget_memory_restore (modest_runtime_get_conf(),
267 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
272 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
274 GObjectClass *gobject_class;
275 ModestWindowClass *modest_window_class;
276 gobject_class = (GObjectClass*) klass;
277 modest_window_class = (ModestWindowClass*) klass;
279 parent_class = g_type_class_peek_parent (klass);
280 gobject_class->finalize = modest_msg_edit_window_finalize;
282 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
283 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
284 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
285 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
286 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
287 modest_window_class->save_state_func = save_state;
289 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
295 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
297 ModestMsgEditWindowPrivate *priv;
298 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
300 priv->msg_body = NULL;
301 priv->from_field = NULL;
302 priv->to_field = NULL;
303 priv->cc_field = NULL;
304 priv->bcc_field = NULL;
305 priv->subject_field = NULL;
306 priv->attachments = NULL;
308 priv->zoom_level = 1.0;
310 priv->cc_caption = NULL;
311 priv->bcc_caption = NULL;
313 priv->priority_flags = 0;
315 priv->find_toolbar = NULL;
316 priv->last_search = NULL;
318 priv->draft_msg = NULL;
319 priv->clipboard_change_handler_id = 0;
320 priv->system_clipboard_change_handler_id = 0;
325 /* FIXME: this is a dup from the one in gtk/ */
328 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
330 static ModestPairList*
331 get_transports (void)
333 GSList *transports = NULL;
335 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
336 GSList *accounts = modest_account_mgr_account_names (account_mgr,
337 TRUE /* only enabled accounts. */);
339 GSList *cursor = accounts;
341 gchar *account_name = cursor->data;
342 gchar *from_string = NULL;
344 from_string = modest_account_mgr_get_from_string (account_mgr,
348 if (from_string && account_name) {
349 gchar *name = account_name;
350 ModestPair *pair = modest_pair_new ((gpointer) name,
351 (gpointer) from_string , TRUE);
352 transports = g_slist_prepend (transports, pair);
355 cursor = cursor->next;
357 g_slist_free (accounts); /* only free the accounts, not the elements,
358 * because they are used in the pairlist */
364 init_window (ModestMsgEditWindow *obj)
366 GtkWidget *from_caption, *to_caption, *subject_caption;
367 GtkWidget *main_vbox;
368 ModestMsgEditWindowPrivate *priv;
370 GtkSizeGroup *size_group;
372 GtkWidget *subject_box;
373 GtkWidget *attachment_icon;
374 GtkWidget *window_box;
376 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
378 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
380 /* Note: This ModestPairList* must exist for as long as the combo
381 * that uses it, because the ModestComboBox uses the ID opaquely,
382 * so it can't know how to manage its memory. */
383 priv->from_field_protos = get_transports ();
385 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
387 priv->to_field = modest_recpt_editor_new ();
388 priv->cc_field = modest_recpt_editor_new ();
389 priv->bcc_field = modest_recpt_editor_new ();
390 subject_box = gtk_hbox_new (FALSE, 0);
391 priv->priority_icon = gtk_image_new ();
392 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
393 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
394 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
395 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
396 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
397 priv->add_attachment_button = gtk_button_new ();
398 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
399 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
400 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
401 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
402 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
403 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
404 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
405 priv->attachments_view = modest_attachments_view_new (NULL);
407 priv->header_box = gtk_vbox_new (FALSE, 0);
409 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
410 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
411 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
412 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
413 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
414 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
415 g_object_unref (size_group);
417 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
418 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
419 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
420 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
421 gtk_size_group_add_widget (size_group, priv->subject_field);
422 gtk_size_group_add_widget (size_group, priv->attachments_view);
423 g_object_unref (size_group);
425 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
426 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
427 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
428 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
429 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
430 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
431 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
434 priv->msg_body = wp_text_view_new ();
435 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
436 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
437 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
438 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
439 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
440 gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
442 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
444 priv->find_toolbar = hildon_find_toolbar_new (NULL);
445 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
447 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
449 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
450 G_CALLBACK (text_buffer_refresh_attributes), obj);
451 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
452 G_CALLBACK (text_buffer_delete_range), obj);
453 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
454 G_CALLBACK (text_buffer_can_undo), obj);
455 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
456 G_CALLBACK (text_buffer_can_redo), obj);
457 g_signal_connect (G_OBJECT (obj), "window-state-event",
458 G_CALLBACK (modest_msg_edit_window_window_state_event),
460 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
461 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
462 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
463 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
464 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
465 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
467 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
468 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
470 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
471 G_CALLBACK (msg_body_focus), obj);
472 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
473 G_CALLBACK (msg_body_focus), obj);
474 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
475 "changed", G_CALLBACK (recpt_field_changed), obj);
476 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
477 "changed", G_CALLBACK (recpt_field_changed), obj);
478 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
479 "changed", G_CALLBACK (recpt_field_changed), obj);
480 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
481 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
483 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
484 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
486 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
487 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
488 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
490 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
492 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
493 frame = gtk_frame_new (NULL);
494 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
496 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
497 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
498 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
500 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
501 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
502 gtk_widget_hide (priv->cc_caption);
504 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
505 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
506 gtk_widget_hide (priv->bcc_caption);
509 window_box = gtk_vbox_new (FALSE, 0);
510 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
511 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
512 gtk_container_add (GTK_CONTAINER(obj), window_box);
513 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
514 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
517 TODO: scroll_area was never instantiated.
518 Stop building without warnings-as-errors. murrayc.
519 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
520 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
523 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
524 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
525 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
526 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
532 modest_msg_edit_window_finalize (GObject *obj)
534 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
536 if (priv->clipboard_change_handler_id > 0) {
537 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
538 priv->clipboard_change_handler_id = 0;
541 if (priv->system_clipboard_change_handler_id > 0) {
542 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
543 priv->system_clipboard_change_handler_id);
544 priv->system_clipboard_change_handler_id = 0;
547 if (priv->draft_msg != NULL) {
548 g_object_unref (priv->draft_msg);
549 priv->draft_msg = NULL;
552 /* This had to stay alive for as long as the combobox that used it: */
553 modest_pair_list_free (priv->from_field_protos);
555 G_OBJECT_CLASS(parent_class)->finalize (obj);
559 menubar_to_menu (GtkUIManager *ui_manager)
561 GtkWidget *main_menu;
565 /* Create new main menu */
566 main_menu = gtk_menu_new();
568 /* Get the menubar from the UI manager */
569 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
571 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
575 menu = GTK_WIDGET (iter->data);
576 gtk_widget_reparent(menu, main_menu);
578 iter = g_list_next (iter);
585 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
588 const gchar *to, *cc, *bcc, *subject;
590 ModestMsgEditWindowPrivate *priv;
592 TnyHeaderFlags priority_flags;
594 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
595 g_return_if_fail (TNY_IS_MSG (msg));
597 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
599 header = tny_msg_get_header (msg);
600 to = tny_header_get_to (header);
601 cc = tny_header_get_cc (header);
602 bcc = tny_header_get_bcc (header);
603 subject = tny_header_get_subject (header);
604 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
607 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
609 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
610 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
611 gtk_widget_show (priv->cc_caption);
612 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
613 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
614 gtk_widget_hide (priv->cc_caption);
617 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
618 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
619 gtk_widget_show (priv->bcc_caption);
620 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
621 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
622 gtk_widget_hide (priv->bcc_caption);
625 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
626 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
629 update_window_title (self);
631 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
632 body = modest_tny_msg_get_body (msg, TRUE);
634 if ((body == NULL)||(body[0] == '\0')) {
636 body = modest_text_utils_convert_to_html ("");
638 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
639 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
642 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
645 /* Get the default format required from configuration */
646 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
647 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
650 /* Set the default focus depending on having already a To: field or not */
651 if ((!to)||(*to == '\0')) {
652 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
654 gtk_widget_grab_focus (priv->msg_body);
657 /* TODO: lower priority, select in the From: combo to the
658 value that comes from msg <- not sure, should it be
661 /* Add attachments to the view */
662 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
663 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
664 if (priv->attachments == NULL) {
665 gtk_widget_hide (priv->attachments_caption);
667 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
668 gtk_widget_show_all (priv->attachments_caption);
671 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
672 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
674 reset_modified (self);
676 update_dimmed (self);
677 text_buffer_can_undo (priv->text_buffer, FALSE, self);
678 text_buffer_can_redo (priv->text_buffer, FALSE, self);
680 priv->draft_msg = g_object_ref(msg);
684 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
687 GList *item_children, *node;
688 GtkWidget *bin_child;
690 bin_child = gtk_bin_get_child (GTK_BIN(item));
692 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
694 for (node = item_children; node != NULL; node = g_list_next (node)) {
695 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
696 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
699 g_list_free (item_children);
703 menu_tool_button_dont_expand (GtkMenuToolButton *item)
706 GList *item_children, *node;
708 box = gtk_bin_get_child (GTK_BIN (item));
709 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
710 item_children = gtk_container_get_children (GTK_CONTAINER (box));
712 for (node = item_children; node != NULL; node = g_list_next (node)) {
713 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
714 if (GTK_IS_TOGGLE_BUTTON (node->data))
715 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
716 else if (GTK_IS_BUTTON (node->data))
717 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
719 g_list_free (item_children);
724 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
726 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
727 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
728 GtkWidget *placeholder;
729 GtkWidget *tool_item;
734 GtkWidget *sizes_menu;
735 GtkWidget *fonts_menu;
736 GSList *radio_group = NULL;
741 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
742 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
744 /* should we hide the toolbar? */
745 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
746 gtk_widget_hide (parent_priv->toolbar);
748 /* Font color placeholder */
749 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
750 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
753 tool_item = GTK_WIDGET (gtk_tool_item_new ());
754 priv->font_color_button = hildon_color_button_new ();
755 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
756 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
757 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
758 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
759 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
760 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
761 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
763 /* Font size and face placeholder */
764 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
765 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
767 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
768 priv->size_tool_button_label = gtk_label_new (NULL);
769 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
770 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
771 size_text,"</span>", NULL);
772 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
774 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
775 sizes_menu = gtk_menu_new ();
776 priv->size_items_group = NULL;
778 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
779 GtkWidget *size_menu_item;
781 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
782 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
783 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
784 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
785 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
786 gtk_widget_show (size_menu_item);
788 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
792 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
793 GtkWidget *item = (GtkWidget *) node->data;
794 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
798 priv->size_items_group = g_slist_reverse (priv->size_items_group);
799 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
800 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
801 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
802 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
803 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
804 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
805 priv->font_size_toolitem = tool_item;
808 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
809 priv->font_tool_button_label = gtk_label_new (NULL);
810 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
811 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
813 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
814 fonts_menu = gtk_menu_new ();
815 priv->font_items_group = NULL;
817 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
818 GtkWidget *font_menu_item;
819 GtkWidget *child_label;
821 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
822 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
823 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
824 wp_get_font_name (font_index), "</span>", NULL);
825 gtk_label_set_markup (GTK_LABEL (child_label), markup);
828 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
829 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
830 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
831 gtk_widget_show (font_menu_item);
833 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
836 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
837 GtkWidget *item = (GtkWidget *) node->data;
838 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
841 priv->font_items_group = g_slist_reverse (priv->font_items_group);
842 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
843 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
844 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
845 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
846 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
847 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
848 priv->font_face_toolitem = tool_item;
850 /* Set expand and homogeneous for remaining items */
851 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
852 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
853 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
854 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
855 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
856 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
857 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
858 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
859 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
867 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
870 ModestWindowPrivate *parent_priv;
871 ModestMsgEditWindowPrivate *priv;
872 GtkActionGroup *action_group;
873 GError *error = NULL;
874 GdkPixbuf *window_icon = NULL;
877 gboolean prefer_formatted;
879 ModestPair *account_pair = NULL;
881 g_return_val_if_fail (msg, NULL);
882 g_return_val_if_fail (account_name, NULL);
884 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
886 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
887 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
889 parent_priv->ui_manager = gtk_ui_manager_new();
890 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
891 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
893 /* Add common actions */
894 gtk_action_group_add_actions (action_group,
895 modest_msg_edit_action_entries,
896 G_N_ELEMENTS (modest_msg_edit_action_entries),
898 gtk_action_group_add_toggle_actions (action_group,
899 modest_msg_edit_toggle_action_entries,
900 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
902 gtk_action_group_add_radio_actions (action_group,
903 modest_msg_edit_alignment_radio_action_entries,
904 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
906 G_CALLBACK (modest_ui_actions_on_change_justify),
908 gtk_action_group_add_radio_actions (action_group,
909 modest_msg_edit_zoom_action_entries,
910 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
912 G_CALLBACK (modest_ui_actions_on_change_zoom),
914 gtk_action_group_add_radio_actions (action_group,
915 modest_msg_edit_priority_action_entries,
916 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
918 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
920 gtk_action_group_add_radio_actions (action_group,
921 modest_msg_edit_file_format_action_entries,
922 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
923 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
924 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
926 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
927 g_object_unref (action_group);
929 /* Load the UI definition */
930 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
933 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
934 g_clear_error (&error);
937 /* Add accelerators */
938 gtk_window_add_accel_group (GTK_WINDOW (obj),
939 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
942 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
943 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
946 init_window (MODEST_MSG_EDIT_WINDOW(obj));
948 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
950 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
952 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
954 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
956 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
957 if (account_pair != NULL)
958 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
960 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
962 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
964 /* Set window icon */
965 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
966 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
968 /* Dim at start clipboard actions */
969 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
970 gtk_action_set_sensitive (action, FALSE);
971 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
972 gtk_action_set_sensitive (action, FALSE);
973 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
974 gtk_action_set_sensitive (action, FALSE);
976 /* Update select all */
977 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
978 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
979 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
980 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
981 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
983 /* set initial state of cc and bcc */
984 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
985 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
986 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
987 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
988 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
989 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
991 /* Setup the file format */
992 conf = modest_runtime_get_conf ();
993 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
995 g_clear_error (&error);
996 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
998 file_format = (prefer_formatted) ?
999 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1000 MODEST_FILE_FORMAT_PLAIN_TEXT;
1001 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1003 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1005 return (ModestWindow*) obj;
1009 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1011 GString **string_buffer = (GString **) user_data;
1013 *string_buffer = g_string_append (*string_buffer, buffer);
1019 * @result: A new string which should be freed with g_free().
1022 get_formatted_data (ModestMsgEditWindow *edit_window)
1024 ModestMsgEditWindowPrivate *priv;
1025 GString *string_buffer = g_string_new ("");
1027 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1029 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1031 return g_string_free (string_buffer, FALSE);
1036 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1039 const gchar *account_name;
1040 ModestMsgEditWindowPrivate *priv;
1042 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1044 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1046 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1047 g_return_val_if_fail (account_name, NULL);
1050 /* don't free these (except from) */
1051 data = g_slice_new0 (MsgData);
1052 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1054 data->account_name = g_strdup (account_name);
1055 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1056 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1057 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1058 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1059 if (priv->draft_msg) {
1060 data->draft_msg = g_object_ref (priv->draft_msg);
1062 data->draft_msg = NULL;
1065 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1067 gtk_text_buffer_get_bounds (buf, &b, &e);
1068 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1070 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1071 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1073 data->html_body = NULL;
1075 /* deep-copy the data */
1076 GList *cursor = priv->attachments;
1077 data->attachments = NULL;
1079 if (!(TNY_IS_MIME_PART(cursor->data))) {
1080 g_warning ("strange data in attachment list");
1083 data->attachments = g_list_append (data->attachments,
1084 g_object_ref (cursor->data));
1085 cursor = g_list_next (cursor);
1088 data->priority_flags = priv->priority_flags;
1095 unref_gobject (GObject *obj, gpointer data)
1097 if (!G_IS_OBJECT(obj))
1099 g_object_unref (obj);
1103 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1106 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1114 g_free (data->subject);
1115 g_free (data->plain_body);
1116 g_free (data->html_body);
1117 g_free (data->account_name);
1119 if (data->draft_msg != NULL) {
1120 g_object_unref (data->draft_msg);
1121 data->draft_msg = NULL;
1124 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1125 g_list_free (data->attachments);
1127 g_slice_free (MsgData, data);
1131 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1134 ModestMsgEditWindowPrivate *priv = NULL;
1135 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1137 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1139 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1141 return MODEST_MSG_EDIT_FORMAT_HTML;
1143 return MODEST_MSG_EDIT_FORMAT_TEXT;
1147 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1148 ModestMsgEditFormat format)
1150 ModestMsgEditWindowPrivate *priv;
1152 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1153 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1156 case MODEST_MSG_EDIT_FORMAT_HTML:
1157 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1159 case MODEST_MSG_EDIT_FORMAT_TEXT:
1160 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1163 g_return_if_reached ();
1167 ModestMsgEditFormatState *
1168 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1170 ModestMsgEditFormatState *format_state = NULL;
1171 ModestMsgEditWindowPrivate *priv;
1172 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1174 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1175 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1177 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1179 format_state = g_new0 (ModestMsgEditFormatState, 1);
1180 format_state->bold = buffer_format->bold&0x1;
1181 format_state->italics = buffer_format->italic&0x1;
1182 format_state->bullet = buffer_format->bullet&0x1;
1183 format_state->color = buffer_format->color;
1184 format_state->font_size = buffer_format->font_size;
1185 format_state->font_family = wp_get_font_name (buffer_format->font);
1186 format_state->justification = buffer_format->justification;
1187 g_free (buffer_format);
1189 return format_state;
1194 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1195 const ModestMsgEditFormatState *format_state)
1197 ModestMsgEditWindowPrivate *priv;
1198 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1199 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1200 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1201 g_return_if_fail (format_state != NULL);
1203 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1204 gtk_widget_grab_focus (priv->msg_body);
1205 buffer_format->bold = (format_state->bold != FALSE);
1206 buffer_format->italic = (format_state->italics != FALSE);
1207 buffer_format->color = format_state->color;
1208 buffer_format->font_size = format_state->font_size;
1209 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1210 buffer_format->justification = format_state->justification;
1211 buffer_format->bullet = format_state->bullet;
1213 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1215 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1216 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1217 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1218 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1219 buffer_format->cs.font = (buffer_format->font != current_format->font);
1220 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1221 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1223 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1224 if (buffer_format->cs.bold) {
1225 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1227 if (buffer_format->cs.italic) {
1228 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1230 if (buffer_format->cs.color) {
1231 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1233 if (buffer_format->cs.font_size) {
1234 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1236 if (buffer_format->cs.justification) {
1237 switch (buffer_format->justification) {
1238 case GTK_JUSTIFY_LEFT:
1239 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1241 case GTK_JUSTIFY_CENTER:
1242 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1244 case GTK_JUSTIFY_RIGHT:
1245 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1252 if (buffer_format->cs.font) {
1253 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1255 if (buffer_format->cs.bullet) {
1256 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1258 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1259 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1261 g_free (current_format);
1266 toggle_action_set_active_block_notify (GtkToggleAction *action,
1269 GSList *proxies = NULL;
1271 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1272 proxies != NULL; proxies = g_slist_next (proxies)) {
1273 GtkWidget *widget = (GtkWidget *) proxies->data;
1274 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1277 gtk_toggle_action_set_active (action, value);
1279 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1280 proxies != NULL; proxies = g_slist_next (proxies)) {
1281 GtkWidget *widget = (GtkWidget *) proxies->data;
1282 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1287 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1289 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1291 ModestWindowPrivate *parent_priv;
1292 ModestMsgEditWindowPrivate *priv;
1293 GtkWidget *new_size_menuitem;
1294 GtkWidget *new_font_menuitem;
1296 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1297 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1299 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1300 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1301 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1302 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1304 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1305 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1306 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1309 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1311 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1312 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1314 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1315 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1317 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1318 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1320 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1321 G_CALLBACK (modest_msg_edit_window_color_button_change),
1323 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1324 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1325 G_CALLBACK (modest_msg_edit_window_color_button_change),
1328 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1329 buffer_format->font_size))->data);
1330 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1334 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1335 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1336 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1338 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1339 G_CALLBACK (modest_msg_edit_window_size_change),
1341 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1342 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1343 G_CALLBACK (modest_msg_edit_window_size_change),
1347 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1348 buffer_format->font))->data);
1349 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1353 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1354 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1355 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1357 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1358 G_CALLBACK (modest_msg_edit_window_font_change),
1360 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1361 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1362 G_CALLBACK (modest_msg_edit_window_font_change),
1366 g_free (buffer_format);
1372 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1375 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1376 ModestMsgEditWindowPrivate *priv;
1377 GtkWidget *dialog = NULL;
1379 const GdkColor *new_color = NULL;
1381 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1382 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1384 #ifdef MODEST_HILDON_VERSION_0
1385 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1386 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1388 dialog = hildon_color_chooser_new ();
1389 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1390 #endif /*MODEST_HILDON_VERSION_0*/
1391 g_free (buffer_format);
1393 response = gtk_dialog_run (GTK_DIALOG (dialog));
1395 case GTK_RESPONSE_OK: {
1396 #ifdef MODEST_HILDON_VERSION_0
1397 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1400 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1402 #endif /*MODEST_HILDON_VERSION_0*/
1409 gtk_widget_destroy (dialog);
1411 if (new_color != NULL)
1412 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1417 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1420 ModestMsgEditWindowPrivate *priv;
1421 GtkWidget *dialog = NULL;
1423 GdkColor *old_color = NULL;
1424 const GdkColor *new_color = NULL;
1426 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1427 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1429 #ifdef MODEST_HILDON_VERSION_0
1430 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1431 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1433 dialog = hildon_color_chooser_new ();
1434 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1435 #endif /*MODEST_HILDON_VERSION_9*/
1437 response = gtk_dialog_run (GTK_DIALOG (dialog));
1439 case GTK_RESPONSE_OK: {
1440 #ifdef MODEST_HILDON_VERSION_0
1441 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1444 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1446 #endif /*MODEST_HILDON_VERSION_0*/
1452 gtk_widget_destroy (dialog);
1454 if (new_color != NULL)
1455 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1461 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1464 ModestMsgEditWindowPrivate *priv;
1465 GtkWidget *dialog = NULL;
1467 GSList *uris = NULL;
1468 GSList *uri_node = NULL;
1470 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1472 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1473 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1474 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1476 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1478 response = gtk_dialog_run (GTK_DIALOG (dialog));
1480 case GTK_RESPONSE_OK:
1481 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1486 gtk_widget_destroy (dialog);
1488 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1490 GnomeVFSHandle *handle = NULL;
1491 GnomeVFSResult result;
1492 GtkTextIter position;
1493 GtkTextMark *insert_mark;
1495 uri = (const gchar *) uri_node->data;
1496 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1497 if (result == GNOME_VFS_OK) {
1498 GdkPixbufLoader *loader;
1500 GnomeVFSFileInfo info;
1501 gchar *filename, *basename;
1502 TnyMimePart *mime_part;
1505 const gchar *mime_type = NULL;
1507 filename = g_filename_from_uri (uri, NULL, NULL);
1508 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1510 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1512 mime_part = tny_platform_factory_new_mime_part
1513 (modest_runtime_get_platform_factory ());
1514 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1516 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1518 content_id = g_strdup_printf ("%d", priv->last_cid);
1519 tny_mime_part_set_content_id (mime_part, content_id);
1520 g_free (content_id);
1523 basename = g_path_get_basename (filename);
1524 tny_mime_part_set_filename (mime_part, basename);
1527 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1528 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1530 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1531 gtk_widget_show_all (priv->attachments_caption);
1532 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1535 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1536 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1537 unsigned char read_buffer[128];
1539 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1540 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1543 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1544 g_object_ref (pixbuf);
1545 gdk_pixbuf_loader_close (loader, NULL);
1546 g_object_unref (loader);
1548 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1549 GdkPixbuf *new_pixbuf;
1551 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1552 gdk_pixbuf_get_width (pixbuf);
1553 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1554 g_object_unref (pixbuf);
1555 pixbuf = new_pixbuf;
1558 if (pixbuf != NULL) {
1559 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1560 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1561 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1570 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1573 ModestMsgEditWindowPrivate *priv;
1574 GtkWidget *dialog = NULL;
1576 GSList *uris = NULL;
1579 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1581 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1582 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1584 response = gtk_dialog_run (GTK_DIALOG (dialog));
1586 case GTK_RESPONSE_OK:
1587 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1592 gtk_widget_destroy (dialog);
1594 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1596 GnomeVFSHandle *handle = NULL;
1597 GnomeVFSResult result;
1599 uri = (const gchar *) uri_node->data;
1600 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1601 if (result == GNOME_VFS_OK) {
1602 TnyMimePart *mime_part;
1604 const gchar *mime_type = NULL;
1608 GnomeVFSFileInfo info;
1610 filename = g_filename_from_uri (uri, NULL, NULL);
1612 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1613 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1614 mime_part = tny_platform_factory_new_mime_part
1615 (modest_runtime_get_platform_factory ());
1616 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1618 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1620 content_id = g_strdup_printf ("%d", priv->last_cid);
1621 tny_mime_part_set_content_id (mime_part, content_id);
1622 g_free (content_id);
1625 basename = g_path_get_basename (filename);
1626 tny_mime_part_set_filename (mime_part, basename);
1629 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1630 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1632 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1633 gtk_widget_show_all (priv->attachments_caption);
1634 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1639 g_slist_foreach (uris, (GFunc) g_free, NULL);
1640 g_slist_free (uris);
1644 modest_msg_edit_window_attach_file_noninteractive (
1645 ModestMsgEditWindow *window,
1646 const gchar *file_uri)
1649 ModestMsgEditWindowPrivate *priv;
1651 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1653 if (file_uri && strlen(file_uri)) {
1656 /* TODO: We should probably try to use only the URI,
1657 * instead of using a filename.
1659 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1661 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1664 file_id = g_open (filename, O_RDONLY, 0);
1665 if (file_id != -1) {
1666 TnyMimePart *mime_part;
1668 const gchar *mime_type;
1671 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1672 mime_type = gnome_vfs_get_mime_type(filename);
1674 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1676 mime_part = tny_platform_factory_new_mime_part
1677 (modest_runtime_get_platform_factory ());
1678 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1680 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1682 content_id = g_strdup_printf ("%d", priv->last_cid);
1683 tny_mime_part_set_content_id (mime_part, content_id);
1684 g_free (content_id);
1687 basename = g_path_get_basename (filename);
1688 tny_mime_part_set_filename (mime_part, basename);
1691 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1692 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1694 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1695 gtk_widget_show_all (priv->attachments_caption);
1696 } else if (file_id == -1) {
1698 g_warning("file to be attached does not exist: %s", filename);
1706 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1709 ModestMsgEditWindowPrivate *priv;
1710 gboolean clean_list = FALSE;
1712 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1713 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1715 if (att_list == NULL) {
1716 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1720 if (att_list == NULL) {
1721 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1723 GtkWidget *confirmation_dialog = NULL;
1724 gboolean dialog_response;
1726 gchar *message = NULL;
1727 const gchar *filename = NULL;
1729 if (att_list->next == NULL) {
1730 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1734 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1735 att_list->next == NULL), filename);
1736 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1738 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1739 gtk_widget_destroy (confirmation_dialog);
1740 if (!dialog_response) {
1742 g_list_free (att_list);
1745 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1747 for (node = att_list; node != NULL; node = g_list_next (node)) {
1748 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1749 const gchar *att_id;
1750 priv->attachments = g_list_remove (priv->attachments, mime_part);
1752 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1754 if (priv->attachments == NULL)
1755 gtk_widget_hide (priv->attachments_caption);
1756 att_id = tny_mime_part_get_content_id (mime_part);
1758 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1760 g_object_unref (mime_part);
1761 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1766 g_list_free (att_list);
1770 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1773 ModestMsgEditWindowPrivate *priv;
1774 GdkColor *new_color;
1775 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1777 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1778 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1781 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1783 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1785 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1787 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1792 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1795 ModestMsgEditWindowPrivate *priv;
1796 gint new_size_index;
1797 ModestMsgEditWindow *window;
1800 window = MODEST_MSG_EDIT_WINDOW (userdata);
1801 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1802 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1804 if (gtk_check_menu_item_get_active (menu_item)) {
1806 WPTextBufferFormat format;
1808 memset (&format, 0, sizeof (format));
1809 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1811 label = gtk_bin_get_child (GTK_BIN (menu_item));
1813 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1814 format.cs.font_size = TRUE;
1815 format.cs.text_position = TRUE;
1816 format.cs.font = TRUE;
1817 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1818 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1820 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1821 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1822 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1824 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1825 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1826 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1832 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1835 ModestMsgEditWindowPrivate *priv;
1836 gint new_font_index;
1837 ModestMsgEditWindow *window;
1840 window = MODEST_MSG_EDIT_WINDOW (userdata);
1841 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1842 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1844 if (gtk_check_menu_item_get_active (menu_item)) {
1847 label = gtk_bin_get_child (GTK_BIN (menu_item));
1849 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1851 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1852 (gpointer) new_font_index))
1853 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1855 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1856 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1857 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1863 modest_msg_edit_window_set_zoom (ModestWindow *window,
1866 ModestMsgEditWindowPrivate *priv;
1867 ModestWindowPrivate *parent_priv;
1868 GtkRadioAction *zoom_radio_action;
1870 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1872 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1873 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1874 priv->zoom_level = zoom;
1875 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1877 /* Zoom level menu options should be updated with the current zoom level */
1878 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1879 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1880 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1881 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1882 /* FIXME: Not availible before Gtk 2.10 */
1884 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1889 modest_msg_edit_window_get_zoom (ModestWindow *window)
1891 ModestMsgEditWindowPrivate *priv;
1893 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1895 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1896 return priv->zoom_level;
1900 zoom_allowed (ModestMsgEditWindow *window)
1904 focus = gtk_window_get_focus (GTK_WINDOW (window));
1905 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1909 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1911 ModestWindowPrivate *parent_priv;
1912 GtkRadioAction *zoom_radio_action;
1913 GSList *group, *node;
1915 /* First we check if the text view is focused. If not, zooming is not allowed */
1916 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1917 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1921 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1922 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1923 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1925 group = gtk_radio_action_get_group (zoom_radio_action);
1927 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1928 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1932 for (node = group; node != NULL; node = g_slist_next (node)) {
1933 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1934 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1942 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1944 ModestWindowPrivate *parent_priv;
1945 GtkRadioAction *zoom_radio_action;
1946 GSList *group, *node;
1948 /* First we check if the text view is focused. If not, zooming is not allowed */
1949 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1950 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1954 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1955 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1956 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1958 group = gtk_radio_action_get_group (zoom_radio_action);
1960 for (node = group; node != NULL; node = g_slist_next (node)) {
1961 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1962 if (node->next != NULL) {
1963 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1966 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1974 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1976 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1977 ModestWindowPrivate *parent_priv;
1978 ModestWindowMgr *mgr;
1979 gboolean is_fullscreen;
1980 GtkAction *fs_toggle_action;
1983 mgr = modest_runtime_get_window_mgr ();
1984 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1986 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1988 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1989 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1990 if (is_fullscreen != active)
1991 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1999 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2001 ModestWindowPrivate *parent_priv;
2002 GtkAction *fs_toggle_action;
2005 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2007 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2008 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2009 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2013 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2016 ModestMsgEditWindowPrivate *priv = NULL;
2017 const gchar *recipients;
2018 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2020 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2021 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2022 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2023 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2024 gtk_widget_show (priv->cc_caption);
2026 gtk_widget_hide (priv->cc_caption);
2027 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2031 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2034 ModestMsgEditWindowPrivate *priv = NULL;
2035 const gchar *recipients;
2036 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2038 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2039 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2040 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2041 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2042 gtk_widget_show (priv->bcc_caption);
2044 gtk_widget_hide (priv->bcc_caption);
2045 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2049 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2050 ModestRecptEditor *editor)
2052 ModestMsgEditWindowPrivate *priv;
2054 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2055 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2056 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2058 if (editor == NULL) {
2059 GtkWidget *view_focus;
2060 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2062 /* This code should be kept in sync with ModestRecptEditor. The
2063 textview inside the recpt editor is the one that really gets the
2064 focus. As it's inside a scrolled window, and this one inside the
2065 hbox recpt editor inherits from, we'll need to go up in the
2066 hierarchy to know if the text view is part of the recpt editor
2067 or if it's a different text entry */
2069 if (gtk_widget_get_parent (view_focus)) {
2070 GtkWidget *first_parent;
2072 first_parent = gtk_widget_get_parent (view_focus);
2073 if (gtk_widget_get_parent (first_parent) &&
2074 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2075 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2080 editor = MODEST_RECPT_EDITOR (priv->to_field);
2084 modest_address_book_select_addresses (editor);
2089 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2091 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2093 modest_msg_edit_window_open_addressbook (window, NULL);
2097 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2098 gboolean show_toolbar)
2100 ModestWindowPrivate *parent_priv;
2102 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2103 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2105 /* FIXME: we can not just use the code of
2106 modest_msg_edit_window_setup_toolbar because it has a
2107 mixture of both initialization and creation code. */
2110 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2112 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2116 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2117 TnyHeaderFlags priority_flags)
2119 ModestMsgEditWindowPrivate *priv;
2120 ModestWindowPrivate *parent_priv;
2122 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2124 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2125 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2126 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2128 if (priv->priority_flags != priority_flags) {
2129 GtkAction *priority_action = NULL;
2131 priv->priority_flags = priority_flags;
2133 switch (priority_flags) {
2134 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2135 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2136 gtk_widget_show (priv->priority_icon);
2137 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2138 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2140 case TNY_HEADER_FLAG_LOW_PRIORITY:
2141 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2142 gtk_widget_show (priv->priority_icon);
2143 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2144 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2147 gtk_widget_hide (priv->priority_icon);
2148 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2149 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2152 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2153 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2158 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2161 ModestMsgEditWindowPrivate *priv;
2162 ModestWindowPrivate *parent_priv;
2163 gint current_format;
2165 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2167 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2168 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2170 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2171 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2173 if (current_format != file_format) {
2174 switch (file_format) {
2175 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2176 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2178 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2182 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2183 response = gtk_dialog_run (GTK_DIALOG (dialog));
2184 gtk_widget_destroy (dialog);
2185 if (response == GTK_RESPONSE_OK) {
2186 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2188 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2189 toggle_action_set_active_block_notify (action, TRUE);
2194 update_dimmed (window);
2199 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2202 ModestMsgEditWindowPrivate *priv;
2203 WPTextBufferFormat oldfmt, fmt;
2204 gint old_position = 0;
2208 GdkColor *color = NULL;
2209 gboolean bold, bold_set, italic, italic_set;
2210 gboolean underline, underline_set;
2211 gboolean strikethrough, strikethrough_set;
2212 gboolean position_set;
2213 gboolean font_size_set, font_set, color_set;
2216 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2217 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2219 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2221 /* First we get the currently selected font information */
2222 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2223 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2225 switch (oldfmt.text_position) {
2226 case TEXT_POSITION_NORMAL:
2229 case TEXT_POSITION_SUPERSCRIPT:
2237 g_object_set (G_OBJECT (dialog),
2238 "bold", oldfmt.bold != FALSE,
2239 "bold-set", !oldfmt.cs.bold,
2240 "underline", oldfmt.underline != FALSE,
2241 "underline-set", !oldfmt.cs.underline,
2242 "italic", oldfmt.italic != FALSE,
2243 "italic-set", !oldfmt.cs.italic,
2244 "strikethrough", oldfmt.strikethrough != FALSE,
2245 "strikethrough-set", !oldfmt.cs.strikethrough,
2246 "color", &oldfmt.color,
2247 "color-set", !oldfmt.cs.color,
2248 "size", wp_font_size[oldfmt.font_size],
2249 "size-set", !oldfmt.cs.font_size,
2250 "position", old_position,
2251 "position-set", !oldfmt.cs.text_position,
2252 "family", wp_get_font_name (oldfmt.font),
2253 "family-set", !oldfmt.cs.font,
2256 gtk_widget_show_all (dialog);
2257 response = gtk_dialog_run (GTK_DIALOG (dialog));
2258 if (response == GTK_RESPONSE_OK) {
2260 g_object_get( dialog,
2262 "bold-set", &bold_set,
2263 "underline", &underline,
2264 "underline-set", &underline_set,
2266 "italic-set", &italic_set,
2267 "strikethrough", &strikethrough,
2268 "strikethrough-set", &strikethrough_set,
2270 "color-set", &color_set,
2272 "size-set", &font_size_set,
2273 "family", &font_name,
2274 "family-set", &font_set,
2275 "position", &position,
2276 "position-set", &position_set,
2281 if (response == GTK_RESPONSE_OK) {
2282 memset(&fmt, 0, sizeof(fmt));
2288 fmt.italic = italic;
2289 fmt.cs.italic = TRUE;
2291 if (underline_set) {
2292 fmt.underline = underline;
2293 fmt.cs.underline = TRUE;
2295 if (strikethrough_set) {
2296 fmt.strikethrough = strikethrough;
2297 fmt.cs.strikethrough = TRUE;
2302 ? TEXT_POSITION_NORMAL
2303 : ( ( position == 1 )
2304 ? TEXT_POSITION_SUPERSCRIPT
2305 : TEXT_POSITION_SUBSCRIPT );
2306 fmt.cs.text_position = TRUE;
2310 fmt.cs.color = TRUE;
2313 fmt.font = wp_get_font_index(font_name,
2318 if (font_size_set) {
2319 fmt.font_size = wp_get_font_size_index(
2320 font_size, DEFAULT_FONT_SIZE);
2321 fmt.cs.font_size = TRUE;
2323 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2325 gtk_widget_destroy (dialog);
2327 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2331 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2333 ModestMsgEditWindowPrivate *priv;
2335 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2336 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2338 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2340 update_dimmed (window);
2345 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2347 ModestMsgEditWindowPrivate *priv;
2349 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2350 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2352 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2354 update_dimmed (window);
2359 update_dimmed (ModestMsgEditWindow *window)
2361 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2362 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2366 gboolean editor_focused;
2368 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2369 editor_focused = gtk_widget_is_focus (priv->msg_body);
2371 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2372 gtk_action_set_sensitive (action, rich_text && editor_focused);
2373 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2374 gtk_action_set_sensitive (action, rich_text && editor_focused);
2375 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2376 gtk_action_set_sensitive (action, rich_text && editor_focused);
2377 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2378 gtk_action_set_sensitive (action, rich_text && editor_focused);
2379 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2380 gtk_action_set_sensitive (action, rich_text && editor_focused);
2381 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2382 gtk_action_set_sensitive (action, rich_text && editor_focused);
2383 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2384 gtk_action_set_sensitive (action, rich_text && editor_focused);
2385 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2386 gtk_action_set_sensitive (action, rich_text && editor_focused);
2387 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2388 gtk_action_set_sensitive (action, rich_text && editor_focused);
2389 widget = priv->font_color_button;
2390 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2391 widget = priv->font_size_toolitem;
2392 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2393 widget = priv->font_face_toolitem;
2394 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2398 setup_insensitive_handlers (ModestMsgEditWindow *window)
2400 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2401 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2404 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2405 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2406 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2407 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2409 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2410 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2411 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2412 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2413 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2414 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2415 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2416 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2417 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2418 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2419 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2420 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2421 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2422 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2423 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2424 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2425 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2426 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2427 widget = priv->font_color_button;
2428 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2429 widget = priv->font_size_toolitem;
2430 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2431 widget = priv->font_face_toolitem;
2432 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, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2435 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2436 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2437 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2439 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2440 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (paste_insensitive_press), window);
2441 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2442 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (copy_insensitive_press), window);
2446 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2448 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2451 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2452 gtk_action_set_sensitive (action, can_undo);
2456 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2458 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2461 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2462 gtk_action_set_sensitive (action, can_redo);
2466 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2469 GtkTextIter match_start, match_end;
2471 if (image_id == NULL)
2474 gtk_text_buffer_get_start_iter (buffer, &iter);
2476 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2477 GSList *tags = gtk_text_iter_get_tags (&match_start);
2479 for (node = tags; node != NULL; node = g_slist_next (node)) {
2480 GtkTextTag *tag = (GtkTextTag *) node->data;
2481 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2482 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2483 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2485 offset = gtk_text_iter_get_offset (&match_start);
2486 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2487 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2491 gtk_text_iter_forward_char (&iter);
2496 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2498 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2499 GtkTextIter real_start, real_end;
2500 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2502 if (gtk_text_iter_compare (start, end) > 0) {
2506 real_start = *start;
2510 GSList *tags = gtk_text_iter_get_tags (&real_start);
2512 for (node = tags; node != NULL; node = g_slist_next (node)) {
2513 GtkTextTag *tag = (GtkTextTag *) node->data;
2514 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2515 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2517 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2519 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2522 } while (gtk_text_iter_forward_char (&real_start)&&
2523 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2527 msg_body_focus (GtkWidget *focus,
2528 GdkEventFocus *event,
2532 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2537 recpt_field_changed (GtkTextBuffer *buffer,
2538 ModestMsgEditWindow *editor)
2540 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2541 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2542 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2543 gboolean dim = FALSE;
2546 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2547 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2548 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2550 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2551 gtk_text_buffer_get_char_count (cc_buffer) +
2552 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2554 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2555 gtk_action_set_sensitive (action, !dim);
2556 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2557 gtk_action_set_sensitive (action, !dim);
2561 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2563 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2567 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2569 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2573 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2575 ModestWindowPrivate *parent_priv;
2576 ModestMsgEditWindowPrivate *priv;
2577 GList *selected_attachments = NULL;
2578 gint n_att_selected = 0;
2580 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2581 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2583 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2584 n_att_selected = g_list_length (selected_attachments);
2585 g_list_free (selected_attachments);
2587 if (n_att_selected > 1)
2588 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2589 else if (n_att_selected == 0)
2590 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2592 hildon_banner_show_information (NULL, NULL, _("mail_ib_unable_to_purge_attachments"));
2596 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2598 gboolean rich_text, editor_focused;
2600 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2601 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2602 editor_focused = gtk_widget_is_focus (priv->msg_body);
2605 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2606 else if (!editor_focused)
2607 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2611 reset_modified (ModestMsgEditWindow *editor)
2613 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2614 GtkTextBuffer *buffer;
2616 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2617 gtk_text_buffer_set_modified (buffer, FALSE);
2618 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2619 gtk_text_buffer_set_modified (buffer, FALSE);
2620 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2621 gtk_text_buffer_set_modified (buffer, FALSE);
2622 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2626 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2628 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2629 GtkTextBuffer *buffer;
2631 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2632 if (gtk_text_buffer_get_modified (buffer))
2634 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2635 if (gtk_text_buffer_get_modified (buffer))
2637 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2638 if (gtk_text_buffer_get_modified (buffer))
2640 if (gtk_text_buffer_get_modified (priv->text_buffer))
2647 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2649 ModestMsgEditWindowPrivate *priv = NULL;
2651 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2652 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2654 /* check if there's no recipient added */
2655 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2656 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2657 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2658 /* no recipient contents, then select contacts */
2659 modest_msg_edit_window_open_addressbook (window, NULL);
2663 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2665 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2667 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2670 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2677 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2678 ModestMsgEditWindow *window)
2680 modest_msg_edit_window_attach_file (window);
2684 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2686 ModestMsgEditWindow *window)
2688 ModestWindowPrivate *parent_priv;
2689 ModestMsgEditWindowPrivate *priv;
2691 gboolean has_selection;
2693 GList *selected_attachments = NULL;
2694 gint n_att_selected = 0;
2696 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2697 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2698 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2699 focused = gtk_window_get_focus (GTK_WINDOW (window));
2701 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2702 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2703 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2704 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2706 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2707 n_att_selected = g_list_length (selected_attachments);
2708 g_list_free (selected_attachments);
2710 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2711 gtk_action_set_sensitive (action, n_att_selected == 1);
2713 update_paste_dimming (window);
2717 update_window_title (ModestMsgEditWindow *window)
2719 ModestMsgEditWindowPrivate *priv = NULL;
2720 const gchar *subject;
2722 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2723 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2724 if (subject == NULL || subject[0] == '\0')
2725 subject = _("mail_va_new_email");
2727 gtk_window_set_title (GTK_WINDOW (window), subject);
2732 subject_field_changed (GtkEditable *editable,
2733 ModestMsgEditWindow *window)
2735 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2736 update_window_title (window);
2737 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2741 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2744 ModestMsgEditWindowPrivate *priv = NULL;
2746 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2747 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2749 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2751 gtk_widget_show_all (priv->find_toolbar);
2752 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2754 gtk_widget_hide_all (priv->find_toolbar);
2755 gtk_widget_grab_focus (priv->msg_body);
2761 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2763 GtkTextIter *match_start,
2764 GtkTextIter *match_end)
2766 GtkTextIter end_iter;
2767 gchar *str_casefold;
2770 gchar *range_casefold;
2773 gboolean result = FALSE;
2780 gtk_text_iter_forward_to_end (&end_iter);
2782 str_casefold = g_utf8_casefold (str, -1);
2783 str_chars_n = strlen (str);
2785 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2786 range_casefold = g_utf8_casefold (range_text, -1);
2787 range_chars_n = strlen (range_casefold);
2789 if (range_chars_n < str_chars_n) {
2790 g_free (str_casefold);
2791 g_free (range_text);
2792 g_free (range_casefold);
2796 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2797 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2798 if (!g_utf8_collate (range_subtext, str_casefold)) {
2799 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2801 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2802 match_start, match_end, NULL);
2803 g_free (found_text);
2805 g_free (range_subtext);
2809 g_free (str_casefold);
2810 g_free (range_text);
2811 g_free (range_casefold);
2818 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2819 ModestMsgEditWindow *window)
2821 gchar *current_search = NULL;
2822 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2824 GtkTextIter selection_start, selection_end;
2825 GtkTextIter match_start, match_end;
2826 gboolean continue_search = FALSE;
2828 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2829 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2830 g_free (current_search);
2831 g_free (priv->last_search);
2832 priv->last_search = NULL;
2833 /* Information banner about empty search */
2834 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2838 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2839 continue_search = TRUE;
2841 g_free (priv->last_search);
2842 priv->last_search = g_strdup (current_search);
2845 if (continue_search) {
2846 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2847 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2848 &match_start, &match_end);
2850 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2852 GtkTextIter buffer_start;
2853 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2854 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2855 &match_start, &match_end);
2857 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2860 /* Mark as selected the string found in search */
2862 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2863 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2865 g_free (priv->last_search);
2866 priv->last_search = NULL;
2868 g_free (current_search);
2872 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2873 ModestMsgEditWindow *window)
2875 GtkToggleAction *toggle;
2876 ModestWindowPrivate *parent_priv;
2877 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2879 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2880 gtk_toggle_action_set_active (toggle, FALSE);
2885 update_paste_dimming (ModestMsgEditWindow *window)
2887 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2888 GtkAction *action = NULL;
2889 GtkClipboard *clipboard = NULL;
2893 focused = gtk_window_get_focus (GTK_WINDOW (window));
2895 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2896 active = gtk_clipboard_wait_is_text_available (clipboard);
2899 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2903 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2904 gtk_action_set_sensitive (action, active);
2909 paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2911 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (editor));
2913 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2914 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
2916 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
2921 copy_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2923 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_copy"));
2929 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2931 ModestMsgEditWindow *window)
2933 update_paste_dimming (window);
2937 update_select_all_dimming (ModestMsgEditWindow *window)
2940 gboolean dimmed = FALSE;
2942 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2944 focused = gtk_window_get_focus (GTK_WINDOW (window));
2945 if (GTK_IS_ENTRY (focused)) {
2946 const gchar *current_text;
2947 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2948 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2949 } else if (GTK_IS_TEXT_VIEW (focused)) {
2950 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2951 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2952 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2955 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2956 gtk_action_set_sensitive (action, !dimmed);
2960 update_zoom_dimming (ModestMsgEditWindow *window)
2963 gboolean dimmed = FALSE;
2965 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2967 focused = gtk_window_get_focus (GTK_WINDOW (window));
2968 dimmed = ! WP_IS_TEXT_VIEW (focused);
2969 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2970 gtk_action_set_sensitive (action, !dimmed);
2974 edit_menu_activated (GtkAction *action,
2977 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2979 update_select_all_dimming (window);
2982 view_menu_activated (GtkAction *action,
2985 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2987 update_zoom_dimming (window);
2991 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2993 ModestMsgEditWindowPrivate *priv;
2995 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3000 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3003 ModestMsgEditWindowPrivate *priv;
3005 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);