Changeset View
Changeset View
Standalone View
Standalone View
libs/ui/kis_node_model.cpp
Show First 20 Lines • Show All 66 Lines • ▼ Show 20 Line(s) | 58 | { | |||
---|---|---|---|---|---|
67 | QPointer<KisDummiesFacadeBase> dummiesFacade = 0; | 67 | QPointer<KisDummiesFacadeBase> dummiesFacade = 0; | ||
68 | bool needFinishRemoveRows = false; | 68 | bool needFinishRemoveRows = false; | ||
69 | bool needFinishInsertRows = false; | 69 | bool needFinishInsertRows = false; | ||
70 | bool showRootLayer = false; | 70 | bool showRootLayer = false; | ||
71 | bool showGlobalSelection = false; | 71 | bool showGlobalSelection = false; | ||
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) | ||
78 | : QAbstractItemModel(parent) | 80 | : QAbstractItemModel(parent) | ||
79 | , m_d(new Private) | 81 | , m_d(new Private) | ||
80 | { | 82 | { | ||
81 | updateSettings(); | 83 | updateSettings(); | ||
82 | connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), this, SLOT(updateSettings())); | 84 | connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), this, SLOT(updateSettings())); | ||
▲ Show 20 Lines • Show All 408 Lines • ▼ Show 20 Line(s) | 438 | { | |||
491 | 493 | | |||
492 | return QVariant(); | 494 | return QVariant(); | ||
493 | } | 495 | } | ||
494 | 496 | | |||
495 | Qt::ItemFlags KisNodeModel::flags(const QModelIndex &index) const | 497 | Qt::ItemFlags KisNodeModel::flags(const QModelIndex &index) const | ||
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; | ||
508 | if (!index.isValid() && m_d->parentOfRemovedNode && m_d->dummiesFacade && m_d->indexConverter) { | 518 | if (!index.isValid() && m_d->parentOfRemovedNode && m_d->dummiesFacade && m_d->indexConverter) { | ||
509 | parentIndex = m_d->indexConverter->indexFromDummy(m_d->parentOfRemovedNode); | 519 | parentIndex = m_d->indexConverter->indexFromDummy(m_d->parentOfRemovedNode); | ||
510 | m_d->parentOfRemovedNode = 0; | 520 | m_d->parentOfRemovedNode = 0; | ||
511 | } | 521 | } | ||
512 | 522 | | |||
▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Line(s) | 648 | return KisMimeData::insertMimeLayers(data, | |||
639 | m_d->image, | 649 | m_d->image, | ||
640 | m_d->shapeController, | 650 | m_d->shapeController, | ||
641 | parentDummy, | 651 | parentDummy, | ||
642 | aboveThisDummy, | 652 | aboveThisDummy, | ||
643 | copyNode, | 653 | copyNode, | ||
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 | } |