33 #include <QItemSelectionRange>
60 const auto& c = Parent_->C_;
61 for (
int i = 0, size = c.size (); i < size; ++i)
62 if (c.at (i).get () ==
this)
71 return static_cast<FlatTreeItem*
> (idx.internalPointer ());
77 : QAbstractItemModel (parent)
94 SourceModel_->columnCount (QModelIndex ()) :
103 QModelIndex source = fti->
Index_;
104 return source.sibling (source.row (), index.column ()).
data (role);
107 index.column () == 0)
109 if (role == Qt::DisplayRole)
111 if (fti->
Tag_.isEmpty ())
112 return tr (
"untagged");
116 return tr (
"<unknown tag>");
130 Qt::Orientation orient,
int role)
const
133 return SourceModel_->headerData (section, orient, role);
140 auto fti =
ToFlat (index);
142 return fti->Index_.flags ();
144 return Qt::ItemIsSelectable |
146 Qt::ItemIsDragEnabled |
147 Qt::ItemIsDropEnabled;
151 const QModelIndex& parent)
const
153 if (!hasIndex (row, column, parent))
154 return QModelIndex ();
157 if (parent.isValid ())
163 return QModelIndex ();
165 return createIndex (row, column, fti->
C_.at (row).get ());
171 if (index.isValid ())
181 return createIndex (parent->Row (), 0, parent.get ());
183 return QModelIndex ();
188 if (index.isValid ())
191 return Root_->C_.size ();
196 return SourceModel_ ?
197 SourceModel_->supportedDropActions () :
198 QAbstractItemModel::supportedDropActions ();
203 return SourceModel_ ?
204 SourceModel_->mimeTypes () :
205 QAbstractItemModel::mimeTypes ();
211 return QAbstractItemModel::mimeData (indexes);
213 QModelIndexList sourceIdxs;
214 for (
const auto&
index : indexes)
219 case FlatTreeItem::Type::TItem:
222 case FlatTreeItem::Type::TFolder:
223 for (
const auto& subItem : item->C_)
224 sourceIdxs << subItem->Index_;
231 return SourceModel_->mimeData (sourceIdxs);
240 for (
const auto& format : data->formats ())
241 modified.setData (format, data->data (format));
243 if (
auto ptr = static_cast<FlatTreeItem*> (parent.internalPointer ()))
247 case FlatTreeItem::Type::TFolder:
248 case FlatTreeItem::Type::TItem:
249 modified.setData (
"x-leechcraft/tag", ptr->Tag_.toLatin1 ());
256 return SourceModel_->dropMimeData (&modified, action, -1, -1, QModelIndex ());
262 disconnect (SourceModel_,
267 SourceModel_ = model;
274 SIGNAL (headerDataChanged (Qt::Orientation,
int,
int)),
276 SIGNAL (headerDataChanged (Qt::Orientation,
int,
int)));
278 SIGNAL (dataChanged (
const QModelIndex&,
const QModelIndex&)),
280 SLOT (handleDataChanged (
const QModelIndex&,
const QModelIndex&)));
282 SIGNAL (layoutAboutToBeChanged ()),
284 SIGNAL (layoutAboutToBeChanged ()));
286 SIGNAL (layoutChanged ()),
288 SIGNAL (layoutChanged ()));
290 SIGNAL (modelReset ()),
292 SLOT (handleModelReset ()));
294 SIGNAL (rowsInserted (
const QModelIndex&,
297 SLOT (handleRowsInserted (
const QModelIndex&,
300 SIGNAL (rowsAboutToBeRemoved (
const QModelIndex&,
303 SLOT (handleRowsAboutToBeRemoved (
const QModelIndex&,
317 if (!proxy.isValid ())
318 return QModelIndex ();
323 return QModelIndex ();
330 auto tags = source.data (
RoleTags).toStringList ();
335 for (
const auto& tag : tags)
337 const auto& folder = FindFolder (tag);
340 qWarning () << Q_FUNC_INFO
341 <<
"could not find folder for tag"
347 const auto& folderIdx =
index (folder->Row (), 0, {});
349 for (
int i = 0; i < folder->C_.size (); ++i)
351 const auto& child = folder->C_.at (i);
352 if (child->Index_ != source)
355 result <<
index (i, 0, folderIdx);
362 FlatTreeItem_ptr FlatToFoldersProxyModel::FindFolder (
const QString& tag)
const
364 for (
const auto& item : Root_->C_)
365 if (item->Tag_ == tag)
374 for (
const auto& item : c)
375 if (item->Tag_ == tag)
381 item->Parent_ = Root_;
383 int size = c.size ();
384 beginInsertRows (QModelIndex (), size, size);
391 void FlatToFoldersProxyModel::HandleRowInserted (
int i)
393 QModelIndex idx = SourceModel_->index (i, 0);
395 QStringList tags = idx.data (
RoleTags).toStringList ();
400 QPersistentModelIndex pidx (idx);
402 Q_FOREACH (QString tag, tags)
403 AddForTag (tag, pidx);
408 QAbstractItemModel *model = SourceModel_;
409 QModelIndex idx = model->index (i, 0);
411 QStringList tags = idx.data (
RoleTags).toStringList ();
416 QPersistentModelIndex pidx (idx);
418 Q_FOREACH (QString tag, tags)
419 RemoveFromTag (tag, pidx);
423 const QPersistentModelIndex& pidx)
430 item->Parent_ = folder;
433 int size = folder->C_.size ();
434 QModelIndex iidx =
index (Root_->C_.indexOf (folder), 0);
435 beginInsertRows (iidx, size, size);
436 folder->C_.append (item);
437 Items_.insert (pidx, item);
441 void FlatToFoldersProxyModel::RemoveFromTag (
const QString& tag,
442 const QPersistentModelIndex& pidx)
446 int findex = Root_->C_.indexOf (folder);
447 for (
int i = 0, size = c.size ();
450 if (c.at (i)->Index_ != pidx)
453 beginRemoveRows (
index (findex, 0), i, i);
454 Items_.remove (pidx, c.at (i));
462 beginRemoveRows (QModelIndex (), findex, findex);
463 Root_->C_.removeAt (findex);
468 void FlatToFoldersProxyModel::HandleChanged (
const QModelIndex& idx)
471 if (newTags.isEmpty ())
472 newTags << QString ();
474 QPersistentModelIndex pidx (idx);
479 oldTags << item->Tag_;
481 QSet<QString> added =
QSet<QString> (newTags).subtract (oldTags);
482 QSet<QString> removed =
QSet<QString> (oldTags).subtract (newTags);
483 QSet<QString> changed =
QSet<QString> (newTags).intersect (oldTags);
485 Q_FOREACH (QString ch, changed)
490 int findex = Root_->C_.indexOf (folder);
491 QModelIndex fmi =
index (findex, 0);
492 for (
int i = 0, size = c.size ();
495 if (c.at (i)->Index_ != pidx)
498 emit dataChanged (
index (i, 0, fmi),
504 Q_FOREACH (QString rem, removed)
505 RemoveFromTag (rem, pidx);
507 Q_FOREACH (QString add, added)
508 AddForTag (add, pidx);
512 const QModelIndex& bottomRight)
514 QItemSelectionRange range (topLeft.sibling (topLeft.row (), 0),
515 bottomRight.sibling (bottomRight.row (), 0));
516 QModelIndexList indexes = range.indexes ();
517 for (
int i = 0, size = indexes.size ();
519 HandleChanged (indexes.at (i));
522 void FlatToFoldersProxyModel::handleModelReset ()
524 if (
const int size = Root_->C_.size ())
526 beginRemoveRows (QModelIndex (), 0, size - 1);
534 for (
int i = 0, size = SourceModel_->rowCount ();
536 HandleRowInserted (i);
541 void FlatToFoldersProxyModel::handleRowsInserted (
const QModelIndex&,
544 for (
int i = start; i <= end; ++i)
545 HandleRowInserted (i);
548 void FlatToFoldersProxyModel::handleRowsAboutToBeRemoved (
const QModelIndex&,
551 for (
int i = start; i <= end; ++i)
552 HandleRowRemoved (i);
FlatToFoldersProxyModel(QObject *=0)
QStringList mimeTypes() const
QList< QModelIndex > MapFromSource(const QModelIndex &) const
QMimeData * mimeData(const QModelIndexList &indexes) const
QModelIndex parent(const QModelIndex &) const
QList< FlatTreeItem_ptr > C_
QPersistentModelIndex Index_
FlatTreeItem * ToFlat(const QModelIndex &idx)
QVariant data(const QModelIndex &, int=Qt::DisplayRole) const
int rowCount(const QModelIndex &=QModelIndex()) const
QModelIndex index(int, int, const QModelIndex &=QModelIndex()) const
std::shared_ptr< FlatTreeItem > FlatTreeItem_ptr
int columnCount(const QModelIndex &=QModelIndex()) const
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
Qt::DropActions supportedDropActions() const
QAbstractItemModel * GetSourceModel() const
QModelIndex MapToSource(const QModelIndex &) const
QVariant headerData(int, Qt::Orientation, int) const
void SetSourceModel(QAbstractItemModel *)
void SetTagsManager(ITagsManager *)
Qt::ItemFlags flags(const QModelIndex &) const