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