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