ModelSelection.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Badge.h>
  8. #include <AK/HashTable.h>
  9. #include <AK/Noncopyable.h>
  10. #include <AK/TemporaryChange.h>
  11. #include <AK/Vector.h>
  12. #include <LibGUI/ModelIndex.h>
  13. namespace GUI {
  14. class ModelSelection {
  15. AK_MAKE_NONCOPYABLE(ModelSelection);
  16. AK_MAKE_NONMOVABLE(ModelSelection);
  17. public:
  18. ModelSelection(AbstractView& view)
  19. : m_view(view)
  20. {
  21. }
  22. int size() const { return m_indices.size(); }
  23. bool is_empty() const { return m_indices.is_empty(); }
  24. bool contains(ModelIndex const& index) const { return m_indices.contains(index); }
  25. bool contains_row(int row) const
  26. {
  27. for (auto& index : m_indices) {
  28. if (index.row() == row)
  29. return true;
  30. }
  31. return false;
  32. }
  33. void set(ModelIndex const&);
  34. void add(ModelIndex const&);
  35. void add_all(Vector<ModelIndex> const&);
  36. void toggle(ModelIndex const&);
  37. bool remove(ModelIndex const&);
  38. void clear();
  39. template<typename Callback>
  40. void for_each_index(Callback callback)
  41. {
  42. for (auto& index : indices())
  43. callback(index);
  44. }
  45. template<typename Callback>
  46. void for_each_index(Callback callback) const
  47. {
  48. for (auto& index : indices())
  49. callback(index);
  50. }
  51. Vector<ModelIndex> indices() const
  52. {
  53. Vector<ModelIndex> selected_indices;
  54. for (auto& index : m_indices)
  55. selected_indices.append(index);
  56. return selected_indices;
  57. }
  58. // FIXME: This doesn't guarantee that what you get is the lowest or "first" index selected..
  59. ModelIndex first() const
  60. {
  61. if (m_indices.is_empty())
  62. return {};
  63. return *m_indices.begin();
  64. }
  65. void remove_all_matching(Function<bool(ModelIndex const&)> filter);
  66. template<typename Function>
  67. void change_from_model(Badge<SortingProxyModel>, Function f)
  68. {
  69. {
  70. TemporaryChange change(m_disable_notify, true);
  71. m_notify_pending = false;
  72. f(*this);
  73. }
  74. if (m_notify_pending)
  75. notify_selection_changed();
  76. }
  77. private:
  78. void notify_selection_changed();
  79. AbstractView& m_view;
  80. HashTable<ModelIndex> m_indices;
  81. bool m_disable_notify { false };
  82. bool m_notify_pending { false };
  83. };
  84. }