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