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 klinkitemselectionmodel.h KLinkItemSelectionModel
23
24 @brief Makes it possible to share a selection in multiple views which do not have the same source model
25
26 Although <a href="https://doc.qt.io/qt-5/model-view-programming.html#handling-selections-of-items">multiple views can share the same QItemSelectionModel</a>,
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 html kproxyitemselectionmodel-simple.png "Sharing a QItemSelectionModel between views on the same model is trivial"
33 @image html kproxyitemselectionmodel-error.png "If a proxy model is used, it is no longer possible to share the QItemSelectionModel directly"
34 @image html 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 html 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 <a href="https://commits.kde.org/kitemmodels?path=tests/proxymodeltestapp/proxyitemselectionwidget.cpp">kitemmodels:
82 tests/proxymodeltestapp/proxyitemselectionwidget.cpp</a>.
83
84 @since 4.5
85 @author Stephen Kelly <steveire@gmail.com>
86
87*/
88class KITEMMODELS_EXPORT KLinkItemSelectionModel : public QItemSelectionModel
89{
90 Q_OBJECT
91 Q_PROPERTY(
92 QItemSelectionModel *linkedItemSelectionModel READ linkedItemSelectionModel WRITE setLinkedItemSelectionModel NOTIFY linkedItemSelectionModelChanged)
93public:
94 /**
95 Constructor.
96 */
97 KLinkItemSelectionModel(QAbstractItemModel *targetModel, QItemSelectionModel *linkedItemSelectionModel, QObject *parent = nullptr);
98
99 explicit KLinkItemSelectionModel(QObject *parent = nullptr);
100
101 ~KLinkItemSelectionModel() override;
102
103 QItemSelectionModel *linkedItemSelectionModel() const;
104 void setLinkedItemSelectionModel(QItemSelectionModel *selectionModel);
105
106 void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) override;
107 void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) override;
108
109Q_SIGNALS:
110 void linkedItemSelectionModelChanged();
111
112protected:
113 std::unique_ptr<KLinkItemSelectionModelPrivate> const d_ptr;
114
115private:
116 Q_DECLARE_PRIVATE(KLinkItemSelectionModel)
117 Q_PRIVATE_SLOT(d_func(), void sourceSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected))
118 Q_PRIVATE_SLOT(d_func(), void sourceCurrentChanged(const QModelIndex &current))
119 Q_PRIVATE_SLOT(d_func(), void slotCurrentChanged(const QModelIndex &current))
120};
121
122#endif
123

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