979b3cd97dfad93112543f722cc996e5d7fae500
[modest] / src / hildon2 / modest-folder-window.c
1 /* Copyright (c) 2008, 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 <modest-folder-window.h>
31 #include <modest-osso-state-saving.h>
32 #include <libosso.h>
33 #include <hildon/hildon-pannable-area.h>
34 #include <modest-window-mgr.h>
35 #include <modest-signal-mgr.h>
36 #include <modest-runtime.h>
37 #include <modest-platform.h>
38 #include <modest-maemo-utils.h>
39 #include <modest-icon-names.h>
40 #include <modest-ui-constants.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
43 #include <modest-defs.h>
44 #include <modest-ui-actions.h>
45 #include <modest-window.h>
46 #include <hildon/hildon-program.h>
47 #include <hildon/hildon-banner.h>
48 #include <hildon/hildon-button.h>
49 #include <tny-account-store-view.h>
50 #include <modest-header-window.h>
51 #include <modest-ui-dimming-rules.h>
52 #include <modest-ui-dimming-manager.h>
53 #include <modest-window-priv.h>
54 #include "modest-text-utils.h"
55 #include "modest-tny-account.h"
56 #include "modest-account-protocol.h"
57
58 typedef enum {
59         EDIT_MODE_COMMAND_MOVE = 1,
60         EDIT_MODE_COMMAND_DELETE = 2,
61         EDIT_MODE_COMMAND_RENAME = 3,
62 } EditModeCommand;
63
64 /* 'private'/'protected' functions */
65 static void modest_folder_window_class_init  (ModestFolderWindowClass *klass);
66 static void modest_folder_window_init        (ModestFolderWindow *obj);
67 static void modest_folder_window_finalize    (GObject *obj);
68
69 static void connect_signals (ModestFolderWindow *self);
70 static void modest_folder_window_disconnect_signals (ModestWindow *self);
71
72 static void on_folder_activated (ModestFolderView *folder_view,
73                                  TnyFolder *folder,
74                                  gpointer userdata);
75 static void setup_menu (ModestFolderWindow *self);
76
77 static void set_delete_edit_mode (GtkButton *button,
78                                   ModestFolderWindow *self);
79 static void set_moveto_edit_mode (GtkButton *button,
80                                   ModestFolderWindow *self);
81 static void set_rename_edit_mode (GtkButton *button,
82                                   ModestFolderWindow *self);
83 static void modest_folder_window_pack_toolbar (ModestHildon2Window *self,
84                                                GtkPackType pack_type,
85                                                GtkWidget *toolbar);
86 static void edit_mode_changed (ModestFolderWindow *folder_window,
87                                gint edit_mode_id,
88                                gboolean enabled,
89                                ModestFolderWindow *self);
90 static void on_progress_list_changed (ModestWindowMgr *mgr,
91                                       ModestFolderWindow *self);
92 static gboolean on_map_event (GtkWidget *widget,
93                               GdkEvent *event,
94                               gpointer userdata);
95 static void update_progress_hint (ModestFolderWindow *self);
96 static void on_queue_changed    (ModestMailOperationQueue *queue,
97                                  ModestMailOperation *mail_op,
98                                  ModestMailOperationQueueNotification type,
99                                  ModestFolderWindow *self);
100 static void on_activity_changed (ModestFolderView *view,
101                                  gboolean activity,
102                                  ModestFolderWindow *folder_window);
103 static void on_visible_account_changed (ModestFolderView *folder_view,
104                                         const gchar *account_id,
105                                         gpointer user_data);
106 static void on_account_changed (TnyAccountStore *account_store,
107                                 TnyAccount *account,
108                                 gpointer user_data);
109
110 typedef struct _ModestFolderWindowPrivate ModestFolderWindowPrivate;
111 struct _ModestFolderWindowPrivate {
112
113         GtkWidget *folder_view;
114         GtkWidget *top_vbox;
115         GtkWidget *new_message_button;
116
117         /* signals */
118         GSList *sighandlers;
119
120         gchar *current_store_account;
121         gboolean progress_hint;
122         guint queue_change_handler;
123 };
124 #define MODEST_FOLDER_WINDOW_GET_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE((o), \
125                                                                           MODEST_TYPE_FOLDER_WINDOW, \
126                                                                           ModestFolderWindowPrivate))
127
128 /* globals */
129 static GtkWindowClass *parent_class = NULL;
130
131 /************************************************************************/
132
133 GType
134 modest_folder_window_get_type (void)
135 {
136         static GType my_type = 0;
137         if (!my_type) {
138                 static const GTypeInfo my_info = {
139                         sizeof(ModestFolderWindowClass),
140                         NULL,           /* base init */
141                         NULL,           /* base finalize */
142                         (GClassInitFunc) modest_folder_window_class_init,
143                         NULL,           /* class finalize */
144                         NULL,           /* class data */
145                         sizeof(ModestFolderWindow),
146                         1,              /* n_preallocs */
147                         (GInstanceInitFunc) modest_folder_window_init,
148                         NULL
149                 };
150                 my_type = g_type_register_static (MODEST_TYPE_HILDON2_WINDOW,
151                                                   "ModestFolderWindow",
152                                                   &my_info, 0);
153         }
154         return my_type;
155 }
156
157 static void
158 modest_folder_window_class_init (ModestFolderWindowClass *klass)
159 {
160         GObjectClass *gobject_class;
161         gobject_class = (GObjectClass*) klass;
162         ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
163         ModestHildon2WindowClass *modest_hildon2_window_class = (ModestHildon2WindowClass *) klass;
164
165         parent_class            = g_type_class_peek_parent (klass);
166         gobject_class->finalize = modest_folder_window_finalize;
167
168         g_type_class_add_private (gobject_class, sizeof(ModestFolderWindowPrivate));
169         
170         modest_window_class->disconnect_signals_func = modest_folder_window_disconnect_signals;
171         modest_hildon2_window_class->pack_toolbar_func = modest_folder_window_pack_toolbar;
172 }
173
174 static void
175 modest_folder_window_init (ModestFolderWindow *obj)
176 {
177         ModestFolderWindowPrivate *priv;
178
179         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE(obj);
180
181         priv->sighandlers = NULL;
182         
183         priv->folder_view = NULL;
184
185         priv->top_vbox = NULL;
186
187         modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
188                                             GTK_WINDOW(obj),
189                                             "applications_email_folderview");
190         priv->progress_hint = FALSE;
191         priv->current_store_account = NULL;
192         priv->queue_change_handler = 0;
193 }
194
195 static void
196 modest_folder_window_finalize (GObject *obj)
197 {
198         ModestFolderWindowPrivate *priv;
199
200         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE(obj);
201
202         if (priv->current_store_account) {
203                 g_free (priv->current_store_account);
204                 priv->current_store_account = NULL;
205         }
206
207         /* Sanity check: shouldn't be needed, the window mgr should
208            call this function before */
209         modest_folder_window_disconnect_signals (MODEST_WINDOW (obj));  
210
211         G_OBJECT_CLASS(parent_class)->finalize (obj);
212 }
213
214 static void
215 modest_folder_window_disconnect_signals (ModestWindow *self)
216 {
217         ModestFolderWindowPrivate *priv;
218         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE(self);
219
220         if (g_signal_handler_is_connected (G_OBJECT (modest_runtime_get_mail_operation_queue ()), 
221                                            priv->queue_change_handler))
222                 g_signal_handler_disconnect (G_OBJECT (modest_runtime_get_mail_operation_queue ()), 
223                                              priv->queue_change_handler);
224
225         modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
226         priv->sighandlers = NULL;
227 }
228
229 static void
230 connect_signals (ModestFolderWindow *self)
231 {
232         ModestFolderWindowPrivate *priv;
233
234         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE(self);
235
236         /* folder view */
237         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
238                                                        G_OBJECT (priv->folder_view), "folder-activated",
239                                                        G_CALLBACK (on_folder_activated), self);
240
241         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
242                                                        G_OBJECT (modest_runtime_get_window_mgr ()),
243                                                        "progress-list-changed",
244                                                        G_CALLBACK (on_progress_list_changed), self);
245
246         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
247                                                        G_OBJECT (priv->folder_view),
248                                                        "visible-account-changed",
249                                                        G_CALLBACK (on_visible_account_changed), self);
250
251         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
252                                                        G_OBJECT (priv->folder_view),
253                                                        "activity-changed",
254                                                        G_CALLBACK (on_activity_changed), self);
255
256         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
257                                                        G_OBJECT (priv->new_message_button),
258                                                        "clicked",
259                                                        G_CALLBACK (modest_ui_actions_on_new_msg), self);
260
261         priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
262                                                        G_OBJECT (modest_runtime_get_account_store()),
263                                                        "account-changed",
264                                                        G_CALLBACK (on_account_changed), self);
265 }
266
267 ModestWindow *
268 modest_folder_window_new (TnyFolderStoreQuery *query)
269 {
270         ModestFolderWindow *self = NULL;        
271         ModestFolderWindowPrivate *priv = NULL;
272         HildonProgram *app;
273         GdkPixbuf *window_icon;
274         GtkWidget *pannable;
275         GtkWidget *action_area_box;
276         GdkPixbuf *new_message_pixbuf;
277         guint accel_key;
278         GdkModifierType accel_mods;
279         GtkAccelGroup *accel_group;
280         GtkWidget *top_alignment;
281         
282         self  = MODEST_FOLDER_WINDOW(g_object_new(MODEST_TYPE_FOLDER_WINDOW, NULL));
283         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE(self);
284
285         pannable = hildon_pannable_area_new ();
286
287         priv->queue_change_handler =
288                 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
289                                   "queue-changed",
290                                   G_CALLBACK (on_queue_changed),
291                                   self);
292
293         priv->folder_view  = modest_platform_create_folder_view (query);
294         modest_folder_view_set_cell_style (MODEST_FOLDER_VIEW (priv->folder_view),
295                                            MODEST_FOLDER_VIEW_CELL_STYLE_COMPACT);
296         modest_folder_view_set_filter (MODEST_FOLDER_VIEW (priv->folder_view), 
297                                        MODEST_FOLDER_VIEW_FILTER_HIDE_ACCOUNTS);
298
299         g_signal_connect (G_OBJECT (self), "edit-mode-changed",
300                           G_CALLBACK (edit_mode_changed), (gpointer) self);
301
302         action_area_box = hildon_tree_view_get_action_area_box (GTK_TREE_VIEW (priv->folder_view));
303         priv->new_message_button = hildon_button_new (MODEST_EDITABLE_SIZE, HILDON_BUTTON_ARRANGEMENT_HORIZONTAL);
304
305         hildon_button_set_title (HILDON_BUTTON (priv->new_message_button), _("mcen_ti_new_message"));
306         new_message_pixbuf = modest_platform_get_icon ("general_add", MODEST_ICON_SIZE_BIG);
307         hildon_button_set_image (HILDON_BUTTON (priv->new_message_button), gtk_image_new_from_pixbuf (new_message_pixbuf));
308         g_object_unref (new_message_pixbuf);
309
310         gtk_box_pack_start (GTK_BOX (action_area_box), priv->new_message_button, TRUE, TRUE, 0);
311         gtk_widget_show_all (priv->new_message_button);
312         hildon_tree_view_set_action_area_visible (GTK_TREE_VIEW (priv->folder_view), TRUE);
313         
314         setup_menu (self);
315
316         /* Set account store */
317         tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
318                                                   TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
319
320         priv->top_vbox = gtk_vbox_new (0, FALSE);
321         top_alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
322         gtk_alignment_set_padding (GTK_ALIGNMENT (top_alignment),
323                                    0, 0,
324                                    HILDON_MARGIN_DOUBLE, HILDON_MARGIN_DOUBLE);
325
326         gtk_container_add (GTK_CONTAINER (pannable), priv->folder_view);
327         gtk_container_add (GTK_CONTAINER (top_alignment), pannable);
328         gtk_box_pack_end (GTK_BOX (priv->top_vbox), top_alignment, TRUE, TRUE, 0);
329         gtk_container_add (GTK_CONTAINER (self), priv->top_vbox);
330
331         gtk_widget_show (priv->folder_view);
332         gtk_widget_show (pannable);
333         gtk_widget_show (priv->top_vbox);
334         gtk_widget_show (top_alignment);
335
336         connect_signals (MODEST_FOLDER_WINDOW (self));
337
338         /* Load previous osso state, for instance if we are being restored from 
339          * hibernation:  */
340         modest_osso_load_state ();
341
342         /* Get device name */
343         modest_maemo_utils_get_device_name ();
344
345         app = hildon_program_get_instance ();
346         hildon_program_add_window (app, HILDON_WINDOW (self));
347         
348         /* Set window icon */
349         window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
350         if (window_icon) {
351                 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
352                 g_object_unref (window_icon);
353         }
354
355         /* Dont't restore settings here, 
356          * because it requires a gtk_widget_show(), 
357          * and we don't want to do that until later,
358          * so that the UI is not visible for non-menu D-Bus activation.
359          */
360
361         /* Register edit modes */
362         modest_hildon2_window_register_edit_mode (MODEST_HILDON2_WINDOW (self), 
363                                                   EDIT_MODE_COMMAND_DELETE,
364                                                   _("mcen_ti_edit_folder_delete"), 
365                                                   _HL("wdgt_bd_delete"),
366                                                   GTK_TREE_VIEW (priv->folder_view),
367                                                   GTK_SELECTION_SINGLE,
368                                                   EDIT_MODE_CALLBACK (modest_ui_actions_on_edit_mode_delete_folder));
369         modest_hildon2_window_register_edit_mode (MODEST_HILDON2_WINDOW (self), 
370                                                   EDIT_MODE_COMMAND_MOVE,
371                                                   _("mcen_ti_edit_move_folder"), 
372                                                   _HL("wdgt_bd_move"),
373                                                   GTK_TREE_VIEW (priv->folder_view),
374                                                   GTK_SELECTION_SINGLE,
375                                                   EDIT_MODE_CALLBACK (modest_ui_actions_on_edit_mode_move_to)); 
376         modest_hildon2_window_register_edit_mode (MODEST_HILDON2_WINDOW (self), 
377                                                   EDIT_MODE_COMMAND_RENAME,
378                                                   _("mcen_ti_edit_rename_folder"), 
379                                                   _HL("wdgt_bd_rename"),
380                                                   GTK_TREE_VIEW (priv->folder_view),
381                                                   GTK_SELECTION_SINGLE,
382                                                   EDIT_MODE_CALLBACK (modest_ui_actions_on_edit_mode_rename_folder));
383         
384         g_signal_connect (G_OBJECT (self), "map-event",
385                           G_CALLBACK (on_map_event),
386                           G_OBJECT (self));
387         update_progress_hint (self);
388
389         accel_group = gtk_accel_group_new ();
390         gtk_accelerator_parse ("<Control>n", &accel_key, &accel_mods);
391         gtk_widget_add_accelerator (priv->new_message_button, "clicked", accel_group,
392                                     accel_key, accel_mods, 0);
393         gtk_window_add_accel_group (GTK_WINDOW (self), accel_group);
394
395         return MODEST_WINDOW(self);
396 }
397
398 ModestFolderView *
399 modest_folder_window_get_folder_view (ModestFolderWindow *self)
400 {
401         ModestFolderWindowPrivate *priv = NULL;
402
403         g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW(self), FALSE);
404
405         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
406         
407         return MODEST_FOLDER_VIEW (priv->folder_view);
408 }
409
410 void
411 modest_folder_window_set_account (ModestFolderWindow *self,
412                                   const gchar *account_name)
413 {
414         ModestFolderWindowPrivate *priv = NULL;
415         ModestAccountMgr *mgr;
416         ModestAccountSettings *settings = NULL;
417         ModestServerAccountSettings *store_settings = NULL;
418
419         g_return_if_fail (MODEST_IS_FOLDER_WINDOW(self));
420
421         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
422
423         /* Get account data */
424         mgr = modest_runtime_get_account_mgr ();
425
426         settings = modest_account_mgr_load_account_settings (mgr, account_name);
427         if (!settings)
428                 goto free_refs;
429
430         store_settings = modest_account_settings_get_store_settings (settings);
431         if (!store_settings)
432                 goto free_refs;
433
434         if (priv->current_store_account != NULL)
435                 g_free (priv->current_store_account);
436         priv->current_store_account = g_strdup (modest_server_account_settings_get_account_name (store_settings));
437
438         modest_folder_view_set_account_id_of_visible_server_account
439                 (MODEST_FOLDER_VIEW (priv->folder_view),
440                  priv->current_store_account);
441
442         modest_window_set_active_account (MODEST_WINDOW (self), account_name);
443         update_progress_hint (self);
444
445 free_refs:
446         if (store_settings)
447                 g_object_unref (store_settings);
448         if (settings)
449                 g_object_unref (settings);
450
451 }
452
453 void
454 modest_folder_window_set_mailbox (ModestFolderWindow *self,
455                                   const gchar *mailbox)
456 {
457         ModestFolderWindowPrivate *priv = NULL;
458
459         g_return_if_fail (MODEST_IS_FOLDER_WINDOW(self));
460         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
461
462         modest_folder_view_set_mailbox (MODEST_FOLDER_VIEW (priv->folder_view), mailbox);
463         modest_window_set_active_mailbox (MODEST_WINDOW (self), mailbox);
464 }
465
466 static void
467 edit_account (GtkButton *button,
468               ModestFolderWindow *self)
469 {
470         const gchar *account_name;
471
472         account_name = modest_window_get_active_account ((ModestWindow *) self);
473         if (modest_ui_actions_check_for_active_account ((ModestWindow *) self, account_name)) {
474                 /* Show the account settings dialog */
475                 ModestAccountProtocol *proto;
476                 ModestProtocolType proto_type;
477
478                 /* Get proto */
479                 proto_type = modest_account_mgr_get_store_protocol (modest_runtime_get_account_mgr (),
480                                                                     account_name);
481                 proto = (ModestAccountProtocol *)
482                         modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
483                                                                        proto_type);
484
485                 /* Create and show the dialog */
486                 if (proto && MODEST_IS_ACCOUNT_PROTOCOL (proto)) {
487                         ModestAccountSettingsDialog *dialog =
488                                 modest_account_protocol_get_account_settings_dialog (proto, account_name);
489                         modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
490                                                      (GtkWindow *) dialog,
491                                                      (GtkWindow *) self);
492                         gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), FALSE);
493                         gtk_widget_show (GTK_WIDGET (dialog));
494                 }
495         }
496 }
497
498 static void
499 setup_menu (ModestFolderWindow *self)
500 {
501         g_return_if_fail (MODEST_IS_FOLDER_WINDOW(self));
502
503         /* folders actions */
504         modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_new_folder"), NULL,
505                                            APP_MENU_CALLBACK (modest_ui_actions_on_new_folder),
506                                            NULL);
507         modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_rename_folder"), NULL,
508                                            APP_MENU_CALLBACK (set_rename_edit_mode),
509                                            MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_rename_folder));
510         modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_move_folder"), NULL,
511                                            APP_MENU_CALLBACK (set_moveto_edit_mode),
512                                            MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_folder_window_move_to));
513         modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_delete_folder"), NULL,
514                                            APP_MENU_CALLBACK (set_delete_edit_mode),
515                                            MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_folder_window_delete));
516
517         /* send receive actions should be only one visible always */
518         modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_sendandreceive"), NULL,
519                                            APP_MENU_CALLBACK (modest_ui_actions_on_send_receive),
520                                            MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_send_receive));
521
522         modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_outbox_cancelsend"), NULL,
523                                            APP_MENU_CALLBACK (modest_ui_actions_cancel_send),
524                                            MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_cancel_sending_all));
525
526         modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_edit_account"), NULL,
527                                            APP_MENU_CALLBACK (edit_account),
528                                            MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_edit_accounts));
529 }
530
531 static void
532 on_folder_activated (ModestFolderView *folder_view,
533                      TnyFolder *folder,
534                      gpointer userdata)
535 {
536         ModestFolderWindowPrivate *priv = NULL;
537         ModestWindow *headerwin;
538         ModestFolderWindow *self = (ModestFolderWindow *) userdata;
539
540         g_return_if_fail (MODEST_IS_FOLDER_WINDOW(self));
541
542         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
543
544         if (!folder || !TNY_IS_FOLDER (folder))
545                 return;
546
547         /* We cannot open noselect folders (fake ones) */
548         if (tny_folder_get_caps (folder) & TNY_FOLDER_CAPS_NOSELECT)
549                 return;
550
551         headerwin = modest_header_window_new (folder, 
552                                               modest_window_get_active_account (MODEST_WINDOW (self)),
553                                               modest_window_get_active_mailbox (MODEST_WINDOW (self)));
554
555         if (modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
556                                                MODEST_WINDOW (headerwin),
557                                                MODEST_WINDOW (self))) {
558                 gtk_widget_show (GTK_WIDGET (headerwin));
559         } else {
560                 gtk_widget_destroy (GTK_WIDGET (headerwin));
561                 headerwin = NULL;
562         }
563 }
564
565 static void
566 set_delete_edit_mode (GtkButton *button,
567                       ModestFolderWindow *self)
568 {
569         modest_hildon2_window_set_edit_mode (MODEST_HILDON2_WINDOW (self), EDIT_MODE_COMMAND_DELETE);
570 }
571
572 static void
573 set_moveto_edit_mode (GtkButton *button,
574                       ModestFolderWindow *self)
575 {
576         modest_hildon2_window_set_edit_mode (MODEST_HILDON2_WINDOW (self), EDIT_MODE_COMMAND_MOVE);
577 }
578
579 static void
580 set_rename_edit_mode (GtkButton *button,
581                       ModestFolderWindow *self)
582 {
583         modest_hildon2_window_set_edit_mode (MODEST_HILDON2_WINDOW (self), EDIT_MODE_COMMAND_RENAME);
584 }
585
586 static void
587 modest_folder_window_pack_toolbar (ModestHildon2Window *self,
588                                    GtkPackType pack_type,
589                                    GtkWidget *toolbar)
590 {
591         ModestFolderWindowPrivate *priv;
592
593         g_return_if_fail (MODEST_IS_FOLDER_WINDOW (self));
594         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
595
596         if (pack_type == GTK_PACK_START) {
597                 gtk_box_pack_start (GTK_BOX (priv->top_vbox), toolbar, FALSE, FALSE, 0);
598         } else {
599                 gtk_box_pack_end (GTK_BOX (priv->top_vbox), toolbar, FALSE, FALSE, 0);
600         }
601 }
602
603 static void 
604 edit_mode_changed (ModestFolderWindow *folder_window,
605                    gint edit_mode_id,
606                    gboolean enabled,
607                    ModestFolderWindow *self)
608 {
609         ModestFolderWindowPrivate *priv;
610         ModestFolderViewFilter filter = MODEST_FOLDER_VIEW_FILTER_NONE;
611
612         g_return_if_fail (MODEST_IS_FOLDER_WINDOW (self));
613         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
614
615         switch (edit_mode_id) {
616         case EDIT_MODE_COMMAND_MOVE:
617                 filter = MODEST_FOLDER_VIEW_FILTER_MOVEABLE;
618                 break;
619         case EDIT_MODE_COMMAND_DELETE:
620                 filter = MODEST_FOLDER_VIEW_FILTER_DELETABLE;
621                 break;
622         case EDIT_MODE_COMMAND_RENAME:
623                 filter = MODEST_FOLDER_VIEW_FILTER_RENAMEABLE;
624                 break;
625         case MODEST_HILDON2_WINDOW_EDIT_MODE_NONE:
626                 filter = MODEST_FOLDER_VIEW_FILTER_NONE;
627                 break;
628         }
629
630         hildon_tree_view_set_action_area_visible (GTK_TREE_VIEW (priv->folder_view), !enabled);
631         if (enabled) {
632                 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (priv->folder_view), 
633                                                filter);
634         } else {
635                 GtkTreeSelection *sel;
636
637                 /* Unselect all. This will prevent us from keeping a
638                    reference to a TnyObject that we don't want to
639                    have */
640                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->folder_view));
641                 gtk_tree_selection_unselect_all (sel);
642
643                 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (priv->folder_view), 
644                                                  filter);
645         }
646 }
647
648 static gboolean 
649 on_map_event (GtkWidget *widget,
650               GdkEvent *event,
651               gpointer userdata)
652 {
653         ModestFolderWindow *self = (ModestFolderWindow *) userdata;
654         ModestFolderWindowPrivate *priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
655
656         if (priv->progress_hint) {
657                 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
658         }
659
660         return FALSE;
661 }
662
663 static gboolean
664 has_active_operations (ModestFolderWindow *self)
665 {
666         GSList *operations = NULL, *node;
667         ModestMailOperationQueue *queue;
668         gboolean has_active = FALSE;
669
670         queue = modest_runtime_get_mail_operation_queue ();
671         operations = modest_mail_operation_queue_get_by_source (queue, G_OBJECT (self));
672
673         for (node = operations; node != NULL; node = g_slist_next (node)) {
674                 if (!modest_mail_operation_is_finished (MODEST_MAIL_OPERATION (node->data))) {
675                         has_active = TRUE;
676                         break;
677                 }
678         }
679
680         if (operations) {
681                 g_slist_foreach (operations, (GFunc) g_object_unref, NULL);
682                 g_slist_free (operations);
683         }
684
685         return has_active;
686 }
687
688 static void
689 update_progress_hint (ModestFolderWindow *self)
690 {
691         ModestFolderWindowPrivate *priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
692
693         if (has_active_operations (self)) {
694                 priv->progress_hint = TRUE;
695         } else {
696                 priv->progress_hint = FALSE;
697         }
698
699         if (!priv->progress_hint && priv->current_store_account) {
700                 priv->progress_hint = modest_window_mgr_has_progress_operation_on_account (modest_runtime_get_window_mgr (),
701                                                                                            priv->current_store_account);
702         }
703
704         if (!priv->progress_hint) {
705                 priv->progress_hint = modest_folder_view_get_activity (MODEST_FOLDER_VIEW (priv->folder_view));
706         }
707
708         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
709
710         if (GTK_WIDGET_VISIBLE (self)) {
711                 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), priv->progress_hint ? 1:0);
712         }
713 }
714
715 static void
716 on_progress_list_changed (ModestWindowMgr *mgr,
717                           ModestFolderWindow *self)
718 {
719         update_progress_hint (self);
720 }
721
722 gboolean
723 modest_folder_window_transfer_mode_enabled (ModestFolderWindow *self)
724 {
725         ModestFolderWindowPrivate *priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
726
727         return priv->progress_hint;
728 }
729
730 static void 
731 on_mail_operation_started (ModestMailOperation *mail_op,
732                            gpointer user_data)
733 {
734         ModestFolderWindow *self;
735         ModestMailOperationTypeOperation op_type;
736         GObject *source = NULL;
737
738         self = MODEST_FOLDER_WINDOW (user_data);
739         op_type = modest_mail_operation_get_type_operation (mail_op);
740         source = modest_mail_operation_get_source(mail_op);
741         if (G_OBJECT (self) == source) {
742                 update_progress_hint (self);
743         }
744         g_object_unref (source);
745 }
746
747 static void 
748 on_mail_operation_finished (ModestMailOperation *mail_op,
749                             gpointer user_data)
750 {
751         ModestFolderWindow *self;
752
753         self = MODEST_FOLDER_WINDOW (user_data);
754
755         /* Don't disable the progress hint if there are more pending
756            operations from this window */
757         update_progress_hint (self);
758
759         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
760 }
761
762 static void
763 on_queue_changed (ModestMailOperationQueue *queue,
764                   ModestMailOperation *mail_op,
765                   ModestMailOperationQueueNotification type,
766                   ModestFolderWindow *self)
767 {
768         ModestFolderWindowPrivate *priv;
769
770         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
771
772         /* If this operations was created by another window, do nothing */
773         if (!modest_mail_operation_is_mine (mail_op, G_OBJECT(self))) 
774                 return;
775
776         if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
777                 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
778                                                                G_OBJECT (mail_op),
779                                                                "operation-started",
780                                                                G_CALLBACK (on_mail_operation_started),
781                                                                self);
782                 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
783                                                                G_OBJECT (mail_op),
784                                                                "operation-finished",
785                                                                G_CALLBACK (on_mail_operation_finished),
786                                                                self);
787         } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
788                 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
789                                                                   G_OBJECT (mail_op),
790                                                                   "operation-started");
791                 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
792                                                                   G_OBJECT (mail_op),
793                                                                   "operation-finished");
794         }
795 }
796
797 static void
798 on_activity_changed (ModestFolderView *view,
799                      gboolean activity,
800                      ModestFolderWindow *folder_window)
801 {
802         g_return_if_fail (MODEST_IS_FOLDER_WINDOW (folder_window));
803
804         update_progress_hint (folder_window);
805 }
806
807
808 static void
809 update_window_title (ModestFolderWindow *self,
810                      TnyAccount *account)
811 {
812         if (account) {
813                 const gchar *name;
814                 const gchar *mailbox;
815                 gchar *title = NULL;
816                 ModestFolderWindowPrivate *priv;
817
818                 priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
819
820                 mailbox = modest_folder_view_get_mailbox (MODEST_FOLDER_VIEW (priv->folder_view));
821                 if (mailbox) {
822                         title = g_strdup (mailbox);
823                 } else {
824                         name = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
825                         title = modest_account_mgr_get_display_name (modest_runtime_get_account_mgr(),
826                                                                      name);
827                 }
828                 if (title) {
829                         gtk_window_set_title (GTK_WINDOW (self), title);
830                         g_free (title);
831                 } else {
832                         gtk_window_set_title (GTK_WINDOW (self), _("mcen_ap_name"));
833                 }
834         } else {
835                 gtk_window_set_title (GTK_WINDOW (self), _("mcen_ap_name"));
836         }
837 }
838
839 static void
840 on_visible_account_changed (ModestFolderView *folder_view,
841                             const gchar *account_id,
842                             gpointer user_data)
843 {
844         TnyAccount *account;
845
846         if (!account_id)
847                 return;
848
849         account = modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store(),
850                                                                MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
851                                                                account_id);
852
853         /* Update window title */
854         if (account) {
855                 update_window_title (MODEST_FOLDER_WINDOW (user_data), account);
856                 g_object_unref (account);
857         }
858 }
859
860 static void
861 on_account_changed (TnyAccountStore *account_store,
862                     TnyAccount *account,
863                     gpointer user_data)
864 {
865         const gchar *acc_id, *visible;
866         ModestFolderWindowPrivate *priv;
867
868         if (!TNY_IS_STORE_ACCOUNT (account))
869                 return;
870
871         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (user_data);
872
873         acc_id = tny_account_get_id (account);
874         visible = modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (priv->folder_view));
875
876         /* Update title if the visible account is the one that have just changed */
877         if (acc_id && visible && !g_utf8_collate (acc_id, visible))
878                 update_window_title (MODEST_FOLDER_WINDOW (user_data), account);
879 }