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