Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/JsonObject.h>
8#include <LibCore/DeprecatedFile.h>
9#include <LibGUI/JsonArrayModel.h>
10
11namespace GUI {
12
13void JsonArrayModel::invalidate()
14{
15 auto file = Core::DeprecatedFile::construct(m_json_path);
16 if (!file->open(Core::OpenMode::ReadOnly)) {
17 dbgln("Unable to open {}", file->filename());
18 m_array.clear();
19 did_update();
20 return;
21 }
22
23 auto json = JsonValue::from_string(file->read_all()).release_value_but_fixme_should_propagate_errors();
24
25 VERIFY(json.is_array());
26 m_array = json.as_array();
27
28 did_update();
29}
30
31void JsonArrayModel::update()
32{
33 auto file = Core::DeprecatedFile::construct(m_json_path);
34 if (!file->open(Core::OpenMode::ReadOnly)) {
35 dbgln("Unable to open {}", file->filename());
36 m_array.clear();
37 did_update();
38 return;
39 }
40
41 auto json = JsonValue::from_string(file->read_all()).release_value_but_fixme_should_propagate_errors();
42
43 VERIFY(json.is_array());
44 m_array = json.as_array();
45
46 did_update(GUI::Model::UpdateFlag::DontInvalidateIndices);
47}
48
49bool JsonArrayModel::store()
50{
51 auto file = Core::DeprecatedFile::construct(m_json_path);
52 if (!file->open(Core::OpenMode::WriteOnly)) {
53 dbgln("Unable to open {}", file->filename());
54 return false;
55 }
56
57 file->write(m_array.to_deprecated_string());
58 file->close();
59 return true;
60}
61
62bool JsonArrayModel::add(Vector<JsonValue> const&& values)
63{
64 VERIFY(values.size() == m_fields.size());
65 JsonObject obj;
66 for (size_t i = 0; i < m_fields.size(); ++i) {
67 auto& field_spec = m_fields[i];
68 obj.set(field_spec.json_field_name, values.at(i));
69 }
70 m_array.append(move(obj));
71 did_update();
72 return true;
73}
74
75bool JsonArrayModel::set(int row, Vector<JsonValue>&& values)
76{
77 VERIFY(values.size() == m_fields.size());
78
79 if ((size_t)row >= m_array.size())
80 return false;
81
82 JsonObject obj;
83 for (size_t i = 0; i < m_fields.size(); ++i) {
84 auto& field_spec = m_fields[i];
85 obj.set(field_spec.json_field_name, move(values.at(i)));
86 }
87
88 m_array.set(row, move(obj));
89 did_update();
90
91 return true;
92}
93
94bool JsonArrayModel::remove(int row)
95{
96 if ((size_t)row >= m_array.size())
97 return false;
98
99 JsonArray new_array;
100 for (size_t i = 0; i < m_array.size(); ++i)
101 if (i != (size_t)row)
102 new_array.append(m_array.at(i));
103
104 m_array = new_array;
105
106 did_update();
107
108 return true;
109}
110
111Variant JsonArrayModel::data(ModelIndex const& index, ModelRole role) const
112{
113 auto& field_spec = m_fields[index.column()];
114 auto& object = m_array.at(index.row()).as_object();
115
116 if (role == ModelRole::TextAlignment) {
117 return field_spec.text_alignment;
118 }
119
120 if (role == ModelRole::Display) {
121 auto& json_field_name = field_spec.json_field_name;
122 auto data = object.get(json_field_name);
123 if (field_spec.massage_for_display)
124 return field_spec.massage_for_display(object);
125 if (!data.has_value())
126 return "";
127 if (data->is_number())
128 return data.value();
129 return data->to_deprecated_string();
130 }
131
132 if (role == ModelRole::Sort) {
133 if (field_spec.massage_for_sort)
134 return field_spec.massage_for_sort(object);
135 return data(index, ModelRole::Display);
136 }
137
138 if (role == ModelRole::Custom) {
139 if (field_spec.massage_for_custom)
140 return field_spec.massage_for_custom(object);
141 return {};
142 }
143
144 return {};
145}
146
147void JsonArrayModel::set_json_path(DeprecatedString const& json_path)
148{
149 if (m_json_path == json_path)
150 return;
151
152 m_json_path = json_path;
153 invalidate();
154}
155
156}