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