* ModestTnyStoreAction doesn't have to be a GObject, because it's stateless
[modest] / src / gtk-glade / modest-ui.c
1 /* modest-ui.c */
2
3 /* insert (c)/licensing information) */
4
5 #include <gtk/gtk.h>
6 #include <glade/glade.h>
7 #include <glib/gi18n.h>
8 #include <string.h>
9
10 #ifdef HAVE_CONFIG_H
11 #include <config.h>
12 #endif /*HAVE_CONFIG_H*/
13
14 /* TODO: put in auto* */
15 #include <tny-text-buffer-stream.h>
16 #include <tny-msg-folder.h>
17
18 #include "../modest-ui.h"
19 #include "../modest-window-mgr.h"
20 #include "../modest-account-mgr.h"
21 #include "../modest-account-mgr.h"
22 #include "../modest-identity-mgr.h"
23
24 #include "../modest-tny-account-store.h"
25 #include "../modest-tny-folder-tree-view.h"
26 #include "../modest-tny-header-tree-view.h"
27 #include "../modest-tny-msg-view.h"
28 #include "../modest-tny-transport-actions.h"
29 #include "../modest-tny-store-actions.h"
30
31 #include "../modest-text-utils.h"
32 #include "../modest-tny-msg-actions.h"
33
34 #include "../modest-editor-window.h"
35
36 #include "modest-ui-glade.h"
37 #include "modest-ui-wizard.h"
38
39 /* 'private'/'protected' functions */
40 static void   modest_ui_class_init     (ModestUIClass *klass);
41 static void   modest_ui_init           (ModestUI *obj);
42 static void   modest_ui_finalize       (GObject *obj);
43
44 static void    modest_ui_window_destroy    (GtkWidget *win, GdkEvent *event, gpointer data);
45 static void    modest_ui_last_window_closed (GObject *obj, gpointer data);
46
47 static GtkWidget* modest_main_window_folder_tree (ModestAccountMgr *modest_acc_mgr,
48                                                   TnyAccountStoreIface *account_store);
49 static GtkWidget* modest_main_window_header_tree (TnyMsgFolderIface *folder);
50
51 //static void on_account_settings1_activate (GtkMenuItem *,
52 //                                  gpointer);
53
54 static void on_password_requested (ModestTnyAccountStore *account_store,
55                                    const gchar *account_name, gpointer user_data);
56
57 static void on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
58                                TnyMsgFolderIface *folder,
59                                gpointer data);
60 static void on_message_clicked (ModestTnyFolderTreeView *folder_tree,
61                                 TnyMsgIface *message,
62                                 gpointer data);
63 static void on_new_mail_clicked (GtkWidget *widget, ModestUI *modest_ui);
64
65 static void on_reply_clicked (GtkWidget *widget, ModestUI *modest_ui);
66
67 static void on_forward_clicked (GtkWidget *widget, ModestUI *modest_ui);
68
69 static void on_delete_clicked (GtkWidget *widget, ModestUI *modest_ui);
70
71 static void on_view_attachments_toggled(GtkWidget *widget, ModestUI *modest_ui);
72
73 static void on_attach_button_clicked (GtkWidget *widget, ModestEditorWindow *modest_editwin);
74
75 #if 1
76 static void on_send_button_clicked (GtkWidget *widget, ModestEditorWindow *modest_editwin);
77 #else
78 static void on_send_button_clicked (GtkWidget *widget, ModestUI *modest_ui);
79 #endif
80
81 static void on_sendreceive_button_clicked (GtkWidget *widget, ModestUI *modest_ui);
82
83 static void register_toolbar_callbacks (ModestUI *modest_ui);
84
85 typedef enum {
86         QUOTED_SEND_REPLY,
87         QUOTED_SEND_REPLY_ALL,
88         QUOTED_SEND_FORWARD
89 } quoted_send_type;
90
91 static void quoted_send_msg (ModestUI *modest_ui, quoted_send_type qstype);
92
93
94 typedef struct {
95         ModestUI *modest_ui;
96         ModestEditorWindow *edit_win;
97         GladeXML *glade_xml;
98         GList *attachments;
99 } EditWinData;
100
101
102 /* list my signals */
103 enum {
104         /* MY_SIGNAL_1, */
105         /* MY_SIGNAL_2, */
106         LAST_SIGNAL
107 };
108
109 /* globals */
110 static GObjectClass *parent_class = NULL;
111
112 /* uncomment the following if you have defined any signals */
113 /* static guint signals[LAST_SIGNAL] = {0}; */
114
115 GType
116 modest_ui_get_type (void)
117 {
118         static GType my_type = 0;
119         if (!my_type) {
120                 static const GTypeInfo my_info = {
121                         sizeof(ModestUIClass),
122                         NULL,           /* base init */
123                         NULL,           /* base finalize */
124                         (GClassInitFunc) modest_ui_class_init,
125                         NULL,           /* class finalize */
126                         NULL,           /* class data */
127                         sizeof(ModestUI),
128                         1,              /* n_preallocs */
129                         (GInstanceInitFunc) modest_ui_init,
130                 };
131                 my_type = g_type_register_static (G_TYPE_OBJECT,
132                                                   "ModestUI",
133                                                   &my_info, 0);
134         }
135         return my_type;
136 }
137
138
139 static void
140 modest_ui_class_init (ModestUIClass *klass)
141 {
142         GObjectClass *gobject_class;
143         gobject_class = (GObjectClass*) klass;
144
145         parent_class            = g_type_class_peek_parent (klass);
146         gobject_class->finalize = modest_ui_finalize;
147
148         g_type_class_add_private (gobject_class, sizeof(ModestUIPrivate));
149
150         /* signal definitions go here, e.g.: */
151 /*      signals[MY_SIGNAL_1] = */
152 /*              g_signal_new ("my_signal_1",....); */
153 /*      signals[MY_SIGNAL_2] = */
154 /*              g_signal_new ("my_signal_2",....); */
155 /*      etc. */
156 }
157
158
159 static void
160 modest_ui_init (ModestUI *obj)
161 {
162         ModestUIPrivate *priv = MODEST_UI_GET_PRIVATE(obj);
163
164         priv->modest_acc_mgr    = NULL;
165         priv->modest_id_mgr     = NULL;
166         priv->modest_conf       = NULL;
167         priv->modest_window_mgr = NULL;
168         priv->glade_xml         = NULL;
169         priv->folder_view       = NULL;
170         priv->header_view       = NULL;
171
172 }
173
174
175 static void
176 modest_ui_finalize (GObject *obj)
177 {
178         ModestUIPrivate *priv = MODEST_UI_GET_PRIVATE(obj);
179
180         if (priv->modest_acc_mgr)
181                 g_object_unref (priv->modest_acc_mgr);
182         priv->modest_acc_mgr = NULL;
183
184         if (priv->modest_id_mgr)
185                 g_object_unref (priv->modest_id_mgr);
186         priv->modest_id_mgr = NULL;
187
188         if (priv->modest_conf)
189                 g_object_unref (priv->modest_conf);
190         priv->modest_conf = NULL;
191
192         if (priv->modest_window_mgr)
193                 g_object_unref (priv->modest_window_mgr);
194         priv->modest_window_mgr = NULL;
195 }
196
197
198 GObject*
199 modest_ui_new (ModestConf *modest_conf)
200 {
201         GObject *obj;
202         ModestUIPrivate *priv;
203         ModestAccountMgr *modest_acc_mgr;
204         ModestIdentityMgr *modest_id_mgr;
205         TnyAccountStoreIface *account_store_iface;
206         GSList *account_names_list;
207         GSList *identities_list;
208
209         g_return_val_if_fail (modest_conf, NULL);
210
211         obj = g_object_new(MODEST_TYPE_UI, NULL);
212         priv = MODEST_UI_GET_PRIVATE(obj);
213
214         modest_acc_mgr =
215                 MODEST_ACCOUNT_MGR(modest_account_mgr_new (modest_conf));
216         if (!modest_acc_mgr) {
217                 g_warning ("could not create ModestAccountMgr instance");
218                 g_object_unref (obj);
219                 return NULL;
220         }
221
222         modest_id_mgr =
223                 MODEST_IDENTITY_MGR(modest_identity_mgr_new (modest_conf));
224         if (!modest_id_mgr) {
225                 g_warning ("could not create ModestIdentityMgr instance");
226                 g_object_unref (obj);
227                 return NULL;
228         }
229
230         account_store_iface =
231                 TNY_ACCOUNT_STORE_IFACE(modest_tny_account_store_new (modest_acc_mgr));
232         if (!account_store_iface) {
233                 g_warning ("could not initialze ModestTnyAccountStore");
234                 return NULL;
235         }
236         g_signal_connect (account_store_iface, "password_requested",
237                           G_CALLBACK(on_password_requested),
238                           NULL);
239
240         glade_init ();
241         priv->glade_xml = glade_xml_new (MODEST_GLADE, NULL,NULL);
242         if (!priv->glade_xml) {
243                 g_warning ("failed to do glade stuff");
244                 g_object_unref (obj);
245                 return NULL;
246         }
247
248         /* FIXME: could be used, but doesn't work atm.
249          * glade_xml_signal_autoconnect(priv->glade_xml);
250          */
251
252         priv->modest_acc_mgr = modest_acc_mgr;
253         priv->modest_id_mgr  = modest_id_mgr;
254         g_object_ref (priv->modest_conf = modest_conf);
255
256         priv->account_store = account_store_iface;
257
258         priv->modest_window_mgr = MODEST_WINDOW_MGR(modest_window_mgr_new());
259         g_signal_connect (priv->modest_window_mgr, "last_window_closed",
260                           G_CALLBACK(modest_ui_last_window_closed),
261                           NULL);
262
263         account_names_list=modest_account_mgr_server_account_names(modest_acc_mgr, NULL, MODEST_PROTO_TYPE_ANY, NULL, FALSE);
264         identities_list=modest_identity_mgr_identity_names(modest_id_mgr, NULL);
265         if (!(account_names_list!=NULL || identities_list!=NULL))
266                 wizard_account_dialog(MODEST_UI(obj));
267         g_slist_free(account_names_list);
268         g_slist_free(identities_list);
269
270         return obj;
271 }
272
273
274 gboolean
275 modest_ui_show_main_window (ModestUI *modest_ui)
276 {
277         GtkWidget       *win;
278         gint              height, width;
279         ModestUIPrivate *priv;
280         GtkWidget     *folder_view, *header_view;
281         GtkWidget     *message_view;
282         GtkWidget     *account_settings_item;
283         GtkWidget     *delete_item;
284         GtkWidget     *view_attachments_item;
285
286         GtkWidget  *folder_view_holder,
287                 *header_view_holder,
288                 *mail_paned;
289
290         priv = MODEST_UI_GET_PRIVATE(modest_ui);
291
292         height = modest_conf_get_int (priv->modest_conf,
293                                       MODEST_CONF_MAIN_WINDOW_HEIGHT,NULL);
294         width  = modest_conf_get_int (priv->modest_conf,
295                                       MODEST_CONF_MAIN_WINDOW_WIDTH,NULL);
296
297         win = glade_xml_get_widget (priv->glade_xml, "main");
298         if (!win) {
299                 g_warning ("could not create main window");
300                 return FALSE;
301         }
302
303         folder_view =
304                 GTK_WIDGET(modest_main_window_folder_tree(priv->modest_acc_mgr,
305                                                           priv->account_store));
306         priv->folder_view = folder_view;
307         folder_view_holder = glade_xml_get_widget (priv->glade_xml, "folders");
308         if (!folder_view||!folder_view_holder) {
309                 g_warning ("failed to create folder tree");
310                 return FALSE;
311         }
312         gtk_container_add (GTK_CONTAINER(folder_view_holder), folder_view);
313
314         header_view  =  GTK_WIDGET(modest_main_window_header_tree (NULL));
315         priv->header_view = header_view;
316         header_view_holder = glade_xml_get_widget (priv->glade_xml, "mail_list");
317         if (!header_view) {
318                 g_warning ("failed to create header tree");
319                 return FALSE;
320         }
321         gtk_container_add (GTK_CONTAINER(header_view_holder), header_view);
322
323         g_signal_connect (G_OBJECT(folder_view), "folder_selected",
324                           G_CALLBACK(on_folder_clicked), modest_ui);
325
326         message_view  = GTK_WIDGET(modest_tny_msg_view_new (NULL, priv->modest_conf));
327         if (!message_view) {
328                 g_warning ("failed to create message view");
329                 return FALSE;
330         }
331         mail_paned = glade_xml_get_widget (priv->glade_xml, "mail_paned");
332         gtk_paned_add2 (GTK_PANED(mail_paned), message_view);
333
334         g_signal_connect (header_view, "message_selected",
335                           G_CALLBACK(on_message_clicked),
336                           modest_ui);
337
338         account_settings_item = glade_xml_get_widget (priv->glade_xml, "AccountSettingsMenuItem");
339         if (!account_settings_item)
340         {
341                 g_warning ("The account settings item isn't available!\n");
342                 return FALSE;
343         }
344         /*
345         g_signal_connect (account_settings_item, "activate",
346                           G_CALLBACK(on_account_settings1_activate),
347                           modest_ui);
348         */
349
350 //      new_account_item = glade_xml_get_widget (priv->glade_xml, "NewAccountWizardMenuItem");
351 //      if (!new_account_item)
352 //      {
353 //              g_warning ("The new account item isn't available!\n");
354 //              return FALSE;
355 //      }
356
357 //        g_signal_connect (new_account_item, "activate",
358 //                         G_CALLBACK(new_wizard_account),
359 //                         modest_ui);
360 //
361         delete_item = glade_xml_get_widget (priv->glade_xml, "delete1");
362         if (!delete_item)
363         {
364                 g_warning ("The delete item isn't available!\n");
365                 return FALSE;
366         }
367
368         g_signal_connect (delete_item, "activate", G_CALLBACK(on_delete_clicked),
369                           modest_ui);
370
371         view_attachments_item = glade_xml_get_widget (priv->glade_xml, "menu_view_attachments");
372         if (!view_attachments_item)
373         {
374                 g_warning ("The view_attachments_item isn't available!");
375                 return FALSE;
376         }
377
378         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(view_attachments_item),
379                                                                    modest_conf_get_bool(priv->modest_conf,
380                                                                                                                 MODEST_CONF_MSG_VIEW_SHOW_ATTACHMENTS_INLINE,
381                                                                                                                 NULL)
382                                                                    );
383
384         g_signal_connect (view_attachments_item,
385                                           "toggled",
386                                           G_CALLBACK(on_view_attachments_toggled),
387                                           modest_ui);
388
389         register_toolbar_callbacks (modest_ui);
390
391         modest_window_mgr_register (priv->modest_window_mgr,
392                                     G_OBJECT(win), MODEST_MAIN_WINDOW, 0);
393         g_signal_connect (win, "destroy-event", G_CALLBACK(modest_ui_window_destroy),
394                           modest_ui);
395         g_signal_connect (win, "delete-event", G_CALLBACK(modest_ui_window_destroy),
396                           modest_ui);
397         gtk_widget_set_usize (GTK_WIDGET(win), width, height);
398         gtk_window_set_title (GTK_WINDOW(win), PACKAGE_STRING);
399
400         gtk_widget_show_all (win);
401         return TRUE;
402 }
403
404
405 static void
406 register_toolbar_callbacks (ModestUI *modest_ui)
407 {
408         ModestUIPrivate *priv;
409         GtkWidget *button;
410
411         g_return_if_fail (modest_ui);
412
413         priv = MODEST_UI_GET_PRIVATE (modest_ui);
414
415         button = glade_xml_get_widget (priv->glade_xml, "toolb_new_mail");
416         if (button)
417                 g_signal_connect (button, "clicked",
418                                   G_CALLBACK(on_new_mail_clicked), modest_ui);
419
420         button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
421         if (button) {
422                 g_signal_connect (button, "clicked",
423                                   G_CALLBACK(on_reply_clicked), modest_ui);
424                 gtk_widget_set_sensitive(button, FALSE);
425         }
426
427         button = glade_xml_get_widget (priv->glade_xml, "toolb_reply_all");
428         if (button) {
429                 //g_signal_connect (button, "clicked",
430                 //                G_CALLBACK(on_reply_all_clicked), modest_ui);
431                 gtk_widget_set_sensitive(button, FALSE);
432         }
433
434         button = glade_xml_get_widget (priv->glade_xml, "toolb_forward");
435         if (button) {
436                 g_signal_connect (button, "clicked",
437                                   G_CALLBACK(on_forward_clicked), modest_ui);
438                 gtk_widget_set_sensitive(button, FALSE);
439         }
440
441         button = glade_xml_get_widget (priv->glade_xml, "toolb_move_to");
442         if (button) {
443                 //g_signal_connect (button, "clicked",
444                 //                G_CALLBACK(on_move_to_clicked), modest_ui);
445                 gtk_widget_set_sensitive(button, FALSE);
446         }
447
448         button = glade_xml_get_widget (priv->glade_xml, "toolb_delete");
449         if (button) {
450                 g_signal_connect (button, "clicked",
451                                   G_CALLBACK(on_delete_clicked), modest_ui);
452                 gtk_widget_set_sensitive(button, FALSE);
453         }
454
455         button = glade_xml_get_widget (priv->glade_xml, "toolb_send_receive");
456         if (button) {
457                 g_signal_connect (button, "clicked",
458                                   G_CALLBACK(on_sendreceive_button_clicked), modest_ui);
459                 gtk_widget_set_sensitive(button, TRUE);
460         }
461 }
462
463 #if 0
464 static void
465 hide_edit_window (GtkWidget *win, GdkEvent *event, gpointer data)
466 {
467         ModestUIPrivate *priv;
468
469         priv = MODEST_UI_GET_PRIVATE(data);
470         gtk_widget_hide (win);
471         modest_window_mgr_unregister(priv->modest_window_mgr, G_OBJECT(win));
472 }
473 #endif
474
475
476 static gboolean close_edit_confirm_dialog(ModestEditorWindow *edit_win)
477 {
478         GtkWidget *mdialog;
479         gint res;
480
481         mdialog = gtk_message_dialog_new(GTK_WINDOW(edit_win),
482                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
483                         GTK_MESSAGE_QUESTION,
484                         GTK_BUTTONS_YES_NO,
485                         _("Message was modified.\nDiscard Changes?"));
486         gtk_widget_show_all (mdialog);
487
488         res=gtk_dialog_run(GTK_DIALOG(mdialog));
489         gtk_widget_destroy (mdialog);
490         if (res == GTK_RESPONSE_YES)
491                 return TRUE;
492         else
493                 return FALSE;
494 }
495
496 static void
497 close_edit_window (GtkWidget *win, GdkEvent *event, gpointer data)
498 {
499         ModestEditorWindow *edit_win;
500         ModestUIPrivate *priv;
501         EditWinData *win_data;
502
503         edit_win = (ModestEditorWindow *)data;
504         win_data = modest_editor_window_get_data(edit_win);
505         priv = MODEST_UI_GET_PRIVATE(win_data->modest_ui);
506
507         // g_message("window was %s modified", modest_editor_window_get_modified(edit_win) ? "" : "not");
508
509         if (modest_editor_window_get_modified(edit_win)) {
510                 if (close_edit_confirm_dialog(edit_win)) {
511                         gtk_widget_hide (GTK_WIDGET(edit_win));
512                         modest_window_mgr_unregister(priv->modest_window_mgr, G_OBJECT(edit_win));
513                         gtk_widget_destroy(GTK_WIDGET(edit_win));
514                         g_message("closing window");
515                 } else {
516                         g_message("not closing window");
517                 }
518         }
519 }
520
521
522 GtkContainer
523 *modest_ui_new_editor_window (ModestUI *modest_ui, gpointer *user_data)
524 {
525         GtkWidget       *top_container;
526
527         GladeXML                *glade_xml;
528         EditWinData             *win_data;
529
530         glade_xml = glade_xml_new(MODEST_GLADE, "new_mail_top_container", NULL);
531         if (!glade_xml)
532                 return NULL;
533
534         win_data = g_malloc(sizeof(EditWinData));
535         win_data->modest_ui = modest_ui;
536         win_data->glade_xml = glade_xml;
537         *user_data = win_data;
538
539         top_container = glade_xml_get_widget(glade_xml, "new_mail_top_container");
540         if (!top_container) {
541                 g_object_unref(G_OBJECT(glade_xml));
542                 return NULL;
543         }
544         
545         win_data->attachments = NULL; /* redundant */
546
547         return GTK_CONTAINER(top_container);
548 }
549
550
551 gboolean
552 modest_ui_editor_window_set_to_header(const gchar *to, gpointer window_data)
553 {
554         GladeXML *glade_xml;
555         GtkWidget *w;
556         EditWinData *win_data;
557
558         win_data = (EditWinData *)window_data;
559         glade_xml = win_data->glade_xml;
560         w = glade_xml_get_widget(glade_xml, "to_entry");
561         gtk_entry_set_text(GTK_ENTRY(w), to);
562
563         return TRUE;
564 }
565
566
567 gboolean
568 modest_ui_editor_window_set_cc_header(const gchar *cc, gpointer window_data)
569 {
570         GladeXML *glade_xml;
571         // GtkWidget *w;
572         EditWinData *win_data;
573
574         win_data = (EditWinData *)window_data;
575         glade_xml = win_data->glade_xml;
576 /*
577         w = glade_xml_get_widget(glade_xml, "cc_entry");
578         gtk_entry_set_text(GTK_ENTRY(w), cc);
579 */
580         return TRUE;
581 }
582
583
584 gboolean
585 modest_ui_editor_window_set_bcc_header(const gchar *bcc, gpointer window_data)
586 {
587         GladeXML *glade_xml;
588         // GtkWidget *w;
589         EditWinData *win_data;
590
591         win_data = (EditWinData *)window_data;
592         glade_xml = win_data->glade_xml;
593 /*
594         w = glade_xml_get_widget(glade_xml, "bcc_entry");
595         gtk_entry_set_text(GTK_ENTRY(w), bcc);
596 */
597         return TRUE;
598 }
599
600
601 gboolean
602 modest_ui_editor_window_set_subject_header(const gchar *subject, gpointer window_data)
603 {
604         GladeXML *glade_xml;
605         GtkWidget *w;
606         EditWinData *win_data;
607
608         win_data = (EditWinData *)window_data;
609         glade_xml = win_data->glade_xml;
610
611         w = glade_xml_get_widget(glade_xml, "subject_entry");
612         gtk_entry_set_text(GTK_ENTRY(w), subject);
613
614         return TRUE;
615 }
616
617
618 gboolean
619 modest_ui_editor_window_set_body(const gchar *body, gpointer window_data)
620 {
621         GladeXML *glade_xml;
622         GtkWidget *body_view;
623         GtkTextBuffer *buf;
624         EditWinData *win_data;
625
626         win_data = (EditWinData *)window_data;
627         glade_xml = win_data->glade_xml;
628
629         body_view = glade_xml_get_widget(glade_xml, "body_view");
630         buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(body_view));
631
632         gtk_text_buffer_set_text(GTK_TEXT_BUFFER(buf), body, -1);
633
634         return TRUE;
635 }
636
637
638 gboolean
639 modest_ui_editor_window_update_attachments(gpointer window_data)
640 {
641         GladeXML *glade_xml;
642         
643         glade_xml = ((EditWinData *) window_data)->glade_xml;
644
645         //body_view = glade_xml_get_widget(glade_xml, "body_view");
646         
647         return TRUE;
648 }
649 #if 0
650 gboolean
651 modest_ui_new_edit_window (ModestUI *modest_ui, const gchar* to,
652                             const gchar* cc, const gchar* bcc,
653                             const gchar* subject, const gchar *body,
654                             const GSList* att)
655 {
656         GtkWidget       *win, *to_entry, *subject_entry, *body_view;
657
658         ModestUIPrivate *priv;
659         GtkWidget       *btn;
660         GtkTextBuffer   *buf;
661
662         priv = MODEST_UI_GET_PRIVATE(modest_ui);
663         int height = modest_conf_get_int (priv->modest_conf,
664                                           MODEST_CONF_EDIT_WINDOW_HEIGHT,NULL);
665         int width  = modest_conf_get_int (priv->modest_conf,
666                                           MODEST_CONF_EDIT_WINDOW_WIDTH,NULL);
667
668         win = glade_xml_get_widget (priv->glade_xml, "new_mail");
669         if (!win) {
670                 g_warning ("could not create new mail  window");
671                 return FALSE;
672         }
673
674         /* FIXME: this also assumes that there can be only one edit window! */
675         if (!modest_window_mgr_find_by_type(priv->modest_window_mgr, MODEST_EDIT_WINDOW)) {
676                 /* there already is one edit win, maybe we should preserver its contents */
677                 modest_window_mgr_register (priv->modest_window_mgr,
678                                                                         G_OBJECT(win), MODEST_EDIT_WINDOW, 0);
679         }
680
681         to_entry      = glade_xml_get_widget (priv->glade_xml, "to_entry");
682         subject_entry = glade_xml_get_widget (priv->glade_xml, "subject_entry");
683         body_view     = glade_xml_get_widget (priv->glade_xml, "body_view");
684
685         gtk_entry_set_text(GTK_ENTRY(subject_entry), subject);
686         gtk_entry_set_text(GTK_ENTRY(to_entry), to);
687
688         buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(body_view));
689         if (body) {
690                 gtk_text_buffer_set_text(buf, body, -1);
691         } else {
692                 gtk_text_buffer_set_text(buf, "", -1);
693         }
694         g_signal_connect (win, "destroy-event", G_CALLBACK(hide_edit_window),
695                           modest_ui);
696         g_signal_connect (win, "delete-event", G_CALLBACK(hide_edit_window),
697                           modest_ui);
698
699         gtk_widget_set_usize (GTK_WIDGET(win), height, width);
700         gtk_window_set_title (GTK_WINDOW(win),
701                               subject ? subject : "Untitled");
702
703
704         btn = glade_xml_get_widget (priv->glade_xml, "toolb_send");
705         g_signal_connect (btn, "clicked", G_CALLBACK(on_send_button_clicked),
706                           modest_ui);
707
708         gtk_widget_show_all (win);
709
710         return TRUE;
711 }
712 #endif
713
714 static void
715 modest_ui_window_destroy (GtkWidget *win, GdkEvent *event, gpointer data)
716 {
717         ModestUIPrivate *priv;
718
719         g_return_if_fail (data);
720         g_return_if_fail(MODEST_IS_UI(data));
721         priv = MODEST_UI_GET_PRIVATE((ModestUI *)data);
722         g_return_if_fail(priv);
723         if (!modest_window_mgr_unregister (priv->modest_window_mgr, G_OBJECT(win)))
724                 g_warning ("modest window mgr: failed to unregister %p",
725                            G_OBJECT(win));
726         else
727                 gtk_widget_hide(win);
728 }
729
730
731 static void
732 modest_ui_last_window_closed (GObject *obj, gpointer data)
733 {
734         /* FIXME: Other cleanups todo? Finalize Tinymail? */
735         gtk_main_quit ();
736 }
737
738
739 void
740 on_account_selector_selection_changed (GtkWidget *widget,
741                                        gpointer user_data)
742 {
743         GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
744         GtkTreeIter iter;
745
746         gchar *account_name;
747
748         if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
749         {
750                 gtk_tree_model_get(GTK_TREE_MODEL(model),
751                                    &iter,
752                                    0, &account_name,
753                                    -1);
754         }
755         else
756         {
757                 account_name="empty";
758         }
759
760         g_message("Value: '%s'\n", account_name);
761
762         free(account_name);
763 }
764
765 #if 0
766 static void
767 on_account_settings1_activate (GtkMenuItem *menuitem,
768                                gpointer user_data)
769 {
770         GladeXML *glade_xml;
771         GtkWidget *advanced_account_setup;
772         ModestUIPrivate *priv;
773         gint retval;
774         GSList *account_name_list;
775         GSList *account_name_list_iter;
776         GtkListStore *account_names;
777         GtkTreeIter account_names_iter;
778         GtkWidget *account_selector;
779         GtkCellRenderer *renderer;
780
781
782         g_return_if_fail(MODEST_IS_UI(user_data));
783         priv = MODEST_UI_GET_PRIVATE(MODEST_UI(user_data));
784
785         glade_xml = glade_xml_new(MODEST_GLADE, "mailbox_setup_advanced", NULL);
786         advanced_account_setup = glade_xml_get_widget(glade_xml, "mailbox_setup_advanced");
787
788         account_name_list=modest_account_mgr_account_names(priv->modest_acc_mgr, NULL);
789         account_names = gtk_list_store_new(1, G_TYPE_STRING);
790
791         for (account_name_list_iter=account_name_list;
792              account_name_list_iter!=NULL;
793              account_name_list_iter=g_slist_next(account_name_list_iter))
794         {
795                 gtk_list_store_append(account_names, &account_names_iter);
796                 gtk_list_store_set(account_names, &account_names_iter,
797                                    0, account_name_list_iter->data,
798                                    -1);
799         }
800
801         g_slist_free(account_name_list);
802
803         account_selector = glade_xml_get_widget(glade_xml, "account_selector");
804         gtk_combo_box_set_model(GTK_COMBO_BOX(account_selector), GTK_TREE_MODEL(account_names));
805
806         renderer = gtk_cell_renderer_text_new ();
807         gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (account_selector), renderer, TRUE);
808         gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (account_selector), renderer,
809                                         "text", 0,
810                                         NULL);
811
812         g_signal_connect(GTK_WIDGET(account_selector), "changed",
813                          G_CALLBACK(on_account_selector_selection_changed),
814                          GTK_WIDGET(advanced_account_setup));
815
816         gtk_combo_box_set_active(GTK_COMBO_BOX(account_selector), 0);
817
818         gtk_widget_show_all(GTK_WIDGET(advanced_account_setup));
819
820         retval=gtk_dialog_run(GTK_DIALOG(advanced_account_setup));
821
822         g_object_unref(account_names);
823
824         gtk_widget_destroy(GTK_WIDGET(advanced_account_setup));
825
826         g_object_unref(glade_xml);
827 }
828 #endif
829
830
831 static void
832 on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
833                    TnyMsgFolderIface *folder,
834                    gpointer data)
835 {
836         GtkWidget *win;
837         GtkWidget *button;
838         GtkWidget *paned;
839         ModestTnyHeaderTreeView *tree_view;
840         ModestTnyMsgView *msg_view;
841         ModestUIPrivate *priv;
842         GtkWidget *scrollview;
843
844         g_return_if_fail (folder);
845         g_return_if_fail (data);
846
847         priv = MODEST_UI_GET_PRIVATE(data);
848         scrollview = glade_xml_get_widget (priv->glade_xml,"mail_list");
849
850         tree_view = MODEST_TNY_HEADER_TREE_VIEW(
851                 gtk_bin_get_child(GTK_BIN(scrollview)));
852         win = glade_xml_get_widget (priv->glade_xml, "main");
853         gtk_window_set_title (GTK_WINDOW(win),
854                               tny_msg_folder_iface_get_name(folder));
855         
856         modest_tny_header_tree_view_set_folder (tree_view, folder);
857
858         button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
859         if (button) {
860                 gtk_widget_set_sensitive(button, FALSE);
861         }
862
863         button = glade_xml_get_widget (priv->glade_xml, "toolb_forward");
864         if (button) {
865                 gtk_widget_set_sensitive(button, FALSE);
866         }
867
868         button = glade_xml_get_widget (priv->glade_xml, "toolb_delete");
869         if (button) {
870                 gtk_widget_set_sensitive(button, FALSE);
871         }
872
873         paned = glade_xml_get_widget (priv->glade_xml,"mail_paned");
874         g_return_if_fail (paned);
875
876         msg_view = MODEST_TNY_MSG_VIEW(gtk_paned_get_child2 (GTK_PANED(paned)));
877         g_return_if_fail (msg_view);
878
879         modest_tny_msg_view_set_message  (msg_view, NULL);
880 }
881
882
883 static void
884 on_message_clicked (ModestTnyFolderTreeView *folder_tree,
885                                 TnyMsgIface *message,
886                                 gpointer data)
887 {
888         GtkWidget *paned;
889         GtkWidget *button;
890         ModestTnyMsgView *msg_view;
891         ModestUIPrivate *priv;
892
893         g_return_if_fail (data);
894         
895         priv = MODEST_UI_GET_PRIVATE(data);
896         paned = glade_xml_get_widget (priv->glade_xml,"mail_paned");
897         msg_view = MODEST_TNY_MSG_VIEW(gtk_paned_get_child2 (GTK_PANED(paned)));
898
899         modest_tny_msg_view_set_message (msg_view,
900                                          message);
901         button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
902         if (button) {
903                 gtk_widget_set_sensitive(button, TRUE);
904         }
905         button = glade_xml_get_widget (priv->glade_xml, "toolb_forward");
906         if (button) {
907                 gtk_widget_set_sensitive(button, TRUE);
908         }
909         button = glade_xml_get_widget (priv->glade_xml, "toolb_delete");
910         if (button) {
911                 gtk_widget_set_sensitive(button, TRUE);
912         }
913 }
914
915
916 static void
917 on_password_requested (ModestTnyAccountStore *account_store,
918                        const gchar *account_name, gpointer user_data)
919 {
920
921         GtkWidget *passdialog;
922         GtkWidget *vbox;
923         GtkWidget *infolabel;
924         GtkWidget *passentry;
925         gint retval;
926         const gchar *infostring=g_strconcat("Please enter the password for ", account_name, ".", NULL);
927
928         passdialog = gtk_dialog_new_with_buttons("MyDialog",
929                                                  NULL,
930                                                  GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
931                                                  GTK_STOCK_OK,
932                                                  GTK_RESPONSE_ACCEPT,
933                                                  GTK_STOCK_CANCEL,
934                                                  GTK_RESPONSE_REJECT,
935                                                  NULL);
936
937         vbox=gtk_vbox_new(FALSE, 0);
938
939         infolabel=gtk_label_new(infostring);
940         passentry=gtk_entry_new();
941
942         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(passdialog)->vbox), infolabel, FALSE, FALSE, 0);
943         gtk_box_pack_start(GTK_BOX(GTK_DIALOG(passdialog)->vbox), passentry, FALSE, FALSE, 0);
944         gtk_widget_show_all(passdialog);
945
946         retval = gtk_dialog_run (GTK_DIALOG(passdialog));
947
948         switch (retval)
949         {
950         case GTK_RESPONSE_ACCEPT:
951                 modest_account_mgr_set_server_account_string(modest_tny_account_store_get_accout_mgr(account_store),
952                                                              account_name,
953                                                              "password",
954                                                              gtk_entry_get_text(GTK_ENTRY(passentry)),
955                                                              NULL);
956                 break;
957         case GTK_RESPONSE_CANCEL:
958                 /* FIXME:
959                  * What happens, if canceled?"
960                  */
961                 break;
962         }
963
964         gtk_widget_destroy (passdialog);
965 }
966
967
968 static GtkWidget*
969 modest_main_window_header_tree (TnyMsgFolderIface *folder)
970 {
971         int i;
972         GSList *columns = NULL;
973         GtkWidget *header_tree;
974         ModestTnyHeaderTreeViewColumn cols[] = {
975                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE,
976                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH,
977                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM,        
978                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT,
979                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE
980         };
981
982         for (i = 0 ; i != sizeof(cols)/sizeof(ModestTnyHeaderTreeViewColumn); ++i)
983                 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
984
985         header_tree = GTK_WIDGET(modest_tny_header_tree_view_new(folder, columns,
986                                                                  MODEST_TNY_HEADER_TREE_VIEW_STYLE_NORMAL));
987         g_slist_free (columns);
988
989         if (!header_tree) {
990                 g_warning ("could not create header tree");
991                 return NULL;
992         }
993
994         return GTK_WIDGET(header_tree);
995 }
996
997
998 static GtkWidget*
999 modest_main_window_folder_tree (ModestAccountMgr *modest_acc_mgr,
1000                                 TnyAccountStoreIface *account_store)
1001 {
1002         GtkWidget *folder_tree;
1003
1004         folder_tree = GTK_WIDGET(modest_tny_folder_tree_view_new (account_store));
1005         if (!folder_tree) {
1006                 g_warning ("could not create folder list");
1007                 return NULL;
1008         }
1009
1010         return folder_tree;
1011 }
1012
1013 static void on_editor_entry_changed(GtkEditable *editable,
1014                                             gpointer     user_data)
1015 {
1016         GtkWidget *edit_win;
1017         EditWinData *windata;
1018
1019         edit_win = (GtkWidget *)user_data;
1020         windata = (EditWinData *)modest_editor_window_get_data(MODEST_EDITOR_WINDOW(edit_win));
1021
1022         modest_editor_window_set_modified(MODEST_EDITOR_WINDOW(edit_win), TRUE);
1023 }
1024
1025 static void on_editor_buffer_changed (GtkTextBuffer *textbuffer,
1026                                             gpointer       user_data)
1027 {
1028         GtkWidget *edit_win;
1029         
1030         edit_win = (GtkWidget *)user_data;
1031         modest_editor_window_set_modified(MODEST_EDITOR_WINDOW(edit_win), TRUE);
1032 }
1033
1034 static void
1035 on_new_mail_clicked (GtkWidget *widget, ModestUI *modest_ui)
1036 {
1037         GtkWidget *edit_win;
1038         GladeXML *glade_xml;
1039         GtkWidget *btn, *w;
1040         GtkTextBuffer *buf;
1041         EditWinData *windata;
1042         ModestUIPrivate *priv;
1043         gint height, width;
1044
1045         g_return_if_fail (modest_ui);
1046         //modest_ui_new_edit_window (modest_ui, "", "", "", "", "", NULL);
1047
1048         edit_win = modest_editor_window_new(modest_ui);
1049         windata = (EditWinData *)modest_editor_window_get_data(MODEST_EDITOR_WINDOW(edit_win));
1050         g_return_if_fail(windata);
1051
1052         windata->edit_win = MODEST_EDITOR_WINDOW(edit_win);
1053         glade_xml = windata->glade_xml;
1054         btn = glade_xml_get_widget (glade_xml, "toolb_send");
1055         g_signal_connect (btn, "clicked", G_CALLBACK(on_send_button_clicked),
1056                           edit_win);
1057         btn = glade_xml_get_widget (glade_xml, "toolb_attach");
1058         g_signal_connect (btn, "clicked", G_CALLBACK(on_attach_button_clicked),
1059                           edit_win);
1060
1061         w = glade_xml_get_widget (glade_xml, "to_entry");
1062         g_signal_connect(w, "changed", G_CALLBACK(on_editor_entry_changed), edit_win);
1063         w = glade_xml_get_widget (glade_xml, "subject_entry");
1064         g_signal_connect(w, "changed", G_CALLBACK(on_editor_entry_changed), edit_win);
1065         w = glade_xml_get_widget (glade_xml, "body_view");
1066         buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
1067         gtk_text_buffer_set_text(buf, "", -1);
1068         g_signal_connect(buf, "changed", G_CALLBACK(on_editor_buffer_changed), edit_win);
1069
1070         g_signal_connect (edit_win, "destroy-event", G_CALLBACK(close_edit_window),
1071                           edit_win);
1072         g_signal_connect (edit_win, "delete-event", G_CALLBACK(close_edit_window),
1073                           edit_win);
1074
1075         priv = MODEST_UI_GET_PRIVATE(windata->modest_ui);
1076         height = modest_conf_get_int (priv->modest_conf,
1077                                           MODEST_CONF_EDIT_WINDOW_HEIGHT, NULL);
1078         width  = modest_conf_get_int (priv->modest_conf,
1079                                           MODEST_CONF_EDIT_WINDOW_WIDTH, NULL);
1080
1081         // g_message("new editor win@%dx%d", width, height);
1082
1083         gtk_widget_set_usize (GTK_WIDGET(edit_win), width, height);
1084         gtk_window_set_title (GTK_WINDOW(edit_win), _("Untitled"));
1085         modest_window_mgr_register(priv->modest_window_mgr, G_OBJECT(edit_win), MODEST_EDIT_WINDOW, 0);
1086         gtk_widget_show(edit_win);
1087 }
1088
1089
1090 static void
1091 new_editor_with_presets (ModestUI *modest_ui, const gchar *to_header,
1092                                                         const gchar *cc_header, const gchar *bcc_header,
1093                                                         const gchar *subject_header, const gchar *body)
1094 {
1095         GtkWidget *edit_win;
1096         GladeXML *glade_xml;
1097         GtkWidget *btn, *w;
1098         GtkTextBuffer *buf;
1099         EditWinData *windata;
1100         ModestUIPrivate *priv;
1101         gint height, width;
1102
1103         g_return_if_fail (modest_ui);
1104
1105         edit_win = modest_editor_window_new(modest_ui);
1106         windata = (EditWinData *)modest_editor_window_get_data(MODEST_EDITOR_WINDOW(edit_win));
1107         g_return_if_fail(windata);
1108
1109         glade_xml = windata->glade_xml;
1110         btn = glade_xml_get_widget (glade_xml, "toolb_send");
1111         g_signal_connect (btn, "clicked", G_CALLBACK(on_send_button_clicked),
1112                           edit_win);
1113         btn = glade_xml_get_widget (glade_xml, "toolb_attach");
1114         g_signal_connect (btn, "clicked", G_CALLBACK(on_attach_button_clicked),
1115                           edit_win);
1116
1117         w = glade_xml_get_widget (glade_xml, "to_entry");
1118         g_signal_connect(w, "changed", G_CALLBACK(on_editor_entry_changed), edit_win);
1119         w = glade_xml_get_widget (glade_xml, "subject_entry");
1120         g_signal_connect(w, "changed", G_CALLBACK(on_editor_entry_changed), edit_win);
1121         w = glade_xml_get_widget (glade_xml, "body_view");
1122         buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(w));
1123         g_signal_connect(buf, "changed", G_CALLBACK(on_editor_buffer_changed), edit_win);
1124
1125         g_signal_connect (edit_win, "destroy-event", G_CALLBACK(close_edit_window),
1126                           edit_win);
1127         g_signal_connect (edit_win, "delete-event", G_CALLBACK(close_edit_window),
1128                           edit_win);
1129
1130         priv = MODEST_UI_GET_PRIVATE(windata->modest_ui);
1131         height = modest_conf_get_int (priv->modest_conf,
1132                                           MODEST_CONF_EDIT_WINDOW_HEIGHT, NULL);
1133         width  = modest_conf_get_int (priv->modest_conf,
1134                                           MODEST_CONF_EDIT_WINDOW_WIDTH, NULL);
1135
1136         // g_message("new editor win@%dx%d", width, height);
1137
1138         gtk_widget_set_usize (GTK_WIDGET(edit_win), width, height);
1139         gtk_window_set_title (GTK_WINDOW(edit_win), _("Untitled"));
1140         modest_window_mgr_register(priv->modest_window_mgr, G_OBJECT(edit_win), MODEST_EDIT_WINDOW, 0);
1141
1142         modest_editor_window_set_to_header(MODEST_EDITOR_WINDOW(edit_win), to_header);
1143         modest_editor_window_set_cc_header(MODEST_EDITOR_WINDOW(edit_win), cc_header);
1144         modest_editor_window_set_bcc_header(MODEST_EDITOR_WINDOW(edit_win), bcc_header);
1145         modest_editor_window_set_subject_header(MODEST_EDITOR_WINDOW(edit_win), subject_header);
1146         modest_editor_window_set_body(MODEST_EDITOR_WINDOW(edit_win), body);
1147
1148         modest_editor_window_set_modified(MODEST_EDITOR_WINDOW(edit_win), FALSE);
1149
1150         gtk_widget_show(edit_win);
1151 }
1152
1153
1154 static void
1155 quoted_send_msg (ModestUI *modest_ui, quoted_send_type qstype) {
1156         GtkTreeSelection *sel;
1157         GtkWidget *paned;
1158         GtkTreeModel *model;
1159         GtkTreeIter iter;
1160         GtkScrolledWindow *scroll;
1161
1162         TnyMsgHeaderIface *header;
1163
1164         ModestTnyHeaderTreeView *header_view;
1165         ModestTnyMsgView *msg_view;
1166         ModestUIPrivate *priv;
1167
1168         const TnyMsgIface *msg;
1169         const TnyMsgFolderIface *folder;
1170         GString *re_sub;
1171         const gchar *subject, *from;
1172         gchar *unquoted, *quoted;
1173         time_t sent_date;
1174         gint line_limit = 76;
1175
1176         g_return_if_fail (modest_ui);
1177
1178         priv = MODEST_UI_GET_PRIVATE(modest_ui);
1179
1180         paned = glade_xml_get_widget (priv->glade_xml,"mail_paned");
1181         g_return_if_fail (paned);
1182
1183         scroll = GTK_SCROLLED_WINDOW(gtk_paned_get_child1 (GTK_PANED(paned)));
1184         g_return_if_fail (scroll);
1185
1186         msg_view = MODEST_TNY_MSG_VIEW(gtk_paned_get_child2 (GTK_PANED(paned)));
1187         g_return_if_fail (msg_view);
1188
1189         header_view = MODEST_TNY_HEADER_TREE_VIEW(gtk_bin_get_child (GTK_BIN(scroll)));
1190         g_return_if_fail (header_view);
1191
1192         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
1193         g_return_if_fail (sel);
1194
1195         if (!gtk_tree_selection_get_selected (sel, &model, &iter)) {
1196                 g_warning("nothing to reply to");
1197                 return;
1198         }
1199
1200         gtk_tree_model_get (model, &iter,
1201                             TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN,
1202                             &header, -1);
1203
1204         if (!header) {
1205                 g_warning("no header");
1206                 return;
1207         }
1208
1209         folder = tny_msg_header_iface_get_folder (TNY_MSG_HEADER_IFACE(header));
1210         if (!folder) {
1211                 g_warning ("cannot find folder");
1212                 return;
1213         }
1214
1215         msg = tny_msg_folder_iface_get_message (TNY_MSG_FOLDER_IFACE(folder), header);
1216         if (!msg) {
1217                 g_warning ("cannot find msg");
1218                 return;
1219         }
1220
1221         subject = tny_msg_header_iface_get_subject(header);
1222         re_sub = g_string_new(subject);
1223         /* FIXME: honor replyto, cc */
1224         from = tny_msg_header_iface_get_from(header);
1225         sent_date = tny_msg_header_iface_get_date_sent(header);
1226
1227         unquoted = modest_tny_msg_view_get_selected_text(msg_view);
1228         quoted = modest_tny_msg_actions_quote(msg, from, sent_date, line_limit, unquoted);
1229
1230         switch (qstype) {
1231                 case QUOTED_SEND_REPLY:
1232                         g_string_prepend(re_sub, _("Re: "));
1233                         new_editor_with_presets(modest_ui, from, /* cc */ "", /* bcc */ "", re_sub->str, quoted);
1234                         break;
1235                 case QUOTED_SEND_FORWARD:
1236                         g_string_prepend(re_sub, _("Fwd: "));
1237                         new_editor_with_presets(modest_ui, /* from */ "", /* cc */ "", /* bcc */ "", re_sub->str, quoted);
1238                         break;
1239                 default:
1240                         break;
1241         }
1242         g_free(quoted);
1243         g_free(unquoted);
1244         g_string_free(re_sub, TRUE);
1245 }
1246
1247
1248 static void
1249 on_reply_clicked (GtkWidget *widget, ModestUI *modest_ui)
1250 {
1251         quoted_send_msg (modest_ui, QUOTED_SEND_REPLY);
1252 }
1253
1254
1255 static void
1256 on_forward_clicked (GtkWidget *widget, ModestUI *modest_ui)
1257 {
1258         quoted_send_msg (modest_ui, QUOTED_SEND_FORWARD);
1259 }
1260
1261
1262 static void
1263 on_attach_button_clicked (GtkWidget *widget, ModestEditorWindow *modest_editwin)
1264 {
1265         /* open file selector */
1266         GtkWidget *dialog;
1267         gchar *mime_type;
1268         gchar *filename = NULL;
1269         
1270         dialog = gtk_file_chooser_dialog_new ("Open File",
1271                                                                                   GTK_WINDOW(modest_editwin),
1272                                                                                   GTK_FILE_CHOOSER_ACTION_OPEN,
1273                                                                                   GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1274                                                                                   GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
1275                                                                                   NULL);
1276
1277         if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
1278         {
1279
1280                 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1281                 printf ("file:%s\n", filename);
1282         }
1283         gtk_widget_destroy (dialog);
1284       
1285         /* check file */
1286         if (!filename)
1287                 return;
1288         
1289         g_return_if_fail(g_str_has_suffix(filename, ".jpg")); /* for now... */
1290         
1291         /* get mime type */
1292         mime_type = "image/jpeg";
1293         
1294         /* attach file */
1295         
1296         modest_editor_window_attach_file(modest_editwin, filename);
1297         
1298         g_free (filename);
1299 }
1300
1301
1302 static void
1303 on_send_button_clicked (GtkWidget *widget, ModestEditorWindow *modest_editwin)
1304 {
1305         ModestTnyTransportActions *actions;
1306         ModestUI *modest_ui;
1307         ModestUIPrivate *priv;
1308         GtkWidget *to_entry, *subject_entry, *body_view;
1309         const gchar *to, *subject, *email_from;
1310         gchar *body;
1311         GtkTextIter start, end;
1312         GtkTextBuffer *buf;
1313         TnyAccountStoreIface *account_store;
1314         const GList *transport_accounts;
1315         TnyTransportAccountIface *transport_account;
1316         ModestIdentityMgr *id_mgr;
1317         EditWinData *win_data;
1318         GList * attachments;
1319
1320
1321         win_data = modest_editor_window_get_data(modest_editwin);
1322         modest_ui = win_data->modest_ui;
1323
1324         g_return_if_fail (modest_ui);
1325
1326         actions = MODEST_TNY_TRANSPORT_ACTIONS
1327                 (modest_tny_transport_actions_new ());
1328
1329         priv = MODEST_UI_GET_PRIVATE(modest_ui);
1330
1331         account_store = priv->account_store;
1332         transport_accounts =
1333                 tny_account_store_iface_get_transport_accounts (account_store);
1334         if (!transport_accounts) {
1335                 g_message ("cannot send message: no transport account defined");
1336                 return;
1337         } else /* take the first one! */
1338                 transport_account =
1339                         TNY_TRANSPORT_ACCOUNT_IFACE(transport_accounts->data);
1340
1341         to_entry      = glade_xml_get_widget (win_data->glade_xml, "to_entry");
1342         subject_entry = glade_xml_get_widget (win_data->glade_xml, "subject_entry");
1343         body_view     = glade_xml_get_widget (win_data->glade_xml, "body_view");
1344
1345         to      = gtk_entry_get_text (GTK_ENTRY(to_entry));
1346         subject = gtk_entry_get_text (GTK_ENTRY(subject_entry));
1347
1348         buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(body_view));
1349         gtk_text_buffer_get_bounds (buf, &start, &end);
1350         body    = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
1351
1352         id_mgr = priv->modest_id_mgr;
1353         email_from = modest_identity_mgr_get_identity_string(id_mgr,
1354                                                              MODEST_IDENTITY_DEFAULT_IDENTITY,
1355                                                              MODEST_IDENTITY_EMAIL, NULL);
1356         attachments = modest_editor_window_get_attachments(modest_editwin);
1357         /* while (attachments) {
1358                 printf("att: %s\n", (gchar *) attachments->data);
1359                 attachments = attachments->next;
1360         } */
1361         if (!email_from)
1362                 email_from = "";
1363         
1364         g_message("sending \"%s\" %s ==> %s", subject, email_from, to);
1365
1366         modest_tny_transport_actions_send_message (actions,
1367                                                    transport_account,
1368                                                    email_from,
1369                                                    to, "", "", subject,
1370                                                    body,
1371                                                    attachments);
1372
1373         g_free (body);
1374         g_object_unref (G_OBJECT(actions));
1375
1376         gtk_widget_hide (GTK_WIDGET(modest_editwin));
1377         modest_window_mgr_unregister(priv->modest_window_mgr, G_OBJECT(modest_editwin));
1378         if (GTK_IS_WIDGET(modest_editwin)) {
1379                 gtk_widget_destroy(GTK_WIDGET(modest_editwin));
1380         } else
1381                 g_warning("editor window has vanished!");
1382 }
1383
1384 static void
1385 on_view_attachments_toggled(GtkWidget *widget, ModestUI *modest_ui)
1386 {
1387         GtkWidget *view_attachments_item, *paned;
1388         ModestTnyMsgView *msg_view;
1389         ModestUIPrivate *priv;
1390
1391         priv = MODEST_UI_GET_PRIVATE(modest_ui);
1392         view_attachments_item = glade_xml_get_widget (priv->glade_xml, "menu_view_attachments");
1393         g_return_if_fail(view_attachments_item);
1394
1395         modest_conf_set_bool(priv->modest_conf,
1396                                                          MODEST_CONF_MSG_VIEW_SHOW_ATTACHMENTS_INLINE,
1397                                                          gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(view_attachments_item)),
1398                                                          NULL);
1399
1400         /* refresh message view */
1401         paned = glade_xml_get_widget (priv->glade_xml,"mail_paned");
1402         msg_view = MODEST_TNY_MSG_VIEW(gtk_paned_get_child2 (GTK_PANED(paned)));
1403         modest_tny_msg_view_redraw(MODEST_TNY_MSG_VIEW(msg_view));
1404 }
1405 static void
1406 on_delete_clicked (GtkWidget *widget, ModestUI *modest_ui)
1407 {
1408         GtkTreeSelection *sel;
1409         GtkWidget *paned;
1410         GtkTreeModel *model;
1411         GtkTreeIter iter;
1412         GtkScrolledWindow *scroll;
1413         GtkTreeModel *mymodel;
1414
1415         ModestTnyHeaderTreeView *header_view;
1416         ModestTnyMsgView *msg_view;
1417         ModestUIPrivate *priv;
1418
1419         g_return_if_fail (modest_ui);
1420
1421         priv = MODEST_UI_GET_PRIVATE(modest_ui);
1422
1423         paned = glade_xml_get_widget (priv->glade_xml,"mail_paned");
1424         g_return_if_fail (paned);
1425
1426         scroll = GTK_SCROLLED_WINDOW(gtk_paned_get_child1 (GTK_PANED(paned)));
1427         g_return_if_fail (scroll);
1428
1429         msg_view = MODEST_TNY_MSG_VIEW(gtk_paned_get_child2 (GTK_PANED(paned)));
1430         g_return_if_fail (msg_view);
1431
1432         header_view = MODEST_TNY_HEADER_TREE_VIEW(gtk_bin_get_child (GTK_BIN(scroll)));
1433         g_return_if_fail (header_view);
1434
1435         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
1436         g_return_if_fail (sel);
1437
1438         /* get all selected mails */
1439         if (G_LIKELY (gtk_tree_selection_get_selected (sel, &model, &iter)))
1440         {
1441                 TnyMsgHeaderIface *header;
1442
1443                 gtk_tree_model_get (model, &iter, TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN,
1444                         &header, -1);
1445
1446                 if (G_LIKELY (header))
1447                 {
1448                         TnyMsgFolderIface *folder;
1449                         // const TnyMsgIface *msg;
1450
1451                         if (GTK_IS_TREE_MODEL_SORT (model))
1452                         {
1453                                 mymodel = gtk_tree_model_sort_get_model
1454                                         (GTK_TREE_MODEL_SORT (model));
1455                         } else
1456                                 mymodel = model;
1457
1458                         folder = (TnyMsgFolderIface*)tny_msg_header_iface_get_folder (header);
1459
1460                         /* this will make the message as deleted */
1461                         /*      tny_msg_folder_iface_expunge (folder); will finally delete messages */
1462                         if (TNY_IS_MSG_FOLDER (folder))
1463                                 tny_msg_folder_iface_remove_message (folder, header);
1464                         gtk_widget_queue_draw (GTK_WIDGET (header_view));
1465                 }
1466         }
1467 }
1468
1469 static void
1470 on_sendreceive_button_clicked (GtkWidget *widget, ModestUI *modest_ui)
1471 {
1472         ModestUIPrivate *priv;
1473         TnyAccountStoreIface *account_store;
1474         const GList *store_accounts;
1475         const GList *iter;
1476
1477         g_return_if_fail (modest_ui);
1478         priv = MODEST_UI_GET_PRIVATE(modest_ui);
1479
1480         account_store = priv->account_store;
1481         store_accounts =
1482                 tny_account_store_iface_get_store_accounts (account_store);
1483         
1484         for (iter = store_accounts; iter; iter = iter->next)
1485                 modest_tny_store_actions_update_folders (TNY_STORE_ACCOUNT_IFACE (iter->data));
1486 }