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