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