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