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