Serenity Operating System
1/*
2 * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
3 * Copyright (c) 2022, the SerenityOS developers.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include "MailboxTreeModel.h"
9#include "AccountHolder.h"
10
11MailboxTreeModel::MailboxTreeModel(AccountHolder const& account_holder)
12 : m_account_holder(account_holder)
13{
14 m_mail_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/app-mail.png"sv).release_value_but_fixme_should_propagate_errors());
15 m_folder_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/filetype-folder.png"sv).release_value_but_fixme_should_propagate_errors());
16 m_account_icon.set_bitmap_for_size(16, Gfx::Bitmap::load_from_file("/res/icons/16x16/home-directory.png"sv).release_value_but_fixme_should_propagate_errors());
17}
18
19GUI::ModelIndex MailboxTreeModel::index(int row, int column, GUI::ModelIndex const& parent) const
20{
21 if (!parent.is_valid()) {
22 if (m_account_holder.accounts().is_empty())
23 return {};
24 return create_index(row, column, &m_account_holder.accounts().at(row));
25 }
26 auto& base_node = *static_cast<BaseNode*>(parent.internal_data());
27
28 if (is<MailboxNode>(base_node)) {
29 auto& remote_mailbox = verify_cast<MailboxNode>(base_node);
30 return create_index(row, column, &remote_mailbox.children().at(row));
31 }
32
33 auto& remote_parent = verify_cast<AccountNode>(base_node);
34 return create_index(row, column, &remote_parent.mailboxes().at(row));
35}
36
37GUI::ModelIndex MailboxTreeModel::parent_index(GUI::ModelIndex const& index) const
38{
39 if (!index.is_valid())
40 return {};
41
42 auto& base_node = *static_cast<BaseNode*>(index.internal_data());
43
44 if (is<AccountNode>(base_node))
45 return {};
46
47 auto& mailbox_node = verify_cast<MailboxNode>(base_node);
48
49 if (!mailbox_node.has_parent()) {
50 for (size_t row = 0; row < mailbox_node.associated_account().mailboxes().size(); ++row) {
51 if (mailbox_node.associated_account().mailboxes()[row] == &mailbox_node) {
52 return create_index(row, index.column(), &mailbox_node.associated_account());
53 }
54 }
55 } else {
56 VERIFY(mailbox_node.parent()->has_children());
57 for (size_t row = 0; row < mailbox_node.parent()->children().size(); ++row) {
58 if (mailbox_node.parent()->children()[row] == &mailbox_node) {
59 return create_index(row, index.column(), mailbox_node.parent());
60 }
61 }
62 }
63
64 VERIFY_NOT_REACHED();
65 return {};
66}
67
68int MailboxTreeModel::row_count(GUI::ModelIndex const& index) const
69{
70 if (!index.is_valid())
71 return m_account_holder.accounts().size();
72
73 auto& base_node = *static_cast<BaseNode*>(index.internal_data());
74
75 if (is<MailboxNode>(base_node))
76 return verify_cast<MailboxNode>(base_node).children().size();
77
78 auto& node = verify_cast<AccountNode>(base_node);
79 return node.mailboxes().size();
80}
81
82int MailboxTreeModel::column_count(GUI::ModelIndex const&) const
83{
84 return 1;
85}
86
87GUI::Variant MailboxTreeModel::data(GUI::ModelIndex const& index, GUI::ModelRole role) const
88{
89 auto& base_node = *static_cast<BaseNode*>(index.internal_data());
90
91 if (role == GUI::ModelRole::Display) {
92 if (is<AccountNode>(base_node)) {
93 auto& account_node = verify_cast<AccountNode>(base_node);
94 return account_node.name();
95 }
96
97 auto& mailbox_node = verify_cast<MailboxNode>(base_node);
98 return mailbox_node.display_name();
99 }
100
101 if (role == GUI::ModelRole::Icon) {
102 if (is<AccountNode>(base_node))
103 return m_account_icon;
104
105 auto& mailbox_node = verify_cast<MailboxNode>(base_node);
106 if (!mailbox_node.children().is_empty())
107 return m_folder_icon;
108 return m_mail_icon;
109 }
110
111 return {};
112}