From f0b909f77267674bf40d8a8621a36a0de7251b0f Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Mon, 26 Sep 2022 16:37:31 +0300 Subject: [PATCH 01/10] code improvement --- client/lobby/CSavingScreen.cpp | 4 --- client/lobby/CSavingScreen.h | 1 - client/windows/GUIClasses.cpp | 7 ++--- launcher/jsonutils.cpp | 30 +++++++-------------- launcher/modManager/cmodmanager.cpp | 4 +-- launcher/settingsView/csettingsview_moc.cpp | 28 +++++++++---------- 6 files changed, 29 insertions(+), 45 deletions(-) diff --git a/client/lobby/CSavingScreen.cpp b/client/lobby/CSavingScreen.cpp index 7632ac691..06071c533 100644 --- a/client/lobby/CSavingScreen.cpp +++ b/client/lobby/CSavingScreen.cpp @@ -44,10 +44,6 @@ CSavingScreen::CSavingScreen() buttonStart->assignedKeys.insert(SDLK_RETURN); } -CSavingScreen::~CSavingScreen() -{ -} - const CMapInfo * CSavingScreen::getMapInfo() { return localMi.get(); diff --git a/client/lobby/CSavingScreen.h b/client/lobby/CSavingScreen.h index ac966a457..b7ac05012 100644 --- a/client/lobby/CSavingScreen.h +++ b/client/lobby/CSavingScreen.h @@ -27,7 +27,6 @@ public: std::shared_ptr localMi; CSavingScreen(); - ~CSavingScreen(); void changeSelection(std::shared_ptr to); void saveGame(); diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 2afd8c033..33372b30b 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -562,10 +562,11 @@ void CSystemOptionsWindow::selectGameRes() std::vector items; const JsonNode & texts = CGI->generaltexth->localizedTexts["systemOptions"]["resolutionMenu"]; - for( config::CConfigHandler::GuiOptionsMap::value_type& value : conf.guiOptions) + for(const auto & it : conf.guiOptions) { - std::string resX = boost::lexical_cast(value.first.first); - std::string resY = boost::lexical_cast(value.first.second); + const auto & resolution = it.first; + std::string resX = boost::lexical_cast(resolution.first); + std::string resY = boost::lexical_cast(resolution.second); items.push_back(resX + 'x' + resY); } diff --git a/launcher/jsonutils.cpp b/launcher/jsonutils.cpp index ccf7bd629..fa19739db 100644 --- a/launcher/jsonutils.cpp +++ b/launcher/jsonutils.cpp @@ -16,7 +16,7 @@ static QVariantMap JsonToMap(const JsonMap & json) QVariantMap map; for(auto & entry : json) { - map.insert(QString::fromUtf8(entry.first.c_str()), JsonUtils::toVariant(entry.second)); + map.insert(QString::fromStdString(entry.first), JsonUtils::toVariant(entry.second)); } return map; } @@ -60,22 +60,16 @@ QVariant toVariant(const JsonNode & node) { switch(node.getType()) { - break; case JsonNode::JsonType::DATA_NULL: return QVariant(); - break; case JsonNode::JsonType::DATA_BOOL: return QVariant(node.Bool()); - break; case JsonNode::JsonType::DATA_FLOAT: return QVariant(node.Float()); - break; case JsonNode::JsonType::DATA_STRING: - return QVariant(QString::fromUtf8(node.String().c_str())); - break; + return QVariant(QString::fromStdString(node.String())); case JsonNode::JsonType::DATA_VECTOR: return JsonToList(node.Vector()); - break; case JsonNode::JsonType::DATA_STRUCT: return JsonToMap(node.Struct()); } @@ -85,19 +79,15 @@ QVariant toVariant(const JsonNode & node) QVariant JsonFromFile(QString filename) { QFile file(filename); - file.open(QFile::ReadOnly); - auto data = file.readAll(); + if(!file.open(QFile::ReadOnly)) + { + logGlobal->error("Failed to open file %s. Reason: %s", qUtf8Printable(filename), qUtf8Printable(file.errorString())); + return {}; + } - if(data.size() == 0) - { - logGlobal->error("Failed to open file %s", filename.toUtf8().data()); - return QVariant(); - } - else - { - JsonNode node(data.data(), data.size()); - return toVariant(node); - } + const auto data = file.readAll(); + JsonNode node(data.data(), data.size()); + return toVariant(node); } JsonNode toJson(QVariant object) diff --git a/launcher/modManager/cmodmanager.cpp b/launcher/modManager/cmodmanager.cpp index eea55af17..f5cb03627 100644 --- a/launcher/modManager/cmodmanager.cpp +++ b/launcher/modManager/cmodmanager.cpp @@ -291,7 +291,7 @@ bool CModManager::doInstallMod(QString modname, QString archivePath) bool CModManager::doUninstallMod(QString modname) { - ResourceID resID(std::string("Mods/") + modname.toUtf8().data(), EResType::DIRECTORY); + ResourceID resID(std::string("Mods/") + modname.toStdString(), EResType::DIRECTORY); // Get location of the mod, in case-insensitive way QString modDir = pathToQString(*CResourceHandler::get()->getResourceName(resID)); @@ -300,7 +300,7 @@ bool CModManager::doUninstallMod(QString modname) QDir modFullDir(modDir); if(!removeModDir(modDir)) - return addError(modname, "Mod is located in protected directory, plase remove it manually:\n" + modFullDir.absolutePath()); + return addError(modname, "Mod is located in protected directory, please remove it manually:\n" + modFullDir.absolutePath()); CResourceHandler::get("initial")->updateFilteredFiles([](const std::string &){ return true; }); loadMods(); diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 95c2a872a..58c71d378 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -19,6 +19,14 @@ #include "../../lib/CConfigHandler.h" #include "../../lib/VCMIDirs.h" +namespace +{ +QString resolutionToString(const QSize & resolution) +{ + return QString{"%1x%2"}.arg(resolution.width()).arg(resolution.height()); +} +} + /// List of encoding which can be selected from Launcher. /// Note that it is possible to specify enconding manually in settings.json static const std::string knownEncodingsList[] = //TODO: remove hardcode @@ -39,12 +47,7 @@ void CSettingsView::setDisplayList() QStringList list; for (const auto screen : QGuiApplication::screens()) - { - QString string; - const auto & rect = screen->geometry(); - QTextStream(&string) << screen->name() << " - " << rect.width() << "x" << rect.height(); - list << string; - } + list << QString{"%1 - %2"}.arg(screen->name(), resolutionToString(screen->size())); if(list.count() < 2) { @@ -79,15 +82,10 @@ void CSettingsView::loadSettings() ui->checkBoxFullScreen->setChecked(settings["video"]["realFullscreen"].Bool()); #endif - int friendlyAIIndex = ui->comboBoxFriendlyAI->findText(QString::fromUtf8(settings["server"]["friendlyAI"].String().c_str())); - int neutralAIIndex = ui->comboBoxNeutralAI->findText(QString::fromUtf8(settings["server"]["neutralAI"].String().c_str())); - int enemyAIIndex = ui->comboBoxEnemyAI->findText(QString::fromUtf8(settings["server"]["enemyAI"].String().c_str())); - int playerAIIndex = ui->comboBoxPlayerAI->findText(QString::fromUtf8(settings["server"]["playerAI"].String().c_str())); - - ui->comboBoxFriendlyAI->setCurrentIndex(friendlyAIIndex); - ui->comboBoxNeutralAI->setCurrentIndex(neutralAIIndex); - ui->comboBoxEnemyAI->setCurrentIndex(enemyAIIndex); - ui->comboBoxPlayerAI->setCurrentIndex(playerAIIndex); + ui->comboBoxFriendlyAI->setCurrentText(QString::fromStdString(settings["server"]["friendlyAI"].String())); + ui->comboBoxNeutralAI->setCurrentText(QString::fromStdString(settings["server"]["neutralAI"].String())); + ui->comboBoxEnemyAI->setCurrentText(QString::fromStdString(settings["server"]["enemyAI"].String())); + ui->comboBoxPlayerAI->setCurrentText(QString::fromStdString(settings["server"]["playerAI"].String())); ui->spinBoxNetworkPort->setValue(settings["server"]["port"].Integer()); From cfba8a537356f66028194c40a611b0a08ca8666c Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Mon, 26 Sep 2022 16:39:10 +0300 Subject: [PATCH 02/10] replace deprecated signal --- launcher/settingsView/csettingsview_moc.cpp | 2 +- launcher/settingsView/csettingsview_moc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 58c71d378..75a4f382d 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -122,7 +122,7 @@ CSettingsView::~CSettingsView() } -void CSettingsView::on_comboBoxResolution_currentIndexChanged(const QString & arg1) +void CSettingsView::on_comboBoxResolution_currentTextChanged(const QString & arg1) { QStringList list = arg1.split("x"); diff --git a/launcher/settingsView/csettingsview_moc.h b/launcher/settingsView/csettingsview_moc.h index b2084a78a..56d4cc834 100644 --- a/launcher/settingsView/csettingsview_moc.h +++ b/launcher/settingsView/csettingsview_moc.h @@ -29,7 +29,7 @@ public: private slots: void on_checkBoxFullScreen_stateChanged(int state); - void on_comboBoxResolution_currentIndexChanged(const QString & arg1); + void on_comboBoxResolution_currentTextChanged(const QString & arg1); void on_comboBoxFullScreen_currentIndexChanged(int index); From 36cbb2f6057e671e602b5298d6cee1dd4a016e67 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Mon, 26 Sep 2022 16:44:02 +0300 Subject: [PATCH 03/10] make Display Index combobox empty by default --- launcher/settingsView/csettingsview_moc.cpp | 1 - launcher/settingsView/csettingsview_moc.ui | 8 +------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 75a4f382d..234980242 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -57,7 +57,6 @@ void CSettingsView::setDisplayList() else { int displayIndex = settings["video"]["displayIndex"].Integer(); - ui->comboBoxDisplayIndex->clear(); ui->comboBoxDisplayIndex->addItems(list); ui->comboBoxDisplayIndex->setCurrentIndex(displayIndex); } diff --git a/launcher/settingsView/csettingsview_moc.ui b/launcher/settingsView/csettingsview_moc.ui index ece3135b5..cf5b3135d 100644 --- a/launcher/settingsView/csettingsview_moc.ui +++ b/launcher/settingsView/csettingsview_moc.ui @@ -417,13 +417,7 @@ - - - - 0 - - - + From 9aad1ae95e34f48eee1cd3eaf140a1af43dd0744 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Mon, 26 Sep 2022 16:38:37 +0300 Subject: [PATCH 04/10] handle integer type in vcmi <-> Qt JSON interoperability --- launcher/jsonutils.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/launcher/jsonutils.cpp b/launcher/jsonutils.cpp index fa19739db..9b144cb8a 100644 --- a/launcher/jsonutils.cpp +++ b/launcher/jsonutils.cpp @@ -66,6 +66,8 @@ QVariant toVariant(const JsonNode & node) return QVariant(node.Bool()); case JsonNode::JsonType::DATA_FLOAT: return QVariant(node.Float()); + case JsonNode::JsonType::DATA_INTEGER: + return QVariant{static_cast(node.Integer())}; case JsonNode::JsonType::DATA_STRING: return QVariant(QString::fromStdString(node.String())); case JsonNode::JsonType::DATA_VECTOR: @@ -102,6 +104,8 @@ JsonNode toJson(QVariant object) ret.String() = object.toString().toUtf8().data(); else if(object.userType() == QMetaType::Bool) ret.Bool() = object.toBool(); + else if(object.canConvert()) + ret.Integer() = object.toInt(); else if(object.canConvert()) ret.Float() = object.toFloat(); From 6e6bf1e77b1e205a7d43961faf175e3cf9a82474 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Mon, 26 Sep 2022 16:39:30 +0300 Subject: [PATCH 05/10] don't list resolutions larger than the current screen's in the game options --- client/windows/GUIClasses.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 33372b30b..302c61a0a 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -562,9 +562,15 @@ void CSystemOptionsWindow::selectGameRes() std::vector items; const JsonNode & texts = CGI->generaltexth->localizedTexts["systemOptions"]["resolutionMenu"]; + SDL_Rect displayBounds; + SDL_GetDisplayBounds(std::max(0, SDL_GetWindowDisplayIndex(mainWindow)), &displayBounds); + for(const auto & it : conf.guiOptions) { const auto & resolution = it.first; + if(displayBounds.w < resolution.first || displayBounds.h < resolution.second) + continue; + std::string resX = boost::lexical_cast(resolution.first); std::string resY = boost::lexical_cast(resolution.second); items.push_back(resX + 'x' + resY); From 063f80fac3785abf90568344ddac9c657b5c7bad Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Mon, 26 Sep 2022 16:58:27 +0300 Subject: [PATCH 06/10] don't list resolutions larger than the selected screen's in the launcher --- launcher/settingsView/csettingsview_moc.cpp | 59 ++++++++++++++-- launcher/settingsView/csettingsview_moc.h | 2 + launcher/settingsView/csettingsview_moc.ui | 76 +-------------------- 3 files changed, 57 insertions(+), 80 deletions(-) diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 234980242..46ee67fc3 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -11,6 +11,8 @@ #include "csettingsview_moc.h" #include "ui_csettingsview_moc.h" +#include "../jsonutils.h" +#include "../launcherdirs.h" #include "../updatedialog_moc.h" #include @@ -53,22 +55,19 @@ void CSettingsView::setDisplayList() { ui->comboBoxDisplayIndex->hide(); ui->labelDisplayIndex->hide(); + fillValidResolutionsForScreen(0); } else { int displayIndex = settings["video"]["displayIndex"].Integer(); ui->comboBoxDisplayIndex->addItems(list); + // calls fillValidResolutions() in slot ui->comboBoxDisplayIndex->setCurrentIndex(displayIndex); } } void CSettingsView::loadSettings() { - int resX = settings["video"]["screenRes"]["width"].Float(); - int resY = settings["video"]["screenRes"]["height"].Float(); - int resIndex = ui->comboBoxResolution->findText(QString("%1x%2").arg(resX).arg(resY)); - - ui->comboBoxResolution->setCurrentIndex(resIndex); ui->comboBoxShowIntro->setCurrentIndex(settings["video"]["showIntro"].Bool()); #ifdef Q_OS_IOS @@ -107,6 +106,54 @@ void CSettingsView::loadSettings() ui->comboBoxAutoSave->setCurrentIndex(settings["general"]["saveFrequency"].Integer() > 0 ? 1 : 0); } +void CSettingsView::fillValidResolutionsForScreen(int screenIndex) +{ + ui->comboBoxResolution->blockSignals(true); // avoid saving wrong resolution after adding first item from the list + ui->comboBoxResolution->clear(); + + // TODO: read available resolutions from all mods + const QLatin1String extrasResolutionsPath{"/vcmi-extras/Mods/extraResolutions/Content/config/resolutions.json"}; + const auto extrasResolutionsJson = JsonUtils::JsonFromFile(CLauncherDirs::get().modsPath() + extrasResolutionsPath); + const auto resolutions = extrasResolutionsJson.toMap().value(QLatin1String{"GUISettings"}).toList(); + if(resolutions.isEmpty()) + { + ui->comboBoxResolution->blockSignals(false); + ui->comboBoxResolution->addItem(resolutionToString({800, 600})); + return; + } + + const auto screens = qGuiApp->screens(); + const auto currentScreen = screenIndex < screens.size() ? screens[screenIndex] : qGuiApp->primaryScreen(); + const auto screenSize = currentScreen->size(); + for(const auto & entry : resolutions) + { + const auto resolutionMap = entry.toMap().value(QLatin1String{"resolution"}).toMap(); + if(resolutionMap.isEmpty()) + continue; + + const auto widthValue = resolutionMap[QLatin1String{"x"}]; + const auto heightValue = resolutionMap[QLatin1String{"y"}]; + if(!widthValue.isValid() || !heightValue.isValid()) + continue; + + const QSize resolution{widthValue.toInt(), heightValue.toInt()}; + if(screenSize.width() < resolution.width() || screenSize.height() < resolution.height()) + continue; + ui->comboBoxResolution->addItem(resolutionToString(resolution)); + } + + int resX = settings["video"]["screenRes"]["width"].Integer(); + int resY = settings["video"]["screenRes"]["height"].Integer(); + int resIndex = ui->comboBoxResolution->findText(resolutionToString({resX, resY})); + ui->comboBoxResolution->setCurrentIndex(resIndex); + + ui->comboBoxResolution->blockSignals(false); + + // if selected resolution no longer exists, force update value to the first resolution + if(resIndex == -1) + ui->comboBoxResolution->setCurrentIndex(0); +} + CSettingsView::CSettingsView(QWidget * parent) : QWidget(parent), ui(new Ui::CSettingsView) { @@ -152,6 +199,8 @@ void CSettingsView::on_comboBoxDisplayIndex_currentIndexChanged(int index) { Settings node = settings.write["video"]; node["displayIndex"].Float() = index; + + fillValidResolutionsForScreen(index); } void CSettingsView::on_comboBoxPlayerAI_currentIndexChanged(const QString & arg1) diff --git a/launcher/settingsView/csettingsview_moc.h b/launcher/settingsView/csettingsview_moc.h index 56d4cc834..92a349057 100644 --- a/launcher/settingsView/csettingsview_moc.h +++ b/launcher/settingsView/csettingsview_moc.h @@ -67,4 +67,6 @@ private slots: private: Ui::CSettingsView * ui; + + void fillValidResolutionsForScreen(int screenIndex); }; diff --git a/launcher/settingsView/csettingsview_moc.ui b/launcher/settingsView/csettingsview_moc.ui index cf5b3135d..a9e05775d 100644 --- a/launcher/settingsView/csettingsview_moc.ui +++ b/launcher/settingsView/csettingsview_moc.ui @@ -333,81 +333,7 @@ - - - 11 - - - - 800x600 - - - - - 1024x600 - - - - - 1024x768 - - - - - 1181x664 - - - - - 1280x720 - - - - - 1280x768 - - - - - 1280x800 - - - - - 1280x960 - - - - - 1280x1024 - - - - - 1366x768 - - - - - 1440x900 - - - - - 1600x1200 - - - - - 1680x1050 - - - - - 1920x1080 - - - + From 76b36b8951de8cbcf5a0ead05d08317c69d9fb5c Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Mon, 26 Sep 2022 16:59:59 +0300 Subject: [PATCH 07/10] iOS can use any resolution --- client/windows/GUIClasses.cpp | 4 ++++ launcher/settingsView/csettingsview_moc.cpp | 2 ++ 2 files changed, 6 insertions(+) diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index 302c61a0a..445145bb6 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -562,14 +562,18 @@ void CSystemOptionsWindow::selectGameRes() std::vector items; const JsonNode & texts = CGI->generaltexth->localizedTexts["systemOptions"]["resolutionMenu"]; +#ifndef VCMI_IOS SDL_Rect displayBounds; SDL_GetDisplayBounds(std::max(0, SDL_GetWindowDisplayIndex(mainWindow)), &displayBounds); +#endif for(const auto & it : conf.guiOptions) { const auto & resolution = it.first; +#ifndef VCMI_IOS if(displayBounds.w < resolution.first || displayBounds.h < resolution.second) continue; +#endif std::string resX = boost::lexical_cast(resolution.first); std::string resY = boost::lexical_cast(resolution.second); diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index 46ee67fc3..cfdfd312a 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -137,8 +137,10 @@ void CSettingsView::fillValidResolutionsForScreen(int screenIndex) continue; const QSize resolution{widthValue.toInt(), heightValue.toInt()}; +#ifndef VCMI_IOS if(screenSize.width() < resolution.width() || screenSize.height() < resolution.height()) continue; +#endif ui->comboBoxResolution->addItem(resolutionToString(resolution)); } From d06977ecbbb8b1cc4215c188ffa955ece80435b8 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Tue, 27 Sep 2022 11:51:49 +0300 Subject: [PATCH 08/10] handle enabling/disabling Extra Resolutions mod --- launcher/mainwindow_moc.cpp | 4 ++++ launcher/modManager/cmodlistview_moc.cpp | 8 +++++++ launcher/modManager/cmodlistview_moc.h | 4 ++++ launcher/modManager/cmodmanager.cpp | 23 +++++++++++++++++++-- launcher/modManager/cmodmanager.h | 11 +++++++++- launcher/settingsView/csettingsview_moc.cpp | 16 +++++++++++--- launcher/settingsView/csettingsview_moc.h | 5 +++++ 7 files changed, 65 insertions(+), 6 deletions(-) diff --git a/launcher/mainwindow_moc.cpp b/launcher/mainwindow_moc.cpp index 82769300f..3dff2b4ff 100644 --- a/launcher/mainwindow_moc.cpp +++ b/launcher/mainwindow_moc.cpp @@ -82,7 +82,11 @@ MainWindow::MainWindow(QWidget * parent) ui->tabSelectList->setMaximumWidth(width + 4); } ui->tabListWidget->setCurrentIndex(0); + + ui->settingsView->isExtraResolutionsModEnabled = ui->stackedWidgetPage2->isExtraResolutionsModEnabled(); ui->settingsView->setDisplayList(); + connect(ui->stackedWidgetPage2, &CModListView::extraResolutionsEnabledChanged, + ui->settingsView, &CSettingsView::fillValidResolutions); connect(ui->tabSelectList, SIGNAL(currentRowChanged(int)), ui->tabListWidget, SLOT(setCurrentIndex(int))); diff --git a/launcher/modManager/cmodlistview_moc.cpp b/launcher/modManager/cmodlistview_moc.cpp index 63d0d36e1..423822999 100644 --- a/launcher/modManager/cmodlistview_moc.cpp +++ b/launcher/modManager/cmodlistview_moc.cpp @@ -28,6 +28,9 @@ void CModListView::setupModModel() { modModel = new CModListModel(this); manager = vstd::make_unique(modModel); + + connect(manager.get(), &CModManager::extraResolutionsEnabledChanged, + this, &CModListView::extraResolutionsEnabledChanged); } void CModListView::setupFilterModel() @@ -320,6 +323,11 @@ void CModListView::selectMod(const QModelIndex & index) } } +bool CModListView::isExtraResolutionsModEnabled() const +{ + return manager->isExtraResolutionsModEnabled(); +} + void CModListView::keyPressEvent(QKeyEvent * event) { if(event->key() == Qt::Key_Escape && ui->modInfoWidget->isVisible()) diff --git a/launcher/modManager/cmodlistview_moc.h b/launcher/modManager/cmodlistview_moc.h index dd80ef860..2cc93f64e 100644 --- a/launcher/modManager/cmodlistview_moc.h +++ b/launcher/modManager/cmodlistview_moc.h @@ -63,6 +63,9 @@ class CModListView : public QWidget QString genChangelogText(CModEntry & mod); QString genModInfoText(CModEntry & mod); +signals: + void extraResolutionsEnabledChanged(bool enabled); + public: explicit CModListView(QWidget * parent = 0); ~CModListView(); @@ -75,6 +78,7 @@ public: void disableModInfo(); void selectMod(const QModelIndex & index); + bool isExtraResolutionsModEnabled() const; private slots: void dataChanged(const QModelIndex & topleft, const QModelIndex & bottomRight); diff --git a/launcher/modManager/cmodmanager.cpp b/launcher/modManager/cmodmanager.cpp index f5cb03627..4595abe31 100644 --- a/launcher/modManager/cmodmanager.cpp +++ b/launcher/modManager/cmodmanager.cpp @@ -18,7 +18,11 @@ #include "../jsonutils.h" #include "../launcherdirs.h" -static QString detectModArchive(QString path, QString modName) +namespace +{ +const QLatin1String extraResolutionsMod{"vcmi-extras.extraresolutions"}; + +QString detectModArchive(QString path, QString modName) { auto files = ZipArchive::listFiles(qstringToPath(path)); @@ -40,6 +44,8 @@ static QString detectModArchive(QString path, QString modName) return ""; } +} + CModManager::CModManager(CModList * modList) : modList(modList) @@ -219,6 +225,11 @@ bool CModManager::canDisableMod(QString modname) return true; } +bool CModManager::isExtraResolutionsModEnabled() const +{ + return modList->hasMod(extraResolutionsMod) && modList->getMod(extraResolutionsMod).isEnabled(); +} + static QVariant writeValue(QString path, QVariantMap input, QVariant value) { if(path.size() > 1) @@ -246,6 +257,9 @@ bool CModManager::doEnableMod(QString mod, bool on) modList->setModSettings(modSettings["activeMods"]); modList->modChanged(mod); + if(mod == extraResolutionsMod) + sendExtraResolutionsEnabledChanged(on); + JsonUtils::JsonToFile(settingsPath(), modSettings); return true; @@ -261,7 +275,7 @@ bool CModManager::doInstallMod(QString modname, QString archivePath) if(localMods.contains(modname)) return addError(modname, "Mod with such name is already installed"); - QString modDirName = detectModArchive(archivePath, modname); + QString modDirName = ::detectModArchive(archivePath, modname); if(!modDirName.size()) return addError(modname, "Mod archive is invalid or corrupted"); @@ -326,3 +340,8 @@ bool CModManager::removeModDir(QString path) return dir.removeRecursively(); } + +void CModManager::sendExtraResolutionsEnabledChanged(bool enabled) +{ + emit extraResolutionsEnabledChanged(enabled); +} diff --git a/launcher/modManager/cmodmanager.h b/launcher/modManager/cmodmanager.h index 1c0401a94..0ce64c101 100644 --- a/launcher/modManager/cmodmanager.h +++ b/launcher/modManager/cmodmanager.h @@ -11,8 +11,10 @@ #include "cmodlist.h" -class CModManager +class CModManager : public QObject { + Q_OBJECT + CModList * modList; QString settingsPath(); @@ -29,6 +31,11 @@ class CModManager bool addError(QString modname, QString message); bool removeModDir(QString mod); + void sendExtraResolutionsEnabledChanged(bool enabled); + +signals: + void extraResolutionsEnabledChanged(bool enabled); + public: CModManager(CModList * modList); @@ -51,4 +58,6 @@ public: bool canUninstallMod(QString mod); bool canEnableMod(QString mod); bool canDisableMod(QString mod); + + bool isExtraResolutionsModEnabled() const; }; diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index cfdfd312a..d753329be 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -106,15 +106,25 @@ void CSettingsView::loadSettings() ui->comboBoxAutoSave->setCurrentIndex(settings["general"]["saveFrequency"].Integer() > 0 ? 1 : 0); } +void CSettingsView::fillValidResolutions(bool isExtraResolutionsModEnabled) +{ + this->isExtraResolutionsModEnabled = isExtraResolutionsModEnabled; + fillValidResolutionsForScreen(ui->comboBoxDisplayIndex->isVisible() ? ui->comboBoxDisplayIndex->currentIndex() : 0); +} + void CSettingsView::fillValidResolutionsForScreen(int screenIndex) { ui->comboBoxResolution->blockSignals(true); // avoid saving wrong resolution after adding first item from the list ui->comboBoxResolution->clear(); // TODO: read available resolutions from all mods - const QLatin1String extrasResolutionsPath{"/vcmi-extras/Mods/extraResolutions/Content/config/resolutions.json"}; - const auto extrasResolutionsJson = JsonUtils::JsonFromFile(CLauncherDirs::get().modsPath() + extrasResolutionsPath); - const auto resolutions = extrasResolutionsJson.toMap().value(QLatin1String{"GUISettings"}).toList(); + QVariantList resolutions; + if(isExtraResolutionsModEnabled) + { + const QLatin1String extrasResolutionsPath{"/vcmi-extras/Mods/extraResolutions/Content/config/resolutions.json"}; + const auto extrasResolutionsJson = JsonUtils::JsonFromFile(CLauncherDirs::get().modsPath() + extrasResolutionsPath); + resolutions = extrasResolutionsJson.toMap().value(QLatin1String{"GUISettings"}).toList(); + } if(resolutions.isEmpty()) { ui->comboBoxResolution->blockSignals(false); diff --git a/launcher/settingsView/csettingsview_moc.h b/launcher/settingsView/csettingsview_moc.h index 92a349057..fba5bd2c6 100644 --- a/launcher/settingsView/csettingsview_moc.h +++ b/launcher/settingsView/csettingsview_moc.h @@ -26,6 +26,11 @@ public: void loadSettings(); void setDisplayList(); + bool isExtraResolutionsModEnabled{}; + +public slots: + void fillValidResolutions(bool isExtraResolutionsModEnabled); + private slots: void on_checkBoxFullScreen_stateChanged(int state); From 42ea458ccffa19bfd71b6e42840acb6c68f8c852 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Tue, 27 Sep 2022 11:52:09 +0300 Subject: [PATCH 09/10] handle (un)installing Extra Resolutions mod --- launcher/modManager/cmodmanager.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/launcher/modManager/cmodmanager.cpp b/launcher/modManager/cmodmanager.cpp index 4595abe31..6c096c937 100644 --- a/launcher/modManager/cmodmanager.cpp +++ b/launcher/modManager/cmodmanager.cpp @@ -300,6 +300,9 @@ bool CModManager::doInstallMod(QString modname, QString archivePath) loadMods(); modList->reloadRepositories(); + if(modname == extraResolutionsMod) + sendExtraResolutionsEnabledChanged(true); + return true; } @@ -320,6 +323,9 @@ bool CModManager::doUninstallMod(QString modname) loadMods(); modList->reloadRepositories(); + if(modname == extraResolutionsMod) + sendExtraResolutionsEnabledChanged(false); + return true; } From e8396401f9e40c25652419c62db3fbff655eef7a Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Tue, 27 Sep 2022 11:55:03 +0300 Subject: [PATCH 10/10] fetch Extra Resolutions mod path from the settings schema --- config/schemas/settings.json | 6 +++++- launcher/settingsView/csettingsview_moc.cpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config/schemas/settings.json b/config/schemas/settings.json index 66d39b630..85e4d4463 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -363,7 +363,7 @@ "type" : "object", "default": {}, "additionalProperties" : false, - "required" : [ "repositoryURL", "enableInstalledMods", "autoCheckRepositories", "updateOnStartup", "updateConfigUrl" ], + "required" : [ "repositoryURL", "enableInstalledMods", "extraResolutionsModPath", "autoCheckRepositories", "updateOnStartup", "updateConfigUrl" ], "properties" : { "repositoryURL" : { "type" : "array", @@ -378,6 +378,10 @@ "type" : "boolean", "default" : true }, + "extraResolutionsModPath" : { + "type" : "string", + "default" : "/vcmi-extras/Mods/extraResolutions/Content/config/resolutions.json" + }, "autoCheckRepositories" : { "type" : "boolean", "default" : true diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index d753329be..d5ebbbb2a 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -121,7 +121,7 @@ void CSettingsView::fillValidResolutionsForScreen(int screenIndex) QVariantList resolutions; if(isExtraResolutionsModEnabled) { - const QLatin1String extrasResolutionsPath{"/vcmi-extras/Mods/extraResolutions/Content/config/resolutions.json"}; + const auto extrasResolutionsPath = settings["launcher"]["extraResolutionsModPath"].String().c_str(); const auto extrasResolutionsJson = JsonUtils::JsonFromFile(CLauncherDirs::get().modsPath() + extrasResolutionsPath); resolutions = extrasResolutionsJson.toMap().value(QLatin1String{"GUISettings"}).toList(); }