| Directory: | ./ |
|---|---|
| File: | src/MessageModelUnion.cpp |
| Date: | 2026-09-08 09:09:37 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 118 | 173 | 68.2% |
| Branches: | 88 | 271 | 32.5% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /***************************************************************************** | ||
| 2 | * | ||
| 3 | * Copyright (C) 2009 - 2025 Florian Pose <fp@igh.de> | ||
| 4 | * | ||
| 5 | * This file is part of the QtPdCom library. | ||
| 6 | * | ||
| 7 | * The QtPdCom library is free software: you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU Lesser General Public License as published by | ||
| 9 | * the Free Software Foundation, either version 3 of the License, or (at your | ||
| 10 | * option) any later version. | ||
| 11 | * | ||
| 12 | * The QtPdCom library is distributed in the hope that it will be useful, but | ||
| 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
| 14 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | ||
| 15 | * License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU Lesser General Public License | ||
| 18 | * along with the QtPdCom Library. If not, see <http://www.gnu.org/licenses/>. | ||
| 19 | * | ||
| 20 | ****************************************************************************/ | ||
| 21 | |||
| 22 | #include "MessageModelUnion.h" | ||
| 23 | using QtPdCom::MessageModelUnion; | ||
| 24 | |||
| 25 | #include "MessageModel.h" | ||
| 26 | |||
| 27 | #include <QAbstractProxyModel> | ||
| 28 | |||
| 29 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 30 | #include <QDebug> | ||
| 31 | #endif | ||
| 32 | |||
| 33 | /***************************************************************************** | ||
| 34 | * MessageModelUnion::Impl | ||
| 35 | ****************************************************************************/ | ||
| 36 | |||
| 37 | 3 | struct MessageModelUnion::Impl | |
| 38 | { | ||
| 39 | Impl() = delete; | ||
| 40 | 3 | Impl(MessageModelUnion *parent): | |
| 41 | 3 | parentModel {parent} | |
| 42 | 3 | {} | |
| 43 | |||
| 44 | MessageModelUnion *const parentModel; | ||
| 45 | |||
| 46 |
1/2✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
|
6 | struct SourceModel |
| 47 | { | ||
| 48 | 10 | ~SourceModel() { QObject::disconnect(connection); } | |
| 49 | |||
| 50 | QAbstractItemModel *model; | ||
| 51 | QString name; | ||
| 52 | const QtPdCom::Message *announcedMessage; | ||
| 53 | QMetaObject::Connection connection; | ||
| 54 | }; | ||
| 55 | QList<SourceModel> sourceModels; | ||
| 56 | const QtPdCom::Message *lastAnnounced {nullptr}; | ||
| 57 | |||
| 58 | struct SourceEntry | ||
| 59 | { | ||
| 60 | SourceModel *sourceModel; | ||
| 61 | int row; // original row in source model | ||
| 62 | }; | ||
| 63 | QVector<SourceEntry> mergedRows; | ||
| 64 | |||
| 65 | enum { SortColumn = 1 }; | ||
| 66 | |||
| 67 | 22 | void rebuildMergedRows() | |
| 68 | { | ||
| 69 | 22 | parentModel->beginResetModel(); | |
| 70 | 22 | mergedRows.clear(); | |
| 71 | |||
| 72 |
5/8✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 26 times.
✓ Branch 10 taken 22 times.
✓ Branch 12 taken 26 times.
✗ Branch 13 not taken.
|
48 | for (auto &sourceModel : sourceModels) { |
| 73 |
1/2✓ Branch 3 taken 26 times.
✗ Branch 4 not taken.
|
26 | int rows = sourceModel.model->rowCount(); |
| 74 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 26 times.
|
33 | for (int row = 0; row < rows; ++row) { |
| 75 |
1/2✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
7 | mergedRows.append({&sourceModel, row}); |
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | 22 | std::sort( | |
| 80 | mergedRows.begin(), | ||
| 81 | mergedRows.end(), | ||
| 82 | 2 | [this](const SourceEntry &a, const SourceEntry &b) { | |
| 83 | 2 | QVariant va = a.sourceModel->model->data( | |
| 84 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
8 | a.sourceModel->model->index( |
| 85 | 2 | a.row, | |
| 86 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
12 | SortColumn)); |
| 87 | 2 | QVariant vb = b.sourceModel->model->data( | |
| 88 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
8 | b.sourceModel->model->index( |
| 89 | 2 | b.row, | |
| 90 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
12 | SortColumn)); |
| 91 |
2/4✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
4 | return vb.toString() < va.toString(); |
| 92 | }); | ||
| 93 | |||
| 94 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 95 |
4/8✓ Branch 3 taken 22 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 22 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 22 times.
✗ Branch 14 not taken.
|
44 | qDebug() << __func__ << "(): Now " << mergedRows.size() |
| 96 |
1/2✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
|
44 | << " rows."; |
| 97 | #endif | ||
| 98 | 22 | parentModel->endResetModel(); | |
| 99 | 22 | } | |
| 100 | |||
| 101 | 8 | void currentMessage( | |
| 102 | SourceModel *sourceModel, | ||
| 103 | const QtPdCom::Message *message) | ||
| 104 | { | ||
| 105 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 106 |
4/8✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 8 times.
✗ Branch 13 not taken.
✓ Branch 16 taken 8 times.
✗ Branch 17 not taken.
|
8 | qDebug() << __func__ << sourceModel << message; |
| 107 | #endif | ||
| 108 | 8 | sourceModel->announcedMessage = message; | |
| 109 | 8 | updateCurrentMessage(); | |
| 110 | 8 | } | |
| 111 | |||
| 112 | 14 | void updateCurrentMessage() | |
| 113 | { | ||
| 114 | 14 | const QtPdCom::Message *candidate {nullptr}; | |
| 115 |
5/8✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 20 times.
✓ Branch 10 taken 14 times.
✓ Branch 12 taken 20 times.
✗ Branch 13 not taken.
|
34 | for (auto &sourceModel : sourceModels) { |
| 116 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 13 times.
|
20 | if (sourceModel.announcedMessage) { |
| 117 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
|
7 | if (not candidate |
| 118 |
4/6✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
|
8 | or sourceModel.announcedMessage->getType() |
| 119 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | > candidate->getType()) { |
| 120 | 6 | candidate = sourceModel.announcedMessage; | |
| 121 | } | ||
| 122 | } | ||
| 123 | } | ||
| 124 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 125 |
3/6✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 14 times.
✗ Branch 10 not taken.
✓ Branch 13 taken 14 times.
✗ Branch 14 not taken.
|
14 | qDebug() << __func__ << candidate; |
| 126 | #endif | ||
| 127 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
|
14 | if (candidate == lastAnnounced) { |
| 128 | 8 | return; | |
| 129 | } | ||
| 130 | 6 | lastAnnounced = candidate; | |
| 131 | 6 | emit parentModel->currentMessage(candidate); | |
| 132 | } | ||
| 133 | }; | ||
| 134 | |||
| 135 | /***************************************************************************** | ||
| 136 | * MessageModelUnion | ||
| 137 | ****************************************************************************/ | ||
| 138 | |||
| 139 | /** Constructor. | ||
| 140 | */ | ||
| 141 | 3 | MessageModelUnion::MessageModelUnion(QObject *parent): | |
| 142 | QAbstractTableModel(parent), | ||
| 143 |
1/2✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
|
3 | impl(std::unique_ptr<Impl>(new MessageModelUnion::Impl(this))) |
| 144 | 3 | {} | |
| 145 | |||
| 146 | /****************************************************************************/ | ||
| 147 | |||
| 148 | /** Destructor. | ||
| 149 | */ | ||
| 150 | 9 | MessageModelUnion::~MessageModelUnion() | |
| 151 | { | ||
| 152 | 3 | clearSourceModels(); | |
| 153 | 6 | } | |
| 154 | |||
| 155 | /****************************************************************************/ | ||
| 156 | |||
| 157 | 5 | void MessageModelUnion::addSourceModel( | |
| 158 | QAbstractItemModel *model, | ||
| 159 | QString sourceName) | ||
| 160 | { | ||
| 161 |
1/2✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
|
5 | impl->sourceModels.push_back( |
| 162 | {model, | ||
| 163 | sourceName, | ||
| 164 | nullptr, // announced message | ||
| 165 | QMetaObject::Connection()}); | ||
| 166 | 5 | auto *sourceModel = &impl->sourceModels.last(); | |
| 167 | |||
| 168 | 9 | connect(model, &QAbstractTableModel::rowsInserted, [this]() { | |
| 169 | 4 | impl->rebuildMergedRows(); | |
| 170 | 4 | }); | |
| 171 | 5 | connect(model, &QAbstractTableModel::rowsRemoved, [this]() { | |
| 172 | ✗ | impl->rebuildMergedRows(); | |
| 173 | ✗ | }); | |
| 174 | 5 | connect(model, &QAbstractTableModel::dataChanged, [this]() { | |
| 175 | ✗ | impl->rebuildMergedRows(); | |
| 176 | ✗ | }); | |
| 177 | 5 | connect(model, &QAbstractTableModel::layoutChanged, [this]() { | |
| 178 | ✗ | impl->rebuildMergedRows(); | |
| 179 | ✗ | }); | |
| 180 | 17 | connect(model, &QAbstractTableModel::modelReset, [this]() { | |
| 181 | 12 | impl->rebuildMergedRows(); | |
| 182 | 12 | }); | |
| 183 | |||
| 184 | // find a QtPdCom::MessageModel after a chain of QAbstractProxyModels | ||
| 185 | 5 | QtPdCom::MessageModel *messageModel {nullptr}; | |
| 186 | while (true) { | ||
| 187 | 5 | auto *proxy {qobject_cast<QAbstractProxyModel *>(model)}; | |
| 188 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | if (not proxy) { |
| 189 | 5 | messageModel = qobject_cast<QtPdCom::MessageModel *>(model); | |
| 190 | 5 | break; | |
| 191 | } | ||
| 192 | ✗ | model = proxy->sourceModel(); | |
| 193 | } | ||
| 194 | |||
| 195 |
1/2✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
|
5 | if (messageModel) { |
| 196 | 10 | sourceModel->connection = | |
| 197 | 10 | connect(messageModel, | |
| 198 | &MessageModel::currentMessage, | ||
| 199 | 16 | [this, sourceModel](const QtPdCom::Message *message) { | |
| 200 | 16 | impl->currentMessage(sourceModel, message); | |
| 201 | 13 | }); | |
| 202 | } | ||
| 203 | |||
| 204 | 5 | impl->rebuildMergedRows(); | |
| 205 | 5 | impl->updateCurrentMessage(); | |
| 206 | 5 | } | |
| 207 | |||
| 208 | /****************************************************************************/ | ||
| 209 | |||
| 210 | 1 | void MessageModelUnion::removeSourceModel(QAbstractItemModel *model) | |
| 211 | { | ||
| 212 | 1 | auto it = std::remove_if( | |
| 213 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | impl->sourceModels.begin(), |
| 214 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | impl->sourceModels.end(), |
| 215 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
5 | [model](const Impl::SourceModel &s) { return s.model == model; }); |
| 216 |
2/4✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
|
1 | impl->sourceModels.erase(it, impl->sourceModels.end()); |
| 217 | |||
| 218 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | impl->rebuildMergedRows(); |
| 219 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | impl->updateCurrentMessage(); |
| 220 | 1 | } | |
| 221 | |||
| 222 | /****************************************************************************/ | ||
| 223 | |||
| 224 | 4 | void MessageModelUnion::clearSourceModels() | |
| 225 | { | ||
| 226 | 4 | beginResetModel(); | |
| 227 | 4 | impl->sourceModels.clear(); | |
| 228 | 4 | endResetModel(); | |
| 229 | 4 | } | |
| 230 | |||
| 231 | /****************************************************************************/ | ||
| 232 | |||
| 233 | 24 | int MessageModelUnion::rowCount(const QModelIndex &) const | |
| 234 | { | ||
| 235 | 24 | return impl->mergedRows.count(); | |
| 236 | } | ||
| 237 | |||
| 238 | /****************************************************************************/ | ||
| 239 | |||
| 240 | 14 | int MessageModelUnion::columnCount(const QModelIndex &) const | |
| 241 | { | ||
| 242 | 14 | return 4; | |
| 243 | } | ||
| 244 | |||
| 245 | /****************************************************************************/ | ||
| 246 | |||
| 247 | 14 | QVariant MessageModelUnion::data(const QModelIndex &index, int role) const | |
| 248 | { | ||
| 249 | 14 | QVariant ret; | |
| 250 | |||
| 251 |
3/6✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
|
14 | if (index.isValid() and index.row() < impl->mergedRows.size()) { |
| 252 |
1/2✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
|
14 | auto entry {impl->mergedRows[index.row()]}; |
| 253 | 14 | QModelIndex sourceIndex = | |
| 254 |
1/2✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
|
14 | entry.sourceModel->model->index(entry.row, index.column()); |
| 255 |
5/6✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 2 times.
|
14 | if (index.column() >= TextColumn and index.column() < SourceColumn) { |
| 256 |
1/2✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
|
12 | ret = entry.sourceModel->model->data(sourceIndex, role); |
| 257 | } | ||
| 258 |
3/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
2 | else if (index.column() == SourceColumn and role == Qt::DisplayRole) { |
| 259 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
2 | ret = entry.sourceModel->name; |
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 264 |
5/10✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 14 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 14 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 14 times.
✗ Branch 19 not taken.
✓ Branch 22 taken 14 times.
✗ Branch 23 not taken.
|
14 | qDebug() << __func__ << index << role << ret; |
| 265 | #endif | ||
| 266 | 14 | return ret; | |
| 267 | } | ||
| 268 | |||
| 269 | /****************************************************************************/ | ||
| 270 | |||
| 271 | QVariant | ||
| 272 | ✗ | MessageModelUnion::headerData(int section, Qt::Orientation o, int role) const | |
| 273 | { | ||
| 274 | ✗ | if (role == Qt::DisplayRole && o == Qt::Horizontal) { | |
| 275 | ✗ | switch (section) { | |
| 276 | ✗ | case TextColumn: | |
| 277 | ✗ | return tr("Message"); | |
| 278 | |||
| 279 | ✗ | case TimeOccurredColumn: | |
| 280 | ✗ | return tr("Time"); | |
| 281 | |||
| 282 | ✗ | case TimeResetColumn: | |
| 283 | ✗ | return tr("Reset"); | |
| 284 | |||
| 285 | ✗ | case SourceColumn: | |
| 286 | ✗ | return tr("Source"); | |
| 287 | |||
| 288 | ✗ | default: | |
| 289 | ✗ | return QVariant(); | |
| 290 | } | ||
| 291 | } | ||
| 292 | else { | ||
| 293 | ✗ | return QVariant(); | |
| 294 | } | ||
| 295 | } | ||
| 296 | |||
| 297 | /****************************************************************************/ | ||
| 298 | |||
| 299 | 4 | Qt::ItemFlags MessageModelUnion::flags(const QModelIndex &index) const | |
| 300 | { | ||
| 301 | 4 | Qt::ItemFlags ret; | |
| 302 | |||
| 303 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
|
4 | if (index.isValid() and index.row() < impl->mergedRows.size()) { |
| 304 |
1/2✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
4 | auto entry {impl->mergedRows[index.row()]}; |
| 305 | 4 | QModelIndex sourceIndex = | |
| 306 |
1/2✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
4 | entry.sourceModel->model->index(entry.row, index.column()); |
| 307 |
3/6✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
|
4 | if (index.column() >= TextColumn and index.column() < SourceColumn) { |
| 308 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | ret = entry.sourceModel->model->flags(sourceIndex); |
| 309 | } | ||
| 310 | ✗ | else if (index.column() == SourceColumn) { | |
| 311 | ✗ | QModelIndex textIndex = | |
| 312 | ✗ | entry.sourceModel->model->index(entry.row, TextColumn); | |
| 313 | ✗ | ret = entry.sourceModel->model->flags(textIndex); | |
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 318 |
4/8✓ Branch 7 taken 4 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 4 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 4 times.
✗ Branch 18 not taken.
|
4 | qDebug() << __func__ << index << ret; |
| 319 | #endif | ||
| 320 | 4 | return ret; | |
| 321 | } | ||
| 322 | |||
| 323 | /****************************************************************************/ | ||
| 324 | |||
| 325 | ✗ | bool MessageModelUnion::canFetchMore(const QModelIndex &index) const | |
| 326 | { | ||
| 327 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 328 | ✗ | qDebug() << __func__ << index; | |
| 329 | #endif | ||
| 330 | ✗ | if (not index.isValid()) { | |
| 331 | // root layer - return true if *any* model can fetch more rows | ||
| 332 | ✗ | for (auto &sourceModel : impl->sourceModels) { | |
| 333 | ✗ | if (sourceModel.model->canFetchMore(index)) { | |
| 334 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 335 | ✗ | qDebug() << sourceModel.model << sourceModel.name << "yes"; | |
| 336 | #endif | ||
| 337 | ✗ | return true; | |
| 338 | } | ||
| 339 | } | ||
| 340 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 341 | ✗ | qDebug() << "no"; | |
| 342 | #endif | ||
| 343 | ✗ | return false; | |
| 344 | } | ||
| 345 | ✗ | else if (index.row() < impl->mergedRows.size()) { | |
| 346 | ✗ | auto entry {impl->mergedRows[index.row()]}; | |
| 347 | ✗ | auto sourceIndex { | |
| 348 | ✗ | entry.sourceModel->model->index(entry.row, index.column())}; | |
| 349 | ✗ | auto canFetch {entry.sourceModel->model->canFetchMore(sourceIndex)}; | |
| 350 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 351 | ✗ | qDebug() << "specific" << canFetch; | |
| 352 | #endif | ||
| 353 | ✗ | return canFetch; | |
| 354 | } | ||
| 355 | else { | ||
| 356 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 357 | ✗ | qDebug() << "invalid"; | |
| 358 | #endif | ||
| 359 | ✗ | return false; | |
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | /****************************************************************************/ | ||
| 364 | |||
| 365 | ✗ | void MessageModelUnion::fetchMore(const QModelIndex &index) | |
| 366 | { | ||
| 367 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 368 | ✗ | qDebug() << __func__ << index; | |
| 369 | #endif | ||
| 370 | ✗ | if (not index.isValid()) { | |
| 371 | // root layer - pass on to *any* model that can fetch more rows | ||
| 372 | ✗ | for (auto &sourceModel : impl->sourceModels) { | |
| 373 | ✗ | if (sourceModel.model->canFetchMore(index)) { | |
| 374 | #if PD_DEBUG_MESSAGE_MODEL | ||
| 375 | ✗ | qDebug() << __func__ << sourceModel.model << sourceModel.name; | |
| 376 | #endif | ||
| 377 | ✗ | sourceModel.model->fetchMore(index); | |
| 378 | } | ||
| 379 | } | ||
| 380 | } | ||
| 381 | ✗ | else if (index.row() < impl->mergedRows.size()) { | |
| 382 | ✗ | auto entry {impl->mergedRows[index.row()]}; | |
| 383 | ✗ | auto sourceIndex { | |
| 384 | ✗ | entry.sourceModel->model->index(entry.row, index.column())}; | |
| 385 | ✗ | entry.sourceModel->model->fetchMore(sourceIndex); | |
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | /****************************************************************************/ | ||
| 390 |