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