diff --git a/src/commandline.cpp b/src/commandline.cpp index aaa31c8af..3aa4b1ca2 100644 --- a/src/commandline.cpp +++ b/src/commandline.cpp @@ -853,6 +853,18 @@ Command::Meta DownloadFileCommand::meta() const return {"download", "downloads a file", "URL", ""}; } +po::options_description DownloadFileCommand::getVisibleOptions() const +{ + po::options_description d; + + d.add_options()("name,n", po::value(), "(optional) the download name")( + "modname,m", po::value(), "(optional) the mod name")( + "version,v", po::value(), "(optional) the download / mod version")( + "source,s", po::value(), "(optional) the download source"); + + return d; +} + po::options_description DownloadFileCommand::getInternalOptions() const { po::options_description d; @@ -879,16 +891,33 @@ bool DownloadFileCommand::canForwardToPrimary() const std::optional DownloadFileCommand::runPostOrganizer(OrganizerCore& core) { const QString url = QString::fromStdString(vm()["URL"].as()); + QString name, modName, version, source; if (!url.startsWith("https://")) { reportError(QObject::tr("Download URL must start with https://")); return 1; } + if (vm().count("name")) { + name = QString::fromStdString(vm()["name"].as()); + } + + if (vm().count("modname")) { + modName = QString::fromStdString(vm()["modname"].as()); + } + + if (vm().count("version")) { + version = QString::fromStdString(vm()["version"].as()); + } + + if (vm().count("source")) { + source = QString::fromStdString(vm()["source"].as()); + } + log::debug("starting direct download from command line: {}", url.toStdString()); MessageDialog::showMessage(QObject::tr("Download started"), qApp->activeWindow(), false); - core.downloadManager()->startDownloadURLs(QStringList() << url); + core.downloadManager()->startDownloadURLWithMeta(url, name, modName, version, source); return {}; } diff --git a/src/commandline.h b/src/commandline.h index 3d7821054..c67a0716f 100644 --- a/src/commandline.h +++ b/src/commandline.h @@ -212,6 +212,7 @@ class DownloadFileCommand : public Command protected: Meta meta() const override; + po::options_description getVisibleOptions() const override; po::options_description getInternalOptions() const override; po::positional_options_description getPositional() const override; diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index ce6ba665d..c4146f4fe 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -1978,6 +1978,22 @@ int DownloadManager::startDownloadURLs(const QStringList& urls) return m_ActiveDownloads.size() - 1; } +int DownloadManager::startDownloadURLWithMeta(const QString& url, const QString& name, + const QString& modName, + const QString& version, + const QString& source) +{ + ModRepositoryFileInfo info; + info.name = name; + info.modName = modName; + info.version = version; + info.repository = source; + if (!addDownload(QStringList(url), "", -1, -1, &info)) { + return 0; + } + return m_ActiveDownloads.size() - 1; +} + int DownloadManager::startDownloadNexusFile(const QString& gameName, int modID, int fileID) { diff --git a/src/downloadmanager.h b/src/downloadmanager.h index abf909c86..ad93b87d2 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -410,6 +410,9 @@ class DownloadManager : public QObject public: // IDownloadManager interface: int startDownloadURLs(const QStringList& urls); + int startDownloadURLWithMeta(const QString& url, const QString& name, + const QString& modName, const QString& version, + const QString& source); int startDownloadNexusFile(const QString& gameName, int modID, int fileID); QString downloadPath(int id); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a651c2d7f..0bc7edf8d 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1356,7 +1356,7 @@ void MainWindow::showEvent(QShowEvent* event) m_OrganizerCore.settings().widgets().restoreIndex(ui->groupCombo); - m_OrganizerCore.settings().nexus().registerAsNXMHandler(false); + m_OrganizerCore.settings().registerDownloadHandlers(false); m_WasVisible = true; updateProblemsButton(); diff --git a/src/settings.cpp b/src/settings.cpp index ef1785b16..4f4845909 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -417,6 +417,35 @@ void Settings::setKeepBackupOnInstall(bool b) set(m_Settings, "General", "backup_install", b); } +void Settings::registerDownloadHandlers(bool force) +{ + m_Nexus.registerAsNXMHandler(force); + registerAsMODLHandler(force); +} + +void Settings::registerAsMODLHandler(bool force) +{ + const auto nxmPath = QCoreApplication::applicationDirPath() + "/" + + QString::fromStdWString(AppConfig::nxmHandlerExe()); + + const auto executable = QCoreApplication::applicationFilePath(); + + QString mode = force ? "forcereg" : "reg"; + QString parameters = mode + " modl " + m_Game.plugin()->gameShortName(); + for (const QString& altGame : m_Game.plugin()->validShortNames()) { + parameters += "," + altGame; + } + parameters += + " \"" + executable + "\" \"-n %name% -m %modname% -v %version% -s %source%\""; + + const auto r = shell::Execute(nxmPath, parameters); + if (!r.success()) { + QMessageBox::critical( + nullptr, QObject::tr("Failed"), + QObject::tr("Failed to start the helper application: %1").arg(r.toString())); + } +} + GameSettings& Settings::game() { return m_Game; @@ -1992,14 +2021,13 @@ void NexusSettings::registerAsNXMHandler(bool force) const auto executable = QCoreApplication::applicationFilePath(); QString mode = force ? "forcereg" : "reg"; - QString parameters = mode + " " + m_Parent.game().plugin()->gameShortName(); + QString parameters = mode + " nxm " + m_Parent.game().plugin()->gameShortName(); for (const QString& altGame : m_Parent.game().plugin()->validShortNames()) { parameters += "," + altGame; } parameters += " \"" + executable + "\""; const auto r = shell::Execute(nxmPath, parameters); - if (!r.success()) { QMessageBox::critical( nullptr, QObject::tr("Failed"), diff --git a/src/settings.h b/src/settings.h index edc1d6445..b4185e869 100644 --- a/src/settings.h +++ b/src/settings.h @@ -809,6 +809,20 @@ class Settings : public QObject unsigned int motdHash() const; void setMotdHash(unsigned int hash); + // registers MO as the handler for download links + // + // if 'force' is true, the registration dialog will be shown even if the user + // said earlier not to + // + void registerDownloadHandlers(bool force); + + // registers MO as the handler for modl links + // + // if 'force' is true, the registration dialog will be shown even if the user + // said earlier not to + // + void registerAsMODLHandler(bool force); + // whether archives should be parsed to show conflicts and contents // bool archiveParsing() const; diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui index 6011b1588..983d25a46 100644 --- a/src/settingsdialog.ui +++ b/src/settingsdialog.ui @@ -31,10 +31,10 @@ #generalScrollAreaWidgetContents { background-color: transparent; } - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain true @@ -85,7 +85,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -166,6 +166,19 @@ + + + + + 300 + 16777215 + + + + Associate MODL Download Links + + + @@ -348,7 +361,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -364,7 +377,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -391,7 +404,7 @@ Style - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -414,7 +427,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -438,16 +451,16 @@ - QAbstractItemView::NoEditTriggers + QAbstractItemView::EditTrigger::NoEditTriggers - QAbstractItemView::SingleSelection + QAbstractItemView::SelectionMode::SingleSelection - QAbstractItemView::SelectRows + QAbstractItemView::SelectionBehavior::SelectRows - QAbstractItemView::ScrollPerPixel + QAbstractItemView::ScrollMode::ScrollPerPixel false @@ -610,10 +623,10 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Fixed + QSizePolicy::Policy::Fixed @@ -771,7 +784,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Horizontal + Qt::Orientation::Horizontal @@ -805,7 +818,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Vertical + Qt::Orientation::Vertical @@ -895,7 +908,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Vertical + Qt::Orientation::Vertical @@ -965,7 +978,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Vertical + Qt::Orientation::Vertical @@ -1008,7 +1021,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Vertical + Qt::Orientation::Vertical @@ -1039,10 +1052,10 @@ If you disable this feature, MO will only display official DLCs this way. Please #nexusScrollAreaWidgetContents { background-color: transparent; } - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain true @@ -1089,7 +1102,7 @@ If you disable this feature, MO will only display official DLCs this way. Please User ID: - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByKeyboard|Qt::TextInteractionFlag::TextSelectableByMouse @@ -1228,7 +1241,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Vertical + Qt::Orientation::Vertical @@ -1259,7 +1272,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - QAbstractScrollArea::AdjustToContents + QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents @@ -1437,10 +1450,10 @@ If you disable this feature, MO will only display official DLCs this way. Please - QAbstractItemView::DragDrop + QAbstractItemView::DragDropMode::DragDrop - Qt::MoveAction + Qt::DropAction::MoveAction @@ -1458,10 +1471,10 @@ If you disable this feature, MO will only display official DLCs this way. Please - QAbstractItemView::DragDrop + QAbstractItemView::DragDropMode::DragDrop - Qt::MoveAction + Qt::DropAction::MoveAction @@ -1484,7 +1497,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Vertical + Qt::Orientation::Vertical @@ -1515,7 +1528,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1571,7 +1584,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop 6 @@ -1582,7 +1595,7 @@ If you disable this feature, MO will only display official DLCs this way. Please Author: - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -1592,7 +1605,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -1602,7 +1615,7 @@ If you disable this feature, MO will only display official DLCs this way. Please Version: - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -1612,7 +1625,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -1622,7 +1635,7 @@ If you disable this feature, MO will only display official DLCs this way. Please Description: - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -1632,7 +1645,7 @@ If you disable this feature, MO will only display official DLCs this way. Please - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop true @@ -1687,7 +1700,7 @@ If you disable this feature, MO will only display official DLCs this way. Please No plugin found. - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter @@ -1729,10 +1742,10 @@ If you disable this feature, MO will only display official DLCs this way. Please #workaroundScrollAreaWidgetContents { background-color: transparent; } - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain true @@ -1851,7 +1864,7 @@ Uncheck this if you want to use Mod Organizer with total conversions (like Nehri - QLineEdit::Password + QLineEdit::EchoMode::Password @@ -2125,7 +2138,7 @@ programs you are intentionally running. - Qt::Horizontal + Qt::Orientation::Horizontal @@ -2141,7 +2154,7 @@ programs you are intentionally running. - Qt::Vertical + Qt::Orientation::Vertical @@ -2182,7 +2195,7 @@ programs you are intentionally running. - QFormLayout::FieldsStayAtSizeHint + QFormLayout::FieldGrowthPolicy::FieldsStayAtSizeHint @@ -2257,7 +2270,7 @@ programs you are intentionally running. - QFormLayout::FieldsStayAtSizeHint + QFormLayout::FieldGrowthPolicy::FieldsStayAtSizeHint @@ -2296,10 +2309,10 @@ programs you are intentionally running. - Qt::Vertical + Qt::Orientation::Vertical - QSizePolicy::Expanding + QSizePolicy::Policy::Expanding @@ -2316,10 +2329,10 @@ programs you are intentionally running. - Qt::Horizontal + Qt::Orientation::Horizontal - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index 265c9db90..374eb6210 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -21,6 +21,11 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) ui->hideDownloadInstallBox->setChecked( settings().interface().hideDownloadsAfterInstallation()); + // connect MODL button + QObject::connect(ui->associateModlButton, &QPushButton::clicked, [&] { + Settings::instance().registerAsMODLHandler(true); + }); + // updates ui->checkForUpdates->setChecked(settings().checkForUpdates()); ui->usePrereleaseBox->setChecked(settings().usePrereleases()); diff --git a/src/settingsdialognexus.cpp b/src/settingsdialognexus.cpp index abd487f14..29873d236 100644 --- a/src/settingsdialognexus.cpp +++ b/src/settingsdialognexus.cpp @@ -343,7 +343,7 @@ NexusSettingsTab::NexusSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab clearCache(); }); QObject::connect(ui->associateButton, &QPushButton::clicked, [&] { - associate(); + Settings::instance().nexus().registerAsNXMHandler(true); }); QObject::connect(ui->useCustomBrowser, &QCheckBox::clicked, [&] { updateCustomBrowser(); @@ -417,11 +417,6 @@ void NexusSettingsTab::clearCache() NexusInterface::instance().clearCache(); } -void NexusSettingsTab::associate() -{ - Settings::instance().nexus().registerAsNXMHandler(true); -} - void NexusSettingsTab::updateNexusData() { const auto user = NexusInterface::instance().getAPIUserAccount(); diff --git a/src/settingsdialognexus.h b/src/settingsdialognexus.h index 41ab207a4..0c14ebf70 100644 --- a/src/settingsdialognexus.h +++ b/src/settingsdialognexus.h @@ -60,7 +60,6 @@ class NexusSettingsTab : public SettingsTab std::unique_ptr m_connectionUI; void clearCache(); - void associate(); void updateNexusData(); void updateCustomBrowser();