* src/widgets/modest-main-window.h
[modest] / src / modest-ui-dimming-rules.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29  
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif /*HAVE_CONFIG_H*/
33
34 #include <string.h>
35 #include "modest-ui-dimming-rules.h"
36 #include "modest-dimming-rule.h"
37 #include "modest-tny-folder.h"
38 #include "modest-tny-account.h"
39 #include "modest-text-utils.h"
40 #include <widgets/modest-attachments-view.h>
41 #include <modest-runtime.h>
42 #include <tny-simple-list.h>
43
44
45 static gboolean _folder_is_any_of_type (TnyFolder *folder, TnyFolderType types[], guint ntypes);
46 static gboolean _invalid_msg_selected (ModestMainWindow *win, gboolean unique, ModestDimmingRule *rule);
47 static gboolean _invalid_attach_selected (ModestWindow *win, 
48                                           gboolean unique, gboolean for_view, gboolean for_remove,
49                                           ModestDimmingRule *rule);
50 static gboolean _purged_attach_selected (ModestWindow *win, gboolean all, ModestDimmingRule *rule);
51 static gboolean _clipboard_is_empty (ModestWindow *win);
52 static gboolean _invalid_clipboard_selected (ModestWindow *win, ModestDimmingRule *rule);
53 /* static gboolean _already_opened_msg (ModestWindow *win, guint *n_messages); */
54 /* static gboolean _selected_msg_marked_as (ModestMainWindow *win, TnyHeaderFlags mask, gboolean opposite, gboolean all); */
55 static gboolean _selected_folder_not_writeable (ModestMainWindow *win);
56 static gboolean _selected_folder_is_snd_level (ModestMainWindow *win);
57 static gboolean _selected_folder_is_any_of_type (ModestWindow *win, TnyFolderType types[], guint ntypes);
58 static gboolean _selected_folder_is_root_or_inbox (ModestMainWindow *win);
59 static gboolean _selected_folder_is_MMC_or_POP_root (ModestMainWindow *win);
60 static gboolean _selected_folder_is_root (ModestMainWindow *win);
61 static gboolean _selected_folder_is_empty (ModestMainWindow *win);
62 static gboolean _selected_folder_is_same_as_source (ModestWindow *win);
63 static gboolean _msg_download_in_progress (ModestMsgViewWindow *win);
64 static gboolean _msg_download_completed (ModestMainWindow *win);
65 static gboolean _selected_msg_sent_in_progress (ModestWindow *win);
66 static gboolean _sending_in_progress (ModestWindow *win);
67 /* static gboolean _message_is_marked_as_deleted (ModestMsgViewWindow *win); */
68 /* static gboolean _selected_message_is_marked_as_deleted (ModestMainWindow *win); */
69 static gboolean _invalid_folder_for_purge (ModestWindow *win, ModestDimmingRule *rule);
70 static gboolean _transfer_mode_enabled (ModestWindow *win);
71
72 static void  fill_list_of_caches (gpointer key, gpointer value, gpointer userdata);
73
74
75 static DimmedState *
76 _define_main_window_dimming_state (ModestMainWindow *window)
77 {
78         DimmedState *state = NULL;
79         GtkWidget *focused_widget = NULL;
80         GtkWidget *header_view = NULL;
81         TnyList *selected_headers = NULL;
82         TnyIterator *iter = NULL;
83         TnyHeader *header = NULL;
84         ModestCacheMgr *cache_mgr = NULL;
85         GHashTable *send_queue_cache = NULL;
86         ModestTnySendQueue *send_queue = NULL;
87         GSList *send_queues = NULL, *node = NULL;
88         ModestWindowMgr *mgr = NULL;
89         gboolean found = FALSE;
90         gchar *msg_uid = NULL;
91         TnyHeaderFlags flags;
92         gboolean all_deleted = TRUE;
93         gboolean all_seen = TRUE;
94         gboolean all_cached = TRUE;
95         gboolean all_has_attach = TRUE;
96
97         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(window), NULL);
98
99         /* Init state */
100         state = g_slice_new0 (DimmedState);
101         state->n_selected = 0;
102         state->already_opened_msg = FALSE;
103         state->any_marked_as_deleted = FALSE;
104         state->all_marked_as_deleted = FALSE;
105         state->any_marked_as_seen = FALSE;
106         state->all_marked_as_seen = FALSE;
107         state->any_marked_as_cached = FALSE;
108         state->all_marked_as_cached = FALSE;
109         state->any_has_attachments = FALSE;
110         state->all_has_attachments = FALSE;
111         state->sent_in_progress = FALSE;
112
113         /* Get focused widget */
114         focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
115         if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
116                 state->n_selected++;
117                 return state;
118         } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
119                 header_view = focused_widget;           
120         } else {
121                 header_view = modest_main_window_get_child_widget (window, MODEST_WIDGET_TYPE_HEADER_VIEW);
122         }
123         
124         /* Get header view and selected headers */
125         selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
126         if (!selected_headers) 
127                 return state;
128
129         /* Examine selected headers */
130         iter = tny_list_create_iterator (selected_headers);
131         while (!tny_iterator_is_done (iter)) {
132                 header = TNY_HEADER (tny_iterator_get_current (iter));
133                 flags = tny_header_get_flags (header);
134                 
135                 /* No selected */
136                 state->n_selected++;
137                 
138                 /* Already opened */
139                 mgr = modest_runtime_get_window_mgr ();
140                 if (!state->already_opened_msg)
141                         state->already_opened_msg = modest_window_mgr_find_registered_header (mgr, header, NULL);
142                 
143
144                 /* Mark as deleted */           
145                 all_deleted = all_deleted && (flags & TNY_HEADER_FLAG_DELETED);
146                 state->all_marked_as_deleted = all_deleted;
147                 if (!state->any_marked_as_deleted)
148                         state->any_marked_as_deleted = flags & TNY_HEADER_FLAG_DELETED;
149                 
150                 /* Mark as seen */
151                 all_seen = all_seen && (flags & TNY_HEADER_FLAG_SEEN);
152                 state->all_marked_as_seen = all_seen;
153                 if (!state->any_marked_as_seen)
154                         state->any_marked_as_seen = flags & TNY_HEADER_FLAG_SEEN;
155                 
156                 /* Mark as cached */
157                 all_cached = all_cached && (flags & TNY_HEADER_FLAG_CACHED);
158                 state->all_marked_as_cached = all_cached;
159                 if (!state->any_marked_as_cached)
160                         state->any_marked_as_cached = flags & TNY_HEADER_FLAG_CACHED;
161                 
162                 /* Mark has_attachments */
163                 all_has_attach = all_has_attach && (flags & TNY_HEADER_FLAG_ATTACHMENTS);
164                 state->all_has_attachments = all_has_attach;
165                 if (!state->any_has_attachments)
166                         state->any_has_attachments = flags & TNY_HEADER_FLAG_ATTACHMENTS;
167         
168                 /* sent in progress */
169                 msg_uid = modest_tny_send_queue_get_msg_id (header);
170                 if (!state->sent_in_progress) {
171                         cache_mgr = modest_runtime_get_cache_mgr ();
172                         send_queue_cache = modest_cache_mgr_get_cache (cache_mgr,
173                                                                        MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE);
174                         
175                         g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues);
176                         
177                         for (node = send_queues; node != NULL && !found; node = g_slist_next (node)) {
178                                 send_queue = MODEST_TNY_SEND_QUEUE (node->data);
179                                 
180                                 /* Check if msg uid is being processed inside send queue */
181                                 found = modest_tny_send_queue_msg_is_being_sent (send_queue, msg_uid);          
182                         }
183                         state->sent_in_progress = found;
184                 }
185
186                 tny_iterator_next (iter);
187                 g_object_unref (header);
188         }
189
190         /* Free */
191         g_free(msg_uid);
192         g_object_unref(selected_headers);
193         g_object_unref(iter);
194         g_slist_free (send_queues);
195         
196         return state;
197 }
198
199 static DimmedState *
200 _define_msg_view_window_dimming_state (ModestMsgViewWindow *window)
201 {
202         DimmedState *state = NULL;
203         TnyHeader *header = NULL;
204         ModestCacheMgr *cache_mgr = NULL;
205         GHashTable *send_queue_cache = NULL;
206         ModestTnySendQueue *send_queue = NULL;
207         GSList *send_queues = NULL, *node = NULL;
208         gboolean found = FALSE;
209         gchar *msg_uid = NULL;
210         TnyHeaderFlags flags;
211         gboolean all_deleted = TRUE;
212         gboolean all_seen = TRUE;
213         gboolean all_cached = TRUE;
214         gboolean all_has_attach = TRUE;
215                         
216         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(window), NULL);
217
218         /* Init state */
219         state = g_slice_new0 (DimmedState);
220         state->n_selected = 0;
221         state->already_opened_msg = FALSE;
222         state->any_marked_as_deleted = FALSE;
223         state->all_marked_as_deleted = FALSE;
224         state->any_marked_as_seen = FALSE;
225         state->all_marked_as_seen = FALSE;
226         state->any_marked_as_cached = FALSE;
227         state->all_marked_as_cached = FALSE;
228         state->any_has_attachments = FALSE;
229         state->all_has_attachments = FALSE;
230         state->sent_in_progress = FALSE;
231
232         header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(window));
233         g_return_val_if_fail (TNY_IS_HEADER(header), state);
234         flags = tny_header_get_flags (header);
235
236         /* Selected */
237         state->n_selected++;
238
239         /* Mark as deleted */           
240         all_deleted = all_deleted && (flags & TNY_HEADER_FLAG_DELETED);
241         state->all_marked_as_deleted = all_deleted;
242         if (!state->any_marked_as_deleted)
243                 state->any_marked_as_deleted = flags & TNY_HEADER_FLAG_DELETED;
244         
245         /* Mark as seen */
246         all_seen = all_seen && (flags & TNY_HEADER_FLAG_SEEN);
247         state->all_marked_as_seen = all_seen;
248         if (!state->any_marked_as_seen)
249                 state->any_marked_as_seen = flags & TNY_HEADER_FLAG_SEEN;
250         
251         /* Mark as cached */
252         all_cached = all_cached && (flags & TNY_HEADER_FLAG_CACHED);
253         state->all_marked_as_cached = all_cached;
254         if (!state->any_marked_as_cached)
255                 state->any_marked_as_cached = flags & TNY_HEADER_FLAG_CACHED;
256         
257         /* Mark has_attachments */
258         all_has_attach = all_has_attach && (flags & TNY_HEADER_FLAG_ATTACHMENTS);
259         state->all_has_attachments = all_has_attach;
260         if (!state->any_has_attachments)
261                 state->any_has_attachments = flags & TNY_HEADER_FLAG_ATTACHMENTS;
262         
263         /* sent in progress */
264         msg_uid = modest_tny_send_queue_get_msg_id (header);
265         if (!state->sent_in_progress) {
266                 cache_mgr = modest_runtime_get_cache_mgr ();
267                 send_queue_cache = modest_cache_mgr_get_cache (cache_mgr,
268                                                                MODEST_CACHE_MGR_CACHE_TYPE_SEND_QUEUE);
269                 
270                 g_hash_table_foreach (send_queue_cache, (GHFunc) fill_list_of_caches, &send_queues);
271                 
272                 for (node = send_queues; node != NULL && !found; node = g_slist_next (node)) {
273                         send_queue = MODEST_TNY_SEND_QUEUE (node->data);
274                         
275                         /* Check if msg uid is being processed inside send queue */
276                         found = modest_tny_send_queue_msg_is_being_sent (send_queue, msg_uid);          
277                 }
278                 state->sent_in_progress = found;
279         }
280         
281         /* Free */
282         g_free(msg_uid);
283         g_object_unref (header);
284         g_slist_free (send_queues);
285
286         return state;
287 }
288
289    
290 DimmedState *
291 modest_ui_dimming_rules_define_dimming_state (ModestWindow *window)
292 {
293         DimmedState *state = NULL;
294
295         g_return_val_if_fail (MODEST_IS_WINDOW(window), NULL);
296         
297         if (MODEST_IS_MAIN_WINDOW (window)) 
298                 state = _define_main_window_dimming_state (MODEST_MAIN_WINDOW(window));
299         else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
300                 state = _define_msg_view_window_dimming_state (MODEST_MSG_VIEW_WINDOW(window));         
301         }
302         
303         return state;
304 }
305
306
307 gboolean 
308 modest_ui_dimming_rules_on_new_msg (ModestWindow *win, gpointer user_data)
309 {
310         ModestDimmingRule *rule = NULL;
311         gboolean dimmed = FALSE;
312
313         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
314         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
315         rule = MODEST_DIMMING_RULE (user_data);
316                 
317         /* Check dimmed rule */ 
318         if (!dimmed) {
319                 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
320                 if (dimmed)
321                         modest_dimming_rule_set_notification (rule, "");
322         }
323
324         return dimmed;
325 }
326
327 gboolean 
328 modest_ui_dimming_rules_on_csm_new_folder (ModestWindow *win, gpointer user_data)
329 {
330         ModestDimmingRule *rule = NULL;
331         gboolean dimmed = FALSE;
332
333         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
334         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
335         rule = MODEST_DIMMING_RULE (user_data);
336
337         /* Check common new folder menu item dimming rules */   
338         dimmed = modest_ui_dimming_rules_on_new_folder (win, user_data);
339         
340         /* Check CSM specific dimming rules */
341         if (!dimmed) {
342                 dimmed = _selected_folder_is_snd_level (MODEST_MAIN_WINDOW(win));
343                 if (dimmed)
344                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_create_error"));
345         }
346         
347         return dimmed;
348 }
349
350 gboolean 
351 modest_ui_dimming_rules_on_new_folder (ModestWindow *win, gpointer user_data)
352 {
353         ModestDimmingRule *rule = NULL;
354         GtkWidget *folder_view = NULL;
355         TnyFolderStore *parent_folder = NULL;
356         gboolean dimmed = FALSE;
357
358         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
359         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
360         rule = MODEST_DIMMING_RULE (user_data);
361
362         /* Get selected folder as parent of new folder to create */
363         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
364                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
365         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
366         if (!parent_folder)
367                 return TRUE;
368         
369         if (TNY_IS_ACCOUNT (parent_folder)) {
370                 /* If it's the local account then do not dim */
371                 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent_folder))) {
372                         dimmed = FALSE;
373                 } else {
374                         const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (parent_folder));
375                         /* If it's POP then dim */
376                         dimmed = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
377                                   MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
378                         if (dimmed)
379                                 modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_create_error"));
380                 }
381         } else {
382                 /* TODO: the specs say that only one level of subfolder is allowed, is this true ? */
383                 
384                 TnyFolderType types[3];
385                                 
386                 types[0] = TNY_FOLDER_TYPE_DRAFTS; 
387                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
388                 types[2] = TNY_FOLDER_TYPE_SENT;
389
390                 /* Apply folder rules */        
391                 if (!dimmed) {
392                         dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
393                         if (dimmed)
394                                 modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_create_error"));
395                 }
396                 if (!dimmed) {
397                         dimmed = _selected_folder_is_any_of_type (win, types, 3);
398                         if (dimmed)
399                                 modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_create_error"));
400                 }
401         }
402         g_object_unref (parent_folder);
403
404         return dimmed;
405 }
406
407 gboolean 
408 modest_ui_dimming_rules_on_delete (ModestWindow *win, gpointer user_data)
409 {
410         ModestDimmingRule *rule = NULL;
411         GtkWidget *folder_view = NULL;
412         GtkWidget *header_view = NULL;  
413         gboolean dimmed = FALSE;
414
415         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
416         rule = MODEST_DIMMING_RULE (user_data);
417         
418         if (MODEST_IS_MAIN_WINDOW (win)) {
419                 /* Get the folder view */
420                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
421                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
422                 
423                 /* Get header view */
424                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
425                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
426
427                 if (header_view && gtk_widget_is_focus (header_view)) 
428                         dimmed = modest_ui_dimming_rules_on_delete_msg (win, rule);
429
430                 if (folder_view && gtk_widget_is_focus (folder_view)) 
431                         dimmed = modest_ui_dimming_rules_on_delete_folder (win, rule);
432
433                 if (header_view && folder_view &&
434                     !gtk_widget_is_focus (header_view) &&
435                     !gtk_widget_is_focus (folder_view)) {
436                         dimmed = TRUE;
437                         modest_dimming_rule_set_notification (rule, dgettext("hildon-common-strings", "ckct_ib_nothing_to_delete"));                    
438                 }
439         } else {
440                 dimmed = modest_ui_dimming_rules_on_delete_folder (win, rule);
441         }
442
443         return dimmed;
444 }
445
446
447
448 gboolean 
449 modest_ui_dimming_rules_on_delete_folder (ModestWindow *win, gpointer user_data)
450 {
451         ModestDimmingRule *rule = NULL;
452         TnyFolderType types[6];
453         gboolean dimmed = FALSE;
454
455         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
456         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
457         rule = MODEST_DIMMING_RULE (user_data);
458
459         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
460         types[1] = TNY_FOLDER_TYPE_OUTBOX;
461         types[2] = TNY_FOLDER_TYPE_SENT;
462         types[3] = TNY_FOLDER_TYPE_INBOX;
463         types[4] = TNY_FOLDER_TYPE_ROOT;
464         types[5] = TNY_FOLDER_TYPE_ARCHIVE;
465
466                 
467         /* Check dimmed rule */ 
468         if (!dimmed) {
469                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
470                 if (dimmed)
471                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_delete_error"));
472         }
473         if (!dimmed) {
474                 dimmed = _selected_folder_is_any_of_type (win, types, 6);
475                 if (dimmed)
476                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_delete_error"));
477         }
478         if (!dimmed) {
479                 dimmed = _selected_folder_is_root_or_inbox (MODEST_MAIN_WINDOW(win));
480                 if (dimmed)
481                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_delete_error"));
482         }
483         if (!dimmed) {
484                 dimmed = _selected_folder_is_MMC_or_POP_root (MODEST_MAIN_WINDOW(win));
485                 if (dimmed)
486                         modest_dimming_rule_set_notification (rule, _("mail_in_ui_folder_delete_error"));
487         }
488         if (!dimmed) {
489                 dimmed = _transfer_mode_enabled (win);
490                 if (dimmed)
491                         modest_dimming_rule_set_notification (rule, _CS("ckct_ib_unable_to_delete"));
492         }
493
494         return dimmed;
495 }
496
497 gboolean
498 modest_ui_dimming_rules_on_sort (ModestWindow *win, gpointer user_data)
499 {
500         ModestDimmingRule *rule = NULL;
501         gboolean dimmed = FALSE;
502
503         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
504         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
505         rule = MODEST_DIMMING_RULE (user_data);
506                 
507         /* Check dimmed rule */ 
508         if (!dimmed) {
509                 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
510                 modest_dimming_rule_set_notification (rule, _CS("ckdg_ib_nothing_to_sort"));
511         }
512
513         if (!dimmed) {
514                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));
515                 modest_dimming_rule_set_notification (rule, _CS("ckdg_ib_nothing_to_sort"));
516         }
517
518         return dimmed;
519         
520 }
521
522 gboolean 
523 modest_ui_dimming_rules_on_rename_folder (ModestWindow *win, gpointer user_data)
524 {
525         ModestDimmingRule *rule = NULL;
526         TnyFolderType types[4];
527         gboolean dimmed = FALSE;
528
529         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
530         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
531         rule = MODEST_DIMMING_RULE (user_data);
532
533         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
534         types[1] = TNY_FOLDER_TYPE_OUTBOX;
535         types[2] = TNY_FOLDER_TYPE_SENT;
536         types[3] = TNY_FOLDER_TYPE_ARCHIVE;
537         
538         /* Check dimmed rule */ 
539         if (!dimmed) {
540                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
541                 if (dimmed)
542                         modest_dimming_rule_set_notification (rule, "");
543         }
544         if (!dimmed) {
545                 dimmed = _selected_folder_is_root_or_inbox (MODEST_MAIN_WINDOW(win));
546                 if (dimmed)
547                         modest_dimming_rule_set_notification (rule, "");
548         }
549         if (!dimmed) {
550                 dimmed = _selected_folder_is_any_of_type (win, types, 4);
551                 if (dimmed)
552                         modest_dimming_rule_set_notification (rule, "");
553         }
554
555         return dimmed;
556 }
557
558 gboolean 
559 modest_ui_dimming_rules_on_open_msg (ModestWindow *win, gpointer user_data)
560 {
561         ModestDimmingRule *rule = NULL;
562         gboolean dimmed = FALSE;
563         const DimmedState *state = NULL;
564
565         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
566         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
567         rule = MODEST_DIMMING_RULE (user_data);
568         state = modest_window_get_dimming_state (win);          
569
570         /* Check dimmed rule */ 
571         if (!dimmed) {
572                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data);
573         }
574         if (!dimmed) {
575                 dimmed = state->any_marked_as_deleted;
576                 if (dimmed)
577                         modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted"));
578         }
579         if (!dimmed) {
580                 dimmed = _selected_msg_sent_in_progress (win);
581                 if (dimmed)
582                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_open_while_sent"));
583         }
584
585         return dimmed;
586 }
587
588 gboolean 
589 modest_ui_dimming_rules_on_reply_msg (ModestWindow *win, gpointer user_data)
590 {
591         ModestDimmingRule *rule = NULL;
592         gboolean dimmed = FALSE;
593         TnyFolderType types[3];
594
595         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
596         rule = MODEST_DIMMING_RULE (user_data);
597
598         /* main window dimming rules */
599         if (MODEST_IS_MAIN_WINDOW(win)) {
600                 
601                 types[0] = TNY_FOLDER_TYPE_DRAFTS; 
602                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
603                 types[2] = TNY_FOLDER_TYPE_ROOT;
604                 
605                 /* Check dimmed rule */ 
606                 if (!dimmed) {
607                         dimmed = _selected_folder_is_any_of_type (win, types, 3);                       
608                         if (dimmed)
609                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_reply"));
610                 }
611                 if (!dimmed) {
612                         dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
613                         if (dimmed)
614                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_nothing_to_reply"));
615                 }
616                 if (!dimmed) {
617                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, rule);
618                 }
619         /* msg view window dimming rules */
620         } else if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
621                 
622                 /* Check dimmed rule */ 
623                 if (!dimmed) {
624                         dimmed = _transfer_mode_enabled (win);                  
625                         if (dimmed)
626                                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
627                 }
628                 if (!dimmed) {
629                         dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW (win));
630                         if (dimmed)
631                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_reply"));
632                 }
633         }
634         
635         return dimmed;
636 }
637
638
639 gboolean 
640 modest_ui_dimming_rules_on_contents_msg (ModestWindow *win, gpointer user_data)
641 {
642         ModestDimmingRule *rule = NULL;
643         gboolean dimmed = FALSE;
644
645         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
646         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
647         rule = MODEST_DIMMING_RULE (user_data);
648                 
649         /* Check dimmed rule */ 
650         if (!dimmed) {
651                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
652         }
653         if (!dimmed) {
654                 dimmed = _msg_download_completed (MODEST_MAIN_WINDOW(win));
655                 if (dimmed)
656                         modest_dimming_rule_set_notification (rule, "");
657         }
658
659         return dimmed;
660 }
661
662 gboolean 
663 modest_ui_dimming_rules_always_dimmed (ModestWindow *win, gpointer user_data)
664 {
665         gboolean dimmed = FALSE;
666
667         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
668                 
669         /* Check dimmed rule */ 
670         if (!dimmed)
671                 dimmed = TRUE;
672
673         return dimmed;
674 }
675
676 gboolean 
677 modest_ui_dimming_rules_on_delete_msg (ModestWindow *win, gpointer user_data)
678 {
679         ModestDimmingRule *rule = NULL;
680         guint n_messages = 0;
681         const DimmedState *state = NULL;
682         gboolean dimmed = FALSE;
683
684         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
685         rule = MODEST_DIMMING_RULE (user_data);
686         state = modest_window_get_dimming_state (win);          
687         
688         /* Check dimmed rule */         
689         if (MODEST_IS_MAIN_WINDOW (win)) {
690                 if (!dimmed) {
691                         dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
692                         if (dimmed)
693                                 modest_dimming_rule_set_notification (rule, _CS("ckct_ib_nothing_to_delete"));
694                 }
695                 if (!dimmed) {
696                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
697                 }
698                 if (!dimmed) {
699                         dimmed = state->already_opened_msg;
700                         n_messages = state->n_selected;
701                         if (dimmed) {
702                                 gchar *num = g_strdup_printf ("%d", n_messages);
703                                 gchar *message = g_strdup_printf(_("mcen_nc_unable_to_delete_n_messages"), num);
704                                 modest_dimming_rule_set_notification (rule, message);
705                                 g_free(message);
706                                 g_free(num);
707                         }
708                         
709                 }
710                 if (!dimmed) {
711                         dimmed = state->any_marked_as_deleted;
712                         if (dimmed) {
713                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted"));
714                         }
715                 }
716                 if (!dimmed) {
717                         dimmed = state->sent_in_progress;
718                         if (dimmed)
719                                 modest_dimming_rule_set_notification (rule, _CS("ckct_ib_unable_to_delete"));
720                 }
721         } 
722         else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
723                 if (!dimmed) {
724                         dimmed = _transfer_mode_enabled (win);                  
725                         if (dimmed)
726                                 modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
727                 }
728                 if (!dimmed) {
729                         dimmed = state->any_marked_as_deleted;
730                         if (dimmed)
731                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_message_already_deleted"));
732                 }
733                 
734                 /* The delete button should be dimmed when viewing an attachment,
735                  * but should be enabled when viewing a message from the list, 
736                  * or when viewing a search result.
737                  */
738                 if (!dimmed) {
739                         if (!modest_msg_view_window_is_search_result (MODEST_MSG_VIEW_WINDOW(win))) {
740                                 dimmed = !modest_msg_view_window_has_headers_model (MODEST_MSG_VIEW_WINDOW(win));
741                                 if (dimmed) {
742                                         modest_dimming_rule_set_notification (rule, _CS("ckct_ib_unable_to_delete"));
743                                 }
744                         }
745                 }
746         }
747
748         return dimmed;
749 }
750
751 gboolean 
752 modest_ui_dimming_rules_on_details (ModestWindow *win, gpointer user_data)
753 {
754         ModestDimmingRule *rule = NULL;
755         GtkWidget *header_view = NULL;
756         gboolean dimmed = FALSE;
757
758         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
759         rule = MODEST_DIMMING_RULE (user_data);
760         
761         /* main window dimming rules */
762         if (MODEST_IS_MAIN_WINDOW(win)) {
763                                 
764                 /* Check dimmed rule */
765                 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
766                                                                    MODEST_WIDGET_TYPE_HEADER_VIEW);
767                 
768                 /* If the header view has the focus: */
769                 if (header_view && gtk_widget_is_focus (header_view)) {
770                         /* Check dimmed rule */ 
771                         if (!dimmed)
772                                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data);
773                 }
774                 else {
775                         /* If the folder view has the focus: */
776                         GtkWidget *folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
777                                 MODEST_WIDGET_TYPE_FOLDER_VIEW);
778                         if (folder_view && gtk_widget_is_focus (folder_view)) {
779                                 TnyFolderStore *folder_store
780                                         = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
781                                 if (folder_store) {
782                                         /* Only enable for folders, not accounts,
783                                          * though the UI spec is not clear about that.
784                                          * If we enable this for accounts then we must 
785                                          * add code to handle them in modest_ui_actions_on_details(). */
786                                         if (!TNY_IS_FOLDER(folder_store)) {
787                                                 dimmed = TRUE;
788                                                 modest_dimming_rule_set_notification (rule, "");
789                                         }
790
791                                         g_object_unref (folder_store);
792                                 }
793                         }
794
795                 }
796
797         /* msg view window dimming rules */
798         } else {
799
800                 /* Check dimmed rule */ 
801                 if (!dimmed) {
802                         if (MODEST_IS_MSG_VIEW_WINDOW (win))
803                                 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW (win));
804                         if (dimmed)
805                                 modest_dimming_rule_set_notification (rule, "");
806                 }
807         }
808
809         return dimmed;
810 }
811
812
813 gboolean 
814 modest_ui_dimming_rules_on_mark_as_read_msg (ModestWindow *win, gpointer user_data)
815 {
816         ModestDimmingRule *rule = NULL;
817         TnyHeaderFlags flags;
818         const DimmedState *state = NULL;
819         gboolean dimmed = FALSE;
820
821         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
822         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
823         rule = MODEST_DIMMING_RULE (user_data);
824         state = modest_window_get_dimming_state (win);          
825         
826         flags = TNY_HEADER_FLAG_SEEN; 
827
828         /* Check dimmed rule */ 
829         if (!dimmed) {
830                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
831         }
832         if (!dimmed) {
833                 dimmed = state->all_marked_as_seen;
834                 if (dimmed)
835                         modest_dimming_rule_set_notification (rule, "");
836         }       
837
838         return dimmed;
839 }
840
841 gboolean 
842 modest_ui_dimming_rules_on_mark_as_unread_msg (ModestWindow *win, gpointer user_data)
843 {
844         ModestDimmingRule *rule = NULL;
845         TnyHeaderFlags flags;
846         const DimmedState *state = NULL;
847         gboolean dimmed = FALSE;
848
849         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
850         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
851         rule = MODEST_DIMMING_RULE (user_data);
852         state = modest_window_get_dimming_state (win);          
853         
854         flags = TNY_HEADER_FLAG_SEEN; 
855
856         /* Check dimmed rule */ 
857         if (!dimmed)
858                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
859         if (!dimmed) {
860                 dimmed = !state->any_marked_as_seen;
861                 if (dimmed)
862                         modest_dimming_rule_set_notification (rule, "");
863         }
864
865         return dimmed;
866 }
867
868 gboolean 
869 modest_ui_dimming_rules_on_move_to (ModestWindow *win, gpointer user_data)
870 {
871         ModestDimmingRule *rule = NULL;
872         gboolean dimmed = FALSE;
873
874         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
875         rule = MODEST_DIMMING_RULE (user_data);
876
877         if (MODEST_IS_MAIN_WINDOW (win)) 
878                 dimmed = modest_ui_dimming_rules_on_main_window_move_to (win, user_data);
879         else if (MODEST_IS_MSG_VIEW_WINDOW (win)) 
880                  dimmed = modest_ui_dimming_rules_on_view_window_move_to (win, user_data);
881
882         return dimmed;
883 }
884
885
886 gboolean 
887 modest_ui_dimming_rules_on_main_window_move_to (ModestWindow *win, gpointer user_data)
888 {
889         GtkWidget *folder_view = NULL;
890         ModestDimmingRule *rule = NULL;
891         guint n_messages = 0;
892         const DimmedState *state = NULL;
893         gboolean dimmed = FALSE;
894         
895         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
896         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
897         rule = MODEST_DIMMING_RULE (user_data);
898         state = modest_window_get_dimming_state (win);          
899         
900         /* Get the folder view */
901         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
902                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
903
904         
905         /* Check diming rules for folders transfer  */
906         if (gtk_widget_is_focus (folder_view)) {
907                 TnyFolderType types[5];
908                 
909                 types[0] = TNY_FOLDER_TYPE_DRAFTS; 
910                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
911                 types[2] = TNY_FOLDER_TYPE_SENT;
912                 types[3] = TNY_FOLDER_TYPE_ROOT; 
913                 types[4] = TNY_FOLDER_TYPE_INBOX; 
914                 
915                 /* Apply folder rules */        
916                 if (!dimmed) {
917                         dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
918                         if (dimmed)
919                                 modest_dimming_rule_set_notification (rule, _("emev_bd_unabletomove_items"));
920                 }
921                 if (!dimmed) {
922                         dimmed = _selected_folder_is_any_of_type (win, types, 5);
923                         if (dimmed)
924                                 modest_dimming_rule_set_notification (rule, _("emev_bd_unabletomove_itemsr"));
925                 }
926         }
927         
928         /* Check diming rules for messages transfer  */
929         if (!dimmed) {
930                 dimmed = state->already_opened_msg;
931                 n_messages = state->n_selected;
932                 if (dimmed) {
933                         gchar *message = g_strdup_printf(_("emev_bd_unabletomove_items"), n_messages);
934                         modest_dimming_rule_set_notification (rule, message);
935                         g_free(message);
936                 }
937         }
938         if (!dimmed) {
939                 if (!gtk_widget_is_focus (folder_view))
940                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
941                 
942         }
943         
944         return dimmed;
945 }
946
947 gboolean 
948 modest_ui_dimming_rules_on_view_window_move_to (ModestWindow *win, gpointer user_data)
949 {
950         ModestDimmingRule *rule = NULL;
951         gboolean dimmed = FALSE;
952
953         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
954         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
955         rule = MODEST_DIMMING_RULE (user_data);
956
957         /* Check dimmed rule */ 
958         if (!dimmed) {
959                 dimmed = _transfer_mode_enabled (win);                  
960                 if (dimmed)
961                         modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
962         }
963         
964         if (!dimmed) {
965                 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
966                         /* The move_to button should be dimmed when viewing an attachment,
967                          * but should be enabled when viewing a message from the list, 
968                          * or when viewing a search result.
969                          */
970                         if (!modest_msg_view_window_is_search_result (MODEST_MSG_VIEW_WINDOW(win))) {
971                                 dimmed = !modest_msg_view_window_has_headers_model (MODEST_MSG_VIEW_WINDOW (win));
972                         }
973                 }
974                 
975                 if (dimmed) 
976                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_move_mail_attachment"));
977         }
978
979         return dimmed;
980 }
981
982 gboolean 
983 modest_ui_dimming_rules_on_find_msg (ModestWindow *win, gpointer user_data)
984 {
985         ModestDimmingRule *rule = NULL;
986         gboolean dimmed = FALSE;
987
988         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
989         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
990         rule = MODEST_DIMMING_RULE (user_data);
991
992         /* Check dimmed rule */ 
993         if (!dimmed) {
994                 dimmed = _transfer_mode_enabled (win);                  
995                 if (dimmed)
996                         modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
997         }
998
999         return dimmed;
1000 }
1001
1002 gboolean 
1003 modest_ui_dimming_rules_on_paste_msgs (ModestWindow *win, gpointer user_data)
1004 {
1005         ModestDimmingRule *rule = NULL;
1006         TnyFolderType types[3];
1007         gboolean dimmed = FALSE;
1008         
1009         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1010         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1011         rule = MODEST_DIMMING_RULE (user_data);
1012
1013         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
1014         types[1] = TNY_FOLDER_TYPE_OUTBOX;
1015         types[2] = TNY_FOLDER_TYPE_SENT;
1016         
1017         /* Check dimmed rule */ 
1018         if (!dimmed) {
1019                 dimmed = _clipboard_is_empty (win);
1020                 if (dimmed)
1021                         modest_dimming_rule_set_notification (rule, dgettext("hildon-common-strings", "ecoc_ib_edwin_nothing_to_paste"));
1022         }
1023         if (!dimmed) {
1024                 dimmed = _selected_folder_is_any_of_type (win, types, 3);
1025                 if (dimmed)
1026                         modest_dimming_rule_set_notification (rule, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
1027         }
1028         if (!dimmed) {
1029                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
1030                 if (dimmed) {
1031                         modest_dimming_rule_set_notification (rule, dgettext("hildon-common-strings", "ckct_ib_unable_to_paste_here"));
1032                 }
1033         }
1034         if (!dimmed) {
1035                 dimmed = _selected_folder_is_same_as_source (win);
1036                 if (dimmed)
1037                         modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_copy_samefolder"));
1038         }
1039
1040         return dimmed;
1041 }
1042
1043
1044 gboolean 
1045 modest_ui_dimming_rules_on_select_all (ModestWindow *win, gpointer user_data)
1046 {
1047         ModestDimmingRule *rule = NULL;
1048         gboolean dimmed = FALSE;
1049
1050         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1051         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1052         rule = MODEST_DIMMING_RULE (user_data);
1053
1054         /* Check dimmed rule */ 
1055         if (!dimmed) {
1056                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
1057                 if (dimmed)
1058                         modest_dimming_rule_set_notification (rule, "");
1059         }
1060                 
1061         return dimmed;
1062 }
1063
1064 gboolean 
1065 modest_ui_dimming_rules_on_view_attachments (ModestWindow *win, gpointer user_data)
1066 {
1067         ModestDimmingRule *rule = NULL;
1068         gboolean dimmed = FALSE;
1069
1070         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1071         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1072         rule = MODEST_DIMMING_RULE (user_data);
1073
1074         /* Check dimmed rule */ 
1075         if (!dimmed) 
1076                 dimmed = _invalid_attach_selected (win, TRUE, TRUE, FALSE, rule);                       
1077
1078         if (!dimmed) {
1079                 dimmed = _purged_attach_selected (win, FALSE, NULL);
1080                 if (dimmed) {
1081                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1082                 }
1083         }
1084                 
1085         return dimmed;
1086 }
1087
1088 gboolean 
1089 modest_ui_dimming_rules_on_save_attachments (ModestWindow *win, gpointer user_data)
1090 {
1091         ModestDimmingRule *rule = NULL;
1092         gboolean dimmed = FALSE;
1093
1094         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1095         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1096         rule = MODEST_DIMMING_RULE (user_data);
1097
1098         /* Check dimmed rule */ 
1099         if (!dimmed) 
1100                 dimmed = _invalid_attach_selected (win, FALSE, FALSE, FALSE, rule);
1101
1102         if (!dimmed) {
1103                 dimmed = _purged_attach_selected (win, FALSE, NULL);
1104                 if (dimmed) {
1105                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1106                 }
1107         }
1108                 
1109         return dimmed;
1110 }
1111
1112 gboolean 
1113 modest_ui_dimming_rules_on_remove_attachments (ModestWindow *win, gpointer user_data)
1114 {
1115         ModestDimmingRule *rule = NULL;
1116         const DimmedState *state = NULL;
1117         gboolean dimmed = FALSE;
1118
1119         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
1120         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1121         rule = MODEST_DIMMING_RULE (user_data);
1122         state = modest_window_get_dimming_state (win);          
1123
1124         /* Check in main window if there's only one message selected */
1125         if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) {
1126                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW (win), TRUE, rule);
1127         }
1128
1129         /* Check in view window if there's any attachment selected */
1130         if (!dimmed && MODEST_IS_MSG_VIEW_WINDOW (win)) {
1131                 dimmed = _invalid_attach_selected (win, FALSE, FALSE, TRUE, NULL);
1132                 if (dimmed)
1133                         modest_dimming_rule_set_notification (rule, _("FIXME:no attachment selected"));
1134         }
1135
1136         /* cannot purge in editable drafts nor pop folders */
1137         if (!dimmed) {
1138                 dimmed = _invalid_folder_for_purge (win, rule);
1139         }
1140
1141         /* Check if the selected message in main window has attachments */
1142         if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) {
1143                 dimmed = state->any_has_attachments;
1144                 if (dimmed)
1145                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
1146         }
1147
1148         /* Check if all attachments are already purged */
1149         if (!dimmed) {
1150                 dimmed = _purged_attach_selected (win, TRUE, rule);
1151         }
1152
1153         /* Check if the message is already downloaded */
1154         if (!dimmed && MODEST_IS_MAIN_WINDOW (win)) {
1155                 dimmed = !_msg_download_completed (MODEST_MAIN_WINDOW (win));
1156                 if (dimmed)
1157                         modest_dimming_rule_set_notification (rule, _("mail_ib_attach_not_local"));
1158         }
1159
1160
1161         return dimmed;
1162 }
1163
1164 gboolean 
1165 modest_ui_dimming_rules_on_undo (ModestWindow *win, gpointer user_data)
1166 {
1167         ModestDimmingRule *rule = NULL;
1168         gboolean dimmed = FALSE;
1169         
1170         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1171         rule = MODEST_DIMMING_RULE (user_data);
1172
1173         /* Check dimmed rule */ 
1174         if (!dimmed) {
1175                 dimmed = _clipboard_is_empty (win); 
1176                 if (dimmed)
1177                         modest_dimming_rule_set_notification (rule, "");
1178         }
1179                                 
1180         return dimmed;  
1181 }
1182
1183 gboolean 
1184 modest_ui_dimming_rules_on_cut (ModestWindow *win, gpointer user_data)
1185 {
1186         ModestDimmingRule *rule = NULL;
1187         gboolean dimmed = FALSE;
1188         
1189         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1190         rule = MODEST_DIMMING_RULE (user_data);
1191
1192         /* Check common dimming rules */
1193         if (!dimmed) {
1194                 dimmed = _invalid_clipboard_selected (win, rule);
1195         }
1196
1197         /* Check window specific dimming rules */
1198         if (MODEST_IS_MAIN_WINDOW (win)) {
1199                 /* Get focused widget */
1200                 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (win));
1201                 
1202                 if (MODEST_IS_HEADER_VIEW (focused)) {
1203                         if (!dimmed) { 
1204                                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
1205                                 if (dimmed)
1206                                         modest_dimming_rule_set_notification (rule, "");
1207                         }
1208                         if (!dimmed) {
1209                                 dimmed = _selected_msg_sent_in_progress (win);
1210                                 if (dimmed)
1211                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_cut_mess"));
1212                         }
1213                 }
1214                 else if (MODEST_IS_FOLDER_VIEW (focused)) {
1215                         TnyFolderType types[3];
1216                         
1217                         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
1218                         types[1] = TNY_FOLDER_TYPE_OUTBOX;
1219                         types[2] = TNY_FOLDER_TYPE_SENT;
1220                         
1221                         /* Apply folder rules */        
1222                         if (!dimmed) {
1223                                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
1224                                 if (dimmed)
1225                                         modest_dimming_rule_set_notification (rule, _("emev_bd_unabletomove_items"));
1226                         }
1227                         if (!dimmed) {
1228                                 dimmed = _selected_folder_is_root_or_inbox (MODEST_MAIN_WINDOW(win));
1229                                 if (dimmed)
1230                                         modest_dimming_rule_set_notification (rule, _("emev_bd_unabletomove_itemsr"));
1231                         }
1232                         if (!dimmed) {
1233                                 dimmed = _selected_folder_is_any_of_type (win, types, 3);
1234                                 if (dimmed)
1235                                         modest_dimming_rule_set_notification (rule, _("emev_bd_unabletomove_itemsr"));
1236                         }
1237                 }
1238         }
1239
1240         return dimmed;
1241 }
1242
1243 gboolean 
1244 modest_ui_dimming_rules_on_copy (ModestWindow *win, gpointer user_data)
1245 {
1246         ModestDimmingRule *rule = NULL;
1247         gboolean dimmed = FALSE;
1248         
1249         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1250         rule = MODEST_DIMMING_RULE (user_data);
1251
1252         /* Check common dimming rules */
1253         if (!dimmed) {
1254                 dimmed = _invalid_clipboard_selected (win, rule);
1255         }
1256         
1257         /* Check window specific dimming rules */
1258         if (MODEST_IS_MAIN_WINDOW (win)) {
1259                 /* Get focused widget */
1260                 GtkWidget *focused = gtk_window_get_focus (GTK_WINDOW (win));
1261                 
1262                 if (MODEST_IS_HEADER_VIEW (focused)) {
1263                         if (!dimmed) {
1264                                 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));                   
1265                                 if (dimmed)
1266                                         modest_dimming_rule_set_notification (rule, "");
1267                         }               
1268                         if (!dimmed) {
1269                                 dimmed = _selected_msg_sent_in_progress (win);
1270                                 if (dimmed)
1271                                         modest_dimming_rule_set_notification (rule, _(""));
1272                         }
1273                 }
1274                 else if (MODEST_IS_FOLDER_VIEW (focused)) {
1275                         if (!dimmed) {
1276                                 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
1277                                 if (dimmed)
1278                                         modest_dimming_rule_set_notification (rule, _(""));
1279                         }
1280                 }
1281         }
1282                 
1283         return dimmed;
1284 }
1285
1286 gboolean 
1287 modest_ui_dimming_rules_on_view_previous (ModestWindow *win, gpointer user_data)
1288 {
1289         ModestDimmingRule *rule = NULL;
1290         gboolean dimmed = FALSE;
1291         
1292         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1293         rule = MODEST_DIMMING_RULE (user_data);
1294
1295         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1296
1297         /* Check dimmed rule */
1298         if (!dimmed) {
1299                 dimmed = _transfer_mode_enabled (win);
1300                 if (dimmed)
1301                         modest_dimming_rule_set_notification (
1302                                         rule, _("mail_ib_notavailable_downloading"));
1303         }
1304         if (!dimmed) {
1305                 dimmed = modest_msg_view_window_first_message_selected (
1306                                 MODEST_MSG_VIEW_WINDOW(win));
1307                 modest_dimming_rule_set_notification (rule, NULL);
1308         }
1309
1310         return dimmed;
1311 }
1312
1313 gboolean 
1314 modest_ui_dimming_rules_on_view_next (ModestWindow *win, gpointer user_data)
1315 {
1316         ModestDimmingRule *rule = NULL;
1317         gboolean dimmed = FALSE;
1318
1319         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
1320         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1321         rule = MODEST_DIMMING_RULE (user_data);
1322
1323         /* Check dimmed rule */ 
1324         if (!dimmed) {
1325                 dimmed = _transfer_mode_enabled (win);                  
1326                 if (dimmed)
1327                         modest_dimming_rule_set_notification (rule, _("mail_ib_notavailable_downloading"));
1328         }
1329         if (!dimmed) {
1330                 dimmed = modest_msg_view_window_last_message_selected (MODEST_MSG_VIEW_WINDOW (win));
1331                 modest_dimming_rule_set_notification (rule, NULL);
1332         }               
1333
1334         return dimmed;
1335 }
1336
1337
1338 gboolean 
1339 modest_ui_dimming_rules_on_tools_smtp_servers (ModestWindow *win, gpointer user_data)
1340 {
1341         const gboolean dimmed = 
1342                 !modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), 
1343                         TRUE);  
1344                 
1345         return dimmed;
1346 }
1347
1348 gboolean 
1349 modest_ui_dimming_rules_on_cancel_sending (ModestWindow *win, gpointer user_data)
1350 {
1351         ModestDimmingRule *rule = NULL;
1352         TnyFolderType types[1];
1353         guint n_messages = 0;
1354         const DimmedState *state = NULL;
1355         gboolean dimmed = FALSE;
1356
1357         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1358         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1359         rule = MODEST_DIMMING_RULE (user_data);
1360         state = modest_window_get_dimming_state (win);
1361
1362         types[0] = TNY_FOLDER_TYPE_OUTBOX; 
1363
1364         /* Check dimmed rules */        
1365         if (!dimmed) {
1366                 dimmed = state->already_opened_msg;
1367                 n_messages = state->n_selected;
1368                 if (dimmed) 
1369                         modest_dimming_rule_set_notification (rule, _("mcen_ib_message_unableto_cancel_send"));
1370         }
1371         if (!dimmed) {
1372                 dimmed = !_selected_folder_is_any_of_type (win, types, 1);
1373                 if (dimmed) 
1374                         modest_dimming_rule_set_notification (rule, "");
1375         }
1376         if (!dimmed) {
1377                 dimmed = !_sending_in_progress (win);
1378                 if (dimmed)
1379                         modest_dimming_rule_set_notification (rule, "");
1380         }
1381
1382         return dimmed;
1383 }
1384
1385 gboolean 
1386 modest_ui_dimming_rules_on_send_receive (ModestWindow *win, gpointer user_data)
1387 {
1388         ModestDimmingRule *rule = NULL;
1389         gboolean dimmed = FALSE;
1390         
1391         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1392         rule = MODEST_DIMMING_RULE (user_data);
1393  
1394         /* Check dimmed rule */ 
1395         if (!dimmed) {
1396                 dimmed = !modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), 
1397                                                           TRUE);        
1398                 if (dimmed)
1399                         modest_dimming_rule_set_notification (rule, _("mcen_nc_no_email_acnts_defined"));
1400         }
1401
1402         return dimmed;
1403 }
1404
1405 gboolean
1406 modest_ui_dimming_rules_on_add_to_contacts (ModestWindow *win, gpointer user_data)
1407 {
1408         ModestDimmingRule *rule = NULL;
1409         gboolean dimmed = FALSE;
1410
1411         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
1412         rule = MODEST_DIMMING_RULE (user_data);
1413
1414         /* Check dimmed rule */
1415         if (!dimmed) {
1416                 GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1417                 gchar *selection = NULL;
1418                 selection = gtk_clipboard_wait_for_text (clipboard);
1419
1420                 dimmed = !((selection != NULL) && (modest_text_utils_validate_recipient (selection, NULL)));
1421         }
1422
1423         return dimmed;
1424 }
1425
1426 /* *********************** static utility functions ******************** */
1427
1428
1429 static gboolean
1430 _selected_folder_not_writeable (ModestMainWindow *win)
1431 {
1432         GtkWidget *folder_view = NULL;
1433         TnyFolderStore *parent_folder = NULL;
1434         ModestTnyFolderRules rules;
1435         gboolean result = FALSE;
1436
1437         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1438
1439         /* Get folder view */
1440         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1441                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1442         /* If no folder view, always dimmed */
1443         if (!folder_view)
1444                 return TRUE;
1445         
1446         /* Get selected folder as parent of new folder to create */
1447         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1448         if (!(parent_folder && TNY_IS_FOLDER(parent_folder))) {
1449                 if (parent_folder)
1450                         g_object_unref (parent_folder);
1451                 return TRUE;
1452         }
1453         
1454         /* Check dimmed rule */ 
1455         rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
1456         result = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
1457
1458         /* free */
1459         g_object_unref (parent_folder);
1460
1461         return result;
1462 }
1463
1464 static gboolean
1465 _selected_folder_is_root_or_inbox (ModestMainWindow *win)
1466 {
1467         TnyFolderType types[2];
1468         gboolean result = FALSE;
1469
1470         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1471
1472         types[0] = TNY_FOLDER_TYPE_ROOT; 
1473         types[1] = TNY_FOLDER_TYPE_INBOX; 
1474
1475         /* Check folder type */
1476         result = _selected_folder_is_any_of_type (MODEST_WINDOW(win), types, 2);
1477
1478         /* Check pop and MMC accounts */
1479         if (!result) {
1480                 result = _selected_folder_is_MMC_or_POP_root (win);
1481         }
1482                 
1483         return result;
1484 }
1485
1486
1487 static gboolean
1488 _selected_folder_is_root (ModestMainWindow *win)
1489 {
1490         TnyFolderType types[1];
1491         gboolean result = FALSE;
1492
1493         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1494
1495         /* All accounts are root items: */
1496         GtkWidget *folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1497                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1498         if (folder_view) {                                      
1499                 gboolean is_account = FALSE;
1500                 TnyFolderStore *folder_store = 
1501                         modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1502                 if (folder_store) {
1503                         is_account = TNY_IS_ACCOUNT (folder_store);
1504                         g_object_unref (folder_store);
1505                         folder_store = NULL;
1506                 }
1507                 
1508                 if (is_account)
1509                         return TRUE;
1510         }
1511                 
1512         /* Try something more precise: */
1513         types[0] = TNY_FOLDER_TYPE_ROOT; 
1514
1515         /* Check folder type */
1516         result = _selected_folder_is_any_of_type (MODEST_WINDOW(win), types, 1);
1517                 
1518         /* Check pop and MMC accounts */
1519         if (!result) {
1520                 result = _selected_folder_is_MMC_or_POP_root (win);
1521         }
1522
1523         return result;
1524 }
1525
1526 static gboolean
1527 _selected_folder_is_MMC_or_POP_root (ModestMainWindow *win)
1528 {
1529         GtkWidget *folder_view = NULL;
1530         TnyFolderStore *parent_folder = NULL;
1531         gboolean result = FALSE;
1532
1533         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1534                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1535         /* Get selected folder as parent of new folder to create */
1536         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1537         if (!parent_folder)
1538                 return TRUE;
1539         
1540         if (TNY_IS_ACCOUNT (parent_folder)) {
1541                 /* If it's the local account then do not dim */
1542                 if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (parent_folder))) {
1543                         result = FALSE;
1544                 } else {
1545                                 /* If it's the MMC root folder then dim it */
1546                         if (!strcmp (tny_account_get_id (TNY_ACCOUNT (parent_folder)), MODEST_MMC_ACCOUNT_ID)) {
1547                                         result = TRUE;
1548                         } else {
1549                                 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (parent_folder));
1550                                 /* If it's POP then dim */
1551                                 result = (modest_protocol_info_get_transport_store_protocol (proto_str) == 
1552                                                   MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
1553                         }
1554                 }
1555         }
1556         g_object_unref (parent_folder);
1557
1558         return result;
1559 }
1560
1561
1562 static gboolean
1563 _selected_folder_is_empty (ModestMainWindow *win)
1564 {
1565         GtkWidget *folder_view = NULL;
1566         TnyFolderStore *folder = NULL;
1567         gboolean result = FALSE;
1568
1569         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1570
1571         /* Get folder view */
1572         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1573                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1574         /* If no folder view, always dimmed */
1575         if (!folder_view)
1576                 return TRUE;
1577         
1578         /* Get selected folder as parent of new folder to create */
1579         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1580         if (!(folder && TNY_IS_FOLDER(folder))) {
1581                 if (folder)
1582                         g_object_unref (folder);
1583                 return TRUE;
1584         }
1585         
1586         /* Check folder type */
1587         result = tny_folder_get_all_count (TNY_FOLDER (folder)) == 0;
1588
1589         /* free */
1590         g_object_unref (folder);
1591
1592         return result;
1593 }
1594
1595 static gboolean
1596 _selected_folder_is_same_as_source (ModestWindow *win)
1597 {
1598         ModestEmailClipboard *clipboard = NULL;
1599         GtkWidget *folder_view = NULL;
1600         TnyFolderStore *folder = NULL;
1601         gboolean result = FALSE;
1602
1603         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1604
1605         /* Get folder view */
1606         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1607                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1608         if (!folder_view)
1609                 return FALSE;
1610         
1611         /* Get selected folder as destination folder */
1612         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1613         if (!(folder && TNY_IS_FOLDER(folder))) {
1614                 result = FALSE;
1615                 goto frees;
1616         }
1617         
1618         /* Check clipboard is cleared */
1619         clipboard = modest_runtime_get_email_clipboard ();
1620         if (modest_email_clipboard_cleared (clipboard)) {
1621                 result = FALSE;
1622                 goto frees;
1623         }
1624                 
1625         /* Check source folder */
1626         result = modest_email_clipboard_check_source_folder (clipboard, 
1627                                                              (const TnyFolder *) folder);
1628         
1629         /* Free */
1630  frees:
1631         g_object_unref (folder);
1632         
1633         return result;
1634 }
1635
1636 static gboolean
1637 _selected_folder_is_any_of_type (ModestWindow *win,
1638                                  TnyFolderType types[], 
1639                                  guint ntypes)
1640 {
1641         GtkWidget *folder_view = NULL;
1642         TnyFolderStore *folder = NULL;
1643         TnyFolderType folder_type;
1644         guint i=0;
1645         gboolean result = FALSE;
1646
1647         /*Get current folder */
1648         if (MODEST_IS_MAIN_WINDOW(win)) {
1649
1650                 /* Get folder view */
1651                 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1652                                                                    MODEST_WIDGET_TYPE_FOLDER_VIEW);
1653                 /* If no folder view, always dimmed */
1654                 if (!folder_view)
1655                         return FALSE;
1656         
1657                 /* Get selected folder as parent of new folder to create */
1658                 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1659
1660                 if (!(folder && TNY_IS_FOLDER(folder))) {
1661                         if (folder)
1662                                 g_object_unref (folder);
1663                         return FALSE;
1664                 }
1665                 
1666                 /* Check folder type */
1667                 result = _folder_is_any_of_type (TNY_FOLDER(folder), types, ntypes);
1668         }
1669         else if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1670                 folder_type = modest_msg_view_window_get_folder_type (MODEST_MSG_VIEW_WINDOW (win));
1671                 for (i=0; i < ntypes; i++) {
1672                         result = result || folder_type == types[i];
1673                 }
1674         }
1675
1676
1677         /* free */
1678         g_object_unref (folder);
1679
1680         return result;  
1681 }
1682
1683 static gboolean
1684 _folder_is_any_of_type (TnyFolder *folder,
1685                         TnyFolderType types[], 
1686                         guint ntypes)
1687 {
1688         TnyFolderType folder_type;
1689         gboolean result = FALSE;
1690         guint i;
1691
1692         g_return_val_if_fail (TNY_IS_FOLDER(folder), FALSE);
1693
1694         /* Get folder type */
1695         folder_type = modest_tny_folder_guess_folder_type (folder);
1696                 
1697         /* Check foler type */
1698         for (i=0; i < ntypes; i++) {
1699                 result = result || folder_type == types[i];
1700         }
1701
1702         return result;
1703 }
1704
1705 static gboolean
1706 _selected_folder_is_snd_level (ModestMainWindow *win)
1707 {
1708         GtkWidget *folder_view = NULL;
1709         GtkTreeSelection *sel = NULL;
1710         GtkTreeModel *model = NULL;
1711         GtkTreePath *path = NULL;
1712         GtkTreeIter iter;
1713         TnyFolderStore *folder = NULL;
1714         gboolean result = FALSE;
1715
1716         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
1717
1718         /*Get curent folder */
1719         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
1720                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1721         /* If no folder view, always dimmed */
1722         if (!folder_view) 
1723                 goto frees;
1724
1725         /* Get selected folder as parent of new folder to create */
1726         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));     
1727         if (!(folder && TNY_IS_FOLDER(folder))) {
1728                 goto frees;
1729         }
1730         
1731         /* Check folder level */
1732         sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(folder_view));
1733         if (!gtk_tree_selection_get_selected (sel, &model, &iter))
1734                 goto frees;
1735         path = gtk_tree_model_get_path (model, &iter);
1736         result = gtk_tree_path_get_depth (path) > 2;
1737         
1738  frees:
1739         if (folder != NULL)
1740                 g_object_unref (folder);
1741         if (path != NULL)
1742                 gtk_tree_path_free (path);
1743         
1744         return result;
1745
1746 }
1747
1748 static gboolean
1749 _clipboard_is_empty (ModestWindow *win)
1750 {
1751         gboolean result = FALSE;
1752         
1753         if (MODEST_IS_MAIN_WINDOW (win)) {
1754                 ModestEmailClipboard *clipboard = NULL;
1755                 clipboard = modest_runtime_get_email_clipboard ();
1756                 if (modest_email_clipboard_cleared (clipboard)) 
1757                  result = TRUE;  
1758         }
1759
1760         return result;
1761 }
1762
1763 static gboolean
1764 _invalid_clipboard_selected (ModestWindow *win,
1765                        ModestDimmingRule *rule) 
1766 {
1767         const DimmedState *state = NULL;
1768         gboolean result = FALSE;
1769
1770         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
1771         state = modest_window_get_dimming_state (win);
1772
1773         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1774                 GtkClipboard *clipboard = NULL;
1775                 gchar *selection = NULL;
1776                 GtkWidget *focused = NULL;
1777
1778                 /* Get clipboard selection*/
1779                 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1780                 selection = gtk_clipboard_wait_for_text (clipboard);
1781
1782                 /* Get focuesed widget */
1783                 focused = gtk_window_get_focus (GTK_WINDOW (win));
1784
1785                 /* Check dimming */
1786                 result = ((selection == NULL) || 
1787                           (MODEST_IS_ATTACHMENTS_VIEW (focused)));
1788                 
1789                 if (result)
1790                         modest_dimming_rule_set_notification (rule, "");
1791                 
1792                 if (selection != NULL) 
1793                         g_free(selection);
1794         }               
1795         else if (MODEST_IS_MAIN_WINDOW (win)) {
1796                 /* Check dimming */
1797                 result = state->n_selected == 0;
1798                 if (result)
1799                         modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));                  
1800         }
1801         
1802         return result;
1803 }
1804
1805
1806 static gboolean
1807 _invalid_attach_selected (ModestWindow *win,
1808                           gboolean unique,
1809                           gboolean for_view,
1810                           gboolean for_remove,
1811                           ModestDimmingRule *rule) 
1812 {
1813         GList *attachments, *node;
1814         gint n_selected;
1815         TnyHeaderFlags flags;
1816         gboolean nested_attachments = FALSE;
1817         gboolean selected_messages = FALSE;
1818         const DimmedState *state = NULL;
1819         gboolean result = FALSE;
1820
1821         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
1822         state = modest_window_get_dimming_state (win);
1823
1824         if (MODEST_IS_MAIN_WINDOW (win)) {
1825                 flags = TNY_HEADER_FLAG_ATTACHMENTS;
1826                 if (!result)
1827                         result = !state->any_has_attachments;
1828         }
1829         else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1830                 
1831                 /* Get selected atachments */
1832                 attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
1833                 n_selected = g_list_length (attachments);
1834
1835                 /* Check unique */              
1836                 if (!result) {
1837                         if (unique) 
1838                                 result = n_selected != 1;
1839                         else
1840                                 
1841                                 result = n_selected < 1;
1842                 }
1843                 
1844                 /* Check attached type (view operation not required) */
1845                 if (!result && !for_view)  {
1846                         for (node = attachments; node != NULL && !result; node = g_list_next (node)) {
1847                                 TnyMimePart *mime_part = TNY_MIME_PART (node->data);
1848                                 TnyList *nested_list = tny_simple_list_new ();
1849                                 if (!for_remove && TNY_IS_MSG (mime_part)) {
1850                                         selected_messages = TRUE;
1851                                         result = TRUE;
1852                                 }
1853                                 tny_mime_part_get_parts (mime_part, nested_list);
1854                                 if (!for_remove && tny_list_get_length (nested_list) > 0) {
1855                                         nested_attachments = TRUE;
1856                                         result = TRUE;
1857                                 }
1858                                 g_object_unref (nested_list);
1859                         }
1860                 }
1861                 
1862                 /* Set notifications */
1863                 if (result && rule != NULL) {
1864                         if (selected_messages) {
1865                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_save_attach_mail"));
1866                         } else if (nested_attachments) {
1867                                 modest_dimming_rule_set_notification (rule, _("FIXME:unable to save attachments with nested elements"));
1868                         } else if (n_selected == 0) {
1869                                 modest_dimming_rule_set_notification (rule, _("FIXME:no attachment selected"));
1870                         } else if (unique) {
1871                                 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_display_more"));
1872                         }
1873                 }
1874                 
1875                 /* Free */
1876                 g_list_free (attachments);
1877         }
1878
1879         return result;
1880 }
1881
1882 static gboolean
1883 _purged_attach_selected (ModestWindow *win, gboolean all, ModestDimmingRule *rule) 
1884 {
1885         GList *attachments = NULL, *node;
1886         gint purged = 0;
1887         gint n_attachments = 0;
1888         gboolean result = FALSE;
1889
1890         /* This should check if _all_ the attachments are already purged. If only some
1891          * of them are purged, then it does not cause dim as there's a confirmation dialog
1892          * for removing only local attachments */
1893
1894         /* Get selected atachments */
1895         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1896                 attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
1897         } else if (MODEST_IS_MAIN_WINDOW (win)) {
1898                 /* If we're in main window, we won't know if there are already purged attachments */
1899                 return FALSE;
1900         }
1901
1902         if (attachments == NULL)
1903                 return FALSE;
1904
1905         for (node = attachments; node != NULL; node = g_list_next (node)) {
1906                 TnyMimePart *mime_part = TNY_MIME_PART (node->data);
1907                 if (tny_mime_part_is_purged (mime_part)) {
1908                         purged++;
1909                 }
1910                 n_attachments++;
1911         }
1912                 
1913         /* Free */
1914         g_list_free (attachments);
1915
1916         if (all)
1917                 result = (purged == n_attachments);
1918         else
1919                 result = (purged > 0);
1920
1921         if (result && (rule != NULL))
1922                 modest_dimming_rule_set_notification (rule, _("mail_ib_attachment_already_purged"));
1923
1924         return result;
1925 }
1926
1927 static gboolean
1928 _invalid_msg_selected (ModestMainWindow *win,
1929                        gboolean unique,
1930                        ModestDimmingRule *rule) 
1931 {
1932         GtkWidget *folder_view = NULL;
1933         const DimmedState *state = NULL;
1934         gboolean result = FALSE;
1935
1936         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
1937         g_return_val_if_fail (MODEST_IS_DIMMING_RULE (rule), FALSE);
1938         state = modest_window_get_dimming_state (MODEST_WINDOW(win));
1939                 
1940         /* Get folder view to check focus */
1941         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1942                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
1943
1944         /* Check dimmed rule (TODO: check focus on widgets */   
1945         if (!result) {
1946                 result = ((state->n_selected == 0 ) ||
1947                           (gtk_widget_is_focus (folder_view)));
1948                 if (result)
1949                         modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));
1950         }
1951         if (!result && unique) {
1952                 result = state->n_selected > 1;
1953                 if (result)
1954                         modest_dimming_rule_set_notification (rule, _("mcen_ib_select_one_message"));
1955         }
1956
1957         return result;
1958 }
1959
1960
1961 static gboolean
1962 _msg_download_in_progress (ModestMsgViewWindow *win)
1963 {
1964         gboolean result = FALSE;
1965
1966         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), FALSE);
1967
1968         result = modest_msg_view_window_toolbar_on_transfer_mode (win);
1969
1970         return result;
1971 }
1972
1973 static gboolean
1974 _msg_download_completed (ModestMainWindow *win)
1975 {
1976         const DimmedState *state = modest_window_get_dimming_state (MODEST_WINDOW(win));
1977         return state->any_marked_as_cached;
1978 }
1979
1980 static void 
1981 fill_list_of_caches (gpointer key, gpointer value, gpointer userdata)
1982 {
1983         GSList **send_queues = (GSList **) userdata;
1984         *send_queues = g_slist_prepend (*send_queues, value);
1985 }
1986
1987 static gboolean
1988 _selected_msg_sent_in_progress (ModestWindow *win)
1989 {
1990         const DimmedState *state = modest_window_get_dimming_state (win);
1991         return state->sent_in_progress;
1992 }
1993
1994
1995 static gboolean
1996 _sending_in_progress (ModestWindow *win)
1997 {
1998         gboolean result = FALSE;
1999         
2000         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (win), FALSE);
2001
2002         /* Check if send operation is in progress */
2003         result = modest_main_window_send_receive_in_progress (MODEST_MAIN_WINDOW (win));
2004
2005         return result;
2006 }
2007
2008 static gboolean
2009 _invalid_folder_for_purge (ModestWindow *win, 
2010                            ModestDimmingRule *rule)
2011 {
2012         TnyMsg *msg = NULL;
2013         TnyFolder *folder = NULL;
2014         TnyAccount *account = NULL;
2015         gboolean result = FALSE;
2016
2017         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2018
2019                 /* Get folder and account of message */
2020                 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2021                 g_return_val_if_fail(msg != NULL, TRUE);                        
2022                 folder = tny_msg_get_folder (msg);      
2023                 if (folder == NULL) {
2024                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
2025                         goto frees;
2026                 }
2027                 g_object_unref (msg);
2028         } else if (MODEST_IS_MAIN_WINDOW (win)) {
2029                 GtkWidget *folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2030                                                                               MODEST_WIDGET_TYPE_FOLDER_VIEW);
2031                 if (!folder_view)
2032                         return FALSE;
2033                 folder = TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
2034                 if (folder == NULL || ! TNY_IS_FOLDER (folder))
2035                         goto frees;             
2036         } else {
2037                 g_return_val_if_reached (FALSE);
2038         }
2039         account = modest_tny_folder_get_account (folder);
2040         if (account == NULL) goto frees;                        
2041                 
2042         /* Check account */
2043         if (modest_tny_account_is_virtual_local_folders (TNY_ACCOUNT (account))) {
2044                 TnyFolderType types[2];
2045                 types[0] = TNY_FOLDER_TYPE_DRAFTS;
2046                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
2047                 
2048                 if (_selected_folder_is_any_of_type (win, types, 2)) {
2049                         result = TRUE;
2050                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_editable_msg"));
2051                 } else {
2052                         /* We're currently disabling purge in any local store */
2053                         result = TRUE;
2054                         modest_dimming_rule_set_notification (rule, _("mail_ib_unable_to_purge_attachments"));
2055                 }
2056         } else {
2057                 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2058                 /* If it's POP then dim */
2059                 if (modest_protocol_info_get_transport_store_protocol (proto_str) == 
2060                     MODEST_PROTOCOL_STORE_POP) {
2061                         GList *attachments = NULL;
2062                         gint n_selected = 0;
2063                         result = TRUE;
2064                         
2065                         /* TODO: This check is here to prevent a gwarning, but this looks like a logic error.
2066                          * murrayc */
2067                         if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2068                                 attachments = modest_msg_view_window_get_attachments (MODEST_MSG_VIEW_WINDOW(win));
2069                                 n_selected = g_list_length (attachments);
2070                                 g_list_free (attachments);
2071                         }
2072                         
2073                         modest_dimming_rule_set_notification (rule, 
2074                                                               ngettext ("mail_ib_unable_to_pure_attach_pop_mail_singular",
2075                                                                         "mail_ib_unable_to_pure_attach_pop_mail_plural", 
2076                                                                         n_selected));
2077                 }
2078         }
2079         
2080 frees:
2081         if (folder != NULL)
2082                 g_object_unref (folder);
2083         if (account != NULL)
2084                 g_object_unref (account);
2085         
2086         return result;
2087 }
2088
2089 static gboolean
2090 _transfer_mode_enabled (ModestWindow *win)
2091 {
2092         gboolean result = FALSE;
2093
2094         /* Check dimming */
2095         if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
2096                 result = modest_msg_view_window_transfer_mode_enabled (MODEST_MSG_VIEW_WINDOW (win));
2097         } else if (MODEST_IS_MAIN_WINDOW(win)) {
2098                 result = modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW (win));
2099         } else {
2100                 g_warning("_transfer_mode_enabled called with wrong window type");
2101         }
2102
2103         return result;
2104 }
2105