Переглянути джерело

Moved Install from file button from Mods to Start Game tab

Ivan Savenko 10 місяців тому
батько
коміт
d34ad05c36

+ 61 - 6
launcher/mainwindow_moc.cpp

@@ -203,12 +203,6 @@ void MainWindow::on_startGameButton_clicked()
 	switchToStartTab();
 }
 
-void MainWindow::on_startEditorButton_clicked()
-{
-	hide();
-	startEditor({});
-}
-
 CModListView * MainWindow::getModView()
 {
 	return ui->modlistView;
@@ -231,6 +225,67 @@ void MainWindow::on_aboutButton_clicked()
 	ui->tabListWidget->setCurrentIndex(TabRows::ABOUT);
 }
 
+void MainWindow::dragEnterEvent(QDragEnterEvent* event)
+{
+	if(event->mimeData()->hasUrls())
+		for(const auto & url : event->mimeData()->urls())
+			for(const auto & ending : QStringList({".zip", ".h3m", ".h3c", ".vmap", ".vcmp", ".json", ".exe"}))
+				if(url.fileName().endsWith(ending, Qt::CaseInsensitive))
+				{
+					event->acceptProposedAction();
+					return;
+				}
+}
+
+void MainWindow::dropEvent(QDropEvent* event)
+{
+	const QMimeData* mimeData = event->mimeData();
+
+	if(mimeData->hasUrls())
+	{
+		const QList<QUrl> urlList = mimeData->urls();
+		for (const auto & url : urlList)
+			manualInstallFile(url.toLocalFile());
+	}
+}
+
+void MainWindow::manualInstallFile(QString filePath)
+{
+	QString fileName = QFileInfo{filePath}.fileName();
+	if(filePath.endsWith(".zip", Qt::CaseInsensitive))
+		getModView()->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")
+													, QUrl::fromLocalFile(filePath), "mods");
+	else if(filePath.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(filePath, configFilePath);
+
+				// reload settings
+				Helper::loadSettings();
+				for(const auto widget : qApp->allWidgets())
+					if(auto settingsView = qobject_cast<CSettingsView *>(widget))
+						settingsView->loadSettings();
+
+				getModView()->reload();
+			}
+		}
+	}
+	else
+		getModView()->downloadFile(fileName, QUrl::fromLocalFile(filePath), fileName);
+}
+
 void MainWindow::updateTranslation()
 {
 #ifdef ENABLE_QT_TRANSLATIONS

+ 4 - 1
launcher/mainwindow_moc.h

@@ -58,6 +58,10 @@ public:
 	void switchToModsTab();
 	void switchToStartTab();
 
+	void dragEnterEvent(QDragEnterEvent* event) override;
+	void dropEvent(QDropEvent *event) override;
+	void manualInstallFile(QString filePath);
+
 protected:
 	void changeEvent(QEvent * event) override;
 
@@ -67,6 +71,5 @@ public slots:
 private slots:
 	void on_modslistButton_clicked();
 	void on_settingsButton_clicked();
-	void on_startEditorButton_clicked();
 	void on_aboutButton_clicked();
 };

+ 2 - 2
launcher/mainwindow_moc.ui

@@ -62,7 +62,7 @@
          <bool>true</bool>
         </property>
         <property name="checked">
-         <bool>true</bool>
+         <bool>false</bool>
         </property>
         <property name="autoExclusive">
          <bool>true</bool>
@@ -218,7 +218,7 @@
          <bool>true</bool>
         </property>
         <property name="checked">
-         <bool>false</bool>
+         <bool>true</bool>
         </property>
         <property name="autoExclusive">
          <bool>true</bool>

+ 6 - 91
launcher/modManager/cmodlistview_moc.cpp

@@ -59,30 +59,6 @@ void CModListView::changeEvent(QEvent *event)
 	QWidget::changeEvent(event);
 }
 
-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", ".json", ".exe"}))
-				if(url.fileName().endsWith(ending, Qt::CaseInsensitive))
-				{
-					event->acceptProposedAction();
-					return;
-				}
-}
-
-void CModListView::dropEvent(QDropEvent* event)
-{
-	const QMimeData* mimeData = event->mimeData();
-
-	if(mimeData->hasUrls())
-	{
-		const QList<QUrl> urlList = mimeData->urls();
-		for (const auto & url : urlList)
-			manualInstallFile(url.toLocalFile());
-	}
-}
-
 void CModListView::setupFilterModel()
 {
 	filterModel = new CModFilterModel(modModel, this);
@@ -169,6 +145,12 @@ CModListView::CModListView(QWidget * parent)
 #endif
 }
 
+void CModListView::reload()
+{
+	modStateModel->reloadLocalState();
+	modModel->reloadRepositories();
+}
+
 void CModListView::loadRepositories()
 {
 	QStringList repositories;
@@ -642,73 +624,6 @@ void CModListView::on_installButton_clicked()
 	}
 }
 
-void CModListView::on_installFromFileButton_clicked()
-{
-	// iOS can't display modal dialogs when called directly on button press
-	// https://bugreports.qt.io/browse/QTBUG-98651
-	QTimer::singleShot(0, this, [this]
-	{
-		QString filter = tr("All supported files") + " (*.h3m *.vmap *.h3c *.vcmp *.zip *.json *.exe);;" + 
-			tr("Maps") + " (*.h3m *.vmap);;" + 
-			tr("Campaigns") + " (*.h3c *.vcmp);;" + 
-			tr("Configs") + " (*.json);;" + 
-			tr("Mods") + " (*.zip);;" + 
-			tr("Gog files") + " (*.exe)";
-#if defined(VCMI_MOBILE)
-		filter = tr("All files (*.*)"); //Workaround for sometimes incorrect mime for some extensions (e.g. for exe)
-#endif
-		QStringList files = QFileDialog::getOpenFileNames(this, tr("Select files (configs, mods, maps, campaigns, gog files) to install..."), QDir::homePath(), filter);
-
-		for(const auto & file : files)
-		{
-			manualInstallFile(file);
-		}
-	});
-}
-
-void CModListView::manualInstallFile(QString filePath)
-{
-	QString fileName = QFileInfo{filePath}.fileName();
-	if(filePath.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")
-			, QUrl::fromLocalFile(filePath), "mods");
-	else if(filePath.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(filePath, configFilePath);
-
-				// reload settings
-				Helper::loadSettings();
-				for(const auto widget : qApp->allWidgets())
-					if(auto settingsView = qobject_cast<CSettingsView *>(widget))
-						settingsView->loadSettings();
-
-				modStateModel->reloadLocalState();
-				modModel->reloadRepositories();
-			}
-		}
-	}
-	else
-		downloadFile(fileName, QUrl::fromLocalFile(filePath), fileName);
-}
-
-void CModListView::downloadFile(QString file, QString url, QString description, qint64 sizeBytes)
-{
-	downloadFile(file, QUrl{url}, description, sizeBytes);
-}
-
 void CModListView::downloadFile(QString file, QUrl url, QString description, qint64 sizeBytes)
 {
 	if(!dlManager)

+ 4 - 19
launcher/modManager/cmodlistview_moc.h

@@ -52,9 +52,6 @@ class CModListView : public QWidget
 	// find mods unknown to mod list (not present in repo and not installed)
 	QStringList findUnavailableMods(QStringList candidates);
 
-	void manualInstallFile(QString filePath);
-	void downloadFile(QString file, QString url, QString description, qint64 sizeBytes = 0);
-	void downloadFile(QString file, QUrl url, QString description, qint64 sizeBytes = 0);
 
 	void installMods(QStringList archives);
 	void installMaps(QStringList maps);
@@ -64,8 +61,6 @@ class CModListView : public QWidget
 	QString genModInfoText(const ModState & mod);
 
 	void changeEvent(QEvent *event) override;
-	void dragEnterEvent(QDragEnterEvent* event) override;
-	void dropEvent(QDropEvent *event) override;
 
 public:
 	explicit CModListView(QWidget * parent = nullptr);
@@ -74,6 +69,8 @@ public:
 	void loadScreenshots();
 	void loadRepositories();
 
+	void reload();
+
 	void disableModInfo();
 
 	void selectMod(const QModelIndex & index);
@@ -95,6 +92,8 @@ public:
 	/// returns true if mod is currently installed
 	bool isModInstalled(const QString & modName);
 
+	void downloadFile(QString file, QUrl url, QString description, qint64 sizeBytes = 0);
+
 public slots:
 	void enableModByName(QString modName);
 	void disableModByName(QString modName);
@@ -109,31 +108,17 @@ private slots:
 	void hideProgressBar();
 
 	void on_lineEdit_textChanged(const QString & arg1);
-
 	void on_comboBox_currentIndexChanged(int index);
-
 	void on_enableButton_clicked();
-
 	void on_disableButton_clicked();
-
 	void on_updateButton_clicked();
-
 	void on_uninstallButton_clicked();
-
 	void on_installButton_clicked();
-
-	void on_installFromFileButton_clicked();
-
 	void on_pushButton_clicked();
-
 	void on_refreshButton_clicked();
-
 	void on_allModsView_activated(const QModelIndex & index);
-
 	void on_tabWidget_currentChanged(int index);
-
 	void on_screenshotsList_clicked(const QModelIndex & index);
-
 	void on_allModsView_doubleClicked(const QModelIndex &index);
 
 private:

+ 3 - 36
launcher/modManager/cmodlistview_moc.ui

@@ -191,7 +191,9 @@
 &lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
 p, li { white-space: pre-wrap; }
 hr { height: 1px; border-width: 0; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'.AppleSystemUIFont'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
+li.unchecked::marker { content: &quot;\2610&quot;; }
+li.checked::marker { content: &quot;\2612&quot;; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
 &lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu'; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
           </property>
           <property name="openExternalLinks">
@@ -349,41 +351,6 @@ 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">

+ 79 - 11
launcher/startGame/StartGameTab.cpp

@@ -4,7 +4,10 @@
 #include "../mainwindow_moc.h"
 #include "../main.h"
 
+#include "../modManager/cmodlistview_moc.h"
+
 #include "../../lib/filesystem/Filesystem.h"
+#include "../../lib/VCMIDirs.h"
 
 StartGameTab::StartGameTab(QWidget * parent)
 	: QWidget(parent)
@@ -13,6 +16,8 @@ StartGameTab::StartGameTab(QWidget * parent)
 	ui->setupUi(this);
 
 	refreshState();
+
+	ui->buttonGameResume->setVisible(false); // TODO: implement
 }
 
 StartGameTab::~StartGameTab()
@@ -29,6 +34,14 @@ MainWindow * StartGameTab::getMainWindow()
 }
 
 void StartGameTab::refreshState()
+{
+	refreshGameData();
+	refreshUpdateStatus(EGameUpdateStatus::NOT_CHECKED);//TODO
+	refreshTranslation(ETranslationStatus::ACTIVE);
+	refreshMods();
+}
+
+void StartGameTab::refreshGameData()
 {
 	// Some players are using pirated version of the game with some of the files missing
 	// leading to broken town hall menu (and possibly other dialogs)
@@ -55,9 +68,6 @@ void StartGameTab::refreshState()
 		"DATA/FOOL",
 	};
 
-	bool updateAvailable = false;
-	bool checkedForUpdate = false;
-
 	bool missingSoundtrack = !CResourceHandler::get()->existsResource(AudioPath::builtin("Music/MainMenu"));
 	bool missingVideoFiles = !CResourceHandler::get()->existsResource(VideoPath::builtin("Video/H3Intro"));
 	bool missingGameFiles = false;
@@ -69,13 +79,6 @@ void StartGameTab::refreshState()
 	for (const auto & filename : armaggedonBladeCampaigns)
 		missingCampaings &= !CResourceHandler::get()->existsResource(ResourcePath(filename, EResType::CAMPAIGN));
 
-	ui->buttonEngine->setText("VCMI " VCMI_VERSION_STRING);
-	ui->buttonUpdateCheck->setVisible(!checkedForUpdate);
-	ui->labelUpdateAvailable->setVisible(checkedForUpdate && updateAvailable);
-	ui->labelUpdateNotFound->setVisible(checkedForUpdate && !updateAvailable);
-	ui->buttonOpenChangelog->setVisible(checkedForUpdate && updateAvailable);
-	ui->buttonOpenDownloads->setVisible(checkedForUpdate && updateAvailable);
-
 	ui->labelMissingCampaigns->setVisible(missingCampaings);
 	ui->labelMissingFiles->setVisible(missingGameFiles);
 	ui->labelMissingVideo->setVisible(missingVideoFiles);
@@ -85,6 +88,35 @@ void StartGameTab::refreshState()
 	ui->buttonMissingFilesHelp->setVisible(missingGameFiles);
 	ui->buttonMissingVideoHelp->setVisible(missingVideoFiles);
 	ui->buttonMissingSoundtrackHelp->setVisible(missingSoundtrack);
+
+	// TODO: Chronicles
+}
+
+void StartGameTab::refreshTranslation(ETranslationStatus status)
+{
+	ui->buttonInstallTranslation->setVisible(status == ETranslationStatus::NOT_INSTALLLED);
+	ui->buttonInstallTranslationHelp->setVisible(status == ETranslationStatus::NOT_INSTALLLED);
+
+	ui->buttonActivateTranslation->setVisible(status == ETranslationStatus::NOT_INSTALLLED);
+	ui->buttonActivateTranslationHelp->setVisible(status == ETranslationStatus::NOT_INSTALLLED);
+}
+
+void StartGameTab::refreshMods()
+{
+	QStringList updateableMods;
+
+	ui->buttonUpdateMods->setVisible(!updateableMods.empty());
+	ui->buttonUpdateModsHelp->setVisible(!updateableMods.empty());
+}
+
+void StartGameTab::refreshUpdateStatus(EGameUpdateStatus status)
+{
+	ui->buttonEngine->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);
 }
 
 void StartGameTab::on_buttonGameStart_clicked()
@@ -93,7 +125,6 @@ void StartGameTab::on_buttonGameStart_clicked()
 	startGame({});
 }
 
-
 void StartGameTab::on_buttonOpenChangelog_clicked()
 {
 	QDesktopServices::openUrl(QUrl("https://vcmi.eu/ChangeLog/"));
@@ -111,3 +142,40 @@ void StartGameTab::on_buttonUpdateCheck_clicked()
 	// TODO: implement
 }
 
+
+void StartGameTab::on_buttonGameEditor_clicked()
+{
+	getMainWindow()->hide();
+	startEditor({});
+}
+
+
+void StartGameTab::on_buttonImportFiles_clicked()
+{
+	const auto & importFunctor = [this]
+	{
+#ifndef VCMI_MOBILE
+		QString filter =
+			tr("All supported files") + " (*.h3m *.vmap *.h3c *.vcmp *.zip *.json *.exe);;" +
+			tr("Maps") + " (*.h3m *.vmap);;" +
+			tr("Campaigns") + " (*.h3c *.vcmp);;" +
+			tr("Configs") + " (*.json);;" +
+			tr("Mods") + " (*.zip);;" +
+			tr("Gog files") + " (*.exe)";
+#else
+		//Workaround for sometimes incorrect mime for some extensions (e.g. for exe)
+		QString filter = tr("All files (*.*)");
+#endif
+		QStringList files = QFileDialog::getOpenFileNames(this, tr("Select files (configs, mods, maps, campaigns, gog files) to install..."), QDir::homePath(), filter);
+
+		for(const auto & file : files)
+			getMainWindow()->manualInstallFile(file);
+	};
+
+	// iOS can't display modal dialogs when called directly on button press
+	// https://bugreports.qt.io/browse/QTBUG-98651
+	QTimer::singleShot(0, this, importFunctor);
+}
+
+
+

+ 25 - 0
launcher/startGame/StartGameTab.h

@@ -8,6 +8,21 @@ namespace Ui
 class StartGameTab;
 }
 
+enum class EGameUpdateStatus : int8_t
+{
+	NOT_CHECKED,
+	NO_UPDATE,
+	UPDATE_AVAILABLE
+};
+
+enum ETranslationStatus
+{
+	NOT_AVAILABLE, // translation for this language was not found in mod list. Could also happen if player is offline or disabled repository checkout
+	NOT_INSTALLLED, // translation mod found, but it is not installed
+	DISABLED, // translation mod found, and installed, but toggled off
+	ACTIVE // translation mod active OR game is already in specified language (e.g. English H3 for players with English language)
+};
+
 class MainWindow;
 
 class StartGameTab : public QWidget
@@ -17,6 +32,12 @@ class StartGameTab : public QWidget
 	MainWindow * getMainWindow();
 
 	void refreshState();
+
+	void refreshUpdateStatus(EGameUpdateStatus status);
+	void refreshTranslation(ETranslationStatus status);
+	void refreshMods();
+	void refreshGameData();
+
 public:
 	explicit StartGameTab(QWidget * parent = nullptr);
 	~StartGameTab();
@@ -30,6 +51,10 @@ private slots:
 
 	void on_buttonUpdateCheck_clicked();
 
+	void on_buttonGameEditor_clicked();
+
+	void on_buttonImportFiles_clicked();
+
 private:
 	Ui::StartGameTab * ui;
 };

+ 1 - 1
launcher/startGame/StartGameTab.ui

@@ -31,7 +31,7 @@
         </size>
        </property>
        <property name="text">
-        <string>Preset %1</string>
+        <string>Preset: %1</string>
        </property>
       </widget>
      </item>