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