20 : QAbstractItemModel (parent)
28 if (!
index.isValid ())
29 return Headers_.size ();
36 if (
orient != Qt::Horizontal ||
role != Qt::DisplayRole)
39 return Headers_.at (
column);
44 if (!
index.isValid ())
51 catch (
const std::exception&
e)
65 catch (
const std::exception&
e)
87 if (!
index.isValid () ||
index.internalPointer () == Root_.get ())
101 return Root_->GetRowCount ();
111 for (
const auto& type :
model->mimeTypes ())
112 if (!
result.contains (type))
131 std::unique_ptr<QMimeData>
result;
137 std::unique_ptr<QMimeData>
subresult {
src.model ()->mimeData ({
src }) };
170 <<
"no next item for"
192 throw std::runtime_error (
"You should not set source model via setSourceModel()");
213 &QAbstractItemModel::dataChanged,
220 &QAbstractItemModel::layoutAboutToBeChanged,
224 &QAbstractItemModel::layoutChanged,
228 &QAbstractItemModel::modelAboutToBeReset,
232 &QAbstractItemModel::modelReset,
236 &QAbstractItemModel::rowsAboutToBeInserted,
240 &QAbstractItemModel::rowsAboutToBeRemoved,
244 &QAbstractItemModel::rowsInserted,
248 &QAbstractItemModel::rowsRemoved,
252 if (
const auto rc =
model->rowCount ())
256 for (
auto i = 0;
i <
rc; ++
i)
257 Root_->AppendChild (
model,
model->index (
i, 0), Root_);
283 for (
auto r = Root_->begin ();
r != Root_->end (); )
284 if ((*r)->GetModel () ==
model)
286 const auto idx =
static_cast<int> (std::distance (Root_->begin (),
r));
289 r = Root_->EraseChild (
r);
307 result += (*i)->rowCount ({});
314 for (
auto i = Models_.begin (); i != it; ++i)
315 result += (*i)->rowCount ({});
321 const auto child = Root_->GetChild (row);
322 const auto it = FindModel (child->GetModel ());
325 *starting = GetStartingRow (it);
332 const auto child = Root_->GetChild (row);
333 const auto it = FindModel (child->GetModel ());
336 *starting = GetStartingRow (it);
344 for (
auto p : Models_)
350 void MergeModel::HandleRowsAboutToBeInserted (QAbstractItemModel *model,
const QModelIndex& parent,
int first,
int last)
352 const auto startingRow = parent.isValid () ?
354 GetStartingRow (FindModel (model));
355 beginInsertRows (mapFromSource (parent),
356 first + startingRow, last + startingRow);
359 void MergeModel::HandleRowsAboutToBeRemoved (QAbstractItemModel *model,
const QModelIndex& parent,
int first,
int last)
361 const auto startingRow = parent.isValid () ?
363 GetStartingRow (FindModel (model));
364 const auto mergedParent = mapFromSource (parent);
365 beginRemoveRows (mergedParent, first + startingRow, last + startingRow);
367 const auto rawItem = parent.isValid () ?
368 static_cast<ModelItem*
> (mergedParent.internalPointer ()) :
370 const auto& item = rawItem->shared_from_this ();
372 auto it = item->EraseChildren (item->begin () + startingRow + first,
373 item->begin () + startingRow + last + 1);
375 RemovalRefreshers_.push ([=] ()
mutable
377 for ( ; it != item->end () && (*it)->GetModel () == model; ++it)
378 (*it)->RefreshIndex (startingRow);
382 void MergeModel::HandleRowsInserted (QAbstractItemModel *model,
const QModelIndex& parent,
int first,
int last)
384 const auto startingRow = parent.isValid () ?
386 GetStartingRow (FindModel (model));
388 const auto rawItem = parent.isValid () ?
389 static_cast<ModelItem*
> (mapFromSource (parent).internalPointer ()) :
391 const auto& item = rawItem->shared_from_this ();
393 for ( ; first <= last; ++first)
395 const auto& srcIdx = model->index (first, 0, parent);
396 item->InsertChild (startingRow + first, model, srcIdx, item);
402 for (
int rc = item->GetRowCount (); last < rc; ++last)
404 const auto child = item->GetChild (last);
405 if (child->GetModel () != model)
408 child->RefreshIndex (startingRow);
414 void MergeModel::HandleRowsRemoved (QAbstractItemModel*,
const QModelIndex&,
int,
int)
416 RemovalRefreshers_.pop () ();
420 void MergeModel::HandleModelAboutToBeReset (QAbstractItemModel *model)
422 if (
const auto rc = model->rowCount ())
424 const auto startingRow = GetStartingRow (FindModel (model));
425 beginRemoveRows ({}, startingRow, rc + startingRow - 1);
426 Root_->EraseChildren (Root_->begin () + startingRow, Root_->begin () + startingRow + rc);
431 void MergeModel::HandleModelReset (QAbstractItemModel *model)
433 if (
const auto rc = model->rowCount ())
435 const auto startingRow = GetStartingRow (FindModel (model));
437 beginInsertRows ({}, startingRow, rc + startingRow - 1);
439 for (
int i = 0; i < rc; ++i)
440 Root_->InsertChild (startingRow + i, model, model->index (i, 0, {}), Root_);
446 bool MergeModel::AcceptsRow (QAbstractItemModel*,
int)
const
448 DefaultAcceptsRowImpl_ =
true;
452 int MergeModel::RowCount (QAbstractItemModel *model)
const
457 int orig = model->rowCount ();
458 if (DefaultAcceptsRowImpl_)
462 for (
int i = 0; i < orig; ++i)
463 result += AcceptsRow (model, i) ? 1 : 0;
QList< QAbstractItemModel * > GetAllModels() const
Returns all models intalled into this one.
QModelIndex index(int, int, const QModelIndex &=QModelIndex()) const override
const_iterator FindModel(const QAbstractItemModel *model) const
Returns a const_iterator corresponding to the passed model, or one-past-end if no such model is found...
virtual void HandleRowsAboutToBeInserted(QAbstractItemModel *, const QModelIndex &, int, int)
void AddModel(QAbstractItemModel *model)
Adds a model to the list of source models.
QMimeData * mimeData(const QModelIndexList &indices) const override
Returns the MIME data for the given indices.
virtual void HandleModelReset(QAbstractItemModel *)
size_t Size() const
Returns the number of child models in the merger.
virtual void HandleModelAboutToBeReset(QAbstractItemModel *)
virtual void setSourceModel(QAbstractItemModel *)
int GetStartingRow(const_iterator it) const
Finds starting row for the model pointed by it.
virtual void HandleRowsAboutToBeRemoved(QAbstractItemModel *, const QModelIndex &, int, int)
QModelIndex parent(const QModelIndex &) const override
virtual void HandleRowsRemoved(QAbstractItemModel *, const QModelIndex &, int, int)
virtual QModelIndex mapToSource(const QModelIndex &index) const
Returns the source model index corresponding to the given index from the sorting filter model.
void RemoveModel(QAbstractItemModel *model)
Removes a model from the list of source models.
int columnCount(const QModelIndex &=QModelIndex()) const override
int rowCount(const QModelIndex &=QModelIndex()) const override
void SetHeaders(const QStringList &headers)
Sets the new headers for this model.
Qt::ItemFlags flags(const QModelIndex &) const override
models_t::const_iterator const_iterator
virtual QModelIndex mapFromSource(const QModelIndex &index) const
Returns the model index in the MergeModel given the index from the source model.
QStringList mimeTypes() const override
Returns the union of MIME types of the models.
models_t::iterator iterator
QVariant data(const QModelIndex &, int=Qt::DisplayRole) const override
MergeModel(QStringList headers, QObject *parent=nullptr)
Constructs the merge model.
virtual void HandleRowsInserted(QAbstractItemModel *, const QModelIndex &, int, int)
QVariant headerData(int, Qt::Orientation, int=Qt::DisplayRole) const override
T_ptr GetParent() const
Returns the pointer to the parent item.
Provides a proxying API on top of an QAbstractItemModel.
QAbstractItemModel * GetModel() const
Returns the wrapped model.
Container< T > Filter(const Container< T > &c, F f)