1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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.
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.
32 #endif /*HAVE_CONFIG_H*/
35 #include "modest-ui-dimming-rules.h"
36 #include "modest-dimming-rule.h"
37 #include "modest-tny-folder.h"
38 #include <modest-runtime.h>
41 static gboolean _folder_is_any_of_type (TnyFolder *folder, TnyFolderType types[], guint ntypes);
42 static gboolean _invalid_msg_selected (ModestMainWindow *win, gboolean unique, ModestDimmingRule *rule);
43 static gboolean _already_opened_msg (ModestWindow *win);
44 static gboolean _selected_msg_marked_as (ModestWindow *win, TnyHeaderFlags mask, gboolean opposite);
45 static gboolean _selected_folder_not_writeable (ModestMainWindow *win);
46 static gboolean _selected_folder_is_any_of_type (ModestMainWindow *win, TnyFolderType types[], guint ntypes);
47 static gboolean _selected_folder_is_root (ModestMainWindow *win);
48 static gboolean _selected_folder_is_empty (ModestMainWindow *win);
49 static gboolean _msg_download_in_progress (ModestMsgViewWindow *win);
53 modest_ui_dimming_rules_on_new_msg (ModestWindow *win, gpointer user_data)
55 gboolean dimmed = FALSE;
57 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win), FALSE);
59 /* Check dimmed rule */
61 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
67 modest_ui_dimming_rules_on_new_folder (ModestWindow *win, gpointer user_data)
69 gboolean dimmed = FALSE;
70 GtkWidget *folder_view = NULL;
71 TnyFolderStore *parent_folder = NULL;
73 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
76 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
77 MODEST_WIDGET_TYPE_FOLDER_VIEW);
78 /* Get selected folder as parent of new folder to create */
79 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
83 if (TNY_IS_ACCOUNT (parent_folder)) {
84 /* If it's the local account then do not dim */
85 if (modest_tny_account_is_virtual_local_folders (
86 TNY_ACCOUNT (parent_folder)))
89 /* If it's the MMC root folder then dim it */
90 if (!strcmp (tny_account_get_id (TNY_ACCOUNT (parent_folder)), MODEST_MMC_ACCOUNT_ID)) {
93 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (parent_folder));
94 /* If it's POP then dim */
95 dimmed = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
96 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
100 /* TODO: the specs say that only one level of subfolder is allowed, is this true ? */
102 /* Apply folder rules */
103 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
110 modest_ui_dimming_rules_on_delete_folder (ModestWindow *win, gpointer user_data)
112 gboolean dimmed = FALSE;
114 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
116 /* Check dimmed rule */
118 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
120 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
126 modest_ui_dimming_rules_on_rename_folder (ModestWindow *win, gpointer user_data)
128 gboolean dimmed = FALSE;
130 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
132 /* Check dimmed rule */
134 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
136 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
142 modest_ui_dimming_rules_on_open_msg (ModestWindow *win, gpointer user_data)
144 ModestDimmingRule *rule = NULL;
145 gboolean dimmed = FALSE;
147 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
148 g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
149 rule = MODEST_DIMMING_RULE (user_data);
151 /* Check dimmed rule */
153 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data);
159 modest_ui_dimming_rules_on_reply_msg (ModestWindow *win, gpointer user_data)
161 ModestDimmingRule *rule = NULL;
162 gboolean dimmed = FALSE;
163 TnyFolderType types[3];
165 g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
166 rule = MODEST_DIMMING_RULE (user_data);
168 /* main window dimming rules */
169 if (MODEST_IS_MAIN_WINDOW(win)) {
171 types[0] = TNY_FOLDER_TYPE_DRAFTS;
172 types[1] = TNY_FOLDER_TYPE_OUTBOX;
173 types[2] = TNY_FOLDER_TYPE_ROOT;
175 /* Check dimmed rule */
177 dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 3);
178 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_reply"));
181 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));
182 modest_dimming_rule_set_notification (rule, _("mcen_ib_nothing_to_reply"));
185 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, rule);
187 /* msg view window dimming rules */
188 } else if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
190 /* Check dimmed rule */
192 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
200 modest_ui_dimming_rules_on_contents_msg (ModestWindow *win, gpointer user_data)
202 gboolean dimmed = FALSE;
204 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
206 /* Check dimmed rule */
207 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
213 modest_ui_dimming_rules_always_dimmed (ModestWindow *win, gpointer user_data)
215 gboolean dimmed = FALSE;
217 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
219 /* Check dimmed rule */
227 modest_ui_dimming_rules_on_delete_msg (ModestWindow *win, gpointer user_data)
229 ModestDimmingRule *rule = NULL;
230 gboolean dimmed = FALSE;
232 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
233 g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
234 rule = MODEST_DIMMING_RULE (user_data);
236 /* Check dimmed rule */
238 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));
239 modest_dimming_rule_set_notification (rule, _("mcen_ib_nothing_to_del"));
242 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
243 modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));
246 dimmed = _already_opened_msg (win);
247 modest_dimming_rule_set_notification (rule, _("mcen_nc_unable_to_delete_n_messages"));
254 modest_ui_dimming_rules_on_details (ModestWindow *win, gpointer user_data)
256 gboolean dimmed = FALSE;
257 GtkWidget *header_view = NULL;
259 /* main window dimming rules */
260 if (MODEST_IS_MAIN_WINDOW(win)) {
262 /* Check dimmed rule */
263 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
264 MODEST_WIDGET_TYPE_HEADER_VIEW);
266 /* If the header view does not have the focus then do
267 not apply msg dimming rules because the action will
268 show the folder details that have no dimming
270 if (gtk_widget_is_focus (header_view)) {
271 /* Check dimmed rule */
273 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data);
276 /* msg view window dimming rules */
279 /* Check dimmed rule */
281 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
288 modest_ui_dimming_rules_on_mark_as_read_msg (ModestWindow *win, gpointer user_data)
290 gboolean dimmed = FALSE;
291 TnyHeaderFlags flags;
293 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
295 flags = TNY_HEADER_FLAG_SEEN;
297 /* Check dimmed rule */
299 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
301 dimmed = _selected_msg_marked_as (win, flags, FALSE);
307 modest_ui_dimming_rules_on_mark_as_unread_msg (ModestWindow *win, gpointer user_data)
309 gboolean dimmed = FALSE;
310 TnyHeaderFlags flags;
312 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
314 flags = TNY_HEADER_FLAG_SEEN;
316 /* Check dimmed rule */
318 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
320 dimmed = _selected_msg_marked_as (win, flags, TRUE);
326 modest_ui_dimming_rules_on_move_to (ModestWindow *win, gpointer user_data)
328 gboolean dimmed = FALSE;
330 if (MODEST_IS_MAIN_WINDOW (win))
331 dimmed = modest_ui_dimming_rules_on_main_window_move_to (win, user_data);
333 dimmed = modest_ui_dimming_rules_on_view_window_move_to (win, user_data);
340 modest_ui_dimming_rules_on_main_window_move_to (ModestWindow *win, gpointer user_data)
342 GtkWidget *folder_view = NULL;
343 GtkWidget *header_view = NULL;
344 gboolean dimmed = FALSE;
346 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
348 /* Get the folder view */
349 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
350 MODEST_WIDGET_TYPE_FOLDER_VIEW);
352 /* Get header view */
353 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
354 MODEST_WIDGET_TYPE_HEADER_VIEW);
356 /* Check common diming rules */
358 /* Check diming rules for folder transfer */
359 if (gtk_widget_is_focus (folder_view)) {
361 dimmed = _selected_folder_not_writeable(MODEST_MAIN_WINDOW(win));
363 /* Check diming rules for msg transfer */
364 else if (gtk_widget_is_focus (header_view)) {
366 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
374 modest_ui_dimming_rules_on_view_window_move_to (ModestWindow *win, gpointer user_data)
376 gboolean dimmed = FALSE;
382 modest_ui_dimming_rules_on_paste_msgs (ModestWindow *win, gpointer user_data)
384 TnyFolderType types[3];
385 gboolean dimmed = FALSE;
387 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
389 types[0] = TNY_FOLDER_TYPE_DRAFTS;
390 types[1] = TNY_FOLDER_TYPE_OUTBOX;
391 types[2] = TNY_FOLDER_TYPE_SENT;
393 /* Check dimmed rule */
395 dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 3);
401 modest_ui_dimming_rules_on_delete_msgs (ModestWindow *win, gpointer user_data)
403 TnyFolderType types[5];
404 gboolean dimmed = FALSE;
406 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
408 types[0] = TNY_FOLDER_TYPE_DRAFTS;
409 types[1] = TNY_FOLDER_TYPE_OUTBOX;
410 types[2] = TNY_FOLDER_TYPE_SENT;
411 types[3] = TNY_FOLDER_TYPE_INBOX;
412 types[4] = TNY_FOLDER_TYPE_ROOT;
414 /* Check dimmed rule */
416 dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 5);
422 /* *********************** static utility functions ******************** */
425 _selected_folder_not_writeable (ModestMainWindow *win)
427 GtkWidget *folder_view = NULL;
428 TnyFolderStore *parent_folder = NULL;
429 ModestTnyFolderRules rules;
430 gboolean result = FALSE;
432 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
434 /* Get folder view */
435 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
436 MODEST_WIDGET_TYPE_FOLDER_VIEW);
437 /* If no folder view, always dimmed */
441 /* Get selected folder as parent of new folder to create */
442 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
443 if (!(parent_folder && TNY_IS_FOLDER(parent_folder)))
446 /* Check dimmed rule */
447 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
448 result = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
451 g_object_unref (parent_folder);
457 _selected_folder_is_root (ModestMainWindow *win)
459 TnyFolderType types[2];
460 gboolean result = FALSE;
462 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
464 types[0] = TNY_FOLDER_TYPE_ROOT;
465 types[1] = TNY_FOLDER_TYPE_INBOX;
467 /* Check folder type */
468 result = _selected_folder_is_any_of_type (win, types, 2);
475 _selected_folder_is_empty (ModestMainWindow *win)
477 GtkWidget *folder_view = NULL;
478 TnyFolderStore *folder = NULL;
479 gboolean result = FALSE;
481 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
483 /* Get folder view */
484 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
485 MODEST_WIDGET_TYPE_FOLDER_VIEW);
486 /* If no folder view, always dimmed */
490 /* Get selected folder as parent of new folder to create */
491 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
492 if (!(folder && TNY_IS_FOLDER(folder)))
495 /* Check folder type */
496 result = tny_folder_get_all_count (TNY_FOLDER (folder)) == 0;
499 g_object_unref (folder);
505 _selected_folder_is_any_of_type (ModestMainWindow *win,
506 TnyFolderType types[],
509 GtkWidget *folder_view = NULL;
510 TnyFolderStore *folder = NULL;
511 gboolean result = FALSE;
513 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
515 /* Get folder view */
516 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
517 MODEST_WIDGET_TYPE_FOLDER_VIEW);
518 /* If no folder view, always dimmed */
522 /* Get selected folder as parent of new folder to create */
523 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
524 if (!(folder && TNY_IS_FOLDER(folder)))
527 /* Check folder type */
528 result = _folder_is_any_of_type (TNY_FOLDER(folder), types, ntypes);
531 g_object_unref (folder);
537 _folder_is_any_of_type (TnyFolder *folder,
538 TnyFolderType types[],
541 TnyFolderType folder_type;
542 gboolean result = FALSE;
545 g_return_val_if_fail (TNY_IS_FOLDER(folder), FALSE);
547 /* Get folder type */
548 if (modest_tny_folder_is_local_folder (folder))
549 folder_type = modest_tny_folder_get_local_folder_type (folder);
551 folder_type = modest_tny_folder_guess_folder_type (folder);
553 /* Check foler type */
554 for (i=0; i < ntypes; i++) {
555 result = result || folder_type == types[i];
564 _invalid_msg_selected (ModestMainWindow *win,
566 ModestDimmingRule *rule)
568 GtkWidget *header_view = NULL;
569 GtkWidget *folder_view = NULL;
570 TnyList *selected_headers = NULL;
571 gboolean result = FALSE;
573 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
574 g_return_val_if_fail (MODEST_IS_DIMMING_RULE (rule), FALSE);
576 /* Get header view to check selected messages */
577 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
578 MODEST_WIDGET_TYPE_HEADER_VIEW);
580 /* Get folder view to check focus */
581 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
582 MODEST_WIDGET_TYPE_FOLDER_VIEW);
584 /* Get selected headers */
585 selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
587 /* Check dimmed rule (TODO: check focus on widgets */
589 result = ((selected_headers == NULL) ||
590 (GTK_WIDGET_HAS_FOCUS (folder_view)));
591 modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));
594 result = tny_list_get_length (selected_headers) > 1;
595 modest_dimming_rule_set_notification (rule, _("mcen_ib_select_one_message"));
599 if (selected_headers != NULL)
600 g_object_unref (selected_headers);
606 _already_opened_msg (ModestWindow *win)
608 ModestWindow *window = NULL;
609 ModestWindowMgr *mgr = NULL;
610 GtkWidget *header_view = NULL;
611 TnyList *selected_headers = NULL;
612 TnyIterator *iter = NULL;
613 TnyHeader *header = NULL;
614 gboolean result = TRUE;
616 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
618 /* Get header view to check selected messages */
619 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
620 MODEST_WIDGET_TYPE_HEADER_VIEW);
622 /* Get selected headers */
623 selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
624 if (selected_headers == NULL)
627 /* Check dimmed rule (TODO: check focus on widgets */
628 mgr = modest_runtime_get_window_mgr ();
629 iter = tny_list_create_iterator (selected_headers);
630 while (!tny_iterator_is_done (iter) && result) {
631 header = TNY_HEADER (tny_iterator_get_current (iter));
632 window = modest_window_mgr_find_window_by_header (mgr, header);
633 result = result && (window != NULL);
635 g_object_unref (header);
636 tny_iterator_next (iter);
640 if (selected_headers != NULL)
641 g_object_unref (selected_headers);
643 g_object_unref (iter);
649 _selected_msg_marked_as (ModestWindow *win,
653 GtkWidget *header_view = NULL;
654 TnyList *selected_headers = NULL;
655 TnyIterator *iter = NULL;
656 TnyHeader *header = NULL;
657 TnyHeaderFlags flags;
658 gboolean result = FALSE;
660 /* Get header view to check selected messages */
661 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
662 MODEST_WIDGET_TYPE_HEADER_VIEW);
664 /* Get selected headers */
665 selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
666 if (selected_headers == NULL)
669 /* Call the function for each header */
670 iter = tny_list_create_iterator (selected_headers);
671 while (!tny_iterator_is_done (iter) && !result) {
672 header = TNY_HEADER (tny_iterator_get_current (iter));
674 flags = tny_header_get_flags (header);
676 result = (flags & mask) == 0;
678 result = (flags & mask) != 0;
680 g_object_unref (header);
681 tny_iterator_next (iter);
685 if (selected_headers != NULL)
686 g_object_unref (selected_headers);
688 g_object_unref (iter);
694 _msg_download_in_progress (ModestMsgViewWindow *win)
696 gboolean result = FALSE;
698 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), FALSE);