Dim fetch images in msg view while downloading a message (fixes NB#151895).
[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         ModestDimmingRule *rule = NULL;
951
952         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), FALSE);
953         rule = MODEST_DIMMING_RULE (user_data);
954
955         dimmed = !modest_msg_view_window_has_blocked_external_images (MODEST_MSG_VIEW_WINDOW (win));
956
957         if (!dimmed) {
958                 dimmed = _transfer_mode_enabled (win);
959                 if (dimmed)
960                         modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
961         }
962         if (!dimmed) {
963                 dimmed = _msg_download_in_progress (win);
964                 if (dimmed)
965                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_reply"));
966         }
967
968         return dimmed;
969 }
970
971
972 gboolean 
973 modest_ui_dimming_rules_on_mark_as_read_msg_in_view (ModestWindow *win, gpointer user_data)
974 {
975         ModestDimmingRule *rule = NULL;
976         TnyHeader *header;
977         TnyHeaderFlags flags;
978         gboolean dimmed = FALSE;
979
980
981         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
982         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
983         rule = MODEST_DIMMING_RULE (user_data);
984
985         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
986         if (!header) {
987                 dimmed = TRUE;
988         }
989
990         /* If the viewer is showing a message sent as attachment */
991         if (!dimmed)
992                 dimmed = !modest_msg_view_window_has_headers_model (MODEST_MSG_VIEW_WINDOW (win));
993
994         if (!dimmed) {
995                 flags = tny_header_get_flags (header);
996                 if (flags & TNY_HEADER_FLAG_SEEN)
997                         dimmed = TRUE;
998         }
999
1000         if (header)
1001                 g_object_unref (header);
1002         return dimmed;
1003 }
1004
1005
1006 gboolean 
1007 modest_ui_dimming_rules_on_mark_as_unread_msg_in_view (ModestWindow *win, gpointer user_data)
1008 {
1009         ModestDimmingRule *rule = NULL;
1010         TnyHeader *header;
1011         TnyHeaderFlags flags;
1012         gboolean dimmed = FALSE;
1013         
1014
1015         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1016         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1017         rule = MODEST_DIMMING_RULE (user_data);
1018         
1019         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1020         if (!header) {
1021                 dimmed = TRUE;
1022         }
1023
1024         /* If the viewer is showing a message sent as attachment */
1025         if (!dimmed)
1026                 dimmed = !modest_msg_view_window_has_headers_model (MODEST_MSG_VIEW_WINDOW (win));
1027
1028         if (!dimmed) {
1029                 flags = tny_header_get_flags (header);
1030                 if (!(flags & TNY_HEADER_FLAG_SEEN))
1031                         dimmed = TRUE;
1032         }
1033
1034         if (header)
1035                 g_object_unref (header);
1036         return dimmed;
1037 }
1038
1039 gboolean 
1040 modest_ui_dimming_rules_on_mark_as_read_msg (ModestWindow *win, gpointer user_data)
1041 {
1042         ModestDimmingRule *rule = NULL;
1043         TnyHeaderFlags flags;
1044         const DimmedState *state = NULL;
1045         gboolean dimmed = FALSE;
1046
1047         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1048         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1049         rule = MODEST_DIMMING_RULE (user_data);
1050         state = modest_window_get_dimming_state (win);          
1051         
1052         flags = TNY_HEADER_FLAG_SEEN; 
1053
1054         /* Check dimmed rule */ 
1055         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);     
1056         if (!dimmed) {
1057                 if (state)
1058                         dimmed = state->all_marked_as_seen;
1059                 if (dimmed)
1060                         modest_dimming_rule_set_notification (rule, "");
1061         }       
1062
1063         return dimmed;
1064 }
1065
1066 gboolean 
1067 modest_ui_dimming_rules_on_mark_as_unread_msg (ModestWindow *win, gpointer user_data)
1068 {
1069         ModestDimmingRule *rule = NULL;
1070         TnyHeaderFlags flags;
1071         const DimmedState *state = NULL;
1072         gboolean dimmed = FALSE;
1073
1074         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1075         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1076         rule = MODEST_DIMMING_RULE (user_data);
1077         state = modest_window_get_dimming_state (win);          
1078         
1079         flags = TNY_HEADER_FLAG_SEEN; 
1080
1081         /* Check dimmed rule */ 
1082         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
1083         if (!dimmed) {
1084                 if (state)
1085                         dimmed = !state->any_marked_as_seen;
1086                 if (dimmed)
1087                         modest_dimming_rule_set_notification (rule, "");
1088         }
1089
1090         return dimmed;
1091 }
1092
1093 gboolean 
1094 modest_ui_dimming_rules_on_move_to (ModestWindow *win, gpointer user_data)
1095 {
1096         ModestDimmingRule *rule = NULL;
1097         gboolean dimmed = FALSE;
1098
1099         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1100         rule = MODEST_DIMMING_RULE (user_data);
1101
1102         if (MODEST_IS_MAIN_WINDOW (win)) 
1103                 dimmed = modest_ui_dimming_rules_on_main_window_move_to (win, user_data);
1104 #ifdef MODEST_TOOLKIT_HILDON2
1105         else if (MODEST_IS_HEADER_WINDOW (win))
1106                 dimmed = modest_ui_dimming_rules_on_header_window_move_to (win, user_data);
1107         else if (MODEST_IS_FOLDER_WINDOW (win))
1108                 dimmed = modest_ui_dimming_rules_on_folder_window_move_to (win, user_data);
1109 #endif
1110         else if (MODEST_IS_MSG_VIEW_WINDOW (win)) 
1111                  dimmed = modest_ui_dimming_rules_on_view_window_move_to (win, user_data);
1112
1113         return dimmed;
1114 }
1115
1116
1117 gboolean 
1118 modest_ui_dimming_rules_on_main_window_move_to (ModestWindow *win, gpointer user_data)
1119 {
1120         GtkWidget *folder_view = NULL;
1121         ModestDimmingRule *rule = NULL;
1122         const DimmedState *state = NULL;
1123         gboolean dimmed = FALSE;
1124         
1125         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
1126         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1127         rule = MODEST_DIMMING_RULE (user_data);
1128         state = modest_window_get_dimming_state (win);          
1129         
1130         /* Get the folder view */
1131         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1132                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1133
1134         if (folder_view) {
1135                 TnyFolderStore *selected = modest_folder_view_get_selected ((ModestFolderView *)folder_view);
1136                 if (selected) {
1137                         TnyAccount *account = NULL;
1138
1139                         if (TNY_IS_ACCOUNT (selected)) {
1140                                 account = g_object_ref (selected);
1141                         } else if (!TNY_IS_MERGE_FOLDER (selected)){
1142                                 account = tny_folder_get_account (TNY_FOLDER (selected));
1143                         }
1144                         if (account) {
1145                                 ModestProtocolType protocol_type;
1146
1147                                 protocol_type = modest_tny_account_get_protocol_type (account);
1148                                 dimmed  = modest_protocol_registry_protocol_type_has_tag
1149                                         (modest_runtime_get_protocol_registry (),
1150                                          protocol_type,
1151                                          MODEST_PROTOCOL_REGISTRY_STORE_FORBID_OUTGOING_XFERS);
1152
1153                                 g_object_unref (account);
1154                         }
1155                         g_object_unref (selected);
1156                 }
1157         }
1158
1159         /* Check diming rules for folders transfer  */
1160         if (!dimmed && folder_view && gtk_widget_is_focus (folder_view)) {
1161                 TnyFolderType types[5];
1162
1163                 types[0] = TNY_FOLDER_TYPE_DRAFTS; 
1164                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
1165                 types[2] = TNY_FOLDER_TYPE_SENT;
1166                 types[3] = TNY_FOLDER_TYPE_ROOT; 
1167                 types[4] = TNY_FOLDER_TYPE_INBOX; 
1168                 
1169                 /* Apply folder rules */        
1170                 dimmed = _selected_folder_not_moveable (MODEST_MAIN_WINDOW(win));
1171                 if (dimmed)
1172                         modest_dimming_rule_set_notification (rule, _("emev_nc_unabletomove_items"));           
1173                 if (!dimmed) {
1174                         dimmed = _selected_folder_is_any_of_type (win, types, 5);
1175                         if (dimmed)
1176                                 modest_dimming_rule_set_notification (rule, _("emev_nc_unabletomove_items"));
1177                 }
1178         }
1179         
1180         /* Check diming rules for messages transfer  */
1181         if (!dimmed) {
1182                 if (state) {
1183                         dimmed = (state->already_opened_msg > 0) ? TRUE : FALSE;
1184                         if (dimmed) {
1185                                 gchar *message = g_strdup_printf(_("emev_nc_unabletomove_items"),
1186                                                                  state->already_opened_msg);
1187                                 modest_dimming_rule_set_notification (rule, message);
1188                                 g_free(message);
1189                         }
1190                 }
1191         }
1192         if (!dimmed) {
1193                 if (!(folder_view && gtk_widget_is_focus (folder_view)))
1194                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
1195
1196         }
1197         if (!dimmed) {
1198                 dimmed = _selected_msg_sent_in_progress (win);
1199                 if (dimmed)
1200                         modest_dimming_rule_set_notification (rule, _("sfil_ib_unable_to_move_selected_items"));
1201         }
1202
1203         return dimmed;
1204 }
1205
1206 static gboolean
1207 _forbid_outgoing_xfers (ModestWindow *window)
1208 {
1209         const gchar *account_name = NULL;
1210         TnyAccount *account = NULL;
1211         gboolean dimmed = FALSE;
1212
1213 #ifdef MODEST_TOOLKIT_HILDON2
1214         /* We cannot just get the active account because the active
1215            account of a header window that shows the headers of a
1216            local account is the ID of the remote account */
1217         if (MODEST_IS_HEADER_WINDOW (window)) {
1218                 ModestHeaderView *header_view;
1219                 TnyFolder *folder;
1220
1221                 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) window);
1222                 folder = modest_header_view_get_folder (header_view);
1223
1224                 if (folder) {
1225                         account = modest_tny_folder_get_account (folder);
1226                         g_object_unref (folder);
1227                 }
1228         }
1229 #endif
1230
1231         if (!account) {
1232                 account_name = modest_window_get_active_account (window);
1233                 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1234                                                                        account_name,
1235                                                                        TNY_ACCOUNT_TYPE_STORE);
1236         }
1237
1238         if (account) {
1239                 ModestProtocolType protocol_type;
1240
1241                 protocol_type = modest_tny_account_get_protocol_type (account);
1242                 dimmed  = modest_protocol_registry_protocol_type_has_tag
1243                         (modest_runtime_get_protocol_registry (),
1244                          protocol_type,
1245                          MODEST_PROTOCOL_REGISTRY_STORE_FORBID_OUTGOING_XFERS);
1246
1247                 g_object_unref (account);
1248         }
1249         return dimmed;
1250 }
1251
1252 gboolean
1253 modest_ui_dimming_rules_on_view_window_move_to (ModestWindow *win, gpointer user_data)
1254 {
1255         ModestDimmingRule *rule = NULL;
1256         gboolean dimmed = FALSE;
1257
1258         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1259         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1260         rule = MODEST_DIMMING_RULE (user_data);
1261
1262         /* This could happen if we load the msg view window with a
1263            preview before loading the full message */
1264         TnyMsg *msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1265         if (!msg) {
1266                 return TRUE;
1267         } else {
1268                 g_object_unref (msg);
1269         }
1270
1271         /* Check dimmed rule */
1272         dimmed = _transfer_mode_enabled (win);
1273         if (dimmed)
1274                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
1275
1276         if (!dimmed)
1277                 dimmed = _forbid_outgoing_xfers (win);
1278
1279         if (!dimmed) {
1280                 const DimmedState *state = modest_window_get_dimming_state (win);
1281                 if (state) {
1282                         dimmed = state->any_marked_as_deleted;
1283                         if (dimmed) {
1284                                 gchar *msg = modest_ui_actions_get_msg_already_deleted_error_msg (win);
1285                                 modest_dimming_rule_set_notification (rule, msg);
1286                                 g_free (msg);
1287                         }
1288                 }
1289         }
1290
1291         if (!dimmed) {
1292                 dimmed = _selected_msg_sent_in_progress (win);
1293                 if (dimmed)
1294                         modest_dimming_rule_set_notification (rule, _("emev_nc_unabletomove_item"));
1295         }
1296
1297         /* This could happen if we're viewing a message of the outbox
1298            that has been already sent */
1299         if (!dimmed)
1300                 dimmed = _message_already_sent (MODEST_MSG_VIEW_WINDOW(win));
1301
1302         if (!dimmed) {
1303                 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1304                         /* The move_to button should be dimmed when viewing an attachment,
1305                          * but should be enabled when viewing a message from the list, 
1306                          * or when viewing a search result.
1307                          */
1308                         if (!modest_msg_view_window_is_search_result (MODEST_MSG_VIEW_WINDOW(win))) {
1309                                 dimmed = !modest_msg_view_window_has_headers_model (MODEST_MSG_VIEW_WINDOW (win));
1310                         }
1311                 }
1312                 if (dimmed) 
1313                         modest_dimming_rule_set_notification (rule, _("emev_nc_unabletomove_item"));
1314         }
1315
1316         return dimmed;
1317 }
1318
1319 gboolean 
1320 modest_ui_dimming_rules_on_find_in_msg (ModestWindow *win, gpointer user_data)
1321 {
1322         ModestDimmingRule *rule = NULL;
1323         gboolean dimmed = FALSE;
1324
1325         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1326         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1327         rule = MODEST_DIMMING_RULE (user_data);
1328
1329         /* This could happen if we load the msg view window with a
1330            preview before loading the full message */
1331         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1332                 TnyMsg *msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1333                 if (!msg) {
1334                         return TRUE;
1335                 } else {
1336                         g_object_unref (msg);
1337                 }
1338         }
1339
1340         /* Check dimmed rule */ 
1341         dimmed = _transfer_mode_enabled (win);
1342         if (dimmed)
1343                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));     
1344
1345         return dimmed;
1346 }
1347
1348 gboolean 
1349 modest_ui_dimming_rules_on_paste (ModestWindow *win, gpointer user_data)
1350 {
1351         ModestDimmingRule *rule = NULL;
1352         TnyFolderType types[3];
1353         gboolean dimmed = FALSE;
1354         
1355         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1356         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1357         rule = MODEST_DIMMING_RULE (user_data);
1358
1359         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
1360         types[1] = TNY_FOLDER_TYPE_OUTBOX;
1361         types[2] = TNY_FOLDER_TYPE_SENT;
1362         
1363         /* Check dimmed rule */ 
1364         dimmed = _clipboard_is_empty (win);
1365         if (dimmed)
1366                 modest_dimming_rule_set_notification (rule, 
1367                                                       _CS("ecoc_ib_edwin_nothing_to_paste"));
1368         if (!dimmed) {
1369                 dimmed = _selected_folder_is_any_of_type (win, types, 3);
1370                 if (dimmed)
1371                         modest_dimming_rule_set_notification (rule, 
1372                                                               _CS("ckct_ib_unable_to_paste_here"));
1373         }
1374         if (!dimmed) {
1375                 dimmed = !_folder_view_has_focus (win);
1376                 if (dimmed)
1377                         modest_dimming_rule_set_notification (rule,
1378                                         _CS("ckct_ib_unable_to_paste_here"));
1379         }
1380         if (!dimmed) {
1381                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win), TRUE);
1382                 if (dimmed) 
1383                         modest_dimming_rule_set_notification (rule, 
1384                                                               _CS("ckct_ib_unable_to_paste_here"));
1385         }
1386         if (!dimmed) {
1387                 dimmed = _selected_folder_is_same_as_source (win);
1388                 if (dimmed)
1389                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_copy_target_error"));
1390         }
1391         if (!dimmed) {
1392                 dimmed = _selected_folder_has_subfolder_with_same_name (win);
1393                 if (dimmed)
1394                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_copy_target_error"));
1395         }
1396         
1397         return dimmed;
1398 }
1399
1400
1401 gboolean 
1402 modest_ui_dimming_rules_on_select_all (ModestWindow *win, gpointer user_data)
1403 {
1404         ModestDimmingRule *rule = NULL;
1405         gboolean dimmed = FALSE;
1406         GtkWidget *focused = NULL;
1407
1408         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
1409         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1410         rule = MODEST_DIMMING_RULE (user_data);
1411
1412         focused = gtk_window_get_focus (GTK_WINDOW (win));
1413
1414         /* Main window dimming rules */ 
1415         if (MODEST_IS_MAIN_WINDOW (win))
1416                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));
1417
1418         if (!dimmed && MODEST_IS_MAIN_WINDOW (win))
1419                 dimmed = _header_view_is_all_selected (MODEST_MAIN_WINDOW(win));
1420
1421         if (!dimmed && GTK_IS_ENTRY (focused)) {
1422                 const gchar *current_text;
1423                 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
1424                 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
1425         }
1426
1427         if (!dimmed && GTK_IS_TEXT_VIEW (focused)) {
1428                 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
1429                 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
1430         }
1431
1432         if (dimmed && MODEST_IS_ATTACHMENTS_VIEW (focused))
1433                 dimmed = FALSE;
1434         return dimmed;
1435 }
1436
1437 gboolean 
1438 modest_ui_dimming_rules_on_view_attachments (ModestWindow *win, gpointer user_data)
1439 {
1440         ModestDimmingRule *rule = NULL;
1441         gboolean dimmed = FALSE;
1442
1443         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1444         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1445         rule = MODEST_DIMMING_RULE (user_data);
1446
1447         /* Check dimmed rule */ 
1448         dimmed = _invalid_attach_selected (win, TRUE, TRUE, FALSE, rule);                       
1449
1450         if (!dimmed) {
1451                 dimmed = _purged_attach_selected (win, FALSE, NULL);
1452                 if (dimmed) {
1453                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1454                 }
1455         }
1456                 
1457         return dimmed;
1458 }
1459
1460 #ifdef MODEST_TOOLKIT_HILDON2
1461 static gboolean
1462 _not_valid_attachments (ModestWindow *win, gboolean save_not_remove)
1463 {
1464         gint n_attachments;
1465         TnyList *attachments;
1466         gboolean result = FALSE;
1467
1468         /* Get atachments */
1469         attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
1470         n_attachments = tny_list_get_length (attachments);
1471
1472         /* Check unique */              
1473         if (!result) {
1474                 result = n_attachments < 1;
1475         }
1476                 
1477         /* Check attached type (view operation not required) */
1478         if (!result)  {
1479                 gint n_valid = 0;
1480
1481                 TnyIterator *iter;
1482                 iter = tny_list_create_iterator (attachments);
1483                 while (!tny_iterator_is_done (iter)) {
1484                         gboolean is_valid = TRUE;
1485                         TnyMimePart *mime_part = TNY_MIME_PART (tny_iterator_get_current (iter));
1486                         TnyList *nested_list = tny_simple_list_new ();
1487                         tny_mime_part_get_parts (mime_part, nested_list);
1488
1489                         if (tny_mime_part_is_purged (mime_part)) {
1490                                 is_valid = FALSE;
1491                         }
1492                         
1493                         if (is_valid && modest_tny_mime_part_is_msg (mime_part)) {
1494                                 TnyMsg *window_msg;
1495                                 window_msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1496                                 if (window_msg) {
1497                                         if (save_not_remove && (TnyMimePart *) window_msg != mime_part) {
1498                                                 is_valid = FALSE;
1499                                         }
1500                                         g_object_unref (window_msg);
1501                                 }
1502                                 if (is_valid && save_not_remove && tny_list_get_length (nested_list) > 0) {
1503                                         is_valid = FALSE;
1504                                 }
1505                         }
1506                         g_object_unref (nested_list);
1507                         g_object_unref (mime_part);
1508                         tny_iterator_next (iter);
1509
1510                         if (is_valid) 
1511                                 n_valid++;
1512                 }
1513                 g_object_unref (iter);
1514                 result = (n_valid == 0);
1515         }
1516         g_object_unref (attachments);
1517         return result;
1518
1519 }
1520 #endif
1521
1522 gboolean 
1523 modest_ui_dimming_rules_on_save_attachments (ModestWindow *win, gpointer user_data)
1524 {
1525         ModestDimmingRule *rule = NULL;
1526         gboolean dimmed = FALSE;
1527
1528         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1529         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1530         rule = MODEST_DIMMING_RULE (user_data);
1531
1532         /* Check dimmed rule */ 
1533
1534 #ifdef MODEST_TOOLKIT_HILDON2
1535         dimmed = _not_valid_attachments (win, TRUE);
1536 #else
1537         dimmed = _invalid_attach_selected (win, FALSE, FALSE, FALSE, rule);
1538
1539         if (!dimmed) {
1540                 dimmed = _purged_attach_selected (win, TRUE, NULL);
1541                 if (dimmed) {
1542                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1543                 }
1544         }
1545 #endif
1546         return dimmed;
1547 }
1548
1549 gboolean 
1550 modest_ui_dimming_rules_on_remove_attachments (ModestWindow *win, gpointer user_data)
1551 {
1552         ModestDimmingRule *rule = NULL;
1553         const DimmedState *state = NULL;
1554         gboolean dimmed = FALSE;
1555
1556         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
1557         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1558         rule = MODEST_DIMMING_RULE (user_data);
1559         state = modest_window_get_dimming_state (win);          
1560
1561         /* Check in main window if there's only one message selected */
1562         if (MODEST_IS_MAIN_WINDOW (win)) {
1563                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW (win), TRUE, rule);
1564         }
1565
1566         /* Check in view window if there's any attachment selected */
1567         if (!dimmed && MODEST_IS_MSG_VIEW_WINDOW (win)) {
1568                 dimmed = _invalid_attach_selected (win, FALSE, FALSE, TRUE, NULL);
1569                 if (dimmed)
1570                         modest_dimming_rule_set_notification (rule, _("FIXME:no attachment selected"));
1571         }
1572
1573         if (!dimmed) {
1574
1575                 dimmed = _selected_msg_sent_in_progress (win);
1576                 if (dimmed) {
1577                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
1578                 }
1579         }
1580
1581         /* cannot purge in editable drafts nor pop folders */
1582         if (!dimmed) {
1583                 dimmed = _invalid_folder_for_purge (win, rule);
1584                 if (dimmed)
1585                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
1586         }
1587
1588         /* Check if the selected message in main window has attachments */
1589         if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) {
1590                 if (state)
1591                         dimmed = !(state->any_has_attachments);
1592                 if (dimmed)
1593                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
1594         }
1595
1596         /* Check if all attachments are already purged */
1597         if (!dimmed) {
1598                 dimmed = _purged_attach_selected (win, TRUE, rule);
1599         }
1600
1601         /* Check if the message is already downloaded */
1602         if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) {
1603                 dimmed = !_msg_download_completed (MODEST_MAIN_WINDOW (win));
1604                 if (dimmed)
1605                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1606         }
1607
1608         return dimmed;
1609 }
1610
1611 gboolean 
1612 modest_ui_dimming_rules_on_undo (ModestWindow *win, gpointer user_data)
1613 {
1614         ModestDimmingRule *rule = NULL;
1615         gboolean dimmed = FALSE;
1616         
1617         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1618         rule = MODEST_DIMMING_RULE (user_data);
1619
1620         /* Check dimmed rule */ 
1621         if (MODEST_IS_MAIN_WINDOW (win)) {
1622                 dimmed = _clipboard_is_empty (win); 
1623                 if (dimmed)
1624                         modest_dimming_rule_set_notification (rule, "");
1625         }
1626
1627         if (!dimmed && MODEST_IS_MSG_EDIT_WINDOW (win)) {
1628                 dimmed = !modest_msg_edit_window_can_undo (MODEST_MSG_EDIT_WINDOW (win));
1629         }
1630
1631         return dimmed;
1632 }
1633
1634 gboolean 
1635 modest_ui_dimming_rules_on_redo (ModestWindow *win, gpointer user_data)
1636 {
1637         ModestDimmingRule *rule = NULL;
1638         gboolean dimmed = FALSE;
1639         
1640         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1641         rule = MODEST_DIMMING_RULE (user_data);
1642
1643         /* Check dimmed rule */ 
1644         if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
1645                 dimmed = !modest_msg_edit_window_can_redo (MODEST_MSG_EDIT_WINDOW (win));
1646         }
1647                                 
1648         return dimmed;  
1649 }
1650
1651 gboolean 
1652 modest_ui_dimming_rules_on_cut (ModestWindow *win, gpointer user_data)
1653 {
1654         ModestDimmingRule *rule = NULL;
1655         const DimmedState *state = NULL;
1656         gboolean dimmed = FALSE;
1657         
1658         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1659         rule = MODEST_DIMMING_RULE (user_data);
1660         state = modest_window_get_dimming_state (win);
1661
1662         /* Check common dimming rules */
1663         dimmed = _invalid_clipboard_selected (win, rule);
1664
1665         /* Check window specific dimming rules */
1666         if (MODEST_IS_MAIN_WINDOW (win)) {
1667                 /* Get focused widget */
1668                 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (win));
1669                 
1670                 if (MODEST_IS_HEADER_VIEW (focused)) {
1671                         if (!dimmed) { 
1672                                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
1673                                 if (dimmed)
1674                                         modest_dimming_rule_set_notification (rule, "");
1675                         }
1676                         if (!dimmed) {
1677                                 dimmed = _selected_msg_sent_in_progress (win);
1678                                 if (dimmed)
1679                                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_cut_mess"));
1680                         }
1681                         if (!dimmed) {
1682                                 if (state)
1683                                         dimmed = (state->already_opened_msg > 0) ? TRUE : FALSE;
1684                                 if(dimmed)
1685                                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_cut_mess"));
1686                         }
1687                 }
1688                 else if (MODEST_IS_FOLDER_VIEW (focused)) {
1689                         TnyFolderType types[3];
1690                         
1691                         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
1692                         types[1] = TNY_FOLDER_TYPE_OUTBOX;
1693                         types[2] = TNY_FOLDER_TYPE_SENT;
1694                         
1695                         /* Apply folder rules */        
1696                         if (!dimmed) {
1697                                 dimmed = _selected_folder_not_deletable (MODEST_MAIN_WINDOW(win));
1698                                 if (dimmed)
1699                                         modest_dimming_rule_set_notification (rule, _("emev_nc_unabletomove_items"));
1700                         }
1701                         if (!dimmed) {
1702                                 dimmed = _selected_folder_is_root_or_inbox (MODEST_MAIN_WINDOW(win));
1703                                 if (dimmed)
1704                                         modest_dimming_rule_set_notification (rule, _("emev_nc_unabletomove_items"));
1705                         }
1706                         if (!dimmed) {
1707                                 dimmed = _selected_folder_is_any_of_type (win, types, 3);
1708                                 if (dimmed)
1709                                         modest_dimming_rule_set_notification (rule, _("emev_nc_unabletomove_items"));
1710                         }
1711                 }
1712         }
1713
1714         return dimmed;
1715 }
1716
1717 gboolean 
1718 modest_ui_dimming_rules_on_copy (ModestWindow *win, gpointer user_data)
1719 {
1720         ModestDimmingRule *rule = NULL;
1721         const DimmedState *state = NULL;
1722         gboolean dimmed = FALSE;
1723
1724         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1725         rule = MODEST_DIMMING_RULE (user_data);
1726         state = modest_window_get_dimming_state (win);
1727
1728         /* Check common dimming rules */
1729         dimmed = _invalid_clipboard_selected (win, rule);       
1730         
1731         /* Check window specific dimming rules */
1732         if (MODEST_IS_MAIN_WINDOW (win)) {
1733                 /* Get focused widget */
1734                 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (win));
1735                 
1736                 if (MODEST_IS_HEADER_VIEW (focused)) {
1737                         if (!dimmed) {
1738                                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
1739                                 if (dimmed)
1740                                         modest_dimming_rule_set_notification (rule, "");
1741                         }               
1742                         if (!dimmed) {
1743                                 dimmed = _selected_msg_sent_in_progress (win);
1744                                 if (dimmed)
1745                                         modest_dimming_rule_set_notification (rule, _(""));
1746                         }
1747                         if (!dimmed) {
1748                                 if (state)
1749                                         dimmed = (state->already_opened_msg > 0) ? TRUE : FALSE;
1750                                 if(dimmed)
1751                                         modest_dimming_rule_set_notification (rule, _(""));
1752                         }
1753                 }
1754                 else if (MODEST_IS_FOLDER_VIEW (focused)) {
1755                         TnyFolderType types[3];
1756                         
1757                         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
1758                         types[1] = TNY_FOLDER_TYPE_OUTBOX;
1759                         types[2] = TNY_FOLDER_TYPE_SENT;
1760
1761                         if (!dimmed) {
1762                                 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
1763                                 if (dimmed)
1764                                         modest_dimming_rule_set_notification (rule, _(""));
1765                         }
1766                         if (!dimmed) {
1767                                 dimmed = _selected_folder_is_any_of_type (win, types, 3);
1768                                 if (dimmed)
1769                                         modest_dimming_rule_set_notification (rule, _(""));
1770                         }
1771                 }
1772         }
1773                 
1774         return dimmed;
1775 }
1776
1777 gboolean 
1778 modest_ui_dimming_rules_on_set_style (ModestWindow *win, gpointer user_data)
1779 {
1780         ModestDimmingRule *rule = NULL;
1781         gboolean dimmed = FALSE;
1782         
1783         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1784         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), TRUE);
1785         rule = MODEST_DIMMING_RULE (user_data);
1786
1787         /* Check common dimming rules */
1788         ModestMsgEditFormat format;
1789         format = modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (win));
1790
1791         dimmed = (format != MODEST_MSG_EDIT_FORMAT_HTML);
1792         if (dimmed)
1793                 modest_dimming_rule_set_notification (rule, _("mcen_ib_item_unavailable_plaintext"));
1794
1795         if (!dimmed) {
1796                 GtkWidget *body;
1797                 body = modest_msg_edit_window_get_child_widget (MODEST_MSG_EDIT_WINDOW (win),
1798                                                                 MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY);
1799                 
1800                 dimmed = ((body == NULL)||(!gtk_widget_is_focus (body)));
1801                 if (dimmed)
1802                         modest_dimming_rule_set_notification (rule, _("mcen_ib_move_cursor_to_message"));
1803         }
1804                
1805         
1806         return dimmed;
1807 }
1808
1809 gboolean 
1810 modest_ui_dimming_rules_on_zoom (ModestWindow *win, gpointer user_data)
1811 {
1812         ModestDimmingRule *rule = NULL;
1813         gboolean dimmed = FALSE;
1814         
1815         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1816         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), TRUE);
1817         rule = MODEST_DIMMING_RULE (user_data);
1818
1819         GtkWidget *body;
1820         body = modest_msg_edit_window_get_child_widget (MODEST_MSG_EDIT_WINDOW (win),
1821                                                         MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY);
1822         
1823         dimmed = ((body == NULL)||(!gtk_widget_is_focus (body)));
1824         if (dimmed)
1825                 modest_dimming_rule_set_notification (rule, _("mcen_ib_move_cursor_to_message"));
1826         
1827         return dimmed;
1828 }
1829
1830 gboolean 
1831 modest_ui_dimming_rules_on_editor_paste (ModestWindow *win, gpointer user_data)
1832 {
1833         ModestDimmingRule *rule = NULL;
1834         gboolean dimmed = FALSE;
1835         GtkWidget *focused = NULL;
1836         
1837         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1838         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), TRUE);
1839         rule = MODEST_DIMMING_RULE (user_data);
1840
1841         focused = gtk_window_get_focus (GTK_WINDOW (win));
1842
1843         dimmed = MODEST_IS_ATTACHMENTS_VIEW (focused);
1844         
1845         if (!dimmed) {
1846                 dimmed = GTK_IS_TOGGLE_BUTTON (focused);
1847         }
1848
1849         if (!dimmed) {
1850                 ModestEmailClipboard *e_clipboard = modest_runtime_get_email_clipboard ();
1851                 const gchar *clipboard_text = modest_msg_edit_window_get_clipboard_text (MODEST_MSG_EDIT_WINDOW (win));
1852
1853                 dimmed = modest_email_clipboard_cleared (e_clipboard) && 
1854                   ((clipboard_text == NULL) || (clipboard_text[0] == '\0'));
1855         }
1856         
1857         return dimmed;
1858 }
1859
1860 gboolean 
1861 modest_ui_dimming_rules_on_editor_remove_attachment (ModestWindow *win, gpointer user_data)
1862 {
1863         ModestDimmingRule *rule = NULL;
1864         gboolean dimmed = FALSE;
1865         TnyList *selected_attachments = NULL;
1866         gint n_att_selected = 0;
1867         GtkWidget *attachments_view;
1868         
1869         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1870         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), TRUE);
1871         rule = MODEST_DIMMING_RULE (user_data);
1872
1873         attachments_view = modest_msg_edit_window_get_child_widget (
1874                                                                     MODEST_MSG_EDIT_WINDOW (win),
1875                                                                     MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS);
1876         
1877 #ifdef MODEST_TOOLKIT_HILDON2
1878         selected_attachments = modest_attachments_view_get_attachments (
1879                                                                       MODEST_ATTACHMENTS_VIEW (attachments_view));
1880 #else
1881         selected_attachments = modest_attachments_view_get_selection (
1882                                                                       MODEST_ATTACHMENTS_VIEW (attachments_view));
1883 #endif
1884         n_att_selected = tny_list_get_length (selected_attachments);
1885         g_object_unref (selected_attachments);
1886         
1887         dimmed = (n_att_selected < 1);  
1888         
1889         return dimmed;
1890 }
1891
1892 gboolean
1893 modest_ui_dimming_rules_on_send (ModestWindow *win, gpointer user_data)
1894 {
1895         ModestDimmingRule *rule = NULL;
1896         gboolean dimmed = FALSE;
1897         GtkWidget *body_field;
1898
1899         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1900         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), TRUE);
1901         rule = MODEST_DIMMING_RULE (user_data);
1902
1903         body_field = modest_msg_edit_window_get_child_widget (MODEST_MSG_EDIT_WINDOW (win),
1904                                                               MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY);
1905
1906         if (!dimmed) {
1907                 GtkWidget *to_field, *cc_field, *bcc_field;
1908                 GtkTextBuffer * to_buffer, *cc_buffer, *bcc_buffer;
1909                 cc_field = modest_msg_edit_window_get_child_widget (MODEST_MSG_EDIT_WINDOW (win),
1910                                                                     MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC);
1911                 to_field = modest_msg_edit_window_get_child_widget (MODEST_MSG_EDIT_WINDOW (win),
1912                                                                     MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO);
1913                 bcc_field = modest_msg_edit_window_get_child_widget (MODEST_MSG_EDIT_WINDOW (win),
1914                                                                      MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC);
1915                 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (to_field));
1916                 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (cc_field));
1917                 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (bcc_field));
1918
1919                 dimmed = ((gtk_text_buffer_get_char_count (to_buffer) +
1920                            gtk_text_buffer_get_char_count (cc_buffer) +
1921                            gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
1922
1923                 if (!dimmed) {
1924                         if (modest_text_utils_no_recipient (to_buffer) &&
1925                             modest_text_utils_no_recipient (cc_buffer) &&
1926                             modest_text_utils_no_recipient (bcc_buffer))
1927                                 dimmed = TRUE;
1928                 }
1929
1930                 if (dimmed)
1931                         modest_dimming_rule_set_notification (rule, _("mcen_ib_add_recipients_first"));
1932         }
1933         
1934         return dimmed;
1935 }
1936
1937 gboolean 
1938 modest_ui_dimming_rules_on_view_previous (ModestWindow *win, gpointer user_data)
1939 {
1940         ModestDimmingRule *rule = NULL;
1941         gboolean dimmed = FALSE;
1942         
1943         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1944         rule = MODEST_DIMMING_RULE (user_data);
1945
1946         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1947
1948         /* Check dimmed rule */
1949         dimmed = _transfer_mode_enabled (win);
1950         if (dimmed)
1951                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
1952         
1953         if (!dimmed) {
1954                 dimmed = modest_msg_view_window_first_message_selected (
1955                                 MODEST_MSG_VIEW_WINDOW(win));
1956                 modest_dimming_rule_set_notification (rule, NULL);
1957         }
1958
1959         return dimmed;
1960 }
1961
1962 gboolean 
1963 modest_ui_dimming_rules_on_view_next (ModestWindow *win, gpointer user_data)
1964 {
1965         ModestDimmingRule *rule = NULL;
1966         gboolean dimmed = FALSE;
1967
1968         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1969         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1970         rule = MODEST_DIMMING_RULE (user_data);
1971
1972         /* Check dimmed rule */ 
1973         dimmed = _transfer_mode_enabled (win);                  
1974         if (dimmed)
1975                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
1976         
1977         if (!dimmed) {
1978                 dimmed = modest_msg_view_window_last_message_selected (MODEST_MSG_VIEW_WINDOW (win));
1979                 modest_dimming_rule_set_notification (rule, NULL);
1980         }
1981
1982         return dimmed;
1983 }
1984
1985
1986 gboolean
1987 modest_ui_dimming_rules_on_tools_smtp_servers (ModestWindow *win, gpointer user_data)
1988 {
1989         gboolean dimmed;
1990         ModestAccountMgr *mgr;
1991
1992         mgr = modest_runtime_get_account_mgr();
1993         dimmed = !modest_account_mgr_has_accounts(mgr, TRUE);
1994
1995         /* Dimm it if we only have metaaccounts */
1996         if (!dimmed) {
1997                 ModestProtocolRegistry *reg = modest_runtime_get_protocol_registry ();
1998                 GSList *account_names = modest_account_mgr_account_names (mgr, TRUE);
1999
2000                 if (account_names) {
2001                         ModestProtocolType store_protocol;
2002                         gboolean found = FALSE;
2003                         GSList *iter = account_names;
2004                         const gchar *tag = MODEST_PROTOCOL_REGISTRY_MULTI_MAILBOX_PROVIDER_PROTOCOLS;
2005
2006                         while (iter && !found) {
2007                                 gchar* account_name;
2008
2009                                 account_name = (gchar *) iter->data;
2010                                 store_protocol = modest_account_mgr_get_store_protocol (mgr, account_name);
2011
2012                                 if (!modest_protocol_registry_protocol_type_has_tag (reg, store_protocol, tag))
2013                                         found = TRUE;
2014                                 else
2015                                         iter = g_slist_next (iter);
2016                         }
2017                         modest_account_mgr_free_account_names (account_names);
2018                         dimmed = !found;
2019                 }
2020         }
2021
2022         return dimmed;
2023 }
2024
2025 gboolean
2026 modest_ui_dimming_rules_on_cancel_sending (ModestWindow *win, gpointer user_data)
2027 {
2028         ModestDimmingRule *rule = NULL;
2029         TnyFolderType types[1];
2030         const DimmedState *state = NULL;
2031         gboolean dimmed = FALSE;
2032
2033         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2034         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
2035         rule = MODEST_DIMMING_RULE (user_data);
2036         state = modest_window_get_dimming_state (win);
2037
2038         types[0] = TNY_FOLDER_TYPE_OUTBOX; 
2039
2040         /* Check dimmed rules */        
2041         dimmed = !_selected_folder_is_any_of_type (win, types, 1);
2042         if (dimmed) 
2043                 modest_dimming_rule_set_notification (rule, "");        
2044         if (!dimmed) {
2045                 if (state)
2046                         dimmed = !state->sent_in_progress;
2047                 if (dimmed)
2048                         modest_dimming_rule_set_notification (rule, "");
2049         }
2050
2051         return dimmed;
2052 }
2053
2054 gboolean 
2055 modest_ui_dimming_rules_on_cancel_sending_all (ModestWindow *win, gpointer user_data)
2056 {
2057         /* We dim if no msg send is in progress (and then cancelling send all has no
2058          * effect */
2059         return !_msgs_send_in_progress ();
2060 }
2061
2062 gboolean 
2063 modest_ui_dimming_rules_on_send_receive (ModestWindow *win, gpointer user_data)
2064 {
2065         ModestDimmingRule *rule = NULL;
2066         gboolean dimmed = FALSE;
2067         ModestAccountMgr *mgr;
2068         const gchar* account_name;
2069
2070         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
2071         rule = MODEST_DIMMING_RULE (user_data);
2072         mgr = modest_runtime_get_account_mgr();
2073
2074         /* Check dimmed rule */
2075         account_name = modest_window_get_active_account (win);
2076
2077         if (account_name)
2078                 dimmed = modest_account_mgr_account_is_busy (mgr, account_name);
2079         else
2080                 dimmed = TRUE;
2081
2082         if (dimmed)
2083                 modest_dimming_rule_set_notification (rule, _("mcen_nc_no_email_acnts_defined"));
2084
2085         return dimmed;
2086 }
2087
2088 gboolean 
2089 modest_ui_dimming_rules_on_send_receive_all (ModestWindow *win, gpointer user_data)
2090 {
2091         ModestDimmingRule *rule = NULL;
2092         gboolean dimmed = FALSE;
2093
2094         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
2095         rule = MODEST_DIMMING_RULE (user_data);
2096  
2097         /* Check dimmed rule */ 
2098         GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
2099         if (g_slist_length (account_names) < 1)
2100                 dimmed = TRUE;
2101         if (dimmed)
2102                 modest_dimming_rule_set_notification (rule, _("mcen_nc_no_email_acnts_defined"));
2103
2104         modest_account_mgr_free_account_names (account_names);
2105
2106         if (!dimmed) {
2107                 dimmed = _send_receive_in_progress (win);
2108         }
2109
2110         return dimmed;
2111 }
2112
2113 #ifdef MODEST_TOOLKIT_HILDON2
2114 gboolean
2115 modest_ui_dimming_rules_on_add_to_contacts (ModestWindow *win, gpointer user_data)
2116 {
2117         GSList *recipients = NULL;
2118         gboolean has_recipients_to_add;
2119
2120         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
2121
2122         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2123                 TnyMsg *msg;
2124
2125                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2126
2127                 /* Message is loaded asynchronously, so this could happen */
2128                 if (!msg) {
2129                         TnyHeader *header;
2130
2131                         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2132                         if (!header)
2133                                 return TRUE;
2134
2135                         recipients = modest_tny_msg_header_get_all_recipients_list (header);
2136                         g_object_unref (header);
2137                 } else {
2138                         recipients = modest_tny_msg_get_all_recipients_list (msg);
2139                         g_object_unref (msg);
2140                 }
2141         } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
2142                 /* Check if there are pending addresses to add */
2143                 return !modest_msg_edit_window_has_pending_addresses ((ModestMsgEditWindow *) win);
2144         }
2145
2146         has_recipients_to_add = FALSE;
2147
2148         if (recipients) {
2149                 GSList *node;
2150                 for (node = recipients; node != NULL; node = g_slist_next (node)) {
2151                         const gchar *recipient = (const gchar *) node->data;
2152                         if (modest_text_utils_validate_recipient (recipient, NULL)) {
2153                                 if (!modest_address_book_has_address (recipient)) {
2154                                         has_recipients_to_add = TRUE;
2155                                         break;
2156                                 }
2157                         }
2158                 }
2159                 g_slist_foreach (recipients, (GFunc) g_free, NULL);
2160                 g_slist_free (recipients);
2161         }
2162
2163         return !has_recipients_to_add;
2164 }
2165 #else
2166 gboolean
2167 modest_ui_dimming_rules_on_add_to_contacts (ModestWindow *win, gpointer user_data)
2168 {
2169         ModestDimmingRule *rule = NULL;
2170         gboolean dimmed = FALSE;
2171         GtkWidget *focused = NULL;
2172
2173         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
2174         rule = MODEST_DIMMING_RULE (user_data);
2175         focused = gtk_window_get_focus (GTK_WINDOW (win));
2176
2177         dimmed = !focused;
2178
2179         if (!dimmed) {
2180                 gchar *selection = NULL;
2181                 if (GTK_IS_TEXT_VIEW (focused)) {
2182                         GtkTextIter start, end;
2183                         GtkTextBuffer *buffer = NULL;
2184                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2185                         if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) {
2186                                 selection = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
2187                         }
2188                 } else if (GTK_IS_LABEL (focused)) {
2189                         selection = modest_text_utils_label_get_selection (GTK_LABEL (focused));
2190                 } else {
2191                         gboolean do_check = TRUE;
2192                         GtkClipboard *clipboard;
2193                         if (GTK_IS_HTML (focused)) {
2194                                 const gchar *sel;
2195                                 int len = -1;
2196                                 sel = gtk_html_get_selection_html (GTK_HTML (focused), &len);
2197                                 do_check = !((sel == NULL) || (sel[0] == '\0'));
2198                         } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2199                                 do_check = FALSE;
2200                         }
2201                         if (do_check) {
2202                                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2203                                 selection = gtk_clipboard_wait_for_text (clipboard);
2204                         } else {
2205                                 selection = NULL;
2206                         }
2207                 }
2208                 dimmed = !((selection != NULL) && (modest_text_utils_validate_recipient (selection, NULL)));
2209         }
2210
2211         return dimmed;
2212 }
2213 #endif
2214
2215 /* *********************** static utility functions ******************** */
2216
2217
2218 static gboolean
2219 _selected_folder_not_writeable (ModestMainWindow *win,
2220                                 gboolean for_paste)
2221 {
2222         GtkWidget *folder_view = NULL;
2223         TnyFolderStore *parent_folder = NULL;
2224         ModestEmailClipboard *clipboard = NULL;
2225         ModestTnyFolderRules rules;
2226         gboolean is_local_acc = FALSE;
2227         gboolean xfer_folders = FALSE;
2228         gboolean result = FALSE;
2229
2230         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2231
2232         /* Get folder view */
2233         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2234                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2235         /* If no folder view, always dimmed */
2236         if (!folder_view)
2237                 return TRUE;
2238         
2239         /* Get selected folder as parent of new folder to create */
2240         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2241         if (!(parent_folder && TNY_IS_FOLDER(parent_folder))) {
2242                 /* If it's the local account and its transfering folders, then do not dim */            
2243                 if (TNY_IS_ACCOUNT (parent_folder)) {
2244                         is_local_acc = modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent_folder));
2245                         if (for_paste) {
2246                                 clipboard = modest_runtime_get_email_clipboard ();
2247                                 xfer_folders = modest_email_clipboard_folder_copied (clipboard);
2248                         }
2249                 }
2250
2251                 if (for_paste) 
2252                         result = !(is_local_acc && xfer_folders); 
2253                 else
2254                         result = !is_local_acc;
2255                 goto frees;             
2256         }
2257         
2258         /* Check dimmed rule */ 
2259         rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
2260         result = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
2261
2262         /* free */
2263  frees:
2264         if (parent_folder != NULL)
2265                 g_object_unref (parent_folder);
2266
2267         return result;
2268 }
2269
2270 static gboolean
2271 _selected_folder_not_deletable (ModestMainWindow *win)
2272 {
2273         GtkWidget *folder_view = NULL;
2274         TnyFolderStore *parent_folder = NULL;
2275         ModestTnyFolderRules rules;
2276         gboolean result = FALSE;
2277
2278         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2279
2280         /* Get folder view */
2281         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2282                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2283         /* If no folder view, always dimmed */
2284         if (!folder_view)
2285                 return TRUE;
2286         
2287         /* Get selected folder as parent of new folder to create */
2288         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2289         if (!(parent_folder && TNY_IS_FOLDER(parent_folder))) {
2290                 result = TRUE;
2291                 goto frees;             
2292         }
2293         
2294         /* Check dimmed rule */ 
2295         rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
2296         result = rules & MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE;
2297
2298         /* free */
2299  frees:
2300         if (parent_folder != NULL)
2301                 g_object_unref (parent_folder);
2302
2303         return result;
2304 }
2305
2306 static gboolean
2307 _selected_folder_not_moveable (ModestMainWindow *win)
2308 {
2309         GtkWidget *folder_view = NULL;
2310         TnyFolderStore *parent_folder = NULL;
2311         ModestTnyFolderRules rules;
2312         gboolean result = FALSE;
2313
2314         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2315
2316         /* Get folder view */
2317         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2318                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2319         /* If no folder view, always dimmed */
2320         if (!folder_view)
2321                 return TRUE;
2322         
2323         /* Get selected folder as parent of new folder to create */
2324         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2325         if (!(parent_folder && TNY_IS_FOLDER(parent_folder))) {
2326                 result = TRUE;
2327                 goto frees;             
2328         }
2329         
2330         /* Check dimmed rule */ 
2331         rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
2332         result = rules & MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE;
2333
2334         /* free */
2335  frees:
2336         if (parent_folder != NULL)
2337                 g_object_unref (parent_folder);
2338
2339         return result;
2340 }
2341
2342 static gboolean
2343 _selected_folder_not_renameable (ModestMainWindow *win)
2344 {
2345         GtkWidget *folder_view = NULL;
2346         TnyFolderStore *parent_folder = NULL;
2347         ModestTnyFolderRules rules;
2348         gboolean result = FALSE;
2349
2350         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2351
2352         /* Get folder view */
2353         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2354                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2355         /* If no folder view, always dimmed */
2356         if (!folder_view)
2357                 return TRUE;
2358         
2359         /* Get selected folder as parent of new folder to create */
2360         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2361         if (!(parent_folder && TNY_IS_FOLDER(parent_folder))) {
2362                 result = TRUE;
2363                 goto frees;             
2364         }
2365         
2366         /* Check dimmed rule */ 
2367         rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
2368         result = rules & MODEST_FOLDER_RULES_FOLDER_NON_RENAMEABLE;
2369
2370         /* free */
2371  frees:
2372         if (parent_folder != NULL)
2373                 g_object_unref (parent_folder);
2374
2375         return result;
2376 }
2377
2378 static gboolean
2379 _selected_folder_is_root_or_inbox (ModestMainWindow *win)
2380 {
2381         TnyFolderType types[2];
2382         gboolean result = FALSE;
2383
2384         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2385
2386         types[0] = TNY_FOLDER_TYPE_ROOT; 
2387         types[1] = TNY_FOLDER_TYPE_INBOX; 
2388
2389         /* Check folder type */
2390         result = _selected_folder_is_any_of_type (MODEST_WINDOW(win), types, 2);
2391
2392         /* Check pop and MMC accounts */
2393         if (!result) {
2394                 result = _selected_folder_is_root (win);
2395         }
2396                 
2397         return result;
2398 }
2399
2400
2401 static gboolean
2402 _selected_folder_is_root (ModestMainWindow *win)
2403 {
2404         TnyFolderType types[1];
2405         gboolean result = FALSE;
2406
2407         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2408
2409         /* All accounts are root items: */
2410         GtkWidget *folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2411                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2412         if (folder_view) {                                      
2413                 gboolean is_account = FALSE;
2414                 TnyFolderStore *folder_store = 
2415                         modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2416                 if (folder_store) {
2417                         is_account = TNY_IS_ACCOUNT (folder_store);
2418
2419                         g_object_unref (folder_store);
2420                         folder_store = NULL;
2421                 }
2422                 
2423                 if (is_account)
2424                         return TRUE;
2425         }
2426                 
2427         /* Try something more precise: */
2428         types[0] = TNY_FOLDER_TYPE_ROOT; 
2429
2430         /* Check folder type */
2431         result = _selected_folder_is_any_of_type (MODEST_WINDOW(win), types, 1);
2432                 
2433         return result;
2434 }
2435
2436 static gboolean
2437 _header_view_is_all_selected (ModestMainWindow *win)
2438 {
2439         const DimmedState *state = NULL;
2440
2441         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
2442
2443         state = modest_window_get_dimming_state (MODEST_WINDOW(win));
2444
2445         return (state) ? state->all_selected : TRUE;
2446 }
2447
2448 static gboolean
2449 _selected_folder_is_empty (ModestMainWindow *win)
2450 {
2451         GtkWidget *folder_view = NULL, *header_view = NULL;
2452         TnyFolderStore *folder = NULL;
2453         gboolean result = FALSE;
2454
2455         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2456
2457         /* Get folder view */
2458         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2459                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2460
2461         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2462                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2463
2464         /* If no folder view, always dimmed */
2465         if (!folder_view || !header_view)
2466                 return TRUE;
2467         
2468         /* Get selected folder as parent of new folder to create */
2469         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2470         if (!(folder && TNY_IS_FOLDER(folder))) {
2471                 if (folder)
2472                         g_object_unref (folder);
2473                 return TRUE;
2474         }
2475         
2476         /* Check folder type */
2477         if (modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)) ||
2478             tny_folder_get_all_count (TNY_FOLDER (folder)) == 0)
2479                 result = TRUE;
2480
2481         /* free */
2482         g_object_unref (folder);
2483
2484         return result;
2485 }
2486
2487 static gboolean
2488 _folder_view_has_focus (ModestWindow *win)
2489 {
2490         GtkWidget *folder_view = NULL;
2491
2492         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2493
2494         /* Get folder view */
2495         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2496                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2497         if (!folder_view)
2498                 return FALSE;
2499         
2500         if (gtk_widget_is_focus(folder_view))
2501                 return TRUE;
2502
2503         return FALSE;
2504 }
2505
2506 static gboolean
2507 _selected_folder_is_same_as_source (ModestWindow *win)
2508 {
2509         ModestEmailClipboard *clipboard = NULL;
2510         GtkWidget *folder_view = NULL;
2511         TnyFolderStore *folder = NULL;
2512         gboolean result = FALSE;
2513
2514         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2515
2516         /* Get folder view */
2517         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2518                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2519         if (!folder_view)
2520                 return FALSE;
2521         
2522         /* Get selected folder as destination folder */
2523         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2524         if (!(folder && TNY_IS_FOLDER(folder))) {
2525                 result = FALSE;
2526                 goto frees;
2527         }
2528         
2529         /* Check clipboard is cleared */
2530         clipboard = modest_runtime_get_email_clipboard ();
2531         if (modest_email_clipboard_cleared (clipboard)) {
2532                 result = FALSE;
2533                 goto frees;
2534         }
2535                 
2536         /* Check source folder */
2537         result = modest_email_clipboard_check_source_folder (clipboard, TNY_FOLDER (folder));
2538         
2539         /* Free */
2540  frees:
2541         g_object_unref (folder);
2542         
2543         return result;
2544 }
2545
2546 static gboolean
2547 _selected_folder_is_any_of_type (ModestWindow *win,
2548                                  TnyFolderType types[], 
2549                                  guint ntypes)
2550 {
2551         GtkWidget *folder_view = NULL;
2552         TnyFolderStore *folder = NULL;
2553         TnyFolderType folder_type;
2554         guint i=0;
2555         gboolean result = FALSE;
2556
2557         /*Get current folder */
2558         if (MODEST_IS_MAIN_WINDOW(win)) {
2559
2560                 /* Get folder view */
2561                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
2562                                                                    MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2563                 /* If no folder view, always dimmed */
2564                 if (!folder_view)
2565                         return FALSE;
2566         
2567                 /* Get selected folder as parent of new folder to create */
2568                 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2569
2570                 if (!(folder && TNY_IS_FOLDER(folder))) {
2571                         if (folder)
2572                                 g_object_unref (folder);
2573                         return FALSE;
2574                 }
2575                 
2576                 /* Check folder type */
2577                 result = _folder_is_any_of_type (TNY_FOLDER(folder), types, ntypes);
2578         }
2579         else if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
2580                 folder_type = modest_msg_view_window_get_folder_type (MODEST_MSG_VIEW_WINDOW (win));
2581                 for (i=0; i < ntypes; i++) {
2582                         result = result || folder_type == types[i];
2583                 }
2584         }
2585
2586
2587         /* free */
2588         if (folder)
2589                 g_object_unref (folder);
2590
2591         return result;  
2592 }
2593
2594 static gboolean
2595 _folder_is_any_of_type (TnyFolder *folder,
2596                         TnyFolderType types[], 
2597                         guint ntypes)
2598 {
2599         TnyFolderType folder_type;
2600         gboolean result = FALSE;
2601         guint i;
2602
2603         g_return_val_if_fail (TNY_IS_FOLDER(folder), FALSE);
2604
2605         /* Get folder type */
2606         folder_type = modest_tny_folder_guess_folder_type (folder);
2607         if (folder_type == TNY_FOLDER_TYPE_INVALID)
2608                 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2609         
2610         /* Check foler type */
2611         for (i=0; i < ntypes; i++) {
2612                 result = result || folder_type == types[i];
2613         }
2614
2615         return result;
2616 }
2617
2618 static gboolean
2619 _clipboard_is_empty (ModestWindow *win)
2620 {
2621         gboolean result = FALSE;
2622         
2623         if (MODEST_IS_MAIN_WINDOW (win)) {
2624                 ModestEmailClipboard *clipboard = NULL;
2625                 clipboard = modest_runtime_get_email_clipboard ();
2626                 if (modest_email_clipboard_cleared (clipboard)) 
2627                  result = TRUE;  
2628         }
2629
2630         return result;
2631 }
2632
2633 static gboolean
2634 _invalid_clipboard_selected (ModestWindow *win,
2635                              ModestDimmingRule *rule) 
2636 {
2637         gboolean result = FALSE;
2638         GtkWidget *focused = NULL;
2639
2640         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
2641
2642         /* Get focuesed widget */
2643         focused = gtk_window_get_focus (GTK_WINDOW (win));
2644
2645         if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
2646                 gboolean has_selection = FALSE;
2647                 if (GTK_IS_TEXT_VIEW (focused)) {
2648                         GtkTextBuffer *buffer = NULL;
2649                         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2650                         has_selection = modest_text_utils_buffer_selection_is_valid (buffer);
2651                 } else if (GTK_IS_EDITABLE (focused)) {
2652                         has_selection = gtk_editable_get_selection_bounds (GTK_EDITABLE (focused), NULL, NULL);
2653                 }
2654                 result = !has_selection;
2655         } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2656                 if (focused) {
2657                         MODEST_DEBUG_BLOCK (g_debug ("FOCUSED %s", g_type_name (G_TYPE_FROM_INSTANCE (focused))););
2658                         if (GTK_IS_LABEL (focused) && 
2659                             !gtk_label_get_selection_bounds (GTK_LABEL (focused), NULL, NULL)) {
2660                                 result = TRUE;
2661                         } else if (GTK_IS_TEXT_VIEW (focused)) {
2662                                 GtkTextBuffer *buffer;
2663                                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2664                                 result = !gtk_text_buffer_get_has_selection (buffer);
2665                         } else if (GTK_IS_HTML (focused)) {
2666                                 const gchar *sel;
2667                                 int len = -1;
2668                                 sel = gtk_html_get_selection_html (GTK_HTML (focused), &len);
2669                                 result = ((sel == NULL) || (sel[0] == '\0'));
2670                         } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2671                                 result = TRUE;
2672                         } else {
2673                                 GtkClipboard *clipboard;
2674                                 gchar *selection;
2675
2676                                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
2677                                 /* Get clipboard selection*/
2678                                 selection = gtk_clipboard_wait_for_text (clipboard);
2679                                 /* Check dimming */
2680                                 result = (selection == NULL);
2681                                 g_free (selection);
2682                         } 
2683                 } else {
2684                         result = TRUE;
2685                 }
2686                 
2687                 if (result)
2688                         modest_dimming_rule_set_notification (rule, "");
2689                 
2690         }               
2691         else if (MODEST_IS_MAIN_WINDOW (win)) {
2692                 const DimmedState *state = NULL;
2693
2694                 /* Check dimming */
2695                 state = modest_window_get_dimming_state (win);
2696                 if (state)
2697                         result = state->n_selected == 0;
2698                 if (result)
2699                         modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));                  
2700         }
2701         
2702         return result;
2703 }
2704
2705
2706 static gboolean
2707 _invalid_attach_selected (ModestWindow *win,
2708                           gboolean unique,
2709                           gboolean for_view,
2710                           gboolean for_remove,
2711                           ModestDimmingRule *rule) 
2712 {
2713         TnyList *attachments;
2714         gint n_selected;
2715         TnyHeaderFlags flags;
2716         gboolean nested_attachments = FALSE;
2717         gboolean selected_messages = FALSE;
2718         gboolean result = FALSE;
2719
2720         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
2721
2722         if (MODEST_IS_MAIN_WINDOW (win)) {
2723                 flags = TNY_HEADER_FLAG_ATTACHMENTS;
2724                 if (!result) {
2725                         const DimmedState *state = NULL;
2726                         state = modest_window_get_dimming_state (win);
2727                         result = !state->any_has_attachments;
2728                 }
2729         }
2730         else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2731                 
2732                 /* Get selected atachments */
2733                 attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
2734                 n_selected = tny_list_get_length (attachments);
2735
2736                 /* Check unique */              
2737                 if (!result) {
2738                         if (unique) 
2739                                 result = n_selected != 1;
2740                         else
2741                                 
2742                                 result = n_selected < 1;
2743                 }
2744                 
2745                 /* Check attached type (view operation not required) */
2746                 if (!result && !for_view)  {
2747                         TnyIterator *iter;
2748                         iter = tny_list_create_iterator (attachments);
2749                         while (!tny_iterator_is_done (iter) && !result) {
2750 #ifdef MODEST_TOOLKIT_HILDON2
2751                                 gboolean not_selectable = FALSE;
2752 #endif
2753                                 TnyMimePart *mime_part = TNY_MIME_PART (tny_iterator_get_current (iter));
2754                                 TnyList *nested_list = tny_simple_list_new ();
2755                                 tny_mime_part_get_parts (mime_part, nested_list);
2756
2757                                 if (!for_remove && modest_tny_mime_part_is_msg (mime_part)) {
2758                                         TnyMsg *window_msg;
2759                                         window_msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2760                                         if ((TnyMimePart *) window_msg != mime_part) {
2761                                                 selected_messages = TRUE;
2762 #ifdef MODEST_TOOLKIT_HILDON2
2763                                                 not_selectable = TRUE;
2764 #else
2765                                                 result = TRUE;
2766 #endif
2767                                         }
2768                                         g_object_unref (window_msg);
2769                                 }
2770                                 if (!for_remove && tny_list_get_length (nested_list) > 0) {
2771                                         nested_attachments = TRUE;
2772 #ifdef MODEST_TOOLKIT_HILDON2
2773                                         not_selectable = TRUE;
2774 #else
2775                                         result = TRUE;
2776 #endif
2777                                 }
2778 #ifdef MODEST_TOOLKIT_HILDON2
2779                                 if (not_selectable)
2780                                         n_selected --;
2781 #endif
2782                                 g_object_unref (nested_list);
2783                                 g_object_unref (mime_part);
2784                                 tny_iterator_next (iter);
2785                         }
2786                         g_object_unref (iter);
2787                 }
2788
2789                 /* No valid attachment available */
2790                 if (n_selected == 0)
2791                         result = TRUE;
2792                 
2793                 /* Set notifications */
2794                 if (result && rule != NULL) {
2795                         if (selected_messages) {
2796                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_save_attach_mail"));
2797                         } else if (nested_attachments) {
2798                                 modest_dimming_rule_set_notification (rule, _("FIXME:unable to save attachments with nested elements"));
2799                         } else if (n_selected == 0) {
2800                                 modest_dimming_rule_set_notification (rule, _("FIXME:no attachment selected"));
2801                         } else if (unique) {
2802                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_display_more"));
2803                         }
2804                 }
2805                 
2806                 /* Free */
2807                 g_object_unref (attachments);
2808         }
2809
2810         return result;
2811 }
2812
2813 static gboolean
2814 _purged_attach_selected (ModestWindow *win, gboolean all, ModestDimmingRule *rule) 
2815 {
2816         TnyList *attachments = NULL;
2817         TnyIterator *iter;
2818         gint purged = 0;
2819         gint n_attachments = 0;
2820         gboolean result = FALSE;
2821
2822         /* This should check if _all_ the attachments are already purged. If only some
2823          * of them are purged, then it does not cause dim as there's a confirmation dialog
2824          * for removing only local attachments */
2825
2826         /* Get selected atachments */
2827         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2828                 attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
2829         } else if (MODEST_IS_MAIN_WINDOW (win)) {
2830                 /* If we're in main window, we won't know if there are already purged attachments */
2831                 return FALSE;
2832         }
2833
2834         if (attachments == NULL)
2835                 return FALSE;
2836
2837         if (tny_list_get_length (attachments) == 0) {
2838                 g_object_unref (attachments);
2839                 return FALSE;
2840         }
2841
2842         iter = tny_list_create_iterator (attachments);
2843         while (!tny_iterator_is_done (iter)) {
2844                 TnyMimePart *mime_part = TNY_MIME_PART (tny_iterator_get_current (iter));
2845                 if (tny_mime_part_is_purged (mime_part)) {
2846                         purged++;
2847                 }
2848                 n_attachments++;
2849                 g_object_unref (mime_part);
2850                 tny_iterator_next (iter);
2851         }
2852         g_object_unref (iter);
2853                 
2854         /* Free */
2855         g_object_unref (attachments);
2856
2857         if (all)
2858                 result = (purged == n_attachments);
2859         else
2860                 result = (purged > 0);
2861
2862         /* This string no longer exists, refer to NB#75415 for more info
2863         if (result && (rule != NULL))
2864                 modest_dimming_rule_set_notification (rule, _("mail_ib_attachment_already_purged"));
2865         */
2866
2867         return result;
2868 }
2869
2870 static gboolean
2871 _invalid_msg_selected (ModestMainWindow *win,
2872                        gboolean unique,
2873                        ModestDimmingRule *rule) 
2874 {
2875         GtkWidget *folder_view = NULL;
2876         const DimmedState *state = NULL;
2877         gboolean result = FALSE;
2878         gint n_selected = 0;
2879
2880         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
2881         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (rule), FALSE);
2882
2883         state = modest_window_get_dimming_state (MODEST_WINDOW(win));
2884         if (state)
2885                 n_selected = state->n_selected;
2886
2887         /* Get folder view to check focus */
2888         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2889                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2890
2891         /* Check dimmed rule (TODO: check focus on widgets */   
2892         if (!result) {
2893                 result = ((n_selected == 0 ) ||
2894                           (gtk_widget_is_focus (folder_view)));
2895                 if (result)
2896                         modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));
2897         }
2898         if (!result && unique) {
2899                 result = n_selected > 1;
2900                 if (result)
2901                         modest_dimming_rule_set_notification (rule, _("mcen_ib_select_one_message"));
2902         }
2903
2904         return result;
2905 }
2906
2907
2908 static gboolean
2909 _msg_download_in_progress (ModestWindow *win)
2910 {
2911         gboolean result = FALSE;
2912
2913         g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
2914
2915         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2916                 result = modest_msg_view_window_toolbar_on_transfer_mode (MODEST_MSG_VIEW_WINDOW(win));
2917         }
2918         else if (MODEST_IS_MAIN_WINDOW (win)) {
2919                 result = modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(win));
2920         }
2921
2922         return result;
2923 }
2924
2925 static gboolean
2926 _msg_download_completed (ModestMainWindow *win)
2927 {
2928         const DimmedState *state = modest_window_get_dimming_state (MODEST_WINDOW(win));
2929         return (state) ? state->any_marked_as_cached : TRUE;
2930 }
2931
2932 static void 
2933 fill_list_of_caches (gpointer key, gpointer value, gpointer userdata)
2934 {
2935         GSList **send_queues = (GSList **) userdata;
2936         *send_queues = g_slist_prepend (*send_queues, value);
2937 }
2938
2939 static gboolean
2940 _selected_msg_sent_in_progress (ModestWindow *win)
2941 {
2942         const DimmedState *state = modest_window_get_dimming_state (win);
2943         return (state) ? state->sent_in_progress : TRUE;
2944 }
2945
2946
2947 static gboolean
2948 _invalid_folder_for_purge (ModestWindow *win, 
2949                            ModestDimmingRule *rule)
2950 {
2951         TnyFolder *folder = NULL;
2952         TnyAccount *account = NULL;
2953         gboolean result = FALSE;
2954
2955         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2956
2957                 /* Get folder and account of message */
2958                 TnyMsg *msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2959                 g_return_val_if_fail(msg != NULL, TRUE);                        
2960                 folder = tny_msg_get_folder (msg);      
2961                 g_object_unref (msg);
2962                 if (folder == NULL) {
2963                         result = TRUE;
2964                         goto frees;
2965                 }
2966         } else if (MODEST_IS_MAIN_WINDOW (win)) {
2967                 GtkWidget *folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2968                                                                               MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2969                 if (!folder_view)
2970                         return FALSE;
2971                 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2972                 /* Could be a folder store */
2973                 if (folder == NULL || ! TNY_IS_FOLDER (folder))
2974                         goto frees;             
2975         } else {
2976                 g_return_val_if_reached (FALSE);
2977         }
2978         account = modest_tny_folder_get_account (folder);
2979         if (account == NULL) goto frees;                        
2980                 
2981         /* Check account */
2982         if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (account))) {
2983                 TnyFolderType types[2];
2984                 types[0] = TNY_FOLDER_TYPE_DRAFTS;
2985                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
2986                 
2987                 if (_selected_folder_is_any_of_type (win, types, 2)) {
2988                         result = TRUE;
2989                 }
2990         } else {
2991                 ModestProtocolType protocol_type = modest_tny_account_get_protocol_type (TNY_ACCOUNT (account));
2992                 /* If it's a remote folder then dim */
2993                 if (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
2994                                                                     protocol_type,
2995                                                                     MODEST_PROTOCOL_REGISTRY_REMOTE_STORE_PROTOCOLS)) {
2996                         result = TRUE;
2997                 }
2998         }
2999         
3000 frees:
3001         if (folder != NULL)
3002                 g_object_unref (folder);
3003         if (account != NULL)
3004                 g_object_unref (account);
3005         
3006         return result;
3007 }
3008
3009 static gboolean
3010 _transfer_mode_enabled (ModestWindow *win)
3011 {
3012         gboolean result = FALSE;
3013
3014         /* Check dimming */
3015         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
3016                 result = modest_msg_view_window_transfer_mode_enabled (MODEST_MSG_VIEW_WINDOW (win));
3017         } else if (MODEST_IS_MAIN_WINDOW(win)) {
3018                 result = modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW (win));
3019 #ifdef MODEST_TOOLKIT_HILDON2
3020         } else if (MODEST_IS_FOLDER_WINDOW (win)) {
3021                 result = modest_folder_window_transfer_mode_enabled (MODEST_FOLDER_WINDOW (win));
3022         } else if (MODEST_IS_HEADER_WINDOW (win)) {
3023                 result = modest_header_window_transfer_mode_enabled (MODEST_HEADER_WINDOW (win));
3024 #endif
3025         } else {
3026                 g_warning("_transfer_mode_enabled called with wrong window type");
3027         }
3028
3029         return result;
3030 }
3031
3032 static gboolean
3033 _selected_folder_has_subfolder_with_same_name (ModestWindow *win)
3034 {
3035         GtkWidget *folder_view = NULL;
3036         TnyFolderStore *folder = NULL;
3037         ModestEmailClipboard *clipboard = NULL;
3038         const gchar *folder_name = NULL;
3039         gboolean result = FALSE;
3040
3041         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
3042
3043         /*Get current parent folder */
3044         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
3045                                                            MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3046         /* If no folder view, always dimmed */
3047         if (!folder_view) return FALSE;
3048         
3049         /* Get selected folder as parent of new folder to create */
3050         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));     
3051         if (!(folder && TNY_IS_FOLDER(folder))) goto frees;
3052         
3053         /* get modest clipboard and source folder */
3054         clipboard = modest_runtime_get_email_clipboard ();
3055         folder_name = modest_email_clipboard_get_folder_name (clipboard);
3056         if (folder_name == NULL) goto frees;
3057
3058         /* Check source subfolders names */
3059         result = modest_tny_folder_has_subfolder_with_name (folder, folder_name,
3060                                                             TRUE);
3061                 
3062         /* Free */
3063  frees:
3064         if (folder != NULL) 
3065                 g_object_unref (folder);
3066
3067
3068         return result;
3069 }
3070
3071 static gboolean
3072 _all_msgs_in_sending_status (ModestHeaderView *header_view)
3073 {
3074         GtkTreeModel *model;
3075         GtkTreeIter iter;
3076         gboolean all_sending = TRUE;
3077
3078         model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
3079         if (gtk_tree_model_get_iter_first (model, &iter)) {
3080                 do {
3081                         TnyHeader *header;
3082
3083                         gtk_tree_model_get (model, &iter,
3084                                             TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
3085                                             &header,
3086                                             -1);
3087
3088                         if (header) {
3089                                 if (modest_tny_all_send_queues_get_msg_status (header) !=
3090                                     MODEST_TNY_SEND_QUEUE_SENDING)
3091                                         all_sending = FALSE;
3092                                 g_object_unref (header);
3093                         }
3094
3095                 } while (all_sending && gtk_tree_model_iter_next (model, &iter));
3096         }
3097         return all_sending;
3098 }
3099
3100 gboolean 
3101 modest_ui_dimming_rules_on_save_to_drafts (ModestWindow *win, 
3102                                            gpointer user_data)
3103 {
3104         ModestDimmingRule *rule = NULL;
3105
3106         g_return_val_if_fail (MODEST_MSG_EDIT_WINDOW (win), FALSE);
3107         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
3108         rule = MODEST_DIMMING_RULE (user_data);
3109
3110         /* Check dimmed rule */ 
3111         return !modest_msg_edit_window_is_modified (MODEST_MSG_EDIT_WINDOW (win));
3112 }
3113
3114 gboolean
3115 modest_ui_dimming_rules_on_insert_image (ModestWindow *win,
3116                                          gpointer user_data)
3117 {
3118         g_return_val_if_fail (MODEST_MSG_EDIT_WINDOW (win), FALSE);
3119
3120         ModestMsgEditFormat format =
3121           modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (win));
3122
3123         return (format != MODEST_MSG_EDIT_FORMAT_HTML);
3124 }
3125
3126 static gboolean 
3127 _send_receive_in_progress (ModestWindow *win)
3128 {
3129         ModestMailOperationQueue *queue;
3130         GSList *op_list, *node;
3131         gboolean found_send_receive;
3132
3133         queue = modest_runtime_get_mail_operation_queue ();
3134         op_list = modest_mail_operation_queue_get_by_source (queue, G_OBJECT (win));
3135
3136         found_send_receive = FALSE;
3137         for (node = op_list; node != NULL; node = g_slist_next (node)) {
3138                 ModestMailOperation *op;
3139
3140                 op = (ModestMailOperation *) node->data;
3141                 if (modest_mail_operation_get_type_operation (op) == MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
3142                         found_send_receive = TRUE;
3143                         break;
3144                 }
3145         }
3146
3147         if (op_list) {
3148                 g_slist_foreach (op_list, (GFunc) g_object_unref, NULL);
3149                 g_slist_free (op_list);
3150         }
3151
3152         return found_send_receive;
3153 }
3154
3155 static gboolean
3156 _msgs_send_in_progress (void)
3157 {
3158         ModestCacheMgr *cache_mgr;
3159         GHashTable *send_queue_cache;
3160         ModestTnySendQueue *send_queue;
3161         GSList *send_queues = NULL, *node = NULL;
3162         gboolean found = FALSE;
3163
3164         cache_mgr = modest_runtime_get_cache_mgr ();
3165         send_queue_cache = modest_cache_mgr_get_cache (cache_mgr,
3166                                                        MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE);
3167
3168         g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues);
3169
3170         for (node = send_queues; node != NULL && !found; node = g_slist_next (node)) {
3171                 send_queue = MODEST_TNY_SEND_QUEUE (node->data);
3172
3173                 /* Check if msg uid is being processed inside send queue */
3174                 if (modest_tny_send_queue_sending_in_progress (send_queue)) {
3175                         found = TRUE;
3176                         break;
3177                 }
3178         }
3179
3180         g_slist_free (send_queues);
3181
3182         return found;
3183 }
3184
3185 /*****************************************************************************/
3186 /********************** HILDON2 only dimming rules ***************************/
3187 /*****************************************************************************/
3188
3189 #ifdef MODEST_TOOLKIT_HILDON2
3190 gboolean 
3191 modest_ui_dimming_rules_on_header_window_move_to (ModestWindow *win, gpointer user_data)
3192 {
3193         ModestDimmingRule *rule = NULL;
3194         gboolean dimmed = FALSE;
3195
3196         g_return_val_if_fail (MODEST_IS_HEADER_WINDOW(win), FALSE);
3197         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
3198         rule = MODEST_DIMMING_RULE (user_data);
3199
3200         /* Check dimmed rule */ 
3201         dimmed = _transfer_mode_enabled (win);
3202         if (dimmed)
3203                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
3204
3205         if (!dimmed)
3206                 dimmed = _forbid_outgoing_xfers (win);
3207
3208         if (!dimmed) {
3209                 GtkWidget *header_view;
3210                 TnyFolder *folder;
3211
3212                 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
3213                 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
3214                 if (folder) {
3215                         dimmed = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0) ||
3216                                 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view));
3217
3218                         if (!dimmed &&
3219                             (tny_folder_get_folder_type (TNY_FOLDER (folder)) == TNY_FOLDER_TYPE_OUTBOX)) {
3220                                 dimmed = _all_msgs_in_sending_status (MODEST_HEADER_VIEW (header_view));;
3221                         }
3222                         g_object_unref (folder);
3223                 }
3224         }
3225
3226         return dimmed;
3227 }
3228
3229 gboolean 
3230 modest_ui_dimming_rules_on_folder_window_move_to (ModestWindow *win, gpointer user_data)
3231 {
3232         ModestDimmingRule *rule = NULL;
3233         gboolean dimmed = FALSE;
3234
3235         g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW(win), FALSE);
3236         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
3237         rule = MODEST_DIMMING_RULE (user_data);
3238
3239         /* Check dimmed rule */ 
3240         dimmed = _transfer_mode_enabled (win);
3241         if (dimmed)
3242                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
3243
3244         if (!dimmed)
3245                 dimmed = _forbid_outgoing_xfers (win);
3246
3247         if (!dimmed && MODEST_IS_FOLDER_WINDOW (win)) {
3248                 ModestFolderView *folder_view;
3249                 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (win));
3250                 dimmed = !modest_folder_view_any_folder_fulfils_rules (folder_view,
3251                                                                        MODEST_FOLDER_RULES_FOLDER_NON_MOVEABLE);
3252         }
3253
3254         if (!dimmed) {
3255                 dimmed = _transfer_mode_enabled (win);
3256                 if (dimmed)
3257                         modest_dimming_rule_set_notification (rule, "");
3258         }
3259
3260         return dimmed;
3261 }
3262
3263 gboolean 
3264 modest_ui_dimming_rules_on_folder_window_delete (ModestWindow *win, gpointer user_data)
3265 {
3266         ModestDimmingRule *rule = NULL;
3267         gboolean dimmed = FALSE;
3268
3269         g_return_val_if_fail (MODEST_IS_FOLDER_WINDOW(win), FALSE);
3270         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
3271         rule = MODEST_DIMMING_RULE (user_data);
3272
3273         /* Check dimmed rule */ 
3274         dimmed = _transfer_mode_enabled (win);
3275         if (dimmed)
3276                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
3277
3278         if (MODEST_IS_FOLDER_WINDOW (win)) {
3279                 ModestFolderView *folder_view;
3280                 folder_view = modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (win));
3281                 dimmed = !modest_folder_view_any_folder_fulfils_rules (folder_view,
3282                                                                        MODEST_FOLDER_RULES_FOLDER_NON_DELETABLE);
3283         }
3284
3285         if (!dimmed) {
3286                 dimmed = _transfer_mode_enabled (win);
3287                 if (dimmed)
3288                         modest_dimming_rule_set_notification (rule, "");
3289         }
3290
3291         return dimmed;
3292 }
3293
3294 gboolean
3295 modest_ui_dimming_rules_on_edit_accounts (ModestWindow *win, gpointer user_data)
3296 {
3297         return !modest_account_mgr_has_accounts (modest_runtime_get_account_mgr (), TRUE);
3298 }
3299 #endif