* first mods to move the menu into the HildonApp
[modest] / src / hildon / modest-ui-main-view.c
1 #include <gtk/gtk.h>
2 #include <glade/glade.h>
3 #include <glib/gi18n.h>
4 #include <string.h>
5
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif /*HAVE_CONFIG_H*/
9
10 #include <hildon-widgets/hildon-app.h>
11
12 /* TODO: put in auto* */
13 #include <tny-text-buffer-stream.h>
14 #include <tny-msg-folder.h>
15
16 #include "../modest-ui.h"
17 #include "../modest-window-mgr.h"
18 #include "../modest-account-mgr.h"
19 #include "../modest-account-mgr.h"
20 #include "../modest-identity-mgr.h"
21
22 #include "../modest-tny-account-store.h"
23 #include "../modest-tny-folder-tree-view.h"
24 #include "../modest-tny-header-tree-view.h"
25 #include "../modest-tny-msg-view.h"
26 #include "../modest-tny-transport-actions.h"
27 #include "../modest-tny-store-actions.h"
28
29 #include "../modest-text-utils.h"
30 #include "../modest-tny-msg-actions.h"
31
32 #include "../modest-editor-window.h"
33
34 #include "modest-ui-glade.h"
35 #include "modest-ui-wizard.h"
36 #include "modest-ui-account-setup.h"
37
38 #include "modest-ui-main-view.h"
39 #include "modest-ui-message-editor.h"
40 #include "modest-ui-message-viewer.h"
41
42
43 static GtkWidget* modest_main_window_folder_tree (ModestAccountMgr *modest_acc_mgr,
44                                                   TnyAccountStoreIface *account_store);
45
46 static GtkWidget* modest_main_window_header_tree (TnyMsgFolderIface *folder);
47
48 static void on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
49                                TnyMsgFolderIface *folder,
50                                gpointer data);
51
52 static void on_message_clicked (ModestTnyFolderTreeView *folder_tree,
53                                 TnyMsgIface *message,
54                                 gpointer data);
55
56 static void on_reply_clicked (GtkWidget *widget, gpointer user_data);
57
58 static void on_forward_clicked (GtkWidget *widget, gpointer user_data);
59
60 static void on_delete_clicked (GtkWidget *widget, gpointer user_data);
61
62 static void on_view_attachments_toggled(GtkWidget *widget, gpointer user_data);
63
64 static void on_sendreceive_button_clicked (GtkWidget *widget, gpointer user_data);
65
66 static void on_forward_attached_activated (GtkWidget *widget, gpointer user_data);
67
68 static void on_headers_status_update (GtkWidget *header_view, const gchar *msg, gint status,
69                           gpointer user_data);
70 static void on_status_cleanup (gpointer user_data);
71
72 static void register_toolbar_callbacks (ModestUI *modest_ui);
73
74
75 static void
76 modest_ui_main_view_destroy (GtkWidget *win, GdkEvent *event, gpointer data)
77 {
78         ModestUIPrivate *priv;
79
80         g_return_if_fail (data);
81         g_return_if_fail(MODEST_IS_UI(data));
82         priv = MODEST_UI_GET_PRIVATE((ModestUI *)data);
83         g_return_if_fail(priv);
84         if (!modest_window_mgr_unregister (priv->modest_window_mgr, G_OBJECT(win)))
85                 g_warning ("modest window mgr: failed to unregister %p",
86                            G_OBJECT(win));
87         else
88                 gtk_widget_hide(win);
89 }
90
91
92 gboolean
93 modest_ui_show_main_window (ModestUI *modest_ui)
94 {
95         GtkWidget       *win;
96         gint              height, width;
97         ModestUIPrivate *priv;
98         GtkWidget     *folder_view, *header_view;
99         GtkWidget     *message_view;
100         GtkWidget     *account_settings_item;
101         GtkWidget     *forward_attached_menu_item;
102         GtkWidget     *delete_item;
103         GtkWidget     *open_item;
104         GtkWidget     *view_attachments_item;
105         GtkWidget     *new_account_item;
106         GtkWidget     *main_menu, *menu_item;
107         
108         GtkWidget  *folder_view_holder,
109                 *header_view_holder,
110                 *mail_paned;
111         gboolean show_attachments_inline;
112
113         priv = MODEST_UI_GET_PRIVATE(modest_ui);
114         
115         height = modest_conf_get_int (priv->modest_conf,
116                                       MODEST_CONF_MAIN_WINDOW_HEIGHT,NULL);
117         width  = modest_conf_get_int (priv->modest_conf,
118                                       MODEST_CONF_MAIN_WINDOW_WIDTH,NULL);
119
120         win = glade_xml_get_widget (priv->glade_xml, "main");
121         if (!win) {
122                 g_warning ("could not create main window");
123                 return FALSE;
124         }
125
126         folder_view = GTK_WIDGET(modest_main_window_folder_tree(priv->modest_acc_mgr,
127                                                           priv->account_store));
128         priv->folder_view = folder_view;
129         folder_view_holder = glade_xml_get_widget (priv->glade_xml, "folders");
130         if (!folder_view||!folder_view_holder) {
131                 g_warning ("failed to create folder tree");
132                 return FALSE;
133         }
134         gtk_container_add (GTK_CONTAINER(folder_view_holder), folder_view);
135
136         header_view  =  GTK_WIDGET(modest_main_window_header_tree (NULL));
137         priv->header_view = header_view;
138         header_view_holder = glade_xml_get_widget (priv->glade_xml, "mail_list");
139         if (!header_view) {
140                 g_warning ("failed to create header tree");
141                 return FALSE;
142         }
143         gtk_container_add (GTK_CONTAINER(header_view_holder), header_view);
144
145         g_signal_connect (G_OBJECT(folder_view), "folder_selected",
146                           G_CALLBACK(on_folder_clicked), modest_ui);
147
148         show_attachments_inline = modest_conf_get_bool(priv->modest_conf,
149                                              MODEST_CONF_MSG_VIEW_SHOW_ATTACHMENTS_INLINE,
150                                              NULL);
151
152         message_view  = GTK_WIDGET(modest_tny_msg_view_new (NULL, show_attachments_inline));
153         priv->message_view = message_view;
154         if (!message_view) {
155                 g_warning ("failed to create message view");
156                 return FALSE;
157         }
158
159         mail_paned = glade_xml_get_widget (priv->glade_xml, "mail_paned");
160         gtk_paned_add2 (GTK_PANED(mail_paned), message_view);
161
162         g_signal_connect (header_view, "message_selected",
163                           G_CALLBACK(on_message_clicked),
164                           modest_ui);
165
166         g_signal_connect (header_view, "status_update",
167                           G_CALLBACK(on_headers_status_update), modest_ui);
168
169         g_signal_connect (header_view, "row-activated",
170                           G_CALLBACK(on_message_activated),
171                           modest_ui);
172
173         account_settings_item = glade_xml_get_widget (priv->glade_xml, "AccountSettingsMenuItem");
174         if (!account_settings_item) {
175                 g_warning ("The account settings item isn't available!\n");
176                 return FALSE;
177         }
178
179         g_signal_connect (account_settings_item, "activate",
180                           G_CALLBACK(account_settings), modest_ui);
181
182         new_account_item = glade_xml_get_widget (priv->glade_xml, "NewAccountWizardMenuItem");
183         if (!new_account_item) {
184                 g_warning ("The new account item isn't available!\n");
185                 return FALSE;
186         }
187
188         g_signal_connect (new_account_item, "activate",
189                 G_CALLBACK(new_wizard_account), modest_ui);
190
191         open_item = glade_xml_get_widget (priv->glade_xml, "open1");
192         if (!open_item) {
193                 g_warning ("The open item isn't available!\n");
194                 return FALSE;
195         }
196         g_signal_connect (open_item, "activate", G_CALLBACK(on_open_message_clicked),
197                           modest_ui);
198
199         delete_item = glade_xml_get_widget (priv->glade_xml, "delete1");
200         if (!delete_item) {
201                 g_warning ("The delete item isn't available!\n");
202                 return FALSE;
203         }
204         g_signal_connect (delete_item, "activate", G_CALLBACK(on_delete_clicked),
205                           modest_ui);
206
207         view_attachments_item = glade_xml_get_widget (priv->glade_xml, "menu_view_attachments");
208         if (!view_attachments_item) {
209                 g_warning ("The view_attachments_item isn't available!");
210                 return FALSE;
211         }
212
213         forward_attached_menu_item = glade_xml_get_widget (priv->glade_xml, "forward_attached");
214         if (!forward_attached_menu_item) {
215                 g_warning ("The forward_attached_menu_item isn't available!");
216                 return FALSE;
217         }
218         g_signal_connect (forward_attached_menu_item, "activate", G_CALLBACK(on_forward_attached_activated),
219                           modest_ui);
220
221         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(view_attachments_item),
222                                         modest_conf_get_bool(priv->modest_conf,
223                                         MODEST_CONF_MSG_VIEW_SHOW_ATTACHMENTS_INLINE,
224                                         NULL));
225
226         g_signal_connect (view_attachments_item, "toggled",
227                                 G_CALLBACK(on_view_attachments_toggled), modest_ui);
228
229         register_toolbar_callbacks (modest_ui);
230
231         modest_window_mgr_register (priv->modest_window_mgr,
232                                     G_OBJECT(win), MODEST_MAIN_WINDOW, 0);
233         g_signal_connect (win, "destroy-event", G_CALLBACK(modest_ui_main_view_destroy),
234                           modest_ui);
235         g_signal_connect (win, "delete-event", G_CALLBACK(modest_ui_main_view_destroy),
236                           modest_ui);
237         gtk_widget_set_usize (GTK_WIDGET(win), width, height);
238         hildon_app_set_title (HILDON_APP(win), PACKAGE_STRING);
239
240         main_menu = hildon_appview_get_menu(HILDON_APP(win));
241         menu_item = glade_xml_get_widget (priv->glade_xml, "MessageMenuItem");
242         gtk_menu_append(main_menu, menu_item);
243
244         gtk_widget_show_all (win);
245
246         menu_item = glade_xml_get_widget (priv->glade_xml, "menubar1");
247         gtk_widget_hide(menu_item);
248
249
250         return TRUE;
251 }
252
253
254 static void
255 register_toolbar_callbacks (ModestUI *modest_ui)
256 {
257         ModestUIPrivate *priv;
258         GtkWidget *button;
259
260         g_return_if_fail (modest_ui);
261
262         priv = MODEST_UI_GET_PRIVATE (modest_ui);
263
264         button = glade_xml_get_widget (priv->glade_xml, "toolb_new_mail");
265         if (button)
266                 g_signal_connect (button, "clicked",
267                                   G_CALLBACK(on_new_mail_clicked), modest_ui);
268
269         button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
270         if (button) {
271                 g_signal_connect (button, "clicked",
272                                   G_CALLBACK(on_reply_clicked), modest_ui);
273                 gtk_widget_set_sensitive(button, FALSE);
274         }
275
276         button = glade_xml_get_widget (priv->glade_xml, "toolb_reply_all");
277         if (button) {
278                 //g_signal_connect (button, "clicked",
279                 //                G_CALLBACK(on_reply_all_clicked), modest_ui);
280                 gtk_widget_set_sensitive(button, FALSE);
281         }
282
283         button = glade_xml_get_widget (priv->glade_xml, "toolb_forward");
284         if (button) {
285                 g_signal_connect (button, "clicked",
286                                   G_CALLBACK(on_forward_clicked), modest_ui);
287                 gtk_widget_set_sensitive(button, FALSE);
288         }
289
290         button = glade_xml_get_widget (priv->glade_xml, "toolb_move_to");
291         if (button) {
292                 //g_signal_connect (button, "clicked",
293                 //                G_CALLBACK(on_move_to_clicked), modest_ui);
294                 gtk_widget_set_sensitive(button, FALSE);
295         }
296
297         button = glade_xml_get_widget (priv->glade_xml, "toolb_delete");
298         if (button) {
299                 g_signal_connect (button, "clicked",
300                                   G_CALLBACK(on_delete_clicked), modest_ui);
301                 gtk_widget_set_sensitive(button, FALSE);
302         }
303
304         button = glade_xml_get_widget (priv->glade_xml, "toolb_send_receive");
305         if (button) {
306                 g_signal_connect (button, "clicked",
307                                   G_CALLBACK(on_sendreceive_button_clicked), modest_ui);
308                 gtk_widget_set_sensitive(button, TRUE);
309         }
310 }
311
312
313 static void
314 on_folder_clicked (ModestTnyFolderTreeView *folder_tree,
315                    TnyMsgFolderIface *folder,
316                    gpointer data)
317 {
318         GtkWidget *win;
319         GtkWidget *button;
320         ModestTnyHeaderTreeView *tree_view;
321         ModestTnyMsgView *msg_view;
322         ModestUIPrivate *priv;
323         GtkWidget *scrollview;
324
325         g_return_if_fail (folder);
326         g_return_if_fail (data);
327
328         priv = MODEST_UI_GET_PRIVATE(data);
329         scrollview = glade_xml_get_widget (priv->glade_xml,"mail_list");
330
331         tree_view = MODEST_TNY_HEADER_TREE_VIEW (priv->header_view);
332
333         win = glade_xml_get_widget (priv->glade_xml, "main");
334         gtk_window_set_title (GTK_WINDOW(win),
335                               tny_msg_folder_iface_get_name(folder));
336
337         modest_tny_header_tree_view_set_folder (tree_view, folder);
338         priv->current_folder = folder;
339
340         button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
341         if (button) {
342                 gtk_widget_set_sensitive(button, FALSE);
343         }
344
345         button = glade_xml_get_widget (priv->glade_xml, "toolb_forward");
346         if (button) {
347                 gtk_widget_set_sensitive(button, FALSE);
348         }
349
350         button = glade_xml_get_widget (priv->glade_xml, "toolb_delete");
351         if (button) {
352                 gtk_widget_set_sensitive(button, FALSE);
353         }
354
355         msg_view = MODEST_TNY_MSG_VIEW (priv->message_view);
356         g_return_if_fail (msg_view);
357
358         modest_tny_msg_view_set_message  (msg_view, NULL);
359 }
360
361
362 static void
363 on_message_clicked (ModestTnyFolderTreeView *folder_tree,
364                                 TnyMsgIface *message,
365                                 gpointer data)
366 {
367         GtkWidget *button;
368         ModestTnyMsgView *msg_view;
369         ModestUIPrivate *priv;
370
371         g_return_if_fail (data);
372
373         priv = MODEST_UI_GET_PRIVATE (data);
374         msg_view = MODEST_TNY_MSG_VIEW (priv->message_view);
375
376         modest_tny_msg_view_set_message (msg_view, message);
377         
378         button = glade_xml_get_widget (priv->glade_xml, "toolb_reply");
379         if (button) {
380                 gtk_widget_set_sensitive(button, TRUE);
381         }
382         button = glade_xml_get_widget (priv->glade_xml, "toolb_forward");
383         if (button) {
384                 gtk_widget_set_sensitive(button, TRUE);
385         }
386         button = glade_xml_get_widget (priv->glade_xml, "toolb_delete");
387         if (button) {
388                 gtk_widget_set_sensitive(button, TRUE);
389         }
390 }
391
392
393 static GtkWidget*
394 modest_main_window_header_tree (TnyMsgFolderIface *folder)
395 {
396         int i;
397         GSList *columns = NULL;
398         GtkWidget *header_tree;
399         ModestTnyHeaderTreeViewColumn cols[] = {
400                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_MSGTYPE,
401                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_ATTACH,
402                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_FROM,
403                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_SUBJECT,
404                 MODEST_TNY_HEADER_TREE_VIEW_COLUMN_RECEIVED_DATE
405         };
406
407         for (i = 0 ; i != sizeof(cols) / sizeof(ModestTnyHeaderTreeViewColumn); ++i)
408                 columns = g_slist_append (columns, GINT_TO_POINTER(cols[i]));
409
410         header_tree = GTK_WIDGET(modest_tny_header_tree_view_new(folder, columns,
411                                                                  MODEST_TNY_HEADER_TREE_VIEW_STYLE_NORMAL));
412         g_slist_free (columns);
413
414         if (!header_tree) {
415                 g_warning ("could not create header tree");
416                 return NULL;
417         }
418
419         return GTK_WIDGET(header_tree);
420 }
421
422
423 static GtkWidget*
424 modest_main_window_folder_tree (ModestAccountMgr *modest_acc_mgr,
425                                 TnyAccountStoreIface *account_store)
426 {
427         GtkWidget *folder_tree;
428
429         folder_tree = GTK_WIDGET (modest_tny_folder_tree_view_new (account_store));
430         if (!folder_tree) {
431                 g_warning ("could not create folder list");
432                 return NULL;
433         }
434
435         return folder_tree;
436 }
437
438
439 static void
440 on_reply_clicked (GtkWidget *widget, gpointer user_data)
441 {
442         ModestUI *modest_ui = (ModestUI *)user_data;
443
444         quoted_send_msg (modest_ui, QUOTED_SEND_REPLY);
445 }
446
447
448 static void
449 on_forward_clicked (GtkWidget *widget, gpointer user_data)
450 {
451         ModestUI *modest_ui = (ModestUI *)user_data;
452
453         quoted_send_msg (modest_ui, QUOTED_SEND_FORWARD);
454 }
455
456
457 static void
458 on_view_attachments_toggled(GtkWidget *widget, gpointer user_data)
459 {
460         ModestUI *modest_ui = (ModestUI *)user_data;
461         GtkWidget *view_attachments_item;
462         ModestTnyMsgView *msg_view;
463         ModestUIPrivate *priv;
464         gboolean view_attachments_inline;
465
466         priv = MODEST_UI_GET_PRIVATE(modest_ui);
467         view_attachments_item = glade_xml_get_widget (priv->glade_xml, "menu_view_attachments");
468         g_return_if_fail(view_attachments_item);
469
470         msg_view = MODEST_TNY_MSG_VIEW(priv->message_view);
471
472         view_attachments_inline = gtk_check_menu_item_get_active(
473                                         GTK_CHECK_MENU_ITEM(view_attachments_item));
474
475         modest_conf_set_bool(priv->modest_conf,
476                              MODEST_CONF_MSG_VIEW_SHOW_ATTACHMENTS_INLINE,
477                              view_attachments_inline,
478                              NULL);
479
480         modest_tny_msg_view_set_show_attachments_inline_flag(msg_view, view_attachments_inline);
481 }
482
483
484 static void
485 on_delete_clicked (GtkWidget *widget, gpointer user_data)
486 {
487         ModestUI *modest_ui = (ModestUI *)user_data;
488         GtkTreeSelection *sel;
489         GtkTreeModel *model;
490         GtkTreeIter iter;
491         GtkTreeModel *mymodel;
492
493         ModestTnyHeaderTreeView *header_view;
494         ModestTnyMsgView *msg_view;
495         ModestUIPrivate *priv;
496
497         g_return_if_fail (modest_ui);
498
499         priv = MODEST_UI_GET_PRIVATE(modest_ui);
500
501         msg_view = MODEST_TNY_MSG_VIEW(priv->message_view);
502         g_return_if_fail (msg_view);
503
504         header_view = MODEST_TNY_HEADER_TREE_VIEW(priv->header_view);
505         g_return_if_fail (header_view);
506
507         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
508         g_return_if_fail (sel);
509
510         /* get all selected mails */
511         if (G_LIKELY (gtk_tree_selection_get_selected (sel, &model, &iter))) {
512                 TnyMsgHeaderIface *header;
513
514                 gtk_tree_model_get (model, &iter, TNY_MSG_HEADER_LIST_MODEL_INSTANCE_COLUMN,
515                         &header, -1);
516
517                 if (G_LIKELY (header)) {
518                         TnyMsgFolderIface *folder;
519                         // const TnyMsgIface *msg;
520
521                         if (GTK_IS_TREE_MODEL_SORT (model)) {
522                                 mymodel = gtk_tree_model_sort_get_model
523                                         (GTK_TREE_MODEL_SORT (model));
524                         } else
525                                 mymodel = model;
526
527                         folder = (TnyMsgFolderIface*)tny_msg_header_iface_get_folder (header);
528
529                         /* this will make the message as deleted */
530                         /*      tny_msg_folder_iface_expunge (folder); will finally delete messages */
531                         if (TNY_IS_MSG_FOLDER (folder))
532                                 tny_msg_folder_iface_remove_message (folder, header);
533                         gtk_widget_queue_draw (GTK_WIDGET (header_view));
534                 }
535         }
536 }
537
538
539 static void
540 on_sendreceive_button_clicked (GtkWidget *widget, gpointer user_data)
541 {
542         ModestUI *modest_ui = (ModestUI *)user_data;
543         ModestUIPrivate *priv;
544         TnyAccountStoreIface *account_store;
545         const GList *store_accounts;
546         const GList *iter;
547
548         g_return_if_fail (modest_ui);
549         priv = MODEST_UI_GET_PRIVATE(modest_ui);
550
551         account_store = priv->account_store;
552         store_accounts =
553                 tny_account_store_iface_get_store_accounts (account_store);
554                 
555         for (iter = store_accounts; iter; iter = iter->next) {
556                 modest_tny_store_actions_update_folders (TNY_STORE_ACCOUNT_IFACE (iter->data));
557
558         }
559         
560         if (priv->header_view && priv->current_folder) {
561                         
562                 modest_tny_header_tree_view_set_folder (MODEST_TNY_HEADER_TREE_VIEW(priv->header_view),
563                                                         priv->current_folder);
564                 gtk_widget_queue_draw (priv->header_view);
565         }
566 }
567 static void
568 on_forward_attached_activated (GtkWidget *widget, gpointer user_data)
569 {
570         ModestUI *modest_ui = (ModestUI *)user_data;
571
572         quoted_send_msg (modest_ui, QUOTED_SEND_FORWARD_ATTACHED);
573 }
574
575 static void
576 on_headers_status_update (GtkWidget *header_view, const gchar *msg, gint status_id,
577                           gpointer user_data)
578 {
579         ModestUIPrivate *priv;
580         ModestUI *modest_ui;
581
582         GtkStatusbar *status_bar;
583         GtkProgressBar *progress_bar;
584         GtkWidget    *status_box;
585         
586         modest_ui = MODEST_UI (user_data);
587         priv      = MODEST_UI_GET_PRIVATE(modest_ui);
588
589         progress_bar = GTK_PROGRESS_BAR(glade_xml_get_widget
590                                         (priv->glade_xml, "progressbar"));
591         status_bar   = GTK_STATUSBAR  (glade_xml_get_widget
592                                        (priv->glade_xml, "statusbar"));
593
594         
595         status_box   = glade_xml_get_widget (priv->glade_xml, "statusbox");
596         
597         
598         if (!status_bar || !progress_bar) {
599                 g_warning ("failed to find status / progress bar");
600                 return;
601         }
602
603         if (msg && status_id) {
604                 gtk_widget_show (status_box);
605                 gtk_progress_bar_pulse (progress_bar);
606                 gtk_statusbar_push (status_bar, status_id, msg);
607         } else {
608                 gtk_widget_hide   (status_box);
609                 gtk_statusbar_pop (status_bar, status_id);
610         }
611 }               
612