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