1/*
2 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
3 SPDX-FileContributor: Stephen Kelly <stephen@kdab.com>
4 SPDX-FileCopyrightText: 2016 Ableton AG <info@ableton.com>
5 SPDX-FileContributor: Stephen Kelly <stephen.kelly@ableton.com>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#ifndef KMODELINDEXPROXYMAPPER_H
11#define KMODELINDEXPROXYMAPPER_H
12
13#include <QObject>
14
15#include "kitemmodels_export.h"
16
17#include <memory>
18
19class QAbstractItemModel;
20class QModelIndex;
21class QItemSelection;
22class KModelIndexProxyMapperPrivate;
23
24/**
25 * @class KModelIndexProxyMapper kmodelindexproxymapper.h KModelIndexProxyMapper
26 *
27 * @brief This class facilitates easy mapping of indexes and selections through proxy models.
28 *
29 * In a complex system of proxy models there can be a need to map indexes and selections between them,
30 * and sometimes to do so without knowledge of the path from one model to another.
31 *
32 * For example,
33 *
34 * @verbatim
35 * Root model
36 * |
37 * / \
38 * Proxy 1 Proxy 3
39 * | |
40 * Proxy 2 Proxy 4
41 * @endverbatim
42 *
43 * If there is a need to map indexes between proxy 2 and proxy 4, a KModelIndexProxyMapper can be created
44 * to facilitate mapping of indexes between them.
45 *
46 * @code
47 * m_indexMapper = new KModelIndexProxyMapper(proxy2, proxy4, this);
48 *
49 * ...
50 *
51 * const QModelIndex proxy4Index = m_mapLeftToRight(proxy2->index(0, 0));
52 * Q_ASSERT(proxy4Index.model() == proxy4);
53 * @endcode
54 *
55 * Note that the aim is to achieve black box connections so that there is no need for application code to
56 * know the structure of proxy models in the path between left and right and attempt to manually map them.
57 *
58 * @verbatim
59 * Root model
60 * |
61 * ---------------
62 * | Black Box |
63 * ---------------
64 * | |
65 * Proxy 2 Proxy 4
66 * @endverbatim
67 *
68 * The isConnected property indicates whether there is a
69 * path from the left side to the right side.
70 *
71 * @author Stephen Kelly <steveire@gmail.com>
72 *
73 */
74class KITEMMODELS_EXPORT KModelIndexProxyMapper : public QObject
75{
76 Q_OBJECT
77
78 /**
79 * Indicates whether there is a chain that can be followed from leftModel to rightModel.
80 *
81 * This value can change if the sourceModel of an intermediate proxy is changed.
82 */
83 Q_PROPERTY(bool isConnected READ isConnected NOTIFY isConnectedChanged)
84public:
85 /**
86 * Constructor
87 */
88 KModelIndexProxyMapper(const QAbstractItemModel *leftModel, const QAbstractItemModel *rightModel, QObject *parent = nullptr);
89
90 ~KModelIndexProxyMapper() override;
91
92 /**
93 * Maps the @p index from the left model to the right model.
94 */
95 QModelIndex mapLeftToRight(const QModelIndex &index) const;
96
97 /**
98 * Maps the @p index from the right model to the left model.
99 */
100 QModelIndex mapRightToLeft(const QModelIndex &index) const;
101
102 /**
103 * Maps the @p selection from the left model to the right model.
104 */
105 QItemSelection mapSelectionLeftToRight(const QItemSelection &selection) const;
106
107 /**
108 * Maps the @p selection from the right model to the left model.
109 */
110 QItemSelection mapSelectionRightToLeft(const QItemSelection &selection) const;
111
112 bool isConnected() const;
113
114Q_SIGNALS:
115 void isConnectedChanged();
116
117private:
118 //@cond PRIVATE
119 Q_DECLARE_PRIVATE(KModelIndexProxyMapper)
120 std::unique_ptr<KModelIndexProxyMapperPrivate> const d_ptr;
121 //@endcond
122};
123
124#endif
125

source code of kitemmodels/src/core/kmodelindexproxymapper.h