* Fixed some bug in new dimming rules approach.
[modest] / src / modest-ui-dimming-rules.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 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif /*HAVE_CONFIG_H*/
33
34 #include <string.h>
35 #include "modest-ui-dimming-rules.h"
36 #include "modest-dimming-rule.h"
37 #include "modest-tny-folder.h"
38 #include "modest-tny-account.h"
39 #include "modest-text-utils.h"
40 #include <widgets/modest-attachments-view.h>
41 #include <modest-runtime.h>
42 #include <tny-simple-list.h>
43
44
45 static gboolean _folder_is_any_of_type (TnyFolder *folder, TnyFolderType types[], guint ntypes);
46 static gboolean _invalid_msg_selected (ModestMainWindow *win, gboolean unique, ModestDimmingRule *rule);
47 static gboolean _invalid_attach_selected (ModestWindow *win, 
48                                           gboolean unique, gboolean for_view, gboolean for_remove,
49                                           ModestDimmingRule *rule);
50 static gboolean _purged_attach_selected (ModestWindow *win, gboolean all, ModestDimmingRule *rule);
51 static gboolean _clipboard_is_empty (ModestWindow *win);
52 static gboolean _invalid_clipboard_selected (ModestWindow *win, ModestDimmingRule *rule);
53 /* static gboolean _already_opened_msg (ModestWindow *win, guint *n_messages); */
54 /* static gboolean _selected_msg_marked_as (ModestMainWindow *win, TnyHeaderFlags mask, gboolean opposite, gboolean all); */
55 static gboolean _selected_folder_not_writeable (ModestMainWindow *win);
56 static gboolean _selected_folder_is_snd_level (ModestMainWindow *win);
57 static gboolean _selected_folder_is_any_of_type (ModestWindow *win, TnyFolderType types[], guint ntypes);
58 static gboolean _selected_folder_is_root_or_inbox (ModestMainWindow *win);
59 static gboolean _selected_folder_is_MMC_or_POP_root (ModestMainWindow *win);
60 static gboolean _selected_folder_is_root (ModestMainWindow *win);
61 static gboolean _selected_folder_is_empty (ModestMainWindow *win);
62 static gboolean _selected_folder_is_same_as_source (ModestWindow *win);
63 static gboolean _msg_download_in_progress (ModestMsgViewWindow *win);
64 static gboolean _msg_download_completed (ModestMainWindow *win);
65 static gboolean _selected_msg_sent_in_progress (ModestWindow *win);
66 static gboolean _sending_in_progress (ModestWindow *win);
67 /* static gboolean _message_is_marked_as_deleted (ModestMsgViewWindow *win); */
68 /* static gboolean _selected_message_is_marked_as_deleted (ModestMainWindow *win); */
69 static gboolean _invalid_folder_for_purge (ModestWindow *win, ModestDimmingRule *rule);
70 static gboolean _transfer_mode_enabled (ModestWindow *win);
71
72 static void  fill_list_of_caches (gpointer key, gpointer value, gpointer userdata);
73
74
75 static DimmedState *
76 _define_main_window_dimming_state (ModestMainWindow *window)
77 {
78         DimmedState *state = NULL;
79         GtkWidget *header_view = NULL;
80         TnyList *selected_headers = NULL;
81         TnyIterator *iter = NULL;
82         TnyHeader *header = NULL;
83         ModestCacheMgr *cache_mgr = NULL;
84         GHashTable *send_queue_cache = NULL;
85         ModestTnySendQueue *send_queue = NULL;
86         GSList *send_queues = NULL, *node = NULL;
87         ModestWindowMgr *mgr = NULL;
88         gboolean found = FALSE;
89         gchar *msg_uid = NULL;
90         TnyHeaderFlags flags;
91         gboolean all_deleted = TRUE;
92         gboolean all_seen = TRUE;
93         gboolean all_cached = TRUE;
94         gboolean all_has_attach = TRUE;
95
96         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(window), NULL);
97
98         /* Init state */
99         state = g_slice_new0 (DimmedState);
100         state->n_selected = 0;
101         state->already_opened_msg = FALSE;
102         state->any_marked_as_deleted = FALSE;
103         state->all_marked_as_deleted = FALSE;
104         state->any_marked_as_seen = FALSE;
105         state->all_marked_as_seen = FALSE;
106         state->any_marked_as_cached = FALSE;
107         state->all_marked_as_cached = FALSE;
108         state->any_has_attachments = FALSE;
109         state->all_has_attachments = FALSE;
110         state->sent_in_progress = FALSE;
111
112         /* Get header view and selected headers */
113         header_view = modest_main_window_get_child_widget (window, MODEST_WIDGET_TYPE_HEADER_VIEW);
114         selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
115         if (!selected_headers) 
116                 return state;
117
118         /* Examine selected headers */
119         iter = tny_list_create_iterator (selected_headers);
120         while (!tny_iterator_is_done (iter)) {
121                 header = TNY_HEADER (tny_iterator_get_current (iter));
122                 flags = tny_header_get_flags (header);
123                 
124                 /* No selected */
125                 state->n_selected++;
126                 
127                 /* Already opened */
128                 mgr = modest_runtime_get_window_mgr ();
129                 if (!state->already_opened_msg)
130                         state->already_opened_msg = modest_window_mgr_find_registered_header (mgr, header, NULL);
131                 
132
133                 /* Mark as deleted */           
134                 all_deleted = all_deleted && (flags & TNY_HEADER_FLAG_DELETED);
135                 state->all_marked_as_deleted = all_deleted;
136                 if (!state->any_marked_as_deleted)
137                         state->any_marked_as_deleted = flags & TNY_HEADER_FLAG_DELETED;
138                 
139                 /* Mark as seen */
140                 all_seen = all_seen && (flags & TNY_HEADER_FLAG_SEEN);
141                 state->all_marked_as_seen = all_seen;
142                 if (!state->any_marked_as_seen)
143                         state->any_marked_as_seen = flags & TNY_HEADER_FLAG_SEEN;
144                 
145                 /* Mark as cached */
146                 all_cached = all_cached && (flags & TNY_HEADER_FLAG_CACHED);
147                 state->all_marked_as_cached = all_cached;
148                 if (!state->any_marked_as_cached)
149                         state->any_marked_as_cached = flags & TNY_HEADER_FLAG_CACHED;
150                 
151                 /* Mark has_attachments */
152                 all_has_attach = all_has_attach && (flags & TNY_HEADER_FLAG_ATTACHMENTS);
153                 state->all_has_attachments = all_has_attach;
154                 if (!state->any_has_attachments)
155                         state->any_has_attachments = flags & TNY_HEADER_FLAG_ATTACHMENTS;
156         
157                 /* sent in progress */
158                 msg_uid = modest_tny_send_queue_get_msg_id (header);
159                 if (!state->sent_in_progress) {
160                         cache_mgr = modest_runtime_get_cache_mgr ();
161                         send_queue_cache = modest_cache_mgr_get_cache (cache_mgr,
162                                                                        MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE);
163                         
164                         g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues);
165                         
166                         for (node = send_queues; node != NULL && !found; node = g_slist_next (node)) {
167                                 send_queue = MODEST_TNY_SEND_QUEUE (node->data);
168                                 
169                                 /* Check if msg uid is being processed inside send queue */
170                                 found = modest_tny_send_queue_msg_is_being_sent (send_queue, msg_uid);          
171                         }
172                         state->sent_in_progress = found;
173                 }
174
175                 tny_iterator_next (iter);
176                 g_object_unref (header);
177         }
178
179         /* Free */
180         g_free(msg_uid);
181         g_object_unref(selected_headers);
182         g_object_unref(iter);
183         g_slist_free (send_queues);
184         
185         return state;
186 }
187
188 static DimmedState *
189 _define_msg_view_window_dimming_state (ModestMsgViewWindow *window)
190 {
191         DimmedState *state = NULL;
192         TnyHeader *header = NULL;
193         ModestCacheMgr *cache_mgr = NULL;
194         GHashTable *send_queue_cache = NULL;
195         ModestTnySendQueue *send_queue = NULL;
196         GSList *send_queues = NULL, *node = NULL;
197         gboolean found = FALSE;
198         gchar *msg_uid = NULL;
199         TnyHeaderFlags flags;
200         gboolean all_deleted = TRUE;
201         gboolean all_seen = TRUE;
202         gboolean all_cached = TRUE;
203         gboolean all_has_attach = TRUE;
204                         
205         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(window), NULL);
206
207         /* Init state */
208         state = g_slice_new0 (DimmedState);
209         state->n_selected = 0;
210         state->already_opened_msg = FALSE;
211         state->any_marked_as_deleted = FALSE;
212         state->all_marked_as_deleted = FALSE;
213         state->any_marked_as_seen = FALSE;
214         state->all_marked_as_seen = FALSE;
215         state->any_marked_as_cached = FALSE;
216         state->all_marked_as_cached = FALSE;
217         state->any_has_attachments = FALSE;
218         state->all_has_attachments = FALSE;
219         state->sent_in_progress = FALSE;
220
221         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(window));
222         g_return_val_if_fail (TNY_IS_HEADER(header), state);
223         flags = tny_header_get_flags (header);
224
225         /* Selected */
226         state->n_selected++;
227
228         /* Mark as deleted */           
229         all_deleted = all_deleted && (flags & TNY_HEADER_FLAG_DELETED);
230         state->all_marked_as_deleted = all_deleted;
231         if (!state->any_marked_as_deleted)
232                 state->any_marked_as_deleted = flags & TNY_HEADER_FLAG_DELETED;
233         
234         /* Mark as seen */
235         all_seen = all_seen && (flags & TNY_HEADER_FLAG_SEEN);
236         state->all_marked_as_seen = all_seen;
237         if (!state->any_marked_as_seen)
238                 state->any_marked_as_seen = flags & TNY_HEADER_FLAG_SEEN;
239         
240         /* Mark as cached */
241         all_cached = all_cached && (flags & TNY_HEADER_FLAG_CACHED);
242         state->all_marked_as_cached = all_cached;
243         if (!state->any_marked_as_cached)
244                 state->any_marked_as_cached = flags & TNY_HEADER_FLAG_CACHED;
245         
246         /* Mark has_attachments */
247         all_has_attach = all_has_attach && (flags & TNY_HEADER_FLAG_ATTACHMENTS);
248         state->all_has_attachments = all_has_attach;
249         if (!state->any_has_attachments)
250                 state->any_has_attachments = flags & TNY_HEADER_FLAG_ATTACHMENTS;
251         
252         /* sent in progress */
253         msg_uid = modest_tny_send_queue_get_msg_id (header);
254         if (!state->sent_in_progress) {
255                 cache_mgr = modest_runtime_get_cache_mgr ();
256                 send_queue_cache = modest_cache_mgr_get_cache (cache_mgr,
257                                                                MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE);
258                 
259                 g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues);
260                 
261                 for (node = send_queues; node != NULL && !found; node = g_slist_next (node)) {
262                         send_queue = MODEST_TNY_SEND_QUEUE (node->data);
263                         
264                         /* Check if msg uid is being processed inside send queue */
265                         found = modest_tny_send_queue_msg_is_being_sent (send_queue, msg_uid);          
266                 }
267                 state->sent_in_progress = found;
268         }
269         
270         /* Free */
271         g_free(msg_uid);
272         g_object_unref (header);
273         g_slist_free (send_queues);
274
275         return state;
276 }
277
278    
279 DimmedState *
280 modest_ui_dimming_rules_define_dimming_state (ModestWindow *window)
281 {
282         DimmedState *state = NULL;
283
284         g_return_val_if_fail (MODEST_IS_WINDOW(window), NULL);
285         
286         if (MODEST_IS_MAIN_WINDOW (window)) 
287                 state = _define_main_window_dimming_state (MODEST_MAIN_WINDOW(window));
288         else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
289                 state = _define_msg_view_window_dimming_state (MODEST_MSG_VIEW_WINDOW(window));         
290         }
291         
292         return state;
293 }
294
295
296 gboolean 
297 modest_ui_dimming_rules_on_new_msg (ModestWindow *win, gpointer user_data)
298 {
299         ModestDimmingRule *rule = NULL;
300         gboolean dimmed = FALSE;
301
302         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
303         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
304         rule = MODEST_DIMMING_RULE (user_data);
305                 
306         /* Check dimmed rule */ 
307         if (!dimmed) {
308                 if (MODEST_IS_MSG_VIEW_WINDOW (win))
309                         dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
310                 if (dimmed)
311                         modest_dimming_rule_set_notification (rule, "");
312         }
313
314         return dimmed;
315 }
316
317 gboolean 
318 modest_ui_dimming_rules_on_csm_new_folder (ModestWindow *win, gpointer user_data)
319 {
320         ModestDimmingRule *rule = NULL;
321         gboolean dimmed = FALSE;
322
323         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
324         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
325         rule = MODEST_DIMMING_RULE (user_data);
326
327         /* Check common new folder menu item dimming rules */   
328         dimmed = modest_ui_dimming_rules_on_new_folder (win, user_data);
329         
330         /* Check CSM specific dimming rules */
331         if (!dimmed) {
332                 dimmed = _selected_folder_is_snd_level (MODEST_MAIN_WINDOW(win));
333                 if (dimmed)
334                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_create_error"));
335         }
336         
337         return dimmed;
338 }
339
340 gboolean 
341 modest_ui_dimming_rules_on_new_folder (ModestWindow *win, gpointer user_data)
342 {
343         ModestDimmingRule *rule = NULL;
344         GtkWidget *folder_view = NULL;
345         TnyFolderStore *parent_folder = NULL;
346         gboolean dimmed = FALSE;
347
348         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
349         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
350         rule = MODEST_DIMMING_RULE (user_data);
351
352         /* Get selected folder as parent of new folder to create */
353         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
354                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
355         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
356         if (!parent_folder)
357                 return TRUE;
358         
359         if (TNY_IS_ACCOUNT (parent_folder)) {
360                 /* If it's the local account then do not dim */
361                 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent_folder))) {
362                         dimmed = FALSE;
363                 } else {
364                         const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (parent_folder));
365                         /* If it's POP then dim */
366                         dimmed = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
367                                   MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
368                         if (dimmed)
369                                 modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_create_error"));
370                 }
371         } else {
372                 /* TODO: the specs say that only one level of subfolder is allowed, is this true ? */
373                 
374                 TnyFolderType types[3];
375                                 
376                 types[0] = TNY_FOLDER_TYPE_DRAFTS; 
377                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
378                 types[2] = TNY_FOLDER_TYPE_SENT;
379
380                 /* Apply folder rules */        
381                 if (!dimmed) {
382                         dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
383                         if (dimmed)
384                                 modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_create_error"));
385                 }
386                 if (!dimmed) {
387                         dimmed = _selected_folder_is_any_of_type (win, types, 3);
388                         if (dimmed)
389                                 modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_create_error"));
390                 }
391         }
392         g_object_unref (parent_folder);
393
394         return dimmed;
395 }
396
397 gboolean 
398 modest_ui_dimming_rules_on_delete (ModestWindow *win, gpointer user_data)
399 {
400         ModestDimmingRule *rule = NULL;
401         GtkWidget *folder_view = NULL;
402         GtkWidget *header_view = NULL;  
403         gboolean dimmed = FALSE;
404
405         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
406         rule = MODEST_DIMMING_RULE (user_data);
407         
408         if (MODEST_IS_MAIN_WINDOW (win)) {
409                 /* Get the folder view */
410                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
411                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
412                 
413                 /* Get header view */
414                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
415                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
416
417                 if (header_view && gtk_widget_is_focus (header_view)) 
418                         dimmed = modest_ui_dimming_rules_on_delete_msg (win, rule);
419
420                 if (folder_view && gtk_widget_is_focus (folder_view)) 
421                         dimmed = modest_ui_dimming_rules_on_delete_folder (win, rule);
422
423                 if (header_view && folder_view &&
424                     !gtk_widget_is_focus (header_view) &&
425                     !gtk_widget_is_focus (folder_view)) {
426                         dimmed = TRUE;
427                         modest_dimming_rule_set_notification (rule, dgettext("hildon-common-strings", "ckct_ib_nothing_to_delete"));                    
428                 }
429         } else {
430                 dimmed = modest_ui_dimming_rules_on_delete_folder (win, rule);
431         }
432
433         return dimmed;
434 }
435
436
437
438 gboolean 
439 modest_ui_dimming_rules_on_delete_folder (ModestWindow *win, gpointer user_data)
440 {
441         ModestDimmingRule *rule = NULL;
442         TnyFolderType types[6];
443         gboolean dimmed = FALSE;
444
445         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
446         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
447         rule = MODEST_DIMMING_RULE (user_data);
448
449         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
450         types[1] = TNY_FOLDER_TYPE_OUTBOX;
451         types[2] = TNY_FOLDER_TYPE_SENT;
452         types[3] = TNY_FOLDER_TYPE_INBOX;
453         types[4] = TNY_FOLDER_TYPE_ROOT;
454         types[5] = TNY_FOLDER_TYPE_ARCHIVE;
455
456                 
457         /* Check dimmed rule */ 
458         if (!dimmed) {
459                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
460                 if (dimmed)
461                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_delete_error"));
462         }
463         if (!dimmed) {
464                 dimmed = _selected_folder_is_any_of_type (win, types, 6);
465                 if (dimmed)
466                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_delete_error"));
467         }
468         if (!dimmed) {
469                 dimmed = _selected_folder_is_root_or_inbox (MODEST_MAIN_WINDOW(win));
470                 if (dimmed)
471                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_delete_error"));
472         }
473         if (!dimmed) {
474                 dimmed = _selected_folder_is_MMC_or_POP_root (MODEST_MAIN_WINDOW(win));
475                 if (dimmed)
476                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_delete_error"));
477         }
478
479         return dimmed;
480 }
481
482 gboolean
483 modest_ui_dimming_rules_on_sort (ModestWindow *win, gpointer user_data)
484 {
485         ModestDimmingRule *rule = NULL;
486         gboolean dimmed = FALSE;
487
488         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
489         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
490         rule = MODEST_DIMMING_RULE (user_data);
491                 
492         /* Check dimmed rule */ 
493         if (!dimmed) {
494                 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
495                 modest_dimming_rule_set_notification (rule, _CS("ckdg_ib_nothing_to_sort"));
496         }
497
498         if (!dimmed) {
499                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));
500                 modest_dimming_rule_set_notification (rule, _CS("ckdg_ib_nothing_to_sort"));
501         }
502
503         return dimmed;
504         
505 }
506
507 gboolean 
508 modest_ui_dimming_rules_on_rename_folder (ModestWindow *win, gpointer user_data)
509 {
510         ModestDimmingRule *rule = NULL;
511         TnyFolderType types[4];
512         gboolean dimmed = FALSE;
513
514         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
515         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
516         rule = MODEST_DIMMING_RULE (user_data);
517
518         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
519         types[1] = TNY_FOLDER_TYPE_OUTBOX;
520         types[2] = TNY_FOLDER_TYPE_SENT;
521         types[3] = TNY_FOLDER_TYPE_ARCHIVE;
522         
523         /* Check dimmed rule */ 
524         if (!dimmed) {
525                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
526                 if (dimmed)
527                         modest_dimming_rule_set_notification (rule, "");
528         }
529         if (!dimmed) {
530                 dimmed = _selected_folder_is_root_or_inbox (MODEST_MAIN_WINDOW(win));
531                 if (dimmed)
532                         modest_dimming_rule_set_notification (rule, "");
533         }
534         if (!dimmed) {
535                 dimmed = _selected_folder_is_any_of_type (win, types, 4);
536                 if (dimmed)
537                         modest_dimming_rule_set_notification (rule, "");
538         }
539
540         return dimmed;
541 }
542
543 gboolean 
544 modest_ui_dimming_rules_on_open_msg (ModestWindow *win, gpointer user_data)
545 {
546         ModestDimmingRule *rule = NULL;
547         gboolean dimmed = FALSE;
548         const DimmedState *state = NULL;
549
550         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
551         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
552         rule = MODEST_DIMMING_RULE (user_data);
553         state = modest_window_get_dimming_state (win);          
554
555         /* Check dimmed rule */ 
556         if (!dimmed) {
557                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data);
558         }
559         if (!dimmed) {
560                 dimmed = state->any_marked_as_deleted;
561                 if (dimmed)
562                         modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted"));
563         }
564         if (!dimmed) {
565                 dimmed = _selected_msg_sent_in_progress (win);
566                 if (dimmed)
567                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_open_while_sent"));
568         }
569
570         return dimmed;
571 }
572
573 gboolean 
574 modest_ui_dimming_rules_on_reply_msg (ModestWindow *win, gpointer user_data)
575 {
576         ModestDimmingRule *rule = NULL;
577         gboolean dimmed = FALSE;
578         TnyFolderType types[3];
579
580         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
581         rule = MODEST_DIMMING_RULE (user_data);
582
583         /* main window dimming rules */
584         if (MODEST_IS_MAIN_WINDOW(win)) {
585                 
586                 types[0] = TNY_FOLDER_TYPE_DRAFTS; 
587                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
588                 types[2] = TNY_FOLDER_TYPE_ROOT;
589                 
590                 /* Check dimmed rule */ 
591                 if (!dimmed) {
592                         dimmed = _selected_folder_is_any_of_type (win, types, 3);                       
593                         if (dimmed)
594                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_reply"));
595                 }
596                 if (!dimmed) {
597                         dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
598                         if (dimmed)
599                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_nothing_to_reply"));
600                 }
601                 if (!dimmed) {
602                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, rule);
603                 }
604         /* msg view window dimming rules */
605         } else if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
606                 
607                 /* Check dimmed rule */ 
608                 if (!dimmed) {
609                         dimmed = _transfer_mode_enabled (win);                  
610                         if (dimmed)
611                                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
612                 }
613                 if (!dimmed) {
614                         if (MODEST_IS_MSG_VIEW_WINDOW (win))
615                                 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW (win));
616                         if (dimmed)
617                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_reply"));
618                 }
619         }
620         
621         return dimmed;
622 }
623
624
625 gboolean 
626 modest_ui_dimming_rules_on_contents_msg (ModestWindow *win, gpointer user_data)
627 {
628         ModestDimmingRule *rule = NULL;
629         gboolean dimmed = FALSE;
630
631         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
632         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
633         rule = MODEST_DIMMING_RULE (user_data);
634                 
635         /* Check dimmed rule */ 
636         if (!dimmed) {
637                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
638         }
639         if (!dimmed) {
640                 dimmed = _msg_download_completed (MODEST_MAIN_WINDOW(win));
641                 if (dimmed)
642                         modest_dimming_rule_set_notification (rule, "");
643         }
644
645         return dimmed;
646 }
647
648 gboolean 
649 modest_ui_dimming_rules_always_dimmed (ModestWindow *win, gpointer user_data)
650 {
651         gboolean dimmed = FALSE;
652
653         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
654                 
655         /* Check dimmed rule */ 
656         if (!dimmed)
657                 dimmed = TRUE;
658
659         return dimmed;
660 }
661
662 gboolean 
663 modest_ui_dimming_rules_on_delete_msg (ModestWindow *win, gpointer user_data)
664 {
665         ModestDimmingRule *rule = NULL;
666         guint n_messages = 0;
667         const DimmedState *state = NULL;
668         gboolean dimmed = FALSE;
669
670         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
671         rule = MODEST_DIMMING_RULE (user_data);
672         state = modest_window_get_dimming_state (win);          
673         
674         /* Check dimmed rule */         
675         if (MODEST_IS_MAIN_WINDOW (win)) {
676                 if (!dimmed) {
677                         dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
678                         if (dimmed)
679                                 modest_dimming_rule_set_notification (rule, _CS("ckct_ib_nothing_to_delete"));
680                 }
681                 if (!dimmed) {
682                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
683                 }
684                 if (!dimmed) {
685                         dimmed = state->already_opened_msg;
686                         n_messages = state->n_selected;
687                         if (dimmed) {
688                                 gchar *num = g_strdup_printf ("%d", n_messages);
689                                 gchar *message = g_strdup_printf(_("mcen_nc_unable_to_delete_n_messages"), num);
690                                 modest_dimming_rule_set_notification (rule, message);
691                                 g_free(message);
692                                 g_free(num);
693                         }
694                         
695                 }
696                 if (!dimmed) {
697                         dimmed = state->any_marked_as_deleted;
698                         if (dimmed) {
699                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted"));
700                         }
701                 }
702                 if (!dimmed) {
703                         dimmed = state->sent_in_progress;
704                         if (dimmed)
705                                 modest_dimming_rule_set_notification (rule, _CS("ckct_ib_unable_to_delete"));
706                 }
707         } 
708         else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
709                 if (!dimmed) {
710                         dimmed = _transfer_mode_enabled (win);                  
711                         if (dimmed)
712                                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
713                 }
714                 if (!dimmed) {
715                         dimmed = state->any_marked_as_deleted;
716                         if (dimmed)
717                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted"));
718                 }
719                 
720                 /* Commented out, because deletion should be possible even when 
721                  * the message window has no header view model, which will be the 
722                  * case when it is not the selected message in the header view.
723                  */
724                 
725                 if (!dimmed) {
726                         dimmed = !modest_msg_view_window_has_headers_model (MODEST_MSG_VIEW_WINDOW(win));
727                         if (dimmed) {
728                                 modest_dimming_rule_set_notification (rule, _CS("ckct_ib_unable_to_delete"));
729                         }
730                 }
731         }
732
733         return dimmed;
734 }
735
736 gboolean 
737 modest_ui_dimming_rules_on_details (ModestWindow *win, gpointer user_data)
738 {
739         ModestDimmingRule *rule = NULL;
740         GtkWidget *header_view = NULL;
741         gboolean dimmed = FALSE;
742
743         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
744         rule = MODEST_DIMMING_RULE (user_data);
745         
746         /* main window dimming rules */
747         if (MODEST_IS_MAIN_WINDOW(win)) {
748                                 
749                 /* Check dimmed rule */
750                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
751                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
752                 
753                 /* If the header view has the focus: */
754                 if (header_view && gtk_widget_is_focus (header_view)) {
755                         /* Check dimmed rule */ 
756                         if (!dimmed)
757                                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data);
758                 }
759                 else {
760                         /* If the folder view has the focus: */
761                         GtkWidget *folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
762                                 MODEST_WIDGET_TYPE_FOLDER_VIEW);
763                         if (folder_view && gtk_widget_is_focus (folder_view)) {
764                                 TnyFolderStore *folder_store
765                                         = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
766                                 if (folder_store) {
767                                         /* Only enable for folders, not accounts,
768                                          * though the UI spec is not clear about that.
769                                          * If we enable this for accounts then we must 
770                                          * add code to handle them in modest_ui_actions_on_details(). */
771                                         if (!TNY_IS_FOLDER(folder_store)) {
772                                                 dimmed = TRUE;
773                                                 modest_dimming_rule_set_notification (rule, "");
774                                         }
775
776                                         g_object_unref (folder_store);
777                                 }
778                         }
779
780                 }
781
782         /* msg view window dimming rules */
783         } else {
784
785                 /* Check dimmed rule */ 
786                 if (!dimmed) {
787                         if (MODEST_IS_MSG_VIEW_WINDOW (win))
788                                 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW (win));
789                         if (dimmed)
790                                 modest_dimming_rule_set_notification (rule, "");
791                 }
792         }
793
794         return dimmed;
795 }
796
797
798 gboolean 
799 modest_ui_dimming_rules_on_mark_as_read_msg (ModestWindow *win, gpointer user_data)
800 {
801         ModestDimmingRule *rule = NULL;
802         TnyHeaderFlags flags;
803         const DimmedState *state = NULL;
804         gboolean dimmed = FALSE;
805
806         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
807         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
808         rule = MODEST_DIMMING_RULE (user_data);
809         state = modest_window_get_dimming_state (win);          
810         
811         flags = TNY_HEADER_FLAG_SEEN; 
812
813         /* Check dimmed rule */ 
814         if (!dimmed) {
815                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
816         }
817         if (!dimmed) {
818                 dimmed = state->all_marked_as_seen;
819                 if (dimmed)
820                         modest_dimming_rule_set_notification (rule, "");
821         }       
822
823         return dimmed;
824 }
825
826 gboolean 
827 modest_ui_dimming_rules_on_mark_as_unread_msg (ModestWindow *win, gpointer user_data)
828 {
829         ModestDimmingRule *rule = NULL;
830         TnyHeaderFlags flags;
831         const DimmedState *state = NULL;
832         gboolean dimmed = FALSE;
833
834         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
835         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
836         rule = MODEST_DIMMING_RULE (user_data);
837         state = modest_window_get_dimming_state (win);          
838         
839         flags = TNY_HEADER_FLAG_SEEN; 
840
841         /* Check dimmed rule */ 
842         if (!dimmed)
843                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
844         if (!dimmed) {
845                 dimmed = !state->any_marked_as_seen;
846                 if (dimmed)
847                         modest_dimming_rule_set_notification (rule, "");
848         }
849
850         return dimmed;
851 }
852
853 gboolean 
854 modest_ui_dimming_rules_on_move_to (ModestWindow *win, gpointer user_data)
855 {
856         ModestDimmingRule *rule = NULL;
857         gboolean dimmed = FALSE;
858
859         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
860         rule = MODEST_DIMMING_RULE (user_data);
861
862         if (MODEST_IS_MAIN_WINDOW (win)) 
863                 dimmed = modest_ui_dimming_rules_on_main_window_move_to (win, user_data);
864         else if (MODEST_IS_MSG_VIEW_WINDOW (win)) 
865                  dimmed = modest_ui_dimming_rules_on_view_window_move_to (win, user_data);
866
867         return dimmed;
868 }
869
870
871 gboolean 
872 modest_ui_dimming_rules_on_main_window_move_to (ModestWindow *win, gpointer user_data)
873 {
874         GtkWidget *folder_view = NULL;
875         ModestDimmingRule *rule = NULL;
876         guint n_messages = 0;
877         const DimmedState *state = NULL;
878         gboolean dimmed = FALSE;
879         
880         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
881         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
882         rule = MODEST_DIMMING_RULE (user_data);
883         state = modest_window_get_dimming_state (win);          
884         
885         /* Get the folder view */
886         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
887                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
888
889         
890         /* Check diming rules for folders transfer  */
891         if (gtk_widget_is_focus (folder_view)) {
892                 TnyFolderType types[5];
893                 
894                 types[0] = TNY_FOLDER_TYPE_DRAFTS; 
895                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
896                 types[2] = TNY_FOLDER_TYPE_SENT;
897                 types[3] = TNY_FOLDER_TYPE_ROOT; 
898                 types[4] = TNY_FOLDER_TYPE_INBOX; 
899                 
900                 /* Apply folder rules */        
901                 if (!dimmed) {
902                         dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
903                         if (dimmed)
904                                 modest_dimming_rule_set_notification (rule, _("emev_bd_unabletomove_items"));
905                 }
906                 if (!dimmed) {
907                         dimmed = _selected_folder_is_any_of_type (win, types, 5);
908                         if (dimmed)
909                                 modest_dimming_rule_set_notification (rule, _("emev_bd_unabletomove_itemsr"));
910                 }
911         }
912         
913         /* Check diming rules for messages transfer  */
914         if (!dimmed) {
915                 dimmed = state->already_opened_msg;
916                 n_messages = state->n_selected;
917                 if (dimmed) {
918                         gchar *message = g_strdup_printf(_("emev_bd_unabletomove_items"), n_messages);
919                         modest_dimming_rule_set_notification (rule, message);
920                         g_free(message);
921                 }
922         }
923         if (!dimmed) {
924                 if (!gtk_widget_is_focus (folder_view))
925                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
926                 
927         }
928         
929         return dimmed;
930 }
931
932 gboolean 
933 modest_ui_dimming_rules_on_view_window_move_to (ModestWindow *win, gpointer user_data)
934 {
935         ModestDimmingRule *rule = NULL;
936         gboolean dimmed = FALSE;
937
938         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
939         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
940         rule = MODEST_DIMMING_RULE (user_data);
941
942         /* Check dimmed rule */ 
943         if (!dimmed) {
944                 dimmed = _transfer_mode_enabled (win);                  
945                 if (dimmed)
946                         modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
947         }
948         if (!dimmed) {
949                 if (MODEST_IS_MSG_VIEW_WINDOW (win))
950                         dimmed = !modest_msg_view_window_has_headers_model (MODEST_MSG_VIEW_WINDOW (win));
951                 if (dimmed) 
952                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_move_mail_attachment"));
953         }
954
955         return dimmed;
956 }
957
958 gboolean 
959 modest_ui_dimming_rules_on_find_msg (ModestWindow *win, gpointer user_data)
960 {
961         ModestDimmingRule *rule = NULL;
962         gboolean dimmed = FALSE;
963
964         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
965         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
966         rule = MODEST_DIMMING_RULE (user_data);
967
968         /* Check dimmed rule */ 
969         if (!dimmed) {
970                 dimmed = _transfer_mode_enabled (win);                  
971                 if (dimmed)
972                         modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
973         }
974
975         return dimmed;
976 }
977
978 gboolean 
979 modest_ui_dimming_rules_on_paste_msgs (ModestWindow *win, gpointer user_data)
980 {
981         ModestDimmingRule *rule = NULL;
982         TnyFolderType types[3];
983         gboolean dimmed = FALSE;
984         
985         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
986         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
987         rule = MODEST_DIMMING_RULE (user_data);
988
989         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
990         types[1] = TNY_FOLDER_TYPE_OUTBOX;
991         types[2] = TNY_FOLDER_TYPE_SENT;
992         
993         /* Check dimmed rule */ 
994         if (!dimmed) {
995                 dimmed = _clipboard_is_empty (win);
996                 if (dimmed)
997                         modest_dimming_rule_set_notification (rule, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
998         }
999         if (!dimmed) {
1000                 dimmed = _selected_folder_is_any_of_type (win, types, 3);
1001                 if (dimmed)
1002                         modest_dimming_rule_set_notification (rule, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
1003         }
1004         if (!dimmed) {
1005                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
1006                 if (dimmed) {
1007                         modest_dimming_rule_set_notification (rule, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
1008                 }
1009         }
1010         if (!dimmed) {
1011                 dimmed = _selected_folder_is_same_as_source (win);
1012                 if (dimmed)
1013                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_copy_samefolder"));
1014         }
1015
1016         return dimmed;
1017 }
1018
1019
1020 gboolean 
1021 modest_ui_dimming_rules_on_select_all (ModestWindow *win, gpointer user_data)
1022 {
1023         ModestDimmingRule *rule = NULL;
1024         gboolean dimmed = FALSE;
1025
1026         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1027         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1028         rule = MODEST_DIMMING_RULE (user_data);
1029
1030         /* Check dimmed rule */ 
1031         if (!dimmed) {
1032                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
1033                 if (dimmed)
1034                         modest_dimming_rule_set_notification (rule, "");
1035         }
1036                 
1037         return dimmed;
1038 }
1039
1040 gboolean 
1041 modest_ui_dimming_rules_on_view_attachments (ModestWindow *win, gpointer user_data)
1042 {
1043         ModestDimmingRule *rule = NULL;
1044         gboolean dimmed = FALSE;
1045
1046         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1047         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1048         rule = MODEST_DIMMING_RULE (user_data);
1049
1050         /* Check dimmed rule */ 
1051         if (!dimmed) 
1052                 dimmed = _invalid_attach_selected (win, TRUE, TRUE, FALSE, rule);                       
1053
1054         if (!dimmed) {
1055                 dimmed = _purged_attach_selected (win, FALSE, NULL);
1056                 if (dimmed) {
1057                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1058                 }
1059         }
1060                 
1061         return dimmed;
1062 }
1063
1064 gboolean 
1065 modest_ui_dimming_rules_on_save_attachments (ModestWindow *win, gpointer user_data)
1066 {
1067         ModestDimmingRule *rule = NULL;
1068         gboolean dimmed = FALSE;
1069
1070         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1071         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1072         rule = MODEST_DIMMING_RULE (user_data);
1073
1074         /* Check dimmed rule */ 
1075         if (!dimmed) 
1076                 dimmed = _invalid_attach_selected (win, FALSE, FALSE, FALSE, rule);
1077
1078         if (!dimmed) {
1079                 dimmed = _purged_attach_selected (win, FALSE, NULL);
1080                 if (dimmed) {
1081                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1082                 }
1083         }
1084                 
1085         return dimmed;
1086 }
1087
1088 gboolean 
1089 modest_ui_dimming_rules_on_remove_attachments (ModestWindow *win, gpointer user_data)
1090 {
1091         ModestDimmingRule *rule = NULL;
1092         const DimmedState *state = NULL;
1093         gboolean dimmed = FALSE;
1094
1095         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
1096         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1097         rule = MODEST_DIMMING_RULE (user_data);
1098         state = modest_window_get_dimming_state (win);          
1099
1100         /* Check in main window if there's only one message selected */
1101         if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) {
1102                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW (win), TRUE, rule);
1103         }
1104
1105         /* Check in view window if there's any attachment selected */
1106         if (!dimmed && MODEST_IS_MSG_VIEW_WINDOW (win)) {
1107                 dimmed = _invalid_attach_selected (win, FALSE, FALSE, TRUE, NULL);
1108                 if (dimmed)
1109                         modest_dimming_rule_set_notification (rule, _("FIXME:no attachment selected"));
1110         }
1111
1112         /* cannot purge in editable drafts nor pop folders */
1113         if (!dimmed) {
1114                 dimmed = _invalid_folder_for_purge (win, rule);
1115         }
1116
1117         /* Check if the selected message in main window has attachments */
1118         if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) {
1119                 dimmed = state->any_has_attachments;
1120                 if (dimmed)
1121                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
1122         }
1123
1124         /* Check if all attachments are already purged */
1125         if (!dimmed) {
1126                 dimmed = _purged_attach_selected (win, TRUE, rule);
1127         }
1128
1129         /* Check if the message is already downloaded */
1130         if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) {
1131                 dimmed = !_msg_download_completed (MODEST_MAIN_WINDOW (win));
1132                 if (dimmed)
1133                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1134         }
1135
1136
1137         return dimmed;
1138 }
1139
1140 gboolean 
1141 modest_ui_dimming_rules_on_undo (ModestWindow *win, gpointer user_data)
1142 {
1143         ModestDimmingRule *rule = NULL;
1144         gboolean dimmed = FALSE;
1145         
1146         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1147         rule = MODEST_DIMMING_RULE (user_data);
1148
1149         /* Check dimmed rule */ 
1150         if (!dimmed) {
1151                 dimmed = _clipboard_is_empty (win); 
1152                 if (dimmed)
1153                         modest_dimming_rule_set_notification (rule, "");
1154         }
1155                                 
1156         return dimmed;  
1157 }
1158
1159 gboolean 
1160 modest_ui_dimming_rules_on_cut (ModestWindow *win, gpointer user_data)
1161 {
1162         ModestDimmingRule *rule = NULL;
1163         gboolean dimmed = FALSE;
1164         
1165         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1166         rule = MODEST_DIMMING_RULE (user_data);
1167
1168         /* Check common dimming rules */
1169         if (!dimmed) {
1170                 dimmed = _invalid_clipboard_selected (win, rule);
1171         }
1172
1173         /* Check window specific dimming rules */
1174         if (MODEST_IS_MAIN_WINDOW (win)) {
1175                 if (!dimmed) { 
1176                         dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
1177                         if (dimmed)
1178                                 modest_dimming_rule_set_notification (rule, "");
1179                 }
1180                 if (!dimmed) {
1181                         dimmed = _selected_msg_sent_in_progress (win);
1182                         if (dimmed)
1183                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_cut_mess"));
1184                 }
1185         }
1186         
1187         return dimmed;
1188 }
1189
1190 gboolean 
1191 modest_ui_dimming_rules_on_copy (ModestWindow *win, gpointer user_data)
1192 {
1193         ModestDimmingRule *rule = NULL;
1194         gboolean dimmed = FALSE;
1195         
1196         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1197         rule = MODEST_DIMMING_RULE (user_data);
1198
1199         /* Check common dimming rules */
1200         if (!dimmed) {
1201                 dimmed = _invalid_clipboard_selected (win, rule);
1202         }
1203         
1204         /* Check window specific dimming rules */
1205         if (MODEST_IS_MAIN_WINDOW (win)) {
1206                 if (!dimmed) {
1207                         dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
1208                         if (dimmed)
1209                                 modest_dimming_rule_set_notification (rule, "");
1210                 }               
1211                 if (!dimmed) {
1212                         dimmed = _selected_msg_sent_in_progress (win);
1213                         if (dimmed)
1214                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_cut_mess"));
1215                 }
1216         }
1217                 
1218         return dimmed;
1219 }
1220
1221 gboolean 
1222 modest_ui_dimming_rules_on_view_previous (ModestWindow *win, gpointer user_data)
1223 {
1224         ModestDimmingRule *rule = NULL;
1225         gboolean dimmed = FALSE;
1226         
1227         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1228         rule = MODEST_DIMMING_RULE (user_data);
1229
1230         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1231
1232         /* Check dimmed rule */ 
1233         if (!dimmed) {
1234                 dimmed = _transfer_mode_enabled (win);                  
1235                 if (dimmed)
1236                         modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
1237         }
1238         if (!dimmed) {
1239                 if (MODEST_IS_MSG_VIEW_WINDOW (win))
1240                         dimmed = modest_msg_view_window_first_message_selected (MODEST_MSG_VIEW_WINDOW(win));
1241                 modest_dimming_rule_set_notification (rule, NULL);
1242         }               
1243
1244         return dimmed;
1245 }
1246
1247 gboolean 
1248 modest_ui_dimming_rules_on_view_next (ModestWindow *win, gpointer user_data)
1249 {
1250         ModestDimmingRule *rule = NULL;
1251         gboolean dimmed = FALSE;
1252
1253         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1254         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1255         rule = MODEST_DIMMING_RULE (user_data);
1256
1257         /* Check dimmed rule */ 
1258         if (!dimmed) {
1259                 dimmed = _transfer_mode_enabled (win);                  
1260                 if (dimmed)
1261                         modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
1262         }
1263         if (!dimmed) {
1264                 if (MODEST_IS_MSG_VIEW_WINDOW (win))
1265                         dimmed = modest_msg_view_window_last_message_selected (MODEST_MSG_VIEW_WINDOW (win));
1266                 modest_dimming_rule_set_notification (rule, NULL);
1267         }               
1268
1269         return dimmed;
1270 }
1271
1272
1273 gboolean 
1274 modest_ui_dimming_rules_on_tools_smtp_servers (ModestWindow *win, gpointer user_data)
1275 {
1276         const gboolean dimmed = 
1277                 !modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), 
1278                         TRUE);  
1279                 
1280         return dimmed;
1281 }
1282
1283 gboolean 
1284 modest_ui_dimming_rules_on_cancel_sending (ModestWindow *win, gpointer user_data)
1285 {
1286         ModestDimmingRule *rule = NULL;
1287         TnyFolderType types[1];
1288         guint n_messages = 0;
1289         const DimmedState *state = NULL;
1290         gboolean dimmed = FALSE;
1291
1292         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1293         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1294         rule = MODEST_DIMMING_RULE (user_data);
1295         state = modest_window_get_dimming_state (win);
1296
1297         types[0] = TNY_FOLDER_TYPE_OUTBOX; 
1298
1299         /* Check dimmed rules */        
1300         if (!dimmed) {
1301                 dimmed = state->already_opened_msg;
1302                 n_messages = state->n_selected;
1303                 if (dimmed) 
1304                         modest_dimming_rule_set_notification (rule, _("mcen_ib_message_unableto_cancel_send"));
1305         }
1306         if (!dimmed) {
1307                 dimmed = !_selected_folder_is_any_of_type (win, types, 1);
1308                 if (dimmed) 
1309                         modest_dimming_rule_set_notification (rule, "");
1310         }
1311         if (!dimmed) {
1312                 dimmed = !_sending_in_progress (win);
1313                 if (dimmed)
1314                         modest_dimming_rule_set_notification (rule, "");
1315         }
1316
1317         return dimmed;
1318 }
1319
1320 gboolean 
1321 modest_ui_dimming_rules_on_send_receive (ModestWindow *win, gpointer user_data)
1322 {
1323         ModestDimmingRule *rule = NULL;
1324         gboolean dimmed = FALSE;
1325         
1326         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1327         rule = MODEST_DIMMING_RULE (user_data);
1328  
1329         /* Check dimmed rule */ 
1330         if (!dimmed) {
1331                 dimmed = !modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), 
1332                                                           TRUE);        
1333                 if (dimmed)
1334                         modest_dimming_rule_set_notification (rule, _("mcen_nc_no_email_acnts_defined"));
1335         }
1336
1337         return dimmed;
1338 }
1339
1340 gboolean
1341 modest_ui_dimming_rules_on_add_to_contacts (ModestWindow *win, gpointer user_data)
1342 {
1343         ModestDimmingRule *rule = NULL;
1344         gboolean dimmed = FALSE;
1345
1346         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1347         rule = MODEST_DIMMING_RULE (user_data);
1348
1349         /* Check dimmed rule */
1350         if (!dimmed) {
1351                 GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1352                 gchar *selection = NULL;
1353                 selection = gtk_clipboard_wait_for_text (clipboard);
1354
1355                 dimmed = !((selection != NULL) && (modest_text_utils_validate_recipient (selection, NULL)));
1356         }
1357
1358         return dimmed;
1359 }
1360
1361 /* *********************** static utility functions ******************** */
1362
1363
1364 static gboolean
1365 _selected_folder_not_writeable (ModestMainWindow *win)
1366 {
1367         GtkWidget *folder_view = NULL;
1368         TnyFolderStore *parent_folder = NULL;
1369         ModestTnyFolderRules rules;
1370         gboolean result = FALSE;
1371
1372         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1373
1374         /* Get folder view */
1375         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1376                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1377         /* If no folder view, always dimmed */
1378         if (!folder_view)
1379                 return TRUE;
1380         
1381         /* Get selected folder as parent of new folder to create */
1382         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1383         if (!(parent_folder && TNY_IS_FOLDER(parent_folder))) {
1384                 if (parent_folder)
1385                         g_object_unref (parent_folder);
1386                 return TRUE;
1387         }
1388         
1389         /* Check dimmed rule */ 
1390         rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
1391         result = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
1392
1393         /* free */
1394         g_object_unref (parent_folder);
1395
1396         return result;
1397 }
1398
1399 static gboolean
1400 _selected_folder_is_root_or_inbox (ModestMainWindow *win)
1401 {
1402         TnyFolderType types[2];
1403         gboolean result = FALSE;
1404
1405         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1406
1407         types[0] = TNY_FOLDER_TYPE_ROOT; 
1408         types[1] = TNY_FOLDER_TYPE_INBOX; 
1409
1410         /* Check folder type */
1411         result = _selected_folder_is_any_of_type (MODEST_WINDOW(win), types, 2);
1412
1413         /* Check pop and MMC accounts */
1414         if (!result) {
1415                 result = _selected_folder_is_MMC_or_POP_root (win);
1416         }
1417                 
1418         return result;
1419 }
1420
1421
1422 static gboolean
1423 _selected_folder_is_root (ModestMainWindow *win)
1424 {
1425         TnyFolderType types[1];
1426         gboolean result = FALSE;
1427
1428         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1429
1430         /* All accounts are root items: */
1431         GtkWidget *folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1432                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1433         if (folder_view) {                                      
1434                 gboolean is_account = FALSE;
1435                 TnyFolderStore *folder_store = 
1436                         modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1437                 if (folder_store) {
1438                         is_account = TNY_IS_ACCOUNT (folder_store);
1439                         g_object_unref (folder_store);
1440                         folder_store = NULL;
1441                 }
1442                 
1443                 if (is_account)
1444                         return TRUE;
1445         }
1446                 
1447         /* Try something more precise: */
1448         types[0] = TNY_FOLDER_TYPE_ROOT; 
1449
1450         /* Check folder type */
1451         result = _selected_folder_is_any_of_type (MODEST_WINDOW(win), types, 1);
1452                 
1453         /* Check pop and MMC accounts */
1454         if (!result) {
1455                 result = _selected_folder_is_MMC_or_POP_root (win);
1456         }
1457
1458         return result;
1459 }
1460
1461 static gboolean
1462 _selected_folder_is_MMC_or_POP_root (ModestMainWindow *win)
1463 {
1464         GtkWidget *folder_view = NULL;
1465         TnyFolderStore *parent_folder = NULL;
1466         gboolean result = FALSE;
1467
1468         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1469                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1470         /* Get selected folder as parent of new folder to create */
1471         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1472         if (!parent_folder)
1473                 return TRUE;
1474         
1475         if (TNY_IS_ACCOUNT (parent_folder)) {
1476                 /* If it's the local account then do not dim */
1477                 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent_folder))) {
1478                         result = FALSE;
1479                 } else {
1480                                 /* If it's the MMC root folder then dim it */
1481                         if (!strcmp (tny_account_get_id (TNY_ACCOUNT (parent_folder)), MODEST_MMC_ACCOUNT_ID)) {
1482                                         result = TRUE;
1483                         } else {
1484                                 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (parent_folder));
1485                                 /* If it's POP then dim */
1486                                 result = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
1487                                                   MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
1488                         }
1489                 }
1490         }
1491         g_object_unref (parent_folder);
1492
1493         return result;
1494 }
1495
1496
1497 static gboolean
1498 _selected_folder_is_empty (ModestMainWindow *win)
1499 {
1500         GtkWidget *folder_view = NULL;
1501         TnyFolderStore *folder = NULL;
1502         gboolean result = FALSE;
1503
1504         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1505
1506         /* Get folder view */
1507         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1508                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1509         /* If no folder view, always dimmed */
1510         if (!folder_view)
1511                 return TRUE;
1512         
1513         /* Get selected folder as parent of new folder to create */
1514         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1515         if (!(folder && TNY_IS_FOLDER(folder))) {
1516                 if (folder)
1517                         g_object_unref (folder);
1518                 return TRUE;
1519         }
1520         
1521         /* Check folder type */
1522         result = tny_folder_get_all_count (TNY_FOLDER (folder)) == 0;
1523
1524         /* free */
1525         g_object_unref (folder);
1526
1527         return result;
1528 }
1529
1530 static gboolean
1531 _selected_folder_is_same_as_source (ModestWindow *win)
1532 {
1533         ModestEmailClipboard *clipboard = NULL;
1534         GtkWidget *folder_view = NULL;
1535         TnyFolderStore *folder = NULL;
1536         gboolean result = FALSE;
1537
1538         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1539
1540         /* Get folder view */
1541         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1542                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1543         if (!folder_view)
1544                 return FALSE;
1545         
1546         /* Get selected folder as destination folder */
1547         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1548         if (!(folder && TNY_IS_FOLDER(folder))) {
1549                 result = FALSE;
1550                 goto frees;
1551         }
1552         
1553         /* Check clipboard is cleared */
1554         clipboard = modest_runtime_get_email_clipboard ();
1555         if (modest_email_clipboard_cleared (clipboard)) {
1556                 result = FALSE;
1557                 goto frees;
1558         }
1559                 
1560         /* Check source folder */
1561         result = modest_email_clipboard_check_source_folder (clipboard, 
1562                                                              (const TnyFolder *) folder);
1563         
1564         /* Free */
1565  frees:
1566         g_object_unref (folder);
1567         
1568         return result;
1569 }
1570
1571 static gboolean
1572 _selected_folder_is_any_of_type (ModestWindow *win,
1573                                  TnyFolderType types[], 
1574                                  guint ntypes)
1575 {
1576         GtkWidget *folder_view = NULL;
1577         TnyFolderStore *folder = NULL;
1578         TnyFolderType folder_type;
1579         guint i=0;
1580         gboolean result = FALSE;
1581
1582         /*Get current folder */
1583         if (MODEST_IS_MAIN_WINDOW(win)) {
1584
1585                 /* Get folder view */
1586                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1587                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
1588                 /* If no folder view, always dimmed */
1589                 if (!folder_view)
1590                         return FALSE;
1591         
1592                 /* Get selected folder as parent of new folder to create */
1593                 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1594
1595                 if (!(folder && TNY_IS_FOLDER(folder))) {
1596                         if (folder)
1597                                 g_object_unref (folder);
1598                         return FALSE;
1599                 }
1600                 
1601                 /* Check folder type */
1602                 result = _folder_is_any_of_type (TNY_FOLDER(folder), types, ntypes);
1603         }
1604         else if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1605                 folder_type = modest_msg_view_window_get_folder_type (MODEST_MSG_VIEW_WINDOW (win));
1606                 for (i=0; i < ntypes; i++) {
1607                         result = result || folder_type == types[i];
1608                 }
1609         }
1610
1611
1612         /* free */
1613         g_object_unref (folder);
1614
1615         return result;  
1616 }
1617
1618 static gboolean
1619 _folder_is_any_of_type (TnyFolder *folder,
1620                         TnyFolderType types[], 
1621                         guint ntypes)
1622 {
1623         TnyFolderType folder_type;
1624         gboolean result = FALSE;
1625         guint i;
1626
1627         g_return_val_if_fail (TNY_IS_FOLDER(folder), FALSE);
1628
1629         /* Get folder type */
1630         folder_type = modest_tny_folder_guess_folder_type (folder);
1631                 
1632         /* Check foler type */
1633         for (i=0; i < ntypes; i++) {
1634                 result = result || folder_type == types[i];
1635         }
1636
1637         return result;
1638 }
1639
1640 static gboolean
1641 _selected_folder_is_snd_level (ModestMainWindow *win)
1642 {
1643         GtkWidget *folder_view = NULL;
1644         GtkTreeSelection *sel = NULL;
1645         GtkTreeModel *model = NULL;
1646         GtkTreePath *path = NULL;
1647         GtkTreeIter iter;
1648         TnyFolderStore *folder = NULL;
1649         gboolean result = FALSE;
1650
1651         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
1652
1653         /*Get curent folder */
1654         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1655                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1656         /* If no folder view, always dimmed */
1657         if (!folder_view) 
1658                 goto frees;
1659
1660         /* Get selected folder as parent of new folder to create */
1661         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));     
1662         if (!(folder && TNY_IS_FOLDER(folder))) {
1663                 goto frees;
1664         }
1665         
1666         /* Check folder level */
1667         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(folder_view));
1668         if (!gtk_tree_selection_get_selected (sel, &model, &iter))
1669                 goto frees;
1670         path = gtk_tree_model_get_path (model, &iter);
1671         result = gtk_tree_path_get_depth (path) > 2;
1672         
1673  frees:
1674         if (folder != NULL)
1675                 g_object_unref (folder);
1676         if (path != NULL)
1677                 gtk_tree_path_free (path);
1678         
1679         return result;
1680
1681 }
1682
1683 static gboolean
1684 _clipboard_is_empty (ModestWindow *win)
1685 {
1686         gboolean result = FALSE;
1687         
1688         if (MODEST_IS_MAIN_WINDOW (win)) {
1689                 ModestEmailClipboard *clipboard = NULL;
1690                 clipboard = modest_runtime_get_email_clipboard ();
1691                 if (modest_email_clipboard_cleared (clipboard)) 
1692                  result = TRUE;  
1693         }
1694
1695         return result;
1696 }
1697
1698 static gboolean
1699 _invalid_clipboard_selected (ModestWindow *win,
1700                        ModestDimmingRule *rule) 
1701 {
1702         const DimmedState *state = NULL;
1703         gboolean result = FALSE;
1704
1705         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
1706         state = modest_window_get_dimming_state (win);
1707
1708         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1709                 GtkClipboard *clipboard = NULL;
1710                 gchar *selection = NULL;
1711                 GtkWidget *focused = NULL;
1712
1713                 /* Get clipboard selection*/
1714                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1715                 selection = gtk_clipboard_wait_for_text (clipboard);
1716
1717                 /* Get focuesed widget */
1718                 focused = gtk_window_get_focus (GTK_WINDOW (win));
1719
1720                 /* Check dimming */
1721                 result = ((selection == NULL) || 
1722                           (MODEST_IS_ATTACHMENTS_VIEW (focused)));
1723                 
1724                 if (result)
1725                         modest_dimming_rule_set_notification (rule, "");
1726                 
1727                 if (selection != NULL) 
1728                         g_free(selection);
1729         }               
1730         else if (MODEST_IS_MAIN_WINDOW (win)) {
1731                 /* Check dimming */
1732                 result = state->n_selected == 0;
1733                 if (result)
1734                         modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));                  
1735         }
1736         
1737         return result;
1738 }
1739
1740
1741 static gboolean
1742 _invalid_attach_selected (ModestWindow *win,
1743                           gboolean unique,
1744                           gboolean for_view,
1745                           gboolean for_remove,
1746                           ModestDimmingRule *rule) 
1747 {
1748         GList *attachments, *node;
1749         gint n_selected;
1750         TnyHeaderFlags flags;
1751         gboolean nested_attachments = FALSE;
1752         gboolean selected_messages = FALSE;
1753         const DimmedState *state = NULL;
1754         gboolean result = FALSE;
1755
1756         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
1757         state = modest_window_get_dimming_state (win);
1758
1759         if (MODEST_IS_MAIN_WINDOW (win)) {
1760                 flags = TNY_HEADER_FLAG_ATTACHMENTS;
1761                 if (!result)
1762                         result = !state->any_has_attachments;
1763         }
1764         else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1765                 
1766                 /* Get selected atachments */
1767                 attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
1768                 n_selected = g_list_length (attachments);
1769
1770                 /* Check unique */              
1771                 if (!result) {
1772                         if (unique) 
1773                                 result = n_selected != 1;
1774                         else
1775                                 
1776                                 result = n_selected < 1;
1777                 }
1778                 
1779                 /* Check attached type (view operation not required) */
1780                 if (!result && !for_view)  {
1781                         for (node = attachments; node != NULL && !result; node = g_list_next (node)) {
1782                                 TnyMimePart *mime_part = TNY_MIME_PART (node->data);
1783                                 TnyList *nested_list = tny_simple_list_new ();
1784                                 if (!for_remove && TNY_IS_MSG (mime_part)) {
1785                                         selected_messages = TRUE;
1786                                         result = TRUE;
1787                                 }
1788                                 tny_mime_part_get_parts (mime_part, nested_list);
1789                                 if (!for_remove && tny_list_get_length (nested_list) > 0) {
1790                                         nested_attachments = TRUE;
1791                                         result = TRUE;
1792                                 }
1793                                 g_object_unref (nested_list);
1794                         }
1795                 }
1796                 
1797                 /* Set notifications */
1798                 if (result && rule != NULL) {
1799                         if (selected_messages) {
1800                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_save_attach_mail"));
1801                         } else if (nested_attachments) {
1802                                 modest_dimming_rule_set_notification (rule, _("FIXME:unable to save attachments with nested elements"));
1803                         } else if (n_selected == 0) {
1804                                 modest_dimming_rule_set_notification (rule, _("FIXME:no attachment selected"));
1805                         } else if (unique) {
1806                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_display_more"));
1807                         }
1808                 }
1809                 
1810                 /* Free */
1811                 g_list_free (attachments);
1812         }
1813
1814         return result;
1815 }
1816
1817 static gboolean
1818 _purged_attach_selected (ModestWindow *win, gboolean all, ModestDimmingRule *rule) 
1819 {
1820         GList *attachments = NULL, *node;
1821         gint purged = 0;
1822         gint n_attachments = 0;
1823         gboolean result = FALSE;
1824
1825         /* This should check if _all_ the attachments are already purged. If only some
1826          * of them are purged, then it does not cause dim as there's a confirmation dialog
1827          * for removing only local attachments */
1828
1829         /* Get selected atachments */
1830         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1831                 attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
1832         } else if (MODEST_IS_MAIN_WINDOW (win)) {
1833                 /* If we're in main window, we won't know if there are already purged attachments */
1834                 return FALSE;
1835         }
1836
1837         if (attachments == NULL)
1838                 return FALSE;
1839
1840         for (node = attachments; node != NULL; node = g_list_next (node)) {
1841                 TnyMimePart *mime_part = TNY_MIME_PART (node->data);
1842                 if (tny_mime_part_is_purged (mime_part)) {
1843                         purged++;
1844                 }
1845                 n_attachments++;
1846         }
1847                 
1848         /* Free */
1849         g_list_free (attachments);
1850
1851         if (all)
1852                 result = (purged == n_attachments);
1853         else
1854                 result = (purged > 0);
1855
1856         if (result && (rule != NULL))
1857                 modest_dimming_rule_set_notification (rule, _("mail_ib_attachment_already_purged"));
1858
1859         return result;
1860 }
1861
1862 static gboolean
1863 _invalid_msg_selected (ModestMainWindow *win,
1864                        gboolean unique,
1865                        ModestDimmingRule *rule) 
1866 {
1867         GtkWidget *folder_view = NULL;
1868         const DimmedState *state = NULL;
1869         gboolean result = FALSE;
1870
1871         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1872         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (rule), FALSE);
1873         state = modest_window_get_dimming_state (MODEST_WINDOW(win));
1874                 
1875         /* Get folder view to check focus */
1876         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1877                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1878
1879         /* Check dimmed rule (TODO: check focus on widgets */   
1880         if (!result) {
1881                 result = ((state->n_selected == 0 ) ||
1882                           (gtk_widget_is_focus (folder_view)));
1883                 if (result)
1884                         modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));
1885         }
1886         if (!result && unique) {
1887                 result = state->n_selected > 1;
1888                 if (result)
1889                         modest_dimming_rule_set_notification (rule, _("mcen_ib_select_one_message"));
1890         }
1891
1892         return result;
1893 }
1894
1895
1896 static gboolean
1897 _msg_download_in_progress (ModestMsgViewWindow *win)
1898 {
1899         gboolean result = FALSE;
1900
1901         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), FALSE);
1902
1903         result = modest_msg_view_window_toolbar_on_transfer_mode (win);
1904
1905         return result;
1906 }
1907
1908 static gboolean
1909 _msg_download_completed (ModestMainWindow *win)
1910 {
1911         const DimmedState *state = modest_window_get_dimming_state (MODEST_WINDOW(win));
1912         return state->any_marked_as_cached;
1913 }
1914
1915 static void 
1916 fill_list_of_caches (gpointer key, gpointer value, gpointer userdata)
1917 {
1918         GSList **send_queues = (GSList **) userdata;
1919         *send_queues = g_slist_prepend (*send_queues, value);
1920 }
1921
1922 static gboolean
1923 _selected_msg_sent_in_progress (ModestWindow *win)
1924 {
1925         const DimmedState *state = modest_window_get_dimming_state (win);
1926         return state->sent_in_progress;
1927 }
1928
1929
1930 static gboolean
1931 _sending_in_progress (ModestWindow *win)
1932 {
1933         gboolean result = FALSE;
1934         
1935         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (win), FALSE);
1936
1937         /* Check if send operation is in progress */
1938         result = modest_main_window_send_receive_in_progress (MODEST_MAIN_WINDOW (win));
1939
1940         return result;
1941 }
1942
1943 static gboolean
1944 _invalid_folder_for_purge (ModestWindow *win, 
1945                            ModestDimmingRule *rule)
1946 {
1947         TnyMsg *msg = NULL;
1948         TnyFolder *folder = NULL;
1949         TnyAccount *account = NULL;
1950         gboolean result = FALSE;
1951
1952         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1953
1954                 /* Get folder and account of message */
1955                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1956                 g_return_val_if_fail(msg != NULL, TRUE);                        
1957                 folder = tny_msg_get_folder (msg);      
1958                 if (folder == NULL) {
1959                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
1960                         goto frees;
1961                 }
1962                 g_object_unref (msg);
1963         } else if (MODEST_IS_MAIN_WINDOW (win)) {
1964                 GtkWidget *folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1965                                                                               MODEST_WIDGET_TYPE_FOLDER_VIEW);
1966                 if (!folder_view)
1967                         return FALSE;
1968                 folder = TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
1969                 if (folder == NULL || ! TNY_IS_FOLDER (folder))
1970                         goto frees;             
1971         } else {
1972                 g_return_val_if_reached (FALSE);
1973         }
1974         account = modest_tny_folder_get_account (folder);
1975         if (account == NULL) goto frees;                        
1976                 
1977         /* Check account */
1978         if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (account))) {
1979                 TnyFolderType types[2];
1980                 types[0] = TNY_FOLDER_TYPE_DRAFTS;
1981                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
1982                 
1983                 if (_selected_folder_is_any_of_type (win, types, 2)) {
1984                         result = TRUE;
1985                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_editable_msg"));
1986                 } else {
1987                         /* We're currently disabling purge in any local store */
1988                         result = TRUE;
1989                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
1990                 }
1991         } else {
1992                 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
1993                 /* If it's POP then dim */
1994                 if (modest_protocol_info_get_transport_store_protocol (proto_str) == 
1995                     MODEST_PROTOCOL_STORE_POP) {
1996                         GList *attachments = NULL;
1997                         gint n_selected = 0;
1998                         result = TRUE;
1999                         
2000                         /* TODO: This check is here to prevent a gwarning, but this looks like a logic error.
2001                          * murrayc */
2002                         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2003                                 attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
2004                                 n_selected = g_list_length (attachments);
2005                                 g_list_free (attachments);
2006                         }
2007                         
2008                         modest_dimming_rule_set_notification (rule, 
2009                                                               ngettext ("mail_ib_unable_to_pure_attach_pop_mail_singular",
2010                                                                         "mail_ib_unable_to_pure_attach_pop_mail_plural", 
2011                                                                         n_selected));
2012                 }
2013         }
2014         
2015 frees:
2016         if (folder != NULL)
2017                 g_object_unref (folder);
2018         if (account != NULL)
2019                 g_object_unref (account);
2020         
2021         return result;
2022 }
2023
2024 static gboolean
2025 _transfer_mode_enabled (ModestWindow *win)
2026 {
2027         gboolean result = FALSE;
2028
2029         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), FALSE);
2030         
2031         /* Check dimming */
2032         result = modest_msg_view_window_transfer_mode_enabled (MODEST_MSG_VIEW_WINDOW (win));
2033
2034         return result;
2035 }
2036