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