42 : QAbstractItemModel (parent)
53 return mapped.model ()->columnCount (mapped);
56 return Headers_.size ();
61 if (orient != Qt::Horizontal || role != Qt::DisplayRole)
64 return Headers_.at (column);
69 if (!index.isValid ())
76 catch (
const std::exception& e)
78 qWarning () << Q_FUNC_INFO
90 catch (
const std::exception& e)
92 qWarning () << Q_FUNC_INFO
100 if (!hasIndex (row, column, parent))
103 auto parentItem = parent.isValid () ?
104 static_cast<ModelItem*
> (parent.internalPointer ()) :
107 return createIndex (row, column, parentItem->EnsureChild (row));
112 if (!index.isValid () || index.internalPointer () == Root_.get ())
115 auto item =
static_cast<ModelItem*
> (index.internalPointer ());
116 auto parent = item->GetParent ();
120 return createIndex (
parent->GetRow (), 0,
parent.get ());
125 if (!parent.isValid ())
126 return Root_->GetRowCount ();
128 const auto item =
static_cast<ModelItem*
> (parent.internalPointer ());
129 return item->
GetModel ()->rowCount (item->GetIndex ());
136 for (
const auto& type : model->mimeTypes ())
137 if (!result.contains (type))
144 void Merge (QMimeData *out,
const QMimeData *sub)
146 for (
const auto& format : sub->formats ())
147 if (format !=
"text/uri-list" && !out->hasFormat (format))
148 out->setData (format, sub->data (format));
150 out->setUrls (out->urls () + sub->urls ());
156 QMimeData *result =
nullptr;
158 for (
const auto&
index : indexes)
162 const auto subresult = src.model ()->mimeData ({ src });
171 Merge (result, subresult);
181 if (!sourceIndex.isValid ())
185 auto parent = sourceIndex;
192 auto currentItem = Root_;
193 for (
const auto& idx : hier)
195 currentItem = currentItem->FindChild (idx);
198 qWarning () << Q_FUNC_INFO
199 <<
"no next item for"
206 return createIndex (currentItem->GetRow (), sourceIndex.column (), currentItem.get ());
211 const auto item = proxyIndex.isValid () ?
212 static_cast<ModelItem*
> (proxyIndex.internalPointer ()) :
215 const auto& srcIdx = item->GetIndex ();
216 return srcIdx.sibling (srcIdx.row (), proxyIndex.column ());
221 throw std::runtime_error (
"You should not set source model via setSourceModel()");
237 SIGNAL (columnsAboutToBeInserted (
const QModelIndex&,
int,
int)),
241 SIGNAL (columnsAboutToBeRemoved (
const QModelIndex&,
int,
int)),
245 SIGNAL (columnsInserted (
const QModelIndex&,
int,
int)),
249 SIGNAL (columnsRemoved (
const QModelIndex&,
int,
int)),
253 SIGNAL (dataChanged (
const QModelIndex&,
const QModelIndex&)),
257 SIGNAL (layoutAboutToBeChanged ()),
261 SIGNAL (layoutChanged ()),
265 SIGNAL (modelAboutToBeReset ()),
269 SIGNAL (modelReset ()),
273 SIGNAL (rowsAboutToBeInserted (
const QModelIndex&,
int,
int)),
277 SIGNAL (rowsAboutToBeRemoved (
const QModelIndex&,
int,
int)),
281 SIGNAL (rowsInserted (
const QModelIndex&,
int,
int)),
285 SIGNAL (rowsRemoved (
const QModelIndex&,
int,
int)),
289 if (
const auto rc = model->rowCount ())
293 for (
auto i = 0; i < rc; ++i)
294 Root_->AppendChild (model, model->index (i, 0), Root_);
316 qWarning () << Q_FUNC_INFO <<
"not found model" << model;
320 for (
auto r = Root_->begin (); r != Root_->end (); )
321 if ((*r)->GetModel () == model)
323 const auto idx = std::distance (Root_->begin (), r);
325 beginRemoveRows ({}, idx, idx);
326 r = Root_->EraseChild (r);
343 for (
auto i =
Models_.begin (); i != it; ++i)
344 result += (*i)->rowCount ({});
350 const auto child = Root_->GetChild (row);
351 const auto it = FindModel (child->GetModel ());
354 *starting = GetStartingRow (it);
361 const auto child = Root_->GetChild (row);
362 const auto it = FindModel (child->GetModel ());
365 *starting = GetStartingRow (it);
373 for (
auto p : Models_)
379 void MergeModel::handleColumnsAboutToBeInserted (
const QModelIndex&,
int,
int)
383 void MergeModel::handleColumnsAboutToBeRemoved (
const QModelIndex&,
int,
int)
385 qWarning () <<
"model" << sender ()
386 <<
"called handleColumnsAboutToBeRemoved, ignoring it";
389 void MergeModel::handleColumnsInserted (
const QModelIndex&,
int,
int)
393 void MergeModel::handleColumnsRemoved (
const QModelIndex&,
int,
int)
395 qWarning () <<
"model" << sender ()
396 <<
"called handleColumnsRemoved, ignoring it";
399 void MergeModel::handleDataChanged (
const QModelIndex& topLeft,
400 const QModelIndex& bottomRight)
402 emit dataChanged (mapFromSource (topLeft), mapFromSource (bottomRight));
405 void MergeModel::handleRowsAboutToBeInserted (
const QModelIndex&
parent,
408 const auto model =
static_cast<QAbstractItemModel*
> (sender ());
410 const auto startingRow = parent.isValid () ?
412 GetStartingRow (FindModel (model));
413 beginInsertRows (mapFromSource (parent),
414 first + startingRow, last + startingRow);
417 void MergeModel::handleRowsAboutToBeRemoved (
const QModelIndex&
parent,
420 auto model =
static_cast<QAbstractItemModel*
> (sender ());
422 const auto startingRow = parent.isValid () ?
424 GetStartingRow (FindModel (model));
425 beginRemoveRows (mapFromSource (parent),
426 first + startingRow, last + startingRow);
428 const auto rawItem = parent.isValid () ?
429 static_cast<ModelItem*
> (mapFromSource (parent).internalPointer ()) :
431 const auto& item = rawItem->shared_from_this ();
433 auto it = item->
EraseChildren (item->begin () + startingRow + first,
434 item->begin () + startingRow + last + 1);
436 for ( ; it < item->end (); ++it)
438 if ((*it)->GetModel () != model)
441 (*it)->RefreshIndex (startingRow);
445 void MergeModel::handleRowsInserted (
const QModelIndex&
parent,
int first,
int last)
447 const auto model =
static_cast<QAbstractItemModel*
> (sender ());
449 const auto startingRow = parent.isValid () ?
451 GetStartingRow (FindModel (model));
453 const auto rawItem = parent.isValid () ?
454 static_cast<ModelItem*
> (mapFromSource (parent).internalPointer ()) :
456 const auto& item = rawItem->shared_from_this ();
458 for ( ; first <= last; ++first)
460 const auto& srcIdx = model->index (first, 0, parent);
461 item->
InsertChild (startingRow + first, model, srcIdx, item);
467 for (
int rc = item->GetRowCount (); last < rc; ++last)
469 const auto child = item->GetChild (last);
470 if (child->GetModel () != model)
473 child->RefreshIndex (startingRow);
479 void MergeModel::handleRowsRemoved (
const QModelIndex&,
int,
int)
484 void MergeModel::handleModelAboutToBeReset ()
486 const auto model =
static_cast<QAbstractItemModel*
> (sender ());
487 if (
const auto rc = model->rowCount ())
489 const auto startingRow = GetStartingRow (FindModel (model));
490 beginRemoveRows ({}, startingRow, rc + startingRow - 1);
491 Root_->EraseChildren (Root_->begin () + startingRow, Root_->begin () + startingRow + rc);
496 void MergeModel::handleModelReset ()
498 const auto model =
static_cast<QAbstractItemModel*
> (sender ());
499 if (
const auto rc = model->rowCount ())
501 const auto startingRow = GetStartingRow (FindModel (model));
503 beginInsertRows ({}, startingRow, rc + startingRow - 1);
505 for (
int i = 0; i < rc; ++i)
506 Root_->InsertChild (startingRow + i, model, model->index (i, 0, {}), Root_);
512 bool MergeModel::AcceptsRow (QAbstractItemModel*,
int)
const
514 DefaultAcceptsRowImpl_ =
true;
518 int MergeModel::RowCount (QAbstractItemModel *model)
const
523 int orig = model->rowCount ();
524 if (DefaultAcceptsRowImpl_)
528 for (
int i = 0; i < orig; ++i)
529 result += AcceptsRow (model, i) ? 1 : 0;
virtual QModelIndex mapToSource(const QModelIndex &index) const
Returns the source model index corresponding to the given index from the sorting filter model...
QMimeData * mimeData(const QModelIndexList &indices) const override
Returns the MIME data for the given indices.
QAbstractItemModel * GetModel() const
Returns the wrapped model.
virtual void setSourceModel(QAbstractItemModel *)
virtual void handleModelAboutToBeReset()
QModelIndex index(int, int, const QModelIndex &=QModelIndex()) const override
virtual void handleColumnsRemoved(const QModelIndex &, int, int)
virtual void handleColumnsAboutToBeRemoved(const QModelIndex &, int, int)
iterator EraseChildren(iterator begin, iterator end)
Erases all child items in the given range.
virtual void handleColumnsAboutToBeInserted(const QModelIndex &, int, int)
size_t Size() const
Returns the number of child models in the merger.
virtual void handleRowsRemoved(const QModelIndex &, int, int)
virtual void handleRowsAboutToBeInserted(const QModelIndex &, int, int)
QVariant headerData(int, Qt::Orientation, int=Qt::DisplayRole) const override
T_ptr & InsertChild(int pos, Args &&...args)
Creates a new child item, inserts it at the given position and returns it.
QVariant data(const QModelIndex &, int=Qt::DisplayRole) const override
QList< QAbstractItemModel * > GetAllModels() const
Returns all models intalled into this one.
QStringList mimeTypes() const override
Returns the union of MIME types of the models.
models_t::const_iterator const_iterator
models_t::iterator iterator
MergeModel(const QStringList &headers, QObject *parent=0)
Constructs the merge model.
virtual void handleRowsAboutToBeRemoved(const QModelIndex &, int, int)
virtual void handleDataChanged(const QModelIndex &, const QModelIndex &)
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 handleRowsInserted(const QModelIndex &, int, int)
Qt::ItemFlags flags(const QModelIndex &) const override
QModelIndex parent(const QModelIndex &) const override
int GetStartingRow(const_iterator it) const
Finds starting row for the model pointed by it.
virtual QModelIndex mapFromSource(const QModelIndex &index) const
Returns the model index in the MergeModel given the index from the source model.
void AddModel(QAbstractItemModel *model)
Adds a model to the list of source models.
void SetHeaders(const QStringList &headers)
Sets the new headers for this model.
Provides a proxying API on top of an QAbstractItemModel.
virtual void handleColumnsInserted(const QModelIndex &, int, int)
virtual void handleModelReset()
int columnCount(const QModelIndex &=QModelIndex()) const override
void RemoveModel(QAbstractItemModel *model)
Removes a model from the list of source models.
int rowCount(const QModelIndex &=QModelIndex()) const override