df05c43de4a24112b8de73e7a9ee98dbec995128
[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                                    HILDON_MARGIN_HALF, 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),
527                                            dngettext(GETTEXT_PACKAGE,
528                                                      "mcen_me_edit_account",
529                                                      "mcen_me_edit_accounts",
530                                                      1),
531                                            NULL, APP_MENU_CALLBACK (edit_account),
532                                            MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_edit_accounts));
533 }
534
535 static void
536 on_folder_activated (ModestFolderView *folder_view,
537                      TnyFolder *folder,
538                      gpointer userdata)
539 {
540         ModestFolderWindowPrivate *priv = NULL;
541         ModestWindow *headerwin;
542         ModestFolderWindow *self = (ModestFolderWindow *) userdata;
543
544         g_return_if_fail (MODEST_IS_FOLDER_WINDOW(self));
545
546         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
547
548         if (!folder || !TNY_IS_FOLDER (folder))
549                 return;
550
551         /* We cannot open noselect folders (fake ones) */
552         if (tny_folder_get_caps (folder) & TNY_FOLDER_CAPS_NOSELECT)
553                 return;
554
555         headerwin = modest_header_window_new (folder, 
556                                               modest_window_get_active_account (MODEST_WINDOW (self)),
557                                               modest_window_get_active_mailbox (MODEST_WINDOW (self)));
558
559         if (modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
560                                                MODEST_WINDOW (headerwin),
561                                                MODEST_WINDOW (self))) {
562                 gtk_widget_show (GTK_WIDGET (headerwin));
563         } else {
564                 gtk_widget_destroy (GTK_WIDGET (headerwin));
565                 headerwin = NULL;
566         }
567 }
568
569 static void
570 set_delete_edit_mode (GtkButton *button,
571                       ModestFolderWindow *self)
572 {
573         modest_hildon2_window_set_edit_mode (MODEST_HILDON2_WINDOW (self), EDIT_MODE_COMMAND_DELETE);
574 }
575
576 static void
577 set_moveto_edit_mode (GtkButton *button,
578                       ModestFolderWindow *self)
579 {
580         modest_hildon2_window_set_edit_mode (MODEST_HILDON2_WINDOW (self), EDIT_MODE_COMMAND_MOVE);
581 }
582
583 static void
584 set_rename_edit_mode (GtkButton *button,
585                       ModestFolderWindow *self)
586 {
587         modest_hildon2_window_set_edit_mode (MODEST_HILDON2_WINDOW (self), EDIT_MODE_COMMAND_RENAME);
588 }
589
590 static void
591 modest_folder_window_pack_toolbar (ModestHildon2Window *self,
592                                    GtkPackType pack_type,
593                                    GtkWidget *toolbar)
594 {
595         ModestFolderWindowPrivate *priv;
596
597         g_return_if_fail (MODEST_IS_FOLDER_WINDOW (self));
598         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
599
600         if (pack_type == GTK_PACK_START) {
601                 gtk_box_pack_start (GTK_BOX (priv->top_vbox), toolbar, FALSE, FALSE, 0);
602         } else {
603                 gtk_box_pack_end (GTK_BOX (priv->top_vbox), toolbar, FALSE, FALSE, 0);
604         }
605 }
606
607 static void 
608 edit_mode_changed (ModestFolderWindow *folder_window,
609                    gint edit_mode_id,
610                    gboolean enabled,
611                    ModestFolderWindow *self)
612 {
613         ModestFolderWindowPrivate *priv;
614         ModestFolderViewFilter filter = MODEST_FOLDER_VIEW_FILTER_NONE;
615
616         g_return_if_fail (MODEST_IS_FOLDER_WINDOW (self));
617         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
618
619         switch (edit_mode_id) {
620         case EDIT_MODE_COMMAND_MOVE:
621                 filter = MODEST_FOLDER_VIEW_FILTER_MOVEABLE;
622                 break;
623         case EDIT_MODE_COMMAND_DELETE:
624                 filter = MODEST_FOLDER_VIEW_FILTER_DELETABLE;
625                 break;
626         case EDIT_MODE_COMMAND_RENAME:
627                 filter = MODEST_FOLDER_VIEW_FILTER_RENAMEABLE;
628                 break;
629         case MODEST_HILDON2_WINDOW_EDIT_MODE_NONE:
630                 filter = MODEST_FOLDER_VIEW_FILTER_NONE;
631                 break;
632         }
633
634         hildon_tree_view_set_action_area_visible (GTK_TREE_VIEW (priv->folder_view), !enabled);
635         if (enabled) {
636                 modest_folder_view_set_filter (MODEST_FOLDER_VIEW (priv->folder_view), 
637                                                filter);
638         } else {
639                 GtkTreeSelection *sel;
640
641                 /* Unselect all. This will prevent us from keeping a
642                    reference to a TnyObject that we don't want to
643                    have */
644                 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->folder_view));
645                 gtk_tree_selection_unselect_all (sel);
646
647                 modest_folder_view_unset_filter (MODEST_FOLDER_VIEW (priv->folder_view), 
648                                                  filter);
649         }
650 }
651
652 static gboolean 
653 on_map_event (GtkWidget *widget,
654               GdkEvent *event,
655               gpointer userdata)
656 {
657         ModestFolderWindow *self = (ModestFolderWindow *) userdata;
658         ModestFolderWindowPrivate *priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
659
660         if (priv->progress_hint) {
661                 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
662         }
663
664         return FALSE;
665 }
666
667 static gboolean
668 has_active_operations (ModestFolderWindow *self)
669 {
670         GSList *operations = NULL, *node;
671         ModestMailOperationQueue *queue;
672         gboolean has_active = FALSE;
673
674         queue = modest_runtime_get_mail_operation_queue ();
675         operations = modest_mail_operation_queue_get_by_source (queue, G_OBJECT (self));
676
677         for (node = operations; node != NULL; node = g_slist_next (node)) {
678                 if (!modest_mail_operation_is_finished (MODEST_MAIL_OPERATION (node->data))) {
679                         has_active = TRUE;
680                         break;
681                 }
682         }
683
684         if (operations) {
685                 g_slist_foreach (operations, (GFunc) g_object_unref, NULL);
686                 g_slist_free (operations);
687         }
688
689         return has_active;
690 }
691
692 static void
693 update_progress_hint (ModestFolderWindow *self)
694 {
695         ModestFolderWindowPrivate *priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
696
697         if (has_active_operations (self)) {
698                 priv->progress_hint = TRUE;
699         } else {
700                 priv->progress_hint = FALSE;
701         }
702
703         if (!priv->progress_hint && priv->current_store_account) {
704                 priv->progress_hint = modest_window_mgr_has_progress_operation_on_account (modest_runtime_get_window_mgr (),
705                                                                                            priv->current_store_account);
706         }
707
708         if (!priv->progress_hint) {
709                 priv->progress_hint = modest_folder_view_get_activity (MODEST_FOLDER_VIEW (priv->folder_view));
710         }
711
712         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
713
714         if (GTK_WIDGET_VISIBLE (self)) {
715                 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), priv->progress_hint ? 1:0);
716         }
717 }
718
719 static void
720 on_progress_list_changed (ModestWindowMgr *mgr,
721                           ModestFolderWindow *self)
722 {
723         update_progress_hint (self);
724 }
725
726 gboolean
727 modest_folder_window_transfer_mode_enabled (ModestFolderWindow *self)
728 {
729         ModestFolderWindowPrivate *priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
730
731         return priv->progress_hint;
732 }
733
734 static void 
735 on_mail_operation_started (ModestMailOperation *mail_op,
736                            gpointer user_data)
737 {
738         ModestFolderWindow *self;
739         ModestMailOperationTypeOperation op_type;
740         GObject *source = NULL;
741
742         self = MODEST_FOLDER_WINDOW (user_data);
743         op_type = modest_mail_operation_get_type_operation (mail_op);
744         source = modest_mail_operation_get_source(mail_op);
745         if (G_OBJECT (self) == source) {
746                 update_progress_hint (self);
747         }
748         g_object_unref (source);
749 }
750
751 static void 
752 on_mail_operation_finished (ModestMailOperation *mail_op,
753                             gpointer user_data)
754 {
755         ModestFolderWindow *self;
756
757         self = MODEST_FOLDER_WINDOW (user_data);
758
759         /* Don't disable the progress hint if there are more pending
760            operations from this window */
761         update_progress_hint (self);
762
763         modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
764 }
765
766 static void
767 on_queue_changed (ModestMailOperationQueue *queue,
768                   ModestMailOperation *mail_op,
769                   ModestMailOperationQueueNotification type,
770                   ModestFolderWindow *self)
771 {
772         ModestFolderWindowPrivate *priv;
773
774         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
775
776         /* If this operations was created by another window, do nothing */
777         if (!modest_mail_operation_is_mine (mail_op, G_OBJECT(self))) 
778                 return;
779
780         if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
781                 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
782                                                                G_OBJECT (mail_op),
783                                                                "operation-started",
784                                                                G_CALLBACK (on_mail_operation_started),
785                                                                self);
786                 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
787                                                                G_OBJECT (mail_op),
788                                                                "operation-finished",
789                                                                G_CALLBACK (on_mail_operation_finished),
790                                                                self);
791         } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
792                 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
793                                                                   G_OBJECT (mail_op),
794                                                                   "operation-started");
795                 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
796                                                                   G_OBJECT (mail_op),
797                                                                   "operation-finished");
798         }
799 }
800
801 static void
802 on_activity_changed (ModestFolderView *view,
803                      gboolean activity,
804                      ModestFolderWindow *folder_window)
805 {
806         g_return_if_fail (MODEST_IS_FOLDER_WINDOW (folder_window));
807
808         update_progress_hint (folder_window);
809 }
810
811
812 static void
813 update_window_title (ModestFolderWindow *self,
814                      TnyAccount *account)
815 {
816         if (account) {
817                 const gchar *name;
818                 const gchar *mailbox;
819                 gchar *title = NULL;
820                 ModestFolderWindowPrivate *priv;
821
822                 priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (self);
823
824                 mailbox = modest_folder_view_get_mailbox (MODEST_FOLDER_VIEW (priv->folder_view));
825                 if (mailbox) {
826                         title = g_strdup (mailbox);
827                 } else {
828                         name = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
829                         title = modest_account_mgr_get_display_name (modest_runtime_get_account_mgr(),
830                                                                      name);
831                 }
832                 if (title) {
833                         gtk_window_set_title (GTK_WINDOW (self), title);
834                         g_free (title);
835                 } else {
836                         gtk_window_set_title (GTK_WINDOW (self), _("mcen_ap_name"));
837                 }
838         } else {
839                 gtk_window_set_title (GTK_WINDOW (self), _("mcen_ap_name"));
840         }
841 }
842
843 static void
844 on_visible_account_changed (ModestFolderView *folder_view,
845                             const gchar *account_id,
846                             gpointer user_data)
847 {
848         TnyAccount *account;
849
850         if (!account_id)
851                 return;
852
853         account = modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store(),
854                                                                MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
855                                                                account_id);
856
857         /* Update window title */
858         if (account) {
859                 update_window_title (MODEST_FOLDER_WINDOW (user_data), account);
860                 g_object_unref (account);
861         }
862 }
863
864 static void
865 on_account_changed (TnyAccountStore *account_store,
866                     TnyAccount *account,
867                     gpointer user_data)
868 {
869         const gchar *acc_id, *visible;
870         ModestFolderWindowPrivate *priv;
871
872         if (!TNY_IS_STORE_ACCOUNT (account))
873                 return;
874
875         priv = MODEST_FOLDER_WINDOW_GET_PRIVATE (user_data);
876
877         acc_id = tny_account_get_id (account);
878         visible = modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (priv->folder_view));
879
880         /* Update title if the visible account is the one that have just changed */
881         if (acc_id && visible && !g_utf8_collate (acc_id, visible))
882                 update_window_title (MODEST_FOLDER_WINDOW (user_data), account);
883 }