/
WAbstractProxyModel.C
219 lines (183 loc) · 5.47 KB
/
WAbstractProxyModel.C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
* Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
*
* See the LICENSE file for terms of use.
*/
#include "Wt/WAbstractProxyModel"
namespace Wt {
#ifndef DOXYGEN_ONLY
WAbstractProxyModel::BaseItem::~BaseItem()
{ }
WAbstractProxyModel::WAbstractProxyModel(WObject *parent)
: WAbstractItemModel(parent),
sourceModel_(0)
{ }
void WAbstractProxyModel::setSourceModel(WAbstractItemModel *sourceModel)
{
sourceModel_ = sourceModel;
}
boost::any WAbstractProxyModel::data(const WModelIndex& index, int role) const
{
return sourceModel_->data(mapToSource(index), role);
}
bool WAbstractProxyModel::setData(const WModelIndex& index,
const boost::any& value, int role)
{
return sourceModel_->setData(mapToSource(index), value, role);
}
bool WAbstractProxyModel::setItemData(const WModelIndex& index,
const DataMap& values)
{
return sourceModel_->setItemData(mapToSource(index), values);
}
WFlags<ItemFlag> WAbstractProxyModel::flags(const WModelIndex& index) const
{
return sourceModel_->flags(mapToSource(index));
}
bool WAbstractProxyModel::insertColumns(int column, int count,
const WModelIndex& parent)
{
return sourceModel_->insertColumns(column, count, parent);
}
bool WAbstractProxyModel::removeColumns(int column, int count,
const WModelIndex& parent)
{
return sourceModel_->removeColumns(column, count, parent);
}
std::string WAbstractProxyModel::mimeType() const
{
return sourceModel_->mimeType();
}
std::vector<std::string> WAbstractProxyModel::acceptDropMimeTypes() const
{
return sourceModel_->acceptDropMimeTypes();
}
void WAbstractProxyModel::dropEvent(const WDropEvent& e, DropAction action,
int row, int column,
const WModelIndex& parent)
{
WModelIndex sourceParent = mapToSource(parent);
int sourceRow = row;
int sourceColumn = column;
if (sourceRow != -1)
sourceRow = mapToSource(index(row, 0, parent)).row();
sourceModel_->dropEvent(e, action, sourceRow, sourceColumn, sourceParent);
}
void *WAbstractProxyModel::toRawIndex(const WModelIndex& index) const
{
return sourceModel_->toRawIndex(mapToSource(index));
}
WModelIndex WAbstractProxyModel::fromRawIndex(void *rawIndex) const
{
return mapFromSource(sourceModel_->fromRawIndex(rawIndex));
}
WFlags<HeaderFlag> WAbstractProxyModel::headerFlags(int section, Orientation orientation) const
{
if (orientation == Wt::Horizontal) {
section = mapToSource(index(0, section, Wt::WModelIndex())).column();
} else {
section = mapToSource(index(section, 0, Wt::WModelIndex())).row();
}
return sourceModel_->headerFlags(section, orientation);
}
boost::any WAbstractProxyModel::headerData(int section, Orientation orientation, int role) const
{
if (orientation == Wt::Horizontal) {
section = mapToSource(index(0, section, Wt::WModelIndex())).column();
} else {
section = mapToSource(index(section, 0, Wt::WModelIndex())).row();
}
return sourceModel_->headerData(section, orientation, role);
}
WModelIndex WAbstractProxyModel::createSourceIndex(int row, int column,
void *ptr) const
{
return sourceModel_->createIndex(row, column, ptr);
}
void WAbstractProxyModel::shiftModelIndexes(const WModelIndex& sourceParent,
int start, int count,
ItemMap& items)
{
/*
* We must shift all indexes within sourceParent >= start with count
* and delete items when count < 0.
*
* If count > 0 : rows inserted, after insertion
* If count < 0 : rows to be removed, before removal
*/
std::vector<BaseItem *> shifted;
std::vector<BaseItem *> erased;
WModelIndex startIndex;
if (sourceModel()->rowCount(sourceParent) == 0)
startIndex = sourceParent;
else if (start >= sourceModel()->rowCount(sourceParent))
startIndex = sourceModel()->index(sourceModel()->rowCount(sourceParent)-1,0,
sourceParent);
else
startIndex = sourceModel()->index(start, 0, sourceParent);
#ifdef WT_TARGET_JAVA
if (!startIndex.isValid())
return;
#endif
for (ItemMap::iterator it = items.lower_bound(startIndex);
it != items.end();) {
#ifndef WT_TARGET_JAVA
ItemMap::iterator n = it;
++n;
#endif
WModelIndex i = it->first;
if (i == sourceParent)
continue;
if (i.isValid()) {
WModelIndex p = i.parent();
if (p != sourceParent && !WModelIndex::isAncestor(p, sourceParent))
break;
if (p == sourceParent) {
if (count < 0 &&
i.row() >= start &&
i.row() < start + (-count))
erased.push_back(it->second);
else
shifted.push_back(it->second);
} else if (count < 0) {
// delete indexes that are about to be deleted, if they are within
// the range of deleted indexes
do {
if (p.parent() == sourceParent
&& p.row() >= start
&& p.row() < start + (-count)) {
erased.push_back(it->second);
break;
} else
p = p.parent();
} while (p != sourceParent);
}
}
#ifndef WT_TARGET_JAVA
it = n;
#endif
}
for (unsigned i = 0; i < erased.size(); ++i) {
items.erase(erased[i]->sourceIndex_);
delete erased[i];
}
for (unsigned i = 0; i < shifted.size(); ++i) {
BaseItem *item = shifted[i];
items.erase(item->sourceIndex_);
if (item->sourceIndex_.row() + count >= start) {
item->sourceIndex_ = sourceModel()->index
(item->sourceIndex_.row() + count,
item->sourceIndex_.column(),
sourceParent);
} else {
delete item;
shifted[i] = 0;
}
}
for (unsigned i = 0; i < shifted.size(); ++i) {
if (shifted[i])
items[shifted[i]->sourceIndex_] = shifted[i];
}
}
#endif // DOXYGEN_ONLY
}