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;
281 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
283 modest_window_class->save_state_func = save_state;
287 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
289 ModestMsgEditWindowPrivate *priv;
290 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
292 priv->msg_body = NULL;
293 priv->from_field = NULL;
294 priv->to_field = NULL;
295 priv->cc_field = NULL;
296 priv->bcc_field = NULL;
297 priv->subject_field = NULL;
298 priv->attachments = NULL;
300 priv->zoom_level = 1.0;
302 priv->cc_caption = NULL;
303 priv->bcc_caption = NULL;
305 priv->priority_flags = 0;
307 priv->find_toolbar = NULL;
308 priv->last_search = NULL;
310 priv->draft_msg = NULL;
311 priv->clipboard_change_handler_id = 0;
312 priv->system_clipboard_change_handler_id = 0;
317 /* FIXME: this is a dup from the one in gtk/ */
320 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
322 static ModestPairList*
323 get_transports (void)
325 GSList *transports = NULL;
327 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
328 GSList *accounts = modest_account_mgr_account_names (account_mgr,
329 TRUE /* only enabled accounts. */);
331 GSList *cursor = accounts;
333 gchar *account_name = cursor->data;
334 gchar *from_string = NULL;
336 from_string = modest_account_mgr_get_from_string (account_mgr,
340 if (from_string && account_name) {
341 gchar *name = account_name;
342 ModestPair *pair = modest_pair_new ((gpointer) name,
343 (gpointer) from_string , TRUE);
344 transports = g_slist_prepend (transports, pair);
347 cursor = cursor->next;
349 g_slist_free (accounts); /* only free the accounts, not the elements,
350 * because they are used in the pairlist */
356 init_window (ModestMsgEditWindow *obj)
358 GtkWidget *from_caption, *to_caption, *subject_caption;
359 GtkWidget *main_vbox;
360 ModestMsgEditWindowPrivate *priv;
362 GtkSizeGroup *size_group;
364 GtkWidget *subject_box;
365 GtkWidget *attachment_icon;
366 GtkWidget *window_box;
368 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
370 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
372 /* Note: This ModestPairList* must exist for as long as the combo
373 * that uses it, because the ModestComboBox uses the ID opaquely,
374 * so it can't know how to manage its memory. */
375 priv->from_field_protos = get_transports ();
377 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
379 priv->to_field = modest_recpt_editor_new ();
380 priv->cc_field = modest_recpt_editor_new ();
381 priv->bcc_field = modest_recpt_editor_new ();
382 subject_box = gtk_hbox_new (FALSE, 0);
383 priv->priority_icon = gtk_image_new ();
384 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
385 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
386 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
387 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
388 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
389 priv->add_attachment_button = gtk_button_new ();
390 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
391 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
392 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
393 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
394 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
395 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
396 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
397 priv->attachments_view = modest_attachments_view_new (NULL);
399 priv->header_box = gtk_vbox_new (FALSE, 0);
401 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
402 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
403 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
404 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
405 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
406 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
407 g_object_unref (size_group);
409 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
410 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
411 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
412 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
413 gtk_size_group_add_widget (size_group, priv->subject_field);
414 gtk_size_group_add_widget (size_group, priv->attachments_view);
415 g_object_unref (size_group);
417 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
418 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
419 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
420 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
421 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
422 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
423 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
426 priv->msg_body = wp_text_view_new ();
427 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
428 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
429 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
430 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
431 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
432 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
434 priv->find_toolbar = hildon_find_toolbar_new (NULL);
435 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
437 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
438 G_CALLBACK (text_buffer_refresh_attributes), obj);
439 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
440 G_CALLBACK (text_buffer_delete_range), obj);
441 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
442 G_CALLBACK (text_buffer_can_undo), obj);
443 g_signal_connect (G_OBJECT (obj), "window-state-event",
444 G_CALLBACK (modest_msg_edit_window_window_state_event),
446 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
447 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
448 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
449 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
450 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
451 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
453 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
454 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
456 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
457 G_CALLBACK (msg_body_focus), obj);
458 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
459 G_CALLBACK (msg_body_focus), obj);
460 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
461 "changed", G_CALLBACK (recpt_field_changed), obj);
462 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
463 "changed", G_CALLBACK (recpt_field_changed), obj);
464 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
465 "changed", G_CALLBACK (recpt_field_changed), obj);
466 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
467 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
469 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
470 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
472 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
473 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
474 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
476 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
478 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
479 frame = gtk_frame_new (NULL);
480 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
482 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
483 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
484 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
486 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
487 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
488 gtk_widget_hide (priv->cc_caption);
490 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
491 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
492 gtk_widget_hide (priv->bcc_caption);
495 window_box = gtk_vbox_new (FALSE, 0);
496 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
497 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
498 gtk_container_add (GTK_CONTAINER(obj), window_box);
499 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
500 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
503 TODO: scroll_area was never instantiated.
504 Stop building without warnings-as-errors. murrayc.
505 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
506 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
509 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
510 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
511 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
512 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
518 modest_msg_edit_window_finalize (GObject *obj)
520 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
522 if (priv->clipboard_change_handler_id > 0) {
523 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
524 priv->clipboard_change_handler_id = 0;
527 if (priv->system_clipboard_change_handler_id > 0) {
528 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
529 priv->system_clipboard_change_handler_id);
530 priv->system_clipboard_change_handler_id = 0;
533 if (priv->draft_msg != NULL) {
534 g_object_unref (priv->draft_msg);
535 priv->draft_msg = NULL;
538 /* This had to stay alive for as long as the combobox that used it: */
539 modest_pair_list_free (priv->from_field_protos);
541 G_OBJECT_CLASS(parent_class)->finalize (obj);
545 menubar_to_menu (GtkUIManager *ui_manager)
547 GtkWidget *main_menu;
551 /* Create new main menu */
552 main_menu = gtk_menu_new();
554 /* Get the menubar from the UI manager */
555 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
557 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
561 menu = GTK_WIDGET (iter->data);
562 gtk_widget_reparent(menu, main_menu);
564 iter = g_list_next (iter);
571 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
574 const gchar *to, *cc, *bcc, *subject;
576 ModestMsgEditWindowPrivate *priv;
578 TnyHeaderFlags priority_flags;
580 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
581 g_return_if_fail (TNY_IS_MSG (msg));
583 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
585 header = tny_msg_get_header (msg);
586 to = tny_header_get_to (header);
587 cc = tny_header_get_cc (header);
588 bcc = tny_header_get_bcc (header);
589 subject = tny_header_get_subject (header);
590 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
593 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
595 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
596 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
597 gtk_widget_show (priv->cc_caption);
598 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
599 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
600 gtk_widget_hide (priv->cc_caption);
603 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
604 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
605 gtk_widget_show (priv->bcc_caption);
606 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
607 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
608 gtk_widget_hide (priv->bcc_caption);
611 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
612 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
615 update_window_title (self);
617 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
618 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
619 body = modest_tny_msg_get_body (msg, TRUE);
621 if ((body == NULL)||(body[0] == '\0')) {
623 body = modest_text_utils_convert_to_html ("");
625 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
626 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
629 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
632 /* Get the default format required from configuration */
633 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
634 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
637 /* Set the default focus depending on having already a To: field or not */
638 if ((!to)||(*to == '\0')) {
639 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
641 gtk_widget_grab_focus (priv->msg_body);
644 /* TODO: lower priority, select in the From: combo to the
645 value that comes from msg <- not sure, should it be
648 /* Add attachments to the view */
649 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
650 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
651 if (priv->attachments == NULL) {
652 gtk_widget_hide (priv->attachments_caption);
654 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
655 gtk_widget_show_all (priv->attachments_caption);
658 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
659 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
661 reset_modified (self);
663 update_dimmed (self);
664 text_buffer_can_undo (priv->text_buffer, FALSE, self);
666 priv->draft_msg = g_object_ref(msg);
670 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
673 GList *item_children, *node;
674 GtkWidget *bin_child;
676 bin_child = gtk_bin_get_child (GTK_BIN(item));
678 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
680 for (node = item_children; node != NULL; node = g_list_next (node)) {
681 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
682 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
685 g_list_free (item_children);
689 menu_tool_button_dont_expand (GtkMenuToolButton *item)
692 GList *item_children, *node;
694 box = gtk_bin_get_child (GTK_BIN (item));
695 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
696 item_children = gtk_container_get_children (GTK_CONTAINER (box));
698 for (node = item_children; node != NULL; node = g_list_next (node)) {
699 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
700 if (GTK_IS_TOGGLE_BUTTON (node->data))
701 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
702 else if (GTK_IS_BUTTON (node->data))
703 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
705 g_list_free (item_children);
710 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
712 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
713 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
714 GtkWidget *placeholder;
715 GtkWidget *tool_item;
720 GtkWidget *sizes_menu;
721 GtkWidget *fonts_menu;
722 GSList *radio_group = NULL;
727 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
728 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
730 /* should we hide the toolbar? */
731 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
732 gtk_widget_hide (parent_priv->toolbar);
734 /* Font color placeholder */
735 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
736 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
739 tool_item = GTK_WIDGET (gtk_tool_item_new ());
740 priv->font_color_button = hildon_color_button_new ();
741 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
742 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
743 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
744 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
745 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
746 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
747 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
749 /* Font size and face placeholder */
750 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
751 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
753 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
754 priv->size_tool_button_label = gtk_label_new (NULL);
755 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
756 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
757 size_text,"</span>", NULL);
758 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
760 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
761 sizes_menu = gtk_menu_new ();
762 priv->size_items_group = NULL;
764 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
765 GtkWidget *size_menu_item;
767 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
768 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
769 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
770 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
771 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
772 gtk_widget_show (size_menu_item);
774 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
778 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
779 GtkWidget *item = (GtkWidget *) node->data;
780 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
784 priv->size_items_group = g_slist_reverse (priv->size_items_group);
785 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
786 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
787 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
788 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
789 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
790 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
791 priv->font_size_toolitem = tool_item;
794 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
795 priv->font_tool_button_label = gtk_label_new (NULL);
796 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
797 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
799 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
800 fonts_menu = gtk_menu_new ();
801 priv->font_items_group = NULL;
803 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
804 GtkWidget *font_menu_item;
805 GtkWidget *child_label;
807 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
808 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
809 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
810 wp_get_font_name (font_index), "</span>", NULL);
811 gtk_label_set_markup (GTK_LABEL (child_label), markup);
814 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
815 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
816 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
817 gtk_widget_show (font_menu_item);
819 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
822 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
823 GtkWidget *item = (GtkWidget *) node->data;
824 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
827 priv->font_items_group = g_slist_reverse (priv->font_items_group);
828 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
829 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
830 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
831 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
832 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
833 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
834 priv->font_face_toolitem = tool_item;
836 /* Set expand and homogeneous for remaining items */
837 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
838 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
839 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
840 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
841 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
842 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
843 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
844 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
845 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
853 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
856 ModestWindowPrivate *parent_priv;
857 ModestMsgEditWindowPrivate *priv;
858 GtkActionGroup *action_group;
859 GError *error = NULL;
860 GdkPixbuf *window_icon = NULL;
863 gboolean prefer_formatted;
865 ModestPair *account_pair = NULL;
867 g_return_val_if_fail (msg, NULL);
868 g_return_val_if_fail (account_name, NULL);
870 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
872 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
873 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
875 parent_priv->ui_manager = gtk_ui_manager_new();
876 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
877 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
879 /* Add common actions */
880 gtk_action_group_add_actions (action_group,
881 modest_msg_edit_action_entries,
882 G_N_ELEMENTS (modest_msg_edit_action_entries),
884 gtk_action_group_add_toggle_actions (action_group,
885 modest_msg_edit_toggle_action_entries,
886 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
888 gtk_action_group_add_radio_actions (action_group,
889 modest_msg_edit_alignment_radio_action_entries,
890 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
892 G_CALLBACK (modest_ui_actions_on_change_justify),
894 gtk_action_group_add_radio_actions (action_group,
895 modest_msg_edit_zoom_action_entries,
896 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
898 G_CALLBACK (modest_ui_actions_on_change_zoom),
900 gtk_action_group_add_radio_actions (action_group,
901 modest_msg_edit_priority_action_entries,
902 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
904 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
906 gtk_action_group_add_radio_actions (action_group,
907 modest_msg_edit_file_format_action_entries,
908 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
909 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
910 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
912 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
913 g_object_unref (action_group);
915 /* Load the UI definition */
916 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
919 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
920 g_clear_error (&error);
923 /* Add accelerators */
924 gtk_window_add_accel_group (GTK_WINDOW (obj),
925 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
928 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
929 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
932 init_window (MODEST_MSG_EDIT_WINDOW(obj));
934 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
936 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
938 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
940 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
942 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
944 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
945 if (account_pair != NULL)
946 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
948 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
950 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
952 /* Set window icon */
953 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
954 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
956 /* Dim at start clipboard actions */
957 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
958 gtk_action_set_sensitive (action, FALSE);
959 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
960 gtk_action_set_sensitive (action, FALSE);
961 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
962 gtk_action_set_sensitive (action, FALSE);
964 /* Update select all */
965 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
966 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
967 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
968 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
969 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
971 /* set initial state of cc and bcc */
972 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
973 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
974 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
975 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
976 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
977 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
979 /* Setup the file format */
980 conf = modest_runtime_get_conf ();
981 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
983 g_clear_error (&error);
984 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
986 file_format = (prefer_formatted) ?
987 MODEST_FILE_FORMAT_FORMATTED_TEXT :
988 MODEST_FILE_FORMAT_PLAIN_TEXT;
989 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
991 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
993 return (ModestWindow*) obj;
997 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
999 GString **string_buffer = (GString **) user_data;
1001 *string_buffer = g_string_append (*string_buffer, buffer);
1007 * @result: A new string which should be freed with g_free().
1010 get_formatted_data (ModestMsgEditWindow *edit_window)
1012 ModestMsgEditWindowPrivate *priv;
1013 GString *string_buffer = g_string_new ("");
1015 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1017 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1019 return g_string_free (string_buffer, FALSE);
1024 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1027 const gchar *account_name;
1028 ModestMsgEditWindowPrivate *priv;
1030 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1032 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1034 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1035 g_return_val_if_fail (account_name, NULL);
1038 /* don't free these (except from) */
1039 data = g_slice_new0 (MsgData);
1040 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1042 data->account_name = g_strdup (account_name);
1043 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1044 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1045 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1046 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1047 if (priv->draft_msg) {
1048 data->draft_msg = g_object_ref (priv->draft_msg);
1050 data->draft_msg = NULL;
1053 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1055 gtk_text_buffer_get_bounds (buf, &b, &e);
1056 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1058 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1059 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1061 data->html_body = NULL;
1063 data->attachments = priv->attachments; /* TODO: copy and free ? */
1064 data->priority_flags = priv->priority_flags;
1069 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1071 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1074 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1082 g_free (data->subject);
1083 g_free (data->plain_body);
1084 g_free (data->html_body);
1085 if (data->draft_msg != NULL) {
1086 g_object_unref (data->draft_msg);
1087 data->draft_msg = NULL;
1089 g_free (data->account_name);
1091 /* TODO: Free data->attachments? */
1093 g_slice_free (MsgData, data);
1097 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1100 ModestMsgEditWindowPrivate *priv = NULL;
1101 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1103 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1105 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1107 return MODEST_MSG_EDIT_FORMAT_HTML;
1109 return MODEST_MSG_EDIT_FORMAT_TEXT;
1113 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1114 ModestMsgEditFormat format)
1116 ModestMsgEditWindowPrivate *priv;
1118 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1119 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1122 case MODEST_MSG_EDIT_FORMAT_HTML:
1123 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1125 case MODEST_MSG_EDIT_FORMAT_TEXT:
1126 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1129 g_return_if_reached ();
1133 ModestMsgEditFormatState *
1134 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1136 ModestMsgEditFormatState *format_state = NULL;
1137 ModestMsgEditWindowPrivate *priv;
1138 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1140 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1141 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1143 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1145 format_state = g_new0 (ModestMsgEditFormatState, 1);
1146 format_state->bold = buffer_format->bold&0x1;
1147 format_state->italics = buffer_format->italic&0x1;
1148 format_state->bullet = buffer_format->bullet&0x1;
1149 format_state->color = buffer_format->color;
1150 format_state->font_size = buffer_format->font_size;
1151 format_state->font_family = wp_get_font_name (buffer_format->font);
1152 format_state->justification = buffer_format->justification;
1153 g_free (buffer_format);
1155 return format_state;
1160 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1161 const ModestMsgEditFormatState *format_state)
1163 ModestMsgEditWindowPrivate *priv;
1164 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1165 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1166 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1167 g_return_if_fail (format_state != NULL);
1169 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1170 gtk_widget_grab_focus (priv->msg_body);
1171 buffer_format->bold = (format_state->bold != FALSE);
1172 buffer_format->italic = (format_state->italics != FALSE);
1173 buffer_format->color = format_state->color;
1174 buffer_format->font_size = format_state->font_size;
1175 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1176 buffer_format->justification = format_state->justification;
1177 buffer_format->bullet = format_state->bullet;
1179 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1181 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1182 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1183 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1184 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1185 buffer_format->cs.font = (buffer_format->font != current_format->font);
1186 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1187 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1189 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1190 if (buffer_format->cs.bold) {
1191 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1193 if (buffer_format->cs.italic) {
1194 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1196 if (buffer_format->cs.color) {
1197 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1199 if (buffer_format->cs.font_size) {
1200 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1202 if (buffer_format->cs.justification) {
1203 switch (buffer_format->justification) {
1204 case GTK_JUSTIFY_LEFT:
1205 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1207 case GTK_JUSTIFY_CENTER:
1208 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1210 case GTK_JUSTIFY_RIGHT:
1211 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1218 if (buffer_format->cs.font) {
1219 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1221 if (buffer_format->cs.bullet) {
1222 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1224 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1225 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1227 g_free (current_format);
1232 toggle_action_set_active_block_notify (GtkToggleAction *action,
1235 GSList *proxies = NULL;
1237 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1238 proxies != NULL; proxies = g_slist_next (proxies)) {
1239 GtkWidget *widget = (GtkWidget *) proxies->data;
1240 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1243 gtk_toggle_action_set_active (action, value);
1245 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1246 proxies != NULL; proxies = g_slist_next (proxies)) {
1247 GtkWidget *widget = (GtkWidget *) proxies->data;
1248 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1253 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1255 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1257 ModestWindowPrivate *parent_priv;
1258 ModestMsgEditWindowPrivate *priv;
1259 GtkWidget *new_size_menuitem;
1260 GtkWidget *new_font_menuitem;
1262 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1263 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1265 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1266 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1267 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1268 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1270 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1271 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1272 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1275 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1277 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1278 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1280 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1281 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1283 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1284 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1286 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1287 G_CALLBACK (modest_msg_edit_window_color_button_change),
1289 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1290 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1291 G_CALLBACK (modest_msg_edit_window_color_button_change),
1294 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1295 buffer_format->font_size))->data);
1296 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1300 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1301 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1302 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1304 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1305 G_CALLBACK (modest_msg_edit_window_size_change),
1307 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1308 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1309 G_CALLBACK (modest_msg_edit_window_size_change),
1313 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1314 buffer_format->font))->data);
1315 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1319 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1320 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1321 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1323 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1324 G_CALLBACK (modest_msg_edit_window_font_change),
1326 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1327 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1328 G_CALLBACK (modest_msg_edit_window_font_change),
1332 g_free (buffer_format);
1338 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1341 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1342 ModestMsgEditWindowPrivate *priv;
1343 GtkWidget *dialog = NULL;
1345 const GdkColor *new_color = NULL;
1347 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1348 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1350 #ifdef MODEST_HILDON_VERSION_0
1351 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1352 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1354 dialog = hildon_color_chooser_new ();
1355 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1356 #endif /*MODEST_HILDON_VERSION_0*/
1357 g_free (buffer_format);
1359 response = gtk_dialog_run (GTK_DIALOG (dialog));
1361 case GTK_RESPONSE_OK: {
1362 #ifdef MODEST_HILDON_VERSION_0
1363 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1366 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1368 #endif /*MODEST_HILDON_VERSION_0*/
1375 gtk_widget_destroy (dialog);
1377 if (new_color != NULL)
1378 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1383 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1386 ModestMsgEditWindowPrivate *priv;
1387 GtkWidget *dialog = NULL;
1389 GdkColor *old_color = NULL;
1390 const GdkColor *new_color = NULL;
1392 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1393 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1395 #ifdef MODEST_HILDON_VERSION_0
1396 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1397 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1399 dialog = hildon_color_chooser_new ();
1400 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1401 #endif /*MODEST_HILDON_VERSION_9*/
1403 response = gtk_dialog_run (GTK_DIALOG (dialog));
1405 case GTK_RESPONSE_OK: {
1406 #ifdef MODEST_HILDON_VERSION_0
1407 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1410 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1412 #endif /*MODEST_HILDON_VERSION_0*/
1418 gtk_widget_destroy (dialog);
1420 if (new_color != NULL)
1421 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1427 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1430 ModestMsgEditWindowPrivate *priv;
1431 GtkWidget *dialog = NULL;
1433 GSList *uris = NULL;
1434 GSList *uri_node = NULL;
1436 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1438 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1439 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1440 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1442 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1444 response = gtk_dialog_run (GTK_DIALOG (dialog));
1446 case GTK_RESPONSE_OK:
1447 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1452 gtk_widget_destroy (dialog);
1454 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1456 GnomeVFSHandle *handle = NULL;
1457 GnomeVFSResult result;
1458 GtkTextIter position;
1459 GtkTextMark *insert_mark;
1461 uri = (const gchar *) uri_node->data;
1462 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1463 if (result == GNOME_VFS_OK) {
1464 GdkPixbufLoader *loader;
1466 GnomeVFSFileInfo info;
1467 gchar *filename, *basename;
1468 TnyMimePart *mime_part;
1471 const gchar *mime_type = NULL;
1473 filename = g_filename_from_uri (uri, NULL, NULL);
1474 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1476 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1478 mime_part = tny_platform_factory_new_mime_part
1479 (modest_runtime_get_platform_factory ());
1480 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1482 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1484 content_id = g_strdup_printf ("%d", priv->last_cid);
1485 tny_mime_part_set_content_id (mime_part, content_id);
1486 g_free (content_id);
1489 basename = g_path_get_basename (filename);
1490 tny_mime_part_set_filename (mime_part, basename);
1493 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1494 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1496 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1497 gtk_widget_show_all (priv->attachments_caption);
1498 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1501 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1502 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1503 unsigned char read_buffer[128];
1505 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1506 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1509 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1510 g_object_ref (pixbuf);
1511 gdk_pixbuf_loader_close (loader, NULL);
1512 g_object_unref (loader);
1514 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1515 GdkPixbuf *new_pixbuf;
1517 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1518 gdk_pixbuf_get_width (pixbuf);
1519 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1520 g_object_unref (pixbuf);
1521 pixbuf = new_pixbuf;
1524 if (pixbuf != NULL) {
1525 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1526 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1527 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1536 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1539 ModestMsgEditWindowPrivate *priv;
1540 GtkWidget *dialog = NULL;
1542 GSList *uris = NULL;
1545 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1547 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1548 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1550 response = gtk_dialog_run (GTK_DIALOG (dialog));
1552 case GTK_RESPONSE_OK:
1553 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1558 gtk_widget_destroy (dialog);
1560 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1562 GnomeVFSHandle *handle = NULL;
1563 GnomeVFSResult result;
1565 uri = (const gchar *) uri_node->data;
1566 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1567 if (result == GNOME_VFS_OK) {
1568 TnyMimePart *mime_part;
1570 const gchar *mime_type = NULL;
1574 GnomeVFSFileInfo info;
1576 filename = g_filename_from_uri (uri, NULL, NULL);
1578 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1579 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1580 mime_part = tny_platform_factory_new_mime_part
1581 (modest_runtime_get_platform_factory ());
1582 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1584 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1586 content_id = g_strdup_printf ("%d", priv->last_cid);
1587 tny_mime_part_set_content_id (mime_part, content_id);
1588 g_free (content_id);
1591 basename = g_path_get_basename (filename);
1592 tny_mime_part_set_filename (mime_part, basename);
1595 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1596 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1598 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1599 gtk_widget_show_all (priv->attachments_caption);
1600 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1605 g_slist_foreach (uris, (GFunc) g_free, NULL);
1606 g_slist_free (uris);
1610 modest_msg_edit_window_attach_file_noninteractive (
1611 ModestMsgEditWindow *window,
1612 const gchar *file_uri)
1615 ModestMsgEditWindowPrivate *priv;
1617 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1619 if (file_uri && strlen(file_uri)) {
1622 /* TODO: We should probably try to use only the URI,
1623 * instead of using a filename.
1625 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1627 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1630 file_id = g_open (filename, O_RDONLY, 0);
1631 if (file_id != -1) {
1632 TnyMimePart *mime_part;
1634 const gchar *mime_type;
1637 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1638 mime_type = gnome_vfs_get_mime_type(filename);
1640 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1642 mime_part = tny_platform_factory_new_mime_part
1643 (modest_runtime_get_platform_factory ());
1644 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1646 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1648 content_id = g_strdup_printf ("%d", priv->last_cid);
1649 tny_mime_part_set_content_id (mime_part, content_id);
1650 g_free (content_id);
1653 basename = g_path_get_basename (filename);
1654 tny_mime_part_set_filename (mime_part, basename);
1657 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1658 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1660 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1661 gtk_widget_show_all (priv->attachments_caption);
1662 } else if (file_id == -1) {
1664 g_warning("file to be attached does not exist: %s", filename);
1672 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1675 ModestMsgEditWindowPrivate *priv;
1676 gboolean clean_list = FALSE;
1678 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1679 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1681 if (att_list == NULL) {
1682 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1686 if (att_list == NULL) {
1687 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1689 GtkWidget *confirmation_dialog = NULL;
1690 gboolean dialog_response;
1692 gchar *message = NULL;
1693 const gchar *filename = NULL;
1695 if (att_list->next == NULL) {
1696 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1700 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1701 att_list->next == NULL), filename);
1702 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1704 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1705 gtk_widget_destroy (confirmation_dialog);
1706 if (!dialog_response) {
1708 g_list_free (att_list);
1711 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1713 for (node = att_list; node != NULL; node = g_list_next (node)) {
1714 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1715 const gchar *att_id;
1716 priv->attachments = g_list_remove (priv->attachments, mime_part);
1718 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1720 if (priv->attachments == NULL)
1721 gtk_widget_hide (priv->attachments_caption);
1722 att_id = tny_mime_part_get_content_id (mime_part);
1724 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1726 g_object_unref (mime_part);
1727 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1732 g_list_free (att_list);
1736 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1739 ModestMsgEditWindowPrivate *priv;
1740 GdkColor *new_color;
1741 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1743 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1744 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1747 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1749 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1751 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1753 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1758 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1761 ModestMsgEditWindowPrivate *priv;
1762 gint new_size_index;
1763 ModestMsgEditWindow *window;
1766 window = MODEST_MSG_EDIT_WINDOW (userdata);
1767 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1768 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1770 if (gtk_check_menu_item_get_active (menu_item)) {
1772 WPTextBufferFormat format;
1774 memset (&format, 0, sizeof (format));
1775 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1777 label = gtk_bin_get_child (GTK_BIN (menu_item));
1779 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1780 format.cs.font_size = TRUE;
1781 format.cs.text_position = TRUE;
1782 format.cs.font = TRUE;
1783 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1784 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1786 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1787 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1788 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1790 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1791 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1792 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1798 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1801 ModestMsgEditWindowPrivate *priv;
1802 gint new_font_index;
1803 ModestMsgEditWindow *window;
1806 window = MODEST_MSG_EDIT_WINDOW (userdata);
1807 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1808 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1810 if (gtk_check_menu_item_get_active (menu_item)) {
1813 label = gtk_bin_get_child (GTK_BIN (menu_item));
1815 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1817 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1818 (gpointer) new_font_index))
1819 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1821 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1822 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1823 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1829 modest_msg_edit_window_set_zoom (ModestWindow *window,
1832 ModestMsgEditWindowPrivate *priv;
1833 ModestWindowPrivate *parent_priv;
1834 GtkRadioAction *zoom_radio_action;
1836 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1838 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1839 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1840 priv->zoom_level = zoom;
1841 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1843 /* Zoom level menu options should be updated with the current zoom level */
1844 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1845 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1846 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1847 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1848 /* FIXME: Not availible before Gtk 2.10 */
1850 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1855 modest_msg_edit_window_get_zoom (ModestWindow *window)
1857 ModestMsgEditWindowPrivate *priv;
1859 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1861 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1862 return priv->zoom_level;
1866 zoom_allowed (ModestMsgEditWindow *window)
1870 focus = gtk_window_get_focus (GTK_WINDOW (window));
1871 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1875 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1877 ModestWindowPrivate *parent_priv;
1878 GtkRadioAction *zoom_radio_action;
1879 GSList *group, *node;
1881 /* First we check if the text view is focused. If not, zooming is not allowed */
1882 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1883 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1887 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1888 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1889 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1891 group = gtk_radio_action_get_group (zoom_radio_action);
1893 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1894 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1898 for (node = group; node != NULL; node = g_slist_next (node)) {
1899 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1900 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1908 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1910 ModestWindowPrivate *parent_priv;
1911 GtkRadioAction *zoom_radio_action;
1912 GSList *group, *node;
1914 /* First we check if the text view is focused. If not, zooming is not allowed */
1915 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1916 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1920 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1921 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1922 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1924 group = gtk_radio_action_get_group (zoom_radio_action);
1926 for (node = group; node != NULL; node = g_slist_next (node)) {
1927 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1928 if (node->next != NULL) {
1929 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1932 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1940 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1942 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1943 ModestWindowPrivate *parent_priv;
1944 ModestWindowMgr *mgr;
1945 gboolean is_fullscreen;
1946 GtkAction *fs_toggle_action;
1949 mgr = modest_runtime_get_window_mgr ();
1950 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1952 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1954 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1955 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1956 if (is_fullscreen != active)
1957 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1965 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1967 ModestWindowPrivate *parent_priv;
1968 GtkAction *fs_toggle_action;
1971 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1973 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1974 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1975 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1979 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1982 ModestMsgEditWindowPrivate *priv = NULL;
1983 const gchar *recipients;
1984 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1986 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1987 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1988 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
1989 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
1990 gtk_widget_show (priv->cc_caption);
1992 gtk_widget_hide (priv->cc_caption);
1993 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1997 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2000 ModestMsgEditWindowPrivate *priv = NULL;
2001 const gchar *recipients;
2002 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2004 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2005 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2006 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2007 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2008 gtk_widget_show (priv->bcc_caption);
2010 gtk_widget_hide (priv->bcc_caption);
2011 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2015 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2016 ModestRecptEditor *editor)
2018 ModestMsgEditWindowPrivate *priv;
2020 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2021 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2022 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2024 if (editor == NULL) {
2025 GtkWidget *view_focus;
2026 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2028 /* This code should be kept in sync with ModestRecptEditor. The
2029 textview inside the recpt editor is the one that really gets the
2030 focus. As it's inside a scrolled window, and this one inside the
2031 hbox recpt editor inherits from, we'll need to go up in the
2032 hierarchy to know if the text view is part of the recpt editor
2033 or if it's a different text entry */
2035 if (gtk_widget_get_parent (view_focus)) {
2036 GtkWidget *first_parent;
2038 first_parent = gtk_widget_get_parent (view_focus);
2039 if (gtk_widget_get_parent (first_parent) &&
2040 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2041 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2046 editor = MODEST_RECPT_EDITOR (priv->to_field);
2050 modest_address_book_select_addresses (editor);
2055 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2057 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2059 modest_msg_edit_window_open_addressbook (window, NULL);
2063 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2064 gboolean show_toolbar)
2066 ModestWindowPrivate *parent_priv;
2068 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2069 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2071 /* FIXME: we can not just use the code of
2072 modest_msg_edit_window_setup_toolbar because it has a
2073 mixture of both initialization and creation code. */
2076 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2078 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2082 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2083 TnyHeaderFlags priority_flags)
2085 ModestMsgEditWindowPrivate *priv;
2086 ModestWindowPrivate *parent_priv;
2088 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2090 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2091 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2092 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2094 if (priv->priority_flags != priority_flags) {
2095 GtkAction *priority_action = NULL;
2097 priv->priority_flags = priority_flags;
2099 switch (priority_flags) {
2100 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2101 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2102 gtk_widget_show (priv->priority_icon);
2103 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2104 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2106 case TNY_HEADER_FLAG_LOW_PRIORITY:
2107 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2108 gtk_widget_show (priv->priority_icon);
2109 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2110 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2113 gtk_widget_hide (priv->priority_icon);
2114 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2115 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2118 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2119 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2124 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2127 ModestMsgEditWindowPrivate *priv;
2128 gint current_format;
2130 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2132 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2134 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2135 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2137 if (current_format != file_format) {
2138 switch (file_format) {
2139 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2140 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2142 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2146 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2147 response = gtk_dialog_run (GTK_DIALOG (dialog));
2148 gtk_widget_destroy (dialog);
2149 if (response == GTK_RESPONSE_OK)
2150 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2154 update_dimmed (window);
2159 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2162 ModestMsgEditWindowPrivate *priv;
2163 WPTextBufferFormat oldfmt, fmt;
2164 gint old_position = 0;
2168 GdkColor *color = NULL;
2169 gboolean bold, bold_set, italic, italic_set;
2170 gboolean underline, underline_set;
2171 gboolean strikethrough, strikethrough_set;
2172 gboolean position_set;
2173 gboolean font_size_set, font_set, color_set;
2176 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2177 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2179 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2181 /* First we get the currently selected font information */
2182 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2183 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2185 switch (oldfmt.text_position) {
2186 case TEXT_POSITION_NORMAL:
2189 case TEXT_POSITION_SUPERSCRIPT:
2197 g_object_set (G_OBJECT (dialog),
2198 "bold", oldfmt.bold != FALSE,
2199 "bold-set", !oldfmt.cs.bold,
2200 "underline", oldfmt.underline != FALSE,
2201 "underline-set", !oldfmt.cs.underline,
2202 "italic", oldfmt.italic != FALSE,
2203 "italic-set", !oldfmt.cs.italic,
2204 "strikethrough", oldfmt.strikethrough != FALSE,
2205 "strikethrough-set", !oldfmt.cs.strikethrough,
2206 "color", &oldfmt.color,
2207 "color-set", !oldfmt.cs.color,
2208 "size", wp_font_size[oldfmt.font_size],
2209 "size-set", !oldfmt.cs.font_size,
2210 "position", old_position,
2211 "position-set", !oldfmt.cs.text_position,
2212 "family", wp_get_font_name (oldfmt.font),
2213 "family-set", !oldfmt.cs.font,
2216 gtk_widget_show_all (dialog);
2217 response = gtk_dialog_run (GTK_DIALOG (dialog));
2218 if (response == GTK_RESPONSE_OK) {
2220 g_object_get( dialog,
2222 "bold-set", &bold_set,
2223 "underline", &underline,
2224 "underline-set", &underline_set,
2226 "italic-set", &italic_set,
2227 "strikethrough", &strikethrough,
2228 "strikethrough-set", &strikethrough_set,
2230 "color-set", &color_set,
2232 "size-set", &font_size_set,
2233 "family", &font_name,
2234 "family-set", &font_set,
2235 "position", &position,
2236 "position-set", &position_set,
2241 if (response == GTK_RESPONSE_OK) {
2242 memset(&fmt, 0, sizeof(fmt));
2248 fmt.italic = italic;
2249 fmt.cs.italic = TRUE;
2251 if (underline_set) {
2252 fmt.underline = underline;
2253 fmt.cs.underline = TRUE;
2255 if (strikethrough_set) {
2256 fmt.strikethrough = strikethrough;
2257 fmt.cs.strikethrough = TRUE;
2262 ? TEXT_POSITION_NORMAL
2263 : ( ( position == 1 )
2264 ? TEXT_POSITION_SUPERSCRIPT
2265 : TEXT_POSITION_SUBSCRIPT );
2266 fmt.cs.text_position = TRUE;
2270 fmt.cs.color = TRUE;
2273 fmt.font = wp_get_font_index(font_name,
2278 if (font_size_set) {
2279 fmt.font_size = wp_get_font_size_index(
2280 font_size, DEFAULT_FONT_SIZE);
2281 fmt.cs.font_size = TRUE;
2283 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2285 gtk_widget_destroy (dialog);
2287 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2291 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2293 ModestMsgEditWindowPrivate *priv;
2295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2296 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2298 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2300 update_dimmed (window);
2305 update_dimmed (ModestMsgEditWindow *window)
2307 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2308 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2312 gboolean editor_focused;
2314 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2315 editor_focused = gtk_widget_is_focus (priv->msg_body);
2317 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2318 gtk_action_set_sensitive (action, rich_text && editor_focused);
2319 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2320 gtk_action_set_sensitive (action, rich_text && editor_focused);
2321 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2322 gtk_action_set_sensitive (action, rich_text && editor_focused);
2323 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2324 gtk_action_set_sensitive (action, rich_text && editor_focused);
2325 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2326 gtk_action_set_sensitive (action, rich_text && editor_focused);
2327 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2328 gtk_action_set_sensitive (action, rich_text && editor_focused);
2329 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2330 gtk_action_set_sensitive (action, rich_text && editor_focused);
2331 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2332 gtk_action_set_sensitive (action, rich_text && editor_focused);
2333 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2334 gtk_action_set_sensitive (action, rich_text && editor_focused);
2335 widget = priv->font_color_button;
2336 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2337 widget = priv->font_size_toolitem;
2338 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2339 widget = priv->font_face_toolitem;
2340 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2344 setup_insensitive_handlers (ModestMsgEditWindow *window)
2346 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2347 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2350 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2351 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2352 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2353 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2355 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2356 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2357 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2358 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2359 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2360 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2361 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2362 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2363 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2364 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2365 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2366 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2367 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2368 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2369 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2370 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2371 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2372 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2373 widget = priv->font_color_button;
2374 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2375 widget = priv->font_size_toolitem;
2376 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2377 widget = priv->font_face_toolitem;
2378 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2380 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2381 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2382 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2383 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2385 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2386 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (paste_insensitive_press), window);
2390 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2392 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2395 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2396 gtk_action_set_sensitive (action, can_undo);
2400 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2403 GtkTextIter match_start, match_end;
2405 if (image_id == NULL)
2408 gtk_text_buffer_get_start_iter (buffer, &iter);
2410 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2411 GSList *tags = gtk_text_iter_get_tags (&match_start);
2413 for (node = tags; node != NULL; node = g_slist_next (node)) {
2414 GtkTextTag *tag = (GtkTextTag *) node->data;
2415 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2416 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2417 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2419 offset = gtk_text_iter_get_offset (&match_start);
2420 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2421 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2425 gtk_text_iter_forward_char (&iter);
2430 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2432 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2433 GtkTextIter real_start, real_end;
2434 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2436 if (gtk_text_iter_compare (start, end) > 0) {
2440 real_start = *start;
2444 GSList *tags = gtk_text_iter_get_tags (&real_start);
2446 for (node = tags; node != NULL; node = g_slist_next (node)) {
2447 GtkTextTag *tag = (GtkTextTag *) node->data;
2448 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2449 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2451 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2453 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2456 } while (gtk_text_iter_forward_char (&real_start)&&
2457 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2461 msg_body_focus (GtkWidget *focus,
2462 GdkEventFocus *event,
2466 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2471 recpt_field_changed (GtkTextBuffer *buffer,
2472 ModestMsgEditWindow *editor)
2474 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2475 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2476 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2477 gboolean dim = FALSE;
2480 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2481 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2482 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2484 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2485 gtk_text_buffer_get_char_count (cc_buffer) +
2486 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2488 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2489 gtk_action_set_sensitive (action, !dim);
2490 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2491 gtk_action_set_sensitive (action, !dim);
2495 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2497 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2501 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2503 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2507 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2509 ModestWindowPrivate *parent_priv;
2510 ModestMsgEditWindowPrivate *priv;
2511 GList *selected_attachments = NULL;
2512 gint n_att_selected = 0;
2514 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2515 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2517 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2518 n_att_selected = g_list_length (selected_attachments);
2519 g_list_free (selected_attachments);
2521 if (n_att_selected > 1)
2522 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2523 else if (n_att_selected == 0)
2524 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2529 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2531 gboolean rich_text, editor_focused;
2533 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2534 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2535 editor_focused = gtk_widget_is_focus (priv->msg_body);
2538 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2539 else if (!editor_focused)
2540 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2544 reset_modified (ModestMsgEditWindow *editor)
2546 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2547 GtkTextBuffer *buffer;
2549 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2550 gtk_text_buffer_set_modified (buffer, FALSE);
2551 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2552 gtk_text_buffer_set_modified (buffer, FALSE);
2553 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2554 gtk_text_buffer_set_modified (buffer, FALSE);
2555 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2559 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2561 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2562 GtkTextBuffer *buffer;
2564 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2565 if (gtk_text_buffer_get_modified (buffer))
2567 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2568 if (gtk_text_buffer_get_modified (buffer))
2570 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2571 if (gtk_text_buffer_get_modified (buffer))
2573 if (gtk_text_buffer_get_modified (priv->text_buffer))
2580 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2582 ModestMsgEditWindowPrivate *priv = NULL;
2584 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2585 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2587 /* check if there's no recipient added */
2588 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2589 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2590 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2591 /* no recipient contents, then select contacts */
2592 modest_msg_edit_window_open_addressbook (window, NULL);
2596 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2598 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2600 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2603 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2610 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2611 ModestMsgEditWindow *window)
2613 modest_msg_edit_window_attach_file (window);
2617 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2619 ModestMsgEditWindow *window)
2621 ModestWindowPrivate *parent_priv;
2622 ModestMsgEditWindowPrivate *priv;
2626 GList *selected_attachments = NULL;
2627 gint n_att_selected = 0;
2629 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2630 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2631 selection = gtk_clipboard_wait_for_text (clipboard);
2632 focused = gtk_window_get_focus (GTK_WINDOW (window));
2634 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2635 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2636 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2637 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2639 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2640 n_att_selected = g_list_length (selected_attachments);
2641 g_list_free (selected_attachments);
2643 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2644 gtk_action_set_sensitive (action, n_att_selected == 1);
2647 update_paste_dimming (window);
2651 update_window_title (ModestMsgEditWindow *window)
2653 ModestMsgEditWindowPrivate *priv = NULL;
2654 const gchar *subject;
2656 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2657 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2658 if (subject == NULL || subject[0] == '\0')
2659 subject = _("mail_va_new_email");
2661 gtk_window_set_title (GTK_WINDOW (window), subject);
2666 subject_field_changed (GtkEditable *editable,
2667 ModestMsgEditWindow *window)
2669 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2670 update_window_title (window);
2671 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2675 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2678 ModestMsgEditWindowPrivate *priv = NULL;
2680 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2681 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2683 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2685 gtk_widget_show_all (priv->find_toolbar);
2686 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2688 gtk_widget_hide_all (priv->find_toolbar);
2689 gtk_widget_grab_focus (priv->msg_body);
2695 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2697 GtkTextIter *match_start,
2698 GtkTextIter *match_end)
2700 GtkTextIter end_iter;
2701 gchar *str_casefold;
2704 gchar *range_casefold;
2707 gboolean result = FALSE;
2714 gtk_text_iter_forward_to_end (&end_iter);
2716 str_casefold = g_utf8_casefold (str, -1);
2717 str_chars_n = strlen (str);
2719 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2720 range_casefold = g_utf8_casefold (range_text, -1);
2721 range_chars_n = strlen (range_casefold);
2723 if (range_chars_n < str_chars_n) {
2724 g_free (str_casefold);
2725 g_free (range_text);
2726 g_free (range_casefold);
2730 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2731 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2732 if (!g_utf8_collate (range_subtext, str_casefold)) {
2733 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2735 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2736 match_start, match_end, NULL);
2737 g_free (found_text);
2739 g_free (range_subtext);
2743 g_free (str_casefold);
2744 g_free (range_text);
2745 g_free (range_casefold);
2752 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2753 ModestMsgEditWindow *window)
2755 gchar *current_search = NULL;
2756 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2758 GtkTextIter selection_start, selection_end;
2759 GtkTextIter match_start, match_end;
2760 gboolean continue_search = FALSE;
2762 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2763 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2764 g_free (current_search);
2765 g_free (priv->last_search);
2766 priv->last_search = NULL;
2767 /* Information banner about empty search */
2768 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2772 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2773 continue_search = TRUE;
2775 g_free (priv->last_search);
2776 priv->last_search = g_strdup (current_search);
2779 if (continue_search) {
2780 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2781 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2782 &match_start, &match_end);
2784 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2786 GtkTextIter buffer_start;
2787 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2788 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2789 &match_start, &match_end);
2791 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2794 /* Mark as selected the string found in search */
2796 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2797 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2799 g_free (priv->last_search);
2800 priv->last_search = NULL;
2802 g_free (current_search);
2806 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2807 ModestMsgEditWindow *window)
2809 GtkToggleAction *toggle;
2810 ModestWindowPrivate *parent_priv;
2811 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2813 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2814 gtk_toggle_action_set_active (toggle, FALSE);
2819 update_paste_dimming (ModestMsgEditWindow *window)
2821 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2822 GtkAction *action = NULL;
2823 GtkClipboard *clipboard = NULL;
2827 focused = gtk_window_get_focus (GTK_WINDOW (window));
2829 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2830 active = gtk_clipboard_wait_is_text_available (clipboard);
2833 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2837 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2838 gtk_action_set_sensitive (action, active);
2843 paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2845 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (editor));
2847 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2848 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
2850 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
2856 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2858 ModestMsgEditWindow *window)
2860 update_paste_dimming (window);
2864 update_select_all_dimming (ModestMsgEditWindow *window)
2867 gboolean dimmed = FALSE;
2869 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2871 focused = gtk_window_get_focus (GTK_WINDOW (window));
2872 if (GTK_IS_ENTRY (focused)) {
2873 const gchar *current_text;
2874 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2875 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2876 } else if (GTK_IS_TEXT_VIEW (focused)) {
2877 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2878 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2879 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2882 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2883 gtk_action_set_sensitive (action, !dimmed);
2887 update_zoom_dimming (ModestMsgEditWindow *window)
2890 gboolean dimmed = FALSE;
2892 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2894 focused = gtk_window_get_focus (GTK_WINDOW (window));
2895 dimmed = ! WP_IS_TEXT_VIEW (focused);
2896 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2897 gtk_action_set_sensitive (action, !dimmed);
2901 edit_menu_activated (GtkAction *action,
2904 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2906 update_select_all_dimming (window);
2909 view_menu_activated (GtkAction *action,
2912 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2914 update_zoom_dimming (window);
2918 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2920 ModestMsgEditWindowPrivate *priv;
2922 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2927 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2930 ModestMsgEditWindowPrivate *priv;
2932 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);