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.
32 #include <glade/glade.h>
33 #include <glib/gi18n.h>
38 #endif /*HAVE_CONFIG_H*/
40 #include <hildon-widgets/hildon-window.h>
41 #include <hildon-widgets/hildon-program.h>
43 /* TODO: put in auto* */
44 #include <tny-text-buffer-stream.h>
45 #include <tny-msg-folder.h>
47 #include "../modest-ui.h"
48 #include "../modest-window-mgr.h"
49 #include "../modest-account-mgr.h"
50 #include "../modest-account-mgr.h"
51 #include "../modest-identity-mgr.h"
53 #include "../modest-tny-account-store.h"
54 #include "../modest-tny-folder-tree-view.h"
55 #include "../modest-tny-header-tree-view.h"
56 #include "../modest-tny-msg-view.h"
57 #include "../modest-tny-transport-actions.h"
58 #include "../modest-tny-store-actions.h"
60 #include "../modest-text-utils.h"
61 #include "../modest-tny-msg-actions.h"
63 #include "../modest-tny-attachment.h"
65 #include "../modest-editor-window.h"
67 #include "modest-ui-glade.h"
68 #include "modest-ui-wizard.h"
70 #include "modest-ui-message-editor.h"
73 static void on_attach_button_clicked (GtkWidget *widget, ModestEditorWindow *modest_editwin);
75 static void on_send_button_clicked (GtkWidget *widget, ModestEditorWindow *modest_editwin);
80 ModestEditorWindow *edit_win;
86 static gboolean close_edit_confirm_dialog(ModestEditorWindow *edit_win)
91 mdialog = gtk_message_dialog_new(GTK_WINDOW(edit_win->window),
92 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
95 _("Message was modified.\nDiscard Changes?"));
96 gtk_widget_show_all (mdialog);
98 res=gtk_dialog_run(GTK_DIALOG(mdialog));
99 gtk_widget_destroy (mdialog);
100 if (res == GTK_RESPONSE_YES)
107 close_edit_window (GtkWidget *win, GdkEvent *event, gpointer data)
109 ModestEditorWindow *edit_win;
110 ModestUIPrivate *priv;
111 EditWinData *win_data;
113 edit_win = (ModestEditorWindow *)data;
114 win_data = modest_editor_window_get_data(edit_win);
115 priv = MODEST_UI_GET_PRIVATE(win_data->modest_ui);
117 if (modest_editor_window_get_modified(edit_win)) {
118 if (close_edit_confirm_dialog(edit_win)) {
119 gtk_widget_hide (GTK_WIDGET(edit_win->window));
120 modest_window_mgr_unregister(priv->modest_window_mgr, G_OBJECT(edit_win->window));
121 hildon_program_remove_window (priv->program, HILDON_WINDOW (edit_win->window));
122 g_object_unref(edit_win);
123 g_message("closing window");
125 g_message("not closing window");
128 gtk_widget_hide (GTK_WIDGET(edit_win->window));
129 modest_window_mgr_unregister(priv->modest_window_mgr, G_OBJECT (edit_win->window));
130 hildon_program_remove_window (priv->program, HILDON_WINDOW (edit_win->window));
131 g_object_unref(edit_win);
132 g_message("closing window");
138 *modest_ui_new_editor_window (ModestUI *modest_ui, gpointer *user_data)
140 GtkWidget *top_container;
142 EditWinData *win_data;
144 glade_xml = glade_xml_new(MODEST_GLADE, "new_mail", NULL);
148 win_data = g_malloc(sizeof(EditWinData));
149 win_data->modest_ui = modest_ui;
150 win_data->glade_xml = glade_xml;
151 win_data->attachments = NULL;
153 *user_data = win_data;
155 top_container = glade_xml_get_widget(glade_xml, "new_mail");
156 if (!top_container) {
157 g_warning ("Could not create window\n");
158 g_object_unref(G_OBJECT(glade_xml));
162 return GTK_CONTAINER(top_container);
167 modest_ui_editor_window_set_to_header(const gchar *to, gpointer window_data)
171 EditWinData *win_data;
173 win_data = (EditWinData *)window_data;
174 glade_xml = win_data->glade_xml;
175 w = glade_xml_get_widget(glade_xml, "to_entry");
176 gtk_entry_set_text(GTK_ENTRY(w), to);
183 modest_ui_editor_window_set_cc_header(const gchar *cc, gpointer window_data)
187 EditWinData *win_data;
189 win_data = (EditWinData *)window_data;
190 glade_xml = win_data->glade_xml;
192 w = glade_xml_get_widget(glade_xml, "cc_entry");
193 gtk_entry_set_text(GTK_ENTRY(w), cc);
200 modest_ui_editor_window_set_bcc_header(const gchar *bcc, gpointer window_data)
204 EditWinData *win_data;
206 win_data = (EditWinData *)window_data;
207 glade_xml = win_data->glade_xml;
209 w = glade_xml_get_widget(glade_xml, "bcc_entry");
210 gtk_entry_set_text(GTK_ENTRY(w), bcc);
217 modest_ui_editor_window_set_subject_header(const gchar *subject, gpointer window_data)
221 EditWinData *win_data;
223 win_data = (EditWinData *)window_data;
224 glade_xml = win_data->glade_xml;
226 w = glade_xml_get_widget(glade_xml, "subject_entry");
227 gtk_entry_set_text(GTK_ENTRY(w), subject);
234 modest_ui_editor_window_set_body(const gchar *body, gpointer window_data)
237 GtkWidget *body_view;
239 EditWinData *win_data;
241 win_data = (EditWinData *)window_data;
242 glade_xml = win_data->glade_xml;
244 body_view = glade_xml_get_widget(glade_xml, "body_view");
245 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(body_view));
247 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(buf), body, -1);
254 modest_ui_editor_window_update_attachments(gpointer window_data)
258 glade_xml = ((EditWinData *) window_data)->glade_xml;
260 //body_view = glade_xml_get_widget(glade_xml, "body_view");
267 void on_editor_entry_changed(GtkEditable *editable,
271 EditWinData *windata;
273 edit_win = (GtkWidget *)user_data;
274 windata = (EditWinData *)modest_editor_window_get_data(MODEST_EDITOR_WINDOW(edit_win));
276 modest_editor_window_set_modified(MODEST_EDITOR_WINDOW(edit_win), TRUE);
281 void on_editor_buffer_changed (GtkTextBuffer *textbuffer,
286 edit_win = (GtkWidget *)user_data;
287 modest_editor_window_set_modified(MODEST_EDITOR_WINDOW(edit_win), TRUE);
292 new_editor_with_presets (ModestUI *modest_ui, const gchar *to_header,
293 const gchar *cc_header, const gchar *bcc_header,
294 const gchar *subject_header, const gchar *body,
295 const GList *attachments)
297 ModestEditorWindow *edit_win;
301 EditWinData *windata;
302 ModestUIPrivate *priv;
303 GtkWidget *toolbar, *menubar, *menu, *menu_item;
305 g_return_if_fail (modest_ui);
307 edit_win = MODEST_EDITOR_WINDOW (modest_editor_window_new(modest_ui));
308 windata = (EditWinData *)modest_editor_window_get_data(MODEST_EDITOR_WINDOW(edit_win));
309 g_return_if_fail(windata);
311 glade_xml = windata->glade_xml;
312 btn = glade_xml_get_widget (glade_xml, "toolb_send");
313 g_signal_connect (btn, "clicked", G_CALLBACK(on_send_button_clicked),
315 btn = glade_xml_get_widget (glade_xml, "toolb_attach");
316 g_signal_connect (btn, "clicked", G_CALLBACK(on_attach_button_clicked),
319 w = glade_xml_get_widget (glade_xml, "to_entry");
320 g_signal_connect(w, "changed", G_CALLBACK(on_editor_entry_changed), edit_win);
321 w = glade_xml_get_widget (glade_xml, "subject_entry");
322 g_signal_connect(w, "changed", G_CALLBACK(on_editor_entry_changed), edit_win);
323 w = glade_xml_get_widget (glade_xml, "body_view");
324 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
325 g_signal_connect(buf, "changed", G_CALLBACK(on_editor_buffer_changed), edit_win);
327 g_signal_connect (edit_win->window, "destroy-event", G_CALLBACK(close_edit_window),
329 g_signal_connect (edit_win->window, "delete-event", G_CALLBACK(close_edit_window),
332 priv = MODEST_UI_GET_PRIVATE(modest_ui);
334 if (strlen(subject_header) > 0)
335 gtk_window_set_title (GTK_WINDOW(edit_win->window), subject_header);
337 gtk_window_set_title (GTK_WINDOW(edit_win->window), _("Untitled"));
339 modest_window_mgr_register(priv->modest_window_mgr, G_OBJECT(edit_win->window), MODEST_EDIT_WINDOW, 0);
341 modest_editor_window_set_to_header(MODEST_EDITOR_WINDOW(edit_win), to_header);
342 modest_editor_window_set_cc_header(MODEST_EDITOR_WINDOW(edit_win), cc_header);
343 modest_editor_window_set_bcc_header(MODEST_EDITOR_WINDOW(edit_win), bcc_header);
344 modest_editor_window_set_subject_header(MODEST_EDITOR_WINDOW(edit_win), subject_header);
345 modest_editor_window_set_body(MODEST_EDITOR_WINDOW(edit_win), body);
346 modest_editor_window_set_attachments(MODEST_EDITOR_WINDOW(edit_win), attachments);
348 modest_editor_window_set_modified(MODEST_EDITOR_WINDOW(edit_win), FALSE);
350 menu = gtk_menu_new();
351 menu_item = glade_xml_get_widget (priv->glade_xml, "menuitem5");
352 gtk_widget_reparent(menu_item, menu);
353 menu_item = glade_xml_get_widget (priv->glade_xml, "menuitem13");
354 gtk_widget_reparent(menu_item, menu);
355 menu_item = glade_xml_get_widget (priv->glade_xml, "menuitem22");
356 gtk_widget_reparent(menu_item, menu);
357 menu_item = glade_xml_get_widget (priv->glade_xml, "menuitem27");
358 gtk_widget_reparent(menu_item, menu);
359 menu_item = glade_xml_get_widget (priv->glade_xml, "menuitem29");
360 gtk_widget_reparent(menu_item, menu);
361 menu_item = glade_xml_get_widget (priv->glade_xml, "menuitem34");
362 gtk_widget_reparent(menu_item, menu);
363 menu_item = glade_xml_get_widget (priv->glade_xml, "menuitem41");
364 gtk_widget_reparent(menu_item, menu);
366 hildon_window_set_menu (HILDON_WINDOW (edit_win->window), GTK_MENU(menu));
368 toolbar = glade_xml_get_widget (priv->glade_xml, "toolbar2");
369 gtk_widget_hide (toolbar);
370 g_object_ref (toolbar);
371 gtk_container_remove (GTK_CONTAINER (glade_xml_get_widget (priv->glade_xml,
372 "new_mail_top_container")), toolbar);
373 hildon_window_add_toolbar (HILDON_WINDOW (edit_win->window), GTK_TOOLBAR (toolbar));
374 gtk_widget_show_all (GTK_WIDGET (edit_win->window));
376 while (gtk_events_pending ())
377 gtk_main_iteration ();
379 toolbar = glade_xml_get_widget (priv->glade_xml, "toolbar2");
380 gtk_widget_hide (toolbar);
382 menubar = glade_xml_get_widget (priv->glade_xml, "menubar2");
383 gtk_widget_hide (GTK_WIDGET(menubar));
385 hildon_program_add_window (priv->program, HILDON_WINDOW (edit_win->window));
390 on_new_mail_clicked (GtkWidget *widget, gpointer user_data)
392 ModestUI *modest_ui = (ModestUI *) user_data;
394 new_editor_with_presets(modest_ui, "", "", "", "", "", NULL);
398 ui_on_mailto_clicked (GtkWidget *widget, const gchar *uri, gpointer user_data)
400 ModestUI *modest_ui = (ModestUI *) user_data;
402 new_editor_with_presets(modest_ui, uri, "", "", "", "", NULL);
407 quoted_send_msg (ModestUI *modest_ui, quoted_send_type qstype)
409 GtkTreeSelection *sel;
413 TnyMsgHeaderIface *header;
415 ModestTnyHeaderTreeView *header_view;
416 ModestTnyMsgView *msg_view;
417 ModestUIPrivate *priv;
419 const TnyMsgIface *msg;
420 const TnyMsgFolderIface *folder;
422 const gchar *subject, *from;
423 gchar *unquoted, *quoted;
425 gint line_limit = 76;
427 GList *attachments = NULL;
429 g_return_if_fail (modest_ui);
431 priv = MODEST_UI_GET_PRIVATE(modest_ui);
433 msg_view = MODEST_TNY_MSG_VIEW(priv->message_view);
434 g_return_if_fail (msg_view);
436 header_view = MODEST_TNY_HEADER_TREE_VIEW(priv->header_view);
437 g_return_if_fail (header_view);
439 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
440 g_return_if_fail (sel);
442 if (!gtk_tree_selection_get_selected (sel, &model, &iter)) {
443 g_warning("nothing to reply to");
447 gtk_tree_model_get (model, &iter,
448 TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN,
452 g_warning("no header");
456 folder = tny_msg_header_iface_get_folder (TNY_MSG_HEADER_IFACE(header));
458 g_warning ("cannot find folder");
462 msg = tny_msg_folder_iface_get_message (TNY_MSG_FOLDER_IFACE(folder), header);
464 g_warning ("cannot find msg");
468 subject = tny_msg_header_iface_get_subject(header);
469 re_sub = g_string_new(subject);
470 /* FIXME: honor replyto, cc */
471 from = tny_msg_header_iface_get_from(header);
472 sent_date = tny_msg_header_iface_get_date_sent(header);
474 unquoted = modest_tny_msg_view_get_selected_text(msg_view);
475 quoted = modest_tny_msg_actions_quote(msg, from, sent_date, line_limit, unquoted);
478 case QUOTED_SEND_REPLY:
479 g_string_prepend(re_sub, _("Re: "));
480 new_editor_with_presets(modest_ui, from, /* cc */ "", /* bcc */ "", re_sub->str, quoted, attachments);
482 case QUOTED_SEND_FORWARD:
483 attachments = modest_tny_attachment_new_list_from_msg(msg, FALSE);
484 g_string_prepend(re_sub, _("Fwd: "));
485 new_editor_with_presets(modest_ui, /* from */ "", /* cc */ "", /* bcc */ "", re_sub->str, quoted, attachments);
487 case QUOTED_SEND_FORWARD_ATTACHED:
488 attachments = modest_tny_attachment_new_list_from_msg(msg, TRUE);
489 g_string_prepend(re_sub, _("Fwd: "));
490 new_editor_with_presets(modest_ui, /* from */ "", /* cc */ "", /* bcc */ "", re_sub->str, "", attachments);
497 g_string_free(re_sub, TRUE);
502 on_attach_button_clicked (GtkWidget *widget, ModestEditorWindow *modest_editwin)
504 /* open file selector */
506 ModestTnyAttachment *attachment;
507 gchar *filename = NULL;
509 dialog = gtk_file_chooser_dialog_new ("Open File",
510 GTK_WINDOW(modest_editwin->window),
511 GTK_FILE_CHOOSER_ACTION_OPEN,
512 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
513 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
516 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
519 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
520 printf ("file:%s\n", filename);
522 gtk_widget_destroy (dialog);
528 attachment = modest_tny_attachment_new();
529 modest_tny_attachment_set_filename(attachment, filename);
530 modest_tny_attachment_guess_mime_type(attachment);
532 modest_editor_window_attach_file(modest_editwin, attachment);
539 on_send_button_clicked (GtkWidget *widget, ModestEditorWindow *modest_editwin)
541 ModestTnyTransportActions *actions;
543 ModestUIPrivate *priv;
544 GtkWidget *to_entry, *subject_entry, *body_view;
545 const gchar *to, *subject, *email_from;
547 GtkTextIter start, end;
549 TnyAccountStoreIface *account_store;
550 TnyListIface *transport_accounts;
551 TnyIteratorIface *iter;
552 TnyTransportAccountIface *transport_account;
553 ModestIdentityMgr *id_mgr;
554 EditWinData *win_data;
558 win_data = modest_editor_window_get_data(modest_editwin);
559 modest_ui = win_data->modest_ui;
561 g_return_if_fail (modest_ui);
563 actions = MODEST_TNY_TRANSPORT_ACTIONS
564 (modest_tny_transport_actions_new ());
566 priv = MODEST_UI_GET_PRIVATE(modest_ui);
568 account_store = priv->account_store;
570 transport_accounts = tny_list_new ();
571 tny_account_store_iface_get_accounts (priv->account_store,
573 TNY_ACCOUNT_STORE_IFACE_TRANSPORT_ACCOUNTS);
574 tny_list_iface_create_iterator (transport_accounts);
576 iter = tny_list_iface_create_iterator(transport_accounts);
577 if (!tny_iterator_iface_first(iter)) {
578 g_message ("cannot send message: no transport account defined");
580 } else /* take the first one! */
582 TNY_TRANSPORT_ACCOUNT_IFACE(tny_iterator_iface_current(iter));
583 g_object_unref (iter);
584 g_object_unref (transport_accounts);
586 to_entry = glade_xml_get_widget (win_data->glade_xml, "to_entry");
587 subject_entry = glade_xml_get_widget (win_data->glade_xml, "subject_entry");
588 body_view = glade_xml_get_widget (win_data->glade_xml, "body_view");
590 to = gtk_entry_get_text (GTK_ENTRY(to_entry));
591 subject = gtk_entry_get_text (GTK_ENTRY(subject_entry));
593 buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(body_view));
594 gtk_text_buffer_get_bounds (buf, &start, &end);
595 body = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
597 id_mgr = priv->modest_id_mgr;
598 email_from = modest_identity_mgr_get_identity_string(id_mgr,
599 MODEST_IDENTITY_DEFAULT_IDENTITY,
600 MODEST_IDENTITY_EMAIL, NULL);
601 attachments = modest_editor_window_get_attachments(modest_editwin);
605 g_message("sending \"%s\" %s ==> %s", subject, email_from, to);
607 modest_tny_transport_actions_send_message (actions,
614 modest_editor_window_set_attachments(modest_editwin, NULL); /* This unrefs them, too. */
616 g_object_unref (G_OBJECT(actions));
618 gtk_widget_hide (GTK_WIDGET(modest_editwin->window));
619 modest_window_mgr_unregister(priv->modest_window_mgr, G_OBJECT(modest_editwin));
620 if (G_IS_OBJECT(modest_editwin)) {
621 g_object_unref(modest_editwin);
623 g_warning("editor window has vanished!");