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