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 setup_insensitive_handlers (ModestMsgEditWindow *editor);
98 static void reset_modified (ModestMsgEditWindow *editor);
100 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
101 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
102 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
103 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
104 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
105 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
107 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
109 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
111 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
112 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
113 GdkEventWindowState *event,
115 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
116 ModestRecptEditor *editor);
117 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
118 ModestMsgEditWindow *window);
120 /* ModestWindow methods implementation */
121 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
122 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
123 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
124 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
125 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
126 gboolean show_toolbar);
127 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
129 ModestMsgEditWindow *window);
130 static void modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
132 ModestMsgEditWindow *window);
133 static void update_window_title (ModestMsgEditWindow *window);
134 static void update_dimmed (ModestMsgEditWindow *window);
135 static void update_paste_dimming (ModestMsgEditWindow *window);
136 static void update_select_all_dimming (ModestMsgEditWindow *window);
137 static void update_zoom_dimming (ModestMsgEditWindow *window);
140 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
141 ModestMsgEditWindow *window);
142 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
143 ModestMsgEditWindow *window);
144 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
146 GtkTextIter *match_start,
147 GtkTextIter *match_end);
151 static void edit_menu_activated (GtkAction *action,
153 static void view_menu_activated (GtkAction *action,
156 /* list my signals */
163 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
164 struct _ModestMsgEditWindowPrivate {
166 GtkWidget *header_box;
168 ModestPairList *from_field_protos;
169 GtkWidget *from_field;
173 GtkWidget *bcc_field;
174 GtkWidget *subject_field;
175 GtkWidget *attachments_view;
176 GtkWidget *priority_icon;
177 GtkWidget *add_attachment_button;
179 GtkWidget *cc_caption;
180 GtkWidget *bcc_caption;
181 GtkWidget *attachments_caption;
183 GtkTextBuffer *text_buffer;
185 GtkWidget *font_size_toolitem;
186 GtkWidget *font_face_toolitem;
187 GtkWidget *font_color_button;
188 GSList *font_items_group;
189 GtkWidget *font_tool_button_label;
190 GSList *size_items_group;
191 GtkWidget *size_tool_button_label;
193 GtkWidget *find_toolbar;
197 GtkWidget *scroll_area;
202 TnyHeaderFlags priority_flags;
206 gulong clipboard_change_handler_id;
207 gulong system_clipboard_change_handler_id;
213 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
214 MODEST_TYPE_MSG_EDIT_WINDOW, \
215 ModestMsgEditWindowPrivate))
217 static GtkWindowClass *parent_class = NULL;
219 /* uncomment the following if you have defined any signals */
220 /* static guint signals[LAST_SIGNAL] = {0}; */
223 modest_msg_edit_window_get_type (void)
225 static GType my_type = 0;
227 static const GTypeInfo my_info = {
228 sizeof(ModestMsgEditWindowClass),
229 NULL, /* base init */
230 NULL, /* base finalize */
231 (GClassInitFunc) modest_msg_edit_window_class_init,
232 NULL, /* class finalize */
233 NULL, /* class data */
234 sizeof(ModestMsgEditWindow),
236 (GInstanceInitFunc) modest_msg_edit_window_init,
239 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
240 "ModestMsgEditWindow",
243 wp_text_buffer_library_init ();
249 save_state (ModestWindow *self)
251 modest_widget_memory_save (modest_runtime_get_conf(),
252 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
257 restore_settings (ModestMsgEditWindow *self)
259 modest_widget_memory_restore (modest_runtime_get_conf(),
260 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
265 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
267 GObjectClass *gobject_class;
268 ModestWindowClass *modest_window_class;
269 gobject_class = (GObjectClass*) klass;
270 modest_window_class = (ModestWindowClass*) klass;
272 parent_class = g_type_class_peek_parent (klass);
273 gobject_class->finalize = modest_msg_edit_window_finalize;
275 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
276 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
277 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
278 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
279 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
280 modest_window_class->save_state_func = save_state;
282 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
288 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
290 ModestMsgEditWindowPrivate *priv;
291 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
293 priv->msg_body = NULL;
294 priv->from_field = NULL;
295 priv->to_field = NULL;
296 priv->cc_field = NULL;
297 priv->bcc_field = NULL;
298 priv->subject_field = NULL;
299 priv->attachments = NULL;
301 priv->zoom_level = 1.0;
303 priv->cc_caption = NULL;
304 priv->bcc_caption = NULL;
306 priv->priority_flags = 0;
308 priv->find_toolbar = NULL;
309 priv->last_search = NULL;
311 priv->draft_msg = NULL;
312 priv->clipboard_change_handler_id = 0;
313 priv->system_clipboard_change_handler_id = 0;
318 /* FIXME: this is a dup from the one in gtk/ */
321 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
323 static ModestPairList*
324 get_transports (void)
326 GSList *transports = NULL;
328 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
329 GSList *accounts = modest_account_mgr_account_names (account_mgr,
330 TRUE /* only enabled accounts. */);
332 GSList *cursor = accounts;
334 gchar *account_name = cursor->data;
335 gchar *from_string = NULL;
337 from_string = modest_account_mgr_get_from_string (account_mgr,
341 if (from_string && account_name) {
342 gchar *name = account_name;
343 ModestPair *pair = modest_pair_new ((gpointer) name,
344 (gpointer) from_string , TRUE);
345 transports = g_slist_prepend (transports, pair);
348 cursor = cursor->next;
350 g_slist_free (accounts); /* only free the accounts, not the elements,
351 * because they are used in the pairlist */
357 init_window (ModestMsgEditWindow *obj)
359 GtkWidget *from_caption, *to_caption, *subject_caption;
360 GtkWidget *main_vbox;
361 ModestMsgEditWindowPrivate *priv;
363 GtkSizeGroup *size_group;
365 GtkWidget *subject_box;
366 GtkWidget *attachment_icon;
367 GtkWidget *window_box;
369 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
371 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
373 /* Note: This ModestPairList* must exist for as long as the combo
374 * that uses it, because the ModestComboBox uses the ID opaquely,
375 * so it can't know how to manage its memory. */
376 priv->from_field_protos = get_transports ();
378 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
380 priv->to_field = modest_recpt_editor_new ();
381 priv->cc_field = modest_recpt_editor_new ();
382 priv->bcc_field = modest_recpt_editor_new ();
383 subject_box = gtk_hbox_new (FALSE, 0);
384 priv->priority_icon = gtk_image_new ();
385 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
386 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
387 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
388 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
389 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
390 priv->add_attachment_button = gtk_button_new ();
391 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
392 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
393 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
394 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
395 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
396 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
397 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
398 priv->attachments_view = modest_attachments_view_new (NULL);
400 priv->header_box = gtk_vbox_new (FALSE, 0);
402 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
403 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
404 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
405 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
406 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
407 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
408 g_object_unref (size_group);
410 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
411 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
412 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
413 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
414 gtk_size_group_add_widget (size_group, priv->subject_field);
415 gtk_size_group_add_widget (size_group, priv->attachments_view);
416 g_object_unref (size_group);
418 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
419 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
420 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
421 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
422 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
423 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
424 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
427 priv->msg_body = wp_text_view_new ();
428 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
429 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
430 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
431 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
432 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
433 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
435 priv->find_toolbar = hildon_find_toolbar_new (NULL);
436 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
438 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
439 G_CALLBACK (text_buffer_refresh_attributes), obj);
440 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
441 G_CALLBACK (text_buffer_delete_range), obj);
442 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
443 G_CALLBACK (text_buffer_can_undo), obj);
444 g_signal_connect (G_OBJECT (obj), "window-state-event",
445 G_CALLBACK (modest_msg_edit_window_window_state_event),
447 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
448 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
449 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
450 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
451 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
452 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
454 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
455 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
457 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
458 G_CALLBACK (msg_body_focus), obj);
459 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
460 G_CALLBACK (msg_body_focus), obj);
461 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
462 "changed", G_CALLBACK (recpt_field_changed), obj);
463 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
464 "changed", G_CALLBACK (recpt_field_changed), obj);
465 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
466 "changed", G_CALLBACK (recpt_field_changed), obj);
467 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
468 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
470 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
471 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
473 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
474 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
475 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
477 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
479 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
480 frame = gtk_frame_new (NULL);
481 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
483 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
484 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
485 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
487 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
488 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
489 gtk_widget_hide (priv->cc_caption);
491 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
492 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
493 gtk_widget_hide (priv->bcc_caption);
496 window_box = gtk_vbox_new (FALSE, 0);
497 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
498 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
499 gtk_container_add (GTK_CONTAINER(obj), window_box);
500 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
501 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
504 TODO: scroll_area was never instantiated.
505 Stop building without warnings-as-errors. murrayc.
506 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
507 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
510 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
511 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
512 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
513 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
519 modest_msg_edit_window_finalize (GObject *obj)
521 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
523 if (priv->clipboard_change_handler_id > 0) {
524 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
525 priv->clipboard_change_handler_id = 0;
528 if (priv->system_clipboard_change_handler_id > 0) {
529 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
530 priv->system_clipboard_change_handler_id);
531 priv->system_clipboard_change_handler_id = 0;
534 if (priv->draft_msg != NULL) {
535 g_object_unref (priv->draft_msg);
536 priv->draft_msg = NULL;
539 /* This had to stay alive for as long as the combobox that used it: */
540 modest_pair_list_free (priv->from_field_protos);
542 G_OBJECT_CLASS(parent_class)->finalize (obj);
546 menubar_to_menu (GtkUIManager *ui_manager)
548 GtkWidget *main_menu;
552 /* Create new main menu */
553 main_menu = gtk_menu_new();
555 /* Get the menubar from the UI manager */
556 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
558 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
562 menu = GTK_WIDGET (iter->data);
563 gtk_widget_reparent(menu, main_menu);
565 iter = g_list_next (iter);
572 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
575 const gchar *to, *cc, *bcc, *subject;
577 ModestMsgEditWindowPrivate *priv;
579 TnyHeaderFlags priority_flags;
581 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
582 g_return_if_fail (TNY_IS_MSG (msg));
584 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
586 header = tny_msg_get_header (msg);
587 to = tny_header_get_to (header);
588 cc = tny_header_get_cc (header);
589 bcc = tny_header_get_bcc (header);
590 subject = tny_header_get_subject (header);
591 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
594 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
596 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
597 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
598 gtk_widget_show (priv->cc_caption);
599 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
600 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
601 gtk_widget_hide (priv->cc_caption);
604 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
605 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
606 gtk_widget_show (priv->bcc_caption);
607 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
608 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
609 gtk_widget_hide (priv->bcc_caption);
612 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
613 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
616 update_window_title (self);
618 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
619 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
620 body = modest_tny_msg_get_body (msg, TRUE);
622 if ((body == NULL)||(body[0] == '\0')) {
624 body = modest_text_utils_convert_to_html ("");
626 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
627 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
630 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
633 /* Get the default format required from configuration */
634 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
635 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
638 /* Set the default focus depending on having already a To: field or not */
639 if ((!to)||(*to == '\0')) {
640 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
642 gtk_widget_grab_focus (priv->msg_body);
645 /* TODO: lower priority, select in the From: combo to the
646 value that comes from msg <- not sure, should it be
649 /* Add attachments to the view */
650 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
651 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
652 if (priv->attachments == NULL) {
653 gtk_widget_hide (priv->attachments_caption);
655 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
656 gtk_widget_show_all (priv->attachments_caption);
659 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
660 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
662 reset_modified (self);
664 update_dimmed (self);
665 text_buffer_can_undo (priv->text_buffer, FALSE, self);
667 priv->draft_msg = g_object_ref(msg);
671 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
674 GList *item_children, *node;
675 GtkWidget *bin_child;
677 bin_child = gtk_bin_get_child (GTK_BIN(item));
679 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
681 for (node = item_children; node != NULL; node = g_list_next (node)) {
682 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
683 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
686 g_list_free (item_children);
690 menu_tool_button_dont_expand (GtkMenuToolButton *item)
693 GList *item_children, *node;
695 box = gtk_bin_get_child (GTK_BIN (item));
696 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
697 item_children = gtk_container_get_children (GTK_CONTAINER (box));
699 for (node = item_children; node != NULL; node = g_list_next (node)) {
700 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
701 if (GTK_IS_TOGGLE_BUTTON (node->data))
702 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
703 else if (GTK_IS_BUTTON (node->data))
704 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
706 g_list_free (item_children);
711 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
713 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
714 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
715 GtkWidget *placeholder;
716 GtkWidget *tool_item;
721 GtkWidget *sizes_menu;
722 GtkWidget *fonts_menu;
723 GSList *radio_group = NULL;
728 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
729 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
731 /* should we hide the toolbar? */
732 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
733 gtk_widget_hide (parent_priv->toolbar);
735 /* Font color placeholder */
736 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
737 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
740 tool_item = GTK_WIDGET (gtk_tool_item_new ());
741 priv->font_color_button = hildon_color_button_new ();
742 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
743 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
744 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
745 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
746 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
747 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
748 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
750 /* Font size and face placeholder */
751 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
752 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
754 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
755 priv->size_tool_button_label = gtk_label_new (NULL);
756 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
757 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
758 size_text,"</span>", NULL);
759 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
761 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
762 sizes_menu = gtk_menu_new ();
763 priv->size_items_group = NULL;
765 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
766 GtkWidget *size_menu_item;
768 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
769 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
770 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
771 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
772 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
773 gtk_widget_show (size_menu_item);
775 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
779 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
780 GtkWidget *item = (GtkWidget *) node->data;
781 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
785 priv->size_items_group = g_slist_reverse (priv->size_items_group);
786 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
787 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
788 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
789 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
790 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
791 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
792 priv->font_size_toolitem = tool_item;
795 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
796 priv->font_tool_button_label = gtk_label_new (NULL);
797 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
798 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
800 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
801 fonts_menu = gtk_menu_new ();
802 priv->font_items_group = NULL;
804 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
805 GtkWidget *font_menu_item;
806 GtkWidget *child_label;
808 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
809 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
810 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
811 wp_get_font_name (font_index), "</span>", NULL);
812 gtk_label_set_markup (GTK_LABEL (child_label), markup);
815 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
816 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
817 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
818 gtk_widget_show (font_menu_item);
820 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
823 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
824 GtkWidget *item = (GtkWidget *) node->data;
825 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
828 priv->font_items_group = g_slist_reverse (priv->font_items_group);
829 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
830 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
831 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
832 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
833 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
834 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
835 priv->font_face_toolitem = tool_item;
837 /* Set expand and homogeneous for remaining items */
838 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
839 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
840 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
841 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
842 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
843 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
844 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
845 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
846 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
854 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
857 ModestWindowPrivate *parent_priv;
858 ModestMsgEditWindowPrivate *priv;
859 GtkActionGroup *action_group;
860 GError *error = NULL;
861 GdkPixbuf *window_icon = NULL;
864 gboolean prefer_formatted;
866 ModestPair *account_pair = NULL;
868 g_return_val_if_fail (msg, NULL);
869 g_return_val_if_fail (account_name, NULL);
871 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
873 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
874 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
876 parent_priv->ui_manager = gtk_ui_manager_new();
877 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
878 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
880 /* Add common actions */
881 gtk_action_group_add_actions (action_group,
882 modest_msg_edit_action_entries,
883 G_N_ELEMENTS (modest_msg_edit_action_entries),
885 gtk_action_group_add_toggle_actions (action_group,
886 modest_msg_edit_toggle_action_entries,
887 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
889 gtk_action_group_add_radio_actions (action_group,
890 modest_msg_edit_alignment_radio_action_entries,
891 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
893 G_CALLBACK (modest_ui_actions_on_change_justify),
895 gtk_action_group_add_radio_actions (action_group,
896 modest_msg_edit_zoom_action_entries,
897 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
899 G_CALLBACK (modest_ui_actions_on_change_zoom),
901 gtk_action_group_add_radio_actions (action_group,
902 modest_msg_edit_priority_action_entries,
903 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
905 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
907 gtk_action_group_add_radio_actions (action_group,
908 modest_msg_edit_file_format_action_entries,
909 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
910 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
911 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
913 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
914 g_object_unref (action_group);
916 /* Load the UI definition */
917 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
920 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
921 g_clear_error (&error);
924 /* Add accelerators */
925 gtk_window_add_accel_group (GTK_WINDOW (obj),
926 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
929 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
930 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
933 init_window (MODEST_MSG_EDIT_WINDOW(obj));
935 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
937 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
939 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
941 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
943 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
945 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
946 if (account_pair != NULL)
947 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
949 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
951 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
953 /* Set window icon */
954 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
955 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
957 /* Dim at start clipboard actions */
958 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
959 gtk_action_set_sensitive (action, FALSE);
960 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
961 gtk_action_set_sensitive (action, FALSE);
962 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
963 gtk_action_set_sensitive (action, FALSE);
965 /* Update select all */
966 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
967 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
968 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
969 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
970 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
972 /* set initial state of cc and bcc */
973 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
974 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
975 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
976 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
977 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
978 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
980 /* Setup the file format */
981 conf = modest_runtime_get_conf ();
982 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
984 g_clear_error (&error);
985 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
987 file_format = (prefer_formatted) ?
988 MODEST_FILE_FORMAT_FORMATTED_TEXT :
989 MODEST_FILE_FORMAT_PLAIN_TEXT;
990 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
992 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
994 return (ModestWindow*) obj;
998 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1000 GString **string_buffer = (GString **) user_data;
1002 *string_buffer = g_string_append (*string_buffer, buffer);
1008 * @result: A new string which should be freed with g_free().
1011 get_formatted_data (ModestMsgEditWindow *edit_window)
1013 ModestMsgEditWindowPrivate *priv;
1014 GString *string_buffer = g_string_new ("");
1016 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1018 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1020 return g_string_free (string_buffer, FALSE);
1025 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1028 const gchar *account_name;
1029 ModestMsgEditWindowPrivate *priv;
1031 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1033 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1035 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1036 g_return_val_if_fail (account_name, NULL);
1039 /* don't free these (except from) */
1040 data = g_slice_new0 (MsgData);
1041 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1043 data->account_name = g_strdup (account_name);
1044 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1045 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1046 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1047 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1048 if (priv->draft_msg) {
1049 data->draft_msg = g_object_ref (priv->draft_msg);
1051 data->draft_msg = NULL;
1054 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1056 gtk_text_buffer_get_bounds (buf, &b, &e);
1057 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1059 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1060 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1062 data->html_body = NULL;
1064 data->attachments = priv->attachments; /* TODO: copy and free ? */
1065 data->priority_flags = priv->priority_flags;
1070 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1072 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1075 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1083 g_free (data->subject);
1084 g_free (data->plain_body);
1085 g_free (data->html_body);
1086 if (data->draft_msg != NULL) {
1087 g_object_unref (data->draft_msg);
1088 data->draft_msg = NULL;
1090 g_free (data->account_name);
1092 /* TODO: Free data->attachments? */
1094 g_slice_free (MsgData, data);
1098 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1101 ModestMsgEditWindowPrivate *priv = NULL;
1102 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1104 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1106 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1108 return MODEST_MSG_EDIT_FORMAT_HTML;
1110 return MODEST_MSG_EDIT_FORMAT_TEXT;
1114 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1115 ModestMsgEditFormat format)
1117 ModestMsgEditWindowPrivate *priv;
1119 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1120 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1123 case MODEST_MSG_EDIT_FORMAT_HTML:
1124 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1126 case MODEST_MSG_EDIT_FORMAT_TEXT:
1127 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1130 g_return_if_reached ();
1134 ModestMsgEditFormatState *
1135 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1137 ModestMsgEditFormatState *format_state = NULL;
1138 ModestMsgEditWindowPrivate *priv;
1139 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1141 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1142 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1144 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1146 format_state = g_new0 (ModestMsgEditFormatState, 1);
1147 format_state->bold = buffer_format->bold&0x1;
1148 format_state->italics = buffer_format->italic&0x1;
1149 format_state->bullet = buffer_format->bullet&0x1;
1150 format_state->color = buffer_format->color;
1151 format_state->font_size = buffer_format->font_size;
1152 format_state->font_family = wp_get_font_name (buffer_format->font);
1153 format_state->justification = buffer_format->justification;
1154 g_free (buffer_format);
1156 return format_state;
1161 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1162 const ModestMsgEditFormatState *format_state)
1164 ModestMsgEditWindowPrivate *priv;
1165 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1166 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1167 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1168 g_return_if_fail (format_state != NULL);
1170 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1171 gtk_widget_grab_focus (priv->msg_body);
1172 buffer_format->bold = (format_state->bold != FALSE);
1173 buffer_format->italic = (format_state->italics != FALSE);
1174 buffer_format->color = format_state->color;
1175 buffer_format->font_size = format_state->font_size;
1176 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1177 buffer_format->justification = format_state->justification;
1178 buffer_format->bullet = format_state->bullet;
1180 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1182 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1183 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1184 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1185 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1186 buffer_format->cs.font = (buffer_format->font != current_format->font);
1187 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1188 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1190 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1191 if (buffer_format->cs.bold) {
1192 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1194 if (buffer_format->cs.italic) {
1195 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1197 if (buffer_format->cs.color) {
1198 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1200 if (buffer_format->cs.font_size) {
1201 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1203 if (buffer_format->cs.justification) {
1204 switch (buffer_format->justification) {
1205 case GTK_JUSTIFY_LEFT:
1206 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1208 case GTK_JUSTIFY_CENTER:
1209 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1211 case GTK_JUSTIFY_RIGHT:
1212 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1219 if (buffer_format->cs.font) {
1220 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1222 if (buffer_format->cs.bullet) {
1223 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1225 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1226 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1228 g_free (current_format);
1233 toggle_action_set_active_block_notify (GtkToggleAction *action,
1236 GSList *proxies = NULL;
1238 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1239 proxies != NULL; proxies = g_slist_next (proxies)) {
1240 GtkWidget *widget = (GtkWidget *) proxies->data;
1241 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1244 gtk_toggle_action_set_active (action, value);
1246 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1247 proxies != NULL; proxies = g_slist_next (proxies)) {
1248 GtkWidget *widget = (GtkWidget *) proxies->data;
1249 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1254 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1256 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1258 ModestWindowPrivate *parent_priv;
1259 ModestMsgEditWindowPrivate *priv;
1260 GtkWidget *new_size_menuitem;
1261 GtkWidget *new_font_menuitem;
1263 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1264 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1266 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1267 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1268 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1269 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1271 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1272 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1273 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1276 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1278 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1279 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1281 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1282 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1284 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1285 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1287 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1288 G_CALLBACK (modest_msg_edit_window_color_button_change),
1290 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1291 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1292 G_CALLBACK (modest_msg_edit_window_color_button_change),
1295 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1296 buffer_format->font_size))->data);
1297 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1301 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1302 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1303 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1305 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1306 G_CALLBACK (modest_msg_edit_window_size_change),
1308 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1309 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1310 G_CALLBACK (modest_msg_edit_window_size_change),
1314 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1315 buffer_format->font))->data);
1316 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1320 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1321 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1322 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1324 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1325 G_CALLBACK (modest_msg_edit_window_font_change),
1327 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1328 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1329 G_CALLBACK (modest_msg_edit_window_font_change),
1333 g_free (buffer_format);
1339 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1342 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1343 ModestMsgEditWindowPrivate *priv;
1344 GtkWidget *dialog = NULL;
1346 const GdkColor *new_color = NULL;
1348 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1349 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1351 #ifdef MODEST_HILDON_VERSION_0
1352 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1353 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1355 dialog = hildon_color_chooser_new ();
1356 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1357 #endif /*MODEST_HILDON_VERSION_0*/
1358 g_free (buffer_format);
1360 response = gtk_dialog_run (GTK_DIALOG (dialog));
1362 case GTK_RESPONSE_OK: {
1363 #ifdef MODEST_HILDON_VERSION_0
1364 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1367 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1369 #endif /*MODEST_HILDON_VERSION_0*/
1376 gtk_widget_destroy (dialog);
1378 if (new_color != NULL)
1379 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1384 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1387 ModestMsgEditWindowPrivate *priv;
1388 GtkWidget *dialog = NULL;
1390 GdkColor *old_color = NULL;
1391 const GdkColor *new_color = NULL;
1393 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1394 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1396 #ifdef MODEST_HILDON_VERSION_0
1397 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1398 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1400 dialog = hildon_color_chooser_new ();
1401 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1402 #endif /*MODEST_HILDON_VERSION_9*/
1404 response = gtk_dialog_run (GTK_DIALOG (dialog));
1406 case GTK_RESPONSE_OK: {
1407 #ifdef MODEST_HILDON_VERSION_0
1408 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1411 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1413 #endif /*MODEST_HILDON_VERSION_0*/
1419 gtk_widget_destroy (dialog);
1421 if (new_color != NULL)
1422 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1428 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1431 ModestMsgEditWindowPrivate *priv;
1432 GtkWidget *dialog = NULL;
1434 GSList *uris = NULL;
1435 GSList *uri_node = NULL;
1437 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1439 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1440 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1441 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1443 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1445 response = gtk_dialog_run (GTK_DIALOG (dialog));
1447 case GTK_RESPONSE_OK:
1448 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1453 gtk_widget_destroy (dialog);
1455 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1457 GnomeVFSHandle *handle = NULL;
1458 GnomeVFSResult result;
1459 GtkTextIter position;
1460 GtkTextMark *insert_mark;
1462 uri = (const gchar *) uri_node->data;
1463 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1464 if (result == GNOME_VFS_OK) {
1465 GdkPixbufLoader *loader;
1467 GnomeVFSFileInfo info;
1468 gchar *filename, *basename;
1469 TnyMimePart *mime_part;
1472 const gchar *mime_type = NULL;
1474 filename = g_filename_from_uri (uri, NULL, NULL);
1475 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1477 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1479 mime_part = tny_platform_factory_new_mime_part
1480 (modest_runtime_get_platform_factory ());
1481 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1483 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1485 content_id = g_strdup_printf ("%d", priv->last_cid);
1486 tny_mime_part_set_content_id (mime_part, content_id);
1487 g_free (content_id);
1490 basename = g_path_get_basename (filename);
1491 tny_mime_part_set_filename (mime_part, basename);
1494 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1495 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1497 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1498 gtk_widget_show_all (priv->attachments_caption);
1499 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1502 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1503 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1504 unsigned char read_buffer[128];
1506 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1507 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1510 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1511 g_object_ref (pixbuf);
1512 gdk_pixbuf_loader_close (loader, NULL);
1513 g_object_unref (loader);
1515 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1516 GdkPixbuf *new_pixbuf;
1518 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1519 gdk_pixbuf_get_width (pixbuf);
1520 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1521 g_object_unref (pixbuf);
1522 pixbuf = new_pixbuf;
1525 if (pixbuf != NULL) {
1526 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1527 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1528 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1537 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1540 ModestMsgEditWindowPrivate *priv;
1541 GtkWidget *dialog = NULL;
1543 GSList *uris = NULL;
1546 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1548 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1549 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1551 response = gtk_dialog_run (GTK_DIALOG (dialog));
1553 case GTK_RESPONSE_OK:
1554 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1559 gtk_widget_destroy (dialog);
1561 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1563 GnomeVFSHandle *handle = NULL;
1564 GnomeVFSResult result;
1566 uri = (const gchar *) uri_node->data;
1567 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1568 if (result == GNOME_VFS_OK) {
1569 TnyMimePart *mime_part;
1571 const gchar *mime_type = NULL;
1575 GnomeVFSFileInfo info;
1577 filename = g_filename_from_uri (uri, NULL, NULL);
1579 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1580 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1581 mime_part = tny_platform_factory_new_mime_part
1582 (modest_runtime_get_platform_factory ());
1583 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1585 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1587 content_id = g_strdup_printf ("%d", priv->last_cid);
1588 tny_mime_part_set_content_id (mime_part, content_id);
1589 g_free (content_id);
1592 basename = g_path_get_basename (filename);
1593 tny_mime_part_set_filename (mime_part, basename);
1596 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1597 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1599 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1600 gtk_widget_show_all (priv->attachments_caption);
1601 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1606 g_slist_foreach (uris, (GFunc) g_free, NULL);
1607 g_slist_free (uris);
1611 modest_msg_edit_window_attach_file_noninteractive (
1612 ModestMsgEditWindow *window,
1613 const gchar *file_uri)
1616 ModestMsgEditWindowPrivate *priv;
1618 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1620 if (file_uri && strlen(file_uri)) {
1623 /* TODO: We should probably try to use only the URI,
1624 * instead of using a filename.
1626 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1628 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1631 file_id = g_open (filename, O_RDONLY, 0);
1632 if (file_id != -1) {
1633 TnyMimePart *mime_part;
1635 const gchar *mime_type;
1638 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1639 mime_type = gnome_vfs_get_mime_type(filename);
1641 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1643 mime_part = tny_platform_factory_new_mime_part
1644 (modest_runtime_get_platform_factory ());
1645 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1647 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1649 content_id = g_strdup_printf ("%d", priv->last_cid);
1650 tny_mime_part_set_content_id (mime_part, content_id);
1651 g_free (content_id);
1654 basename = g_path_get_basename (filename);
1655 tny_mime_part_set_filename (mime_part, basename);
1658 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1659 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1661 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1662 gtk_widget_show_all (priv->attachments_caption);
1663 } else if (file_id == -1) {
1665 g_warning("file to be attached does not exist: %s", filename);
1673 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1676 ModestMsgEditWindowPrivate *priv;
1677 gboolean clean_list = FALSE;
1679 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1680 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1682 if (att_list == NULL) {
1683 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1687 if (att_list == NULL) {
1688 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1690 GtkWidget *confirmation_dialog = NULL;
1691 gboolean dialog_response;
1693 gchar *message = NULL;
1694 const gchar *filename = NULL;
1696 if (att_list->next == NULL) {
1697 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1701 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1702 att_list->next == NULL), filename);
1703 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1705 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1706 gtk_widget_destroy (confirmation_dialog);
1707 if (!dialog_response) {
1709 g_list_free (att_list);
1712 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1714 for (node = att_list; node != NULL; node = g_list_next (node)) {
1715 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1716 const gchar *att_id;
1717 priv->attachments = g_list_remove (priv->attachments, mime_part);
1719 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1721 if (priv->attachments == NULL)
1722 gtk_widget_hide (priv->attachments_caption);
1723 att_id = tny_mime_part_get_content_id (mime_part);
1725 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1727 g_object_unref (mime_part);
1728 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1733 g_list_free (att_list);
1737 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1740 ModestMsgEditWindowPrivate *priv;
1741 GdkColor *new_color;
1742 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1744 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1745 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1748 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1750 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1752 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1754 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1759 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1762 ModestMsgEditWindowPrivate *priv;
1763 gint new_size_index;
1764 ModestMsgEditWindow *window;
1767 window = MODEST_MSG_EDIT_WINDOW (userdata);
1768 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1769 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1771 if (gtk_check_menu_item_get_active (menu_item)) {
1773 WPTextBufferFormat format;
1775 memset (&format, 0, sizeof (format));
1776 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1778 label = gtk_bin_get_child (GTK_BIN (menu_item));
1780 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1781 format.cs.font_size = TRUE;
1782 format.cs.text_position = TRUE;
1783 format.cs.font = TRUE;
1784 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1785 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1787 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1788 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1789 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1791 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1792 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1793 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1799 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1802 ModestMsgEditWindowPrivate *priv;
1803 gint new_font_index;
1804 ModestMsgEditWindow *window;
1807 window = MODEST_MSG_EDIT_WINDOW (userdata);
1808 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1809 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1811 if (gtk_check_menu_item_get_active (menu_item)) {
1814 label = gtk_bin_get_child (GTK_BIN (menu_item));
1816 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1818 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1819 (gpointer) new_font_index))
1820 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1822 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1823 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1824 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1830 modest_msg_edit_window_set_zoom (ModestWindow *window,
1833 ModestMsgEditWindowPrivate *priv;
1834 ModestWindowPrivate *parent_priv;
1835 GtkRadioAction *zoom_radio_action;
1837 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1839 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1840 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1841 priv->zoom_level = zoom;
1842 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1844 /* Zoom level menu options should be updated with the current zoom level */
1845 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1846 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1847 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1848 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1849 /* FIXME: Not availible before Gtk 2.10 */
1851 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1856 modest_msg_edit_window_get_zoom (ModestWindow *window)
1858 ModestMsgEditWindowPrivate *priv;
1860 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1862 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1863 return priv->zoom_level;
1867 zoom_allowed (ModestMsgEditWindow *window)
1871 focus = gtk_window_get_focus (GTK_WINDOW (window));
1872 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1876 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1878 ModestWindowPrivate *parent_priv;
1879 GtkRadioAction *zoom_radio_action;
1880 GSList *group, *node;
1882 /* First we check if the text view is focused. If not, zooming is not allowed */
1883 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1884 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1888 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1889 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1890 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1892 group = gtk_radio_action_get_group (zoom_radio_action);
1894 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1895 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1899 for (node = group; node != NULL; node = g_slist_next (node)) {
1900 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1901 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1909 modest_msg_edit_window_zoom_minus (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 for (node = group; node != NULL; node = g_slist_next (node)) {
1928 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1929 if (node->next != NULL) {
1930 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1933 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1941 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1943 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1944 ModestWindowPrivate *parent_priv;
1945 ModestWindowMgr *mgr;
1946 gboolean is_fullscreen;
1947 GtkAction *fs_toggle_action;
1950 mgr = modest_runtime_get_window_mgr ();
1951 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1953 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1955 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1956 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1957 if (is_fullscreen != active)
1958 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1966 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1968 ModestWindowPrivate *parent_priv;
1969 GtkAction *fs_toggle_action;
1972 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1974 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1975 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1976 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1980 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1983 ModestMsgEditWindowPrivate *priv = NULL;
1984 const gchar *recipients;
1985 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1987 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1988 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1989 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
1990 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
1991 gtk_widget_show (priv->cc_caption);
1993 gtk_widget_hide (priv->cc_caption);
1994 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1998 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2001 ModestMsgEditWindowPrivate *priv = NULL;
2002 const gchar *recipients;
2003 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2005 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2006 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2007 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2008 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2009 gtk_widget_show (priv->bcc_caption);
2011 gtk_widget_hide (priv->bcc_caption);
2012 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2016 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2017 ModestRecptEditor *editor)
2019 ModestMsgEditWindowPrivate *priv;
2021 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2022 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2023 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2025 if (editor == NULL) {
2026 GtkWidget *view_focus;
2027 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2029 /* This code should be kept in sync with ModestRecptEditor. The
2030 textview inside the recpt editor is the one that really gets the
2031 focus. As it's inside a scrolled window, and this one inside the
2032 hbox recpt editor inherits from, we'll need to go up in the
2033 hierarchy to know if the text view is part of the recpt editor
2034 or if it's a different text entry */
2036 if (gtk_widget_get_parent (view_focus)) {
2037 GtkWidget *first_parent;
2039 first_parent = gtk_widget_get_parent (view_focus);
2040 if (gtk_widget_get_parent (first_parent) &&
2041 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2042 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2047 editor = MODEST_RECPT_EDITOR (priv->to_field);
2051 modest_address_book_select_addresses (editor);
2056 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2058 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2060 modest_msg_edit_window_open_addressbook (window, NULL);
2064 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2065 gboolean show_toolbar)
2067 ModestWindowPrivate *parent_priv;
2069 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2070 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2072 /* FIXME: we can not just use the code of
2073 modest_msg_edit_window_setup_toolbar because it has a
2074 mixture of both initialization and creation code. */
2077 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2079 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2083 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2084 TnyHeaderFlags priority_flags)
2086 ModestMsgEditWindowPrivate *priv;
2087 ModestWindowPrivate *parent_priv;
2089 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2091 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2092 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2093 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2095 if (priv->priority_flags != priority_flags) {
2096 GtkAction *priority_action = NULL;
2098 priv->priority_flags = priority_flags;
2100 switch (priority_flags) {
2101 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2102 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2103 gtk_widget_show (priv->priority_icon);
2104 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2105 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2107 case TNY_HEADER_FLAG_LOW_PRIORITY:
2108 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2109 gtk_widget_show (priv->priority_icon);
2110 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2111 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2114 gtk_widget_hide (priv->priority_icon);
2115 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2116 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2119 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2120 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2125 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2128 ModestMsgEditWindowPrivate *priv;
2129 gint current_format;
2131 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2133 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2135 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2136 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2138 if (current_format != file_format) {
2139 switch (file_format) {
2140 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2141 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2143 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2147 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2148 response = gtk_dialog_run (GTK_DIALOG (dialog));
2149 gtk_widget_destroy (dialog);
2150 if (response == GTK_RESPONSE_OK)
2151 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2155 update_dimmed (window);
2160 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2163 ModestMsgEditWindowPrivate *priv;
2164 WPTextBufferFormat oldfmt, fmt;
2165 gint old_position = 0;
2169 GdkColor *color = NULL;
2170 gboolean bold, bold_set, italic, italic_set;
2171 gboolean underline, underline_set;
2172 gboolean strikethrough, strikethrough_set;
2173 gboolean position_set;
2174 gboolean font_size_set, font_set, color_set;
2177 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2178 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2180 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2182 /* First we get the currently selected font information */
2183 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2184 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2186 switch (oldfmt.text_position) {
2187 case TEXT_POSITION_NORMAL:
2190 case TEXT_POSITION_SUPERSCRIPT:
2198 g_object_set (G_OBJECT (dialog),
2199 "bold", oldfmt.bold != FALSE,
2200 "bold-set", !oldfmt.cs.bold,
2201 "underline", oldfmt.underline != FALSE,
2202 "underline-set", !oldfmt.cs.underline,
2203 "italic", oldfmt.italic != FALSE,
2204 "italic-set", !oldfmt.cs.italic,
2205 "strikethrough", oldfmt.strikethrough != FALSE,
2206 "strikethrough-set", !oldfmt.cs.strikethrough,
2207 "color", &oldfmt.color,
2208 "color-set", !oldfmt.cs.color,
2209 "size", wp_font_size[oldfmt.font_size],
2210 "size-set", !oldfmt.cs.font_size,
2211 "position", old_position,
2212 "position-set", !oldfmt.cs.text_position,
2213 "family", wp_get_font_name (oldfmt.font),
2214 "family-set", !oldfmt.cs.font,
2217 gtk_widget_show_all (dialog);
2218 response = gtk_dialog_run (GTK_DIALOG (dialog));
2219 if (response == GTK_RESPONSE_OK) {
2221 g_object_get( dialog,
2223 "bold-set", &bold_set,
2224 "underline", &underline,
2225 "underline-set", &underline_set,
2227 "italic-set", &italic_set,
2228 "strikethrough", &strikethrough,
2229 "strikethrough-set", &strikethrough_set,
2231 "color-set", &color_set,
2233 "size-set", &font_size_set,
2234 "family", &font_name,
2235 "family-set", &font_set,
2236 "position", &position,
2237 "position-set", &position_set,
2242 if (response == GTK_RESPONSE_OK) {
2243 memset(&fmt, 0, sizeof(fmt));
2249 fmt.italic = italic;
2250 fmt.cs.italic = TRUE;
2252 if (underline_set) {
2253 fmt.underline = underline;
2254 fmt.cs.underline = TRUE;
2256 if (strikethrough_set) {
2257 fmt.strikethrough = strikethrough;
2258 fmt.cs.strikethrough = TRUE;
2263 ? TEXT_POSITION_NORMAL
2264 : ( ( position == 1 )
2265 ? TEXT_POSITION_SUPERSCRIPT
2266 : TEXT_POSITION_SUBSCRIPT );
2267 fmt.cs.text_position = TRUE;
2271 fmt.cs.color = TRUE;
2274 fmt.font = wp_get_font_index(font_name,
2279 if (font_size_set) {
2280 fmt.font_size = wp_get_font_size_index(
2281 font_size, DEFAULT_FONT_SIZE);
2282 fmt.cs.font_size = TRUE;
2284 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2286 gtk_widget_destroy (dialog);
2288 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2292 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2294 ModestMsgEditWindowPrivate *priv;
2296 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2297 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2299 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2301 update_dimmed (window);
2306 update_dimmed (ModestMsgEditWindow *window)
2308 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2309 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2313 gboolean editor_focused;
2315 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2316 editor_focused = gtk_widget_is_focus (priv->msg_body);
2318 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2319 gtk_action_set_sensitive (action, rich_text && editor_focused);
2320 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2321 gtk_action_set_sensitive (action, rich_text && editor_focused);
2322 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2323 gtk_action_set_sensitive (action, rich_text && editor_focused);
2324 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2325 gtk_action_set_sensitive (action, rich_text && editor_focused);
2326 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2327 gtk_action_set_sensitive (action, rich_text && editor_focused);
2328 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2329 gtk_action_set_sensitive (action, rich_text && editor_focused);
2330 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2331 gtk_action_set_sensitive (action, rich_text && editor_focused);
2332 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2333 gtk_action_set_sensitive (action, rich_text && editor_focused);
2334 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2335 gtk_action_set_sensitive (action, rich_text && editor_focused);
2336 widget = priv->font_color_button;
2337 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2338 widget = priv->font_size_toolitem;
2339 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2340 widget = priv->font_face_toolitem;
2341 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2345 setup_insensitive_handlers (ModestMsgEditWindow *window)
2347 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2348 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2351 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2352 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2353 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2354 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2356 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2357 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2358 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2359 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2360 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2361 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2362 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2363 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2364 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2365 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2366 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2367 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2368 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2369 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2370 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2371 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2372 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2373 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2374 widget = priv->font_color_button;
2375 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2376 widget = priv->font_size_toolitem;
2377 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2378 widget = priv->font_face_toolitem;
2379 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2381 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2382 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2383 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2384 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2386 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2387 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (paste_insensitive_press), window);
2391 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2393 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2396 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2397 gtk_action_set_sensitive (action, can_undo);
2401 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2404 GtkTextIter match_start, match_end;
2406 if (image_id == NULL)
2409 gtk_text_buffer_get_start_iter (buffer, &iter);
2411 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2412 GSList *tags = gtk_text_iter_get_tags (&match_start);
2414 for (node = tags; node != NULL; node = g_slist_next (node)) {
2415 GtkTextTag *tag = (GtkTextTag *) node->data;
2416 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2417 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2418 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2420 offset = gtk_text_iter_get_offset (&match_start);
2421 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2422 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2426 gtk_text_iter_forward_char (&iter);
2431 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2433 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2434 GtkTextIter real_start, real_end;
2435 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2437 if (gtk_text_iter_compare (start, end) > 0) {
2441 real_start = *start;
2445 GSList *tags = gtk_text_iter_get_tags (&real_start);
2447 for (node = tags; node != NULL; node = g_slist_next (node)) {
2448 GtkTextTag *tag = (GtkTextTag *) node->data;
2449 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2450 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2452 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2454 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2457 } while (gtk_text_iter_forward_char (&real_start)&&
2458 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2462 msg_body_focus (GtkWidget *focus,
2463 GdkEventFocus *event,
2467 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2472 recpt_field_changed (GtkTextBuffer *buffer,
2473 ModestMsgEditWindow *editor)
2475 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2476 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2477 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2478 gboolean dim = FALSE;
2481 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2482 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2483 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2485 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2486 gtk_text_buffer_get_char_count (cc_buffer) +
2487 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2489 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2490 gtk_action_set_sensitive (action, !dim);
2491 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2492 gtk_action_set_sensitive (action, !dim);
2496 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2498 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2502 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2504 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2508 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2510 ModestWindowPrivate *parent_priv;
2511 ModestMsgEditWindowPrivate *priv;
2512 GList *selected_attachments = NULL;
2513 gint n_att_selected = 0;
2515 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2516 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2518 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2519 n_att_selected = g_list_length (selected_attachments);
2520 g_list_free (selected_attachments);
2522 if (n_att_selected > 1)
2523 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2524 else if (n_att_selected == 0)
2525 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2530 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2532 gboolean rich_text, editor_focused;
2534 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2535 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2536 editor_focused = gtk_widget_is_focus (priv->msg_body);
2539 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2540 else if (!editor_focused)
2541 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2545 reset_modified (ModestMsgEditWindow *editor)
2547 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2548 GtkTextBuffer *buffer;
2550 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2551 gtk_text_buffer_set_modified (buffer, FALSE);
2552 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2553 gtk_text_buffer_set_modified (buffer, FALSE);
2554 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2555 gtk_text_buffer_set_modified (buffer, FALSE);
2556 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2560 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2562 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2563 GtkTextBuffer *buffer;
2565 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2566 if (gtk_text_buffer_get_modified (buffer))
2568 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2569 if (gtk_text_buffer_get_modified (buffer))
2571 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2572 if (gtk_text_buffer_get_modified (buffer))
2574 if (gtk_text_buffer_get_modified (priv->text_buffer))
2581 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2583 ModestMsgEditWindowPrivate *priv = NULL;
2585 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2586 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2588 /* check if there's no recipient added */
2589 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2590 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2591 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2592 /* no recipient contents, then select contacts */
2593 modest_msg_edit_window_open_addressbook (window, NULL);
2597 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2599 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2601 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2604 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2611 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2612 ModestMsgEditWindow *window)
2614 modest_msg_edit_window_attach_file (window);
2618 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2620 ModestMsgEditWindow *window)
2622 ModestWindowPrivate *parent_priv;
2623 ModestMsgEditWindowPrivate *priv;
2627 GList *selected_attachments = NULL;
2628 gint n_att_selected = 0;
2630 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2631 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2632 selection = gtk_clipboard_wait_for_text (clipboard);
2633 focused = gtk_window_get_focus (GTK_WINDOW (window));
2635 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2636 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2637 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2638 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2640 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2641 n_att_selected = g_list_length (selected_attachments);
2642 g_list_free (selected_attachments);
2644 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2645 gtk_action_set_sensitive (action, n_att_selected == 1);
2648 update_paste_dimming (window);
2652 update_window_title (ModestMsgEditWindow *window)
2654 ModestMsgEditWindowPrivate *priv = NULL;
2655 const gchar *subject;
2657 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2658 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2659 if (subject == NULL || subject[0] == '\0')
2660 subject = _("mail_va_new_email");
2662 gtk_window_set_title (GTK_WINDOW (window), subject);
2667 subject_field_changed (GtkEditable *editable,
2668 ModestMsgEditWindow *window)
2670 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2671 update_window_title (window);
2672 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2676 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2679 ModestMsgEditWindowPrivate *priv = NULL;
2681 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2682 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2684 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2686 gtk_widget_show_all (priv->find_toolbar);
2687 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2689 gtk_widget_hide_all (priv->find_toolbar);
2690 gtk_widget_grab_focus (priv->msg_body);
2696 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2698 GtkTextIter *match_start,
2699 GtkTextIter *match_end)
2701 GtkTextIter end_iter;
2702 gchar *str_casefold;
2705 gchar *range_casefold;
2708 gboolean result = FALSE;
2715 gtk_text_iter_forward_to_end (&end_iter);
2717 str_casefold = g_utf8_casefold (str, -1);
2718 str_chars_n = strlen (str);
2720 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2721 range_casefold = g_utf8_casefold (range_text, -1);
2722 range_chars_n = strlen (range_casefold);
2724 if (range_chars_n < str_chars_n) {
2725 g_free (str_casefold);
2726 g_free (range_text);
2727 g_free (range_casefold);
2731 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2732 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2733 if (!g_utf8_collate (range_subtext, str_casefold)) {
2734 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2736 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2737 match_start, match_end, NULL);
2738 g_free (found_text);
2740 g_free (range_subtext);
2744 g_free (str_casefold);
2745 g_free (range_text);
2746 g_free (range_casefold);
2753 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2754 ModestMsgEditWindow *window)
2756 gchar *current_search = NULL;
2757 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2759 GtkTextIter selection_start, selection_end;
2760 GtkTextIter match_start, match_end;
2761 gboolean continue_search = FALSE;
2763 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2764 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2765 g_free (current_search);
2766 g_free (priv->last_search);
2767 priv->last_search = NULL;
2768 /* Information banner about empty search */
2769 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2773 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2774 continue_search = TRUE;
2776 g_free (priv->last_search);
2777 priv->last_search = g_strdup (current_search);
2780 if (continue_search) {
2781 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2782 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2783 &match_start, &match_end);
2785 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2787 GtkTextIter buffer_start;
2788 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2789 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2790 &match_start, &match_end);
2792 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2795 /* Mark as selected the string found in search */
2797 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2798 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2800 g_free (priv->last_search);
2801 priv->last_search = NULL;
2803 g_free (current_search);
2807 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2808 ModestMsgEditWindow *window)
2810 GtkToggleAction *toggle;
2811 ModestWindowPrivate *parent_priv;
2812 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2814 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2815 gtk_toggle_action_set_active (toggle, FALSE);
2820 update_paste_dimming (ModestMsgEditWindow *window)
2822 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2823 GtkAction *action = NULL;
2824 GtkClipboard *clipboard = NULL;
2828 focused = gtk_window_get_focus (GTK_WINDOW (window));
2830 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2831 active = gtk_clipboard_wait_is_text_available (clipboard);
2834 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2838 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2839 gtk_action_set_sensitive (action, active);
2844 paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2846 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (editor));
2848 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2849 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
2851 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
2857 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2859 ModestMsgEditWindow *window)
2861 update_paste_dimming (window);
2865 update_select_all_dimming (ModestMsgEditWindow *window)
2868 gboolean dimmed = FALSE;
2870 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2872 focused = gtk_window_get_focus (GTK_WINDOW (window));
2873 if (GTK_IS_ENTRY (focused)) {
2874 const gchar *current_text;
2875 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2876 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2877 } else if (GTK_IS_TEXT_VIEW (focused)) {
2878 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2879 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2880 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2883 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2884 gtk_action_set_sensitive (action, !dimmed);
2888 update_zoom_dimming (ModestMsgEditWindow *window)
2891 gboolean dimmed = FALSE;
2893 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2895 focused = gtk_window_get_focus (GTK_WINDOW (window));
2896 dimmed = ! WP_IS_TEXT_VIEW (focused);
2897 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2898 gtk_action_set_sensitive (action, !dimmed);
2902 edit_menu_activated (GtkAction *action,
2905 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2907 update_select_all_dimming (window);
2910 view_menu_activated (GtkAction *action,
2913 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2915 update_zoom_dimming (window);
2919 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2921 ModestMsgEditWindowPrivate *priv;
2923 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2928 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2931 ModestMsgEditWindowPrivate *priv;
2933 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);