Replaced the old XML name with the new one
[modest] / src / maemo / modest-main-window.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
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.
16  *
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.
28  */
29
30 #include <hildon-widgets/hildon-window.h>
31
32 #include <glib/gi18n.h>
33 #include <gtk/gtktreeviewcolumn.h>
34 #include <modest-runtime.h>
35
36 #include <widgets/modest-main-window.h>
37 #include <widgets/modest-msg-edit-window.h>
38
39 #include "modest-widget-memory.h"
40 #include "modest-window-priv.h"
41 #include "modest-main-window-ui.h"
42 #include "modest-account-view-window.h"
43 #include "modest-account-mgr.h"
44 #include "modest-conf.h"
45
46 #include "modest-tny-platform-factory.h"
47 #include "modest-tny-msg.h"
48 #include "modest-mail-operation.h"
49 #include "modest-icon-names.h"
50
51 /* 'private'/'protected' functions */
52 static void modest_main_window_class_init    (ModestMainWindowClass *klass);
53 static void modest_main_window_init          (ModestMainWindow *obj);
54 static void modest_main_window_finalize      (GObject *obj);
55
56 static void connect_signals (ModestMainWindow *self);
57 static void restore_sizes (ModestMainWindow *self);
58 static void save_sizes (ModestMainWindow *self);
59
60 /* list my signals */
61 enum {
62         /* MY_SIGNAL_1, */
63         /* MY_SIGNAL_2, */
64         LAST_SIGNAL
65 };
66
67 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
68 struct _ModestMainWindowPrivate {
69         GtkWidget *msg_paned;
70         GtkWidget *main_paned;
71 };
72
73
74 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
75                                                 MODEST_TYPE_MAIN_WINDOW, \
76                                                 ModestMainWindowPrivate))
77
78 typedef struct _GetMsgAsyncHelper {
79         ModestMainWindowPrivate *main_window_private;
80         guint action;
81         ModestMailOperationReplyType reply_type;
82         ModestMailOperationForwardType forward_type;
83         gchar *from;
84         TnyIterator *iter;
85 } GetMsgAsyncHelper;
86
87 /* globals */
88 static GtkWindowClass *parent_class = NULL;
89
90 /* uncomment the following if you have defined any signals */
91 /* static guint signals[LAST_SIGNAL] = {0}; */
92
93 GType
94 modest_main_window_get_type (void)
95 {
96         static GType my_type = 0;
97         if (!my_type) {
98                 static const GTypeInfo my_info = {
99                         sizeof(ModestMainWindowClass),
100                         NULL,           /* base init */
101                         NULL,           /* base finalize */
102                         (GClassInitFunc) modest_main_window_class_init,
103                         NULL,           /* class finalize */
104                         NULL,           /* class data */
105                         sizeof(ModestMainWindow),
106                         1,              /* n_preallocs */
107                         (GInstanceInitFunc) modest_main_window_init,
108                         NULL
109                 };
110                 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
111                                                   "ModestMainWindow",
112                                                   &my_info, 0);
113         }
114         return my_type;
115 }
116
117 static void
118 modest_main_window_class_init (ModestMainWindowClass *klass)
119 {
120         GObjectClass *gobject_class;
121         gobject_class = (GObjectClass*) klass;
122
123         parent_class            = g_type_class_peek_parent (klass);
124         gobject_class->finalize = modest_main_window_finalize;
125
126         g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
127 }
128
129 static void
130 modest_main_window_init (ModestMainWindow *obj)
131 {
132         ModestMainWindowPrivate *priv;
133
134         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
135
136         priv->msg_paned    = NULL;
137         priv->main_paned   = NULL;      
138         obj->header_view  = NULL;
139         obj->folder_view  = NULL;
140
141         /* progress bar */
142         obj->progress_bar = gtk_progress_bar_new ();
143         gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(obj->progress_bar), 1.0);
144         gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR(obj->progress_bar),
145                                         PANGO_ELLIPSIZE_END);
146 }
147
148 static void
149 modest_main_window_finalize (GObject *obj)
150 {
151         G_OBJECT_CLASS(parent_class)->finalize (obj);
152 }
153
154
155
156 static void
157 restore_sizes (ModestMainWindow *self)
158 {
159         ModestConf *conf;
160         ModestMainWindowPrivate *priv;
161
162         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
163
164         conf = modest_runtime_get_conf ();
165         
166         modest_widget_memory_restore (conf,G_OBJECT(self),
167                                       "modest-main-window");
168         modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
169                                       "modest-main-paned");
170         modest_widget_memory_restore (conf, G_OBJECT(self->header_view),
171                                       "header-view");
172 }
173
174
175 static void
176 save_sizes (ModestMainWindow *self)
177 {
178         ModestConf *conf;
179         ModestMainWindowPrivate *priv;
180                 
181         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
182         conf = modest_runtime_get_conf ();
183         
184         modest_widget_memory_save (conf,G_OBJECT(self), "modest-main-window");
185         modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
186                                    "modest-main-paned");
187         modest_widget_memory_save (conf, G_OBJECT(self->header_view), "header-view");
188 }
189
190 static GtkWidget*
191 wrapped_in_scrolled_window (GtkWidget *widget, gboolean needs_viewport)
192 {
193         GtkWidget *win;
194
195         win = gtk_scrolled_window_new (NULL, NULL);
196         gtk_scrolled_window_set_policy
197                 (GTK_SCROLLED_WINDOW (win),GTK_POLICY_NEVER,
198                  GTK_POLICY_AUTOMATIC);
199         
200         if (needs_viewport)
201                 gtk_scrolled_window_add_with_viewport
202                         (GTK_SCROLLED_WINDOW(win), widget);
203         else
204                 gtk_container_add (GTK_CONTAINER(win),
205                                    widget);
206
207         return win;
208 }
209
210
211 static gboolean
212 on_delete_event (GtkWidget *widget, GdkEvent  *event, ModestMainWindow *self)
213 {
214         save_sizes (self);
215         return FALSE;
216 }
217
218 static GtkWidget *
219 menubar_to_menu (GtkUIManager *ui_manager)
220 {
221         GtkWidget *main_menu;
222         GtkWidget *menubar;
223         GList *iter;
224
225         /* Create new main menu */
226         main_menu = gtk_menu_new();
227
228         /* Get the menubar from the UI manager */
229         menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
230
231         iter = gtk_container_get_children (GTK_CONTAINER (menubar));
232         while (iter) {
233                 GtkWidget *menu;
234
235                 menu = GTK_WIDGET (iter->data);
236                 gtk_widget_reparent(menu, main_menu);
237
238                 iter = g_list_next (iter);
239         }
240         return main_menu;
241 }
242
243 static GtkWidget*
244 get_toolbar (ModestMainWindow *self)
245 {
246         GtkWidget   *toolbar, *progress_box, *progress_alignment;
247         GtkToolItem *progress_item;
248         ModestWindowPrivate *parent_priv;
249         GtkWidget   *stop_icon;
250         
251         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
252         
253         /* Toolbar */
254         toolbar       = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
255
256         gtk_progress_bar_set_text (GTK_PROGRESS_BAR(self->progress_bar), "Connecting...");
257
258         progress_box        = gtk_hbox_new (FALSE, HILDON_MARGIN_DEFAULT);
259         progress_alignment  = gtk_alignment_new (0.5, 0.5, 1, 0);
260         
261         gtk_container_add  (GTK_CONTAINER(progress_alignment), self->progress_bar);
262         gtk_box_pack_start (GTK_BOX(progress_box), progress_alignment, TRUE, TRUE, 0);
263         
264         progress_item  = gtk_tool_item_new ();
265         gtk_container_add (GTK_CONTAINER(progress_item), progress_box);
266         gtk_tool_item_set_homogeneous (progress_item, FALSE);
267         gtk_tool_item_set_expand(progress_item, TRUE);
268         
269         gtk_toolbar_insert (GTK_TOOLBAR(toolbar), progress_item,
270                             gtk_toolbar_get_n_items(GTK_TOOLBAR(toolbar)));
271
272         stop_icon = gtk_image_new_from_icon_name("qgn_toolb_gene_stop", GTK_ICON_SIZE_BUTTON);
273         gtk_toolbar_insert (GTK_TOOLBAR(toolbar), gtk_tool_button_new(stop_icon, NULL),
274                             gtk_toolbar_get_n_items(GTK_TOOLBAR(toolbar)));
275
276
277         gtk_widget_show_all (toolbar);
278         return toolbar;
279 }
280
281
282 static void
283 on_destroy (GtkWidget *widget, GdkEvent  *event, ModestMainWindow *self)
284 {
285         gtk_main_quit();
286 }
287
288 static void
289 connect_signals (ModestMainWindow *self)
290 {       
291         ModestWindowPrivate *parent_priv;
292         ModestMainWindowPrivate *priv;
293         TnyDevice *device;
294         ModestTnyAccountStore *account_store;
295         
296         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
297         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
298
299         account_store = modest_runtime_get_account_store ();
300         device        = tny_account_store_get_device(TNY_ACCOUNT_STORE(account_store));
301         
302         /* folder view */
303         g_signal_connect (G_OBJECT(self->folder_view), "folder_selection_changed",
304                           G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
305         g_signal_connect (G_OBJECT(self->folder_view), "folder_moved",
306                           G_CALLBACK(modest_ui_actions_on_folder_moved), NULL);
307 //      g_signal_connect (G_OBJECT(self->folder_view), "button-press-event",
308 //                        G_CALLBACK (on_folder_view_button_press_event),self);
309 //      g_signal_connect (self->folder_view,"popup-menu",
310 //                        G_CALLBACK (on_folder_view_button_press_event),self);
311
312         /* header view */
313         g_signal_connect (G_OBJECT(self->header_view), "status_update",
314                           G_CALLBACK(modest_ui_actions_on_header_status_update), self);
315         g_signal_connect (G_OBJECT(self->header_view), "header_selected",
316                           G_CALLBACK(modest_ui_actions_on_header_selected), self);
317         g_signal_connect (G_OBJECT(self->header_view), "header_activated",
318                           G_CALLBACK(modest_ui_actions_on_header_activated), self);
319         g_signal_connect (G_OBJECT(self->header_view), "item_not_found",
320                           G_CALLBACK(modest_ui_actions_on_item_not_found), self);
321 //      g_signal_connect (G_OBJECT(self->header_view), "button-press-event",
322 //                        G_CALLBACK (on_header_view_button_press_event), self);
323 //      g_signal_connect (G_OBJECT(self->header_view),"popup-menu",0
324 //                        G_CALLBACK (on_header_view_button_press_event), self);
325
326         /* Account store */
327         g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), "accounts_reloaded",
328                           G_CALLBACK (modest_ui_actions_on_accounts_reloaded), self);
329         
330         
331         /* window */
332         g_signal_connect (G_OBJECT(self), "destroy", G_CALLBACK(on_destroy), NULL);
333         g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
334 }
335
336
337
338 ModestWindow*
339 modest_main_window_new (void)
340 {
341         ModestMainWindow *self; 
342         ModestMainWindowPrivate *priv;
343         ModestWindowPrivate *parent_priv;
344         GtkWidget *main_vbox;
345         GtkWidget *header_win, *folder_win;
346         GtkActionGroup *action_group;
347         GError *error = NULL;
348         TnyFolderStoreQuery     *query;
349
350         self  = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
351         priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
352         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
353
354         parent_priv->ui_manager = gtk_ui_manager_new();
355         action_group = gtk_action_group_new ("ModestMainWindowActions");
356
357         /* Add common actions */
358         gtk_action_group_add_actions (action_group,
359                                       modest_action_entries,
360                                       G_N_ELEMENTS (modest_action_entries),
361                                       self);
362         
363         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
364         g_object_unref (action_group);
365
366         /* Load the UI definition */
367         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-main-window-ui.xml", &error);
368         if (error != NULL) {
369                 g_warning ("Could not merge modest-ui.xml: %s", error->message);
370                 g_error_free (error);
371                 error = NULL;
372         }
373
374         /* Add accelerators */
375         gtk_window_add_accel_group (GTK_WINDOW (self), 
376                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
377
378         /* add the toolbar */
379         parent_priv->toolbar = get_toolbar(self);
380         hildon_window_add_toolbar (HILDON_WINDOW (self), GTK_TOOLBAR (parent_priv->toolbar));
381
382         /* Menubar */
383         parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
384         hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
385
386         /* folder view */
387         query = tny_folder_store_query_new ();
388         tny_folder_store_query_add_item (query, NULL,
389                                          TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
390         self->folder_view =
391                 MODEST_FOLDER_VIEW(modest_folder_view_new (modest_runtime_get_account_store(),
392                                                            query));
393         if (!self->folder_view)
394                 g_printerr ("modest: cannot instantiate folder view\n");        
395         g_object_unref (G_OBJECT (query));
396         
397         /* header view */
398         self->header_view  =
399                 MODEST_HEADER_VIEW(modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
400         if (!self->header_view)
401                 g_printerr ("modest: cannot instantiate header view\n");
402         
403         
404         folder_win = wrapped_in_scrolled_window (GTK_WIDGET(self->folder_view), FALSE);
405         header_win = wrapped_in_scrolled_window (GTK_WIDGET(self->header_view), FALSE);                    
406
407         /* paned */
408         priv->main_paned = gtk_hpaned_new ();
409         gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
410         gtk_paned_add2 (GTK_PANED(priv->main_paned), header_win);
411         gtk_widget_show (GTK_WIDGET(self->header_view));
412         gtk_tree_view_columns_autosize (GTK_TREE_VIEW(self->header_view));
413
414         /* putting it all together... */
415         main_vbox = gtk_vbox_new (FALSE, 6);
416         gtk_box_pack_start (GTK_BOX(main_vbox), priv->main_paned, TRUE, TRUE,0);
417
418         gtk_container_add (GTK_CONTAINER(self), main_vbox);
419         restore_sizes (MODEST_MAIN_WINDOW(self));       
420
421         gtk_window_set_title (GTK_WINDOW(self), _("Modest"));
422         gtk_window_set_icon_from_file (GTK_WINDOW(self), MODEST_APP_ICON, NULL);
423         
424         gtk_widget_show_all (main_vbox);
425
426         g_signal_connect (G_OBJECT(self), "delete-event",
427                           G_CALLBACK(on_delete_event), self);
428
429         connect_signals (self);
430         return MODEST_WINDOW(self);
431 }