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 it's the local account do not dim */
84 if (modest_tny_folder_store_is_virtual_local_folders (parent_folder)) {
86 } else if (TNY_IS_ACCOUNT (parent_folder)) {
87 /* If it's the MMC root folder then dim it */
88 if (!strcmp (tny_account_get_id (TNY_ACCOUNT (parent_folder)), MODEST_MMC_ACCOUNT_ID)) {
91 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (parent_folder));
92 /* If it's POP then dim */
93 dimmed = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
94 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
97 /* TODO: the specs say that only one level of subfolder is allowed, is this true ? */
99 /* Apply folder rules */
100 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
107 modest_ui_dimming_rules_on_delete_folder (ModestWindow *win, gpointer user_data)
109 gboolean dimmed = FALSE;
111 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
113 /* Check dimmed rule */
115 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
117 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
123 modest_ui_dimming_rules_on_rename_folder (ModestWindow *win, gpointer user_data)
125 gboolean dimmed = FALSE;
127 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
129 /* Check dimmed rule */
131 dimmed = _selected_folder_not_writeable (MODEST_MAIN_WINDOW(win));
133 dimmed = _selected_folder_is_root (MODEST_MAIN_WINDOW(win));
139 modest_ui_dimming_rules_on_open_msg (ModestWindow *win, gpointer user_data)
141 ModestDimmingRule *rule = NULL;
142 gboolean dimmed = FALSE;
144 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
145 g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
146 rule = MODEST_DIMMING_RULE (user_data);
148 /* Check dimmed rule */
150 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data);
156 modest_ui_dimming_rules_on_reply_msg (ModestWindow *win, gpointer user_data)
158 ModestDimmingRule *rule = NULL;
159 gboolean dimmed = FALSE;
160 TnyFolderType types[3];
162 g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
163 rule = MODEST_DIMMING_RULE (user_data);
165 /* main window dimming rules */
166 if (MODEST_IS_MAIN_WINDOW(win)) {
168 types[0] = TNY_FOLDER_TYPE_DRAFTS;
169 types[1] = TNY_FOLDER_TYPE_OUTBOX;
170 types[2] = TNY_FOLDER_TYPE_ROOT;
172 /* Check dimmed rule */
174 dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 3);
175 modest_dimming_rule_set_notification (rule, _("mcen_ib_unable_to_reply"));
178 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));
179 modest_dimming_rule_set_notification (rule, _("mcen_ib_nothing_to_reply"));
182 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, rule);
184 /* msg view window dimming rules */
185 } else if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
187 /* Check dimmed rule */
189 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
197 modest_ui_dimming_rules_on_contents_msg (ModestWindow *win, gpointer user_data)
199 gboolean dimmed = FALSE;
201 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
203 /* Check dimmed rule */
204 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
210 modest_ui_dimming_rules_always_dimmed (ModestWindow *win, gpointer user_data)
212 gboolean dimmed = FALSE;
214 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
216 /* Check dimmed rule */
224 modest_ui_dimming_rules_on_delete_msg (ModestWindow *win, gpointer user_data)
226 ModestDimmingRule *rule = NULL;
227 gboolean dimmed = FALSE;
229 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
230 g_return_val_if_fail (MODEST_IS_DIMMING_RULE (user_data), FALSE);
231 rule = MODEST_DIMMING_RULE (user_data);
233 /* Check dimmed rule */
235 dimmed = _selected_folder_is_empty (MODEST_MAIN_WINDOW(win));
236 modest_dimming_rule_set_notification (rule, _("mcen_ib_nothing_to_del"));
239 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
240 modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));
243 dimmed = _already_opened_msg (win);
244 modest_dimming_rule_set_notification (rule, _("mcen_nc_unable_to_delete_n_messages"));
251 modest_ui_dimming_rules_on_details (ModestWindow *win, gpointer user_data)
253 gboolean dimmed = FALSE;
254 GtkWidget *header_view = NULL;
256 /* main window dimming rules */
257 if (MODEST_IS_MAIN_WINDOW(win)) {
259 /* Check dimmed rule */
260 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
261 MODEST_WIDGET_TYPE_HEADER_VIEW);
263 /* If the header view does not have the focus then do
264 not apply msg dimming rules because the action will
265 show the folder details that have no dimming
267 if (gtk_widget_is_focus (header_view)) {
268 /* Check dimmed rule */
270 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), TRUE, user_data);
273 /* msg view window dimming rules */
276 /* Check dimmed rule */
278 dimmed = _msg_download_in_progress (MODEST_MSG_VIEW_WINDOW(win));
285 modest_ui_dimming_rules_on_mark_as_read_msg (ModestWindow *win, gpointer user_data)
287 gboolean dimmed = FALSE;
288 TnyHeaderFlags flags;
290 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
292 flags = TNY_HEADER_FLAG_SEEN;
294 /* Check dimmed rule */
296 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
298 dimmed = _selected_msg_marked_as (win, flags, FALSE);
304 modest_ui_dimming_rules_on_mark_as_unread_msg (ModestWindow *win, gpointer user_data)
306 gboolean dimmed = FALSE;
307 TnyHeaderFlags flags;
309 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
311 flags = TNY_HEADER_FLAG_SEEN;
313 /* Check dimmed rule */
315 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
317 dimmed = _selected_msg_marked_as (win, flags, TRUE);
323 modest_ui_dimming_rules_on_move_to (ModestWindow *win, gpointer user_data)
325 gboolean dimmed = FALSE;
327 if (MODEST_IS_MAIN_WINDOW (win))
328 dimmed = modest_ui_dimming_rules_on_main_window_move_to (win, user_data);
330 dimmed = modest_ui_dimming_rules_on_view_window_move_to (win, user_data);
337 modest_ui_dimming_rules_on_main_window_move_to (ModestWindow *win, gpointer user_data)
339 GtkWidget *folder_view = NULL;
340 GtkWidget *header_view = NULL;
341 gboolean dimmed = FALSE;
343 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), TRUE);
345 /* Get the folder view */
346 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
347 MODEST_WIDGET_TYPE_FOLDER_VIEW);
349 /* Get header view */
350 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
351 MODEST_WIDGET_TYPE_HEADER_VIEW);
353 /* Check common diming rules */
355 /* Check diming rules for folder transfer */
356 if (gtk_widget_is_focus (folder_view)) {
358 dimmed = _selected_folder_not_writeable(MODEST_MAIN_WINDOW(win));
360 /* Check diming rules for msg transfer */
361 else if (gtk_widget_is_focus (header_view)) {
363 dimmed = _invalid_msg_selected (MODEST_MAIN_WINDOW(win), FALSE, user_data);
371 modest_ui_dimming_rules_on_view_window_move_to (ModestWindow *win, gpointer user_data)
373 gboolean dimmed = FALSE;
379 modest_ui_dimming_rules_on_paste_msgs (ModestWindow *win, gpointer user_data)
381 TnyFolderType types[3];
382 gboolean dimmed = FALSE;
384 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
386 types[0] = TNY_FOLDER_TYPE_DRAFTS;
387 types[1] = TNY_FOLDER_TYPE_OUTBOX;
388 types[2] = TNY_FOLDER_TYPE_SENT;
390 /* Check dimmed rule */
392 dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 3);
398 modest_ui_dimming_rules_on_delete_msgs (ModestWindow *win, gpointer user_data)
400 TnyFolderType types[5];
401 gboolean dimmed = FALSE;
403 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
405 types[0] = TNY_FOLDER_TYPE_DRAFTS;
406 types[1] = TNY_FOLDER_TYPE_OUTBOX;
407 types[2] = TNY_FOLDER_TYPE_SENT;
408 types[3] = TNY_FOLDER_TYPE_INBOX;
409 types[4] = TNY_FOLDER_TYPE_ROOT;
411 /* Check dimmed rule */
413 dimmed = _selected_folder_is_any_of_type (MODEST_MAIN_WINDOW(win), types, 5);
419 /* *********************** static utility functions ******************** */
422 _selected_folder_not_writeable (ModestMainWindow *win)
424 GtkWidget *folder_view = NULL;
425 TnyFolderStore *parent_folder = NULL;
426 ModestTnyFolderRules rules;
427 gboolean result = FALSE;
429 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
431 /* Get folder view */
432 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
433 MODEST_WIDGET_TYPE_FOLDER_VIEW);
434 /* If no folder view, always dimmed */
438 /* Get selected folder as parent of new folder to create */
439 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
440 if (!(parent_folder && TNY_IS_FOLDER(parent_folder)))
443 /* Check dimmed rule */
444 rules = modest_tny_folder_get_rules (TNY_FOLDER (parent_folder));
445 result = rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE;
448 g_object_unref (parent_folder);
454 _selected_folder_is_root (ModestMainWindow *win)
456 TnyFolderType types[2];
457 gboolean result = FALSE;
459 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
461 types[0] = TNY_FOLDER_TYPE_ROOT;
462 types[1] = TNY_FOLDER_TYPE_INBOX;
464 /* Check folder type */
465 result = _selected_folder_is_any_of_type (win, types, 2);
472 _selected_folder_is_empty (ModestMainWindow *win)
474 GtkWidget *folder_view = NULL;
475 TnyFolderStore *folder = NULL;
476 gboolean result = FALSE;
478 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
480 /* Get folder view */
481 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
482 MODEST_WIDGET_TYPE_FOLDER_VIEW);
483 /* If no folder view, always dimmed */
487 /* Get selected folder as parent of new folder to create */
488 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
489 if (!(folder && TNY_IS_FOLDER(folder)))
492 /* Check folder type */
493 result = tny_folder_get_all_count (TNY_FOLDER (folder)) == 0;
496 g_object_unref (folder);
502 _selected_folder_is_any_of_type (ModestMainWindow *win,
503 TnyFolderType types[],
506 GtkWidget *folder_view = NULL;
507 TnyFolderStore *folder = NULL;
508 gboolean result = FALSE;
510 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
512 /* Get folder view */
513 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
514 MODEST_WIDGET_TYPE_FOLDER_VIEW);
515 /* If no folder view, always dimmed */
519 /* Get selected folder as parent of new folder to create */
520 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
521 if (!(folder && TNY_IS_FOLDER(folder)))
524 /* Check folder type */
525 result = _folder_is_any_of_type (TNY_FOLDER(folder), types, ntypes);
528 g_object_unref (folder);
534 _folder_is_any_of_type (TnyFolder *folder,
535 TnyFolderType types[],
538 TnyFolderType folder_type;
539 gboolean result = FALSE;
542 g_return_val_if_fail (TNY_IS_FOLDER(folder), FALSE);
544 /* Get folder type */
545 if (modest_tny_folder_is_local_folder (folder))
546 folder_type = modest_tny_folder_get_local_folder_type (folder);
548 folder_type = modest_tny_folder_guess_folder_type (folder);
550 /* Check foler type */
551 for (i=0; i < ntypes; i++) {
552 result = result || folder_type == types[i];
561 _invalid_msg_selected (ModestMainWindow *win,
563 ModestDimmingRule *rule)
565 GtkWidget *header_view = NULL;
566 GtkWidget *folder_view = NULL;
567 TnyList *selected_headers = NULL;
568 gboolean result = FALSE;
570 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
571 g_return_val_if_fail (MODEST_IS_DIMMING_RULE (rule), FALSE);
573 /* Get header view to check selected messages */
574 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
575 MODEST_WIDGET_TYPE_HEADER_VIEW);
577 /* Get folder view to check focus */
578 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
579 MODEST_WIDGET_TYPE_FOLDER_VIEW);
581 /* Get selected headers */
582 selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
584 /* Check dimmed rule (TODO: check focus on widgets */
586 result = ((selected_headers == NULL) ||
587 (GTK_WIDGET_HAS_FOCUS (folder_view)));
588 modest_dimming_rule_set_notification (rule, _("mcen_ib_no_message_selected"));
591 result = tny_list_get_length (selected_headers) > 1;
592 modest_dimming_rule_set_notification (rule, _("mcen_ib_select_one_message"));
596 if (selected_headers != NULL)
597 g_object_unref (selected_headers);
603 _already_opened_msg (ModestWindow *win)
605 ModestWindow *window = NULL;
606 ModestWindowMgr *mgr = NULL;
607 GtkWidget *header_view = NULL;
608 TnyList *selected_headers = NULL;
609 TnyIterator *iter = NULL;
610 TnyHeader *header = NULL;
611 gboolean result = TRUE;
613 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(win), FALSE);
615 /* Get header view to check selected messages */
616 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
617 MODEST_WIDGET_TYPE_HEADER_VIEW);
619 /* Get selected headers */
620 selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
621 if (selected_headers == NULL)
624 /* Check dimmed rule (TODO: check focus on widgets */
625 mgr = modest_runtime_get_window_mgr ();
626 iter = tny_list_create_iterator (selected_headers);
627 while (!tny_iterator_is_done (iter) && result) {
628 header = TNY_HEADER (tny_iterator_get_current (iter));
629 window = modest_window_mgr_find_window_by_header (mgr, header);
630 result = result && (window != NULL);
632 g_object_unref (header);
633 tny_iterator_next (iter);
637 if (selected_headers != NULL)
638 g_object_unref (selected_headers);
640 g_object_unref (iter);
646 _selected_msg_marked_as (ModestWindow *win,
650 GtkWidget *header_view = NULL;
651 TnyList *selected_headers = NULL;
652 TnyIterator *iter = NULL;
653 TnyHeader *header = NULL;
654 TnyHeaderFlags flags;
655 gboolean result = FALSE;
657 /* Get header view to check selected messages */
658 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
659 MODEST_WIDGET_TYPE_HEADER_VIEW);
661 /* Get selected headers */
662 selected_headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
663 if (selected_headers == NULL)
666 /* Call the function for each header */
667 iter = tny_list_create_iterator (selected_headers);
668 while (!tny_iterator_is_done (iter) && !result) {
669 header = TNY_HEADER (tny_iterator_get_current (iter));
671 flags = tny_header_get_flags (header);
673 result = (flags & mask) == 0;
675 result = (flags & mask) != 0;
677 g_object_unref (header);
678 tny_iterator_next (iter);
682 if (selected_headers != NULL)
683 g_object_unref (selected_headers);
685 g_object_unref (iter);
691 _msg_download_in_progress (ModestMsgViewWindow *win)
693 gboolean result = FALSE;
695 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win), FALSE);