diff --git a/launcher/modManager/cmodlistview_moc.cpp b/launcher/modManager/cmodlistview_moc.cpp
index a8085bfd5..4ecd9060a 100644
--- a/launcher/modManager/cmodlistview_moc.cpp
+++ b/launcher/modManager/cmodlistview_moc.cpp
@@ -1076,3 +1076,34 @@ void CModListView::on_allModsView_doubleClicked(const QModelIndex &index)
return;
}
}
+
+void CModListView::createNewPreset(const QString & presetName)
+{
+ modStateModel->createNewPreset(presetName);
+}
+
+void CModListView::deletePreset(const QString & presetName)
+{
+ modStateModel->deletePreset(presetName);
+}
+
+void CModListView::activatePreset(const QString & presetName)
+{
+ modStateModel->activatePreset(presetName);
+ modStateModel->reloadLocalState();
+}
+
+void CModListView::renamePreset(const QString & oldPresetName, const QString & newPresetName)
+{
+ modStateModel->renamePreset(oldPresetName, newPresetName);
+}
+
+QStringList CModListView::getAllPresets() const
+{
+ return modStateModel->getAllPresets();
+}
+
+QString CModListView::getActivePreset() const
+{
+ return modStateModel->getActivePreset();
+}
diff --git a/launcher/modManager/cmodlistview_moc.h b/launcher/modManager/cmodlistview_moc.h
index 41be3221d..c0c589290 100644
--- a/launcher/modManager/cmodlistview_moc.h
+++ b/launcher/modManager/cmodlistview_moc.h
@@ -94,6 +94,18 @@ public:
/// finds all mods that can be updated
QStringList getUpdateableMods();
+ void createNewPreset(const QString & presetName);
+
+ void deletePreset(const QString & presetName);
+
+ void activatePreset(const QString & presetName);
+
+ void renamePreset(const QString & oldPresetName, const QString & newPresetName);
+
+ QStringList getAllPresets() const;
+
+ QString getActivePreset() const;
+
/// returns true if mod is currently enabled
bool isModEnabled(const QString & modName);
diff --git a/launcher/modManager/modstatemodel.cpp b/launcher/modManager/modstatemodel.cpp
index be4bc5627..9bcfa2863 100644
--- a/launcher/modManager/modstatemodel.cpp
+++ b/launcher/modManager/modstatemodel.cpp
@@ -128,3 +128,34 @@ QString ModStateModel::getTopParent(QString modname) const
else
return "";
}
+
+void ModStateModel::createNewPreset(const QString & presetName)
+{
+ modManager->createNewPreset(presetName.toStdString());
+}
+
+void ModStateModel::deletePreset(const QString & presetName)
+{
+ modManager->deletePreset(presetName.toStdString());
+}
+
+void ModStateModel::activatePreset(const QString & presetName)
+{
+ modManager->activatePreset(presetName.toStdString());
+}
+
+void ModStateModel::renamePreset(const QString & oldPresetName, const QString & newPresetName)
+{
+ modManager->renamePreset(oldPresetName.toStdString(), newPresetName.toStdString());
+}
+
+QStringList ModStateModel::getAllPresets() const
+{
+ auto result = modManager->getAllPresets();
+ return stringListStdToQt(result);
+}
+
+QString ModStateModel::getActivePreset() const
+{
+ return QString::fromStdString(modManager->getActivePreset());
+}
diff --git a/launcher/modManager/modstatemodel.h b/launcher/modManager/modstatemodel.h
index 08bf1935f..168da5dfe 100644
--- a/launcher/modManager/modstatemodel.h
+++ b/launcher/modManager/modstatemodel.h
@@ -49,4 +49,12 @@ public:
bool isSubmod(QString modname);
QString getTopParent(QString modname) const;
+
+ void createNewPreset(const QString & presetName);
+ void deletePreset(const QString & presetName);
+ void activatePreset(const QString & presetName);
+ void renamePreset(const QString & oldPresetName, const QString & newPresetName);
+
+ QStringList getAllPresets() const;
+ QString getActivePreset() const;
};
diff --git a/launcher/startGame/StartGameTab.cpp b/launcher/startGame/StartGameTab.cpp
index 41dec18cf..c3dbc0074 100644
--- a/launcher/startGame/StartGameTab.cpp
+++ b/launcher/startGame/StartGameTab.cpp
@@ -23,6 +23,8 @@ StartGameTab::StartGameTab(QWidget * parent)
refreshState();
ui->buttonGameResume->setVisible(false); // TODO: implement
+ ui->buttonPresetExport->setVisible(false); // TODO: implement
+ ui->buttonPresetImport->setVisible(false); // TODO: implement
}
StartGameTab::~StartGameTab()
@@ -41,11 +43,23 @@ MainWindow * StartGameTab::getMainWindow()
void StartGameTab::refreshState()
{
refreshGameData();
- refreshUpdateStatus(EGameUpdateStatus::NOT_CHECKED);//TODO
+ refreshUpdateStatus(EGameUpdateStatus::NOT_CHECKED);//TODO - follow automatic check on startup setting
refreshTranslation(getMainWindow()->getTranslationStatus());
+ refreshPresets();
refreshMods();
}
+void StartGameTab::refreshPresets()
+{
+ QSignalBlocker blocker(ui->comboBoxModPresets);
+
+ QStringList allPresets = getMainWindow()->getModView()->getAllPresets();
+ ui->comboBoxModPresets->clear();
+ ui->comboBoxModPresets->addItems(allPresets);
+ ui->comboBoxModPresets->setCurrentText(getMainWindow()->getModView()->getActivePreset());
+ ui->buttonPresetDelete->setVisible(allPresets.size() > 1);
+}
+
void StartGameTab::refreshGameData()
{
// Some players are using pirated version of the game with some of the files missing
@@ -121,12 +135,17 @@ void StartGameTab::refreshMods()
void StartGameTab::refreshUpdateStatus(EGameUpdateStatus status)
{
+ QString availableVersion; // TODO
+
ui->labelTitleEngine->setText("VCMI " VCMI_VERSION_STRING);
ui->buttonUpdateCheck->setVisible(status == EGameUpdateStatus::NOT_CHECKED);
ui->labelUpdateNotFound->setVisible(status == EGameUpdateStatus::NO_UPDATE);
ui->labelUpdateAvailable->setVisible(status == EGameUpdateStatus::UPDATE_AVAILABLE);
ui->buttonOpenChangelog->setVisible(status == EGameUpdateStatus::UPDATE_AVAILABLE);
ui->buttonOpenDownloads->setVisible(status == EGameUpdateStatus::UPDATE_AVAILABLE);
+
+ if (status == EGameUpdateStatus::UPDATE_AVAILABLE)
+ ui->labelUpdateAvailable->setText(tr("Update to %1 available").arg(availableVersion));
}
void StartGameTab::on_buttonGameStart_clicked()
@@ -204,8 +223,10 @@ void StartGameTab::on_buttonUpdateMods_clicked()
{
QStringList updateableMods = getMainWindow()->getModView()->getUpdateableMods();
+ getMainWindow()->switchToModsTab();
+
for (const auto & modName : updateableMods)
- getMainWindow()->getModView()->doInstallMod(modName);
+ getMainWindow()->getModView()->doUpdateMod(modName);
}
void StartGameTab::on_buttonHelpImportFiles_clicked()
@@ -248,7 +269,7 @@ void StartGameTab::on_buttonUpdateModsHelp_clicked()
QString message = tr(
"A new version of some of the mods that you have installed is now available in mod repository. "
"Use this option to automatically update all your mods to latest version.\n\n"
- "WARNING: IN some cases, updated versions of mods may not be compatible with your existing saves. "
+ "WARNING: In some cases, updated versions of mods may not be compatible with your existing saves. "
"You many want to postpone mod update until you finish any of your ongoing games."
);
@@ -324,10 +345,59 @@ void StartGameTab::on_buttonPresetImport_clicked()
void StartGameTab::on_buttonPresetNew_clicked()
{
- // TODO
+ bool ok;
+ QString presetName = QInputDialog::getText(
+ this,
+ ui->buttonPresetNew->text(),
+ tr("Enter preset name:"),
+ QLineEdit::Normal,
+ QString(),
+ &ok);
+
+ if (ok && !presetName.isEmpty())
+ {
+ getMainWindow()->getModView()->createNewPreset(presetName);
+ getMainWindow()->getModView()->activatePreset(presetName);
+ refreshPresets();
+ }
}
void StartGameTab::on_buttonPresetDelete_clicked()
{
- // TODO
+ QString activePresetBefore = getMainWindow()->getModView()->getActivePreset();
+ QStringList allPresets = getMainWindow()->getModView()->getAllPresets();
+
+ allPresets.removeAll(activePresetBefore);
+ if (!allPresets.empty())
+ {
+ getMainWindow()->getModView()->activatePreset(allPresets.front());
+ getMainWindow()->getModView()->deletePreset(activePresetBefore);
+ refreshPresets();
+ }
}
+
+void StartGameTab::on_comboBoxModPresets_currentTextChanged(const QString &presetName)
+{
+ getMainWindow()->getModView()->activatePreset(presetName);
+}
+
+void StartGameTab::on_buttonPresetRename_clicked()
+{
+ QString currentName = getMainWindow()->getModView()->getActivePreset();
+
+ bool ok;
+ QString newName = QInputDialog::getText(
+ this,
+ ui->buttonPresetNew->text(),
+ tr("Rename preset '%1' to:").arg(currentName),
+ QLineEdit::Normal,
+ currentName,
+ &ok);
+
+ if (ok && !newName.isEmpty())
+ {
+ getMainWindow()->getModView()->renamePreset(currentName, newName);
+ refreshPresets();
+ }
+}
+
diff --git a/launcher/startGame/StartGameTab.h b/launcher/startGame/StartGameTab.h
index 9ca2d0799..3503f726c 100644
--- a/launcher/startGame/StartGameTab.h
+++ b/launcher/startGame/StartGameTab.h
@@ -30,6 +30,7 @@ class StartGameTab : public QWidget
void refreshUpdateStatus(EGameUpdateStatus status);
void refreshTranslation(ETranslationStatus status);
void refreshMods();
+ void refreshPresets();
void refreshGameData();
public:
@@ -64,6 +65,10 @@ private slots:
void on_buttonPresetDelete_clicked();
+ void on_comboBoxModPresets_currentTextChanged(const QString &arg1);
+
+ void on_buttonPresetRename_clicked();
+
private:
Ui::StartGameTab * ui;
};
diff --git a/launcher/startGame/StartGameTab.ui b/launcher/startGame/StartGameTab.ui
index 28a5acfa7..813ec31ed 100644
--- a/launcher/startGame/StartGameTab.ui
+++ b/launcher/startGame/StartGameTab.ui
@@ -26,11 +26,11 @@
0
0
- 240
- 222
+ 226
+ 234
-
+
-
@@ -50,7 +50,7 @@
- -
+
-
Qt::Vertical
@@ -63,8 +63,8 @@
- -
-
+
-
+
0
@@ -78,26 +78,7 @@
- Export to Clipboard
-
-
-
- -
-
-
-
- 0
- 30
-
-
-
-
- 16777215
- 30
-
-
-
- Create New Preset
+ Rename Current Preset
@@ -122,7 +103,45 @@
- -
+
-
+
+
+
+ 0
+ 30
+
+
+
+
+ 16777215
+ 30
+
+
+
+ Create New Preset
+
+
+
+ -
+
+
+
+ 0
+ 30
+
+
+
+
+ 16777215
+ 30
+
+
+
+ Export to Clipboard
+
+
+
+ -
@@ -580,7 +599,7 @@
- Update to %1 available
+
true
diff --git a/lib/modding/ModManager.cpp b/lib/modding/ModManager.cpp
index f18452def..a117eff2c 100644
--- a/lib/modding/ModManager.cpp
+++ b/lib/modding/ModManager.cpp
@@ -326,6 +326,61 @@ void ModsPresetState::saveConfigurationState() const
file << modConfig.toCompactString();
}
+void ModsPresetState::createNewPreset(const std::string & presetName)
+{
+ if (modConfig["presets"][presetName].isNull())
+ modConfig["presets"][presetName]["mods"].Vector().emplace_back("vcmi");
+}
+
+void ModsPresetState::deletePreset(const std::string & presetName)
+{
+ if (modConfig["presets"].Struct().size() < 2)
+ throw std::runtime_error("Unable to delete last preset!");
+
+ modConfig["presets"].Struct().erase(presetName);
+}
+
+void ModsPresetState::activatePreset(const std::string & presetName)
+{
+ if (modConfig["presets"].Struct().count(presetName) == 0)
+ throw std::runtime_error("Unable to activate non-exinsting preset!");
+
+ modConfig["activePreset"].String() = presetName;
+}
+
+void ModsPresetState::renamePreset(const std::string & oldPresetName, const std::string & newPresetName)
+{
+ if (oldPresetName == newPresetName)
+ throw std::runtime_error("Unable to rename preset to the same name!");
+
+ if (modConfig["presets"].Struct().count(oldPresetName) == 0)
+ throw std::runtime_error("Unable to rename non-existing last preset!");
+
+ if (modConfig["presets"].Struct().count(newPresetName) != 0)
+ throw std::runtime_error("Unable to rename preset - preset with such name already exists!");
+
+ modConfig["presets"][newPresetName] = modConfig["presets"][oldPresetName];
+ modConfig["presets"].Struct().erase(oldPresetName);
+
+ if (modConfig["activePreset"].String() == oldPresetName)
+ modConfig["activePreset"].String() = newPresetName;
+}
+
+std::vector ModsPresetState::getAllPresets() const
+{
+ std::vector presets;
+
+ for (const auto & preset : modConfig["presets"].Struct())
+ presets.push_back(preset.first);
+
+ return presets;
+}
+
+std::string ModsPresetState::getActivePreset() const
+{
+ return modConfig["activePreset"].String();
+}
+
ModsStorage::ModsStorage(const std::vector & modsToLoad, const JsonNode & repositoryList)
{
JsonNode coreModConfig(JsonPath::builtin("config/gameConfig.json"));
@@ -703,4 +758,38 @@ void ModDependenciesResolver::tryAddMods(TModList modsToResolve, const ModsStora
brokenMods.insert(brokenMods.end(), modsToResolve.begin(), modsToResolve.end());
}
+void ModManager::createNewPreset(const std::string & presetName)
+{
+ modsPreset->createNewPreset(presetName);
+ modsPreset->saveConfigurationState();
+}
+
+void ModManager::deletePreset(const std::string & presetName)
+{
+ modsPreset->deletePreset(presetName);
+ modsPreset->saveConfigurationState();
+}
+
+void ModManager::activatePreset(const std::string & presetName)
+{
+ modsPreset->activatePreset(presetName);
+ modsPreset->saveConfigurationState();
+}
+
+void ModManager::renamePreset(const std::string & oldPresetName, const std::string & newPresetName)
+{
+ modsPreset->renamePreset(oldPresetName, newPresetName);
+ modsPreset->saveConfigurationState();
+}
+
+std::vector ModManager::getAllPresets() const
+{
+ return modsPreset->getAllPresets();
+}
+
+std::string ModManager::getActivePreset() const
+{
+ return modsPreset->getActivePreset();
+}
+
VCMI_LIB_NAMESPACE_END
diff --git a/lib/modding/ModManager.h b/lib/modding/ModManager.h
index 2acdb90a6..616e2632d 100644
--- a/lib/modding/ModManager.h
+++ b/lib/modding/ModManager.h
@@ -50,6 +50,14 @@ class ModsPresetState : boost::noncopyable
public:
ModsPresetState();
+ void createNewPreset(const std::string & presetName);
+ void deletePreset(const std::string & presetName);
+ void activatePreset(const std::string & presetName);
+ void renamePreset(const std::string & oldPresetName, const std::string & newPresetName);
+
+ std::vector getAllPresets() const;
+ std::string getActivePreset() const;
+
void setModActive(const TModID & modName, bool isActive);
void addRootMod(const TModID & modName);
@@ -139,6 +147,14 @@ public:
void tryEnableMods(const TModList & modList);
void tryDisableMod(const TModID & modName);
+
+ void createNewPreset(const std::string & presetName);
+ void deletePreset(const std::string & presetName);
+ void activatePreset(const std::string & presetName);
+ void renamePreset(const std::string & oldPresetName, const std::string & newPresetName);
+
+ std::vector getAllPresets() const;
+ std::string getActivePreset() const;
};
VCMI_LIB_NAMESPACE_END