/* * Copyright (c) 2020, the SerenityOS developers. * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include namespace GUI { class FilteringProxyModel final : public Model , public ModelClient { public: enum class FilteringOptions { None, SortByScore = 1 << 1 }; static ErrorOr> create(NonnullRefPtr model, FilteringOptions filtering_options = FilteringOptions::None) { return adopt_nonnull_ref_or_enomem(new (nothrow) FilteringProxyModel(move(model), filtering_options)); } virtual ~FilteringProxyModel() override { m_model->unregister_client(*this); } virtual int row_count(ModelIndex const& = ModelIndex()) const override; virtual int column_count(ModelIndex const& = ModelIndex()) const override; virtual ErrorOr column_name(int) const override; virtual Variant data(ModelIndex const&, ModelRole = ModelRole::Display) const override; virtual void invalidate() override; virtual ModelIndex index(int row, int column = 0, ModelIndex const& parent = ModelIndex()) const override; virtual bool is_searchable() const override; virtual Vector matches(StringView, unsigned = MatchesFlag::AllMatching, ModelIndex const& = ModelIndex()) override; void set_filter_term(StringView term); ModelIndex map(ModelIndex const&) const; protected: virtual void model_did_update([[maybe_unused]] unsigned flags) override { invalidate(); } private: struct ModelIndexWithScore { ModelIndex index; int score { 0 }; }; void filter(); explicit FilteringProxyModel(NonnullRefPtr model, FilteringOptions filtering_options = FilteringOptions::None) : m_model(move(model)) , m_filtering_options(filtering_options) { m_model->register_client(*this); } NonnullRefPtr m_model; // Maps row to actual model index. Vector m_matching_indices; DeprecatedString m_filter_term; FilteringOptions m_filtering_options; }; AK_ENUM_BITWISE_OPERATORS(FilteringProxyModel::FilteringOptions); }