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