aboutsummaryrefslogtreecommitdiff
path: root/launcher
diff options
context:
space:
mode:
Diffstat (limited to 'launcher')
-rw-r--r--launcher/Application.cpp3
-rw-r--r--launcher/CMakeLists.txt9
-rw-r--r--launcher/InstancePageProvider.h4
-rw-r--r--launcher/MMCZip.cpp2
-rw-r--r--launcher/launch/steps/CheckJava.cpp16
-rw-r--r--launcher/launch/steps/CheckJava.h2
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp10
-rw-r--r--launcher/minecraft/MojangDownloadInfo.h2
-rw-r--r--launcher/minecraft/launch/LauncherPartLaunch.cpp2
-rw-r--r--launcher/news/NewsEntry.cpp2
-rw-r--r--launcher/tasks/ConcurrentTask.cpp144
-rw-r--r--launcher/tasks/ConcurrentTask.h58
-rw-r--r--launcher/ui/MainWindow.cpp114
-rw-r--r--launcher/ui/MainWindow.h2
-rw-r--r--launcher/ui/dialogs/AboutDialog.ui27
-rw-r--r--launcher/ui/dialogs/NewsDialog.cpp49
-rw-r--r--launcher/ui/dialogs/NewsDialog.h30
-rw-r--r--launcher/ui/dialogs/NewsDialog.ui113
-rw-r--r--launcher/ui/pages/instance/ExternalResourcesPage.cpp297
-rw-r--r--launcher/ui/pages/instance/ExternalResourcesPage.h73
-rw-r--r--launcher/ui/pages/instance/ExternalResourcesPage.ui (renamed from launcher/ui/pages/instance/ModFolderPage.ui)49
-rw-r--r--launcher/ui/pages/instance/ModFolderPage.cpp381
-rw-r--r--launcher/ui/pages/instance/ModFolderPage.h112
-rw-r--r--launcher/ui/pages/instance/ResourcePackPage.h20
-rw-r--r--launcher/ui/pages/instance/ShaderPackPage.h16
-rw-r--r--launcher/ui/pages/instance/TexturePackPage.h18
-rw-r--r--launcher/ui/pages/modplatform/flame/FlamePage.ui2
-rw-r--r--launcher/ui/pages/modplatform/modrinth/ModrinthModel.cpp10
28 files changed, 1012 insertions, 555 deletions
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index ab3110a3..bafb928b 100644
--- a/launcher/Application.cpp
+++ b/launcher/Application.cpp
@@ -226,7 +226,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
setOrganizationName(BuildConfig.LAUNCHER_NAME);
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
setApplicationName(BuildConfig.LAUNCHER_NAME);
- setApplicationDisplayName(BuildConfig.LAUNCHER_DISPLAYNAME);
+ setApplicationDisplayName(QString("%1 %2").arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString()));
setApplicationVersion(BuildConfig.printableVersionString());
setDesktopFileName(BuildConfig.LAUNCHER_DESKTOPFILENAME);
startTime = QDateTime::currentDateTime();
@@ -626,6 +626,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
m_settings->registerSetting("JavaPath", "");
m_settings->registerSetting("JavaTimestamp", 0);
m_settings->registerSetting("JavaArchitecture", "");
+ m_settings->registerSetting("JavaRealArchitecture", "");
m_settings->registerSetting("JavaVersion", "");
m_settings->registerSetting("JavaVendor", "");
m_settings->registerSetting("LastHostname", "");
diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt
index b8db803b..26bcfe09 100644
--- a/launcher/CMakeLists.txt
+++ b/launcher/CMakeLists.txt
@@ -418,6 +418,8 @@ set(TASKS_SOURCES
# Tasks
tasks/Task.h
tasks/Task.cpp
+ tasks/ConcurrentTask.h
+ tasks/ConcurrentTask.cpp
tasks/SequentialTask.h
tasks/SequentialTask.cpp
)
@@ -717,6 +719,8 @@ SET(LAUNCHER_SOURCES
ui/pages/BasePageProvider.h
# GUI - instance pages
+ ui/pages/instance/ExternalResourcesPage.cpp
+ ui/pages/instance/ExternalResourcesPage.h
ui/pages/instance/GameOptionsPage.cpp
ui/pages/instance/GameOptionsPage.h
ui/pages/instance/VersionPage.cpp
@@ -845,6 +849,8 @@ SET(LAUNCHER_SOURCES
ui/dialogs/NewComponentDialog.h
ui/dialogs/NewInstanceDialog.cpp
ui/dialogs/NewInstanceDialog.h
+ ui/dialogs/NewsDialog.cpp
+ ui/dialogs/NewsDialog.h
ui/pagedialog/PageDialog.cpp
ui/pagedialog/PageDialog.h
ui/dialogs/ProgressDialog.cpp
@@ -924,7 +930,7 @@ qt5_wrap_ui(LAUNCHER_UI
ui/pages/global/ProxyPage.ui
ui/pages/global/MinecraftPage.ui
ui/pages/global/ExternalToolsPage.ui
- ui/pages/instance/ModFolderPage.ui
+ ui/pages/instance/ExternalResourcesPage.ui
ui/pages/instance/NotesPage.ui
ui/pages/instance/LogPage.ui
ui/pages/instance/ServersPage.ui
@@ -954,6 +960,7 @@ qt5_wrap_ui(LAUNCHER_UI
ui/dialogs/NewInstanceDialog.ui
ui/dialogs/UpdateDialog.ui
ui/dialogs/NewComponentDialog.ui
+ ui/dialogs/NewsDialog.ui
ui/dialogs/ProfileSelectDialog.ui
ui/dialogs/SkinUploadDialog.ui
ui/dialogs/ExportInstanceDialog.ui
diff --git a/launcher/InstancePageProvider.h b/launcher/InstancePageProvider.h
index 357157d0..78fb7016 100644
--- a/launcher/InstancePageProvider.h
+++ b/launcher/InstancePageProvider.h
@@ -33,10 +33,10 @@ public:
values.append(new LogPage(inst));
std::shared_ptr<MinecraftInstance> onesix = std::dynamic_pointer_cast<MinecraftInstance>(inst);
values.append(new VersionPage(onesix.get()));
- auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList(), "mods", "loadermods", tr("Mods"), "Loader-mods");
+ auto modsPage = new ModFolderPage(onesix.get(), onesix->loaderModList());
modsPage->setFilter("%1 (*.zip *.jar *.litemod)");
values.append(modsPage);
- values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList(), "coremods", "coremods", tr("Core mods"), "Core-mods"));
+ values.append(new CoreModFolderPage(onesix.get(), onesix->coreModList()));
values.append(new ResourcePackPage(onesix.get()));
values.append(new TexturePackPage(onesix.get()));
values.append(new ShaderPackPage(onesix.get()));
diff --git a/launcher/MMCZip.cpp b/launcher/MMCZip.cpp
index 627ceaf1..d7ad4428 100644
--- a/launcher/MMCZip.cpp
+++ b/launcher/MMCZip.cpp
@@ -305,7 +305,7 @@ nonstd::optional<QStringList> MMCZip::extractSubDir(QuaZip *zip, const QString &
QString path;
if(name.contains('/') && !name.endsWith('/')){
path = name.section('/', 0, -2) + "/";
- FS::ensureFolderPathExists(path);
+ FS::ensureFolderPathExists(FS::PathCombine(target, path));
name = name.split('/').last();
}
diff --git a/launcher/launch/steps/CheckJava.cpp b/launcher/launch/steps/CheckJava.cpp
index 3226fae7..ef5db2c9 100644
--- a/launcher/launch/steps/CheckJava.cpp
+++ b/launcher/launch/steps/CheckJava.cpp
@@ -75,11 +75,14 @@ void CheckJava::executeTask()
qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
auto storedUnixTime = settings->get("JavaTimestamp").toLongLong();
auto storedArchitecture = settings->get("JavaArchitecture").toString();
+ auto storedRealArchitecture = settings->get("JavaRealArchitecture").toString();
auto storedVersion = settings->get("JavaVersion").toString();
auto storedVendor = settings->get("JavaVendor").toString();
m_javaUnixTime = javaUnixTime;
// if timestamps are not the same, or something is missing, check!
- if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 || storedArchitecture.size() == 0 || storedVendor.size() == 0)
+ if (javaUnixTime != storedUnixTime || storedVersion.size() == 0
+ || storedArchitecture.size() == 0 || storedRealArchitecture.size() == 0
+ || storedVendor.size() == 0)
{
m_JavaChecker = new JavaChecker();
emit logLine(QString("Checking Java version..."), MessageLevel::Launcher);
@@ -92,8 +95,9 @@ void CheckJava::executeTask()
{
auto verString = instance->settings()->get("JavaVersion").toString();
auto archString = instance->settings()->get("JavaArchitecture").toString();
+ auto realArchString = settings->get("JavaRealArchitecture").toString();
auto vendorString = instance->settings()->get("JavaVendor").toString();
- printJavaInfo(verString, archString, vendorString);
+ printJavaInfo(verString, archString, realArchString, vendorString);
}
emitSucceeded();
}
@@ -124,10 +128,11 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
case JavaCheckResult::Validity::Valid:
{
auto instance = m_parent->instance();
- printJavaInfo(result.javaVersion.toString(), result.realPlatform, result.javaVendor);
+ printJavaInfo(result.javaVersion.toString(), result.mojangPlatform, result.realPlatform, result.javaVendor);
printSystemInfo(true, result.is_64bit);
instance->settings()->set("JavaVersion", result.javaVersion.toString());
instance->settings()->set("JavaArchitecture", result.mojangPlatform);
+ instance->settings()->set("JavaRealArchitecture", result.realPlatform);
instance->settings()->set("JavaVendor", result.javaVendor);
instance->settings()->set("JavaTimestamp", m_javaUnixTime);
emitSucceeded();
@@ -136,9 +141,10 @@ void CheckJava::checkJavaFinished(JavaCheckResult result)
}
}
-void CheckJava::printJavaInfo(const QString& version, const QString& architecture, const QString & vendor)
+void CheckJava::printJavaInfo(const QString& version, const QString& architecture, const QString& realArchitecture, const QString & vendor)
{
- emit logLine(QString("Java is version %1, using %2 architecture, from %3.\n\n").arg(version, architecture, vendor), MessageLevel::Launcher);
+ emit logLine(QString("Java is version %1, using %2 (%3) architecture, from %4.\n\n")
+ .arg(version, architecture, realArchitecture, vendor), MessageLevel::Launcher);
}
void CheckJava::printSystemInfo(bool javaIsKnown, bool javaIs64bit)
diff --git a/launcher/launch/steps/CheckJava.h b/launcher/launch/steps/CheckJava.h
index 68cd618b..d084b132 100644
--- a/launcher/launch/steps/CheckJava.h
+++ b/launcher/launch/steps/CheckJava.h
@@ -35,7 +35,7 @@ private slots:
void checkJavaFinished(JavaCheckResult result);
private:
- void printJavaInfo(const QString & version, const QString & architecture, const QString & vendor);
+ void printJavaInfo(const QString & version, const QString & architecture, const QString & realArchitecture, const QString & vendor);
void printSystemInfo(bool javaIsKnown, bool javaIs64bit);
private:
diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp
index 7e72601f..e0113a09 100644
--- a/launcher/minecraft/MinecraftInstance.cpp
+++ b/launcher/minecraft/MinecraftInstance.cpp
@@ -826,8 +826,16 @@ QString MinecraftInstance::getStatusbarDescription()
traits.append(tr("broken"));
}
+ QString mcVersion = m_components->getComponentVersion("net.minecraft");
+ if (mcVersion.isEmpty())
+ {
+ // Load component info if needed
+ m_components->reload(Net::Mode::Offline);
+ mcVersion = m_components->getComponentVersion("net.minecraft");
+ }
+
QString description;
- description.append(tr("Minecraft %1 (%2)").arg(m_components->getComponentVersion("net.minecraft")).arg(typeName()));
+ description.append(tr("Minecraft %1").arg(mcVersion));
if(m_settings->get("ShowGameTime").toBool())
{
if (lastTimePlayed() > 0) {
diff --git a/launcher/minecraft/MojangDownloadInfo.h b/launcher/minecraft/MojangDownloadInfo.h
index 88f87287..13e27e15 100644
--- a/launcher/minecraft/MojangDownloadInfo.h
+++ b/launcher/minecraft/MojangDownloadInfo.h
@@ -65,7 +65,7 @@ struct MojangAssetIndexInfo : public MojangDownloadInfo
// https://www.theregister.co.uk/2017/02/28/aws_is_awol_as_s3_goes_haywire/
if(id == "legacy")
{
- url = "https://launchermeta.mojang.com/mc/assets/legacy/c0fd82e8ce9fbc93119e40d96d5a4e62cfa3f729/legacy.json";
+ url = "https://piston-meta.mojang.com/mc/assets/legacy/c0fd82e8ce9fbc93119e40d96d5a4e62cfa3f729/legacy.json";
}
// HACK
else
diff --git a/launcher/minecraft/launch/LauncherPartLaunch.cpp b/launcher/minecraft/launch/LauncherPartLaunch.cpp
index 427bc32b..fe8a1b1b 100644
--- a/launcher/minecraft/launch/LauncherPartLaunch.cpp
+++ b/launcher/minecraft/launch/LauncherPartLaunch.cpp
@@ -142,7 +142,7 @@ void LauncherPartLaunch::executeTask()
#else
args << classPath.join(':');
#endif
- args << "org.multimc.EntryPoint";
+ args << "org.polymc.EntryPoint";
qDebug() << args.join(' ');
diff --git a/launcher/news/NewsEntry.cpp b/launcher/news/NewsEntry.cpp
index 137703d1..cfe07e86 100644
--- a/launcher/news/NewsEntry.cpp
+++ b/launcher/news/NewsEntry.cpp
@@ -54,7 +54,7 @@ inline QString childValue(const QDomElement& element, const QString& childName,
bool NewsEntry::fromXmlElement(const QDomElement& element, NewsEntry* entry, QString* errorMsg)
{
QString title = childValue(element, "title", tr("Untitled"));
- QString content = childValue(element, "description", tr("No content."));
+ QString content = childValue(element, "content", tr("No content."));
QString link = childValue(element, "id");
entry->title = title;
diff --git a/launcher/tasks/ConcurrentTask.cpp b/launcher/tasks/ConcurrentTask.cpp
new file mode 100644
index 00000000..b88cfb13
--- /dev/null
+++ b/launcher/tasks/ConcurrentTask.cpp
@@ -0,0 +1,144 @@
+#include "ConcurrentTask.h"
+
+#include <QDebug>
+
+ConcurrentTask::ConcurrentTask(QObject* parent, QString task_name, int max_concurrent)
+ : Task(parent), m_name(task_name), m_total_max_size(max_concurrent)
+{}
+
+ConcurrentTask::~ConcurrentTask()
+{
+ for (auto task : m_queue) {
+ if (task)
+ task->deleteLater();
+ }
+}
+
+auto ConcurrentTask::getStepProgress() const -> qint64
+{
+ return m_stepProgress;
+}
+
+auto ConcurrentTask::getStepTotalProgress() const -> qint64
+{
+ return m_stepTotalProgress;
+}
+
+void ConcurrentTask::addTask(Task::Ptr task)
+{
+ if (!isRunning())
+ m_queue.append(task);
+ else
+ qWarning() << "Tried to add a task to a running concurrent task!";
+}
+
+void ConcurrentTask::executeTask()
+{
+ m_total_size = m_queue.size();
+
+ for (int i = 0; i < m_total_max_size; i++)
+ startNext();
+}
+
+bool ConcurrentTask::abort()
+{
+ if (m_doing.isEmpty()) {
+ // Don't call emitAborted() here, we want to bypass the 'is the task running' check
+ emit aborted();
+ emit finished();
+
+ m_aborted = true;
+ return true;
+ }
+
+ m_queue.clear();
+
+ m_aborted = true;
+ for (auto task : m_doing)
+ m_aborted &= task->abort();
+
+ if (m_aborted)
+ emitAborted();
+
+ return m_aborted;
+}
+
+void ConcurrentTask::startNext()
+{
+ if (m_aborted || m_doing.count() > m_total_max_size)
+ return;
+
+ if (m_queue.isEmpty() && m_doing.isEmpty()) {
+ emitSucceeded();
+ return;
+ }
+
+ if (m_queue.isEmpty())
+ return;
+
+ Task::Ptr next = m_queue.dequeue();
+
+ connect(next.get(), &Task::succeeded, this, [this, next] { subTaskSucceeded(next); });
+ connect(next.get(), &Task::failed, this, [this, next](QString msg) { subTaskFailed(next, msg); });
+
+ connect(next.get(), &Task::status, this, &ConcurrentTask::subTaskStatus);
+ connect(next.get(), &Task::stepStatus, this, &ConcurrentTask::subTaskStatus);
+
+ connect(next.get(), &Task::progress, this, &ConcurrentTask::subTaskProgress);
+
+ m_doing.insert(next.get(), next);
+
+ setStepStatus(next->isMultiStep() ? next->getStepStatus() : next->getStatus());
+ updateState();
+
+ next->start();
+}
+
+void ConcurrentTask::subTaskSucceeded(Task::Ptr task)
+{
+ m_done.insert(task.get(), task);
+ m_doing.remove(task.get());
+
+ disconnect(task.get(), 0, this, 0);
+
+ updateState();
+
+ startNext();
+}
+
+void ConcurrentTask::subTaskFailed(Task::Ptr task, const QString& msg)
+{
+ m_done.insert(task.get(), task);
+ m_failed.insert(task.get(), task);
+
+ m_doing.remove(task.get());
+
+ disconnect(task.get(), 0, this, 0);
+
+ updateState();
+
+ startNext();
+}
+
+void ConcurrentTask::subTaskStatus(const QString& msg)
+{
+ setStepStatus(msg);
+}
+
+void ConcurrentTask::subTaskProgress(qint64 current, qint64 total)
+{
+ if (total == 0) {
+ setProgress(0, 100);
+ return;
+ }
+
+ m_stepProgress = current;
+ m_stepTotalProgress = total;
+}
+
+void ConcurrentTask::updateState()
+{
+ setProgress(m_done.count(), m_total_size);
+ setStatus(tr("Executing %1 task(s) (%2 out of %3 are done)")
+ .arg(QString::number(m_doing.count()), QString::number(m_done.count()), QString::number(m_total_size)));
+}
diff --git a/launcher/tasks/ConcurrentTask.h b/launcher/tasks/ConcurrentTask.h
new file mode 100644
index 00000000..5898899d
--- /dev/null
+++ b/launcher/tasks/ConcurrentTask.h
@@ -0,0 +1,58 @@
+#pragma once
+
+#include <QQueue>
+#include <QSet>
+
+#include "tasks/Task.h"
+
+class ConcurrentTask : public Task {
+ Q_OBJECT
+public:
+ explicit ConcurrentTask(QObject* parent = nullptr, QString task_name = "", int max_concurrent = 6);
+ virtual ~ConcurrentTask();
+
+ inline auto isMultiStep() const -> bool override { return m_queue.size() > 1; };
+ auto getStepProgress() const -> qint64 override;
+ auto getStepTotalProgress() const -> qint64 override;
+
+ inline auto getStepStatus() const -> QString override { return m_step_status; }
+
+ void addTask(Task::Ptr task);
+
+public slots:
+ bool abort() override;
+
+protected
+slots:
+ void executeTask() override;
+
+ virtual void startNext();
+
+ void subTaskSucceeded(Task::Ptr);
+ void subTaskFailed(Task::Ptr, const QString &msg);
+ void subTaskStatus(const QString &msg);
+ void subTaskProgress(qint64 current, qint64 total);
+
+protected:
+ void setStepStatus(QString status) { m_step_status = status; emit stepStatus(status); };
+
+ virtual void updateState();
+
+protected:
+ QString m_name;
+ QString m_step_status;
+
+ QQueue<Task::Ptr> m_queue;
+
+ QHash<Task*, Task::Ptr> m_doing;
+ QHash<Task*, Task::Ptr> m_done;
+ QHash<Task*, Task::Ptr> m_failed;
+
+ int m_total_max_size;
+ int m_total_size;
+
+ qint64 m_stepProgress = 0;
+ qint64 m_stepTotalProgress = 100;
+
+ bool m_aborted = false;
+};
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 210442df..f68cf61a 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -95,6 +95,7 @@
#include "ui/instanceview/InstanceDelegate.h"
#include "ui/widgets/LabeledToolButton.h"
#include "ui/dialogs/NewInstanceDialog.h"
+#include "ui/dialogs/NewsDialog.h"
#include "ui/dialogs/ProgressDialog.h"
#include "ui/dialogs/AboutDialog.h"
#include "ui/dialogs/VersionSelectDialog.h"
@@ -224,6 +225,7 @@ public:
TranslatedAction actionMoreNews;
TranslatedAction actionManageAccounts;
TranslatedAction actionLaunchInstance;
+ TranslatedAction actionKillInstance;
TranslatedAction actionRenameInstance;
TranslatedAction actionChangeInstGroup;
TranslatedAction actionChangeInstIcon;
@@ -282,27 +284,6 @@ public:
TranslatedToolbar instanceToolBar;
TranslatedToolbar newsToolBar;
QVector<TranslatedToolbar *> all_toolbars;
- bool m_kill = false;
-
- void updateLaunchAction()
- {
- if(m_kill)
- {
- actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Kill"));
- actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Kill the running instance"));
- }
- else
- {
- actionLaunchInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Launch"));
- actionLaunchInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance."));
- }
- actionLaunchInstance.retranslate();
- }
- void setLaunchAction(bool kill)
- {
- m_kill = kill;
- updateLaunchAction();
- }
void createMainToolbarActions(QMainWindow *MainWindow)
{
@@ -503,9 +484,12 @@ public:
menuBar->setVisible(APPLICATION->settings()->get("MenuBarInsteadOfToolBar").toBool());
fileMenu = menuBar->addMenu(tr("&File"));
+ // Workaround for QTBUG-94802 (https://bugreports.qt.io/browse/QTBUG-94802); also present for other menus
+ fileMenu->setSeparatorsCollapsible(false);
fileMenu->addAction(actionAddInstance);
fileMenu->addAction(actionLaunchInstance);
fileMenu->addAction(actionLaunchInstanceOffline);
+ fileMenu->addAction(actionKillInstance);
fileMenu->addAction(actionCloseWindow);
fileMenu->addSeparator();
fileMenu->addAction(actionEditInstance);
@@ -526,15 +510,18 @@ public:
fileMenu->addAction(actionSettings);
viewMenu = menuBar->addMenu(tr("&View"));
+ viewMenu->setSeparatorsCollapsible(false);
viewMenu->addAction(actionCAT);
viewMenu->addSeparator();
menuBar->addMenu(foldersMenu);
profileMenu = menuBar->addMenu(tr("&Profiles"));
+ profileMenu->setSeparatorsCollapsible(false);
profileMenu->addAction(actionManageAccounts);
helpMenu = menuBar->addMenu(tr("&Help"));
+ helpMenu->setSeparatorsCollapsible(false);
helpMenu->addAction(actionAbout);
helpMenu->addAction(actionOpenWiki);
helpMenu->addAction(actionNewsMenuBar);
@@ -580,10 +567,9 @@ public:
}
// "Instance actions" are actions that require an instance to be selected (i.e. "new instance" is not here)
+ // Actions that also require other conditions (e.g. a running instance) won't be changed.
void setInstanceActionsEnabled(bool enabled)
{
- actionLaunchInstance->setEnabled(enabled);
- actionLaunchInstanceOffline->setEnabled(enabled);
actionEditInstance->setEnabled(enabled);
actionEditInstNotes->setEnabled(enabled);
actionMods->setEnabled(enabled);
@@ -670,6 +656,14 @@ public:
actionLaunchInstanceOffline.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Launch the selected instance in offline mode."));
all_actions.append(&actionLaunchInstanceOffline);
+ actionKillInstance = TranslatedAction(MainWindow);
+ actionKillInstance->setObjectName(QStringLiteral("actionKillInstance"));
+ actionKillInstance->setDisabled(true);
+ actionKillInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "&Kill"));
+ actionKillInstance.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Kill the running instance"));
+ actionKillInstance->setShortcut(QKeySequence(tr("Ctrl+K")));
+ all_actions.append(&actionKillInstance);
+
actionEditInstance = TranslatedAction(MainWindow);
actionEditInstance->setObjectName(QStringLiteral("actionEditInstance"));
actionEditInstance.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Edit Inst&ance..."));
@@ -785,6 +779,7 @@ public:
instanceToolBar->addAction(actionLaunchInstance);
instanceToolBar->addAction(actionLaunchInstanceOffline);
+ instanceToolBar->addAction(actionKillInstance);
instanceToolBar->addSeparator();
@@ -822,7 +817,7 @@ public:
}
MainWindow->resize(800, 600);
MainWindow->setWindowIcon(APPLICATION->getThemedIcon("logo"));
- MainWindow->setWindowTitle(BuildConfig.LAUNCHER_DISPLAYNAME);
+ MainWindow->setWindowTitle(APPLICATION->applicationDisplayName());
#ifndef QT_NO_ACCESSIBILITY
MainWindow->setAccessibleName(BuildConfig.LAUNCHER_NAME);
#endif
@@ -857,8 +852,6 @@ public:
void retranslateUi(MainWindow *MainWindow)
{
- QString winTitle = tr("%1 - Version %2", "Launcher - Version X").arg(BuildConfig.LAUNCHER_DISPLAYNAME, BuildConfig.printableVersionString());
- MainWindow->setWindowTitle(winTitle);
// all the actions
for(auto * item: all_actions)
{
@@ -1184,14 +1177,10 @@ void MainWindow::updateToolsMenu()
QToolButton *launchButton = dynamic_cast<QToolButton*>(ui->instanceToolBar->widgetForAction(ui->actionLaunchInstance));
QToolButton *launchOfflineButton = dynamic_cast<QToolButton*>(ui->instanceToolBar->widgetForAction(ui->actionLaunchInstanceOffline));
- if(m_selectedInstance && m_selectedInstance->isRunning())
- {
- ui->actionLaunchInstance->setMenu(nullptr);
- ui->actionLaunchInstanceOffline->setMenu(nullptr);
- launchButton->setPopupMode(QToolButton::InstantPopup);
- launchOfflineButton->setPopupMode(QToolButton::InstantPopup);
- return;
- }
+ bool currentInstanceRunning = m_selectedInstance && m_selectedInstance->isRunning();
+
+ ui->actionLaunchInstance->setDisabled(!m_selectedInstance || currentInstanceRunning);
+ ui->actionLaunchInstanceOffline->setDisabled(!m_selectedInstance || currentInstanceRunning);
QMenu *launchMenu = ui->actionLaunchInstance->menu();
QMenu *launchOfflineMenu = ui->actionLaunchInstanceOffline->menu();
@@ -1219,6 +1208,9 @@ void MainWindow::updateToolsMenu()
normalLaunchOffline->setShortcut(QKeySequence(tr("Ctrl+Shift+O")));
if (m_selectedInstance)
{
+ normalLaunch->setEnabled(m_selectedInstance->canLaunch());
+ normalLaunchOffline->setEnabled(m_selectedInstance->canLaunch());
+
connect(normalLaunch, &QAction::triggered, [this]() {
APPLICATION->launch(m_selectedInstance, true);
});
@@ -1249,6 +1241,9 @@ void MainWindow::updateToolsMenu()
}
else if (m_selectedInstance)
{
+ profilerAction->setEnabled(m_selectedInstance->canLaunch());
+ profilerOfflineAction->setEnabled(m_selectedInstance->canLaunch());
+
connect(profilerAction, &QAction::triggered, [this, profiler]()
{
APPLICATION->launch(m_selectedInstance, true, profiler.get());
@@ -1952,20 +1947,17 @@ void MainWindow::on_actionOpenWiki_triggered()
void MainWindow::on_actionMoreNews_triggered()
{
- DesktopServices::openUrl(QUrl(BuildConfig.NEWS_OPEN_URL));
+ auto entries = m_newsChecker->getNewsEntries();
+ NewsDialog news_dialog(entries, this);
+ news_dialog.exec();
}
void MainWindow::newsButtonClicked()
{
- QList<NewsEntryPtr> entries = m_newsChecker->getNewsEntries();
- if (entries.count() > 0)
- {
- DesktopServices::openUrl(QUrl(entries[0]->link));
- }
- else
- {
- DesktopServices::openUrl(QUrl(BuildConfig.NEWS_OPEN_URL));
- }
+ auto entries = m_newsChecker->getNewsEntries();
+ NewsDialog news_dialog(entries, this);
+ news_dialog.toggleArticleList();
+ news_dialog.exec();
}
void MainWindow::on_actionAbout_triggered()
@@ -2081,15 +2073,7 @@ void MainWindow::instanceActivated(QModelIndex index)
void MainWindow::on_actionLaunchInstance_triggered()
{
- if (!m_selectedInstance)
- {
- return;
- }
- if(m_selectedInstance->isRunning())
- {
- APPLICATION->kill(m_selectedInstance);
- }
- else
+ if(m_selectedInstance && !m_selectedInstance->isRunning())
{
APPLICATION->launch(m_selectedInstance);
}
@@ -2108,6 +2092,14 @@ void MainWindow::on_actionLaunchInstanceOffline_triggered()
}
}
+void MainWindow::on_actionKillInstance_triggered()
+{
+ if(m_selectedInstance && m_selectedInstance->isRunning())
+ {
+ APPLICATION->kill(m_selectedInstance);
+ }
+}
+
void MainWindow::taskEnd()
{
QObject *sender = QObject::sender();
@@ -2141,17 +2133,9 @@ void MainWindow::instanceChanged(const QModelIndex &current, const QModelIndex &
{
ui->instanceToolBar->setEnabled(true);
ui->setInstanceActionsEnabled(true);
- if(m_selectedInstance->isRunning())
- {
- ui->actionLaunchInstance->setEnabled(true);
- ui->setLaunchAction(true);
- }
- else
- {
- ui->actionLaunchInstance->setEnabled(m_selectedInstance->canLaunch());
- ui->setLaunchAction(false);
- }
+ ui->actionLaunchInstance->setEnabled(m_selectedInstance->canLaunch());
ui->actionLaunchInstanceOffline->setEnabled(m_selectedInstance->canLaunch());
+ ui->actionKillInstance->setEnabled(m_selectedInstance->isRunning());
ui->actionExportInstance->setEnabled(m_selectedInstance->canExport());
ui->renameButton->setText(m_selectedInstance->name());
m_statusLeft->setText(m_selectedInstance->getStatusbarDescription());
@@ -2168,6 +2152,9 @@ void MainWindow::instanceChanged(const QModelIndex &current, const QModelIndex &
{
ui->instanceToolBar->setEnabled(false);
ui->setInstanceActionsEnabled(false);
+ ui->actionLaunchInstance->setEnabled(false);
+ ui->actionLaunchInstanceOffline->setEnabled(false);
+ ui->actionKillInstance->setEnabled(false);
APPLICATION->settings()->set("SelectedInstance", QString());
selectionBad();
return;
@@ -2197,6 +2184,7 @@ void MainWindow::selectionBad()
statusBar()->clearMessage();
ui->instanceToolBar->setEnabled(false);
ui->setInstanceActionsEnabled(false);
+ updateToolsMenu();
ui->r