OutlineModel.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright (c) 2021, Matthew Olsson <mattco@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "OutlineModel.h"
  7. #include <LibGfx/FontDatabase.h>
  8. NonnullRefPtr<OutlineModel> OutlineModel::create(const NonnullRefPtr<PDF::OutlineDict>& outline)
  9. {
  10. return adopt_ref(*new OutlineModel(outline));
  11. }
  12. OutlineModel::OutlineModel(const NonnullRefPtr<PDF::OutlineDict>& outline)
  13. : m_outline(outline)
  14. {
  15. m_closed_item_icon.set_bitmap_for_size(16, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/book.png"));
  16. m_open_item_icon.set_bitmap_for_size(16, Gfx::Bitmap::try_load_from_file("/res/icons/16x16/book-open.png"));
  17. }
  18. void OutlineModel::set_index_open_state(const GUI::ModelIndex& index, bool is_open)
  19. {
  20. VERIFY(index.is_valid());
  21. auto* outline_item = static_cast<PDF::OutlineItem*>(index.internal_data());
  22. if (is_open) {
  23. m_open_outline_items.set(outline_item);
  24. } else {
  25. m_open_outline_items.remove(outline_item);
  26. }
  27. }
  28. int OutlineModel::row_count(const GUI::ModelIndex& index) const
  29. {
  30. if (!index.is_valid())
  31. return m_outline->children.size();
  32. auto outline_item = static_cast<PDF::OutlineItem*>(index.internal_data());
  33. return static_cast<int>(outline_item->children.size());
  34. }
  35. int OutlineModel::column_count(const GUI::ModelIndex&) const
  36. {
  37. return 1;
  38. }
  39. GUI::Variant OutlineModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
  40. {
  41. VERIFY(index.is_valid());
  42. auto outline_item = static_cast<PDF::OutlineItem*>(index.internal_data());
  43. switch (role) {
  44. case GUI::ModelRole::Display:
  45. return outline_item->title;
  46. case GUI::ModelRole::Icon:
  47. if (m_open_outline_items.contains(outline_item))
  48. return m_open_item_icon;
  49. return m_closed_item_icon;
  50. default:
  51. return {};
  52. }
  53. }
  54. GUI::ModelIndex OutlineModel::parent_index(const GUI::ModelIndex& index) const
  55. {
  56. if (!index.is_valid())
  57. return {};
  58. auto* outline_item = static_cast<PDF::OutlineItem*>(index.internal_data());
  59. auto& parent = outline_item->parent;
  60. if (!parent)
  61. return {};
  62. if (parent->parent) {
  63. auto& grandparent = parent->parent;
  64. for (size_t i = 0; i < grandparent->children.size(); i++) {
  65. auto* sibling = &grandparent->children[i];
  66. if (sibling == index.internal_data())
  67. return create_index(static_cast<int>(i), 0, sibling);
  68. }
  69. } else {
  70. for (size_t i = 0; i < m_outline->children.size(); i++) {
  71. auto* sibling = &m_outline->children[i];
  72. if (sibling == index.internal_data())
  73. return create_index(static_cast<int>(i), 0, sibling);
  74. }
  75. }
  76. VERIFY_NOT_REACHED();
  77. }
  78. GUI::ModelIndex OutlineModel::index(int row, int column, const GUI::ModelIndex& parent) const
  79. {
  80. if (!parent.is_valid())
  81. return create_index(row, column, &m_outline->children[row]);
  82. auto parent_outline_item = static_cast<PDF::OutlineItem*>(parent.internal_data());
  83. return create_index(row, column, &parent_outline_item->children[row]);
  84. }