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