Salome HOME
089b8f3d8f7607b7955fd1740d162f57e23236c9
[modules/hexablock.git] / src / HEXABLOCKGUI / klinkitemselectionmodel.hxx
1 /*
2     Copyright (C) 2010 Klarälvdalens Datakonsult AB,
3         a KDAB Group company, info@kdab.net,
4         author Stephen Kelly <stephen@kdab.com>
5
6     This library is free software; you can redistribute it and/or modify it
7     under the terms of the GNU Library General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or (at your
9     option) any later version.
10
11     This library is distributed in the hope that it will be useful, but WITHOUT
12     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
14     License for more details.
15
16     You should have received a copy of the GNU Library General Public License
17     along with this library; see the file COPYING.LIB.  If not, write to the
18     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19     02110-1301, USA.
20 */
21
22 #ifndef KLINKITEMSELECTIONMODEL_H
23 #define KLINKITEMSELECTIONMODEL_H
24
25 #include "HEXABLOCKGUI_Export.hxx"
26
27 #include <QtCore/QObject>
28 #include <QtGui/QItemSelectionModel>
29 #include <QtGui/QAbstractProxyModel>
30
31 #include <iostream>
32
33 // #include "kdeui_export.h"
34 // #include "klinkitemselectionmodel_p.hxx"
35
36 #include "kmodelindexproxymapper.hxx"
37
38 class KLinkItemSelectionModelPrivate;
39
40 class HEXABLOCK_EXPORT KLinkItemSelectionModel : public QItemSelectionModel
41 {
42     Q_OBJECT
43 public:
44     KLinkItemSelectionModel(QAbstractItemModel *targetModel, QItemSelectionModel *linkedItemSelectionModel, QObject *parent = 0);
45     ~KLinkItemSelectionModel();
46     /* reimp */ void select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command);
47     /* reimp */ void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command);
48
49 protected:
50     KLinkItemSelectionModelPrivate * const d_ptr;
51
52 private:
53     Q_DECLARE_PRIVATE(KLinkItemSelectionModel)
54     Q_PRIVATE_SLOT( d_func(), void sourceSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected))
55
56 };
57
58
59 // QAbstractProxyModel::mapSelectionFromSource creates invalid ranges to we filter
60 // those out manually in a loop. Hopefully fixed in Qt 4.7.2, so we ifdef it out.
61 // http://qt.gitorious.org/qt/qt/merge_requests/2474
62 // http://qt.gitorious.org/qt/qt/merge_requests/831
63 #if QT_VERSION < 0x040702
64 #define RANGE_FIX_HACK
65 #endif
66
67 #ifdef RANGE_FIX_HACK
68 static QItemSelection klink_removeInvalidRanges(const QItemSelection &selection)
69 {
70 //   std::cout<< " klink_removeInvalidRanges " << std::endl;
71   QItemSelection result;
72   Q_FOREACH(const QItemSelectionRange &range, selection)
73   {
74
75 //    Q_FOREACH(const QModelIndex &i, range.indexes ())
76 //    {
77 ////       std::cout<< " =====> " << i.data().toString().toStdString() << std::endl;
78 //    }
79     if (!range.isValid())
80       continue;
81 //     std::cout<< " is VALID !!"<< std::endl;
82     result << range;
83   }
84   return result;
85 }
86 #endif
87
88
89 class HEXABLOCK_EXPORT KLinkItemSelectionModelPrivate
90 {
91 public:
92     KLinkItemSelectionModelPrivate(KLinkItemSelectionModel *proxySelectionModel, QAbstractItemModel *model,
93                                     QItemSelectionModel *linkedItemSelectionModel)
94       : q_ptr(proxySelectionModel),
95         m_model(model),
96         m_linkedItemSelectionModel(linkedItemSelectionModel),
97         m_ignoreCurrentChanged(false),
98         m_indexMapper(new KModelIndexProxyMapper(model, linkedItemSelectionModel->model(), proxySelectionModel))
99     {
100     }
101
102     Q_DECLARE_PUBLIC(KLinkItemSelectionModel)
103     KLinkItemSelectionModel * const q_ptr;
104
105
106     bool assertSelectionValid(const QItemSelection &selection) const {
107       foreach(const QItemSelectionRange &range, selection) {
108 //         if (!range.isValid()) {
109 //           kDebug() << selection;
110 //         }
111         
112         Q_ASSERT(range.isValid());
113       }
114       return true;
115     }
116
117 void sourceSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected)
118 {
119
120     
121     Q_Q(KLinkItemSelectionModel);
122 #ifdef RANGE_FIX_HACK
123 //     std::cout<<"XXXXXXXXXXXXX  sourceSelectionChanged!!!!!!!! RANGE_FIX_HACK"<<std::endl;
124     QItemSelection _selected = klink_removeInvalidRanges(selected);
125     QItemSelection _deselected = klink_removeInvalidRanges(deselected);
126 #else
127 //     std::cout<<"XXXXXXXXXXXXX  sourceSelectionChanged!!!!!!!! "<<std::endl;
128     QItemSelection _selected = selected;
129     QItemSelection _deselected = deselected;
130 #endif
131     Q_ASSERT(assertSelectionValid(_selected));
132     Q_ASSERT(assertSelectionValid(_deselected));
133
134 //     std::cout << "XXXXXXXXXXXXX  _selected.count() "   << _selected.count() << std::endl;
135 //     std::cout << "XXXXXXXXXXXXX  _deselected.count() " << _deselected.count() << std::endl;
136
137     const QItemSelection mappedDeselection = m_indexMapper->mapSelectionRightToLeft(_deselected);
138     const QItemSelection mappedSelection   = m_indexMapper->mapSelectionRightToLeft(_selected);
139
140 //     const QItemSelection mappedDeselection = _deselected;
141 //     const QItemSelection mappedSelection   = _selected;
142
143 //     std::cout << "XXXXXXXXXXXXX  mappedSelection.count() "   << mappedSelection.count() << std::endl;
144 //     std::cout << "XXXXXXXXXXXXX  mappedDeselection.count() " << mappedDeselection.count() << std::endl;
145
146     q->QItemSelectionModel::select(mappedDeselection, QItemSelectionModel::Deselect);
147     q->QItemSelectionModel::select(mappedSelection, QItemSelectionModel::Select);
148
149 //     q->select(mappedDeselection, QItemSelectionModel::Deselect);
150 //     q->select(mappedSelection, QItemSelectionModel::Select);
151
152
153 }
154
155     QAbstractItemModel * const m_model;
156     QItemSelectionModel * const m_linkedItemSelectionModel;
157     bool m_ignoreCurrentChanged;
158     KModelIndexProxyMapper * const m_indexMapper;
159 };
160
161
162
163 #endif