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