JsonArrayModel.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2023, Cameron Youell <cameronyouell@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/JsonObject.h>
  8. #include <LibCore/File.h>
  9. #include <LibGUI/JsonArrayModel.h>
  10. namespace GUI {
  11. void JsonArrayModel::invalidate()
  12. {
  13. auto invalidate_or_error = [this]() -> ErrorOr<void> {
  14. auto file = TRY(Core::File::open(m_json_path, Core::File::OpenMode::Read));
  15. auto file_contents = TRY(file->read_until_eof());
  16. auto json = TRY(JsonValue::from_string(file_contents));
  17. VERIFY(json.is_array());
  18. m_array = json.as_array();
  19. return {};
  20. };
  21. if (auto result = invalidate_or_error(); result.is_error()) {
  22. dbgln("Unable to invalidate {}: {}", m_json_path, result.error());
  23. m_array.clear();
  24. }
  25. did_update();
  26. }
  27. void JsonArrayModel::update()
  28. {
  29. auto update_or_error = [this]() -> ErrorOr<void> {
  30. auto file = TRY(Core::File::open(m_json_path, Core::File::OpenMode::Read));
  31. auto file_contents = TRY(file->read_until_eof());
  32. auto json = TRY(JsonValue::from_string(file_contents));
  33. VERIFY(json.is_array());
  34. m_array = json.as_array();
  35. return {};
  36. };
  37. if (auto result = update_or_error(); result.is_error()) {
  38. dbgln("Unable to update {}: {}", m_json_path, result.error());
  39. m_array.clear();
  40. did_update();
  41. return;
  42. }
  43. did_update(GUI::Model::UpdateFlag::DontInvalidateIndices);
  44. }
  45. ErrorOr<void> JsonArrayModel::store()
  46. {
  47. auto file = TRY(Core::File::open(m_json_path, Core::File::OpenMode::Write));
  48. ByteBuffer json_bytes = m_array.to_byte_string().to_byte_buffer();
  49. TRY(file->write_until_depleted(json_bytes));
  50. file->close();
  51. return {};
  52. }
  53. ErrorOr<void> JsonArrayModel::add(Vector<JsonValue> const&& fields)
  54. {
  55. VERIFY(fields.size() == m_fields.size());
  56. JsonObject obj;
  57. for (size_t i = 0; i < m_fields.size(); ++i) {
  58. auto& field_spec = m_fields[i];
  59. obj.set(field_spec.json_field_name, fields.at(i));
  60. }
  61. TRY(m_array.append(move(obj)));
  62. did_update();
  63. return {};
  64. }
  65. ErrorOr<void> JsonArrayModel::set(int row, Vector<JsonValue>&& fields)
  66. {
  67. VERIFY(fields.size() == m_fields.size());
  68. if ((size_t)row >= m_array.size())
  69. return Error::from_string_view("Row out of bounds"sv);
  70. JsonObject obj;
  71. for (size_t i = 0; i < m_fields.size(); ++i) {
  72. auto& field_spec = m_fields[i];
  73. obj.set(field_spec.json_field_name, move(fields.at(i)));
  74. }
  75. m_array.set(row, move(obj));
  76. did_update();
  77. return {};
  78. }
  79. ErrorOr<void> JsonArrayModel::remove(int row)
  80. {
  81. if ((size_t)row >= m_array.size())
  82. return Error::from_string_view("Row out of bounds"sv);
  83. JsonArray new_array;
  84. for (size_t i = 0; i < m_array.size(); ++i)
  85. if (i != (size_t)row)
  86. TRY(new_array.append(m_array.at(i)));
  87. m_array = new_array;
  88. did_update();
  89. return {};
  90. }
  91. Variant JsonArrayModel::data(ModelIndex const& index, ModelRole role) const
  92. {
  93. auto& field_spec = m_fields[index.column()];
  94. auto& object = m_array.at(index.row()).as_object();
  95. if (role == ModelRole::TextAlignment) {
  96. return field_spec.text_alignment;
  97. }
  98. if (role == ModelRole::Display) {
  99. auto& json_field_name = field_spec.json_field_name;
  100. auto data = object.get(json_field_name);
  101. if (field_spec.massage_for_display)
  102. return field_spec.massage_for_display(object);
  103. if (!data.has_value())
  104. return "";
  105. if (data->is_number())
  106. return data.value();
  107. return data->as_string();
  108. }
  109. if (role == ModelRole::Sort) {
  110. if (field_spec.massage_for_sort)
  111. return field_spec.massage_for_sort(object);
  112. return data(index, ModelRole::Display);
  113. }
  114. if (role == ModelRole::Custom) {
  115. if (field_spec.massage_for_custom)
  116. return field_spec.massage_for_custom(object);
  117. return {};
  118. }
  119. return {};
  120. }
  121. void JsonArrayModel::set_json_path(ByteString const& json_path)
  122. {
  123. if (m_json_path == json_path)
  124. return;
  125. m_json_path = json_path;
  126. invalidate();
  127. }
  128. }