33 #include <QItemSelectionRange>
41 QList<FlatTreeItem_ptr>
C_;
60 QList<FlatTreeItem_ptr> c =
Parent_->C_;
61 for (
int i = 0, size =
Parent_->C_.size ();
63 if (c.at (i).get () ==
this)
72 return static_cast<FlatTreeItem*
> (idx.internalPointer ());
78 : QAbstractItemModel (parent)
95 SourceModel_->columnCount (QModelIndex ()) :
104 QModelIndex source = fti->
Index_;
105 return source.sibling (source.row (), index.column ()).
data (role);
108 index.column () == 0)
110 if (role == Qt::DisplayRole)
112 if (fti->
Tag_.isEmpty ())
113 return tr (
"untagged");
117 return tr (
"<unknown tag>");
131 Qt::Orientation orient,
int role)
const
134 return SourceModel_->headerData (section, orient, role);
141 auto fti =
ToFlat (index);
143 return fti->Index_.flags ();
145 return Qt::ItemIsSelectable |
147 Qt::ItemIsDragEnabled |
148 Qt::ItemIsDropEnabled;
152 const QModelIndex& parent)
const
154 if (!hasIndex (row, column, parent))
155 return QModelIndex ();
158 if (parent.isValid ())
164 return QModelIndex ();
166 return createIndex (row, column, fti->
C_.at (row).get ());
172 if (index.isValid ())
182 return createIndex (parent->Row (), 0, parent.get ());
184 return QModelIndex ();
189 if (index.isValid ())
192 return Root_->C_.size ();
197 return SourceModel_ ?
198 SourceModel_->supportedDropActions () :
199 QAbstractItemModel::supportedDropActions ();
204 return SourceModel_ ?
205 SourceModel_->mimeTypes () :
206 QAbstractItemModel::mimeTypes ();
212 return QAbstractItemModel::mimeData (indexes);
214 QModelIndexList sourceIdxs;
215 for (
const auto&
index : indexes)
220 case FlatTreeItem::Type::TItem:
223 case FlatTreeItem::Type::TFolder:
224 for (
const auto& subItem : item->C_)
225 sourceIdxs << subItem->Index_;
232 return SourceModel_->mimeData (sourceIdxs);
241 for (
const auto& format : data->formats ())
242 modified.setData (format, data->data (format));
244 if (
auto ptr = static_cast<FlatTreeItem*> (parent.internalPointer ()))
248 case FlatTreeItem::Type::TFolder:
249 case FlatTreeItem::Type::TItem:
250 modified.setData (
"x-leechcraft/tag", ptr->Tag_.toLatin1 ());
257 return SourceModel_->dropMimeData (&modified, action, -1, -1, QModelIndex ());
263 disconnect (SourceModel_,
268 SourceModel_ = model;
275 SIGNAL (headerDataChanged (Qt::Orientation,
int,
int)),
277 SIGNAL (headerDataChanged (Qt::Orientation,
int,
int)));
279 SIGNAL (dataChanged (
const QModelIndex&,
const QModelIndex&)),
281 SLOT (handleDataChanged (
const QModelIndex&,
const QModelIndex&)));
283 SIGNAL (layoutAboutToBeChanged ()),
285 SIGNAL (layoutAboutToBeChanged ()));
287 SIGNAL (layoutChanged ()),
289 SIGNAL (layoutChanged ()));
291 SIGNAL (modelReset ()),
293 SLOT (handleModelReset ()));
295 SIGNAL (rowsInserted (
const QModelIndex&,
298 SLOT (handleRowsInserted (
const QModelIndex&,
301 SIGNAL (rowsAboutToBeRemoved (
const QModelIndex&,
304 SLOT (handleRowsAboutToBeRemoved (
const QModelIndex&,
318 if (!proxy.isValid ())
319 return QModelIndex ();
324 return QModelIndex ();
331 QList<QModelIndex> result;
332 Q_FOREACH (
FlatTreeItem_ptr item, Items_.values (QPersistentModelIndex (source)))
333 result << item->Index_;
339 QList<FlatTreeItem_ptr>& c = Root_->C_;
341 if (item->Tag_ == tag)
345 item->Type_ = FlatTreeItem::TFolder;
347 item->Parent_ = Root_;
349 int size = c.size ();
350 beginInsertRows (QModelIndex (), size, size);
359 QModelIndex idx = SourceModel_->index (i, 0);
361 QStringList tags = idx.data (
RoleTags).toStringList ();
366 QPersistentModelIndex pidx (idx);
368 Q_FOREACH (QString tag, tags)
369 AddForTag (tag, pidx);
374 QAbstractItemModel *model = SourceModel_;
375 QModelIndex idx = model->index (i, 0);
377 QStringList tags = idx.data (
RoleTags).toStringList ();
382 QPersistentModelIndex pidx (idx);
384 Q_FOREACH (QString tag, tags)
385 RemoveFromTag (tag, pidx);
389 const QPersistentModelIndex& pidx)
396 item->Parent_ = folder;
399 int size = folder->C_.size ();
400 QModelIndex iidx =
index (Root_->C_.indexOf (folder), 0);
401 beginInsertRows (iidx, size, size);
402 folder->C_.append (item);
403 Items_.insert (pidx, item);
407 void FlatToFoldersProxyModel::RemoveFromTag (
const QString& tag,
408 const QPersistentModelIndex& pidx)
411 QList<FlatTreeItem_ptr>& c = folder->C_;
412 int findex = Root_->C_.indexOf (folder);
413 for (
int i = 0, size = c.size ();
416 if (c.at (i)->Index_ != pidx)
419 beginRemoveRows (
index (findex, 0), i, i);
420 Items_.remove (pidx, c.at (i));
428 beginRemoveRows (QModelIndex (), findex, findex);
429 Root_->C_.removeAt (findex);
434 void FlatToFoldersProxyModel::HandleChanged (
const QModelIndex& idx)
436 QSet<QString> newTags = QSet<QString>::fromList (idx.data (
RoleTags).toStringList ());
437 if (newTags.isEmpty ())
438 newTags << QString ();
440 QPersistentModelIndex pidx (idx);
441 QList<FlatTreeItem_ptr> items = Items_.values (pidx);
443 QSet<QString> oldTags;
445 oldTags << item->Tag_;
447 QSet<QString> added = QSet<QString> (newTags).subtract (oldTags);
448 QSet<QString> removed = QSet<QString> (oldTags).subtract (newTags);
449 QSet<QString> changed = QSet<QString> (newTags).intersect (oldTags);
451 Q_FOREACH (QString ch, changed)
455 QList<FlatTreeItem_ptr>& c = folder->C_;
456 int findex = Root_->C_.indexOf (folder);
457 QModelIndex fmi =
index (findex, 0);
458 for (
int i = 0, size = c.size ();
461 if (c.at (i)->Index_ != pidx)
464 emit dataChanged (
index (i, 0, fmi),
470 Q_FOREACH (QString rem, removed)
471 RemoveFromTag (rem, pidx);
473 Q_FOREACH (QString add, added)
474 AddForTag (add, pidx);
478 const QModelIndex& bottomRight)
480 QItemSelectionRange range (topLeft.sibling (topLeft.row (), 0),
481 bottomRight.sibling (bottomRight.row (), 0));
482 QModelIndexList indexes = range.indexes ();
483 for (
int i = 0, size = indexes.size ();
485 HandleChanged (indexes.at (i));
488 void FlatToFoldersProxyModel::handleModelReset ()
490 if (
const int size = Root_->C_.size ())
492 beginRemoveRows (QModelIndex (), 0, size - 1);
500 for (
int i = 0, size = SourceModel_->rowCount ();
502 HandleRowInserted (i);
507 void FlatToFoldersProxyModel::handleRowsInserted (
const QModelIndex&,
510 for (
int i = start; i <= end; ++i)
511 HandleRowInserted (i);
514 void FlatToFoldersProxyModel::handleRowsAboutToBeRemoved (
const QModelIndex&,
517 for (
int i = start; i <= end; ++i)
518 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