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 KLINKITEMSELECTIONMODEL_H
11#define KLINKITEMSELECTIONMODEL_H
12
13#include <QItemSelectionModel>
14
15#include "kitemmodels_export.h"
16
17#include <memory>
18
19class KLinkItemSelectionModelPrivate;
20
21/*!
22 \class KLinkItemSelectionModel
23 \inmodule KItemModels
24 \brief Makes it possible to share a selection in multiple views which do not have the same source model.
25
26 Although \l {https://doc.qt.io/qt-6/model-view-programming.html#handling-selections-of-items}{multiple views can share the same QItemSelectionModel},
27 the views then need to have the same source model.
28
29 If there is a proxy model between the model and one of the views, or different proxy models in each, this class makes
30 it possible to share the selection between the views.
31
32 \image kproxyitemselectionmodel-simple.png "Sharing a QItemSelectionModel between views on the same model is trivial"
33 \image kproxyitemselectionmodel-error.png "If a proxy model is used, it is no longer possible to share the QItemSelectionModel directly"
34 \image kproxyitemselectionmodel-solution.png "A KLinkItemSelectionModel can be used to map the selection through the proxy model"
35
36 \code
37 QAbstractItemModel *model = getModel();
38
39 QSortFilterProxyModel *proxy = new QSortFilterProxyModel();
40 proxy->setSourceModel(model);
41
42 QTreeView *view1 = new QTreeView(splitter);
43 view1->setModel(model);
44
45 KLinkItemSelectionModel *view2SelectionModel = new KLinkItemSelectionModel( proxy, view1->selectionModel());
46
47 QTreeView *view2 = new QTreeView(splitter);
48 // Note that the QAbstractItemModel passed to KLinkItemSelectionModel must be the same as what is used in the view
49 view2->setModel(proxy);
50 view2->setSelectionModel( view2SelectionModel );
51 \endcode
52
53 \image kproxyitemselectionmodel-complex.png "Arbitrarily complex proxy configurations on the same root model can be used"
54
55 \code
56 QAbstractItemModel *model = getModel();
57
58 QSortFilterProxyModel *proxy1 = new QSortFilterProxyModel();
59 proxy1->setSourceModel(model);
60 QSortFilterProxyModel *proxy2 = new QSortFilterProxyModel();
61 proxy2->setSourceModel(proxy1);
62 QSortFilterProxyModel *proxy3 = new QSortFilterProxyModel();
63 proxy3->setSourceModel(proxy2);
64
65 QTreeView *view1 = new QTreeView(splitter);
66 view1->setModel(proxy3);
67
68 QSortFilterProxyModel *proxy4 = new QSortFilterProxyModel();
69 proxy4->setSourceModel(model);
70 QSortFilterProxyModel *proxy5 = new QSortFilterProxyModel();
71 proxy5->setSourceModel(proxy4);
72
73 KLinkItemSelectionModel *view2SelectionModel = new KLinkItemSelectionModel( proxy5, view1->selectionModel());
74
75 QTreeView *view2 = new QTreeView(splitter);
76 // Note that the QAbstractItemModel passed to KLinkItemSelectionModel must be the same as what is used in the view
77 view2->setModel(proxy5);
78 view2->setSelectionModel( view2SelectionModel );
79 \endcode
80
81 See also \l {https://commits.kde.org/kitemmodels?path=tests/proxymodeltestapp/proxyitemselectionwidget.cpp}{kitemmodels:
82 tests/proxymodeltestapp/proxyitemselectionwidget.cpp}.
83
84 \since 4.5
85*/
86class KITEMMODELS_EXPORT KLinkItemSelectionModel : public QItemSelectionModel
87{
88 Q_OBJECT
89
90 /*!
91 * \property KLinkItemSelectionModel::linkedItemSelectionModel
92 */
93 Q_PROPERTY(
94 QItemSelectionModel *linkedItemSelectionModel READ linkedItemSelectionModel WRITE setLinkedItemSelectionModel NOTIFY linkedItemSelectionModelChanged)
95public:
96 /*!
97 Constructor.
98 */
99 KLinkItemSelectionModel(QAbstractItemModel *targetModel, QItemSelectionModel *linkedItemSelectionModel, QObject *parent = nullptr);
100
101 /*!
102 *
103 */
104 explicit KLinkItemSelectionModel(QObject *parent = nullptr);
105
106 ~KLinkItemSelectionModel() override;
107
108 QItemSelectionModel *linkedItemSelectionModel() const;
109 void setLinkedItemSelectionModel(QItemSelectionModel *selectionModel);
110
111 void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) override;
112 void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override;
113
114Q_SIGNALS:
115 void linkedItemSelectionModelChanged();
116
117protected:
118 std::unique_ptr<KLinkItemSelectionModelPrivate> const d_ptr;
119
120private:
121 Q_DECLARE_PRIVATE(KLinkItemSelectionModel)
122 Q_PRIVATE_SLOT(d_func(), void sourceSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected))
123 Q_PRIVATE_SLOT(d_func(), void sourceCurrentChanged(const QModelIndex &current))
124 Q_PRIVATE_SLOT(d_func(), void slotCurrentChanged(const QModelIndex &current))
125};
126
127#endif
128

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