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