ModelAdapter.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include "StringUtils.h"
  8. #include <AK/JsonValue.h>
  9. #include <AK/NonnullOwnPtr.h>
  10. #include <AK/Optional.h>
  11. #include <AK/String.h>
  12. #include <AK/StringView.h>
  13. #include <LibWeb/CSS/Selector.h>
  14. #include <LibWebView/ModelIndex.h>
  15. #include <LibWebView/PropertyTableModel.h>
  16. #include <QAbstractItemModel>
  17. namespace Ladybird {
  18. template<typename ModelType>
  19. class ModelAdapter : public QAbstractItemModel {
  20. public:
  21. using Type = typename ModelType::Type;
  22. static ErrorOr<NonnullOwnPtr<ModelAdapter>> create(Type type, StringView model, QObject* parent = nullptr)
  23. {
  24. auto json_model = TRY(JsonValue::from_string(model));
  25. if (!json_model.is_object())
  26. return Error::from_string_literal("Expected model to be a JSON object");
  27. return adopt_own(*new ModelAdapter(type, move(json_model), parent));
  28. }
  29. virtual int rowCount(QModelIndex const& parent) const override
  30. {
  31. return m_model.row_count(to_web_view_model_index(parent));
  32. }
  33. virtual int columnCount(QModelIndex const& parent) const override
  34. {
  35. return m_model.column_count(to_web_view_model_index(parent));
  36. }
  37. virtual QModelIndex index(int row, int column, QModelIndex const& parent) const override
  38. {
  39. auto index = m_model.index(row, column, to_web_view_model_index(parent));
  40. return to_qt_model_index(index);
  41. }
  42. virtual QModelIndex parent(QModelIndex const& index) const override
  43. {
  44. if constexpr (requires { m_model.parent(declval<WebView::ModelIndex const&>()); }) {
  45. auto parent = m_model.parent(to_web_view_model_index(index));
  46. return to_qt_model_index(parent);
  47. } else {
  48. return {};
  49. }
  50. }
  51. virtual QVariant data(QModelIndex const& index, int role) const override
  52. {
  53. if (role == Qt::DisplayRole) {
  54. auto text = m_model.text_for_display(to_web_view_model_index(index));
  55. return qstring_from_ak_string(text);
  56. }
  57. return {};
  58. }
  59. QModelIndex index_for_node(i32 node_id, Optional<Web::CSS::Selector::PseudoElement> const& pseudo_element) const
  60. {
  61. if constexpr (requires { m_model.index_for_node(node_id, pseudo_element); }) {
  62. auto parent = m_model.index_for_node(node_id, pseudo_element);
  63. return to_qt_model_index(parent);
  64. } else {
  65. return {};
  66. }
  67. }
  68. private:
  69. ModelAdapter(Type type, JsonValue model, QObject* parent)
  70. : QAbstractItemModel(parent)
  71. , m_model(type, move(model))
  72. {
  73. }
  74. ALWAYS_INLINE QModelIndex to_qt_model_index(WebView::ModelIndex const& index) const
  75. {
  76. if (!index.is_valid())
  77. return {};
  78. return createIndex(index.row, index.column, index.internal_data);
  79. }
  80. ALWAYS_INLINE WebView::ModelIndex to_web_view_model_index(QModelIndex const& index) const
  81. {
  82. if (!index.isValid())
  83. return {};
  84. return { index.row(), index.column(), index.constInternalPointer() };
  85. }
  86. ModelType m_model;
  87. };
  88. using PropertyTableModel = ModelAdapter<WebView::PropertyTableModel>;
  89. }