From e5744941aed23a160c7329be0f2cb79af7d3a928 Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Tue, 29 Dec 2020 12:18:40 +0100 Subject: Fix dropping below/above separators. --- src/mainwindow.cpp | 1 + src/modlistbypriorityproxy.cpp | 18 +++++++++++++++++- src/modlistbypriorityproxy.h | 3 +++ src/modlistview.cpp | 10 ++++++---- src/modlistview.h | 24 +++++++++++++++++++----- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d083330f..7c72f132 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -582,6 +582,7 @@ void MainWindow::setupModList() ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder); connect(ui->modList, &ModListView::dragEntered, m_OrganizerCore.modList(), &ModList::onDragEnter); + connect(ui->modList, &ModListView::dropEntered, m_ModListByPriorityProxy, &ModListByPriorityProxy::onDropEnter); connect(m_OrganizerCore.modList(), &ModList::modPrioritiesChanged, this, &MainWindow::onModPrioritiesChanged); connect( diff --git a/src/modlistbypriorityproxy.cpp b/src/modlistbypriorityproxy.cpp index 0b73ba78..756d3bcf 100644 --- a/src/modlistbypriorityproxy.cpp +++ b/src/modlistbypriorityproxy.cpp @@ -215,8 +215,13 @@ bool ModListByPriorityProxy::canDropMimeData(const QMimeData* data, Qt::DropActi return false; } + // if the previous row is a collapsed separator, disable dropping if (row > 0 && m_Root.children[row - 1]->mod->isSeparator()) { - if (m_Root.children[row]->mod->isSeparator() || m_Root.children[row]->mod->isOverwrite()) { + // we cannot use the name of the mod directly because it does not exactly + // match the display value (e.g. for separators) + QString display = sourceModel()->index(m_Root.children[row - 1]->index, ModList::COL_NAME).data(Qt::DisplayRole).toString(); + if (m_CollapsedItems.contains(display) + && (m_Root.children[row]->mod->isSeparator() || m_Root.children[row]->mod->isOverwrite())) { return false; } } @@ -240,6 +245,12 @@ bool ModListByPriorityProxy::dropMimeData(const QMimeData* data, Qt::DropAction if (!parent.isValid()) { if (row < m_Root.children.size()) { sourceRow = m_Root.children[row]->index; + if (row > 0 + && m_Root.children[row - 1]->mod->isSeparator() + && !m_Root.children[row - 1]->children.empty() + && m_DropPosition == ModListView::DropPosition::BelowItem) { + sourceRow = m_Root.children[row - 1]->children[0]->index; + } } else { sourceRow = ModInfo::getNumMods(); @@ -282,6 +293,11 @@ QModelIndex ModListByPriorityProxy::index(int row, int column, const QModelIndex return createIndex(row, column, parentItem->children[row].get()); } +void ModListByPriorityProxy::onDropEnter(const QMimeData*, ModListView::DropPosition dropPosition) +{ + m_DropPosition = dropPosition; +} + void ModListByPriorityProxy::expanded(const QModelIndex& index) { auto it = m_CollapsedItems.find(index.data(Qt::DisplayRole).toString()); diff --git a/src/modlistbypriorityproxy.h b/src/modlistbypriorityproxy.h index 19d79f7f..cb50352f 100644 --- a/src/modlistbypriorityproxy.h +++ b/src/modlistbypriorityproxy.h @@ -13,6 +13,7 @@ #include #include "modinfo.h" +#include "modlistview.h" class ModList; class Profile; @@ -48,6 +49,7 @@ signals: public slots: + void onDropEnter(const QMimeData* data, ModListView::DropPosition dropPosition); void expanded(const QModelIndex& index); void collapsed(const QModelIndex& index); @@ -82,6 +84,7 @@ private: private: Profile* m_Profile; + ModListView::DropPosition m_DropPosition = ModListView::DropPosition::OnItem; }; #endif //GROUPINGPROXY_H diff --git a/src/modlistview.cpp b/src/modlistview.cpp index e966ce4e..b1cce82e 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -3,16 +3,16 @@ #include #include -ModListView::ModListView(QWidget *parent) +ModListView::ModListView(QWidget* parent) : QTreeView(parent) - , m_Scrollbar(new ViewMarkingScrollBar(this->model(), this)) + , m_scrollbar(new ViewMarkingScrollBar(this->model(), this)) { - setVerticalScrollBar(m_Scrollbar); + setVerticalScrollBar(m_scrollbar); MOBase::setCustomizableColumns(this); setAutoExpandDelay(500); } -void ModListView::setModel(QAbstractItemModel *model) +void ModListView::setModel(QAbstractItemModel* model) { QTreeView::setModel(model); setVerticalScrollBar(new ViewMarkingScrollBar(model, this)); @@ -38,6 +38,8 @@ void ModListView::dragMoveEvent(QDragMoveEvent* event) void ModListView::dropEvent(QDropEvent* event) { + emit dropEntered(event->mimeData(), static_cast(dropIndicatorPosition())); + m_inDragMoveEvent = true; QTreeView::dropEvent(event); m_inDragMoveEvent = false; diff --git a/src/modlistview.h b/src/modlistview.h index c6d42d2d..af608427 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -8,19 +8,32 @@ class ModListView : public QTreeView { Q_OBJECT + public: - explicit ModListView(QWidget *parent = 0); - void setModel(QAbstractItemModel *model) override; - QModelIndexList selectedIndexes() const; + // this is a public version of DropIndicatorPosition + enum DropPosition { + OnItem = DropIndicatorPosition::OnItem, + AboveItem = DropIndicatorPosition::AboveItem, + BelowItem = DropIndicatorPosition::BelowItem, + OnViewport = DropIndicatorPosition::OnViewport + }; + +public: + explicit ModListView(QWidget* parent = 0); + void setModel(QAbstractItemModel* model) override; signals: void dragEntered(const QMimeData* mimeData); + void dropEntered(const QMimeData* mimeData, DropPosition position); protected: - bool m_inDragMoveEvent = false; + // re-implemented to fake the return value to allow drag-and-drop on + // itself for separators + // + QModelIndexList selectedIndexes() const; void dragEnterEvent(QDragEnterEvent* event) override; void dragMoveEvent(QDragMoveEvent* event) override; @@ -28,7 +41,8 @@ protected: private: - ViewMarkingScrollBar *m_Scrollbar; + ViewMarkingScrollBar* m_scrollbar; + bool m_inDragMoveEvent = false; }; -- cgit v1.3.1