From 25b6fe1471f665b86dc765232a0832daeffc8f8a Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 13 Apr 2018 14:49:59 +0100 Subject: Reload plugin translation databases when changing language. --- src/mainwindow.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index abcb5312..6cbe364e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3726,6 +3726,9 @@ void MainWindow::languageChange(const QString &newLanguage) installTranslator("qt"); installTranslator(ToQString(AppConfig::translationPrefix())); + for (const QString &fileName : m_PluginContainer.pluginFileNames()) { + installTranslator(QFileInfo(fileName).baseName()); + } ui->retranslateUi(this); qDebug("loaded language %s", qPrintable(newLanguage)); -- cgit v1.3.1 From ae4e4f9df84a547c554a8a68bb65b082adaae9f5 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sun, 15 Apr 2018 12:59:04 +0100 Subject: Load qtbase_.qm when possible --- src/mainwindow.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6cbe364e..23423194 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3725,6 +3725,7 @@ void MainWindow::languageChange(const QString &newLanguage) m_CurrentLanguage = newLanguage; installTranslator("qt"); + installTranslator("qtbase"); installTranslator(ToQString(AppConfig::translationPrefix())); for (const QString &fileName : m_PluginContainer.pluginFileNames()) { installTranslator(QFileInfo(fileName).baseName()); -- cgit v1.3.1 From 30c177cb371e92fe5e4cfc600cf27586402cf0a8 Mon Sep 17 00:00:00 2001 From: Silarn Date: Mon, 16 Apr 2018 12:47:17 -0500 Subject: Support for multi-game downloads --- src/downloadlistwidget.cpp | 4 +- src/downloadlistwidgetcompact.cpp | 4 +- src/downloadmanager.cpp | 76 ++++++++------- src/downloadmanager.h | 23 +++-- src/installationmanager.cpp | 18 +++- src/installationmanager.h | 2 +- src/main.cpp | 3 +- src/mainwindow.cpp | 62 ++++++------ src/mainwindow.h | 6 +- src/modinfo.cpp | 56 +++++++---- src/modinfo.h | 24 +++-- src/modinfobackup.cpp | 4 +- src/modinfobackup.h | 2 +- src/modinfodialog.cpp | 4 +- src/modinfoforeign.cpp | 5 +- src/modinfoforeign.h | 3 +- src/modinfooverwrite.cpp | 2 +- src/modinfooverwrite.h | 3 +- src/modinforegular.cpp | 32 ++++--- src/modinforegular.h | 17 +++- src/modinfowithconflictinfo.cpp | 4 +- src/modinfowithconflictinfo.h | 2 +- src/modlist.cpp | 23 ++++- src/modlist.h | 7 +- src/nexusinterface.cpp | 194 ++++++++++++++++++++++---------------- src/nexusinterface.h | 108 +++++++++------------ src/organizercore.cpp | 51 ++++++---- src/organizercore.h | 2 +- src/organizerproxy.cpp | 6 +- src/organizerproxy.h | 4 +- src/plugincontainer.cpp | 3 +- src/plugincontainer.h | 6 +- src/profile.cpp | 1 + src/selfupdater.cpp | 6 ++ src/selfupdater.h | 3 + src/settings.cpp | 4 +- src/settings.h | 3 +- src/settingsdialog.cpp | 6 +- src/settingsdialog.h | 6 +- 39 files changed, 466 insertions(+), 323 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/downloadlistwidget.cpp b/src/downloadlistwidget.cpp index 9a8ef572..cb7a49c3 100644 --- a/src/downloadlistwidget.cpp +++ b/src/downloadlistwidget.cpp @@ -88,8 +88,8 @@ void DownloadListWidgetDelegate::drawCache(QPainter *painter, const QStyleOption void DownloadListWidgetDelegate::paintPendingDownload(int downloadIndex) const { - std::pair nexusids = m_Manager->getPendingDownload(downloadIndex); - m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second)); + std::tuple nexusids = m_Manager->getPendingDownload(downloadIndex); + m_NameLabel->setText(tr("< game %1 mod %2 file %3 >").arg(std::get<0>(nexusids)).arg(std::get<1>(nexusids)).arg(std::get<2>(nexusids))); m_SizeLabel->setText("???"); m_InstallLabel->setVisible(true); m_InstallLabel->setText(tr("Pending")); diff --git a/src/downloadlistwidgetcompact.cpp b/src/downloadlistwidgetcompact.cpp index f7975150..b390bff4 100644 --- a/src/downloadlistwidgetcompact.cpp +++ b/src/downloadlistwidgetcompact.cpp @@ -88,8 +88,8 @@ void DownloadListWidgetCompactDelegate::drawCache(QPainter *painter, const QStyl void DownloadListWidgetCompactDelegate::paintPendingDownload(int downloadIndex) const { - std::pair nexusids = m_Manager->getPendingDownload(downloadIndex); - m_NameLabel->setText(tr("< mod %1 file %2 >").arg(nexusids.first).arg(nexusids.second)); + std::tuple nexusids = m_Manager->getPendingDownload(downloadIndex); + m_NameLabel->setText(tr("< game %1 mod %2 file %3 >").arg(std::get<0>(nexusids)).arg(std::get<1>(nexusids)).arg(std::get<2>(nexusids))); if (m_SizeLabel != nullptr) { m_SizeLabel->setText("???"); } diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 569a7d31..d54d6f24 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see . #include "nexusinterface.h" #include "nxmaccessmanager.h" #include "iplugingame.h" +#include "downloadmanager.h" #include #include #include "utility.h" @@ -113,15 +114,17 @@ DownloadManager::DownloadInfo *DownloadManager::DownloadInfo::createFromMeta(con info->m_Urls = metaFile.value("url", "").toString().split(";"); info->m_Tries = 0; info->m_TaskProgressId = TaskProgressManager::instance().getId(); + QString gameName = metaFile.value("gameName", "").toString(); int modID = metaFile.value("modID", 0).toInt(); int fileID = metaFile.value("fileID", 0).toInt(); - info->m_FileInfo = new ModRepositoryFileInfo(modID, fileID); + info->m_FileInfo = new ModRepositoryFileInfo(gameName, modID, fileID); info->m_FileInfo->name = metaFile.value("name", "").toString(); if (info->m_FileInfo->name == "0") { // bug in earlier version info->m_FileInfo->name = ""; } info->m_FileInfo->modName = metaFile.value("modName", "").toString(); + info->m_FileInfo->gameName = gameName; info->m_FileInfo->modID = modID; info->m_FileInfo->fileID = fileID; info->m_FileInfo->description = metaFile.value("description").toString(); @@ -260,6 +263,11 @@ void DownloadManager::setShowHidden(bool showHidden) refreshList(); } +void DownloadManager::setPluginContainer(PluginContainer *pluginContainer) +{ + m_NexusInterface->setPluginContainer(pluginContainer); +} + void DownloadManager::refreshList() { try { @@ -329,7 +337,7 @@ void DownloadManager::refreshList() } -bool DownloadManager::addDownload(const QStringList &URLs, +bool DownloadManager::addDownload(const QStringList &URLs, QString gameName, int modID, int fileID, const ModRepositoryFileInfo *fileInfo) { QString fileName = QFileInfo(URLs.first()).fileName(); @@ -340,7 +348,7 @@ bool DownloadManager::addDownload(const QStringList &URLs, QUrl preferredUrl = QUrl::fromEncoded(URLs.first().toLocal8Bit()); qDebug("selected download url: %s", qPrintable(preferredUrl.toString())); QNetworkRequest request(preferredUrl); - return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, modID, fileID, fileInfo); + return addDownload(m_NexusInterface->getAccessManager()->get(request), URLs, fileName, gameName, modID, fileID, fileInfo); } @@ -351,12 +359,12 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const ModRepositoryFileI fileName = "unknown"; } - return addDownload(reply, QStringList(reply->url().toString()), fileName, fileInfo->modID, fileInfo->fileID, fileInfo); + return addDownload(reply, QStringList(reply->url().toString()), fileName, fileInfo->gameName, fileInfo->modID, fileInfo->fileID, fileInfo); } bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, - int modID, int fileID, const ModRepositoryFileInfo *fileInfo) + QString gameName, int modID, int fileID, const ModRepositoryFileInfo *fileInfo) { // download invoked from an already open network reply (i.e. download link in the browser) DownloadInfo *newDownload = DownloadInfo::createNew(fileInfo, URLs); @@ -375,7 +383,7 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, (QMessageBox::question(nullptr, tr("Download again?"), tr("A file with the same name has already been downloaded. " "Do you want to download it again? The new file will receive a different name."), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)) { - removePending(modID, fileID); + removePending(gameName, modID, fileID); delete newDownload; return false; } @@ -387,12 +395,12 @@ bool DownloadManager::addDownload(QNetworkReply *reply, const QStringList &URLs, } -void DownloadManager::removePending(int modID, int fileID) +void DownloadManager::removePending(QString gameName, int modID, int fileID) { emit aboutToUpdate(); - for (auto iter = m_PendingDownloads.begin(); iter != m_PendingDownloads.end(); ++iter) { - if ((iter->first == modID) && (iter->second == fileID)) { - m_PendingDownloads.erase(iter); + for (auto iter : m_PendingDownloads) { + if (gameName.compare(std::get<0>(iter), Qt::CaseInsensitive) == 0 && (std::get<1>(iter) == modID) && (std::get<2>(iter) == fileID)) { + m_PendingDownloads.removeAt(m_PendingDownloads.indexOf(iter)); break; } } @@ -431,7 +439,7 @@ void DownloadManager::startDownload(QNetworkReply *reply, DownloadInfo *newDownl if (!resume) { newDownload->m_PreResumeSize = newDownload->m_Output.size(); - removePending(newDownload->m_FileInfo->modID, newDownload->m_FileInfo->fileID); + removePending(newDownload->m_FileInfo->gameName, newDownload->m_FileInfo->modID, newDownload->m_FileInfo->fileID); emit aboutToUpdate(); m_ActiveDownloads.append(newDownload); @@ -451,17 +459,19 @@ void DownloadManager::addNXMDownload(const QString &url) { NXMUrl nxmInfo(url); - QString managedGame = m_ManagedGame->gameShortName(); + QStringList validGames; + validGames.append(m_ManagedGame->gameShortName()); + validGames.append(m_ManagedGame->validShortNames()); qDebug("add nxm download: %s", qPrintable(url)); - if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) { - qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame), qPrintable(nxmInfo.game())); + if (!validGames.contains(nxmInfo.game(), Qt::CaseInsensitive)) { + qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(m_ManagedGame->gameShortName()), qPrintable(nxmInfo.game())); QMessageBox::information(nullptr, tr("Wrong Game"), tr("The download link is for a mod for \"%1\" but this instance of MO " - "has been set up for \"%2\".").arg(nxmInfo.game()).arg(managedGame), QMessageBox::Ok); + "has been set up for \"%2\".").arg(nxmInfo.game()).arg(m_ManagedGame->gameShortName()), QMessageBox::Ok); return; } - for (auto pair : m_PendingDownloads) { - if (pair.first == nxmInfo.modId() && pair.second == nxmInfo.fileId()) { + for (auto tuple : m_PendingDownloads) { + if (std::get<0>(tuple).compare(nxmInfo.game(), Qt::CaseInsensitive) == 0, std::get<1>(tuple) == nxmInfo.modId() && std::get<2>(tuple) == nxmInfo.fileId()) { qDebug("download requested is already started (mod id: %s, file id: %s)", qPrintable(QString(nxmInfo.modId())), qPrintable(QString(nxmInfo.fileId()))); QMessageBox::information(nullptr, tr("Already Started"), tr("A download for this mod file has already been queued."), QMessageBox::Ok); return; @@ -483,11 +493,11 @@ void DownloadManager::addNXMDownload(const QString &url) emit aboutToUpdate(); - m_PendingDownloads.append(std::make_pair(nxmInfo.modId(), nxmInfo.fileId())); + m_PendingDownloads.append(std::make_tuple(nxmInfo.game(), nxmInfo.modId(), nxmInfo.fileId())); emit update(-1); emit downloadAdded(); - m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId(), "")); + m_RequestIDs.insert(m_NexusInterface->requestFileInfo(nxmInfo.game(), nxmInfo.modId(), nxmInfo.fileId(), this, nxmInfo.fileId(), "")); } @@ -743,7 +753,7 @@ int DownloadManager::numPendingDownloads() const return m_PendingDownloads.size(); } -std::pair DownloadManager::getPendingDownload(int index) +std::tuple DownloadManager::getPendingDownload(int index) { if ((index < 0) || (index >= m_PendingDownloads.size())) { throw MyException(tr("get pending: invalid download index %1").arg(index)); @@ -1003,10 +1013,10 @@ void DownloadManager::setState(DownloadManager::DownloadInfo *info, DownloadMana info->m_Reply->abort(); } break; case STATE_FETCHINGMODINFO: { - m_RequestIDs.insert(m_NexusInterface->requestDescription(info->m_FileInfo->modID, this, info->m_DownloadID, QString())); + m_RequestIDs.insert(m_NexusInterface->requestDescription(info->m_FileInfo->gameName, info->m_FileInfo->modID, this, info->m_DownloadID, QString())); } break; case STATE_FETCHINGFILEINFO: { - m_RequestIDs.insert(m_NexusInterface->requestFiles(info->m_FileInfo->modID, this, info->m_DownloadID, QString())); + m_RequestIDs.insert(m_NexusInterface->requestFiles(info->m_FileInfo->gameName, info->m_FileInfo->modID, this, info->m_DownloadID, QString())); } break; case STATE_READY: { createMetaFile(info); @@ -1080,6 +1090,7 @@ void DownloadManager::downloadReadyRead() void DownloadManager::createMetaFile(DownloadInfo *info) { QSettings metaFile(QString("%1.meta").arg(info->m_Output.fileName()), QSettings::IniFormat); + metaFile.setValue("gameName", info->m_FileInfo->gameName); metaFile.setValue("modID", info->m_FileInfo->modID); metaFile.setValue("fileID", info->m_FileInfo->fileID); metaFile.setValue("url", info->m_Urls.join(";")); @@ -1108,7 +1119,7 @@ void DownloadManager::createMetaFile(DownloadInfo *info) } -void DownloadManager::nxmDescriptionAvailable(int, QVariant userData, QVariant resultData, int requestID) +void DownloadManager::nxmDescriptionAvailable(QString, int, QVariant userData, QVariant resultData, int requestID) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1157,7 +1168,7 @@ static EFileCategory convertFileCategory(int id) } -void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultData, int requestID) +void DownloadManager::nxmFilesAvailable(QString, int, QVariant userData, QVariant resultData, int requestID) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1237,7 +1248,7 @@ void DownloadManager::nxmFilesAvailable(int, QVariant userData, QVariant resultD } -void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) +void DownloadManager::nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1260,11 +1271,12 @@ void DownloadManager::nxmFileInfoAvailable(int modID, int fileID, QVariant userD info->description = BBCode::convertToHTML(result["description"].toString()); info->repository = "Nexus"; + info->gameName = gameName; info->modID = modID; info->fileID = fileID; QObject *test = info; - m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(modID, fileID, this, qVariantFromValue(test), QString())); + m_RequestIDs.insert(m_NexusInterface->requestDownloadURL(gameName, modID, fileID, this, qVariantFromValue(test), QString())); } static int evaluateFileInfoMap(const QVariantMap &map, const std::map &preferredServers) @@ -1300,7 +1312,7 @@ bool DownloadManager::ServerByPreference(const std::map &preferred int DownloadManager::startDownloadURLs(const QStringList &urls) { ModRepositoryFileInfo info; - addDownload(urls, -1, -1, &info); + addDownload(urls, "", -1, -1, &info); return m_ActiveDownloads.size() - 1; } @@ -1326,7 +1338,7 @@ int DownloadManager::indexByName(const QString &fileName) const return -1; } -void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) +void DownloadManager::nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1338,7 +1350,7 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u ModRepositoryFileInfo *info = qobject_cast(qvariant_cast(userData)); QVariantList resultList = resultData.toList(); if (resultList.length() == 0) { - removePending(modID, fileID); + removePending(gameName, modID, fileID); emit showMessage(tr("No download server available. Please try again later.")); return; } @@ -1352,11 +1364,11 @@ void DownloadManager::nxmDownloadURLsAvailable(int modID, int fileID, QVariant u foreach (const QVariant &server, resultList) { URLs.append(server.toMap()["URI"].toString()); } - addDownload(URLs, modID, fileID, info); + addDownload(URLs, gameName, modID, fileID, info); } -void DownloadManager::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString) +void DownloadManager::nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorString) { std::set::iterator idIter = m_RequestIDs.find(requestID); if (idIter == m_RequestIDs.end()) { @@ -1381,7 +1393,7 @@ void DownloadManager::nxmRequestFailed(int modID, int fileID, QVariant userData, } } - removePending(modID, fileID); + removePending(gameName, modID, fileID); emit showMessage(tr("Failed to request file info from nexus: %1").arg(errorString)); } diff --git a/src/downloadmanager.h b/src/downloadmanager.h index a6d3b20c..780aeb5c 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -38,6 +38,7 @@ along with Mod Organizer. If not, see . namespace MOBase { class IPluginGame; } class NexusInterface; +class PluginContainer; /*! * \brief manages downloading of files and provides progress information for gui elements @@ -162,6 +163,8 @@ public: */ void setShowHidden(bool showHidden); + void setPluginContainer(PluginContainer *pluginContainer); + /** * @brief download from an already open network connection * @@ -179,7 +182,7 @@ public: * @param fileInfo information previously retrieved from the nexus network * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again **/ - bool addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, int modID, int fileID = 0, const MOBase::ModRepositoryFileInfo *fileInfo = new MOBase::ModRepositoryFileInfo()); + bool addDownload(QNetworkReply *reply, const QStringList &URLs, const QString &fileName, QString gameName, int modID, int fileID = 0, const MOBase::ModRepositoryFileInfo *fileInfo = new MOBase::ModRepositoryFileInfo()); /** * @brief start a download using a nxm-link @@ -209,7 +212,7 @@ public: * @param index index of the pending download (index in the range [0, numPendingDownloads()[) * @return pair of modid, fileid */ - std::pair getPendingDownload(int index); + std::tuple getPendingDownload(int index); /** * @brief retrieve the full path to the download specified by index @@ -411,15 +414,15 @@ public slots: void queryInfo(int index); - void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID); + void nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID); + void nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString); + void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorString); void managedGameChanged(MOBase::IPluginGame const *gamePlugin); @@ -462,7 +465,7 @@ private: * @param fileInfo information previously retrieved from the mod page * @return true if the download was started, false if it wasn't. The latter currently only happens if there is a duplicate and the user decides not to download again **/ - bool addDownload(const QStringList &URLs, int modID, int fileID, const MOBase::ModRepositoryFileInfo *fileInfo); + bool addDownload(const QStringList &URLs, QString gameName, int modID, int fileID, const MOBase::ModRepositoryFileInfo *fileInfo); // important: the caller has to lock the list-mutex, otherwise the DownloadInfo-pointer might get invalidated at any time DownloadInfo *findDownload(QObject *reply, int *index = nullptr) const; @@ -481,7 +484,7 @@ private: QDateTime matchDate(const QString &timeString); - void removePending(int modID, int fileID); + void removePending(QString gameName, int modID, int fileID); static QString getFileTypeString(int fileType); @@ -493,7 +496,7 @@ private: NexusInterface *m_NexusInterface; - QVector > m_PendingDownloads; + QVector> m_PendingDownloads; QVector m_ActiveDownloads; diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp index 9a70f8bd..6785bf67 100644 --- a/src/installationmanager.cpp +++ b/src/installationmanager.cpp @@ -537,7 +537,7 @@ bool InstallationManager::ensureValidModName(GuessedValue &name) const return true; } -bool InstallationManager::doInstall(GuessedValue &modName, int modID, +bool InstallationManager::doInstall(GuessedValue &modName, QString gameName, int modID, const QString &version, const QString &newestVersion, int categoryID, const QString &repository) { @@ -582,6 +582,9 @@ bool InstallationManager::doInstall(GuessedValue &modName, int modID, QSettings settingsFile(targetDirectory + "/meta.ini", QSettings::IniFormat); // overwrite settings only if they are actually are available or haven't been set before + if ((gameName != "") || !settingsFile.contains("gameName")) { + settingsFile.setValue("gameName", gameName); + } if ((modID != 0) || !settingsFile.contains("modid")) { settingsFile.setValue("modid", modID); } @@ -662,6 +665,7 @@ bool InstallationManager::install(const QString &fileName, modName.update(QFileInfo(fileName).completeBaseName(), GUESS_FALLBACK); // read out meta information from the download if available + QString gameName = ""; int modID = 0; QString version = ""; QString newestVersion = ""; @@ -671,6 +675,7 @@ bool InstallationManager::install(const QString &fileName, QString metaName = fileName + ".meta"; if (QFile(metaName).exists()) { QSettings metaFile(metaName, QSettings::IniFormat); + gameName = metaFile.value("gameName", "").toString(); modID = metaFile.value("modID", 0).toInt(); QTextDocument doc; doc.setHtml(metaFile.value("name", "").toString()); @@ -759,7 +764,7 @@ bool InstallationManager::install(const QString &fileName, mapToArchive(filesTree.data()); // the simple installer only prepares the installation, the rest // works the same for all installers - if (!doInstall(modName, modID, version, newestVersion, categoryID, + if (!doInstall(modName, gameName, modID, version, newestVersion, categoryID, repository)) { installResult = IPluginInstaller::RESULT_FAILED; } @@ -780,6 +785,15 @@ bool InstallationManager::install(const QString &fileName, if (installerExt.find(fileInfo.suffix()) != installerExt.end()) { installResult = installerCustom->install(modName, fileName, version, modID); + if (installResult == IPluginInstaller::RESULT_SUCCESS) { + mapToArchive(filesTree.data()); + // the simple installer only prepares the installation, the rest + // works the same for all installers + if (!doInstall(modName, gameName, modID, version, newestVersion, categoryID, + repository)) { + installResult = IPluginInstaller::RESULT_FAILED; + } + } unsigned int idx = ModInfo::getIndex(modName); if (idx != UINT_MAX) { ModInfo::Ptr info = ModInfo::getByIndex(idx); diff --git a/src/installationmanager.h b/src/installationmanager.h index e1ebb519..bdf71a8d 100644 --- a/src/installationmanager.h +++ b/src/installationmanager.h @@ -168,7 +168,7 @@ private: bool isSimpleArchiveTopLayer(const MOBase::DirectoryTree::Node *node, bool bainStyle); MOBase::DirectoryTree::Node *getSimpleArchiveBase(MOBase::DirectoryTree *dataTree); - bool doInstall(MOBase::GuessedValue &modName, + bool doInstall(MOBase::GuessedValue &modName, QString gameName, int modID, const QString &version, const QString &newestVersion, int categoryID, const QString &repository); QString generateBackupName(const QString &directoryName) const; diff --git a/src/main.cpp b/src/main.cpp index fc332fe7..d67c2673 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,6 +46,7 @@ along with Mod Organizer. If not, see . #include "nxmaccessmanager.h" #include "instancemanager.h" #include "moshortcut.h" +#include "organizercore.h" #include #include @@ -602,7 +603,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, QSplashScreen splash(pixmap); splash.show(); - NexusInterface::instance()->getAccessManager()->startLoginCheck(); + NexusInterface::instance(&pluginContainer)->getAccessManager()->startLoginCheck(); qDebug("initializing tutorials"); TutorialManager::init( diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6cbe364e..171026cf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -266,6 +266,7 @@ MainWindow::MainWindow(QSettings &initSettings // hide these columns by default ui->modList->header()->setSectionHidden(ModList::COL_CONTENT, true); ui->modList->header()->setSectionHidden(ModList::COL_MODID, true); + ui->modList->header()->setSectionHidden(ModList::COL_GAME, true); ui->modList->header()->setSectionHidden(ModList::COL_INSTALLTIME, true); } @@ -343,11 +344,11 @@ MainWindow::MainWindow(QSettings &initSettings connect(m_OrganizerCore.updater(), SIGNAL(updateAvailable()), this, SLOT(updateAvailable())); connect(m_OrganizerCore.updater(), SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString))); - connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); - connect(NexusInterface::instance(), SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(int,int,QVariant,QVariant,int))); - connect(NexusInterface::instance(), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusLogin())); - connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); - connect(NexusInterface::instance()->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)), + connect(NexusInterface::instance(&pluginContainer), SIGNAL(requestNXMDownload(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); + connect(NexusInterface::instance(&pluginContainer), SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(int,int,QVariant,QVariant,int))); + connect(NexusInterface::instance(&pluginContainer), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusLogin())); + connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); + connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)), this, SLOT(updateWindowTitle(const QString&, bool))); connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString))); @@ -2347,7 +2348,7 @@ void MainWindow::reinstallMod_clicked() void MainWindow::resumeDownload(int downloadIndex) { - if (NexusInterface::instance()->getAccessManager()->loggedIn()) { + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn()) { m_OrganizerCore.downloadManager()->resumeDownload(downloadIndex); } else { QString username, password; @@ -2355,7 +2356,7 @@ void MainWindow::resumeDownload(int downloadIndex) m_OrganizerCore.doAfterLogin([this, downloadIndex] () { this->resumeDownload(downloadIndex); }); - NexusInterface::instance()->getAccessManager()->login(username, password); + NexusInterface::instance(&m_PluginContainer)->getAccessManager()->login(username, password); } else { MessageDialog::showMessage(tr("You need to be logged in with Nexus to resume a download"), this); } @@ -2365,13 +2366,13 @@ void MainWindow::resumeDownload(int downloadIndex) void MainWindow::endorseMod(ModInfo::Ptr mod) { - if (NexusInterface::instance()->getAccessManager()->loggedIn()) { + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn()) { mod->endorse(true); } else { QString username, password; if (m_OrganizerCore.settings().getNexusLogin(username, password)) { m_OrganizerCore.doAfterLogin(boost::bind(&MainWindow::endorseMod, this, mod)); - NexusInterface::instance()->getAccessManager()->login(username, password); + NexusInterface::instance(&m_PluginContainer)->getAccessManager()->login(username, password); } else { MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this); } @@ -2393,12 +2394,12 @@ void MainWindow::dontendorse_clicked() void MainWindow::unendorse_clicked() { QString username, password; - if (NexusInterface::instance()->getAccessManager()->loggedIn()) { + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn()) { ModInfo::getByIndex(m_ContextRow)->endorse(false); } else { if (m_OrganizerCore.settings().getNexusLogin(username, password)) { m_OrganizerCore.doAfterLogin([this] () { this->unendorse_clicked(); }); - NexusInterface::instance()->getAccessManager()->login(username, password); + NexusInterface::instance(&m_PluginContainer)->getAccessManager()->login(username, password); } else { MessageDialog::showMessage(tr("You need to be logged in with Nexus to endorse"), this); } @@ -2574,8 +2575,9 @@ void MainWindow::ignoreMissingData_clicked() void MainWindow::visitOnNexus_clicked() { int modID = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole).toInt(); + QString gameName = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole + 4).toString(); if (modID > 0) { - nexusLinkActivated(NexusInterface::instance()->getModURL(modID)); + nexusLinkActivated(NexusInterface::instance(&m_PluginContainer)->getModURL(modID, gameName)); } else { MessageDialog::showMessage(tr("Nexus ID for this Mod is unknown"), this); } @@ -2921,18 +2923,18 @@ void MainWindow::saveArchiveList() void MainWindow::checkModsForUpdates() { statusBar()->show(); - if (NexusInterface::instance()->getAccessManager()->loggedIn()) { - m_ModsToUpdate = ModInfo::checkAllForUpdate(this); + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn()) { + m_ModsToUpdate = ModInfo::checkAllForUpdate(&m_PluginContainer, this); m_RefreshProgress->setRange(0, m_ModsToUpdate); } else { QString username, password; if (m_OrganizerCore.settings().getNexusLogin(username, password)) { m_OrganizerCore.doAfterLogin([this] () { this->checkModsForUpdates(); }); - NexusInterface::instance()->getAccessManager()->login(username, password); + NexusInterface::instance(&m_PluginContainer)->getAccessManager()->login(username, password); } else { // otherwise there will be no endorsement info MessageDialog::showMessage(tr("Not logged in, endorsement information will be wrong"), this, true); - m_ModsToUpdate = ModInfo::checkAllForUpdate(this); + m_ModsToUpdate = ModInfo::checkAllForUpdate(&m_PluginContainer, this); } } } @@ -3207,7 +3209,7 @@ void MainWindow::exportModListCSV() if (nexus_ID->isChecked()) builder.setRowField("#Nexus_ID", info->getNexusID()); if (mod_Nexus_URL->isChecked()) - builder.setRowField("#Mod_Nexus_URL",(info->getNexusID()>0)? NexusInterface::instance()->getModURL(info->getNexusID()) : ""); + builder.setRowField("#Mod_Nexus_URL",(info->getNexusID()>0)? NexusInterface::instance(&m_PluginContainer)->getModURL(info->getNexusID(), info->getGameName()) : ""); if (mod_Version->isChecked()) builder.setRowField("#Mod_Version", info->getVersion().canonicalString()); if (install_Date->isChecked()) @@ -3629,7 +3631,7 @@ void MainWindow::on_actionSettings_triggered() bool oldDisplayForeign(settings.displayForeign()); bool proxy = settings.useProxy(); - settings.query(this); + settings.query(&m_PluginContainer, this); InstallationManager *instManager = m_OrganizerCore.installationManager(); instManager->setModsDirectory(settings.getModDirectory()); @@ -3661,14 +3663,14 @@ void MainWindow::on_actionSettings_triggered() } if (settings.getCacheDirectory() != oldCacheDirectory) { - NexusInterface::instance()->setCacheDirectory(settings.getCacheDirectory()); + NexusInterface::instance(&m_PluginContainer)->setCacheDirectory(settings.getCacheDirectory()); } if (proxy != settings.useProxy()) { activateProxy(settings.useProxy()); } - NexusInterface::instance()->setNMMVersion(settings.getNMMVersion()); + NexusInterface::instance(&m_PluginContainer)->setNMMVersion(settings.getNMMVersion()); updateDownloadListDelegate(); @@ -3680,7 +3682,7 @@ void MainWindow::on_actionSettings_triggered() void MainWindow::on_actionNexus_triggered() { ::ShellExecuteW(nullptr, L"open", - NexusInterface::instance()->getGameURL().toStdWString().c_str(), + NexusInterface::instance(&m_PluginContainer)->getGameURL(m_OrganizerCore.managedGame()->gameShortName()).toStdWString().c_str(), nullptr, nullptr, SW_SHOWNORMAL); } @@ -4099,10 +4101,10 @@ void MainWindow::on_actionEndorseMO_triggered() { if (QMessageBox::question(this, tr("Endorse Mod Organizer"), tr("Do you want to endorse Mod Organizer on %1 now?").arg( - NexusInterface::instance()->getGameURL()), + NexusInterface::instance(&m_PluginContainer)->getGameURL(m_OrganizerCore.managedGame()->gameShortName())), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - NexusInterface::instance()->requestToggleEndorsement( - m_OrganizerCore.managedGame()->nexusModOrganizerID(), true, this, QVariant(), QString()); + NexusInterface::instance(&m_PluginContainer)->requestToggleEndorsement( + m_OrganizerCore.managedGame()->gameShortName(), m_OrganizerCore.managedGame()->nexusModOrganizerID(), true, this, QVariant(), QString()); } } @@ -4174,7 +4176,7 @@ void MainWindow::nxmUpdatesAvailable(const std::vector &modIDs, QVariant us for (auto iter = info.begin(); iter != info.end(); ++iter) { (*iter)->setNewestVersion(result["version"].toString()); (*iter)->setNexusDescription(result["description"].toString()); - if (NexusInterface::instance()->getAccessManager()->loggedIn() && + if (NexusInterface::instance(&m_PluginContainer)->getAccessManager()->loggedIn() && result.contains("voted_by_user")) { // don't use endorsement info if we're not logged in or if the response doesn't contain it (*iter)->setIsEndorsed(result["voted_by_user"].toBool()); @@ -4197,20 +4199,20 @@ void MainWindow::nxmUpdatesAvailable(const std::vector &modIDs, QVariant us } } -void MainWindow::nxmEndorsementToggled(int, QVariant, QVariant resultData, int) +void MainWindow::nxmEndorsementToggled(QString, int, QVariant, QVariant resultData, int) { if (resultData.toBool()) { ui->actionEndorseMO->setVisible(false); QMessageBox::question(this, tr("Thank you!"), tr("Thank you for your endorsement!")); } - if (!disconnect(sender(), SIGNAL(nxmEndorsementToggled(int, QVariant, QVariant, int)), - this, SLOT(nxmEndorsementToggled(int, QVariant, QVariant, int)))) { + if (!disconnect(sender(), SIGNAL(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)), + this, SLOT(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)))) { qCritical("failed to disconnect endorsement slot"); } } -void MainWindow::nxmDownloadURLs(int, int, QVariant, QVariant resultData, int) +void MainWindow::nxmDownloadURLs(QString, int, int, QVariant, QVariant resultData, int) { QVariantList serverList = resultData.toList(); @@ -4229,7 +4231,7 @@ void MainWindow::nxmDownloadURLs(int, int, QVariant, QVariant resultData, int) } -void MainWindow::nxmRequestFailed(int modID, int, QVariant, int, const QString &errorString) +void MainWindow::nxmRequestFailed(QString, int modID, int, QVariant, int, const QString &errorString) { if (modID == -1) { // must be the update-check that failed diff --git a/src/mainwindow.h b/src/mainwindow.h index ef6eb262..d684dbc0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -461,9 +461,9 @@ private slots: void modInstalled(const QString &modName); void nxmUpdatesAvailable(const std::vector &modIDs, QVariant userData, QVariant resultData, int requestID); - void nxmEndorsementToggled(int, QVariant, QVariant resultData, int); - void nxmDownloadURLs(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString); + void nxmEndorsementToggled(QString, int, QVariant, QVariant resultData, int); + void nxmDownloadURLs(QString, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmRequestFailed(QString, int modID, int fileID, QVariant userData, int requestID, const QString &errorString); void editCategories(); void deselectFilters(); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index d80c636b..2cd3aec7 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -61,16 +61,16 @@ bool ModInfo::ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS) } -ModInfo::Ptr ModInfo::createFrom(const QDir &dir, DirectoryEntry **directoryStructure) +ModInfo::Ptr ModInfo::createFrom(PluginContainer *pluginContainer, QString gameName, const QDir &dir, DirectoryEntry **directoryStructure) { QMutexLocker locker(&s_Mutex); // int id = s_NextID++; static QRegExp backupExp(".*backup[0-9]*"); ModInfo::Ptr result; if (backupExp.exactMatch(dir.dirName())) { - result = ModInfo::Ptr(new ModInfoBackup(dir, directoryStructure)); + result = ModInfo::Ptr(new ModInfoBackup(pluginContainer, gameName, dir, directoryStructure)); } else { - result = ModInfo::Ptr(new ModInfoRegular(dir, directoryStructure)); + result = ModInfo::Ptr(new ModInfoRegular(pluginContainer, gameName, dir, directoryStructure)); } s_Collection.push_back(result); return result; @@ -80,10 +80,11 @@ ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, - DirectoryEntry **directoryStructure) { + DirectoryEntry **directoryStructure, + PluginContainer *pluginContainer) { QMutexLocker locker(&s_Mutex); ModInfo::Ptr result = ModInfo::Ptr( - new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure)); + new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure, pluginContainer)); s_Collection.push_back(result); return result; } @@ -105,11 +106,11 @@ QString ModInfo::getContentTypeName(int contentType) } } -void ModInfo::createFromOverwrite() +void ModInfo::createFromOverwrite(PluginContainer *pluginContainer) { QMutexLocker locker(&s_Mutex); - s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite)); + s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite(pluginContainer))); } unsigned int ModInfo::getNumMods() @@ -207,6 +208,7 @@ unsigned int ModInfo::findMod(const boost::function &filter void ModInfo::updateFromDisc(const QString &modDirectory, DirectoryEntry **directoryStructure, + PluginContainer *pluginContainer, bool displayForeign, MOBase::IPluginGame const *game) { @@ -219,7 +221,7 @@ void ModInfo::updateFromDisc(const QString &modDirectory, mods.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); QDirIterator modIter(mods); while (modIter.hasNext()) { - createFrom(QDir(modIter.next()), directoryStructure); + createFrom(pluginContainer, game->gameShortName(), QDir(modIter.next()), directoryStructure); } } @@ -233,11 +235,12 @@ void ModInfo::updateFromDisc(const QString &modDirectory, unmanaged->referenceFile(modName).absoluteFilePath(), unmanaged->secondaryFiles(modName), modType, - directoryStructure); + directoryStructure, + pluginContainer); } } - createFromOverwrite(); + createFromOverwrite(pluginContainer); std::sort(s_Collection.begin(), s_Collection.end(), ModInfo::ByName); @@ -259,21 +262,21 @@ void ModInfo::updateIndices() } -ModInfo::ModInfo() +ModInfo::ModInfo(PluginContainer *pluginContainer) : m_Valid(false), m_PrimaryCategory(-1) { } -void ModInfo::checkChunkForUpdate(const std::vector &modIDs, QObject *receiver) +void ModInfo::checkChunkForUpdate(PluginContainer *pluginContainer, const std::vector &modIDs, QObject *receiver, QString gameName) { if (modIDs.size() != 0) { - NexusInterface::instance()->requestUpdates(modIDs, receiver, QVariant(), QString()); + NexusInterface::instance(pluginContainer)->requestUpdates(modIDs, receiver, QVariant(), gameName, QString()); } } -int ModInfo::checkAllForUpdate(QObject *receiver) +int ModInfo::checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiver) { // technically this should be 255 but those requests can take nexus fairly long, produce // large output and may have been the cause of issue #1166 @@ -284,20 +287,33 @@ int ModInfo::checkAllForUpdate(QObject *receiver) //I ought to store this, it's used elsewhere IPluginGame const *game = qApp->property("managed_game").value(); - modIDs.push_back(game->nexusModOrganizerID()); + checkChunkForUpdate(pluginContainer, modIDs, receiver, game->gameShortName()); - for (const ModInfo::Ptr &mod : s_Collection) { + std::multimap> organizedGames; + for (auto mod : s_Collection) { if (mod->canBeUpdated()) { - modIDs.push_back(mod->getNexusID()); - if (modIDs.size() >= chunkSize) { - checkChunkForUpdate(modIDs, receiver); + organizedGames.insert(std::pair>(mod->getGameName(), mod)); + } + } + + QString currentGame = ""; + for (auto game : organizedGames) { + if (currentGame != game.first) { + if (currentGame != "") { + checkChunkForUpdate(pluginContainer, modIDs, receiver, currentGame); modIDs.clear(); } + currentGame = game.first; + } + modIDs.push_back(game.second->getNexusID()); + if (modIDs.size() >= chunkSize) { + checkChunkForUpdate(pluginContainer, modIDs, receiver, currentGame); + modIDs.clear(); } } - checkChunkForUpdate(modIDs, receiver); + checkChunkForUpdate(pluginContainer, modIDs, receiver, currentGame); return result; } diff --git a/src/modinfo.h b/src/modinfo.h index 1ceb8e1f..f321f068 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -23,6 +23,8 @@ along with Mod Organizer. If not, see . #include "imodinterface.h" #include "versioninfo.h" +class PluginContainer; + class QDateTime; class QDir; #include @@ -115,6 +117,7 @@ public: **/ static void updateFromDisc(const QString &modDirectory, MOShared::DirectoryEntry **directoryStructure, + PluginContainer *pluginContainer, bool displayForeign, MOBase::IPluginGame const *game); @@ -176,19 +179,19 @@ public: * @param modIDs list of mods (Nexus Mod IDs) to check for updates * @return */ - static void checkChunkForUpdate(const std::vector &modIDs, QObject *receiver); + static void checkChunkForUpdate(PluginContainer *pluginContainer, const std::vector &modIDs, QObject *receiver, QString gameName); /** * @brief query nexus information for every mod and update the "newest version" information **/ - static int checkAllForUpdate(QObject *receiver); + static int checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiver); /** * @brief create a new mod from the specified directory and add it to the collection * @param dir directory to create from * @return pointer to the info-structure of the newly created/added mod */ - static ModInfo::Ptr createFrom(const QDir &dir, MOShared::DirectoryEntry **directoryStructure); + static ModInfo::Ptr createFrom(PluginContainer *pluginContainer, QString gameName, const QDir &dir, MOShared::DirectoryEntry **directoryStructure); /** * @brief create a new "foreign-managed" mod from a tuple of plugin and archives @@ -196,7 +199,7 @@ public: * @param bsaNames names of archives * @return a new mod */ - static ModInfo::Ptr createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, MOShared::DirectoryEntry **directoryStructure); + static ModInfo::Ptr createFromPlugin(const QString &modName, const QString &espName, const QStringList &bsaNames, ModInfo::EModType modType, MOShared::DirectoryEntry **directoryStructure, PluginContainer *pluginContainer); /** * @brief retieve a name for one of the CONTENT_ enums @@ -408,7 +411,14 @@ public: * * @return the nexus mod id. may be 0 if the mod id isn't known or doesn't exist **/ - virtual int getNexusID() const = 0; + virtual int getNexusID() const = 0; + + /** + * @brief getter for the source game repository + * + * @return the source game repository. should default to the active game. + **/ + virtual QString getGameName() const = 0; /** * @return the fixed priority of mods of this type or INT_MIN if the priority of mods @@ -596,14 +606,14 @@ signals: protected: - ModInfo(); + ModInfo(PluginContainer *pluginContainer); static void updateIndices(); static bool ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS); private: - static void createFromOverwrite(); + static void createFromOverwrite(PluginContainer *pluginContainer); protected: diff --git a/src/modinfobackup.cpp b/src/modinfobackup.cpp index a57b84fe..b779dca1 100644 --- a/src/modinfobackup.cpp +++ b/src/modinfobackup.cpp @@ -14,7 +14,7 @@ QString ModInfoBackup::getDescription() const } -ModInfoBackup::ModInfoBackup(const QDir &path, MOShared::DirectoryEntry **directoryStructure) - : ModInfoRegular(path, directoryStructure) +ModInfoBackup::ModInfoBackup(PluginContainer *pluginContainer, QString gameName, const QDir &path, MOShared::DirectoryEntry **directoryStructure) + : ModInfoRegular(pluginContainer, gameName, path, directoryStructure) { } diff --git a/src/modinfobackup.h b/src/modinfobackup.h index adbac783..aa59dda4 100644 --- a/src/modinfobackup.h +++ b/src/modinfobackup.h @@ -32,7 +32,7 @@ public: private: - ModInfoBackup(const QDir &path, MOShared::DirectoryEntry **directoryStructure); + ModInfoBackup(PluginContainer *pluginContainer, QString gameName, const QDir &path, MOShared::DirectoryEntry **directoryStructure); }; diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 6a53d915..31ffe82d 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -714,7 +714,7 @@ void ModInfoDialog::linkClicked(const QUrl &url) { //Ideally we'd ask the mod for the game and the web service then pass the game //and URL to the web service - if (NexusInterface::instance()->isURLGameRelated(url)) { + if (NexusInterface::instance(m_PluginContainer)->isURLGameRelated(url)) { this->close(); emit nexusLinkActivated(url.toString()); } else { @@ -860,7 +860,7 @@ void ModInfoDialog::activateNexusTab() QLineEdit *modIDEdit = findChild("modIDEdit"); int modID = modIDEdit->text().toInt(); if (modID != 0) { - QString nexusLink = NexusInterface::instance()->getModURL(modID); + QString nexusLink = NexusInterface::instance(m_PluginContainer)->getModURL(modID, m_ModInfo->getGameName()); QLabel *visitNexusLabel = findChild("visitNexusLabel"); visitNexusLabel->setText(tr("Visit on Nexus").arg(nexusLink)); visitNexusLabel->setToolTip(nexusLink); diff --git a/src/modinfoforeign.cpp b/src/modinfoforeign.cpp index 6ac66c67..b599d4eb 100644 --- a/src/modinfoforeign.cpp +++ b/src/modinfoforeign.cpp @@ -51,8 +51,9 @@ ModInfoForeign::ModInfoForeign(const QString &modName, const QString &referenceFile, const QStringList &archives, ModInfo::EModType modType, - DirectoryEntry **directoryStructure) - : ModInfoWithConflictInfo(directoryStructure), + DirectoryEntry **directoryStructure, + PluginContainer *pluginContainer) + : ModInfoWithConflictInfo(pluginContainer, directoryStructure), m_ReferenceFile(referenceFile), m_Archives(archives) { m_CreationTime = QFileInfo(referenceFile).created(); switch (modType) { diff --git a/src/modinfoforeign.h b/src/modinfoforeign.h index d60064f0..23500df8 100644 --- a/src/modinfoforeign.h +++ b/src/modinfoforeign.h @@ -37,6 +37,7 @@ public: virtual QString absolutePath() const; virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } virtual QString getInstallationFile() const { return ""; } + virtual QString getGameName() const { return ""; } virtual int getNexusID() const { return -1; } virtual std::vector getIniTweaks() const { return std::vector(); } virtual std::vector getFlags() const; @@ -53,7 +54,7 @@ public: protected: ModInfoForeign(const QString &modName, const QString &referenceFile, const QStringList &archives, ModInfo::EModType modType, - MOShared::DirectoryEntry **directoryStructure); + MOShared::DirectoryEntry **directoryStructure, PluginContainer *pluginContainer); private: QString m_Name; diff --git a/src/modinfooverwrite.cpp b/src/modinfooverwrite.cpp index 360212c0..742ae384 100644 --- a/src/modinfooverwrite.cpp +++ b/src/modinfooverwrite.cpp @@ -6,7 +6,7 @@ #include #include -ModInfoOverwrite::ModInfoOverwrite() +ModInfoOverwrite::ModInfoOverwrite(PluginContainer *pluginContainer) : ModInfo(pluginContainer) { testValid(); } diff --git a/src/modinfooverwrite.h b/src/modinfooverwrite.h index b6cdfb43..360c7335 100644 --- a/src/modinfooverwrite.h +++ b/src/modinfooverwrite.h @@ -40,6 +40,7 @@ public: virtual MOBase::VersionInfo getNewestVersion() const { return QString(); } virtual QString getInstallationFile() const { return ""; } virtual int getFixedPriority() const { return INT_MAX; } + virtual QString getGameName() const { return ""; } virtual int getNexusID() const { return -1; } virtual std::vector getIniTweaks() const { return std::vector(); } virtual std::vector getFlags() const; @@ -52,7 +53,7 @@ public: private: - ModInfoOverwrite(); + ModInfoOverwrite(PluginContainer *pluginContainer); }; diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 4572f5bf..69718705 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -24,26 +24,27 @@ namespace { } } -ModInfoRegular::ModInfoRegular(const QDir &path, DirectoryEntry **directoryStructure) - : ModInfoWithConflictInfo(directoryStructure) +ModInfoRegular::ModInfoRegular(PluginContainer *pluginContainer, QString gameName, const QDir &path, DirectoryEntry **directoryStructure) + : ModInfoWithConflictInfo(pluginContainer, directoryStructure) + , m_GameName(gameName) , m_Name(path.dirName()) , m_Path(path.absolutePath()) , m_Repository() , m_MetaInfoChanged(false) , m_EndorsedState(ENDORSED_UNKNOWN) - , m_NexusBridge() + , m_NexusBridge(pluginContainer) { testValid(); m_CreationTime = QFileInfo(path.absolutePath()).created(); // read out the meta-file for information readMeta(); - connect(&m_NexusBridge, SIGNAL(descriptionAvailable(int,QVariant,QVariant)) - , this, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant))); - connect(&m_NexusBridge, SIGNAL(endorsementToggled(int,QVariant,QVariant)) - , this, SLOT(nxmEndorsementToggled(int,QVariant,QVariant))); - connect(&m_NexusBridge, SIGNAL(requestFailed(int,int,QVariant,QString)) - , this, SLOT(nxmRequestFailed(int,int,QVariant,QString))); + connect(&m_NexusBridge, SIGNAL(descriptionAvailable(QString,int,QVariant,QVariant)) + , this, SLOT(nxmDescriptionAvailable(QString,int,QVariant,QVariant))); + connect(&m_NexusBridge, SIGNAL(endorsementToggled(QString,int,QVariant,QVariant)) + , this, SLOT(nxmEndorsementToggled(QString,int,QVariant,QVariant))); + connect(&m_NexusBridge, SIGNAL(requestFailed(QString,int,int,QVariant,QString)) + , this, SLOT(nxmRequestFailed(QString,int,int,QVariant,QString))); } @@ -71,6 +72,8 @@ void ModInfoRegular::readMeta() { QSettings metaFile(m_Path + "/meta.ini", QSettings::IniFormat); m_Notes = metaFile.value("notes", "").toString(); + QString tempGameName = metaFile.value("gameName", m_GameName).toString(); + if (tempGameName != "") m_GameName = tempGameName; m_NexusID = metaFile.value("modid", -1).toInt(); m_Version.parse(metaFile.value("version", "").toString()); m_NewestVersion = metaFile.value("newestVersion", "").toString(); @@ -135,6 +138,7 @@ void ModInfoRegular::saveMeta() metaFile.setValue("version", m_Version.canonicalString()); metaFile.setValue("installationFile", m_InstallationFile); metaFile.setValue("repository", m_Repository); + metaFile.setValue("gameName", m_GameName); metaFile.setValue("modid", m_NexusID); metaFile.setValue("notes", m_Notes); metaFile.setValue("nexusDescription", m_NexusDescription); @@ -185,7 +189,7 @@ bool ModInfoRegular::downgradeAvailable() const } -void ModInfoRegular::nxmDescriptionAvailable(int, QVariant, QVariant resultData) +void ModInfoRegular::nxmDescriptionAvailable(QString, int, QVariant, QVariant resultData) { QVariantMap result = resultData.toMap(); setNewestVersion(VersionInfo(result["version"].toString())); @@ -201,7 +205,7 @@ void ModInfoRegular::nxmDescriptionAvailable(int, QVariant, QVariant resultData) } -void ModInfoRegular::nxmEndorsementToggled(int, QVariant, QVariant resultData) +void ModInfoRegular::nxmEndorsementToggled(QString, int, QVariant, QVariant resultData) { m_EndorsedState = resultData.toBool() ? ENDORSED_TRUE : ENDORSED_FALSE; m_MetaInfoChanged = true; @@ -210,7 +214,7 @@ void ModInfoRegular::nxmEndorsementToggled(int, QVariant, QVariant resultData) } -void ModInfoRegular::nxmRequestFailed(int, int, QVariant userData, const QString &errorMessage) +void ModInfoRegular::nxmRequestFailed(QString, int, int, QVariant userData, const QString &errorMessage) { QString fullMessage = errorMessage; if (userData.canConvert() && (userData.toInt() == 1)) { @@ -226,7 +230,7 @@ void ModInfoRegular::nxmRequestFailed(int, int, QVariant userData, const QString bool ModInfoRegular::updateNXMInfo() { if (m_NexusID > 0) { - m_NexusBridge.requestDescription(m_NexusID, QVariant()); + m_NexusBridge.requestDescription(m_GameName, m_NexusID, QVariant()); return true; } return false; @@ -387,7 +391,7 @@ bool ModInfoRegular::remove() void ModInfoRegular::endorse(bool doEndorse) { if (doEndorse != (m_EndorsedState == ENDORSED_TRUE)) { - m_NexusBridge.requestToggleEndorsement(getNexusID(), doEndorse, QVariant(1)); + m_NexusBridge.requestToggleEndorsement(m_GameName, getNexusID(), doEndorse, QVariant(1)); } } diff --git a/src/modinforegular.h b/src/modinforegular.h index a94d0363..7a6f4827 100644 --- a/src/modinforegular.h +++ b/src/modinforegular.h @@ -206,6 +206,14 @@ public: * @return file used to install this mod from */ virtual QString getInstallationFile() const { return m_InstallationFile; } + + /** + * @brief getter for the source game repository + * + * @return the source game repository. should default to the active game. + **/ + QString getGameName() const { return m_GameName; } + /** * @brief getter for the nexus mod id * @@ -308,13 +316,13 @@ private: private slots: - void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData); - void nxmEndorsementToggled(int, QVariant userData, QVariant resultData); - void nxmRequestFailed(int modID, int fileID, QVariant userData, const QString &errorMessage); + void nxmDescriptionAvailable(QString, int modID, QVariant userData, QVariant resultData); + void nxmEndorsementToggled(QString, int, QVariant userData, QVariant resultData); + void nxmRequestFailed(QString, int modID, int fileID, QVariant userData, const QString &errorMessage); protected: - ModInfoRegular(const QDir &path, MOShared::DirectoryEntry **directoryStructure); + ModInfoRegular(PluginContainer *pluginContainer, QString gameName, const QDir &path, MOShared::DirectoryEntry **directoryStructure); private: @@ -325,6 +333,7 @@ private: QString m_NexusDescription; QString m_Repository; QString m_URL; + QString m_GameName; QDateTime m_CreationTime; QDateTime m_LastNexusQuery; diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index b8ece783..e88ba29d 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -6,8 +6,8 @@ using namespace MOBase; using namespace MOShared; -ModInfoWithConflictInfo::ModInfoWithConflictInfo(DirectoryEntry **directoryStructure) - : m_DirectoryStructure(directoryStructure) {} +ModInfoWithConflictInfo::ModInfoWithConflictInfo(PluginContainer *pluginContainer, DirectoryEntry **directoryStructure) + : ModInfo(pluginContainer), m_DirectoryStructure(directoryStructure) {} void ModInfoWithConflictInfo::clearCaches() { diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h index be31f20f..6c1591c5 100644 --- a/src/modinfowithconflictinfo.h +++ b/src/modinfowithconflictinfo.h @@ -10,7 +10,7 @@ class ModInfoWithConflictInfo : public ModInfo public: - ModInfoWithConflictInfo(MOShared::DirectoryEntry **directoryStructure); + ModInfoWithConflictInfo(PluginContainer *pluginContainer, MOShared::DirectoryEntry **directoryStructure); std::vector getFlags() const; diff --git a/src/modlist.cpp b/src/modlist.cpp index 7b2ad1f9..c8fd4b3e 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -53,13 +53,14 @@ along with Mod Organizer. If not, see . using namespace MOBase; -ModList::ModList(QObject *parent) +ModList::ModList(PluginContainer *pluginContainer, QObject *parent) : QAbstractItemModel(parent) , m_Profile(nullptr) , m_NexusInterface(nullptr) , m_Modified(false) , m_FontMetrics(QFont()) , m_DropOnItems(false) + , m_PluginContainer(pluginContainer) { m_ContentIcons[ModInfo::CONTENT_PLUGIN] = std::make_tuple(":/MO/gui/content/plugin", tr("Game Plugins (ESP/ESM/ESL)")); m_ContentIcons[ModInfo::CONTENT_INTERFACE] = std::make_tuple(":/MO/gui/content/interface", tr("Interface")); @@ -219,9 +220,18 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const int modID = modInfo->getNexusID(); if (modID >= 0) { return modID; - } else { + } + else { return QVariant(); } + } else if (column == COL_GAME) { + if (m_PluginContainer != nullptr) { + for (auto game : m_PluginContainer->plugins()) { + if (game->gameShortName() == modInfo->getGameName()) + return game->gameName(); + } + } + return modInfo->getGameName(); } else if (column == COL_CATEGORY) { if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) { return tr("Non-MO"); @@ -309,6 +319,8 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const } } else if (role == Qt::UserRole + 3) { return contentsToIcons(modInfo->getContents()); + } else if (role == Qt::UserRole + 4) { + return modInfo->getGameName(); } else if (role == Qt::FontRole) { QFont result; if (column == COL_NAME) { @@ -659,6 +671,11 @@ void ModList::setOverwriteMarkers(const std::set &overwrite, const notifyChange(0, rowCount() - 1); } +void ModList::setPluginContainer(PluginContainer *pluginContianer) +{ + m_PluginContainer = pluginContianer; +} + bool ModList::modInfoAboutToChange(ModInfo::Ptr info) { if (m_ChangeInfo.name.isEmpty()) { @@ -1051,6 +1068,7 @@ QString ModList::getColumnName(int column) case COL_VERSION: return tr("Version"); case COL_PRIORITY: return tr("Priority"); case COL_CATEGORY: return tr("Category"); + case COL_GAME: return tr("Source Game"); case COL_MODID: return tr("Nexus ID"); case COL_INSTALLTIME: return tr("Installation"); default: return tr("unknown"); @@ -1066,6 +1084,7 @@ QString ModList::getColumnToolTip(int column) case COL_PRIORITY: return tr("Installation priority of your mod. The higher, the more \"important\" it is and thus " "overwrites files from mods with lower priority."); case COL_CATEGORY: return tr("Category of the mod."); + case COL_GAME: return tr("The source game which was the origin of this mod."); case COL_MODID: return tr("Id of the mod as used on Nexus."); case COL_FLAGS: return tr("Emblemes to highlight things that might require attention."); case COL_CONTENT: return tr("Depicts the content of the mod:
" diff --git a/src/modlist.h b/src/modlist.h index bd715107..b5f18e98 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -42,6 +42,7 @@ along with Mod Organizer. If not, see . class QSortFilterProxyModel; +class PluginContainer; /** * Model presenting an overview of the installed mod @@ -60,6 +61,7 @@ public: COL_CONTENT, COL_CATEGORY, COL_MODID, + COL_GAME, COL_VERSION, COL_INSTALLTIME, COL_PRIORITY, @@ -76,7 +78,7 @@ public: * @brief constructor * @todo ensure this view works without a profile set, otherwise there are intransparent dependencies on the initialisation order **/ - ModList(QObject *parent = nullptr); + ModList(PluginContainer *pluginContainer, QObject *parent = nullptr); ~ModList(); @@ -106,6 +108,7 @@ public: void changeModPriority(int sourceIndex, int newPriority); void setOverwriteMarkers(const std::set &overwrite, const std::set &overwritten); + void setPluginContainer(PluginContainer *pluginContainer); bool modInfoAboutToChange(ModInfo::Ptr info); void modInfoChanged(ModInfo::Ptr info); @@ -329,6 +332,8 @@ private: QTime m_LastCheck; + PluginContainer *m_PluginContainer; + }; #endif // MODLIST_H diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index 97186e8b..434c0334 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -36,48 +36,48 @@ using namespace MOBase; using namespace MOShared; -NexusBridge::NexusBridge(const QString &subModule) - : m_Interface(NexusInterface::instance()) +NexusBridge::NexusBridge(PluginContainer *pluginContainer, const QString &subModule) + : m_Interface(NexusInterface::instance(pluginContainer)) , m_SubModule(subModule) { } -void NexusBridge::requestDescription(int modID, QVariant userData) +void NexusBridge::requestDescription(QString gameName, int modID, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestDescription(modID, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestDescription(gameName, modID, this, userData, m_SubModule)); } -void NexusBridge::requestFiles(int modID, QVariant userData) +void NexusBridge::requestFiles(QString gameName, int modID, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestFiles(modID, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestFiles(gameName, modID, this, userData, m_SubModule)); } -void NexusBridge::requestFileInfo(int modID, int fileID, QVariant userData) +void NexusBridge::requestFileInfo(QString gameName, int modID, int fileID, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestFileInfo(modID, fileID, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestFileInfo(gameName, modID, fileID, this, userData, m_SubModule)); } -void NexusBridge::requestDownloadURL(int modID, int fileID, QVariant userData) +void NexusBridge::requestDownloadURL(QString gameName, int modID, int fileID, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestDownloadURL(modID, fileID, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestDownloadURL(gameName, modID, fileID, this, userData, m_SubModule)); } -void NexusBridge::requestToggleEndorsement(int modID, bool endorse, QVariant userData) +void NexusBridge::requestToggleEndorsement(QString gameName, int modID, bool endorse, QVariant userData) { - m_RequestIDs.insert(m_Interface->requestToggleEndorsement(modID, endorse, this, userData, m_SubModule)); + m_RequestIDs.insert(m_Interface->requestToggleEndorsement(gameName, modID, endorse, this, userData, m_SubModule)); } -void NexusBridge::nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit descriptionAvailable(modID, userData, resultData); + emit descriptionAvailable(gameName, modID, userData, resultData); } } -void NexusBridge::nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { @@ -100,43 +100,43 @@ void NexusBridge::nxmFilesAvailable(int modID, QVariant userData, QVariant resul fileInfoList.append(temp); } - emit filesAvailable(modID, userData, fileInfoList); + emit filesAvailable(gameName, modID, userData, fileInfoList); } } -void NexusBridge::nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit fileInfoAvailable(modID, fileID, userData, resultData); + emit fileInfoAvailable(gameName, modID, fileID, userData, resultData); } } -void NexusBridge::nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit downloadURLsAvailable(modID, fileID, userData, resultData); + emit downloadURLsAvailable(gameName, modID, fileID, userData, resultData); } } -void NexusBridge::nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID) +void NexusBridge::nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit endorsementToggled(modID, userData, resultData); + emit endorsementToggled(gameName, modID, userData, resultData); } } -void NexusBridge::nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage) +void NexusBridge::nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage) { std::set::iterator iter = m_RequestIDs.find(requestID); if (iter != m_RequestIDs.end()) { m_RequestIDs.erase(iter); - emit requestFailed(modID, fileID, userData, errorMessage); + emit requestFailed(gameName, modID, fileID, userData, errorMessage); } } @@ -144,8 +144,8 @@ void NexusBridge::nxmRequestFailed(int modID, int fileID, QVariant userData, int QAtomicInt NexusInterface::NXMRequestInfo::s_NextID(0); -NexusInterface::NexusInterface() - : m_NMMVersion() +NexusInterface::NexusInterface(PluginContainer *pluginContainer) + : m_NMMVersion(), m_PluginContainer(pluginContainer) { VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath())); m_MOVersion = VersionInfo(version.dwFileVersionMS >> 16, @@ -167,9 +167,9 @@ NexusInterface::~NexusInterface() cleanup(); } -NexusInterface *NexusInterface::instance() +NexusInterface *NexusInterface::instance(PluginContainer *pluginContainer) { - static NexusInterface s_Instance; + static NexusInterface s_Instance(pluginContainer); return &s_Instance; } @@ -246,12 +246,16 @@ void NexusInterface::interpretNexusFileName(const QString &fileName, QString &mo bool NexusInterface::isURLGameRelated(const QUrl &url) const { QString const name(url.toString()); - return name.startsWith(getGameURL() + "/") || + return name.startsWith(getGameURL("") + "/") || name.startsWith(getOldModsURL() + "/"); } -QString NexusInterface::getGameURL() const +QString NexusInterface::getGameURL(QString gameName) const { + IPluginGame *game = getGame(gameName); + if (game != nullptr) { + return "http://www.nexusmods.com/" + game->gameNexusName().toLower(); + } return "http://www.nexusmods.com/" + m_Game->gameNexusName().toLower(); } @@ -261,9 +265,9 @@ QString NexusInterface::getOldModsURL() const } -QString NexusInterface::getModURL(int modID) const +QString NexusInterface::getModURL(int modID, QString gameName = "") const { - return QString("%1/mods/%2").arg(getGameURL()).arg(modID); + return QString("%1/mods/%2").arg(getGameURL(gameName)).arg(modID); } bool NexusInterface::isModURL(int modID, const QString &url) const @@ -276,17 +280,22 @@ bool NexusInterface::isModURL(int modID, const QString &url) const return QUrl(alt) == QUrl(url); } -int NexusInterface::requestDescription(int modID, QObject *receiver, QVariant userData, +void NexusInterface::setPluginContainer(PluginContainer *pluginContainer) +{ + m_PluginContainer = pluginContainer; +} + +int NexusInterface::requestDescription(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game) { NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_DESCRIPTION, userData, subModule, game); m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmDescriptionAvailable(int,QVariant,QVariant,int)), - receiver, SLOT(nxmDescriptionAvailable(int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmDescriptionAvailable(QString,int,QVariant,QVariant,int)), + receiver, SLOT(nxmDescriptionAvailable(QString,int,QVariant,QVariant,int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString,int,int,QVariant,int,QString)), + receiver, SLOT(nxmRequestFailed(QString,int,int,QVariant,int,QString)), Qt::UniqueConnection); nextRequest(); return requestInfo.m_ID; @@ -294,19 +303,25 @@ int NexusInterface::requestDescription(int modID, QObject *receiver, QVariant us int NexusInterface::requestUpdates(const std::vector &modIDs, QObject *receiver, QVariant userData, - const QString &subModule, MOBase::IPluginGame const *game) + QString gameName, const QString &subModule) { - NXMRequestInfo requestInfo(modIDs, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game); - m_RequestQueue.enqueue(requestInfo); + IPluginGame *game = getGame(gameName); - connect(this, SIGNAL(nxmUpdatesAvailable(std::vector,QVariant,QVariant,int)), - receiver, SLOT(nxmUpdatesAvailable(std::vector,QVariant,QVariant,int)), Qt::UniqueConnection); + if (game != nullptr) { + NXMRequestInfo requestInfo(modIDs, NXMRequestInfo::TYPE_GETUPDATES, userData, subModule, game); + m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmUpdatesAvailable(std::vector, QVariant, QVariant, int)), + receiver, SLOT(nxmUpdatesAvailable(std::vector, QVariant, QVariant, int)), Qt::UniqueConnection); - nextRequest(); - return requestInfo.m_ID; + connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QString)), + receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QString)), Qt::UniqueConnection); + + nextRequest(); + return requestInfo.m_ID; + } + + return -1; } @@ -325,72 +340,75 @@ void NexusInterface::fakeFiles() fileMap["size"] = "512"; result.append(fileMap); - emit nxmFilesAvailable(1234, "fake", result, id++); + emit nxmFilesAvailable("fakeGame", 1234, "fake", result, id++); } -int NexusInterface::requestFiles(int modID, QObject *receiver, QVariant userData, +int NexusInterface::requestFiles(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game) { NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_FILES, userData, subModule, game); m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmFilesAvailable(int,QVariant,QVariant,int)), - receiver, SLOT(nxmFilesAvailable(int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmFilesAvailable(QString,int,QVariant,QVariant,int)), + receiver, SLOT(nxmFilesAvailable(QString,int,QVariant,QVariant,int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString,int,int,QVariant,int,QString)), + receiver, SLOT(nxmRequestFailed(QString,int,int,QVariant,int,QString)), Qt::UniqueConnection); nextRequest(); return requestInfo.m_ID; } -int NexusInterface::requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, - MOBase::IPluginGame const *game) +int NexusInterface::requestFileInfo(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule) { - NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData, subModule, game); - m_RequestQueue.enqueue(requestInfo); + IPluginGame *gamePlugin = getGame(gameName); + if (gamePlugin != nullptr) { + NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_FILEINFO, userData, subModule, gamePlugin); + m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmFileInfoAvailable(int,int,QVariant,QVariant,int)), - receiver, SLOT(nxmFileInfoAvailable(int,int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmFileInfoAvailable(QString, int, int, QVariant, QVariant, int)), + receiver, SLOT(nxmFileInfoAvailable(QString, int, int, QVariant, QVariant, int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString, int, int, QVariant, int, QString)), + receiver, SLOT(nxmRequestFailed(QString, int, int, QVariant, int, QString)), Qt::UniqueConnection); - nextRequest(); - return requestInfo.m_ID; + nextRequest(); + return requestInfo.m_ID; + } + return -1; } -int NexusInterface::requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, +int NexusInterface::requestDownloadURL(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game) { NXMRequestInfo requestInfo(modID, fileID, NXMRequestInfo::TYPE_DOWNLOADURL, userData, subModule, game); m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), - receiver, SLOT(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmDownloadURLsAvailable(QString,int,int,QVariant,QVariant,int)), + receiver, SLOT(nxmDownloadURLsAvailable(QString,int,int,QVariant,QVariant,int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString,int,int,QVariant,int,QString)), + receiver, SLOT(nxmRequestFailed(QString,int,int,QVariant,int,QString)), Qt::UniqueConnection); nextRequest(); return requestInfo.m_ID; } -int NexusInterface::requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, +int NexusInterface::requestToggleEndorsement(QString gameName, int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game) { NXMRequestInfo requestInfo(modID, NXMRequestInfo::TYPE_TOGGLEENDORSEMENT, userData, subModule, game); requestInfo.m_Endorse = endorse; m_RequestQueue.enqueue(requestInfo); - connect(this, SIGNAL(nxmEndorsementToggled(int,QVariant,QVariant,int)), - receiver, SLOT(nxmEndorsementToggled(int,QVariant,QVariant,int)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmEndorsementToggled(QString,int,QVariant,QVariant,int)), + receiver, SLOT(nxmEndorsementToggled(QString,int,QVariant,QVariant,int)), Qt::UniqueConnection); - connect(this, SIGNAL(nxmRequestFailed(int,int,QVariant,int,QString)), - receiver, SLOT(nxmRequestFailed(int,int,QVariant,int,QString)), Qt::UniqueConnection); + connect(this, SIGNAL(nxmRequestFailed(QString,int,int,QVariant,int,QString)), + receiver, SLOT(nxmRequestFailed(QString,int,int,QVariant,int,QString)), Qt::UniqueConnection); nextRequest(); return requestInfo.m_ID; @@ -402,6 +420,19 @@ bool NexusInterface::requiresLogin(const NXMRequestInfo &info) || (info.m_Type == NXMRequestInfo::TYPE_DOWNLOADURL); } +IPluginGame* NexusInterface::getGame(QString gameName) const +{ + auto gamePlugins = m_PluginContainer->plugins(); + IPluginGame *gamePlugin = nullptr; + for (auto plugin : gamePlugins) { + if (plugin->gameShortName().compare(gameName, Qt::CaseInsensitive) == 0) { + gamePlugin = plugin; + break; + } + } + return gamePlugin; +} + void NexusInterface::cleanup() { // delete m_AccessManager; @@ -492,7 +523,7 @@ void NexusInterface::requestFinished(std::list::iterator iter) if (reply->error() != QNetworkReply::NoError) { qWarning("request failed: %s", reply->errorString().toUtf8().constData()); - emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->errorString()); + emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, reply->errorString()); } else { int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (statusCode == 301) { @@ -510,33 +541,33 @@ void NexusInterface::requestFinished(std::list::iterator iter) nexusError = tr("empty response"); } qDebug("nexus error: %s", qPrintable(nexusError)); - emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, nexusError); + emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, nexusError); } else { bool ok; QVariant result = QtJson::parse(data, ok); if (result.isValid() && ok) { switch (iter->m_Type) { case NXMRequestInfo::TYPE_DESCRIPTION: { - emit nxmDescriptionAvailable(iter->m_ModID, iter->m_UserData, result, iter->m_ID); + emit nxmDescriptionAvailable(iter->m_GameName, iter->m_ModID, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_FILES: { - emit nxmFilesAvailable(iter->m_ModID, iter->m_UserData, result, iter->m_ID); + emit nxmFilesAvailable(iter->m_GameName, iter->m_ModID, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_FILEINFO: { - emit nxmFileInfoAvailable(iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID); + emit nxmFileInfoAvailable(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_DOWNLOADURL: { - emit nxmDownloadURLsAvailable(iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID); + emit nxmDownloadURLsAvailable(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_GETUPDATES: { emit nxmUpdatesAvailable(iter->m_ModIDList, iter->m_UserData, result, iter->m_ID); } break; case NXMRequestInfo::TYPE_TOGGLEENDORSEMENT: { - emit nxmEndorsementToggled(iter->m_ModID, iter->m_UserData, result, iter->m_ID); + emit nxmEndorsementToggled(iter->m_GameName, iter->m_ModID, iter->m_UserData, result, iter->m_ID); } break; } } else { - emit nxmRequestFailed(iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, tr("invalid response")); + emit nxmRequestFailed(iter->m_GameName, iter->m_ModID, iter->m_FileID, iter->m_UserData, iter->m_ID, tr("invalid response")); } } } @@ -620,6 +651,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID , m_URL(get_management_url(game)) , m_SubModule(subModule) , m_NexusGameID(game->nexusGameID()) + , m_GameName(game->gameShortName()) , m_Endorse(false) {} @@ -641,6 +673,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(std::vector modIDList , m_URL(get_management_url(game)) , m_SubModule(subModule) , m_NexusGameID(game->nexusGameID()) + , m_GameName(game->gameShortName()) , m_Endorse(false) {} @@ -662,5 +695,6 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID , m_URL(get_management_url(game)) , m_SubModule(subModule) , m_NexusGameID(game->nexusGameID()) + , m_GameName(game->gameShortName()) , m_Endorse(false) {} diff --git a/src/nexusinterface.h b/src/nexusinterface.h index 9e7f3642..9a01c5c5 100644 --- a/src/nexusinterface.h +++ b/src/nexusinterface.h @@ -23,6 +23,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include @@ -53,7 +54,7 @@ class NexusBridge : public MOBase::IModRepositoryBridge public: - NexusBridge(const QString &subModule = ""); + NexusBridge(PluginContainer *pluginContainer, const QString &subModule = ""); /** * @brief request description for a mod @@ -62,7 +63,7 @@ public: * @param userData user data to be returned with the result * @param url the url to request from **/ - virtual void requestDescription(int modID, QVariant userData); + virtual void requestDescription(QString gameName, int modID, QVariant userData); /** * @brief request a list of the files belonging to a mod @@ -70,7 +71,7 @@ public: * @param modID id of the mod caller is interested in * @param userData user data to be returned with the result **/ - virtual void requestFiles(int modID, QVariant userData); + virtual void requestFiles(QString gameName, int modID, QVariant userData); /** * @brief request info about a single file of a mod @@ -79,7 +80,7 @@ public: * @param fileID id of the file the caller is interested in * @param userData user data to be returned with the result **/ - virtual void requestFileInfo(int modID, int fileID, QVariant userData); + virtual void requestFileInfo(QString gameName, int modID, int fileID, QVariant userData); /** * @brief request the download url of a file @@ -88,23 +89,23 @@ public: * @param fileID id of the file the caller is interested in * @param userData user data to be returned with the result **/ - virtual void requestDownloadURL(int modID, int fileID, QVariant userData); + virtual void requestDownloadURL(QString gameName, int modID, int fileID, QVariant userData); /** * @brief requestToggleEndorsement * @param modID id of the mod caller is interested in * @param userData user data to be returned with the result */ - virtual void requestToggleEndorsement(int modID, bool endorse, QVariant userData); + virtual void requestToggleEndorsement(QString gameName, int modID, bool endorse, QVariant userData); public slots: - void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage); + void nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); + void nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); + void nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); + void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorMessage); private: @@ -130,7 +131,7 @@ public: ~NexusInterface(); - static NexusInterface *instance(); + static NexusInterface *instance(PluginContainer *pluginContainer); /** * @return the access manager object used to connect to nexus @@ -155,9 +156,9 @@ public: * @param userData user data to be returned with the result * @return int an id to identify the request **/ - int requestDescription(int modID, QObject *receiver, QVariant userData, const QString &subModule) + int requestDescription(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule) { - return requestDescription(modID, receiver, userData, subModule, m_Game); + return requestDescription(gameName, modID, receiver, userData, subModule, getGame(gameName)); } /** @@ -169,21 +170,9 @@ public: * @param game Game with which the mod is associated * @return int an id to identify the request **/ - int requestDescription(int modID, QObject *receiver, QVariant userData, const QString &subModule, + int requestDescription(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); - /** - * @brief request nexus descriptions for multiple mods at once - * @param modIDs a list of ids of mods the caller is interested in (assumed to be for the current game) - * @param receiver the object to receive the result asynchronously via a signal (nxmDescriptionAvailable) - * @param userData user data to be returned with the result - * @return int an id to identify the request - */ - int requestUpdates(const std::vector &modIDs, QObject *receiver, QVariant userData, const QString &subModule) - { - return requestUpdates(modIDs, receiver, userData, subModule, m_Game); - } - /** * @brief request nexus descriptions for multiple mods at once * @param modIDs a list of ids of mods the caller is interested in @@ -192,8 +181,7 @@ public: * @param game the game with which the mods are associated * @return int an id to identify the request */ - int requestUpdates(const std::vector &modIDs, QObject *receiver, QVariant userData, const QString &subModule, - MOBase::IPluginGame const *game); + int requestUpdates(const std::vector &modIDs, QObject *receiver, QVariant userData, QString gameName, const QString &subModule); /** * @brief request a list of the files belonging to a mod @@ -203,9 +191,9 @@ public: * @param userData user data to be returned with the result * @return int an id to identify the request **/ - int requestFiles(int modID, QObject *receiver, QVariant userData, const QString &subModule) + int requestFiles(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule) { - return requestFiles(modID, receiver, userData, subModule, m_Game); + return requestFiles(gameName, modID, receiver, userData, subModule, getGame(gameName)); } @@ -218,35 +206,20 @@ public: * @param game the game with which the mods are associated * @return int an id to identify the request **/ - int requestFiles(int modID, QObject *receiver, QVariant userData, const QString &subModule, + int requestFiles(QString gameName, int modID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); /** * @brief request info about a single file of a mod * + * @param game name of the game short name to request the download from * @param modID id of the mod caller is interested in (assumed to be for the current game) * @param fileID id of the file the caller is interested in * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable) * @param userData user data to be returned with the result * @return int an id to identify the request **/ - int requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule) - { - return requestFileInfo(modID, fileID, receiver, userData, subModule, m_Game); - } - - /** - * @brief request info about a single file of a mod - * - * @param modID id of the mod caller is interested in (assumed to be for the current game) - * @param fileID id of the file the caller is interested in - * @param receiver the object to receive the result asynchronously via a signal (nxmFilesAvailable) - * @param userData user data to be returned with the result - * @param game the game with which the mods are associated - * @return int an id to identify the request - **/ - int requestFileInfo(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, - MOBase::IPluginGame const *game); + int requestFileInfo(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule); /** * @brief request the download url of a file @@ -257,9 +230,9 @@ public: * @param userData user data to be returned with the result * @return int an id to identify the request **/ - int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule) + int requestDownloadURL(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule) { - return requestDownloadURL(modID, fileID, receiver, userData, subModule, m_Game); + return requestDownloadURL(gameName, modID, fileID, receiver, userData, subModule, getGame(gameName)); } /** @@ -272,7 +245,7 @@ public: * @param game the game with which the mods are associated * @return int an id to identify the request **/ - int requestDownloadURL(int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); + int requestDownloadURL(QString gameName, int modID, int fileID, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); /** * @brief toggle endorsement state of the mod @@ -282,9 +255,9 @@ public: * @param userData user data to be returned with the result * @return int an id to identify the request */ - int requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule) + int requestToggleEndorsement(QString gameName, int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule) { - return requestToggleEndorsement(modID, endorse, receiver, userData, subModule, m_Game); + return requestToggleEndorsement(gameName, modID, endorse, receiver, userData, subModule, getGame(gameName)); } /** @@ -296,7 +269,7 @@ public: * @param game the game with which the mods are associated * @return int an id to identify the request */ - int requestToggleEndorsement(int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule, + int requestToggleEndorsement(QString gameName, int modID, bool endorse, QObject *receiver, QVariant userData, const QString &subModule, MOBase::IPluginGame const *game); /** @@ -342,13 +315,13 @@ public: * * Arguably, this should optionally take a gameplugin pointer */ - QString getGameURL() const; + QString getGameURL(QString gameName) const; /** * @brief Get the URL for the mod web page * @param modID */ - QString getModURL(int modID) const; + QString getModURL(int modID, QString gameName) const; /** * @brief Checks if the specified URL might correspond to a nexus mod @@ -358,19 +331,21 @@ public: */ bool isModURL(int modID, QString const &url) const; + void setPluginContainer(PluginContainer *pluginContainer); + signals: void requestNXMDownload(const QString &url); void needLogin(); - void nxmDescriptionAvailable(int modID, QVariant userData, QVariant resultData, int requestID); + void nxmDescriptionAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); void nxmUpdatesAvailable(const std::vector &modIDs, QVariant userData, QVariant resultData, int requestID); - void nxmFilesAvailable(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmFileInfoAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmDownloadURLsAvailable(int modID, int fileID, QVariant userData, QVariant resultData, int requestID); - void nxmEndorsementToggled(int modID, QVariant userData, QVariant resultData, int requestID); - void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString); + void nxmFilesAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); + void nxmFileInfoAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmDownloadURLsAvailable(QString gameName, int modID, int fileID, QVariant userData, QVariant resultData, int requestID); + void nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID); + void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, const QString &errorString); public slots: void managedGameChanged(MOBase::IPluginGame const *game); @@ -404,6 +379,7 @@ private: QTimer *m_Timeout; QString m_URL; QString m_SubModule; + QString m_GameName; int m_NexusGameID; bool m_Reroute; int m_ID; @@ -421,10 +397,11 @@ private: private: - NexusInterface(); + NexusInterface(PluginContainer *pluginContainer); void nextRequest(); void requestFinished(std::list::iterator iter); bool requiresLogin(const NXMRequestInfo &info); + MOBase::IPluginGame *getGame(QString gameName) const; QString getOldModsURL() const; private: @@ -440,6 +417,7 @@ private: QString m_NMMVersion; MOBase::IPluginGame const *m_Game; + PluginContainer *m_PluginContainer; }; diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 999c7732..3248a8e0 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -192,15 +192,15 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) , m_GameName() , m_CurrentProfile(nullptr) , m_Settings(initSettings) - , m_Updater(NexusInterface::instance()) + , m_Updater(NexusInterface::instance(m_PluginContainer)) , m_AboutToRun() , m_FinishedRun() , m_ModInstalled() - , m_ModList(this) + , m_ModList(m_PluginContainer, this) , m_PluginList(this) , m_DirectoryRefresher() , m_DirectoryStructure(new DirectoryEntry(L"data", nullptr, 0)) - , m_DownloadManager(NexusInterface::instance(), this) + , m_DownloadManager(NexusInterface::instance(m_PluginContainer), this) , m_InstallationManager() , m_RefresherThread() , m_AskForNexusPW(false) @@ -211,8 +211,8 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory()); m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers()); - NexusInterface::instance()->setCacheDirectory(m_Settings.getCacheDirectory()); - NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion()); + NexusInterface::instance(m_PluginContainer)->setCacheDirectory(m_Settings.getCacheDirectory()); + NexusInterface::instance(m_PluginContainer)->setNMMVersion(m_Settings.getNMMVersion()); MOBase::QuestionBoxMemory::init(initSettings.fileName()); @@ -227,9 +227,9 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString))); - connect(NexusInterface::instance()->getAccessManager(), + connect(NexusInterface::instance(m_PluginContainer)->getAccessManager(), SIGNAL(loginSuccessful(bool)), this, SLOT(loginSuccessful(bool))); - connect(NexusInterface::instance()->getAccessManager(), + connect(NexusInterface::instance(m_PluginContainer)->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); // This seems awfully imperative @@ -241,7 +241,7 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings) connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), &m_PluginList, SLOT(managedGameChanged(MOBase::IPluginGame const *))); connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame const *)), - NexusInterface::instance(), + NexusInterface::instance(m_PluginContainer), SLOT(managedGameChanged(MOBase::IPluginGame const *))); connect(&m_PluginList, &PluginList::writePluginsList, &m_PluginListsWriter, @@ -454,7 +454,7 @@ void OrganizerCore::updateExecutablesList(QSettings &settings) // TODO this has nothing to do with executables list move to an appropriate // function! ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_Settings.displayForeign(), managedGame()); + m_PluginContainer, m_Settings.displayForeign(), managedGame()); } void OrganizerCore::setUserInterface(IUserInterface *userInterface, @@ -504,6 +504,9 @@ void OrganizerCore::connectPlugins(PluginContainer *container) m_DownloadManager.setSupportedExtensions( m_InstallationManager.getSupportedExtensions()); m_PluginContainer = container; + m_Updater.setPluginContainer(m_PluginContainer); + m_DownloadManager.setPluginContainer(m_PluginContainer); + m_ModList.setPluginContainer(m_PluginContainer); if (!m_GameName.isEmpty()) { m_GamePlugin = m_PluginContainer->managedGame(m_GameName); @@ -518,6 +521,9 @@ void OrganizerCore::disconnectPlugins() m_ModInstalled.disconnect_all_slots(); m_ModList.disconnectSlots(); m_PluginList.disconnectSlots(); + m_Updater.setPluginContainer(nullptr); + m_DownloadManager.setPluginContainer(nullptr); + m_ModList.setPluginContainer(nullptr); m_Settings.clearPlugins(); m_GamePlugin = nullptr; @@ -540,7 +546,7 @@ Settings &OrganizerCore::settings() bool OrganizerCore::nexusLogin(bool retry) { NXMAccessManager *accessManager - = NexusInterface::instance()->getAccessManager(); + = NexusInterface::instance(m_PluginContainer)->getAccessManager(); if ((accessManager->loginAttempted() || accessManager->loggedIn()) && !retry) { @@ -612,12 +618,12 @@ void OrganizerCore::externalMessage(const QString &message) } } -void OrganizerCore::downloadRequested(QNetworkReply *reply, int modID, +void OrganizerCore::downloadRequested(QNetworkReply *reply, QString gameName, int modID, const QString &fileName) { try { - if (m_DownloadManager.addDownload(reply, QStringList(), fileName, modID, 0, - new ModRepositoryFileInfo(modID))) { + if (m_DownloadManager.addDownload(reply, QStringList(), fileName, gameName, modID, 0, + new ModRepositoryFileInfo(gameName, modID))) { MessageDialog::showMessage(tr("Download started"), qApp->activeWindow()); } } catch (const std::exception &e) { @@ -739,7 +745,7 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) MOBase::IModRepositoryBridge *OrganizerCore::createNexusBridge() const { - return new NexusBridge(); + return new NexusBridge(m_PluginContainer); } QString OrganizerCore::profileName() const @@ -813,7 +819,7 @@ MOBase::IModInterface *OrganizerCore::createMod(GuessedValue &name) settingsFile.endArray(); } - return ModInfo::createFrom(QDir(targetDirectory), &m_DirectoryStructure) + return ModInfo::createFrom(m_PluginContainer, m_GamePlugin->gameShortName(), QDir(targetDirectory), &m_DirectoryStructure) .data(); } @@ -1552,7 +1558,7 @@ void OrganizerCore::refreshModList(bool saveChanges) m_CurrentProfile->writeModlistNow(true); } ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_Settings.displayForeign(), managedGame()); + m_PluginContainer, m_Settings.displayForeign(), managedGame()); m_CurrentProfile->refreshModStatus(); @@ -1719,8 +1725,13 @@ void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply) // no mod found that could handle the download. Is it a nexus mod? if (url.host() == "www.nexusmods.com") { + QString gameName = ""; int modID = 0; int fileID = 0; + QRegExp nameExp("www\.nexusmods\.com/(\\a+)/"); + if (nameExp.indexIn(url.toString()) != -1) { + gameName = nameExp.cap(1); + } QRegExp modExp("mods/(\\d+)"); if (modExp.indexIn(url.toString()) != -1) { modID = modExp.cap(1).toInt(); @@ -1730,7 +1741,7 @@ void OrganizerCore::requestDownload(const QUrl &url, QNetworkReply *reply) fileID = fileExp.cap(1).toInt(); } m_DownloadManager.addDownload(reply, - new ModRepositoryFileInfo(modID, fileID)); + new ModRepositoryFileInfo(gameName, modID, fileID)); } else { if (QMessageBox::question(qApp->activeWindow(), tr("Download?"), tr("A download has been started but no installed " @@ -1827,7 +1838,7 @@ void OrganizerCore::profileRefresh() // have to refresh mods twice (again in refreshModList), otherwise the refresh // isn't complete. Not sure why ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_Settings.displayForeign(), managedGame()); + m_PluginContainer, m_Settings.displayForeign(), managedGame()); m_CurrentProfile->refreshModStatus(); refreshModList(); @@ -1885,7 +1896,7 @@ void OrganizerCore::loginSuccessful(bool necessary) } m_PostLoginTasks.clear(); - NexusInterface::instance()->loginCompleted(); + NexusInterface::instance(m_PluginContainer)->loginCompleted(); } void OrganizerCore::loginSuccessfulUpdate(bool necessary) @@ -1920,7 +1931,7 @@ void OrganizerCore::loginFailed(const QString &message) qApp->activeWindow()); m_PostLoginTasks.clear(); } - NexusInterface::instance()->loginCompleted(); + NexusInterface::instance(m_PluginContainer)->loginCompleted(); } void OrganizerCore::loginFailedUpdate(const QString &message) diff --git a/src/organizercore.h b/src/organizercore.h index 54d9dd6d..76c286be 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -285,7 +285,7 @@ private: private slots: void directory_refreshed(); - void downloadRequested(QNetworkReply *reply, int modID, const QString &fileName); + void downloadRequested(QNetworkReply *reply, QString gameName, int modID, const QString &fileName); void removeOrigin(const QString &name); void downloadSpeed(const QString &serverName, int bytesPerSecond); void loginSuccessful(bool necessary); diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp index cf2e29e3..77d61a52 100644 --- a/src/organizerproxy.cpp +++ b/src/organizerproxy.cpp @@ -2,6 +2,7 @@ #include "appconfig.h" #include "organizercore.h" +#include "plugincontainer.h" #include @@ -9,15 +10,16 @@ using namespace MOBase; using namespace MOShared; -OrganizerProxy::OrganizerProxy(OrganizerCore *organizer, const QString &pluginName) +OrganizerProxy::OrganizerProxy(OrganizerCore *organizer, PluginContainer *pluginContainer, const QString &pluginName) : m_Proxied(organizer) + , m_PluginContainer(pluginContainer) , m_PluginName(pluginName) { } IModRepositoryBridge *OrganizerProxy::createNexusBridge() const { - return new NexusBridge(m_PluginName); + return new NexusBridge(m_PluginContainer, m_PluginName); } QString OrganizerProxy::profileName() const diff --git a/src/organizerproxy.h b/src/organizerproxy.h index 7004db14..cebb98ac 100644 --- a/src/organizerproxy.h +++ b/src/organizerproxy.h @@ -5,13 +5,14 @@ #include class OrganizerCore; +class PluginContainer; class OrganizerProxy : public MOBase::IOrganizer { public: - OrganizerProxy(OrganizerCore *organizer, const QString &pluginName); + OrganizerProxy(OrganizerCore *organizer, PluginContainer *pluginContainer, const QString &pluginName); virtual MOBase::IModRepositoryBridge *createNexusBridge() const; virtual QString profileName() const; @@ -55,6 +56,7 @@ public: private: OrganizerCore *m_Proxied; + PluginContainer *m_PluginContainer; const QString &m_PluginName; diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp index 60d1130c..f6376496 100644 --- a/src/plugincontainer.cpp +++ b/src/plugincontainer.cpp @@ -1,4 +1,5 @@ #include "plugincontainer.h" +#include "organizercore.h" #include "organizerproxy.h" #include "report.h" #include @@ -67,7 +68,7 @@ bool PluginContainer::verifyPlugin(IPlugin *plugin) { if (plugin == nullptr) { return false; - } else if (!plugin->init(new OrganizerProxy(m_Organizer, plugin->name()))) { + } else if (!plugin->init(new OrganizerProxy(m_Organizer, this, plugin->name()))) { qWarning("plugin failed to initialize"); return false; } diff --git a/src/plugincontainer.h b/src/plugincontainer.h index 70392d0b..172dbd09 100644 --- a/src/plugincontainer.h +++ b/src/plugincontainer.h @@ -1,9 +1,11 @@ #ifndef PLUGINCONTAINER_H #define PLUGINCONTAINER_H - -#include "organizercore.h" #include "previewgenerator.h" + +class OrganizerCore; +class IUserInterface; + #include #include #include diff --git a/src/profile.cpp b/src/profile.cpp index bbb5b814..7f10bd02 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -753,6 +753,7 @@ bool Profile::enableLocalSettings(bool enable) QString backupFile = getIniFileName() + "_"; if (enable) { if (m_Directory.exists(backupFile)) { + shellRename(backupFile, getIniFileName()); } else { IPluginGame *game = qApp->property("managed_game").value(); diff --git a/src/selfupdater.cpp b/src/selfupdater.cpp index 8f962ba4..debf9106 100644 --- a/src/selfupdater.cpp +++ b/src/selfupdater.cpp @@ -30,6 +30,7 @@ along with Mod Organizer. If not, see . #include "nxmaccessmanager.h" #include "settings.h" #include "bbcode.h" +#include "plugincontainer.h" #include #include #include @@ -120,6 +121,11 @@ void SelfUpdater::setUserInterface(QWidget *widget) m_Parent = widget; } +void SelfUpdater::setPluginContainer(PluginContainer *pluginContainer) +{ + m_Interface->setPluginContainer(pluginContainer); +} + void SelfUpdater::testForUpdate() { // TODO: if prereleases are disabled we could just request the latest release diff --git a/src/selfupdater.h b/src/selfupdater.h index 4743f6a4..bce49495 100644 --- a/src/selfupdater.h +++ b/src/selfupdater.h @@ -26,6 +26,7 @@ along with Mod Organizer. If not, see . class Archive; class NexusInterface; +class PluginContainer; namespace MOBase { class IPluginGame; } #include @@ -77,6 +78,8 @@ public: void setUserInterface(QWidget *widget); + void setPluginContainer(PluginContainer *pluginContainer); + /** * @brief start the update process * @note this should not be called if there is no update available diff --git a/src/settings.cpp b/src/settings.cpp index d1130e05..9510999d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -584,9 +584,9 @@ void Settings::resetDialogs() } -void Settings::query(QWidget *parent) +void Settings::query(PluginContainer *pluginContainer, QWidget *parent) { - SettingsDialog dialog(parent); + SettingsDialog dialog(pluginContainer, parent); connect(&dialog, SIGNAL(resetDialogs()), this, SLOT(resetDialogs())); diff --git a/src/settings.h b/src/settings.h index ae38223f..76ab55da 100644 --- a/src/settings.h +++ b/src/settings.h @@ -51,6 +51,7 @@ namespace MOBase { } class SettingsDialog; +class PluginContainer; /** * manages the settings for Mod Organizer. The settings are not cached @@ -88,7 +89,7 @@ public: * displays a SettingsDialog that allows the user to change settings. If the * user accepts the changes, the settings are immediately written **/ - void query(QWidget *parent); + void query(PluginContainer *pluginContainer, QWidget *parent); /** * set up the settings for the specified plugins diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index fb9433a6..a4071c26 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -27,6 +27,7 @@ along with Mod Organizer. If not, see . #include "settings.h" #include "instancemanager.h" #include "nexusinterface.h" +#include "plugincontainer.h" #include #include @@ -40,9 +41,10 @@ along with Mod Organizer. If not, see . using namespace MOBase; -SettingsDialog::SettingsDialog(QWidget *parent) +SettingsDialog::SettingsDialog(PluginContainer *pluginContainer, QWidget *parent) : TutorableDialog("SettingsDialog", parent) , ui(new Ui::SettingsDialog) + , m_PluginContainer(pluginContainer) { ui->setupUi(this); @@ -252,6 +254,6 @@ void SettingsDialog::on_associateButton_clicked() void SettingsDialog::on_clearCacheButton_clicked() { QDir(Settings::instance().getCacheDirectory()).removeRecursively(); - NexusInterface::instance()->clearCache(); + NexusInterface::instance(m_PluginContainer)->clearCache(); } diff --git a/src/settingsdialog.h b/src/settingsdialog.h index e9d995d3..32a8d0c5 100644 --- a/src/settingsdialog.h +++ b/src/settingsdialog.h @@ -25,6 +25,8 @@ along with Mod Organizer. If not, see . #include #include +class PluginContainer; + namespace Ui { class SettingsDialog; } @@ -39,7 +41,7 @@ class SettingsDialog : public MOBase::TutorableDialog Q_OBJECT public: - explicit SettingsDialog(QWidget *parent = 0); + explicit SettingsDialog(PluginContainer *pluginContainer, QWidget *parent = 0); ~SettingsDialog(); void addPlugins(const std::vector &plugins); @@ -87,7 +89,7 @@ private slots: private: Ui::SettingsDialog *ui; - + PluginContainer *m_PluginContainer; }; -- cgit v1.3.1 From b4eae6e5d1cbd92140e9a1058d623a4338a35c43 Mon Sep 17 00:00:00 2001 From: Silarn Date: Tue, 17 Apr 2018 00:33:15 -0500 Subject: Fix signal/slot connector for available server parser --- src/mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 651afba9..802adc24 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -345,7 +345,7 @@ MainWindow::MainWindow(QSettings &initSettings connect(m_OrganizerCore.updater(), SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString))); connect(NexusInterface::instance(&pluginContainer), SIGNAL(requestNXMDownload(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); - connect(NexusInterface::instance(&pluginContainer), SIGNAL(nxmDownloadURLsAvailable(int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(int,int,QVariant,QVariant,int))); + connect(NexusInterface::instance(&pluginContainer), SIGNAL(nxmDownloadURLsAvailable(QString,int,int,QVariant,QVariant,int)), this, SLOT(nxmDownloadURLs(QString,int,int,QVariant,QVariant,int))); connect(NexusInterface::instance(&pluginContainer), SIGNAL(needLogin()), &m_OrganizerCore, SLOT(nexusLogin())); connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)), -- cgit v1.3.1 From a14ed8fcd1f0cb06fb9353a3f672a70251394e2c Mon Sep 17 00:00:00 2001 From: Al12rs Date: Mon, 16 Apr 2018 18:38:54 +0200 Subject: Changed the modifodialog to open the first enabled left most tab, if no particular tab was specified by the function caller. This will allow the users to choose what tab should be opened when opening the mod informations since the order of the tabs can be changed and is saved. --- src/mainwindow.cpp | 17 ++++++++++++++++- src/mainwindow.h | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 802adc24..401e3c8b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2461,9 +2461,24 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, connect(&dialog, SIGNAL(modOpenPrev()), this, SLOT(modOpenPrev()), Qt::QueuedConnection); connect(&dialog, SIGNAL(originModified(int)), this, SLOT(originModified(int))); connect(&dialog, SIGNAL(endorseMod(ModInfo::Ptr)), this, SLOT(endorseMod(ModInfo::Ptr))); + + //Open the tab first if we want to use the standard indexes of the tabs. + if (tab != -1) { + dialog.openTab(tab); + } - dialog.openTab(tab); dialog.restoreTabState(m_OrganizerCore.settings().directInterface().value("mod_info_tabs").toByteArray()); + + //If no tab was specified use the first tab from the left based on the user order. + if (tab == -1) { + for (int i = 0; i < dialog.findChild("tabWidget")->count(); ++i) { + if (dialog.findChild("tabWidget")->isTabEnabled(i)) { + dialog.findChild("tabWidget")->setCurrentIndex(i); + break; + } + } + } + dialog.exec(); m_OrganizerCore.settings().directInterface().setValue("mod_info_tabs", dialog.saveTabState()); diff --git a/src/mainwindow.h b/src/mainwindow.h index d684dbc0..8faaa349 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -217,7 +217,7 @@ private: QList findFileInfos(const QString &path, const std::function &filter) const; bool modifyExecutablesDialog(); - void displayModInformation(int row, int tab = 0); + void displayModInformation(int row, int tab = -1); void testExtractBSA(int modIndex); void writeDataToFile(QFile &file, const QString &directory, const MOShared::DirectoryEntry &directoryEntry); -- cgit v1.3.1 From 62dc387de644a0a47156079f78f7e0ab174abdaa Mon Sep 17 00:00:00 2001 From: Al12rs Date: Tue, 17 Apr 2018 01:32:03 +0200 Subject: Added key shourtcuts to open in explorer a selected mo by pressing Enter or Return. Needs support for overwrte --- src/mainwindow.cpp | 18 ++++++++++++++++++ src/mainwindow.h | 4 ++++ 2 files changed, 22 insertions(+) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 401e3c8b..3eb7244a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -150,6 +150,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include @@ -369,6 +370,9 @@ MainWindow::MainWindow(QSettings &initSettings connect(ui->espList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(esplistSelectionsChanged(QItemSelection))); connect(ui->modList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(modlistSelectionsChanged(QItemSelection))); + new QShortcut(QKeySequence(Qt::Key_Enter), this, SLOT(openExplorer_activated())); + new QShortcut(QKeySequence(Qt::Key_Return), this, SLOT(openExplorer_activated())); + m_UpdateProblemsTimer.setSingleShot(true); connect(&m_UpdateProblemsTimer, SIGNAL(timeout()), this, SLOT(updateProblemsButton())); @@ -2615,6 +2619,20 @@ void MainWindow::openExplorer_clicked() ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } +void MainWindow::openExplorer_activated() +{ + QItemSelectionModel *selection = ui->modList->selectionModel(); + if (selection->hasSelection() && selection->selectedRows().count() == 1 && ui->modList->hasFocus()) { + + QModelIndex idx = selection->currentIndex(); + ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + if (modInfo->isRegular()) { + ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); + } + + } +} + void MainWindow::information_clicked() { try { diff --git a/src/mainwindow.h b/src/mainwindow.h index 8faaa349..31c52bc0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -386,6 +386,7 @@ private slots: void showMessage(const QString &message); void showError(const QString &message); + // main window actions void helpTriggered(); void issueTriggered(); @@ -393,6 +394,9 @@ private slots: void tutorialTriggered(); void extractBSATriggered(); + //modlist shortcuts + void openExplorer_activated(); + // modlist context menu void installMod_clicked(); void createEmptyMod_clicked(); -- cgit v1.3.1 From b1329c18cde91c9e245f59475ae3b32c2c663a8c Mon Sep 17 00:00:00 2001 From: Al12rs Date: Tue, 17 Apr 2018 09:26:56 +0200 Subject: Added Enter shortcut support for ovewrite as well to open the Explorer window. --- src/mainwindow.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3eb7244a..0d9ca4a9 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2626,7 +2626,9 @@ void MainWindow::openExplorer_activated() QModelIndex idx = selection->currentIndex(); ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); - if (modInfo->isRegular()) { + std::vector flags = modInfo->getFlags(); + + if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) { ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } -- cgit v1.3.1 From b64fd1ed4d68fc64ac061b0f126af54cf7147462 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Tue, 17 Apr 2018 16:13:43 +0200 Subject: Enter shourcut will now open the mod containing the selected plugin if the ESPList has the focus. Added F5 shourcut to refresh the profile. Removed a redundant variable I saw by chance. --- src/mainwindow.cpp | 50 ++++++++++++++++++++++++++++++++++++++++---------- src/mainwindow.h | 1 + src/modlist.cpp | 1 - 3 files changed, 41 insertions(+), 11 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0d9ca4a9..2d6ccc94 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -372,6 +372,9 @@ MainWindow::MainWindow(QSettings &initSettings new QShortcut(QKeySequence(Qt::Key_Enter), this, SLOT(openExplorer_activated())); new QShortcut(QKeySequence(Qt::Key_Return), this, SLOT(openExplorer_activated())); + + new QShortcut(QKeySequence::Refresh, this, SLOT(refreshProfile_activated())); + m_UpdateProblemsTimer.setSingleShot(true); connect(&m_UpdateProblemsTimer, SIGNAL(timeout()), this, SLOT(updateProblemsButton())); @@ -2621,20 +2624,47 @@ void MainWindow::openExplorer_clicked() void MainWindow::openExplorer_activated() { - QItemSelectionModel *selection = ui->modList->selectionModel(); - if (selection->hasSelection() && selection->selectedRows().count() == 1 && ui->modList->hasFocus()) { - - QModelIndex idx = selection->currentIndex(); - ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); - std::vector flags = modInfo->getFlags(); - - if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) { - ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); + if (ui->modList->hasFocus()) { + QItemSelectionModel *selection = ui->modList->selectionModel(); + if (selection->hasSelection() && selection->selectedRows().count() == 1 ) { + + QModelIndex idx = selection->currentIndex(); + ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + std::vector flags = modInfo->getFlags(); + + if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) { + ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); + } + } + } + + if (ui->espList->hasFocus()) { + QItemSelectionModel *selection = ui->espList->selectionModel(); + + if (selection->hasSelection() && selection->selectedRows().count() == 1) { + + QModelIndex idx = selection->currentIndex(); + QString fileName = idx.data().toString(); + + + ModInfo::Ptr modInfo = ModInfo::getByIndex(ModInfo::getIndex(m_OrganizerCore.pluginList()->origin(fileName))); + std::vector flags = modInfo->getFlags(); + + if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) { + ::ShellExecuteW(nullptr, L"explore", ToWString(modInfo->absolutePath()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); + } + + } } } +void MainWindow::refreshProfile_activated() +{ + m_OrganizerCore.profileRefresh(); +} + void MainWindow::information_clicked() { try { @@ -4557,7 +4587,7 @@ void MainWindow::on_espList_customContextMenuRequested(const QPoint &pos) menu.addAction(tr("Unlock load order"), this, SLOT(unlockESPIndex())); } if (hasUnlocked) { - menu.addAction(tr("Lock load order"), this, SLOT(lockESPIndex())); + menu.addAction(tr("Lock load order"), this, SLOT(f())); } try { diff --git a/src/mainwindow.h b/src/mainwindow.h index 31c52bc0..3d093131 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -396,6 +396,7 @@ private slots: //modlist shortcuts void openExplorer_activated(); + void refreshProfile_activated(); // modlist context menu void installMod_clicked(); diff --git a/src/modlist.cpp b/src/modlist.cpp index c8fd4b3e..3f9a732a 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -724,7 +724,6 @@ void ModList::highlightMods(const QItemSelection &selected, const MOShared::Dire const MOShared::FileEntry::Ptr fileEntry = directoryEntry.findFile(modName.toStdWString()); if (fileEntry.get() != nullptr) { - QString fileName; bool archive = false; std::vector> origins; { -- cgit v1.3.1 From f2762035171f60fdd0b16052c07f67a0f79d60a8 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Tue, 17 Apr 2018 21:16:44 +0200 Subject: Changed mod Information dialog "Next" and "Previous" buttons to remember the currently viewed tab. --- src/mainwindow.cpp | 16 ++++++++-------- src/mainwindow.h | 4 ++-- src/modinfodialog.cpp | 14 ++++++++++---- src/modinfodialog.h | 4 ++-- 4 files changed, 22 insertions(+), 16 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2d6ccc94..00c7895e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2464,8 +2464,8 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString))); connect(&dialog, SIGNAL(downloadRequest(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection); - connect(&dialog, SIGNAL(modOpenNext()), this, SLOT(modOpenNext()), Qt::QueuedConnection); - connect(&dialog, SIGNAL(modOpenPrev()), this, SLOT(modOpenPrev()), Qt::QueuedConnection); + connect(&dialog, SIGNAL(modOpenNext(int)), this, SLOT(modOpenNext(int)), Qt::QueuedConnection); + connect(&dialog, SIGNAL(modOpenPrev(int)), this, SLOT(modOpenPrev(int)), Qt::QueuedConnection); connect(&dialog, SIGNAL(originModified(int)), this, SLOT(originModified(int))); connect(&dialog, SIGNAL(endorseMod(ModInfo::Ptr)), this, SLOT(endorseMod(ModInfo::Ptr))); @@ -2526,7 +2526,7 @@ void MainWindow::setWindowEnabled(bool enabled) } -void MainWindow::modOpenNext() +void MainWindow::modOpenNext(int tab) { QModelIndex index = m_ModListSortProxy->mapFromSource(m_OrganizerCore.modList()->index(m_ContextRow, 0)); index = m_ModListSortProxy->index((index.row() + 1) % m_ModListSortProxy->rowCount(), 0); @@ -2537,13 +2537,13 @@ void MainWindow::modOpenNext() if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end())) { // skip overwrite and backups - modOpenNext(); + modOpenNext(tab); } else { - displayModInformation(m_ContextRow); + displayModInformation(m_ContextRow,tab); } } -void MainWindow::modOpenPrev() +void MainWindow::modOpenPrev(int tab) { QModelIndex index = m_ModListSortProxy->mapFromSource(m_OrganizerCore.modList()->index(m_ContextRow, 0)); int row = index.row() - 1; @@ -2557,9 +2557,9 @@ void MainWindow::modOpenPrev() if ((std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end())) { // skip overwrite and backups - modOpenPrev(); + modOpenPrev(tab); } else { - displayModInformation(m_ContextRow); + displayModInformation(m_ContextRow,tab); } } diff --git a/src/mainwindow.h b/src/mainwindow.h index 3d093131..b06da353 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -474,8 +474,8 @@ private slots: void deselectFilters(); void displayModInformation(const QString &modName, int tab); - void modOpenNext(); - void modOpenPrev(); + void modOpenNext(int tab=-1); + void modOpenPrev(int tab=-1); void modRenamed(const QString &oldName, const QString &newName); void modRemoved(const QString &fileName); diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 705f0019..c25041f2 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -1448,14 +1448,20 @@ void ModInfoDialog::on_endorseBtn_clicked() void ModInfoDialog::on_nextButton_clicked() { - emit modOpenNext(); - this->accept(); + int currentTab = ui->tabWidget->currentIndex(); + int tab = m_RealTabPos[currentTab]; + + emit modOpenNext(tab); + this->accept(); } void ModInfoDialog::on_prevButton_clicked() { - emit modOpenPrev(); - this->accept(); + int currentTab = ui->tabWidget->currentIndex(); + int tab = m_RealTabPos[currentTab]; + + emit modOpenPrev(tab); + this->accept(); } diff --git a/src/modinfodialog.h b/src/modinfodialog.h index b5cc12a8..ddd72f4d 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -112,8 +112,8 @@ signals: void nexusLinkActivated(const QString &link); void downloadRequest(const QString &link); void modOpen(const QString &modName, int tab); - void modOpenNext(); - void modOpenPrev(); + void modOpenNext(int tab=-1); + void modOpenPrev(int tab=-1); void originModified(int originID); void endorseMod(ModInfo::Ptr nexusID); -- cgit v1.3.1 From 08b56ee783131537d3f87e60819e88316ea1e062 Mon Sep 17 00:00:00 2001 From: Silarn Date: Wed, 18 Apr 2018 03:41:53 -0500 Subject: Improve and fix handling of external links --- src/CMakeLists.txt | 2 ++ src/aboutdialog.cpp | 5 +++++ src/aboutdialog.h | 5 +++++ src/aboutdialog.ui | 2 +- src/mainwindow.cpp | 31 ++++++++++++++----------------- src/mainwindow.h | 1 - src/modidlineedit.cpp | 19 +++++++++++++++++++ src/modidlineedit.h | 22 ++++++++++++++++++++++ src/modinfodialog.cpp | 12 ++++++++++-- src/modinfodialog.h | 3 ++- src/modinfodialog.ui | 15 ++++++++++----- src/modinforegular.cpp | 2 +- 12 files changed, 91 insertions(+), 28 deletions(-) create mode 100644 src/modidlineedit.cpp create mode 100644 src/modidlineedit.h (limited to 'src/mainwindow.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fef640b3..066d08d6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,6 +30,7 @@ SET(organizer_SRCS motddialog.cpp modlistsortproxy.cpp modlist.cpp + modidlineedit.cpp modinfodialog.cpp modinfo.cpp modinfobackup.cpp @@ -120,6 +121,7 @@ SET(organizer_HDRS motddialog.h modlistsortproxy.h modlist.h + modidlineedit.h modinfodialog.h modinfo.h modinfobackup.h diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index a350036f..9d68fe2b 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -114,3 +114,8 @@ void AboutDialog::on_creditsList_currentItemChanged(QListWidgetItem *current, QL ui->licenseText->setText(tr("No license")); } } + +void AboutDialog::on_copyrightText_linkActivated(const QString &link) +{ + emit linkClicked(link); +} \ No newline at end of file diff --git a/src/aboutdialog.h b/src/aboutdialog.h index 3ae3237b..285d0066 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -40,6 +40,10 @@ public: explicit AboutDialog(const QString &version, QWidget *parent = 0); ~AboutDialog(); +signals: + + void linkClicked(QString link); + private: enum Licenses { @@ -70,6 +74,7 @@ private: private slots: void on_creditsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); + void on_copyrightText_linkActivated(const QString &link); private: diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui index 69e52708..fc2f3290 100644 --- a/src/aboutdialog.ui +++ b/src/aboutdialog.ui @@ -125,7 +125,7 @@ - + <html><head/><body><p>This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</p><p>See the GNU General Public License for more details.</p><p>Source code can be found at <a href="https://github.com/Modorganizer2/modorganizer"><span style=" text-decoration: underline; color:#007af4;">GitHub</span></a>.</p></body></html> diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 00c7895e..6b176868 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -98,6 +98,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include #include @@ -319,6 +320,11 @@ MainWindow::MainWindow(QSettings &initSettings ui->groupCombo->installEventFilter(noWheel); ui->profileBox->installEventFilter(noWheel); + if (organizerCore.managedGame()->sortMechanism() == MOBase::IPluginGame::SortMechanism::NONE) { + ui->bossButton->setDisabled(true); + ui->bossButton->setToolTip(tr("There is no supported sort mechanism for this game. You will probably have to use a third-party tool.")); + } + connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(saveSelectionChanged(QListWidgetItem*))); connect(ui->modList, SIGNAL(dropModeUpdate(bool)), m_OrganizerCore.modList(), SLOT(dropModeUpdate(bool))); @@ -667,6 +673,7 @@ size_t MainWindow::checkForProblems() void MainWindow::about() { AboutDialog dialog(m_OrganizerCore.getVersion().displayString(), this); + connect(&dialog, SIGNAL(linkClicked(QString)), this, SLOT(linkClicked(QString))); dialog.exec(); } @@ -1008,8 +1015,7 @@ void MainWindow::modPagePluginInvoke() m_IntegratedBrowser.setWindowTitle(plugin->displayName()); m_IntegratedBrowser.openUrl(plugin->pageURL()); } else { - ::ShellExecuteW(nullptr, L"open", ToWString(plugin->pageURL().toString()).c_str(), - nullptr, nullptr, SW_SHOWNORMAL); + QDesktopServices::openUrl(QUrl(plugin->pageURL())); } } } @@ -1894,12 +1900,12 @@ void MainWindow::helpTriggered() void MainWindow::wikiTriggered() { - ::ShellExecuteW(nullptr, L"open", L"http://wiki.step-project.com/Guide:Mod_Organizer", nullptr, nullptr, SW_SHOWNORMAL); + QDesktopServices::openUrl(QUrl("http://wiki.step-project.com/Guide:Mod_Organizer")); } void MainWindow::issueTriggered() { - ::ShellExecuteW(nullptr, L"open", L"http://github.com/Modorganizer2/modorganizer/issues", nullptr, nullptr, SW_SHOWNORMAL); + QDesktopServices::openUrl(QUrl("http://github.com/Modorganizer2/modorganizer/issues")); } void MainWindow::tutorialTriggered() @@ -2461,7 +2467,7 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, } else { modInfo->saveMeta(); ModInfoDialog dialog(modInfo, m_OrganizerCore.directoryStructure(), modInfo->hasFlag(ModInfo::FLAG_FOREIGN), &m_OrganizerCore, &m_PluginContainer,this); - connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString))); + connect(&dialog, SIGNAL(linkActivated(QString)), this, SLOT(linkClicked(QString))); connect(&dialog, SIGNAL(downloadRequest(QString)), &m_OrganizerCore, SLOT(downloadRequestedNXM(QString))); connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection); connect(&dialog, SIGNAL(modOpenNext(int)), this, SLOT(modOpenNext(int)), Qt::QueuedConnection); @@ -2599,7 +2605,7 @@ void MainWindow::visitOnNexus_clicked() int modID = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole).toInt(); QString gameName = m_OrganizerCore.modList()->data(m_OrganizerCore.modList()->index(m_ContextRow, 0), Qt::UserRole + 4).toString(); if (modID > 0) { - nexusLinkActivated(NexusInterface::instance(&m_PluginContainer)->getModURL(modID, gameName)); + linkClicked(NexusInterface::instance(&m_PluginContainer)->getModURL(modID, gameName)); } else { MessageDialog::showMessage(tr("Nexus ID for this Mod is unknown"), this); } @@ -3746,22 +3752,13 @@ void MainWindow::on_actionSettings_triggered() void MainWindow::on_actionNexus_triggered() { - ::ShellExecuteW(nullptr, L"open", - NexusInterface::instance(&m_PluginContainer)->getGameURL(m_OrganizerCore.managedGame()->gameShortName()).toStdWString().c_str(), - nullptr, nullptr, SW_SHOWNORMAL); -} - - -void MainWindow::nexusLinkActivated(const QString &link) -{ - ::ShellExecuteW(nullptr, L"open", ToWString(link).c_str(), nullptr, nullptr, SW_SHOWNORMAL); - ui->tabWidget->setCurrentIndex(4); + QDesktopServices::openUrl(QUrl(NexusInterface::instance(&m_PluginContainer)->getGameURL(m_OrganizerCore.managedGame()->gameShortName()))); } void MainWindow::linkClicked(const QString &url) { - ::ShellExecuteW(nullptr, L"open", ToWString(url).c_str(), nullptr, nullptr, SW_SHOWNORMAL); + QDesktopServices::openUrl(QUrl(url)); } diff --git a/src/mainwindow.h b/src/mainwindow.h index b06da353..7f38d766 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -443,7 +443,6 @@ private slots: // nexus related void checkModsForUpdates(); - void nexusLinkActivated(const QString &link); void loginFailed(const QString &message); diff --git a/src/modidlineedit.cpp b/src/modidlineedit.cpp new file mode 100644 index 00000000..7d1f0c38 --- /dev/null +++ b/src/modidlineedit.cpp @@ -0,0 +1,19 @@ +#include "modidlineedit.h" +#include + +#include +#include + +ModIDLineEdit::ModIDLineEdit(QWidget *parent) : QLineEdit(parent) {} +ModIDLineEdit::ModIDLineEdit(const QString &text, QWidget *parent) : QLineEdit(text, parent) {} + +bool ModIDLineEdit::event(QEvent *event) +{ + if (event->type() == QEvent::WhatsThisClicked) + { + QWhatsThisClickedEvent *wtcEvent = static_cast(event); + emit linkClicked(wtcEvent->href().trimmed()); + } + + return QLineEdit::event(event); +} \ No newline at end of file diff --git a/src/modidlineedit.h b/src/modidlineedit.h new file mode 100644 index 00000000..2a3db36c --- /dev/null +++ b/src/modidlineedit.h @@ -0,0 +1,22 @@ +#ifndef MODIDLINEEDIT_H +#define MODIDLINEEDIT_H + +#include + +class ModIDLineEdit : public QLineEdit +{ + Q_OBJECT + +public: + explicit ModIDLineEdit(QWidget *parent = 0); + explicit ModIDLineEdit(const QString &text, QWidget *parent = 0); + +public: + virtual bool event(QEvent* event) override; + +signals: + void linkClicked(QString); + +}; + +#endif //MODIDLINEEDIT_H \ No newline at end of file diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index 710b9696..a137873e 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -22,6 +22,7 @@ along with Mod Organizer. If not, see . #include "descriptionpage.h" #include "mainwindow.h" +#include "modidlineedit.h" #include "iplugingame.h" #include "nexusinterface.h" #include "report.h" @@ -93,6 +94,8 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo ui->modIDEdit->setValidator(new QIntValidator(modIDEdit)); ui->modIDEdit->setText(QString("%1").arg(modInfo->getNexusID())); + connect(ui->modIDEdit, SIGNAL(linkClicked(QString)), this, SLOT(linkClicked(QString))); + ui->sourceGameEdit->addItem(organizerCore->managedGame()->gameName(), organizerCore->managedGame()->gameShortName()); if (organizerCore->managedGame()->validShortNames().size() == 0) { ui->sourceGameEdit->setDisabled(true); @@ -724,7 +727,7 @@ void ModInfoDialog::on_deactivateESP_clicked() void ModInfoDialog::on_visitNexusLabel_linkActivated(const QString &link) { - emit nexusLinkActivated(link); + emit linkActivated(link); } void ModInfoDialog::linkClicked(const QUrl &url) @@ -733,12 +736,17 @@ void ModInfoDialog::linkClicked(const QUrl &url) //and URL to the web service if (NexusInterface::instance(m_PluginContainer)->isURLGameRelated(url)) { - emit nexusLinkActivated(url.toString()); + emit linkActivated(url.toString()); } else { ::ShellExecuteW(nullptr, L"open", ToWString(url.toString()).c_str(), nullptr, nullptr, SW_SHOWNORMAL); } } +void ModInfoDialog::linkClicked(QString url) +{ + emit linkActivated(url); +} + void ModInfoDialog::refreshNexusData(int modID) { diff --git a/src/modinfodialog.h b/src/modinfodialog.h index 4709a1d2..f3bc48b4 100644 --- a/src/modinfodialog.h +++ b/src/modinfodialog.h @@ -109,7 +109,7 @@ public: signals: void thumbnailClickedSignal(const QString &filename); - void nexusLinkActivated(const QString &link); + void linkActivated(const QString &link); void downloadRequest(const QString &link); void modOpen(const QString &modName, int tab); void modOpenNext(int tab=-1); @@ -164,6 +164,7 @@ private slots: void thumbnailClicked(const QString &fileName); void linkClicked(const QUrl &url); + void linkClicked(QString url); void delete_activated(); diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui index 4352ba4e..de9fe5ed 100644 --- a/src/modinfodialog.ui +++ b/src/modinfodialog.ui @@ -238,8 +238,8 @@ 0 0 - 746 - 126 + 98 + 28 @@ -600,7 +600,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e - + Mod ID for this mod on Nexus. @@ -723,8 +723,8 @@ p, li { white-space: pre-wrap; } - - + + about:blank @@ -886,6 +886,11 @@ p, li { white-space: pre-wrap; } QWidget
QtWebEngineWidgets/QWebEngineView
+ + ModIDLineEdit + QLineEdit +
modidlineedit.h
+
diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index a514e1bf..045366ba 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -459,7 +459,7 @@ std::vector ModInfoRegular::getContents() const if (dir.exists(sePluginPath)) m_CachedContent.push_back(CONTENT_SKSE); } - if (dir.exists("textures")) + if (dir.exists("textures") || dir.exists("icons") || dir.exists("bookart")) m_CachedContent.push_back(CONTENT_TEXTURE); if (dir.exists("meshes")) m_CachedContent.push_back(CONTENT_MESH); -- cgit v1.3.1 From 001fddb069f35850b02ecac0d11f220461c70706 Mon Sep 17 00:00:00 2001 From: Al12rs Date: Sun, 22 Apr 2018 16:36:40 +0200 Subject: Changed the shortcut to open in explorer a mod to CTRL+Enter to avoid consuming the Enter key press so that people can still use it to finish renaming a mod. --- src/mainwindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6b176868..e737dd38 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -376,8 +376,8 @@ MainWindow::MainWindow(QSettings &initSettings connect(ui->espList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(esplistSelectionsChanged(QItemSelection))); connect(ui->modList->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(modlistSelectionsChanged(QItemSelection))); - new QShortcut(QKeySequence(Qt::Key_Enter), this, SLOT(openExplorer_activated())); - new QShortcut(QKeySequence(Qt::Key_Return), this, SLOT(openExplorer_activated())); + new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Enter), this, SLOT(openExplorer_activated())); + new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return), this, SLOT(openExplorer_activated())); new QShortcut(QKeySequence::Refresh, this, SLOT(refreshProfile_activated())); -- cgit v1.3.1 From 0306b0fc42ba1dbd76d86466ed045eab4e45186d Mon Sep 17 00:00:00 2001 From: Silarn Date: Sat, 28 Apr 2018 23:32:39 -0500 Subject: Change Nexus API URL --- src/browserdialog.cpp | 4 ++-- src/mainwindow.cpp | 2 +- src/nexusinterface.cpp | 2 +- src/nxmaccessmanager.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp index c2c65acc..e186ad63 100644 --- a/src/browserdialog.cpp +++ b/src/browserdialog.cpp @@ -173,13 +173,13 @@ void BrowserDialog::titleChanged(const QString &title) QString BrowserDialog::guessFileName(const QString &url) { - QRegExp uploadsExp(QString("http://.+/uploads/([^/]+)$")); + QRegExp uploadsExp(QString("https://.+/uploads/([^/]+)$")); if (uploadsExp.indexIn(url) != -1) { // these seem to be premium downloads return uploadsExp.cap(1); } - QRegExp filesExp(QString("http://.+\\?file=([^&]+)")); + QRegExp filesExp(QString("https://.+\\?file=([^&]+)")); if (filesExp.indexIn(url) != -1) { // a regular manual download? return filesExp.cap(1); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index e737dd38..6e244d49 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1905,7 +1905,7 @@ void MainWindow::wikiTriggered() void MainWindow::issueTriggered() { - QDesktopServices::openUrl(QUrl("http://github.com/Modorganizer2/modorganizer/issues")); + QDesktopServices::openUrl(QUrl("https://github.com/Modorganizer2/modorganizer/issues")); } void MainWindow::tutorialTriggered() diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index 45811658..8bf0de6e 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -645,7 +645,7 @@ void NexusInterface::managedGameChanged(IPluginGame const *game) namespace { QString get_management_url(MOBase::IPluginGame const *game) { - return "https://nmm.nexusmods.com/" + game->gameNexusName().toLower(); + return "https://legacy-api.nexusmods.com/" + game->gameNexusName().toLower(); } } diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 5b067d3c..05016e8f 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -42,7 +42,7 @@ along with Mod Organizer. If not, see . using namespace MOBase; namespace { - QString const Nexus_Management_URL("https://nmm.nexusmods.com"); + QString const Nexus_Management_URL("https://legacy-api.nexusmods.com"); } // unfortunately Nexus doesn't seem to document these states, all I know is all these listed -- cgit v1.3.1 From 2b7274380ea101e3d33e9177d7d8e06011cba6e7 Mon Sep 17 00:00:00 2001 From: Silarn Date: Tue, 1 May 2018 12:36:47 -0500 Subject: Release memory --- src/mainwindow.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6e244d49..3933987e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3545,6 +3545,7 @@ void MainWindow::deleteSavegame_clicked() } else { ISaveGame const *save = info->getSaveGameInfo(name); deleteFiles += save->allFiles(); + delete save; } } -- cgit v1.3.1 From 168da18aa51868ad3ac908affb55a8aabdba1aed Mon Sep 17 00:00:00 2001 From: Silarn Date: Wed, 2 May 2018 12:38:23 -0500 Subject: Fix MO endorsement check and add game to ModInfo s_ModsByModID --- src/downloadmanager.cpp | 8 ++++++++ src/downloadmanager.h | 8 ++++++++ src/mainwindow.cpp | 12 ++++++++++-- src/modinfo.cpp | 14 ++++++++------ src/modinfo.h | 4 ++-- src/organizercore.cpp | 3 ++- 6 files changed, 38 insertions(+), 11 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 097a1168..d9e86544 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -895,6 +895,14 @@ int DownloadManager::getModID(int index) const return m_ActiveDownloads.at(index)->m_FileInfo->modID; } +QString DownloadManager::getGameName(int index) const +{ + if ((index < 0) || (index >= m_ActiveDownloads.size())) { + throw MyException(tr("mod id: invalid download index %1").arg(index)); + } + return m_ActiveDownloads.at(index)->m_FileInfo->gameName; +} + bool DownloadManager::isHidden(int index) const { if ((index < 0) || (index >= m_ActiveDownloads.size())) { diff --git a/src/downloadmanager.h b/src/downloadmanager.h index 0ff77011..e1925040 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -288,6 +288,14 @@ public: **/ int getModID(int index) const; + /** + * @brief retrieve the game name of the downlaod specified by the index + * + * @param index index of the file to look up + * @return the game name + **/ + QString getGameName(int index) const; + /** * @brief determine if the specified file is supposed to be hidden * @param index index of the file to look up diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3933987e..a95b7b70 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4231,12 +4231,20 @@ void MainWindow::nxmUpdatesAvailable(const std::vector &modIDs, QVariant us QVariantList resultList = resultData.toList(); for (auto iter = resultList.begin(); iter != resultList.end(); ++iter) { QVariantMap result = iter->toMap(); - if (result["id"].toInt() == m_OrganizerCore.managedGame()->nexusModOrganizerID()) { + if (result["id"].toInt() == m_OrganizerCore.managedGame()->nexusModOrganizerID() + && result["game_id"].toInt() == m_OrganizerCore.managedGame()->nexusGameID()) { if (!result["voted_by_user"].toBool()) { ui->actionEndorseMO->setVisible(true); } } else { - std::vector info = ModInfo::getByModID(result["id"].toInt()); + QString gameName = m_OrganizerCore.managedGame()->gameShortName(); + for (IPluginGame *game : m_PluginContainer.plugins()) { + if (game->nexusGameID() == result["game_id"].toInt()) { + gameName = game->gameShortName(); + break; + } + } + std::vector info = ModInfo::getByModID(gameName, result["id"].toInt()); for (auto iter = info.begin(); iter != info.end(); ++iter) { (*iter)->setNewestVersion(result["version"].toString()); (*iter)->setNexusDescription(result["description"].toString()); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index d916d982..6b3fd528 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -48,7 +48,7 @@ using namespace MOShared; std::vector ModInfo::s_Collection; std::map ModInfo::s_ModsByName; -std::map > ModInfo::s_ModsByModID; +std::map, std::vector> ModInfo::s_ModsByModID; int ModInfo::s_NextID; QMutex ModInfo::s_Mutex(QMutex::Recursive); @@ -132,11 +132,11 @@ ModInfo::Ptr ModInfo::getByIndex(unsigned int index) } -std::vector ModInfo::getByModID(int modID) +std::vector ModInfo::getByModID(QString game, int modID) { QMutexLocker locker(&s_Mutex); - auto iter = s_ModsByModID.find(modID); + auto iter = s_ModsByModID.find(std::pair(game, modID)); if (iter == s_ModsByModID.end()) { return std::vector(); } @@ -161,11 +161,11 @@ bool ModInfo::removeMod(unsigned int index) ModInfo::Ptr modInfo = s_Collection[index]; s_ModsByName.erase(s_ModsByName.find(modInfo->name())); - auto iter = s_ModsByModID.find(modInfo->getNexusID()); + auto iter = s_ModsByModID.find(std::pair(modInfo->getGameName(), modInfo->getNexusID())); if (iter != s_ModsByModID.end()) { std::vector indices = iter->second; indices.erase(std::remove(indices.begin(), indices.end(), index), indices.end()); - s_ModsByModID[modInfo->getNexusID()] = indices; + s_ModsByModID[std::pair(modInfo->getGameName(), modInfo->getNexusID())] = indices; } // physically remove the mod directory @@ -255,9 +255,10 @@ void ModInfo::updateIndices() for (unsigned int i = 0; i < s_Collection.size(); ++i) { QString modName = s_Collection[i]->internalName(); + QString game = s_Collection[i]->getGameName(); int modID = s_Collection[i]->getNexusID(); s_ModsByName[modName] = i; - s_ModsByModID[modID].push_back(i); + s_ModsByModID[std::pair(game, modID)].push_back(i); } } @@ -289,6 +290,7 @@ int ModInfo::checkAllForUpdate(PluginContainer *pluginContainer, QObject *receiv IPluginGame const *game = qApp->property("managed_game").value(); modIDs.push_back(game->nexusModOrganizerID()); checkChunkForUpdate(pluginContainer, modIDs, receiver, game->gameShortName()); + modIDs.clear(); std::multimap> organizedGames; for (auto mod : s_Collection) { diff --git a/src/modinfo.h b/src/modinfo.h index 19be2ca2..7bb2bdad 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -148,7 +148,7 @@ public: * @todo in its current form, this function is broken! There may be multiple mods with the same nexus id, * this function will return only one of them **/ - static std::vector getByModID(int modID); + static std::vector getByModID(QString game, int modID); /** * @brief remove a mod by index @@ -638,7 +638,7 @@ protected: private: static QMutex s_Mutex; - static std::map > s_ModsByModID; + static std::map, std::vector > s_ModsByModID; static int s_NextID; bool m_Valid; diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 69c28c5c..4739021a 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -919,13 +919,14 @@ void OrganizerCore::installDownload(int index) { try { QString fileName = m_DownloadManager.getFilePath(index); + QString gameName = m_DownloadManager.getGameName(index); int modID = m_DownloadManager.getModID(index); int fileID = m_DownloadManager.getFileInfo(index)->fileID; GuessedValue modName; // see if there already are mods with the specified mod id if (modID != 0) { - std::vector modInfo = ModInfo::getByModID(modID); + std::vector modInfo = ModInfo::getByModID(gameName, modID); for (auto iter = modInfo.begin(); iter != modInfo.end(); ++iter) { std::vector flags = (*iter)->getFlags(); if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) -- cgit v1.3.1 From 9872c1e462d100221ca38aeb1f8ab35eda7fc8c2 Mon Sep 17 00:00:00 2001 From: Silarn Date: Thu, 3 May 2018 16:17:40 -0500 Subject: Allow for primary game sources and marking mods as converted/working --- src/mainwindow.cpp | 12 ++++++++++++ src/mainwindow.h | 1 + src/modinfo.cpp | 2 +- src/modinfo.h | 5 +++++ src/modinforegular.cpp | 22 +++++++++++++++++----- src/modinforegular.h | 7 +++++++ src/modlist.cpp | 2 +- 7 files changed, 44 insertions(+), 7 deletions(-) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a95b7b70..d3ea2b08 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2599,6 +2599,14 @@ void MainWindow::ignoreMissingData_clicked() emit modListDataChanged(m_OrganizerCore.modList()->index(m_ContextRow, 0), m_OrganizerCore.modList()->index(m_ContextRow, m_OrganizerCore.modList()->columnCount() - 1)); } +void MainWindow::markConverted_clicked() +{ + ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); + info->markConverted(true); + connect(this, SIGNAL(modListDataChanged(QModelIndex, QModelIndex)), m_OrganizerCore.modList(), SIGNAL(dataChanged(QModelIndex, QModelIndex))); + emit modListDataChanged(m_OrganizerCore.modList()->index(m_ContextRow, 0), m_OrganizerCore.modList()->index(m_ContextRow, m_OrganizerCore.modList()->columnCount() - 1)); +} + void MainWindow::visitOnNexus_clicked() { @@ -3463,6 +3471,10 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) menu->addAction(tr("Ignore missing data"), this, SLOT(ignoreMissingData_clicked())); } + if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_ALTERNATE_GAME) != flags.end()) { + menu->addAction(tr("Mark as converted/working"), this, SLOT(markConverted_clicked())); + } + if (info->getNexusID() > 0) { menu->addAction(tr("Visit on Nexus"), this, SLOT(visitOnNexus_clicked())); } else if ((info->getURL() != "")) { diff --git a/src/mainwindow.h b/src/mainwindow.h index 7f38d766..7af6d712 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -409,6 +409,7 @@ private slots: void dontendorse_clicked(); void unendorse_clicked(); void ignoreMissingData_clicked(); + void markConverted_clicked(); void visitOnNexus_clicked(); void visitWebPage_clicked(); void openExplorer_clicked(); diff --git a/src/modinfo.cpp b/src/modinfo.cpp index e505bacc..bd4c1254 100644 --- a/src/modinfo.cpp +++ b/src/modinfo.cpp @@ -414,4 +414,4 @@ void ModInfo::testValid() while (dirIter.hasNext()) { dirIter.next(); } -} +} \ No newline at end of file diff --git a/src/modinfo.h b/src/modinfo.h index 7bb2bdad..001a78dc 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -568,6 +568,11 @@ public: */ void testValid(); + /** + * @brief updates the mod to flag it as converted in order to ignore the alternate game warning + */ + virtual void markConverted(bool converted) {} + /** * @brief reads meta information from disk */ diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 49fc3aa2..c19294f1 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -30,6 +30,7 @@ ModInfoRegular::ModInfoRegular(PluginContainer *pluginContainer, const IPluginGa , m_Repository() , m_GameName(game->gameShortName()) , m_IsAlternate(false) + , m_Converted(false) , m_MetaInfoChanged(false) , m_EndorsedState(ENDORSED_UNKNOWN) , m_NexusBridge(pluginContainer) @@ -39,7 +40,8 @@ ModInfoRegular::ModInfoRegular(PluginContainer *pluginContainer, const IPluginGa // read out the meta-file for information readMeta(); if (m_GameName.compare(game->gameShortName(), Qt::CaseInsensitive) != 0) - m_IsAlternate = true; + if (!game->primarySources().contains(m_GameName, Qt::CaseInsensitive)) + m_IsAlternate = true; connect(&m_NexusBridge, SIGNAL(descriptionAvailable(QString,int,QVariant,QVariant)) , this, SLOT(nxmDescriptionAvailable(QString,int,QVariant,QVariant))); @@ -82,9 +84,10 @@ void ModInfoRegular::readMeta() m_IgnoredVersion = metaFile.value("ignoredVersion", "").toString(); m_InstallationFile = metaFile.value("installationFile", "").toString(); m_NexusDescription = metaFile.value("nexusDescription", "").toString(); - m_Repository = metaFile.value("repository", "Nexus").toString(); - m_URL = metaFile.value("url", "").toString(); - m_LastNexusQuery = QDateTime::fromString(metaFile.value("lastNexusQuery", "").toString(), Qt::ISODate); + m_Repository = metaFile.value("repository", "Nexus").toString(); + m_Converted = metaFile.value("converted", false).toBool(); + m_URL = metaFile.value("url", "").toString(); + m_LastNexusQuery = QDateTime::fromString(metaFile.value("lastNexusQuery", "").toString(), Qt::ISODate); if (metaFile.contains("endorsed")) { if (metaFile.value("endorsed").canConvert()) { switch (metaFile.value("endorsed").toInt()) { @@ -146,6 +149,7 @@ void ModInfoRegular::saveMeta() metaFile.setValue("nexusDescription", m_NexusDescription); metaFile.setValue("url", m_URL); metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate)); + metaFile.setValue("converted", m_Converted); if (m_EndorsedState != ENDORSED_UNKNOWN) { metaFile.setValue("endorsed", m_EndorsedState); } @@ -403,6 +407,14 @@ void ModInfoRegular::endorse(bool doEndorse) } } +void ModInfoRegular::markConverted(bool converted) +{ + m_Converted = converted; + m_MetaInfoChanged = true; + saveMeta(); + emit modDetailsUpdated(true); +} + QString ModInfoRegular::absolutePath() const { @@ -435,7 +447,7 @@ std::vector ModInfoRegular::getFlags() const if (m_PluginSelected) { result.push_back(ModInfo::FLAG_PLUGIN_SELECTED); } - if (m_IsAlternate) { + if (m_IsAlternate && !m_Converted) { result.push_back(ModInfo::FLAG_ALTERNATE_GAME); } return result; diff --git a/src/modinforegular.h b/src/modinforegular.h index c47f10c8..3abaded4 100644 --- a/src/modinforegular.h +++ b/src/modinforegular.h @@ -27,6 +27,7 @@ public: virtual bool isEmpty() const; bool isAlternate() { return m_IsAlternate; } + bool isConverted() { return m_Converted; } /** * @brief test if there is a newer version of the mod @@ -182,6 +183,11 @@ public: */ virtual void endorse(bool doEndorse); + /** + * @brief updates the mod to flag it as converted in order to ignore the alternate game warning + */ + virtual void markConverted(bool converted) override; + /** * @brief getter for the mod name * @@ -351,6 +357,7 @@ private: bool m_MetaInfoChanged; bool m_IsAlternate; + bool m_Converted; MOBase::VersionInfo m_NewestVersion; MOBase::VersionInfo m_IgnoredVersion; diff --git a/src/modlist.cpp b/src/modlist.cpp index aad88d1f..2d58081d 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -763,7 +763,7 @@ IModList::ModStates ModList::state(unsigned int modIndex) const } if (modInfo->isRegular()) { QSharedPointer modInfoRegular = modInfo.staticCast(); - if (modInfoRegular->isAlternate()) + if (modInfoRegular->isAlternate() && !modInfoRegular->isConverted()) result |= IModList::STATE_ALTERNATE; } if (modInfo->canBeEnabled()) { -- cgit v1.3.1 From 0eaa1c6791910ad54227e5d578c6570e6f68c046 Mon Sep 17 00:00:00 2001 From: Silarn Date: Thu, 3 May 2018 19:36:14 -0500 Subject: Add version check and update processor --- src/main.cpp | 1 + src/mainwindow.cpp | 24 ++++++++++++++++++++++++ src/mainwindow.h | 1 + 3 files changed, 26 insertions(+) (limited to 'src/mainwindow.cpp') diff --git a/src/main.cpp b/src/main.cpp index 2e496e0f..9c30a1c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -631,6 +631,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, QObject::connect(&instance, SIGNAL(messageSent(QString)), &organizer, SLOT(externalMessage(QString))); + mainWindow.processUpdates(); mainWindow.readSettings(); qDebug("displaying main window"); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d3ea2b08..2aaf7f59 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -148,6 +148,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include #include @@ -1665,6 +1666,29 @@ void MainWindow::readSettings() } } +void MainWindow::processUpdates() { + QSettings settings(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::iniFileName()), QSettings::IniFormat); + QVersionNumber lastVersion = QVersionNumber::fromString(settings.value("version", "2.1.2").toString()).normalized(); + QVersionNumber currentVersion = QVersionNumber::fromString(m_OrganizerCore.getVersion().displayString()).normalized(); + if (!m_OrganizerCore.settings().directInterface().value("first_start", true).toBool()) { + if (lastVersion < QVersionNumber(2, 1, 3)) { + bool lastHidden = true; + for (int i = ModList::COL_GAME; i < ui->modList->model()->columnCount(); ++i) { + bool hidden = ui->modList->header()->isSectionHidden(i); + ui->modList->header()->setSectionHidden(i, lastHidden); + lastHidden = hidden; + } + } + } + + if (currentVersion > lastVersion) + settings.setValue("version", currentVersion.toString()); + else if (currentVersion < lastVersion) + qWarning() << tr("Notice: Your current MO version (%1) is lower than the previous version (%2).
" + "The GUI may not downgrade gracefully, so you may experience oddities.
" + "However, there should be no serious issues.").arg(lastVersion.toString()).arg(currentVersion.toString()).toStdWString(); +} + void MainWindow::storeSettings(QSettings &settings) { settings.setValue("group_state", ui->groupCombo->currentIndex()); diff --git a/src/mainwindow.h b/src/mainwindow.h index 7af6d712..bbff0d93 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -116,6 +116,7 @@ public: void storeSettings(QSettings &settings) override; void readSettings(); + void processUpdates(); virtual ILockedWaitingForProcess* lock() override; virtual void unlock() override; -- cgit v1.3.1 From 54e219759283c4805f40c03d2215831081f55d51 Mon Sep 17 00:00:00 2001 From: Silarn Date: Fri, 4 May 2018 11:35:44 -0500 Subject: Allow update processor to include the managed game if nexus info matches --- src/mainwindow.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/mainwindow.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2aaf7f59..2830c776 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -4274,13 +4274,21 @@ void MainWindow::nxmUpdatesAvailable(const std::vector &modIDs, QVariant us } } else { QString gameName = m_OrganizerCore.managedGame()->gameShortName(); + bool sameNexus = false; for (IPluginGame *game : m_PluginContainer.plugins()) { if (game->nexusGameID() == result["game_id"].toInt()) { gameName = game->gameShortName(); + if (game->nexusGameID() == m_OrganizerCore.managedGame()->nexusGameID()) + sameNexus = true; break; } } std::vector info = ModInfo::getByModID(gameName, result["id"].toInt()); + if (sameNexus) { + std::vector mainInfo = ModInfo::getByModID(m_OrganizerCore.managedGame()->gameShortName(), result["id"].toInt()); + info.reserve(info.size() + mainInfo.size()); + info.insert(info.end(), mainInfo.begin(), mainInfo.end()); + } for (auto iter = info.begin(); iter != info.end(); ++iter) { (*iter)->setNewestVersion(result["version"].toString()); (*iter)->setNexusDescription(result["description"].toString()); -- cgit v1.3.1