From cc5f0c8555fbbcc4b6d0dc29a42b8c7869df1859 Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Sun, 27 Dec 2020 23:23:56 +0100 Subject: Drag and drop from download view to install + Expand and scroll to mod on install. --- src/downloadlist.cpp | 12 +++++++ src/downloadlist.h | 3 +- src/downloadstab.cpp | 3 ++ src/mainwindow.cpp | 24 ++++++++++---- src/modlist.cpp | 88 +++++++++++++++++++++++++++++++++++++++------------ src/modlist.h | 18 ++++++++--- src/organizercore.cpp | 14 ++++++-- src/organizercore.h | 2 +- 8 files changed, 128 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/downloadlist.cpp b/src/downloadlist.cpp index a5c284e6..78e5fd24 100644 --- a/src/downloadlist.cpp +++ b/src/downloadlist.cpp @@ -90,6 +90,18 @@ QVariant DownloadList::headerData(int section, Qt::Orientation orientation, int } } +Qt::ItemFlags DownloadList::flags(const QModelIndex& idx) const +{ + return QAbstractTableModel::flags(idx) | Qt::ItemIsDragEnabled; +} + +QMimeData* DownloadList::mimeData(const QModelIndexList& indexes) const +{ + QMimeData* result = QAbstractItemModel::mimeData(indexes); + result->setData("text/plain", "archive"); + return result; +} + QVariant DownloadList::data(const QModelIndex &index, int role) const { bool pendingDownload = index.row() >= m_Manager->numTotalDownloads(); diff --git a/src/downloadlist.h b/src/downloadlist.h index 2171c013..65d03ab9 100644 --- a/src/downloadlist.h +++ b/src/downloadlist.h @@ -68,11 +68,12 @@ public: * @return number of rows to display **/ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex &parent) const; QModelIndex index(int row, int column, const QModelIndex &parent) const; QModelIndex parent(const QModelIndex &child) const; + Qt::ItemFlags flags(const QModelIndex& idx) const override; + QMimeData* mimeData(const QModelIndexList& indexes) const override; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; diff --git a/src/downloadstab.cpp b/src/downloadstab.cpp index a0602ede..e04799ec 100644 --- a/src/downloadstab.cpp +++ b/src/downloadstab.cpp @@ -17,6 +17,9 @@ DownloadsTab::DownloadsTab(OrganizerCore& core, Ui::MainWindow* mwui) ui.list->setItemDelegate(new DownloadProgressDelegate( m_core.downloadManager(), ui.list)); + ui.list->setDragEnabled(true); + ui.list->setDragDropMode(QAbstractItemView::DragDropMode::DragDrop); + update(); m_filter.setEdit(ui.filter); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 74f3fd62..ea7d5967 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -578,7 +578,6 @@ void MainWindow::setupModList() ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder); - connect( ui->modList, SIGNAL(dropModeUpdate(bool)), m_OrganizerCore.modList(), SLOT(dropModeUpdate(bool))); @@ -653,6 +652,10 @@ void MainWindow::setupModList() ui->modList->header()->setSectionHidden(ModList::COL_NAME, false); ui->modList->installEventFilter(m_OrganizerCore.modList()); + + connect(m_OrganizerCore.modList(), &ModList::downloadArchiveDropped, this, [this](int row, int priority) { + m_OrganizerCore.installDownload(row, priority); + }); } void MainWindow::resetActionIcons() @@ -743,6 +746,7 @@ MainWindow::~MainWindow() } } + void MainWindow::updateWindowTitle(const APIUserAccount& user) { //"\xe2\x80\x93" is an "em dash", a longer "-" @@ -2483,15 +2487,23 @@ void MainWindow::modorder_changed() void MainWindow::modInstalled(const QString &modName) { - QModelIndexList posList = - m_OrganizerCore.modList()->match(m_OrganizerCore.modList()->index(0, 0), Qt::DisplayRole, modName); - if (posList.count() == 1) { - ui->modList->scrollTo(posList.at(0)); + unsigned int index = ModInfo::getIndex(modName); + + if (index == UINT_MAX) { + return; + } + + QModelIndex qIndex = m_OrganizerCore.modList()->index(index, 0); + + if (m_ModListSortProxy->sourceModel() == m_ModListByPriorityProxy) { + qIndex = m_ModListByPriorityProxy->mapFromSource(qIndex); + ui->modList->expand(m_ModListSortProxy->mapFromSource(qIndex)); } + ui->modList->scrollTo(m_ModListSortProxy->mapFromSource(qIndex)); // force an update to happen std::multimap IDs; - ModInfo::Ptr info = ModInfo::getByIndex(ModInfo::getIndex(modName)); + ModInfo::Ptr info = ModInfo::getByIndex(index); IDs.insert(std::make_pair(info->gameName(), info->nexusId())); modUpdateCheck(IDs); } diff --git a/src/modlist.cpp b/src/modlist.cpp index 4191e2db..ca4741e6 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -1087,6 +1087,32 @@ boost::signals2::connection ModList::onModMoved(const std::function(row) >= ModInfo::getNumMods())) { + return -1; + } + + int newPriority = 0; + { + if ((row < 0) || (row > static_cast(m_Profile->numRegularMods()))) { + newPriority = m_Profile->numRegularMods() + 1; + } + else { + newPriority = m_Profile->getModPriority(row); + } + if (newPriority == -1) { + newPriority = m_Profile->numRegularMods() + 1; + } + } + + return newPriority; +} + bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &parent) { if (row == -1) { @@ -1160,7 +1186,6 @@ bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &pa bool ModList::dropMod(const QMimeData *mimeData, int row, const QModelIndex &parent) { - try { QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist"); QDataStream stream(&encoded, QIODevice::ReadOnly); @@ -1175,26 +1200,12 @@ bool ModList::dropMod(const QMimeData *mimeData, int row, const QModelIndex &par } } - if (row == -1) { - row = parent.row(); - } - - if ((row < 0) || (static_cast(row) >= ModInfo::getNumMods())) { + int newPriority = dropPriority(row, parent); + if (newPriority == -1) { return false; } - - int newPriority = 0; - { - if ((row < 0) || (row > static_cast(m_Profile->numRegularMods()))) { - newPriority = m_Profile->numRegularMods() + 1; - } else { - newPriority = m_Profile->getModPriority(row); - } - if (newPriority == -1) { - newPriority = m_Profile->numRegularMods() + 1; - } - } changeModPriority(sourceRows, newPriority); + } catch (const std::exception &e) { reportError(tr("drag&drop failed: %1").arg(e.what())); } @@ -1202,6 +1213,37 @@ bool ModList::dropMod(const QMimeData *mimeData, int row, const QModelIndex &par return false; } +bool ModList::dropArchive(const QMimeData* mimeData, int row, const QModelIndex& parent) +{ + int priority = dropPriority(row, parent); + if (priority == -1) { + return false; + } + + try { + QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist"); + QDataStream stream(&encoded, QIODevice::ReadOnly); + std::vector sourceRows; + + while (!stream.atEnd()) { + int sourceRow, col; + QMap roleDataMap; + stream >> sourceRow >> col >> roleDataMap; + if (col == 0) { + sourceRows.push_back(sourceRow); + } + } + + if (sourceRows.size() == 1) { + emit downloadArchiveDropped(sourceRows[0], priority); + } + } + catch (const std::exception& e) { + reportError(tr("drag&drop failed: %1").arg(e.what())); + } + + return false; +} bool ModList::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int, const QModelIndex &parent) { @@ -1214,10 +1256,14 @@ bool ModList::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int if (mimeData->hasUrls()) { return dropURLs(mimeData, row, parent); } else if (mimeData->hasText()) { - return dropMod(mimeData, row, parent); - } else { - return false; + if (mimeData->text() == "mod") { + return dropMod(mimeData, row, parent); + } + else if (mimeData->text() == "archive") { + return dropArchive(mimeData, row, parent); + } } + return false; } void ModList::removeRowForce(int row, const QModelIndex &parent) diff --git a/src/modlist.h b/src/modlist.h index fad53755..2ca2fff1 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -310,6 +310,10 @@ signals: void postDataChanged(); + // emitted when an item is dropped from the download list, the row is from the + // download list + void downloadArchiveDropped(int row, int priority); + protected: // event filter, handles event from the header and the tree view itself @@ -336,10 +340,6 @@ private: bool renameMod(int index, const QString &newName); - bool dropURLs(const QMimeData *mimeData, int row, const QModelIndex &parent); - - bool dropMod(const QMimeData *mimeData, int row, const QModelIndex &parent); - MOBase::IModList::ModStates state(unsigned int modIndex) const; bool moveSelection(QAbstractItemView *itemView, int direction); @@ -367,6 +367,16 @@ private: QFlags state; }; +private: + + bool dropURLs(const QMimeData* mimeData, int row, const QModelIndex& parent); + bool dropMod(const QMimeData* mimeData, int row, const QModelIndex& parent); + bool dropArchive(const QMimeData* mimeData, int row, const QModelIndex& parent); + + // return the priority of the mod for a drop event + // + int dropPriority(int row, const QModelIndex& parent) const; + private: friend class ModListByPriorityProxy; diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 74b6ed08..454247b6 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -830,13 +830,13 @@ MOBase::IModInterface *OrganizerCore::installMod(const QString &fileName, return nullptr; } -void OrganizerCore::installDownload(int index) +ModInfo::Ptr OrganizerCore::installDownload(int index, int priority) { if (m_InstallationManager.isRunning()) { QMessageBox::information( qApp->activeWindow(), tr("Installation cancelled"), tr("Another installation is currently in progress."), QMessageBox::Ok); - return; + return nullptr; } try { @@ -873,10 +873,15 @@ void OrganizerCore::installDownload(int index) refresh(); int modIndex = ModInfo::getIndex(modName); + ModInfo::Ptr modInfo = nullptr; if (modIndex != UINT_MAX) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); + modInfo = ModInfo::getByIndex(modIndex); modInfo->addInstalledFile(modID, fileID); + if (priority != -1) { + m_ModList.changeModPriority(modIndex, priority); + } + if (hasIniTweaks && m_UserInterface != nullptr && (QMessageBox::question(qApp->activeWindow(), tr("Configure Mod"), tr("This mod contains ini tweaks. Do you " @@ -894,6 +899,7 @@ void OrganizerCore::installDownload(int index) } m_DownloadManager.markInstalled(index); emit modInstalled(modName); + return modInfo; } else { m_InstallationManager.notifyInstallationEnd(result, nullptr); @@ -909,6 +915,8 @@ void OrganizerCore::installDownload(int index) } catch (const std::exception &e) { reportError(e.what()); } + + return nullptr; } QString OrganizerCore::resolvePath(const QString &fileName) const diff --git a/src/organizercore.h b/src/organizercore.h index f2b904cd..cb577437 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -376,7 +376,7 @@ public slots: void refreshLists(); - void installDownload(int downloadIndex); + ModInfo::Ptr installDownload(int downloadIndex, int priority = -1); void modStatusChanged(unsigned int index); void modStatusChanged(QList index); -- cgit v1.3.1