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