20 : QAbstractItemModel (parent)
21 , Headers_ (std::move (headers))
22 , Root_ (std::make_shared<ModelItem> ())
28 if (!
index.isValid ())
29 return Headers_.size ();
31 return mapped.model ()->columnCount (mapped);
36 if (orient != Qt::Horizontal || role != Qt::DisplayRole)
39 return Headers_.at (column);
44 if (!
index.isValid ())
51 catch (
const std::exception& e)
53 qWarning () << Q_FUNC_INFO
65 catch (
const std::exception& e)
67 qWarning () << Q_FUNC_INFO
73 QModelIndex
MergeModel::index (
int row,
int column,
const QModelIndex& parent)
const
75 if (!hasIndex (row, column,
parent))
78 auto parentItem =
parent.isValid () ?
82 return createIndex (row, column, parentItem->EnsureChild (row));
87 if (!
index.isValid () ||
index.internalPointer () == Root_.get ())
90 auto item =
static_cast<ModelItem*
> (
index.internalPointer ());
95 return createIndex (
parent->GetRow (), 0,
parent.get ());
101 return Root_->GetRowCount ();
103 const auto item =
static_cast<ModelItem*
> (
parent.internalPointer ());
104 return item->GetModel ()->rowCount (item->GetIndex ());
111 for (
const auto& type : model->mimeTypes ())
112 if (!result.contains (type))
119 void Merge (QMimeData& out,
const QMimeData& sub)
121 for (
const auto& format : sub.formats ())
122 if (format !=
"text/uri-list"_ql && !out.hasFormat (format))
123 out.setData (format, sub.data (format));
125 out.setUrls (out.urls () + sub.urls ());
131 std::unique_ptr<QMimeData> result;
133 for (
const auto&
index : indexes)
137 std::unique_ptr<QMimeData> subresult { src.model ()->mimeData ({ src }) };
142 result = std::move (subresult);
144 Merge (*result, *subresult);
147 return result.release ();
152 if (!sourceIndex.isValid ())
163 auto currentItem = Root_;
164 for (
const auto& idx : hier)
166 currentItem = currentItem->FindChild (idx);
169 qWarning () << Q_FUNC_INFO
170 <<
"no next item for"
177 return createIndex (currentItem->GetRow (), sourceIndex.column (), currentItem.get ());
182 const auto item = proxyIndex.isValid () ?
183 static_cast<ModelItem*
> (proxyIndex.internalPointer ()) :
186 const auto& srcIdx = item->GetIndex ();
187 return srcIdx.sibling (srcIdx.row (), proxyIndex.column ());
192 throw std::runtime_error (
"You should not set source model via setSourceModel()");
207 auto withModel = [
this, model]<
typename... Args> (void (
MergeModel::*method) (QAbstractItemModel*, Args...))
209 return [
this, model, method] (Args... args) { (this->*method) (model, args...); };
213 &QAbstractItemModel::dataChanged,
215 [
this] (
const QModelIndex& topLeft,
const QModelIndex& bottomRight)
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_);
279 qWarning () << Q_FUNC_INFO <<
"not found model" << model;
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));
288 beginRemoveRows ({}, idx, idx);
289 r = Root_->EraseChild (r);
306 for (
auto i =
Models_.begin (); i != it; ++i)
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 ());
332 const auto child = Root_->GetChild (row);
333 const auto it =
FindModel (child->GetModel ());
352 const auto startingRow =
parent.isValid () ?
356 first + startingRow, last + startingRow);
361 const auto startingRow =
parent.isValid () ?
365 first + startingRow, last + startingRow);
367 const auto rawItem =
parent.isValid () ?
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);
384 const auto startingRow =
parent.isValid () ?
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);
416 RemovalRefreshers_.pop () ();
422 if (
const auto rc = model->rowCount ())
425 beginRemoveRows ({}, startingRow, rc + startingRow - 1);
426 Root_->EraseChildren (Root_->begin () + startingRow, Root_->begin () + startingRow + rc);
433 if (
const auto rc = model->rowCount ())
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_);
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)