File indexing completed on 2024-05-05 03:56:42
0001 /* 0002 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0003 SPDX-FileContributor: Stephen Kelly <stephen@kdab.com> 0004 SPDX-FileCopyrightText: 2016 Ableton AG <info@ableton.com> 0005 SPDX-FileContributor: Stephen Kelly <stephen.kelly@ableton.com> 0006 0007 SPDX-License-Identifier: LGPL-2.0-or-later 0008 */ 0009 0010 #ifndef KMODELINDEXPROXYMAPPER_H 0011 #define KMODELINDEXPROXYMAPPER_H 0012 0013 #include <QObject> 0014 0015 #include "kitemmodels_export.h" 0016 0017 #include <memory> 0018 0019 class QAbstractItemModel; 0020 class QModelIndex; 0021 class QItemSelection; 0022 class KModelIndexProxyMapperPrivate; 0023 0024 /** 0025 * @class KModelIndexProxyMapper kmodelindexproxymapper.h KModelIndexProxyMapper 0026 * 0027 * @brief This class facilitates easy mapping of indexes and selections through proxy models. 0028 * 0029 * In a complex system of proxy models there can be a need to map indexes and selections between them, 0030 * and sometimes to do so without knowledge of the path from one model to another. 0031 * 0032 * For example, 0033 * 0034 * @verbatim 0035 * Root model 0036 * | 0037 * / \ 0038 * Proxy 1 Proxy 3 0039 * | | 0040 * Proxy 2 Proxy 4 0041 * @endverbatim 0042 * 0043 * If there is a need to map indexes between proxy 2 and proxy 4, a KModelIndexProxyMapper can be created 0044 * to facilitate mapping of indexes between them. 0045 * 0046 * @code 0047 * m_indexMapper = new KModelIndexProxyMapper(proxy2, proxy4, this); 0048 * 0049 * ... 0050 * 0051 * const QModelIndex proxy4Index = m_mapLeftToRight(proxy2->index(0, 0)); 0052 * Q_ASSERT(proxy4Index.model() == proxy4); 0053 * @endcode 0054 * 0055 * Note that the aim is to achieve black box connections so that there is no need for application code to 0056 * know the structure of proxy models in the path between left and right and attempt to manually map them. 0057 * 0058 * @verbatim 0059 * Root model 0060 * | 0061 * --------------- 0062 * | Black Box | 0063 * --------------- 0064 * | | 0065 * Proxy 2 Proxy 4 0066 * @endverbatim 0067 * 0068 * The isConnected property indicates whether there is a 0069 * path from the left side to the right side. 0070 * 0071 * @author Stephen Kelly <steveire@gmail.com> 0072 * 0073 */ 0074 class KITEMMODELS_EXPORT KModelIndexProxyMapper : public QObject 0075 { 0076 Q_OBJECT 0077 0078 /** 0079 * Indicates whether there is a chain that can be followed from leftModel to rightModel. 0080 * 0081 * This value can change if the sourceModel of an intermediate proxy is changed. 0082 */ 0083 Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged) 0084 public: 0085 /** 0086 * Constructor 0087 */ 0088 KModelIndexProxyMapper(const QAbstractItemModel *leftModel, const QAbstractItemModel *rightModel, QObject *parent = nullptr); 0089 0090 ~KModelIndexProxyMapper() override; 0091 0092 /** 0093 * Maps the @p index from the left model to the right model. 0094 */ 0095 QModelIndex mapLeftToRight(const QModelIndex &index) const; 0096 0097 /** 0098 * Maps the @p index from the right model to the left model. 0099 */ 0100 QModelIndex mapRightToLeft(const QModelIndex &index) const; 0101 0102 /** 0103 * Maps the @p selection from the left model to the right model. 0104 */ 0105 QItemSelection mapSelectionLeftToRight(const QItemSelection &selection) const; 0106 0107 /** 0108 * Maps the @p selection from the right model to the left model. 0109 */ 0110 QItemSelection mapSelectionRightToLeft(const QItemSelection &selection) const; 0111 0112 bool isConnected() const; 0113 0114 Q_SIGNALS: 0115 void isConnectedChanged(); 0116 0117 private: 0118 //@cond PRIVATE 0119 Q_DECLARE_PRIVATE(KModelIndexProxyMapper) 0120 std::unique_ptr<KModelIndexProxyMapperPrivate> const d_ptr; 0121 //@endcond 0122 }; 0123 0124 #endif