Changeset View
Changeset View
Standalone View
Standalone View
libs/ui/kis_node_model.cpp
Context not available. | |||||
72 | QPersistentModelIndex activeNodeIndex; | 72 | QPersistentModelIndex activeNodeIndex; | ||
---|---|---|---|---|---|
73 | 73 | | |||
74 | QPointer<KisNodeDummy> parentOfRemovedNode = 0; | 74 | QPointer<KisNodeDummy> parentOfRemovedNode = 0; | ||
75 | | ||||
76 | QSet<quintptr> dropEnabled; | ||||
75 | }; | 77 | }; | ||
76 | 78 | | |||
77 | KisNodeModel::KisNodeModel(QObject * parent) | 79 | KisNodeModel::KisNodeModel(QObject * parent) | ||
Context not available. | |||||
496 | { | 498 | { | ||
497 | if(!m_d->dummiesFacade || !index.isValid()) return Qt::ItemIsDropEnabled; | 499 | if(!m_d->dummiesFacade || !index.isValid()) return Qt::ItemIsDropEnabled; | ||
498 | 500 | | |||
499 | Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled; | 501 | Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEditable; | ||
502 | if (m_d->dropEnabled.contains(index.internalId())) { | ||||
503 | flags |= Qt::ItemIsDropEnabled; | ||||
504 | } | ||||
500 | return flags; | 505 | return flags; | ||
501 | } | 506 | } | ||
502 | 507 | | |||
503 | bool KisNodeModel::setData(const QModelIndex &index, const QVariant &value, int role) | 508 | bool KisNodeModel::setData(const QModelIndex &index, const QVariant &value, int role) | ||
504 | { | 509 | { | ||
510 | if (role == KisNodeModel::DropEnabled) { | ||||
511 | const QMimeData *mimeData = static_cast<const QMimeData*>(value.value<void*>()); | ||||
512 | setDropEnabled(mimeData); | ||||
513 | return true; | ||||
514 | } | ||||
505 | 515 | | |||
506 | if (role == KisNodeModel::ActiveRole || role == KisNodeModel::AlternateActiveRole) { | 516 | if (role == KisNodeModel::ActiveRole || role == KisNodeModel::AlternateActiveRole) { | ||
507 | QModelIndex parentIndex; | 517 | QModelIndex parentIndex; | ||
Context not available. | |||||
644 | m_d->nodeInsertionAdapter); | 654 | m_d->nodeInsertionAdapter); | ||
645 | } | 655 | } | ||
646 | 656 | | |||
657 | bool KisNodeModel::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const { | ||||
658 | if (parent.isValid()) { | ||||
659 | // drop occured on an item. always return true as returning false will mess up | ||||
660 | // QT5's drag handling (see KisNodeModel::setDropEnabled). | ||||
661 | return true; | ||||
662 | } else { | ||||
663 | return QAbstractItemModel::canDropMimeData(data, action, row, column, parent); | ||||
664 | } | ||||
665 | } | ||||
666 | | ||||
667 | void KisNodeModel::setDropEnabled(const QMimeData *data) { | ||||
668 | // what happens here should really happen in KisNodeModel::canDropMimeData(), but QT5 | ||||
669 | // will mess up if an item's Qt::ItemIsDropEnabled does not match what is returned by | ||||
670 | // canDropMimeData; specifically, if we set the flag, but decide in canDropMimeData() | ||||
671 | // later on that an "onto" drag is not allowed, QT will display an drop indicator for | ||||
672 | // insertion, but not perform any drop when the mouse is released. | ||||
673 | | ||||
674 | // the only robust implementation seems to set all flags correctly, which is done here. | ||||
675 | | ||||
676 | bool copyNode = false; | ||||
677 | KisNodeList nodes = KisMimeData::loadNodesFast(data, m_d->image, m_d->shapeController, copyNode); | ||||
678 | m_d->dropEnabled.clear(); | ||||
679 | updateDropEnabled(nodes); | ||||
680 | } | ||||
681 | | ||||
682 | void KisNodeModel::updateDropEnabled(const QList<KisNodeSP> &nodes, QModelIndex parent) { | ||||
683 | for (int r = 0; r < rowCount(parent); r++) { | ||||
684 | QModelIndex idx = index(r, 0, parent); | ||||
685 | | ||||
686 | KisNodeSP target = nodeFromIndex(idx); | ||||
687 | | ||||
688 | bool dropEnabled = true; | ||||
689 | Q_FOREACH (const KisNodeSP &node, nodes) { | ||||
690 | if (!target->allowAsChild(node)) { | ||||
691 | dropEnabled = false; | ||||
692 | break; | ||||
693 | } | ||||
694 | } | ||||
695 | if (dropEnabled) { | ||||
696 | m_d->dropEnabled.insert(idx.internalId()); | ||||
697 | } | ||||
698 | emit dataChanged(idx, idx); // indicate to QT that flags() have changed | ||||
699 | | ||||
700 | if (hasChildren(idx)) { | ||||
701 | updateDropEnabled(nodes, idx); | ||||
702 | } | ||||
703 | } | ||||
704 | } | ||||
Context not available. |