* Add the MsgView Window dimming rules file.
[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 "modest-ui-dimming-rules.h"
35 #include "modest-tny-folder.h"
36 #include <modest-runtime.h>
37
38
39 static gboolean _folder_is_any_of_type (TnyFolder *folder, TnyFolderType types[], guint ntypes);
40 static gboolean _invalid_msg_selected (ModestMainWindow *win, gboolean unique);
41 static gboolean _already_opened_msg (ModestWindow *win);
42 static gboolean _selected_msg_marked_as (ModestWindow *win, TnyHeaderFlags mask, gboolean opposite);
43 static gboolean _selected_folder_not_writeable (ModestMainWindow *win);
44 static gboolean _selected_folder_is_any_of_type (ModestMainWindow *win, TnyFolderType types[], guint ntypes);
45 static gboolean _selected_folder_is_root (ModestMainWindow *win);
46 static gboolean _msg_download_in_progress (ModestMsgViewWindow *win);
47
48
49 gboolean 
50 modest_ui_dimming_rules_on_new_msg (ModestWindow *win, gpointer user_data)
51 {
52         gboolean dimmed = FALSE;
53
54         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
55                 
56         /* Check dimmed rule */ 
57         if (!dimmed)
58                 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
59
60         return dimmed;
61 }
62
63 gboolean 
64 modest_ui_dimming_rules_on_new_folder (ModestWindow *win, gpointer user_data)
65 {
66         gboolean dimmed = FALSE;
67
68         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
69                 
70         /* Check dimmed rule */ 
71         if (!dimmed)
72                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
73
74         return dimmed;
75 }
76
77 gboolean 
78 modest_ui_dimming_rules_on_rename_folder (ModestWindow *win, gpointer user_data)
79 {
80         gboolean dimmed = FALSE;
81
82         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
83                 
84         /* Check dimmed rule */ 
85         if (!dimmed)
86                 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
87         if (!dimmed)
88                 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
89
90         return dimmed;
91 }
92
93 gboolean 
94 modest_ui_dimming_rules_on_open_msg (ModestWindow *win, gpointer user_data)
95 {
96         gboolean dimmed = FALSE;
97
98         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
99                 
100         /* Check dimmed rule */ 
101         if (!dimmed)
102                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE);
103
104         return dimmed;
105 }
106
107 gboolean 
108 modest_ui_dimming_rules_on_reply_msg (ModestWindow *win, gpointer user_data)
109 {
110         gboolean dimmed = FALSE;
111         TnyFolderType types[3];
112
113         /* main window dimming rules */
114         if (MODEST_IS_MAIN_WINDOW(win)) {
115                 
116                 types[0] = TNY_FOLDER_TYPE_DRAFTS; 
117                 types[1] = TNY_FOLDER_TYPE_OUTBOX;
118                 types[2] = TNY_FOLDER_TYPE_ROOT;
119                 
120                 /* Check dimmed rule */ 
121                 if (!dimmed)
122                         dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 3);
123                 
124                 if (!dimmed)
125                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE);
126
127         /* msg view window dimming rules */
128         } else if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
129                 
130                 /* Check dimmed rule */ 
131                 if (!dimmed)
132                         dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
133         }
134         
135         return dimmed;
136 }
137
138
139 gboolean 
140 modest_ui_dimming_rules_on_contents_msg (ModestWindow *win, gpointer user_data)
141 {
142         gboolean dimmed = FALSE;
143
144         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
145                 
146         /* Check dimmed rule */ 
147         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE);
148
149         return dimmed;
150 }
151
152 gboolean 
153 modest_ui_dimming_rules_always_dimmed (ModestWindow *win, gpointer user_data)
154 {
155         gboolean dimmed = FALSE;
156
157         g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
158                 
159         /* Check dimmed rule */ 
160         if (!dimmed)
161                 dimmed = TRUE;
162
163         return dimmed;
164 }
165
166 gboolean 
167 modest_ui_dimming_rules_on_delete_msg (ModestWindow *win, gpointer user_data)
168 {
169         gboolean dimmed = FALSE;
170         
171         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
172         
173         /* Check dimmed rule */ 
174         if (!dimmed)
175                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE);
176         if (!dimmed)
177                 dimmed = _already_opened_msg (win);
178         
179         return dimmed;
180 }
181
182 gboolean 
183 modest_ui_dimming_rules_on_details_msg (ModestWindow *win, gpointer user_data)
184 {
185         gboolean dimmed = FALSE;
186         
187         /* main window dimming rules */
188         if (MODEST_IS_MAIN_WINDOW(win)) {
189                 
190                 /* Check dimmed rule */ 
191                 if (!dimmed)
192                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE);
193
194         /* msg view window dimming rules */
195         } else {
196
197                 /* Check dimmed rule */ 
198                 if (!dimmed)
199                         dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
200         }
201
202         return dimmed;
203 }
204
205 gboolean 
206 modest_ui_dimming_rules_on_mark_as_read_msg (ModestWindow *win, gpointer user_data)
207 {
208         gboolean dimmed = FALSE;
209         TnyHeaderFlags flags;
210
211         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
212         
213         flags = TNY_HEADER_FLAG_SEEN; 
214
215         /* Check dimmed rule */ 
216         if (!dimmed)
217                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE);
218         if (!dimmed) 
219                 dimmed = _selected_msg_marked_as (win, flags, FALSE);
220         
221         return dimmed;
222 }
223
224 gboolean 
225 modest_ui_dimming_rules_on_mark_as_unread_msg (ModestWindow *win, gpointer user_data)
226 {
227         gboolean dimmed = FALSE;
228         TnyHeaderFlags flags;
229
230         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
231         
232         flags = TNY_HEADER_FLAG_SEEN; 
233
234         /* Check dimmed rule */ 
235         if (!dimmed)
236                 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE);
237         if (!dimmed) 
238                 dimmed = _selected_msg_marked_as (win, flags, TRUE);
239
240         return dimmed;
241 }
242
243 gboolean 
244 modest_ui_dimming_rules_on_move_to (ModestWindow *win, gpointer user_data)
245 {
246         gboolean dimmed = FALSE;
247
248         if (MODEST_IS_MAIN_WINDOW (win)) 
249                 dimmed = modest_ui_dimming_rules_on_main_window_move_to (win, user_data);
250         else 
251                 dimmed = modest_ui_dimming_rules_on_view_window_move_to (win, user_data);
252
253         return dimmed;
254 }
255
256
257 gboolean 
258 modest_ui_dimming_rules_on_main_window_move_to (ModestWindow *win, gpointer user_data)
259 {
260         GtkWidget *folder_view = NULL;
261         GtkWidget *header_view = NULL;
262         gboolean dimmed = FALSE;
263         
264         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
265         
266         /* Get the folder view */
267         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
268                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
269
270         /* Get header view */
271         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
272                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
273
274         /* Check common diming rules */
275
276         /* Check diming rules for folder transfer  */
277         if (gtk_widget_is_focus (folder_view)) {
278                 if (!dimmed) 
279                         dimmed = _selected_folder_not_writeable(MODEST_MAIN_WINDOW(win));
280         }
281         /* Check diming rules for msg transfer  */
282         else if (gtk_widget_is_focus (header_view)) {
283                 if (!dimmed)
284                         dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE);
285                 
286         }
287
288         return dimmed;
289 }
290
291 gboolean 
292 modest_ui_dimming_rules_on_view_window_move_to (ModestWindow *win, gpointer user_data)
293 {
294         gboolean dimmed = FALSE;
295
296         return dimmed;
297 }
298
299 gboolean 
300 modest_ui_dimming_rules_on_paste_msgs (ModestWindow *win, gpointer user_data)
301 {
302         TnyFolderType types[3];
303         gboolean dimmed = FALSE;
304
305         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
306
307         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
308         types[1] = TNY_FOLDER_TYPE_OUTBOX;
309         types[2] = TNY_FOLDER_TYPE_SENT;
310         
311         /* Check dimmed rule */ 
312         if (!dimmed)
313                 dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 3);
314
315         return dimmed;
316 }
317
318 gboolean 
319 modest_ui_dimming_rules_on_delete_msgs (ModestWindow *win, gpointer user_data)
320 {
321         TnyFolderType types[5];
322         gboolean dimmed = FALSE;
323
324         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
325
326         types[0] = TNY_FOLDER_TYPE_DRAFTS; 
327         types[1] = TNY_FOLDER_TYPE_OUTBOX;
328         types[2] = TNY_FOLDER_TYPE_SENT;
329         types[3] = TNY_FOLDER_TYPE_INBOX;
330         types[4] = TNY_FOLDER_TYPE_ROOT;
331         
332         /* Check dimmed rule */ 
333         if (!dimmed)
334                 dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 5);
335
336         return dimmed;
337 }
338
339
340 /* *********************** static utility functions ******************** */
341
342 static gboolean
343 _selected_folder_not_writeable (ModestMainWindow *win)
344 {
345         GtkWidget *folder_view = NULL;
346         TnyFolderStore *parent_folder = NULL;
347         ModestTnyFolderRules rules;
348         gboolean result = FALSE;
349
350         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
351
352         /* Get folder view */
353         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
354                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
355         /* If no folder view, always dimmed */
356         if (!folder_view)
357                 return TRUE;
358         
359         /* Get selected folder as parent of new folder to create */
360         parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
361         if (!(parent_folder || TNY_IS_FOLDER(parent_folder)))
362                 return TRUE;
363         
364         /* Check dimmed rule */ 
365         rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
366         result = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
367
368         /* free */
369         g_object_unref (parent_folder);
370
371         return result;
372 }
373
374 static gboolean
375 _selected_folder_is_root (ModestMainWindow *win)
376 {
377         TnyFolderType types[2];
378         gboolean result = FALSE;
379
380         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
381
382         types[0] = TNY_FOLDER_TYPE_ROOT; 
383         types[1] = TNY_FOLDER_TYPE_INBOX; 
384
385         /* Check folder type */
386         result = _selected_folder_is_any_of_type (win, types, 2);
387
388         return result;
389 }
390
391 static gboolean
392 _selected_folder_is_any_of_type (ModestMainWindow *win,
393                                  TnyFolderType types[], 
394                                  guint ntypes)
395 {
396         GtkWidget *folder_view = NULL;
397         TnyFolderStore *folder = NULL;
398         gboolean result = FALSE;
399
400         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
401
402         /* Get folder view */
403         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
404                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
405         /* If no folder view, always dimmed */
406         if (!folder_view)
407                 return TRUE;
408         
409         /* Get selected folder as parent of new folder to create */
410         folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
411         if (!(folder || TNY_IS_FOLDER(folder)))
412                 return TRUE;
413         
414         /* Check folder type */
415         result = _folder_is_any_of_type (TNY_FOLDER(folder), types, ntypes);
416
417         /* free */
418         g_object_unref (folder);
419
420         return result;  
421 }
422
423 static gboolean
424 _folder_is_any_of_type (TnyFolder *folder,
425                         TnyFolderType types[], 
426                         guint ntypes)
427 {
428         TnyFolderType folder_type;
429         gboolean result = FALSE;
430         guint i;
431
432         g_return_val_if_fail (TNY_IS_FOLDER(folder), FALSE);
433
434         /* Get folder type */
435         if (modest_tny_folder_is_local_folder (folder))
436                 folder_type = modest_tny_folder_get_local_folder_type (folder);         
437         else 
438                 folder_type = modest_tny_folder_guess_folder_type (folder);             
439         
440         /* Check foler type */
441         for (i=0; i < ntypes; i++) {
442                 result = result || folder_type == types[i];
443         }
444
445         return result;
446 }
447
448
449
450 static gboolean
451 _invalid_msg_selected (ModestMainWindow *win,
452                        gboolean unique) 
453 {
454         GtkWidget *header_view = NULL;          
455         GtkWidget *folder_view = NULL;
456         TnyList *selected_headers = NULL;
457         gboolean result = FALSE;
458
459         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
460                 
461         /* Get header view to check selected messages */
462         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
463                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
464         
465         /* Get folder view to check focus */
466         folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
467                                                            MODEST_WIDGET_TYPE_FOLDER_VIEW);
468
469         /* Get selected headers */
470         selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
471
472         /* Check dimmed rule (TODO: check focus on widgets */   
473         result = ((selected_headers == NULL) || 
474                   (GTK_WIDGET_HAS_FOCUS (folder_view)));
475         if (!result)
476                 result = tny_list_get_length (selected_headers) > 1;
477         
478         /* free */
479         if (selected_headers != NULL) 
480                 g_object_unref (selected_headers);
481
482         return result;
483 }
484
485 static gboolean
486 _already_opened_msg (ModestWindow *win)
487 {
488         ModestWindow *window = NULL;
489         ModestWindowMgr *mgr = NULL;
490         GtkWidget *header_view = NULL;          
491         TnyList *selected_headers = NULL;
492         TnyIterator *iter = NULL;
493         TnyHeader *header = NULL;
494         gboolean result = TRUE;
495
496         g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
497                 
498         /* Get header view to check selected messages */
499         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
500                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
501
502         /* Get selected headers */
503         selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
504         if (selected_headers == NULL) 
505                 return FALSE;
506
507         /* Check dimmed rule (TODO: check focus on widgets */   
508         mgr = modest_runtime_get_window_mgr ();
509         iter = tny_list_create_iterator (selected_headers);
510         while (!tny_iterator_is_done (iter) && result) {        
511                 header = TNY_HEADER (tny_iterator_get_current (iter));
512                 window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
513                 result = result && (window != NULL);
514                         
515                 g_object_unref (header);
516                 tny_iterator_next (iter);
517         }
518         
519         /* free */
520         if (selected_headers != NULL) 
521                 g_object_unref (selected_headers);
522         if (iter != NULL)
523                 g_object_unref (iter);
524                 
525         return result;
526 }
527
528 static gboolean
529 _selected_msg_marked_as (ModestWindow *win, 
530                          TnyHeaderFlags mask, 
531                          gboolean opposite)
532 {
533         GtkWidget *header_view = NULL;
534         TnyList *selected_headers = NULL;
535         TnyIterator *iter = NULL;
536         TnyHeader *header = NULL;
537         TnyHeaderFlags flags;
538         gboolean result = FALSE;
539
540         /* Get header view to check selected messages */
541         header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
542                                                            MODEST_WIDGET_TYPE_HEADER_VIEW);
543
544         /* Get selected headers */
545         selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
546         if (selected_headers == NULL) 
547                 return TRUE;
548         
549         /* Call the function for each header */
550         iter = tny_list_create_iterator (selected_headers);
551         while (!tny_iterator_is_done (iter) && !result) {
552                 header = TNY_HEADER (tny_iterator_get_current (iter));
553
554                 flags = tny_header_get_flags (header);
555                 if (opposite)
556                         result = (flags & mask) == 0; 
557                 else
558                         result = (flags & mask) != 0; 
559
560                 g_object_unref (header);
561                 tny_iterator_next (iter);
562         }
563
564         /* free */
565         if (selected_headers != NULL) 
566                 g_object_unref (selected_headers);
567         if (iter != NULL)
568                 g_object_unref (iter);
569
570         return result;
571 }
572
573 static gboolean
574 _msg_download_in_progress (ModestMsgViewWindow *win)
575 {
576         gboolean result = FALSE;
577
578         g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), FALSE);
579
580         return result;
581 }