summaryrefslogtreecommitdiff
path: root/src/modlistdropinfo.cpp
diff options
context:
space:
mode:
authorMikaël Capelle <capelle.mikael@gmail.com>2020-12-30 19:11:48 +0100
committerMikaël Capelle <capelle.mikael@gmail.com>2021-01-02 15:38:17 +0100
commit89ff59da4613f06a05a633b4aa4387470831ce94 (patch)
tree2217435c5c5b575ab81013d9113d673e2409bb4a /src/modlistdropinfo.cpp
parent313589cf10640ae06cd7873989b5840f7c476e50 (diff)
Add message for invalid drag. Split & clean code.
Diffstat (limited to 'src/modlistdropinfo.cpp')
-rw-r--r--src/modlistdropinfo.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/modlistdropinfo.cpp b/src/modlistdropinfo.cpp
new file mode 100644
index 00000000..62a103a4
--- /dev/null
+++ b/src/modlistdropinfo.cpp
@@ -0,0 +1,124 @@
+#include "modlistdropinfo.h"
+
+#include "organizercore.h"
+
+ModListDropInfo::ModListDropInfo(const QMimeData* mimeData, OrganizerCore& core) :
+ m_rows{}, m_download{ -1 }, m_localUrls{}, m_url{}
+{
+ // this only check if the drop is valid, not if the content of the drop
+ // matches the target, a drop is valid if either
+ // 1. it contains items from another model (drag&drop in modlist or from download list)
+ // 2. it contains URLs from MO2 (overwrite or from another mod)
+ // 3. it contains a single URL to an external folder
+ // 4. it contains a single URL to a valid archive for MO2
+ try {
+ if (mimeData->hasUrls()) {
+ for (auto& url : mimeData->urls()) {
+ auto p = relativeUrl(url);
+ if (p) {
+ m_localUrls.push_back(*p);
+ }
+ }
+
+ // external drop
+ if (m_localUrls.empty() && mimeData->urls().size() == 1) {
+ auto url = mimeData->urls()[0];
+ if (url.isLocalFile() && !relativeUrl(url)) {
+ QFileInfo info(url.toLocalFile());
+ if (info.isDir()) {
+ m_url = url;
+ }
+ else if (core.installationManager()->getSupportedExtensions().contains(info.suffix(), Qt::CaseInsensitive)) {
+ m_url = url;
+ }
+ }
+ }
+
+ }
+ else if (mimeData->hasText()) {
+ QByteArray encoded = mimeData->data("application/x-qabstractitemmodeldatalist");
+ QDataStream stream(&encoded, QIODevice::ReadOnly);
+
+ while (!stream.atEnd()) {
+ int sourceRow, col;
+ QMap<int, QVariant> roleDataMap;
+ stream >> sourceRow >> col >> roleDataMap;
+ if (col == 0) {
+ m_rows.push_back(sourceRow);
+ }
+ }
+
+ if (mimeData->text() != ModListDropInfo::MOD_TEXT) {
+ if (mimeData->text() == ModListDropInfo::DOWNLOAD_TEXT && m_rows.size() == 1) {
+ m_download = m_rows[0];
+ }
+ m_rows = {};
+ }
+ }
+ }
+ catch (std::exception const&) {
+ m_rows = {};
+ m_download = -1;
+ m_localUrls.clear();
+ m_url = {};
+ }
+}
+
+std::optional<ModListDropInfo::RelativeUrl> ModListDropInfo::relativeUrl(const QUrl& url) const
+{
+ if (!url.isLocalFile()) {
+ return {};
+ }
+
+ QDir allModsDir(Settings::instance().paths().mods());
+ QDir overwriteDir(Settings::instance().paths().overwrite());
+
+ QFileInfo sourceInfo(url.toLocalFile());
+ QString sourceFile = sourceInfo.canonicalFilePath();
+
+ QString relativePath;
+ QString originName;
+
+ if (sourceFile.startsWith(allModsDir.canonicalPath())) {
+ QDir relativeDir(allModsDir.relativeFilePath(sourceFile));
+ QStringList splitPath = relativeDir.path().split("/");
+ originName = splitPath[0];
+ splitPath.pop_front();
+ return { { url, splitPath.join("/"), originName } };
+ }
+ else if (sourceFile.startsWith(overwriteDir.canonicalPath())) {
+ return { { url, overwriteDir.relativeFilePath(sourceFile), ModInfo::getOverwrite()->name() } };
+ }
+
+ return {};
+}
+
+bool ModListDropInfo::isValid() const
+{
+ return isLocalFileDrop() || isModDrop() || isDownloadDrop() || m_url.isLocalFile();
+}
+
+bool ModListDropInfo::isLocalFileDrop() const
+{
+ return !m_localUrls.empty();
+}
+
+bool ModListDropInfo::isModDrop() const
+{
+ return !m_rows.empty();
+}
+
+bool ModListDropInfo::isDownloadDrop() const
+{
+ return m_download != -1;
+}
+
+bool ModListDropInfo::isExternalArchiveDrop() const
+{
+ return m_url.isLocalFile() && QFileInfo(m_url.toLocalFile()).isFile();
+}
+
+bool ModListDropInfo::isExternalFolderDrop() const
+{
+ return m_url.isLocalFile() && QFileInfo(m_url.toLocalFile()).isDir();
+}