mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Merge pull request #3797 from Laserlicht/install_from_file
Install from file button in launcher
This commit is contained in:
commit
ba3137582b
@ -15,6 +15,7 @@ set(launcher_SRCS
|
||||
settingsView/csettingsview_moc.cpp
|
||||
firstLaunch/firstlaunch_moc.cpp
|
||||
main.cpp
|
||||
helper.cpp
|
||||
mainwindow_moc.cpp
|
||||
languages.cpp
|
||||
launcherdirs.cpp
|
||||
@ -39,6 +40,7 @@ set(launcher_HEADERS
|
||||
jsonutils.h
|
||||
updatedialog_moc.h
|
||||
main.h
|
||||
helper.cpp
|
||||
)
|
||||
|
||||
set(launcher_FORMS
|
||||
|
@ -379,7 +379,7 @@ void FirstLaunchView::copyHeroesData(const QString & path, bool move)
|
||||
|
||||
if(dirData.empty())
|
||||
{
|
||||
QMessageBox::critical(this, "Heroes III data not found!", "Failed to detect valid Heroes III data in chosen directory.\nPlease select directory with installed Heroes III data.");
|
||||
QMessageBox::critical(this, tr("Heroes III data not found!"), tr("Failed to detect valid Heroes III data in chosen directory.\nPlease select directory with installed Heroes III data."));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -393,19 +393,19 @@ void FirstLaunchView::copyHeroesData(const QString & path, bool move)
|
||||
if (roeFiles.empty())
|
||||
{
|
||||
// Directory structure is correct (Data/Maps/Mp3) but no .lod archives that should be present in any install
|
||||
QMessageBox::critical(this, "Heroes III data not found!", "Failed to detect valid Heroes III data in chosen directory.\nPlease select directory with installed Heroes III data.");
|
||||
QMessageBox::critical(this, tr("Heroes III data not found!"), tr("Failed to detect valid Heroes III data in chosen directory.\nPlease select directory with installed Heroes III data."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hdFiles.empty())
|
||||
{
|
||||
// HD Edition contains only RoE data so we can't use even unmodified files from it
|
||||
QMessageBox::critical(this, "Heroes III data not found!", "Heroes III: HD Edition files are not supported by VCMI.\nPlease select directory with Heroes III: Complete Edition or Heroes III: Shadow of Death.");
|
||||
QMessageBox::critical(this, tr("Heroes III data not found!"), tr("Heroes III: HD Edition files are not supported by VCMI.\nPlease select directory with Heroes III: Complete Edition or Heroes III: Shadow of Death."));
|
||||
return;
|
||||
}
|
||||
|
||||
// RoE or some other unsupported edition. Demo version?
|
||||
QMessageBox::critical(this, "Heroes III data not found!", "Unknown or unsupported Heroes III version found.\nPlease select directory with Heroes III: Complete Edition or Heroes III: Shadow of Death.");
|
||||
QMessageBox::critical(this, tr("Heroes III data not found!"), tr("Unknown or unsupported Heroes III version found.\nPlease select directory with Heroes III: Complete Edition or Heroes III: Shadow of Death."));
|
||||
return;
|
||||
}
|
||||
|
||||
|
18
launcher/helper.cpp
Normal file
18
launcher/helper.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* jsonutils.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "helper.h"
|
||||
|
||||
#include "../lib/CConfigHandler.h"
|
||||
|
||||
void Helper::loadSettings()
|
||||
{
|
||||
settings.init("config/settings.json", "vcmi:settings");
|
||||
}
|
15
launcher/helper.h
Normal file
15
launcher/helper.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* jsonutils.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace Helper
|
||||
{
|
||||
void loadSettings();
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "updatedialog_moc.h"
|
||||
#include "main.h"
|
||||
#include "helper.h"
|
||||
|
||||
void MainWindow::load()
|
||||
{
|
||||
@ -45,7 +46,7 @@ void MainWindow::load()
|
||||
QDir::addSearchPath("icons", pathToQString(VCMIDirs::get().userDataPath() / "launcher" / "icons"));
|
||||
#endif
|
||||
|
||||
settings.init("config/settings.json", "vcmi:settings");
|
||||
Helper::loadSettings();
|
||||
}
|
||||
|
||||
void MainWindow::computeSidePanelSizes()
|
||||
|
@ -20,9 +20,12 @@
|
||||
#include "cmodlistmodel_moc.h"
|
||||
#include "cmodmanager.h"
|
||||
#include "cdownloadmanager_moc.h"
|
||||
#include "../settingsView/csettingsview_moc.h"
|
||||
#include "../launcherdirs.h"
|
||||
#include "../jsonutils.h"
|
||||
#include "../helper.h"
|
||||
|
||||
#include "../../lib/VCMIDirs.h"
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/Languages.h"
|
||||
#include "../../lib/modding/CModVersion.h"
|
||||
@ -52,7 +55,7 @@ void CModListView::dragEnterEvent(QDragEnterEvent* event)
|
||||
{
|
||||
if(event->mimeData()->hasUrls())
|
||||
for(const auto & url : event->mimeData()->urls())
|
||||
for(const auto & ending : QStringList({".zip", ".h3m", ".h3c", ".vmap", ".vcmp"}))
|
||||
for(const auto & ending : QStringList({".zip", ".h3m", ".h3c", ".vmap", ".vcmp", ".json"}))
|
||||
if(url.fileName().endsWith(ending, Qt::CaseInsensitive))
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
@ -69,19 +72,7 @@ void CModListView::dropEvent(QDropEvent* event)
|
||||
const QList<QUrl> urlList = mimeData->urls();
|
||||
|
||||
for (const auto & url : urlList)
|
||||
{
|
||||
QString urlStr = url.toString();
|
||||
QString fileName = url.fileName();
|
||||
if(urlStr.endsWith(".zip", Qt::CaseInsensitive))
|
||||
downloadFile(fileName.toLower()
|
||||
// mod name currently comes from zip file -> remove suffixes from github zip download
|
||||
.replace(QRegularExpression("-[0-9a-f]{40}"), "")
|
||||
.replace(QRegularExpression("-vcmi-.+\\.zip"), ".zip")
|
||||
.replace("-main.zip", ".zip")
|
||||
, urlStr, "mods", 0);
|
||||
else
|
||||
downloadFile(fileName, urlStr, "mods", 0);
|
||||
}
|
||||
manualInstallFile(url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -631,6 +622,56 @@ void CModListView::on_installButton_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
void CModListView::on_installFromFileButton_clicked()
|
||||
{
|
||||
QString filter = tr("All supported files") + " (*.h3m *.vmap *.h3c *.vcmp *.zip *.json);;" + tr("Maps") + " (*.h3m *.vmap);;" + tr("Campaigns") + " (*.h3c *.vcmp);;" + tr("Configs") + " (*.json);;" + tr("Mods") + " (*.zip)";
|
||||
QStringList files = QFileDialog::getOpenFileNames(this, tr("Select files (configs, mods, maps, campaigns) to install..."), QDir::homePath(), filter);
|
||||
|
||||
for (const auto & file : files)
|
||||
{
|
||||
QUrl url = QUrl::fromLocalFile(file);
|
||||
manualInstallFile(url);
|
||||
}
|
||||
}
|
||||
|
||||
void CModListView::manualInstallFile(QUrl url)
|
||||
{
|
||||
QString urlStr = url.toString();
|
||||
QString fileName = url.fileName();
|
||||
if(urlStr.endsWith(".zip", Qt::CaseInsensitive))
|
||||
downloadFile(fileName.toLower()
|
||||
// mod name currently comes from zip file -> remove suffixes from github zip download
|
||||
.replace(QRegularExpression("-[0-9a-f]{40}"), "")
|
||||
.replace(QRegularExpression("-vcmi-.+\\.zip"), ".zip")
|
||||
.replace("-main.zip", ".zip")
|
||||
, urlStr, "mods", 0);
|
||||
else if(urlStr.endsWith(".json", Qt::CaseInsensitive))
|
||||
{
|
||||
QDir configDir(QString::fromStdString(VCMIDirs::get().userConfigPath().string()));
|
||||
QStringList configFile = configDir.entryList({fileName}, QDir::Filter::Files); // case insensitive check
|
||||
if(!configFile.empty())
|
||||
{
|
||||
auto dialogResult = QMessageBox::warning(this, tr("Replace config file?"), tr("Do you want to replace %1?").arg(configFile[0]), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
||||
if(dialogResult == QMessageBox::Yes)
|
||||
{
|
||||
const auto configFilePath = configDir.filePath(configFile[0]);
|
||||
QFile::remove(configFilePath);
|
||||
QFile::copy(url.toLocalFile(), configFilePath);
|
||||
|
||||
// reload settings
|
||||
Helper::loadSettings();
|
||||
for(auto widget : qApp->allWidgets())
|
||||
if(auto settingsView = qobject_cast<CSettingsView *>(widget))
|
||||
settingsView->loadSettings();
|
||||
manager->loadMods();
|
||||
manager->loadModSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
downloadFile(fileName, urlStr, "mods", 0);
|
||||
}
|
||||
|
||||
void CModListView::downloadFile(QString file, QString url, QString description, qint64 size)
|
||||
{
|
||||
if(!dlManager)
|
||||
|
@ -51,6 +51,7 @@ class CModListView : public QWidget
|
||||
// find mods that depend on this one
|
||||
QStringList findDependentMods(QString mod, bool excludeDisabled);
|
||||
|
||||
void manualInstallFile(QUrl url);
|
||||
void downloadFile(QString file, QString url, QString description, qint64 size = 0);
|
||||
|
||||
void installMods(QStringList archives);
|
||||
@ -120,6 +121,8 @@ private slots:
|
||||
|
||||
void on_installButton_clicked();
|
||||
|
||||
void on_installFromFileButton_clicked();
|
||||
|
||||
void on_pushButton_clicked();
|
||||
|
||||
void on_refreshButton_clicked();
|
||||
|
@ -349,6 +349,41 @@ hr { height: 1px; border-width: 0; }
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="installFromFileButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>51</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>170</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Install from file</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>icons:mod-download.png</normaloff>icons:mod-download.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="modButtonSpacer">
|
||||
<property name="orientation">
|
||||
@ -521,7 +556,7 @@ hr { height: 1px; border-width: 0; }
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
|
@ -277,15 +277,15 @@ bool CModManager::doInstallMod(QString modname, QString archivePath)
|
||||
const auto destDir = CLauncherDirs::modsPath() + QChar{'/'};
|
||||
|
||||
if(!QFile(archivePath).exists())
|
||||
return addError(modname, "Mod archive is missing");
|
||||
return addError(modname, tr("Mod archive is missing"));
|
||||
|
||||
if(localMods.contains(modname))
|
||||
return addError(modname, "Mod with such name is already installed");
|
||||
return addError(modname, tr("Mod with such name is already installed"));
|
||||
|
||||
std::vector<std::string> filesToExtract;
|
||||
QString modDirName = ::detectModArchive(archivePath, modname, filesToExtract);
|
||||
if(!modDirName.size())
|
||||
return addError(modname, "Mod archive is invalid or corrupted");
|
||||
return addError(modname, tr("Mod archive is invalid or corrupted"));
|
||||
|
||||
std::atomic<int> filesCounter = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user