Serenity Operating System
at master 93 lines 2.6 kB view raw
1/* 2 * Copyright (c) 2021, sin-ack <sin-ack@protonmail.com> 3 * Copyright (c) 2022, the SerenityOS developers. 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <AK/RefCounted.h> 11#include <AK/WeakPtr.h> 12#include <LibGUI/Model.h> 13#include <LibGUI/ModelIndex.h> 14 15namespace GUI { 16 17/// A PersistentHandle is an internal data structure used to keep track of the 18/// target of multiple PersistentModelIndex instances. 19class PersistentHandle : public Weakable<PersistentHandle> { 20 friend Model; 21 friend PersistentModelIndex; 22 friend AK::Traits<GUI::PersistentModelIndex>; 23 24 PersistentHandle(ModelIndex const& index) 25 : m_index(index) 26 { 27 } 28 29 ModelIndex m_index; 30}; 31 32class PersistentModelIndex { 33public: 34 PersistentModelIndex() = default; 35 PersistentModelIndex(ModelIndex const&); 36 PersistentModelIndex(PersistentModelIndex const&) = default; 37 PersistentModelIndex(PersistentModelIndex&&) = default; 38 39 PersistentModelIndex& operator=(PersistentModelIndex const&) = default; 40 PersistentModelIndex& operator=(PersistentModelIndex&&) = default; 41 42 bool is_valid() const { return has_valid_handle() && m_handle->m_index.is_valid(); } 43 bool has_valid_handle() const { return !m_handle.is_null(); } 44 45 int row() const; 46 int column() const; 47 PersistentModelIndex parent() const; 48 PersistentModelIndex sibling_at_column(int column) const; 49 Variant data(ModelRole = ModelRole::Display) const; 50 51 void* internal_data() const 52 { 53 if (has_valid_handle()) 54 return m_handle->m_index.internal_data(); 55 else 56 return nullptr; 57 } 58 59 operator ModelIndex() const; 60 bool operator==(PersistentModelIndex const&) const; 61 bool operator!=(PersistentModelIndex const&) const; 62 bool operator==(ModelIndex const&) const; 63 bool operator!=(ModelIndex const&) const; 64 65private: 66 friend AK::Traits<GUI::PersistentModelIndex>; 67 68 WeakPtr<PersistentHandle> m_handle; 69}; 70 71} 72 73namespace AK { 74 75template<> 76struct Formatter<GUI::PersistentModelIndex> : Formatter<FormatString> { 77 ErrorOr<void> format(FormatBuilder& builder, GUI::PersistentModelIndex const& value) 78 { 79 return Formatter<FormatString>::format(builder, "PersistentModelIndex({},{},{})"sv, value.row(), value.column(), value.internal_data()); 80 } 81}; 82 83template<> 84struct Traits<GUI::PersistentModelIndex> : public GenericTraits<GUI::PersistentModelIndex> { 85 static unsigned hash(const GUI::PersistentModelIndex& index) 86 { 87 if (index.has_valid_handle()) 88 return Traits<GUI::ModelIndex>::hash(index.m_handle->m_index); 89 return 0; 90 } 91}; 92 93}