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 /* This had to stay alive for as long as the combobox that used it: */
534 modest_pair_list_free (priv->from_field_protos);
536 G_OBJECT_CLASS(parent_class)->finalize (obj);
540 menubar_to_menu (GtkUIManager *ui_manager)
542 GtkWidget *main_menu;
546 /* Create new main menu */
547 main_menu = gtk_menu_new();
549 /* Get the menubar from the UI manager */
550 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
552 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
556 menu = GTK_WIDGET (iter->data);
557 gtk_widget_reparent(menu, main_menu);
559 iter = g_list_next (iter);
566 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
569 const gchar *to, *cc, *bcc, *subject;
571 ModestMsgEditWindowPrivate *priv;
573 TnyHeaderFlags priority_flags;
575 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
576 g_return_if_fail (TNY_IS_MSG (msg));
578 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
580 header = tny_msg_get_header (msg);
581 to = tny_header_get_to (header);
582 cc = tny_header_get_cc (header);
583 bcc = tny_header_get_bcc (header);
584 subject = tny_header_get_subject (header);
585 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
588 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
590 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
591 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
592 gtk_widget_show (priv->cc_caption);
593 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
594 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
595 gtk_widget_hide (priv->cc_caption);
598 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
599 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
600 gtk_widget_show (priv->bcc_caption);
601 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
602 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
603 gtk_widget_hide (priv->bcc_caption);
606 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
607 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
610 update_window_title (self);
612 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
613 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
614 body = modest_tny_msg_get_body (msg, TRUE);
616 if ((body == NULL)||(body[0] == '\0')) {
618 body = modest_text_utils_convert_to_html ("");
620 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
621 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
624 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
627 /* Get the default format required from configuration */
628 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
629 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
632 /* Set the default focus depending on having already a To: field or not */
633 if ((!to)||(*to == '\0')) {
634 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
636 gtk_widget_grab_focus (priv->msg_body);
639 /* TODO: lower priority, select in the From: combo to the
640 value that comes from msg <- not sure, should it be
643 /* Add attachments to the view */
644 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
645 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
646 if (priv->attachments == NULL) {
647 gtk_widget_hide (priv->attachments_caption);
649 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
650 gtk_widget_show_all (priv->attachments_caption);
653 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
654 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
656 reset_modified (self);
658 update_dimmed (self);
659 text_buffer_can_undo (priv->text_buffer, FALSE, self);
661 priv->draft_msg = msg;
665 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
668 GList *item_children, *node;
669 GtkWidget *bin_child;
671 bin_child = gtk_bin_get_child (GTK_BIN(item));
673 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
675 for (node = item_children; node != NULL; node = g_list_next (node)) {
676 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
677 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
680 g_list_free (item_children);
684 menu_tool_button_dont_expand (GtkMenuToolButton *item)
687 GList *item_children, *node;
689 box = gtk_bin_get_child (GTK_BIN (item));
690 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
691 item_children = gtk_container_get_children (GTK_CONTAINER (box));
693 for (node = item_children; node != NULL; node = g_list_next (node)) {
694 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
695 if (GTK_IS_TOGGLE_BUTTON (node->data))
696 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
697 else if (GTK_IS_BUTTON (node->data))
698 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
700 g_list_free (item_children);
705 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
707 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
708 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
709 GtkWidget *placeholder;
710 GtkWidget *tool_item;
715 GtkWidget *sizes_menu;
716 GtkWidget *fonts_menu;
717 GSList *radio_group = NULL;
722 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
723 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
725 /* should we hide the toolbar? */
726 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
727 gtk_widget_hide (parent_priv->toolbar);
729 /* Font color placeholder */
730 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
731 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
734 tool_item = GTK_WIDGET (gtk_tool_item_new ());
735 priv->font_color_button = hildon_color_button_new ();
736 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
737 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
738 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
739 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
740 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
741 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
742 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
744 /* Font size and face placeholder */
745 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
746 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
748 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
749 priv->size_tool_button_label = gtk_label_new (NULL);
750 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
751 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
752 size_text,"</span>", NULL);
753 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
755 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
756 sizes_menu = gtk_menu_new ();
757 priv->size_items_group = NULL;
759 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
760 GtkWidget *size_menu_item;
762 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
763 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
764 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
765 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
766 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
767 gtk_widget_show (size_menu_item);
769 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
773 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
774 GtkWidget *item = (GtkWidget *) node->data;
775 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
779 priv->size_items_group = g_slist_reverse (priv->size_items_group);
780 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
781 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
782 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
783 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
784 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
785 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
786 priv->font_size_toolitem = tool_item;
789 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
790 priv->font_tool_button_label = gtk_label_new (NULL);
791 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
792 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
794 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
795 fonts_menu = gtk_menu_new ();
796 priv->font_items_group = NULL;
798 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
799 GtkWidget *font_menu_item;
800 GtkWidget *child_label;
802 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
803 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
804 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
805 wp_get_font_name (font_index), "</span>", NULL);
806 gtk_label_set_markup (GTK_LABEL (child_label), markup);
809 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
810 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
811 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
812 gtk_widget_show (font_menu_item);
814 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
817 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
818 GtkWidget *item = (GtkWidget *) node->data;
819 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
822 priv->font_items_group = g_slist_reverse (priv->font_items_group);
823 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
824 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
825 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
826 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
827 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
828 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
829 priv->font_face_toolitem = tool_item;
831 /* Set expand and homogeneous for remaining items */
832 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
833 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
834 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
835 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
836 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
837 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
838 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
839 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
840 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
848 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
851 ModestWindowPrivate *parent_priv;
852 ModestMsgEditWindowPrivate *priv;
853 GtkActionGroup *action_group;
854 GError *error = NULL;
855 GdkPixbuf *window_icon = NULL;
858 gboolean prefer_formatted;
860 ModestPair *account_pair = NULL;
862 g_return_val_if_fail (msg, NULL);
863 g_return_val_if_fail (account_name, NULL);
865 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
867 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
868 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
870 parent_priv->ui_manager = gtk_ui_manager_new();
871 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
872 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
874 /* Add common actions */
875 gtk_action_group_add_actions (action_group,
876 modest_msg_edit_action_entries,
877 G_N_ELEMENTS (modest_msg_edit_action_entries),
879 gtk_action_group_add_toggle_actions (action_group,
880 modest_msg_edit_toggle_action_entries,
881 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
883 gtk_action_group_add_radio_actions (action_group,
884 modest_msg_edit_alignment_radio_action_entries,
885 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
887 G_CALLBACK (modest_ui_actions_on_change_justify),
889 gtk_action_group_add_radio_actions (action_group,
890 modest_msg_edit_zoom_action_entries,
891 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
893 G_CALLBACK (modest_ui_actions_on_change_zoom),
895 gtk_action_group_add_radio_actions (action_group,
896 modest_msg_edit_priority_action_entries,
897 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
899 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
901 gtk_action_group_add_radio_actions (action_group,
902 modest_msg_edit_file_format_action_entries,
903 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
904 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
905 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
907 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
908 g_object_unref (action_group);
910 /* Load the UI definition */
911 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
914 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
915 g_clear_error (&error);
918 /* Add accelerators */
919 gtk_window_add_accel_group (GTK_WINDOW (obj),
920 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
923 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
924 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
927 init_window (MODEST_MSG_EDIT_WINDOW(obj));
929 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
931 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
933 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
935 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
937 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
939 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
940 if (account_pair != NULL)
941 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
943 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
945 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
947 /* Set window icon */
948 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
949 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
951 /* Dim at start clipboard actions */
952 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
953 gtk_action_set_sensitive (action, FALSE);
954 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
955 gtk_action_set_sensitive (action, FALSE);
956 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
957 gtk_action_set_sensitive (action, FALSE);
959 /* Update select all */
960 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
961 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
962 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
963 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
964 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
966 /* set initial state of cc and bcc */
967 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
968 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
969 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
970 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
971 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
972 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
974 /* Setup the file format */
975 conf = modest_runtime_get_conf ();
976 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
978 g_clear_error (&error);
979 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
981 file_format = (prefer_formatted) ?
982 MODEST_FILE_FORMAT_FORMATTED_TEXT :
983 MODEST_FILE_FORMAT_PLAIN_TEXT;
984 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
986 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
988 return (ModestWindow*) obj;
992 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
994 GString **string_buffer = (GString **) user_data;
996 *string_buffer = g_string_append (*string_buffer, buffer);
1002 * @result: A new string which should be freed with g_free().
1005 get_formatted_data (ModestMsgEditWindow *edit_window)
1007 ModestMsgEditWindowPrivate *priv;
1008 GString *string_buffer = g_string_new ("");
1010 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1012 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1014 return g_string_free (string_buffer, FALSE);
1019 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1022 const gchar *account_name;
1023 ModestMsgEditWindowPrivate *priv;
1025 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1027 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1029 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1030 g_return_val_if_fail (account_name, NULL);
1033 /* don't free these (except from) */
1034 data = g_slice_new0 (MsgData);
1035 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1037 data->account_name = g_strdup (account_name);
1038 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1039 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1040 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1041 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1042 if (priv->draft_msg) {
1043 data->draft_msg = g_object_ref (priv->draft_msg);
1045 data->draft_msg = NULL;
1048 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1050 gtk_text_buffer_get_bounds (buf, &b, &e);
1051 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1053 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1054 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1056 data->html_body = NULL;
1058 data->attachments = priv->attachments; /* TODO: copy and free ? */
1059 data->priority_flags = priv->priority_flags;
1064 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1066 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1069 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1077 g_free (data->subject);
1078 g_free (data->plain_body);
1079 g_free (data->html_body);
1080 if (data->draft_msg != NULL) {
1081 g_object_unref (data->draft_msg);
1082 data->draft_msg = NULL;
1084 g_free (data->account_name);
1086 /* TODO: Free data->attachments? */
1088 g_slice_free (MsgData, data);
1092 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1095 ModestMsgEditWindowPrivate *priv = NULL;
1096 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1098 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1100 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1102 return MODEST_MSG_EDIT_FORMAT_HTML;
1104 return MODEST_MSG_EDIT_FORMAT_TEXT;
1108 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1109 ModestMsgEditFormat format)
1111 ModestMsgEditWindowPrivate *priv;
1113 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1114 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1117 case MODEST_MSG_EDIT_FORMAT_HTML:
1118 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1120 case MODEST_MSG_EDIT_FORMAT_TEXT:
1121 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1124 g_return_if_reached ();
1128 ModestMsgEditFormatState *
1129 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1131 ModestMsgEditFormatState *format_state = NULL;
1132 ModestMsgEditWindowPrivate *priv;
1133 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1135 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1136 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1138 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1140 format_state = g_new0 (ModestMsgEditFormatState, 1);
1141 format_state->bold = buffer_format->bold&0x1;
1142 format_state->italics = buffer_format->italic&0x1;
1143 format_state->bullet = buffer_format->bullet&0x1;
1144 format_state->color = buffer_format->color;
1145 format_state->font_size = buffer_format->font_size;
1146 format_state->font_family = wp_get_font_name (buffer_format->font);
1147 format_state->justification = buffer_format->justification;
1148 g_free (buffer_format);
1150 return format_state;
1155 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1156 const ModestMsgEditFormatState *format_state)
1158 ModestMsgEditWindowPrivate *priv;
1159 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1160 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1161 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1162 g_return_if_fail (format_state != NULL);
1164 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1165 gtk_widget_grab_focus (priv->msg_body);
1166 buffer_format->bold = (format_state->bold != FALSE);
1167 buffer_format->italic = (format_state->italics != FALSE);
1168 buffer_format->color = format_state->color;
1169 buffer_format->font_size = format_state->font_size;
1170 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1171 buffer_format->justification = format_state->justification;
1172 buffer_format->bullet = format_state->bullet;
1174 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1176 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1177 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1178 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1179 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1180 buffer_format->cs.font = (buffer_format->font != current_format->font);
1181 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1182 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1184 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1185 if (buffer_format->cs.bold) {
1186 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1188 if (buffer_format->cs.italic) {
1189 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1191 if (buffer_format->cs.color) {
1192 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1194 if (buffer_format->cs.font_size) {
1195 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1197 if (buffer_format->cs.justification) {
1198 switch (buffer_format->justification) {
1199 case GTK_JUSTIFY_LEFT:
1200 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1202 case GTK_JUSTIFY_CENTER:
1203 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1205 case GTK_JUSTIFY_RIGHT:
1206 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1213 if (buffer_format->cs.font) {
1214 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1216 if (buffer_format->cs.bullet) {
1217 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1219 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1220 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1222 g_free (current_format);
1227 toggle_action_set_active_block_notify (GtkToggleAction *action,
1230 GSList *proxies = NULL;
1232 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1233 proxies != NULL; proxies = g_slist_next (proxies)) {
1234 GtkWidget *widget = (GtkWidget *) proxies->data;
1235 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1238 gtk_toggle_action_set_active (action, value);
1240 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1241 proxies != NULL; proxies = g_slist_next (proxies)) {
1242 GtkWidget *widget = (GtkWidget *) proxies->data;
1243 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1248 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1250 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1252 ModestWindowPrivate *parent_priv;
1253 ModestMsgEditWindowPrivate *priv;
1254 GtkWidget *new_size_menuitem;
1255 GtkWidget *new_font_menuitem;
1257 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1258 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1260 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1261 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1262 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1263 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1265 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1266 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1267 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1270 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1272 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1273 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1275 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1276 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1278 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1279 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1281 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1282 G_CALLBACK (modest_msg_edit_window_color_button_change),
1284 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1285 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1286 G_CALLBACK (modest_msg_edit_window_color_button_change),
1289 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1290 buffer_format->font_size))->data);
1291 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1295 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1296 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1297 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1299 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1300 G_CALLBACK (modest_msg_edit_window_size_change),
1302 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1303 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1304 G_CALLBACK (modest_msg_edit_window_size_change),
1308 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1309 buffer_format->font))->data);
1310 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1314 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1315 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1316 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1318 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1319 G_CALLBACK (modest_msg_edit_window_font_change),
1321 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1322 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1323 G_CALLBACK (modest_msg_edit_window_font_change),
1327 g_free (buffer_format);
1333 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1336 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1337 ModestMsgEditWindowPrivate *priv;
1338 GtkWidget *dialog = NULL;
1340 const GdkColor *new_color = NULL;
1342 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1343 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1345 #ifdef MODEST_HILDON_VERSION_0
1346 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1347 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1349 dialog = hildon_color_chooser_new ();
1350 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1351 #endif /*MODEST_HILDON_VERSION_0*/
1352 g_free (buffer_format);
1354 response = gtk_dialog_run (GTK_DIALOG (dialog));
1356 case GTK_RESPONSE_OK: {
1357 #ifdef MODEST_HILDON_VERSION_0
1358 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1361 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1363 #endif /*MODEST_HILDON_VERSION_0*/
1370 gtk_widget_destroy (dialog);
1372 if (new_color != NULL)
1373 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1378 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1381 ModestMsgEditWindowPrivate *priv;
1382 GtkWidget *dialog = NULL;
1384 GdkColor *old_color = NULL;
1385 const GdkColor *new_color = NULL;
1387 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1388 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1390 #ifdef MODEST_HILDON_VERSION_0
1391 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1392 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1394 dialog = hildon_color_chooser_new ();
1395 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1396 #endif /*MODEST_HILDON_VERSION_9*/
1398 response = gtk_dialog_run (GTK_DIALOG (dialog));
1400 case GTK_RESPONSE_OK: {
1401 #ifdef MODEST_HILDON_VERSION_0
1402 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1405 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1407 #endif /*MODEST_HILDON_VERSION_0*/
1413 gtk_widget_destroy (dialog);
1415 if (new_color != NULL)
1416 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1422 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1425 ModestMsgEditWindowPrivate *priv;
1426 GtkWidget *dialog = NULL;
1428 GSList *uris = NULL;
1429 GSList *uri_node = NULL;
1431 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1433 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1434 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1435 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1437 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1439 response = gtk_dialog_run (GTK_DIALOG (dialog));
1441 case GTK_RESPONSE_OK:
1442 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1447 gtk_widget_destroy (dialog);
1449 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1451 GnomeVFSHandle *handle = NULL;
1452 GnomeVFSResult result;
1453 GtkTextIter position;
1454 GtkTextMark *insert_mark;
1456 uri = (const gchar *) uri_node->data;
1457 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1458 if (result == GNOME_VFS_OK) {
1459 GdkPixbufLoader *loader;
1461 GnomeVFSFileInfo info;
1462 gchar *filename, *basename;
1463 TnyMimePart *mime_part;
1466 const gchar *mime_type = NULL;
1468 filename = g_filename_from_uri (uri, NULL, NULL);
1469 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1471 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1473 mime_part = tny_platform_factory_new_mime_part
1474 (modest_runtime_get_platform_factory ());
1475 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1477 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1479 content_id = g_strdup_printf ("%d", priv->last_cid);
1480 tny_mime_part_set_content_id (mime_part, content_id);
1481 g_free (content_id);
1484 basename = g_path_get_basename (filename);
1485 tny_mime_part_set_filename (mime_part, basename);
1488 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1489 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1491 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1492 gtk_widget_show_all (priv->attachments_caption);
1493 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1496 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1497 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1498 unsigned char read_buffer[128];
1500 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1501 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1504 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1505 g_object_ref (pixbuf);
1506 gdk_pixbuf_loader_close (loader, NULL);
1507 g_object_unref (loader);
1509 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1510 GdkPixbuf *new_pixbuf;
1512 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1513 gdk_pixbuf_get_width (pixbuf);
1514 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1515 g_object_unref (pixbuf);
1516 pixbuf = new_pixbuf;
1519 if (pixbuf != NULL) {
1520 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1521 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1522 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1531 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1534 ModestMsgEditWindowPrivate *priv;
1535 GtkWidget *dialog = NULL;
1537 GSList *uris = NULL;
1540 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1542 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1543 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1545 response = gtk_dialog_run (GTK_DIALOG (dialog));
1547 case GTK_RESPONSE_OK:
1548 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1553 gtk_widget_destroy (dialog);
1555 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1557 GnomeVFSHandle *handle = NULL;
1558 GnomeVFSResult result;
1560 uri = (const gchar *) uri_node->data;
1561 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1562 if (result == GNOME_VFS_OK) {
1563 TnyMimePart *mime_part;
1565 const gchar *mime_type = NULL;
1569 GnomeVFSFileInfo info;
1571 filename = g_filename_from_uri (uri, NULL, NULL);
1573 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1574 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1575 mime_part = tny_platform_factory_new_mime_part
1576 (modest_runtime_get_platform_factory ());
1577 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1579 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1581 content_id = g_strdup_printf ("%d", priv->last_cid);
1582 tny_mime_part_set_content_id (mime_part, content_id);
1583 g_free (content_id);
1586 basename = g_path_get_basename (filename);
1587 tny_mime_part_set_filename (mime_part, basename);
1590 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1591 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1593 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1594 gtk_widget_show_all (priv->attachments_caption);
1595 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1600 g_slist_foreach (uris, (GFunc) g_free, NULL);
1601 g_slist_free (uris);
1605 modest_msg_edit_window_attach_file_noninteractive (
1606 ModestMsgEditWindow *window,
1607 const gchar *file_uri)
1610 ModestMsgEditWindowPrivate *priv;
1612 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1614 if (file_uri && strlen(file_uri)) {
1617 /* TODO: We should probably try to use only the URI,
1618 * instead of using a filename.
1620 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1622 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1625 file_id = g_open (filename, O_RDONLY, 0);
1626 if (file_id != -1) {
1627 TnyMimePart *mime_part;
1629 const gchar *mime_type;
1632 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1633 mime_type = gnome_vfs_get_mime_type(filename);
1635 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1637 mime_part = tny_platform_factory_new_mime_part
1638 (modest_runtime_get_platform_factory ());
1639 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1641 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1643 content_id = g_strdup_printf ("%d", priv->last_cid);
1644 tny_mime_part_set_content_id (mime_part, content_id);
1645 g_free (content_id);
1648 basename = g_path_get_basename (filename);
1649 tny_mime_part_set_filename (mime_part, basename);
1652 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1653 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1655 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1656 gtk_widget_show_all (priv->attachments_caption);
1657 } else if (file_id == -1) {
1659 g_warning("file to be attached does not exist: %s", filename);
1667 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1670 ModestMsgEditWindowPrivate *priv;
1671 gboolean clean_list = FALSE;
1673 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1674 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1676 if (att_list == NULL) {
1677 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1681 if (att_list == NULL) {
1682 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1684 GtkWidget *confirmation_dialog = NULL;
1685 gboolean dialog_response;
1687 gchar *message = NULL;
1688 const gchar *filename = NULL;
1690 if (att_list->next == NULL) {
1691 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1695 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1696 att_list->next == NULL), filename);
1697 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1699 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1700 gtk_widget_destroy (confirmation_dialog);
1701 if (!dialog_response) {
1703 g_list_free (att_list);
1706 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1708 for (node = att_list; node != NULL; node = g_list_next (node)) {
1709 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1710 const gchar *att_id;
1711 priv->attachments = g_list_remove (priv->attachments, mime_part);
1713 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1715 if (priv->attachments == NULL)
1716 gtk_widget_hide (priv->attachments_caption);
1717 att_id = tny_mime_part_get_content_id (mime_part);
1719 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1721 g_object_unref (mime_part);
1722 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1727 g_list_free (att_list);
1731 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1734 ModestMsgEditWindowPrivate *priv;
1735 GdkColor *new_color;
1736 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1738 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1739 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1742 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1744 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1746 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1748 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1753 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1756 ModestMsgEditWindowPrivate *priv;
1757 gint new_size_index;
1758 ModestMsgEditWindow *window;
1761 window = MODEST_MSG_EDIT_WINDOW (userdata);
1762 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1763 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1765 if (gtk_check_menu_item_get_active (menu_item)) {
1767 WPTextBufferFormat format;
1769 memset (&format, 0, sizeof (format));
1770 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1772 label = gtk_bin_get_child (GTK_BIN (menu_item));
1774 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1775 format.cs.font_size = TRUE;
1776 format.cs.text_position = TRUE;
1777 format.cs.font = TRUE;
1778 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1779 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1781 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1782 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1783 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1785 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1786 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1787 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1793 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1796 ModestMsgEditWindowPrivate *priv;
1797 gint new_font_index;
1798 ModestMsgEditWindow *window;
1801 window = MODEST_MSG_EDIT_WINDOW (userdata);
1802 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1803 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1805 if (gtk_check_menu_item_get_active (menu_item)) {
1808 label = gtk_bin_get_child (GTK_BIN (menu_item));
1810 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1812 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1813 (gpointer) new_font_index))
1814 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1816 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1817 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1818 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1824 modest_msg_edit_window_set_zoom (ModestWindow *window,
1827 ModestMsgEditWindowPrivate *priv;
1828 ModestWindowPrivate *parent_priv;
1829 GtkRadioAction *zoom_radio_action;
1831 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1833 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1834 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1835 priv->zoom_level = zoom;
1836 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1838 /* Zoom level menu options should be updated with the current zoom level */
1839 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1840 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1841 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1842 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1843 /* FIXME: Not availible before Gtk 2.10 */
1845 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1850 modest_msg_edit_window_get_zoom (ModestWindow *window)
1852 ModestMsgEditWindowPrivate *priv;
1854 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1856 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1857 return priv->zoom_level;
1861 zoom_allowed (ModestMsgEditWindow *window)
1865 focus = gtk_window_get_focus (GTK_WINDOW (window));
1866 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1870 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1872 ModestWindowPrivate *parent_priv;
1873 GtkRadioAction *zoom_radio_action;
1874 GSList *group, *node;
1876 /* First we check if the text view is focused. If not, zooming is not allowed */
1877 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1878 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1882 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1883 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1884 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1886 group = gtk_radio_action_get_group (zoom_radio_action);
1888 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1889 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1893 for (node = group; node != NULL; node = g_slist_next (node)) {
1894 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1895 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1903 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1905 ModestWindowPrivate *parent_priv;
1906 GtkRadioAction *zoom_radio_action;
1907 GSList *group, *node;
1909 /* First we check if the text view is focused. If not, zooming is not allowed */
1910 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1911 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1915 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1916 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1917 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1919 group = gtk_radio_action_get_group (zoom_radio_action);
1921 for (node = group; node != NULL; node = g_slist_next (node)) {
1922 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1923 if (node->next != NULL) {
1924 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1927 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1935 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1937 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1938 ModestWindowPrivate *parent_priv;
1939 ModestWindowMgr *mgr;
1940 gboolean is_fullscreen;
1941 GtkAction *fs_toggle_action;
1944 mgr = modest_runtime_get_window_mgr ();
1945 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1947 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1949 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1950 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1951 if (is_fullscreen != active)
1952 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1960 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1962 ModestWindowPrivate *parent_priv;
1963 GtkAction *fs_toggle_action;
1966 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1968 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1969 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1970 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1974 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1977 ModestMsgEditWindowPrivate *priv = NULL;
1978 const gchar *recipients;
1979 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1981 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1982 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1983 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
1984 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
1985 gtk_widget_show (priv->cc_caption);
1987 gtk_widget_hide (priv->cc_caption);
1988 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1992 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1995 ModestMsgEditWindowPrivate *priv = NULL;
1996 const gchar *recipients;
1997 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1999 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2000 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2001 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2002 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2003 gtk_widget_show (priv->bcc_caption);
2005 gtk_widget_hide (priv->bcc_caption);
2006 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2010 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2011 ModestRecptEditor *editor)
2013 ModestMsgEditWindowPrivate *priv;
2015 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2016 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2017 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2019 if (editor == NULL) {
2020 GtkWidget *view_focus;
2021 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2023 /* This code should be kept in sync with ModestRecptEditor. The
2024 textview inside the recpt editor is the one that really gets the
2025 focus. As it's inside a scrolled window, and this one inside the
2026 hbox recpt editor inherits from, we'll need to go up in the
2027 hierarchy to know if the text view is part of the recpt editor
2028 or if it's a different text entry */
2030 if (gtk_widget_get_parent (view_focus)) {
2031 GtkWidget *first_parent;
2033 first_parent = gtk_widget_get_parent (view_focus);
2034 if (gtk_widget_get_parent (first_parent) &&
2035 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2036 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2041 editor = MODEST_RECPT_EDITOR (priv->to_field);
2045 modest_address_book_select_addresses (editor);
2050 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2052 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2054 modest_msg_edit_window_open_addressbook (window, NULL);
2058 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2059 gboolean show_toolbar)
2061 ModestWindowPrivate *parent_priv;
2063 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2064 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2066 /* FIXME: we can not just use the code of
2067 modest_msg_edit_window_setup_toolbar because it has a
2068 mixture of both initialization and creation code. */
2071 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2073 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2077 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2078 TnyHeaderFlags priority_flags)
2080 ModestMsgEditWindowPrivate *priv;
2081 ModestWindowPrivate *parent_priv;
2083 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2085 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2086 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2087 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2089 if (priv->priority_flags != priority_flags) {
2090 GtkAction *priority_action = NULL;
2092 priv->priority_flags = priority_flags;
2094 switch (priority_flags) {
2095 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2096 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2097 gtk_widget_show (priv->priority_icon);
2098 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2099 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2101 case TNY_HEADER_FLAG_LOW_PRIORITY:
2102 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2103 gtk_widget_show (priv->priority_icon);
2104 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2105 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2108 gtk_widget_hide (priv->priority_icon);
2109 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2110 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2113 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2114 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2119 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2122 ModestMsgEditWindowPrivate *priv;
2123 gint current_format;
2125 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2127 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2129 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2130 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2132 if (current_format != file_format) {
2133 switch (file_format) {
2134 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2135 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2137 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2141 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2142 response = gtk_dialog_run (GTK_DIALOG (dialog));
2143 gtk_widget_destroy (dialog);
2144 if (response == GTK_RESPONSE_OK)
2145 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2149 update_dimmed (window);
2154 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2157 ModestMsgEditWindowPrivate *priv;
2158 WPTextBufferFormat oldfmt, fmt;
2159 gint old_position = 0;
2163 GdkColor *color = NULL;
2164 gboolean bold, bold_set, italic, italic_set;
2165 gboolean underline, underline_set;
2166 gboolean strikethrough, strikethrough_set;
2167 gboolean position_set;
2168 gboolean font_size_set, font_set, color_set;
2171 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2172 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2174 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2176 /* First we get the currently selected font information */
2177 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2178 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2180 switch (oldfmt.text_position) {
2181 case TEXT_POSITION_NORMAL:
2184 case TEXT_POSITION_SUPERSCRIPT:
2192 g_object_set (G_OBJECT (dialog),
2193 "bold", oldfmt.bold != FALSE,
2194 "bold-set", !oldfmt.cs.bold,
2195 "underline", oldfmt.underline != FALSE,
2196 "underline-set", !oldfmt.cs.underline,
2197 "italic", oldfmt.italic != FALSE,
2198 "italic-set", !oldfmt.cs.italic,
2199 "strikethrough", oldfmt.strikethrough != FALSE,
2200 "strikethrough-set", !oldfmt.cs.strikethrough,
2201 "color", &oldfmt.color,
2202 "color-set", !oldfmt.cs.color,
2203 "size", wp_font_size[oldfmt.font_size],
2204 "size-set", !oldfmt.cs.font_size,
2205 "position", old_position,
2206 "position-set", !oldfmt.cs.text_position,
2207 "family", wp_get_font_name (oldfmt.font),
2208 "family-set", !oldfmt.cs.font,
2211 gtk_widget_show_all (dialog);
2212 response = gtk_dialog_run (GTK_DIALOG (dialog));
2213 if (response == GTK_RESPONSE_OK) {
2215 g_object_get( dialog,
2217 "bold-set", &bold_set,
2218 "underline", &underline,
2219 "underline-set", &underline_set,
2221 "italic-set", &italic_set,
2222 "strikethrough", &strikethrough,
2223 "strikethrough-set", &strikethrough_set,
2225 "color-set", &color_set,
2227 "size-set", &font_size_set,
2228 "family", &font_name,
2229 "family-set", &font_set,
2230 "position", &position,
2231 "position-set", &position_set,
2236 if (response == GTK_RESPONSE_OK) {
2237 memset(&fmt, 0, sizeof(fmt));
2243 fmt.italic = italic;
2244 fmt.cs.italic = TRUE;
2246 if (underline_set) {
2247 fmt.underline = underline;
2248 fmt.cs.underline = TRUE;
2250 if (strikethrough_set) {
2251 fmt.strikethrough = strikethrough;
2252 fmt.cs.strikethrough = TRUE;
2257 ? TEXT_POSITION_NORMAL
2258 : ( ( position == 1 )
2259 ? TEXT_POSITION_SUPERSCRIPT
2260 : TEXT_POSITION_SUBSCRIPT );
2261 fmt.cs.text_position = TRUE;
2265 fmt.cs.color = TRUE;
2268 fmt.font = wp_get_font_index(font_name,
2273 if (font_size_set) {
2274 fmt.font_size = wp_get_font_size_index(
2275 font_size, DEFAULT_FONT_SIZE);
2276 fmt.cs.font_size = TRUE;
2278 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2280 gtk_widget_destroy (dialog);
2282 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2286 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2288 ModestMsgEditWindowPrivate *priv;
2290 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2291 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2293 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2295 update_dimmed (window);
2300 update_dimmed (ModestMsgEditWindow *window)
2302 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2303 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2307 gboolean editor_focused;
2309 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2310 editor_focused = gtk_widget_is_focus (priv->msg_body);
2312 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2313 gtk_action_set_sensitive (action, rich_text && editor_focused);
2314 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2315 gtk_action_set_sensitive (action, rich_text && editor_focused);
2316 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2317 gtk_action_set_sensitive (action, rich_text && editor_focused);
2318 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2319 gtk_action_set_sensitive (action, rich_text && editor_focused);
2320 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2321 gtk_action_set_sensitive (action, rich_text && editor_focused);
2322 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2323 gtk_action_set_sensitive (action, rich_text && editor_focused);
2324 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2325 gtk_action_set_sensitive (action, rich_text && editor_focused);
2326 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2327 gtk_action_set_sensitive (action, rich_text && editor_focused);
2328 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2329 gtk_action_set_sensitive (action, rich_text && editor_focused);
2330 widget = priv->font_color_button;
2331 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2332 widget = priv->font_size_toolitem;
2333 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2334 widget = priv->font_face_toolitem;
2335 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2339 setup_insensitive_handlers (ModestMsgEditWindow *window)
2341 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2342 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2345 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2346 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2347 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2348 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2350 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2351 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2352 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2353 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2354 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2355 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2356 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2357 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2358 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2359 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2360 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2361 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2362 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2363 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2364 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2365 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2366 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2367 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2368 widget = priv->font_color_button;
2369 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2370 widget = priv->font_size_toolitem;
2371 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2372 widget = priv->font_face_toolitem;
2373 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2375 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2376 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2377 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2378 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2380 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2381 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (paste_insensitive_press), window);
2385 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2387 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2390 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2391 gtk_action_set_sensitive (action, can_undo);
2395 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2398 GtkTextIter match_start, match_end;
2400 if (image_id == NULL)
2403 gtk_text_buffer_get_start_iter (buffer, &iter);
2405 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2406 GSList *tags = gtk_text_iter_get_tags (&match_start);
2408 for (node = tags; node != NULL; node = g_slist_next (node)) {
2409 GtkTextTag *tag = (GtkTextTag *) node->data;
2410 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2411 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2412 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2414 offset = gtk_text_iter_get_offset (&match_start);
2415 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2416 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2420 gtk_text_iter_forward_char (&iter);
2425 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2427 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2428 GtkTextIter real_start, real_end;
2429 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2431 if (gtk_text_iter_compare (start, end) > 0) {
2435 real_start = *start;
2439 GSList *tags = gtk_text_iter_get_tags (&real_start);
2441 for (node = tags; node != NULL; node = g_slist_next (node)) {
2442 GtkTextTag *tag = (GtkTextTag *) node->data;
2443 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2444 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2446 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2448 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2451 } while (gtk_text_iter_forward_char (&real_start)&&
2452 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2456 msg_body_focus (GtkWidget *focus,
2457 GdkEventFocus *event,
2461 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2466 recpt_field_changed (GtkTextBuffer *buffer,
2467 ModestMsgEditWindow *editor)
2469 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2470 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2471 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2472 gboolean dim = FALSE;
2475 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2476 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2477 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2479 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2480 gtk_text_buffer_get_char_count (cc_buffer) +
2481 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2483 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2484 gtk_action_set_sensitive (action, !dim);
2485 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2486 gtk_action_set_sensitive (action, !dim);
2490 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2492 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2496 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2498 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2502 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2504 ModestWindowPrivate *parent_priv;
2505 ModestMsgEditWindowPrivate *priv;
2506 GList *selected_attachments = NULL;
2507 gint n_att_selected = 0;
2509 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2510 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2512 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2513 n_att_selected = g_list_length (selected_attachments);
2514 g_list_free (selected_attachments);
2516 if (n_att_selected > 1)
2517 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2518 else if (n_att_selected == 0)
2519 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2524 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2526 gboolean rich_text, editor_focused;
2528 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2529 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2530 editor_focused = gtk_widget_is_focus (priv->msg_body);
2533 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2534 else if (!editor_focused)
2535 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2539 reset_modified (ModestMsgEditWindow *editor)
2541 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2542 GtkTextBuffer *buffer;
2544 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2545 gtk_text_buffer_set_modified (buffer, FALSE);
2546 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2547 gtk_text_buffer_set_modified (buffer, FALSE);
2548 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2549 gtk_text_buffer_set_modified (buffer, FALSE);
2550 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2554 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2556 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2557 GtkTextBuffer *buffer;
2559 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2560 if (gtk_text_buffer_get_modified (buffer))
2562 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2563 if (gtk_text_buffer_get_modified (buffer))
2565 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2566 if (gtk_text_buffer_get_modified (buffer))
2568 if (gtk_text_buffer_get_modified (priv->text_buffer))
2575 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2577 ModestMsgEditWindowPrivate *priv = NULL;
2579 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2580 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2582 /* check if there's no recipient added */
2583 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2584 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2585 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2586 /* no recipient contents, then select contacts */
2587 modest_msg_edit_window_open_addressbook (window, NULL);
2591 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2593 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2595 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2598 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2605 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2606 ModestMsgEditWindow *window)
2608 modest_msg_edit_window_attach_file (window);
2612 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2614 ModestMsgEditWindow *window)
2616 ModestWindowPrivate *parent_priv;
2617 ModestMsgEditWindowPrivate *priv;
2621 GList *selected_attachments = NULL;
2622 gint n_att_selected = 0;
2624 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2625 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2626 selection = gtk_clipboard_wait_for_text (clipboard);
2627 focused = gtk_window_get_focus (GTK_WINDOW (window));
2629 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2630 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2631 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2632 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2634 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2635 n_att_selected = g_list_length (selected_attachments);
2636 g_list_free (selected_attachments);
2638 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2639 gtk_action_set_sensitive (action, n_att_selected == 1);
2642 update_paste_dimming (window);
2646 update_window_title (ModestMsgEditWindow *window)
2648 ModestMsgEditWindowPrivate *priv = NULL;
2649 const gchar *subject;
2651 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2652 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2653 if (subject == NULL || subject[0] == '\0')
2654 subject = _("mail_va_new_email");
2656 gtk_window_set_title (GTK_WINDOW (window), subject);
2661 subject_field_changed (GtkEditable *editable,
2662 ModestMsgEditWindow *window)
2664 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2665 update_window_title (window);
2666 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2670 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2673 ModestMsgEditWindowPrivate *priv = NULL;
2675 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2676 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2678 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2680 gtk_widget_show_all (priv->find_toolbar);
2681 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2683 gtk_widget_hide_all (priv->find_toolbar);
2684 gtk_widget_grab_focus (priv->msg_body);
2690 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2692 GtkTextIter *match_start,
2693 GtkTextIter *match_end)
2695 GtkTextIter end_iter;
2696 gchar *str_casefold;
2699 gchar *range_casefold;
2702 gboolean result = FALSE;
2709 gtk_text_iter_forward_to_end (&end_iter);
2711 str_casefold = g_utf8_casefold (str, -1);
2712 str_chars_n = strlen (str);
2714 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2715 range_casefold = g_utf8_casefold (range_text, -1);
2716 range_chars_n = strlen (range_casefold);
2718 if (range_chars_n < str_chars_n) {
2719 g_free (str_casefold);
2720 g_free (range_text);
2721 g_free (range_casefold);
2725 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2726 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2727 if (!g_utf8_collate (range_subtext, str_casefold)) {
2728 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2730 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2731 match_start, match_end, NULL);
2732 g_free (found_text);
2734 g_free (range_subtext);
2738 g_free (str_casefold);
2739 g_free (range_text);
2740 g_free (range_casefold);
2747 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2748 ModestMsgEditWindow *window)
2750 gchar *current_search = NULL;
2751 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2753 GtkTextIter selection_start, selection_end;
2754 GtkTextIter match_start, match_end;
2755 gboolean continue_search = FALSE;
2757 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2758 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2759 g_free (current_search);
2760 g_free (priv->last_search);
2761 priv->last_search = NULL;
2762 /* Information banner about empty search */
2763 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2767 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2768 continue_search = TRUE;
2770 g_free (priv->last_search);
2771 priv->last_search = g_strdup (current_search);
2774 if (continue_search) {
2775 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2776 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2777 &match_start, &match_end);
2779 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2781 GtkTextIter buffer_start;
2782 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2783 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2784 &match_start, &match_end);
2786 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2789 /* Mark as selected the string found in search */
2791 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2792 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2794 g_free (priv->last_search);
2795 priv->last_search = NULL;
2797 g_free (current_search);
2801 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2802 ModestMsgEditWindow *window)
2804 GtkToggleAction *toggle;
2805 ModestWindowPrivate *parent_priv;
2806 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2808 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2809 gtk_toggle_action_set_active (toggle, FALSE);
2814 update_paste_dimming (ModestMsgEditWindow *window)
2816 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2817 GtkAction *action = NULL;
2818 GtkClipboard *clipboard = NULL;
2822 focused = gtk_window_get_focus (GTK_WINDOW (window));
2824 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2825 active = gtk_clipboard_wait_is_text_available (clipboard);
2828 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2832 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2833 gtk_action_set_sensitive (action, active);
2838 paste_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2840 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (editor));
2842 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2843 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
2845 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
2851 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2853 ModestMsgEditWindow *window)
2855 update_paste_dimming (window);
2859 update_select_all_dimming (ModestMsgEditWindow *window)
2862 gboolean dimmed = FALSE;
2864 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2866 focused = gtk_window_get_focus (GTK_WINDOW (window));
2867 if (GTK_IS_ENTRY (focused)) {
2868 const gchar *current_text;
2869 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2870 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2871 } else if (GTK_IS_TEXT_VIEW (focused)) {
2872 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2873 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2874 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2877 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2878 gtk_action_set_sensitive (action, !dimmed);
2882 update_zoom_dimming (ModestMsgEditWindow *window)
2885 gboolean dimmed = FALSE;
2887 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2889 focused = gtk_window_get_focus (GTK_WINDOW (window));
2890 dimmed = ! WP_IS_TEXT_VIEW (focused);
2891 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2892 gtk_action_set_sensitive (action, !dimmed);
2896 edit_menu_activated (GtkAction *action,
2899 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2901 update_select_all_dimming (window);
2904 view_menu_activated (GtkAction *action,
2907 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2909 update_zoom_dimming (window);
2913 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2915 ModestMsgEditWindowPrivate *priv;
2917 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2922 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2925 ModestMsgEditWindowPrivate *priv;
2927 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);