1 /*
2 * Copyright (C) 2008 Emweb bv, Herent, Belgium.
3 *
4 * See the LICENSE file for terms of use.
5 */
6 #include <iostream>
7
8 #include "Wt/WAggregateProxyModel.h"
9 #include "Wt/WException.h"
10
11 namespace {
contains2(int a1,int a2,int b1,int b2)12 bool contains2(int a1, int a2, int b1, int b2) {
13 return b1 >= a1 && b1 <= a2 && b2 >= a1 && b2 <= a2;
14 }
15
overlaps(int a1,int a2,int b1,int b2)16 bool overlaps(int a1, int a2, int b1, int b2) {
17 return !((a2 < b1) || (a1 > b2));
18 }
19
nestingError(int pa,int a1,int a2,int pb,int b1,int b2)20 std::string nestingError(int pa, int a1, int a2, int pb, int b1, int b2) {
21 std::stringstream msg;
22
23 msg
24 << "WAggregateProxyModel: aggregates must strictly nest: ["
25 << pa << ": " << a1 << " - " << a2 << "] overlaps partially with ["
26 << pb << ": " << b1 << " - " << b2 << "]";
27
28 return msg.str();
29 }
30 }
31
32 namespace Wt {
33
Aggregate()34 WAggregateProxyModel::Aggregate::Aggregate()
35 : parentSrc_(-1),
36 firstChildSrc_(-1),
37 lastChildSrc_(-1),
38 level_(0),
39 collapsed_(false)
40 { }
41
Aggregate(int parentColumn,int firstColumn,int lastColumn)42 WAggregateProxyModel::Aggregate::Aggregate(int parentColumn,
43 int firstColumn, int lastColumn)
44 : parentSrc_(parentColumn),
45 firstChildSrc_(firstColumn),
46 lastChildSrc_(lastColumn),
47 level_(0),
48 collapsed_(false)
49 {
50 if (parentSrc_ != firstChildSrc_ - 1 && parentSrc_ != lastChildSrc_ + 1)
51 throw WException("WAggregateProxyModel::addAggregate: parent column "
52 "must border children range");
53 }
54
contains(const Aggregate & other)55 bool WAggregateProxyModel::Aggregate::contains(const Aggregate& other) const
56 {
57 int pa = parentSrc_, a1 = firstChildSrc_, a2 = lastChildSrc_,
58 pb = other.parentSrc_, b1 = other.firstChildSrc_, b2 = other.lastChildSrc_;
59
60 if (pb >= a1 && pb <= a2) {
61 if (!::contains2(a1, a2, b1, b2))
62 throw WException(nestingError(pa, a1, a2, pb, b1, b2));
63
64 return true;
65 } else {
66 if (::overlaps(a1, a2, b1, b2))
67 throw WException(nestingError(pa, a1, a2, pb, b1, b2));
68
69 return false;
70 }
71 }
72
73 WAggregateProxyModel::Aggregate *
add(const Aggregate & toAdd)74 WAggregateProxyModel::Aggregate::add(const Aggregate& toAdd)
75 {
76 for (unsigned int i = 0; i < nestedAggregates_.size(); ++i) {
77 Aggregate& a = nestedAggregates_[i];
78
79 if (a.contains(toAdd))
80 return a.add(toAdd);
81
82 if (toAdd.before(a)) {
83 nestedAggregates_.insert(nestedAggregates_.begin() + i, toAdd);
84 nestedAggregates_[i].level_ = level_ + 1;
85 return &nestedAggregates_[i];
86 }
87 }
88
89 nestedAggregates_.push_back(toAdd);
90 nestedAggregates_.back().level_ = level_ + 1;
91 return &nestedAggregates_.back();
92 }
93
94 WAggregateProxyModel::Aggregate *
findAggregate(int parentColumn)95 WAggregateProxyModel::Aggregate::findAggregate(int parentColumn)
96 {
97 if (parentSrc_ == parentColumn)
98 return this;
99 else if (parentSrc_ != -1 && parentColumn > lastChildSrc_)
100 return nullptr;
101 else {
102 for (unsigned int i = 0; i < nestedAggregates_.size(); ++i) {
103 Aggregate& a = nestedAggregates_[i];
104
105 Aggregate *result = a.findAggregate(parentColumn);
106 if (result)
107 return result;
108 }
109 }
110
111 return nullptr;
112 }
113
114 const WAggregateProxyModel::Aggregate *
findAggregate(int parentColumn)115 WAggregateProxyModel::Aggregate::findAggregate(int parentColumn) const
116 {
117 return const_cast<Aggregate *>(this)->findAggregate(parentColumn);
118 }
119
120 const WAggregateProxyModel::Aggregate *
findEnclosingAggregate(int column)121 WAggregateProxyModel::Aggregate::findEnclosingAggregate(int column) const
122 {
123 for (unsigned int i = 0; i < nestedAggregates_.size(); ++i) {
124 const Aggregate& a = nestedAggregates_[i];
125
126 if (a.after(column))
127 return this;
128
129 if (a.contains(column))
130 return a.findEnclosingAggregate(column);
131 }
132
133 return this;
134 }
135
mapFromSource(int sourceColumn)136 int WAggregateProxyModel::Aggregate::mapFromSource(int sourceColumn) const
137 {
138 int collapsedCount = 0;
139
140 for (unsigned i = 0; i < nestedAggregates_.size(); ++i) {
141 const Aggregate& a = nestedAggregates_[i];
142
143 if (a.after(sourceColumn))
144 return sourceColumn - collapsedCount;
145 else if (a.contains(sourceColumn))
146 if (a.collapsed_)
147 return -1;
148 else
149 return a.mapFromSource(sourceColumn) - collapsedCount;
150 else // a < sourceColumn
151 collapsedCount += a.collapsedCount();
152 }
153
154 return sourceColumn - collapsedCount;
155 }
156
mapToSource(int column)157 int WAggregateProxyModel::Aggregate::mapToSource(int column) const
158 {
159 int sourceColumn = column;
160
161 for (unsigned i = 0; i < nestedAggregates_.size(); ++i) {
162 const Aggregate& a = nestedAggregates_[i];
163
164 if (a.after(sourceColumn))
165 return sourceColumn;
166 else if (!a.collapsed_ && a.contains(sourceColumn))
167 return a.mapToSource(sourceColumn);
168 else
169 sourceColumn += a.collapsedCount();
170 }
171
172 return sourceColumn;
173 }
174
before(const Aggregate & other)175 bool WAggregateProxyModel::Aggregate::before(const Aggregate& other) const
176 {
177 return lastChildSrc_ < other.firstChildSrc_;
178 }
179
after(int column)180 bool WAggregateProxyModel::Aggregate::after(int column) const
181 {
182 return firstChildSrc_ > column;
183 }
184
before(int column)185 bool WAggregateProxyModel::Aggregate::before(int column) const
186 {
187 return lastChildSrc_ < column;
188 }
189
contains(int sourceColumn)190 bool WAggregateProxyModel::Aggregate::contains(int sourceColumn) const
191 {
192 return firstChildSrc_ <= sourceColumn && sourceColumn <= lastChildSrc_;
193 }
194
collapsedCount()195 int WAggregateProxyModel::Aggregate::collapsedCount() const
196 {
197 if (collapsed_)
198 return lastChildSrc_ - firstChildSrc_ + 1;
199 else {
200 int result = 0;
201
202 for (unsigned i = 0; i < nestedAggregates_.size(); ++i) {
203 const Aggregate& a = nestedAggregates_[i];
204
205 result += a.collapsedCount();
206 }
207
208 return result;
209 }
210 }
211
firstVisibleNotBefore(int column)212 int WAggregateProxyModel::Aggregate::firstVisibleNotBefore(int column) const
213 {
214 if (collapsed_)
215 return lastChildSrc_ + 1;
216 else {
217 for (unsigned i = 0; i < nestedAggregates_.size(); ++i) {
218 const Aggregate& a = nestedAggregates_[i];
219
220 if (a.after(column))
221 return column;
222 else if (a.before(column))
223 continue;
224 else
225 column = a.firstVisibleNotBefore(column);
226 }
227
228 return column;
229 }
230 }
231
lastVisibleNotAfter(int column)232 int WAggregateProxyModel::Aggregate::lastVisibleNotAfter(int column) const
233 {
234 if (collapsed_)
235 return firstChildSrc_ - 1;
236 else {
237 for (int i = nestedAggregates_.size() - 1; i >= 0; --i) {
238 const Aggregate& a = nestedAggregates_[i];
239
240 if (a.before(column))
241 return column;
242 else if (a.after(column))
243 continue;
244 else
245 column = a.lastVisibleNotAfter(column);
246 }
247
248 return column;
249 }
250 }
251
WAggregateProxyModel()252 WAggregateProxyModel::WAggregateProxyModel()
253 : topLevel_()
254 { }
255
~WAggregateProxyModel()256 WAggregateProxyModel::~WAggregateProxyModel()
257 { }
258
259 void WAggregateProxyModel
setSourceModel(const std::shared_ptr<WAbstractItemModel> & model)260 ::setSourceModel(const std::shared_ptr<WAbstractItemModel>& model)
261 {
262 for (unsigned i = 0; i < modelConnections_.size(); ++i)
263 modelConnections_[i].disconnect();
264 modelConnections_.clear();
265
266 WAbstractProxyModel::setSourceModel(model);
267
268 modelConnections_.push_back(sourceModel()->columnsAboutToBeInserted().connect
269 (this, &WAggregateProxyModel::sourceColumnsAboutToBeInserted));
270 modelConnections_.push_back(sourceModel()->columnsInserted().connect
271 (this, &WAggregateProxyModel::sourceColumnsInserted));
272
273 modelConnections_.push_back(sourceModel()->columnsAboutToBeRemoved().connect
274 (this, &WAggregateProxyModel::sourceColumnsAboutToBeRemoved));
275 modelConnections_.push_back(sourceModel()->columnsRemoved().connect
276 (this, &WAggregateProxyModel::sourceColumnsRemoved));
277
278 modelConnections_.push_back(sourceModel()->rowsAboutToBeInserted().connect
279 (this, &WAggregateProxyModel::sourceRowsAboutToBeInserted));
280 modelConnections_.push_back(sourceModel()->rowsInserted().connect
281 (this, &WAggregateProxyModel::sourceRowsInserted));
282
283 modelConnections_.push_back(sourceModel()->rowsAboutToBeRemoved().connect
284 (this, &WAggregateProxyModel::sourceRowsAboutToBeRemoved));
285 modelConnections_.push_back(sourceModel()->rowsRemoved().connect
286 (this, &WAggregateProxyModel::sourceRowsRemoved));
287
288 modelConnections_.push_back(sourceModel()->dataChanged().connect
289 (this, &WAggregateProxyModel::sourceDataChanged));
290 modelConnections_.push_back(sourceModel()->headerDataChanged().connect
291 (this, &WAggregateProxyModel::sourceHeaderDataChanged));
292
293 modelConnections_.push_back(sourceModel()->layoutAboutToBeChanged().connect
294 (this, &WAggregateProxyModel::sourceLayoutAboutToBeChanged));
295 modelConnections_.push_back(sourceModel()->layoutChanged().connect
296 (this, &WAggregateProxyModel::sourceLayoutChanged));
297
298 modelConnections_.push_back(sourceModel()->modelReset().connect
299 (this, &WAggregateProxyModel::sourceModelReset));
300
301 topLevel_ = Aggregate();
302 }
303
addAggregate(int parentColumn,int firstColumn,int lastColumn)304 void WAggregateProxyModel::addAggregate(int parentColumn,
305 int firstColumn, int lastColumn)
306 {
307 Aggregate *added
308 = topLevel_.add(Aggregate(parentColumn, firstColumn, lastColumn));
309
310 collapse(*added);
311 }
312
propagateBeginRemove(const WModelIndex & proxyIndex,int start,int end)313 void WAggregateProxyModel::propagateBeginRemove(const WModelIndex& proxyIndex,
314 int start, int end)
315 {
316 // should be beginRemoveColumns(), but endRemoveColumns() calls cannot
317 // be nested
318 columnsAboutToBeRemoved().emit(proxyIndex, start, end);
319
320 unsigned int rc = rowCount(proxyIndex);
321 for (unsigned i = 0; i < rc; ++i)
322 propagateBeginRemove(index(i, 0, proxyIndex), start, end);
323 }
324
propagateEndRemove(const WModelIndex & proxyIndex,int start,int end)325 void WAggregateProxyModel::propagateEndRemove(const WModelIndex& proxyIndex,
326 int start, int end)
327 {
328 // should be endRemoveColumns(), but endRemoveColumns() calls cannot
329 // be nested
330 columnsRemoved().emit(proxyIndex, start, end);
331
332 unsigned int rc = rowCount(proxyIndex);
333 for (unsigned i = 0; i < rc; ++i)
334 propagateEndRemove(index(i, 0, proxyIndex), start, end);
335 }
336
propagateBeginInsert(const WModelIndex & proxyIndex,int start,int end)337 void WAggregateProxyModel::propagateBeginInsert(const WModelIndex& proxyIndex,
338 int start, int end)
339 {
340 // should be beginInsertColumns(), but endInsertColumns() calls cannot
341 // be nested
342 columnsAboutToBeInserted().emit(proxyIndex, start, end);
343
344 unsigned int rc = rowCount(proxyIndex);
345 for (unsigned i = 0; i < rc; ++i)
346 propagateBeginInsert(index(i, 0, proxyIndex), start, end);
347 }
348
propagateEndInsert(const WModelIndex & proxyIndex,int start,int end)349 void WAggregateProxyModel::propagateEndInsert(const WModelIndex& proxyIndex,
350 int start, int end)
351 {
352 // should be endInsertColumns(), but endInsertColumns() calls cannot
353 // be nested
354 columnsInserted().emit(proxyIndex, start, end);
355
356 unsigned int rc = rowCount(proxyIndex);
357 for (unsigned i = 0; i < rc; ++i)
358 propagateEndInsert(index(i, 0, proxyIndex), start, end);
359 }
360
expandColumn(int column)361 void WAggregateProxyModel::expandColumn(int column)
362 {
363 int sourceColumn = topLevel_.mapToSource(column);
364 Aggregate *ag = topLevel_.findAggregate(sourceColumn);
365
366 if (ag)
367 expand(*ag);
368 }
369
collapseColumn(int column)370 void WAggregateProxyModel::collapseColumn(int column)
371 {
372 int sourceColumn = topLevel_.mapToSource(column);
373 Aggregate *ag = topLevel_.findAggregate(sourceColumn);
374
375 if (ag)
376 collapse(*ag);
377 }
378
expand(Aggregate & aggregate)379 void WAggregateProxyModel::expand(Aggregate& aggregate)
380 {
381 int c = topLevel_.mapFromSource(aggregate.parentSrc_);
382 if (c >= 0) {
383 aggregate.collapsed_ = false;
384 int c1 = topLevel_.mapFromSource(firstVisibleSourceNotBefore
385 (aggregate.firstChildSrc_));
386 int c2 = topLevel_.mapFromSource(lastVisibleSourceNotAfter
387 (aggregate.lastChildSrc_));
388 aggregate.collapsed_ = true;
389
390 propagateBeginInsert(WModelIndex(), c1, c2);
391 aggregate.collapsed_ = false;
392 propagateEndInsert(WModelIndex(), c1, c2);
393 } else
394 aggregate.collapsed_ = false;
395 }
396
collapse(Aggregate & aggregate)397 void WAggregateProxyModel::collapse(Aggregate& aggregate)
398 {
399 int c = topLevel_.mapFromSource(aggregate.parentSrc_);
400 if (c >= 0) {
401 int c1 = topLevel_.mapFromSource(firstVisibleSourceNotBefore
402 (aggregate.firstChildSrc_));
403 int c2 = topLevel_.mapFromSource(lastVisibleSourceNotAfter
404 (aggregate.lastChildSrc_));
405
406 propagateBeginRemove(WModelIndex(), c1, c2);
407 aggregate.collapsed_ = true;
408 propagateEndRemove(WModelIndex(), c1, c2);
409 } else
410 aggregate.collapsed_ = true;
411 }
412
mapFromSource(const WModelIndex & sourceIndex)413 WModelIndex WAggregateProxyModel::mapFromSource(const WModelIndex& sourceIndex)
414 const
415 {
416 if (sourceIndex.isValid()) {
417 int column = topLevel_.mapFromSource(sourceIndex.column());
418 if (column >= 0) {
419 int row = sourceIndex.row();
420
421 return createIndex(row, column, sourceIndex.internalPointer());
422 } else
423 return WModelIndex();
424 } else
425 return WModelIndex();
426 }
427
mapToSource(const WModelIndex & proxyIndex)428 WModelIndex WAggregateProxyModel::mapToSource(const WModelIndex& proxyIndex)
429 const
430 {
431 if (proxyIndex.isValid()) {
432 int column = topLevel_.mapToSource(proxyIndex.column());
433 int row = proxyIndex.row();
434
435 return createSourceIndex(row, column, proxyIndex.internalPointer());
436 } else
437 return WModelIndex();
438 }
439
index(int row,int column,const WModelIndex & parent)440 WModelIndex WAggregateProxyModel::index(int row, int column,
441 const WModelIndex& parent) const
442 {
443 WModelIndex sourceParent = mapToSource(parent);
444 int sourceRow = row;
445 int sourceColumn = topLevel_.mapToSource(column);
446
447 WModelIndex sourceIndex
448 = sourceModel()->index(sourceRow, sourceColumn, sourceParent);
449
450 return createIndex(row, column,
451 sourceIndex.isValid() ? sourceIndex.internalPointer() :
452 nullptr);
453 }
454
parent(const WModelIndex & index)455 WModelIndex WAggregateProxyModel::parent(const WModelIndex& index) const
456 {
457 if (index.isValid())
458 return mapFromSource(mapToSource(index).parent());
459 else
460 return WModelIndex();
461 }
462
columnCount(const WModelIndex & parent)463 int WAggregateProxyModel::columnCount(const WModelIndex& parent) const
464 {
465 int c = sourceModel()->columnCount(mapToSource(parent));
466 if (c > 0) {
467 c = lastVisibleSourceNotAfter(c - 1);
468 return topLevel_.mapFromSource(c) + 1;
469 } else
470 return 0;
471 }
472
rowCount(const WModelIndex & parent)473 int WAggregateProxyModel::rowCount(const WModelIndex& parent) const
474 {
475 return sourceModel()->rowCount(mapToSource(parent));
476 }
477
sort(int column,Wt::SortOrder order)478 void WAggregateProxyModel::sort(int column, Wt::SortOrder order)
479 {
480 sourceModel()->sort(topLevel_.mapToSource(column), order);
481 }
482
headerData(int section,Orientation orientation,ItemDataRole role)483 cpp17::any WAggregateProxyModel::headerData(int section,
484 Orientation orientation, ItemDataRole role) const
485 {
486 if (orientation == Orientation::Horizontal) {
487 section = topLevel_.mapToSource(section);
488 if (role == ItemDataRole::Level) {
489 const Aggregate *agg = topLevel_.findEnclosingAggregate(section);
490 return cpp17::any(agg->level_);
491 } else
492 return sourceModel()->headerData(section, orientation, role);
493 } else
494 return sourceModel()->headerData(section, orientation, role);
495 }
496
setHeaderData(int section,Orientation orientation,const cpp17::any & value,ItemDataRole role)497 bool WAggregateProxyModel::setHeaderData(int section, Orientation orientation,
498 const cpp17::any& value, ItemDataRole role)
499 {
500 if (orientation == Orientation::Horizontal)
501 section = topLevel_.mapToSource(section);
502
503 return sourceModel()->setHeaderData(section, orientation, value, role);
504 }
505
headerFlags(int section,Orientation orientation)506 WFlags<HeaderFlag> WAggregateProxyModel::headerFlags(int section,
507 Orientation orientation)
508 const
509 {
510 if (orientation == Orientation::Horizontal) {
511 int srcColumn = topLevel_.mapToSource(section);
512
513 WFlags<HeaderFlag> result
514 = sourceModel()->headerFlags(srcColumn, orientation);
515
516 const Aggregate *agg = topLevel_.findAggregate(srcColumn);
517 if (agg) {
518 if (agg->collapsed_)
519 return result | HeaderFlag::ColumnIsCollapsed;
520 else
521 if (agg->parentSrc_ == agg->lastChildSrc_ + 1)
522 return result | HeaderFlag::ColumnIsExpandedLeft;
523 else // agg->parentSrc_ == firstChildSrc_ - 1
524 return result | HeaderFlag::ColumnIsExpandedRight;
525 } else
526 return result;
527 } else
528 return sourceModel()->headerFlags(section, orientation);
529 }
530
sourceColumnsAboutToBeInserted(const WModelIndex & parent,int start,int end)531 void WAggregateProxyModel::sourceColumnsAboutToBeInserted
532 (const WModelIndex& parent, int start, int end)
533 {
534 throw WException("WAggregateProxyModel does not support "
535 "source model column insertion");
536 }
537
sourceColumnsInserted(const WModelIndex & parent,int start,int end)538 void WAggregateProxyModel::sourceColumnsInserted(const WModelIndex& parent,
539 int start, int end)
540 {
541 throw WException("WAggregateProxyModel does not support "
542 "source model column insertion");
543 }
544
sourceColumnsAboutToBeRemoved(const WModelIndex & parent,int start,int end)545 void WAggregateProxyModel::sourceColumnsAboutToBeRemoved
546 (const WModelIndex& parent, int start, int end)
547 {
548 throw WException("WAggregateProxyModel does not support "
549 "source model column removal");
550 }
551
sourceColumnsRemoved(const WModelIndex & parent,int start,int end)552 void WAggregateProxyModel::sourceColumnsRemoved(const WModelIndex& parent,
553 int start, int end)
554 {
555 throw WException("WAggregateProxyModel does not support "
556 "source model column removal");
557 }
558
sourceRowsAboutToBeInserted(const WModelIndex & parent,int start,int end)559 void WAggregateProxyModel::sourceRowsAboutToBeInserted
560 (const WModelIndex& parent, int start, int end)
561 {
562 WModelIndex proxyParent = mapFromSource(parent);
563
564 if (proxyParent.isValid() || !parent.isValid())
565 beginInsertRows(proxyParent, start, end);
566 }
567
sourceRowsInserted(const WModelIndex & parent,int start,int end)568 void WAggregateProxyModel::sourceRowsInserted(const WModelIndex& parent,
569 int start, int end)
570 {
571 WModelIndex proxyParent = mapFromSource(parent);
572
573 if (proxyParent.isValid() || !parent.isValid())
574 endInsertRows();
575 }
576
sourceRowsAboutToBeRemoved(const WModelIndex & parent,int start,int end)577 void WAggregateProxyModel::sourceRowsAboutToBeRemoved
578 (const WModelIndex& parent, int start, int end)
579 {
580 WModelIndex proxyParent = mapFromSource(parent);
581
582 if (proxyParent.isValid() || !parent.isValid())
583 beginRemoveRows(proxyParent, start, end);
584 }
585
sourceRowsRemoved(const WModelIndex & parent,int start,int end)586 void WAggregateProxyModel::sourceRowsRemoved(const WModelIndex& parent,
587 int start, int end)
588 {
589 WModelIndex proxyParent = mapFromSource(parent);
590
591 if (proxyParent.isValid() || !parent.isValid())
592 endRemoveRows();
593 }
594
firstVisibleSourceNotBefore(int column)595 int WAggregateProxyModel::firstVisibleSourceNotBefore(int column) const
596 {
597 return topLevel_.firstVisibleNotBefore(column);
598 }
599
lastVisibleSourceNotAfter(int column)600 int WAggregateProxyModel::lastVisibleSourceNotAfter(int column) const
601 {
602 return topLevel_.lastVisibleNotAfter(column);
603 }
604
sourceDataChanged(const WModelIndex & topLeft,const WModelIndex & bottomRight)605 void WAggregateProxyModel::sourceDataChanged(const WModelIndex& topLeft,
606 const WModelIndex& bottomRight)
607 {
608 int l = firstVisibleSourceNotBefore(topLeft.column());
609 int r = lastVisibleSourceNotAfter(bottomRight.column());
610
611 if (r >= l) {
612 WModelIndex tl = mapFromSource(sourceModel()->index(topLeft.row(),
613 l,
614 topLeft.parent()));
615 WModelIndex br = mapFromSource(sourceModel()->index(bottomRight.row(),
616 r,
617 bottomRight.parent()));
618 dataChanged().emit(tl, br);
619 }
620 }
621
sourceHeaderDataChanged(Orientation orientation,int start,int end)622 void WAggregateProxyModel::sourceHeaderDataChanged(Orientation orientation,
623 int start, int end)
624 {
625 if (orientation == Orientation::Vertical) {
626 headerDataChanged().emit(orientation, start, end);
627 } else {
628 int l = firstVisibleSourceNotBefore(start);
629 int r = lastVisibleSourceNotAfter(end);
630
631 if (r >= l) {
632 l = topLevel_.mapFromSource(l);
633 r = topLevel_.mapFromSource(r);
634
635 headerDataChanged().emit(orientation, l, r);
636 }
637 }
638 }
639
sourceLayoutAboutToBeChanged()640 void WAggregateProxyModel::sourceLayoutAboutToBeChanged()
641 {
642 layoutAboutToBeChanged().emit();
643 }
644
sourceLayoutChanged()645 void WAggregateProxyModel::sourceLayoutChanged()
646 {
647 layoutChanged().emit();
648 }
649
sourceModelReset()650 void WAggregateProxyModel::sourceModelReset()
651 {
652 topLevel_ = Aggregate();
653 reset();
654 }
655
656 }
657