diff options
| author | Petr Mrázek <peterix@gmail.com> | 2016-08-06 15:39:29 +0200 |
|---|---|---|
| committer | Petr Mrázek <peterix@gmail.com> | 2016-08-07 11:48:15 +0200 |
| commit | bc6d1b5304f715ad0d8be27efd6630f820572da4 (patch) | |
| tree | 6f42bdd351664b6f828247b4860ee3ad723b0971 | |
| parent | c44d41ee9b132d4f757658bd62d4b115b7887fe3 (diff) | |
| download | PrismLauncher-bc6d1b5304f715ad0d8be27efd6630f820572da4.tar.gz PrismLauncher-bc6d1b5304f715ad0d8be27efd6630f820572da4.tar.bz2 PrismLauncher-bc6d1b5304f715ad0d8be27efd6630f820572da4.zip | |
GH-338, GH-513, GH-700 Unify edit instance with console window
* The resulting instance window can be closed at any point.
* Main window is kept open and running instances are marked with a badge.
* Multiple instances can now run from the same MultiMC - it's even more **multi** now.
* MultiMC can be entirely closed, keeping Minecraft(s) running.
29 files changed, 630 insertions, 351 deletions
diff --git a/api/logic/BaseInstance.cpp b/api/logic/BaseInstance.cpp index ce55d5e4..9dee2c38 100644 --- a/api/logic/BaseInstance.cpp +++ b/api/logic/BaseInstance.cpp @@ -92,11 +92,14 @@ bool BaseInstance::isRunning() const void BaseInstance::setRunning(bool running) { - if(running && !m_isRunning) + if(running == m_isRunning) + return; + + if(running) { m_timeStarted = QDateTime::currentDateTime(); } - else if(!running && m_isRunning) + else { qint64 current = settings()->get("totalTimePlayed").toLongLong(); QDateTime timeEnded = QDateTime::currentDateTime(); @@ -104,6 +107,8 @@ void BaseInstance::setRunning(bool running) emit propertiesChanged(this); } m_isRunning = running; + + emit runningStatusChanged(running); } int64_t BaseInstance::totalTimePlayed() const @@ -179,7 +184,7 @@ void BaseInstance::unsetFlag(const BaseInstance::InstanceFlag flag) bool BaseInstance::canLaunch() const { - return !(flags() & VersionBrokenFlag); + return (!(flags() & VersionBrokenFlag)) && (!isRunning()); } bool BaseInstance::reload() @@ -268,3 +273,8 @@ QStringList BaseInstance::extraArguments() const { return Commandline::splitArgs(settings()->get("JvmArgs").toString()); } + +std::shared_ptr<LaunchTask> BaseInstance::getLaunchTask() +{ + return m_launchProcess; +} diff --git a/api/logic/BaseInstance.h b/api/logic/BaseInstance.h index f0fb6096..9a6976cb 100644 --- a/api/logic/BaseInstance.h +++ b/api/logic/BaseInstance.h @@ -157,6 +157,9 @@ public: /// returns a valid launcher (task container) virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) = 0; + /// returns the current launch task (if any) + std::shared_ptr<LaunchTask> getLaunchTask(); + /*! * Returns a task that should be done right before launch * This task should do any extra preparations needed @@ -231,6 +234,10 @@ signals: void flagsChanged(); + void launchTaskChanged(std::shared_ptr<LaunchTask>); + + void runningStatusChanged(bool running); + protected slots: void iconUpdated(QString key); @@ -240,6 +247,7 @@ protected: SettingsObjectPtr m_settings; InstanceFlags m_flags; bool m_isRunning = false; + std::shared_ptr<LaunchTask> m_launchProcess; QDateTime m_timeStarted; }; diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp index f706c16d..b64d9bd2 100644 --- a/api/logic/minecraft/MinecraftInstance.cpp +++ b/api/logic/minecraft/MinecraftInstance.cpp @@ -465,7 +465,9 @@ std::shared_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr s { process->setCensorFilter(createCensorFilterFromSession(session)); } - return process; + m_launchProcess = process; + emit launchTaskChanged(m_launchProcess); + return m_launchProcess; } QString MinecraftInstance::launchMethod() diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt index 9d71f977..46c496e2 100644 --- a/application/CMakeLists.txt +++ b/application/CMakeLists.txt @@ -103,12 +103,11 @@ SET(MULTIMC_SOURCES # GUI - windows MainWindow.h MainWindow.cpp - ConsoleWindow.h - ConsoleWindow.cpp + InstanceWindow.h + InstanceWindow.cpp # GUI - settings-specific wrappers for paged dialog SettingsUI.h - SettingsUI.cpp # Processes LaunchInteraction.h diff --git a/application/ConsoleWindow.cpp b/application/ConsoleWindow.cpp deleted file mode 100644 index e620d700..00000000 --- a/application/ConsoleWindow.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* Copyright 2013-2015 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ConsoleWindow.h" -#include "MultiMC.h" - -#include <QScrollBar> -#include <QMessageBox> -#include <QSystemTrayIcon> -#include <QHBoxLayout> -#include <QPushButton> -#include <qlayoutitem.h> -#include <QCloseEvent> - -#include <dialogs/CustomMessageBox.h> -#include <dialogs/ProgressDialog.h> -#include "widgets/PageContainer.h" -#include "pages/LogPage.h" -#include "InstancePageProvider.h" - -#include "icons/IconList.h" - -class LogPageProvider : public BasePageProvider -{ -public: - LogPageProvider(BasePageProviderPtr parent, BasePage * log_page) - { - m_parent = parent; - m_log_page = log_page; - } - virtual QString dialogTitle() {return "Fake";}; - virtual QList<BasePage *> getPages() - { - auto pages = m_parent->getPages(); - pages.prepend(m_log_page); - return pages; - } -private: - BasePageProviderPtr m_parent; - BasePage * m_log_page; -}; - -ConsoleWindow::ConsoleWindow(std::shared_ptr<LaunchTask> proc, QWidget *parent) - : QMainWindow(parent), m_proc(proc) -{ - setAttribute(Qt::WA_DeleteOnClose); - - auto instance = m_proc->instance(); - auto icon = MMC->icons()->getIcon(instance->iconKey()); - QString windowTitle = tr("Console window for ") + instance->name(); - - // Set window properties - { - setWindowIcon(icon); - setWindowTitle(windowTitle); - } - - // Add page container - { - auto mainLayout = new QVBoxLayout; - auto provider = std::make_shared<InstancePageProvider>(m_proc->instance()); - auto baseprovider = std::dynamic_pointer_cast<BasePageProvider>(provider); - auto proxy_provider = std::make_shared<LogPageProvider>(baseprovider, new LogPage(m_proc)); - m_container = new PageContainer(proxy_provider, "console", this); - mainLayout->addWidget(m_container); - mainLayout->setSpacing(0); - mainLayout->setContentsMargins(0,0,0,0); - setLayout(mainLayout); - setCentralWidget(m_container); - } - - // Add custom buttons to the page container layout. - { - auto horizontalLayout = new QHBoxLayout(); - horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); - horizontalLayout->setContentsMargins(6, -1, 6, -1); - - auto btnHelp = new QPushButton(); - btnHelp->setText(tr("Help")); - horizontalLayout->addWidget(btnHelp); - connect(btnHelp, SIGNAL(clicked(bool)), m_container, SLOT(help())); - - auto spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - horizontalLayout->addSpacerItem(spacer); - - m_killButton = new QPushButton(); - m_killButton->setText(tr("Kill Minecraft")); - horizontalLayout->addWidget(m_killButton); - connect(m_killButton, SIGNAL(clicked(bool)), SLOT(on_btnKillMinecraft_clicked())); - - m_closeButton = new QPushButton(); - m_closeButton->setText(tr("Close")); - horizontalLayout->addWidget(m_closeButton); - connect(m_closeButton, SIGNAL(clicked(bool)), SLOT(on_closeButton_clicked())); - - m_container->addButtons(horizontalLayout); - } - - // restore window state - { - auto base64State = MMC->settings()->get("ConsoleWindowState").toByteArray(); - restoreState(QByteArray::fromBase64(base64State)); - auto base64Geometry = MMC->settings()->get("ConsoleWindowGeometry").toByteArray(); - restoreGeometry(QByteArray::fromBase64(base64Geometry)); - } - - // Set up tray icon - { - m_trayIcon = new QSystemTrayIcon(icon, this); - m_trayIcon->setToolTip(windowTitle); - - connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); - m_trayIcon->show(); - } - - // Set up signal connections - connect(m_proc.get(), &LaunchTask::succeeded, this, &ConsoleWindow::onSucceeded); - connect(m_proc.get(), &LaunchTask::failed, this, &ConsoleWindow::onFailed); - connect(m_proc.get(), &LaunchTask::requestProgress, this, &ConsoleWindow::onProgressRequested); - - setMayClose(false); - - if (m_proc->instance()->settings()->get("ShowConsole").toBool()) - { - show(); - } -} - -void ConsoleWindow::iconActivated(QSystemTrayIcon::ActivationReason reason) -{ - switch (reason) - { - case QSystemTrayIcon::Trigger: - { - toggleConsole(); - } - default: - return; - } -} - -void ConsoleWindow::on_closeButton_clicked() -{ - close(); -} - -void ConsoleWindow::setMayClose(bool mayclose) -{ - if(mayclose) - m_closeButton->setText(tr("Close")); - else - m_closeButton->setText(tr("Hide")); - m_mayclose = mayclose; -} - -void ConsoleWindow::toggleConsole() -{ - if (isVisible()) - { - if(!isActiveWindow()) - { - activateWindow(); - return; - } - hide(); - } - else - { - show(); - } -} - -void ConsoleWindow::closeEvent(QCloseEvent *event) -{ - if (!m_mayclose) - { - toggleConsole(); - event->ignore(); - } - else if(m_container->requestClose(event)) - { - MMC->settings()->set("ConsoleWindowState", saveState().toBase64()); - MMC->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64()); - - emit isClosing(); - m_trayIcon->hide(); - event->accept(); - } -} - -void ConsoleWindow::on_btnKillMinecraft_clicked() -{ - m_killButton->setEnabled(false); - auto response = CustomMessageBox::selectable( - this, tr("Kill Minecraft?"), - tr("This can cause the instance to get corrupted and should only be used if Minecraft " - "is frozen for some reason"), - QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec(); - if (response == QMessageBox::Yes) - m_proc->abort(); - else - m_killButton->setEnabled(true); -} - -void ConsoleWindow::onSucceeded() -{ - m_killButton->setEnabled(false); - setMayClose(true); - if (m_proc->instance()->settings()->get("AutoCloseConsole").toBool() && m_container->requestClose(nullptr)) - { - this->close(); - return; - } - if (!isVisible()) - { - show(); - } - // Raise Window - if (MMC->settings()->get("RaiseConsole").toBool()) - { - raise(); - activateWindow(); - } -} - -void ConsoleWindow::onFailed(QString reason) -{ - m_killButton->setEnabled(false); - setMayClose(true); - if (!isVisible()) - { - show(); - } -} - -void ConsoleWindow::onProgressRequested(Task* task) -{ - ProgressDialog progDialog(this); - m_proc->proceed(); - progDialog.execWithTask(task); -} - - -ConsoleWindow::~ConsoleWindow() -{ - -} diff --git a/application/InstancePageProvider.h b/application/InstancePageProvider.h index dfc2e4dd..1d6cc5d7 100644 --- a/application/InstancePageProvider.h +++ b/application/InstancePageProvider.h @@ -3,6 +3,7 @@ #include "minecraft/legacy/LegacyInstance.h" #include <FileSystem.h> #include "pages/BasePage.h" +#include "pages/LogPage.h" #include "pages/VersionPage.h" #include "pages/ModFolderPage.h" #include "pages/ResourcePackPage.h" @@ -29,6 +30,7 @@ public: virtual QList<BasePage *> getPages() override { QList<BasePage *> values; + values.append(new LogPage(inst)); std::shared_ptr<OneSixInstance> onesix = std::dynamic_pointer_cast<OneSixInstance>(inst); if(onesix) { diff --git a/application/InstanceWindow.cpp b/application/InstanceWindow.cpp new file mode 100644 index 00000000..dfc7b815 --- /dev/null +++ b/application/InstanceWindow.cpp @@ -0,0 +1,226 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "InstanceWindow.h" +#include "MultiMC.h" + +#include <QScrollBar> +#include <QMessageBox> +#include <QHBoxLayout> +#include <QPushButton> +#include <qlayoutitem.h> +#include <QCloseEvent> + +#include <dialogs/CustomMessageBox.h> +#include <dialogs/ProgressDialog.h> +#include "widgets/PageContainer.h" +#include "InstancePageProvider.h" + +#include "icons/IconList.h" + +InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) + : QMainWindow(parent), m_instance(instance) +{ + setAttribute(Qt::WA_DeleteOnClose); + + auto icon = MMC->icons()->getIcon(m_instance->iconKey()); + QString windowTitle = tr("Console window for ") + m_instance->name(); + + // Set window properties + { + setWindowIcon(icon); + setWindowTitle(windowTitle); + } + + // Add page container + { + auto mainLayout = new QVBoxLayout; + auto provider = std::make_shared<InstancePageProvider>(m_instance); + m_container = new PageContainer(provider, "console", this); + mainLayout->addWidget(m_container); + mainLayout->setSpacing(0); + mainLayout->setContentsMargins(0,0,0,0); + setLayout(mainLayout); + setCentralWidget(m_container); + } + + // Add custom buttons to the page container layout. + { + auto horizontalLayout = new QHBoxLayout(); + horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); + horizontalLayout->setContentsMargins(6, -1, 6, -1); + + auto btnHelp = new QPushButton(); + btnHelp->setText(tr("Help")); + horizontalLayout->addWidget(btnHelp); + connect(btnHelp, SIGNAL(clicked(bool)), m_container, SLOT(help())); + + auto spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + horizontalLayout->addSpacerItem(spacer); + + m_killButton = new QPushButton(); + horizontalLayout->addWidget(m_killButton); + setKillButton(m_instance->isRunning()); + connect(m_killButton, SIGNAL(clicked(bool)), SLOT(on_btnKillMinecraft_clicked())); + + m_closeButton = new QPushButton(); + m_closeButton->setText(tr("Close")); + horizontalLayout->addWidget(m_closeButton); + connect(m_closeButton, SIGNAL(clicked(bool)), SLOT(on_closeButton_clicked())); + + m_container->addButtons(horizontalLayout); + } + + // restore window state + { + auto base64State = MMC->settings()->get("ConsoleWindowState").toByteArray(); + restoreState(QByteArray::fromBase64(base64State)); + auto base64Geometry = MMC->settings()->get("ConsoleWindowGeometry").toByteArray(); + restoreGeometry(QByteArray::fromBase64(base64Geometry)); + } + + // set up instance and launch process recognition + { + auto launchTask = m_instance->getLaunchTask(); + on_InstanceLaunchTask_changed(launchTask); + connect(m_instance.get(), &BaseInstance::launchTaskChanged, + this, &InstanceWindow::on_InstanceLaunchTask_changed); + connect(m_instance.get(), &BaseInstance::runningStatusChanged, + this, &InstanceWindow::on_RunningState_changed); + } + show(); +} + +void InstanceWindow::setKillButton(bool kill) +{ + if(kill) + { + m_killButton->setText(tr("Kill")); + m_killButton->setToolTip(tr("Kill the running instance")); + } + else + { + m_killButton->setText(tr("Launch")); + m_killButton->setToolTip(tr("Launch the instance")); + } +} + +void InstanceWindow::on_InstanceLaunchTask_changed(std::shared_ptr<LaunchTask> proc) +{ + if(m_proc) + { + disconnect(m_proc.get(), &LaunchTask::succeeded, this, &InstanceWindow::onSucceeded); + disconnect(m_proc.get(), &LaunchTask::failed, this, &InstanceWindow::onFailed); + disconnect(m_proc.get(), &LaunchTask::requestProgress, this, &InstanceWindow::onProgressRequested); + } + + m_proc = proc; + + if(m_proc) + { + // Set up signal connections + connect(m_proc.get(), &LaunchTask::succeeded, this, &InstanceWindow::onSucceeded); + connect(m_proc.get(), &LaunchTask::failed, this, &InstanceWindow::onFailed); + connect(m_proc.get(), &LaunchTask::requestProgress, this, &InstanceWindow::onProgressRequested); + } +} + +void InstanceWindow::on_RunningState_changed(bool running) +{ + setKillButton(running); + m_container->refresh(); +} + +void InstanceWindow::on_closeButton_clicked() +{ + close(); +} + +void InstanceWindow::closeEvent(QCloseEvent *event) +{ + MMC->settings()->set("ConsoleWindowState", saveState().toBase64()); + MMC->settings()->set("ConsoleWindowGeometry", saveGeometry().toBase64()); + + if(m_container->requestClose(event)) + { + emit isClosing(); + event->accept(); + } +} + +void InstanceWindow::on_btnKillMinecraft_clicked() +{ + if(m_instance->isRunning()) + { + auto response = CustomMessageBox::selectable( + this, tr("Kill Minecraft?"), + tr("This can cause the instance to get corrupted and should only be used if Minecraft " + "is frozen for some reason"), + QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)->exec(); + if (response == QMessageBox::Yes) + { + m_proc->abort(); + } + } + else + { + m_launchController.reset(new LaunchController()); + m_launchController->setInstance(m_instance); + m_launchController->setOnline(true); + m_launchController->setParentWidget(this); + m_launchController->start(); + } +} + +void InstanceWindow::onSucceeded() +{ + if (m_instance->settings()->get("AutoCloseConsole").toBool() && m_container->requestClose(nullptr)) + { + this->close(); + return; + } + // Raise Window + if (MMC->settings()->get("RaiseConsole").toBool()) + { + show(); + raise(); + activateWindow(); + } +} + +void InstanceWindow::onFailed(QString reason) +{ +} + +void InstanceWindow::onProgressRequested(Task* task) +{ + ProgressDialog progDialog(this); + m_proc->proceed(); + progDialog.execWithTask(task); +} + +QString InstanceWindow::instanceId() +{ + return m_instance->id(); +} + +bool InstanceWindow::selectPage(QString pageId) +{ + return m_container->selectPage(pageId); +} + +InstanceWindow::~InstanceWindow() +{ +} diff --git a/application/ConsoleWindow.h b/application/InstanceWindow.h index ac5a6fd1..7ffc4142 100644 --- a/application/ConsoleWindow.h +++ b/application/InstanceWindow.h @@ -16,25 +16,25 @@ #pragma once #include <QMainWindow> +#include "LaunchInteraction.h" +#include <QObjectPtr.h> #include <QSystemTrayIcon> #include "launch/LaunchTask.h" +#include "pages/BasePageContainer.h" class QPushButton; class PageContainer; -class ConsoleWindow : public QMainWindow +class InstanceWindow : public QMainWindow, public BasePageContainer { Q_OBJECT public: - explicit ConsoleWindow(std::shared_ptr<LaunchTask> proc, QWidget *parent = 0); - virtual ~ConsoleWindow(); + explicit InstanceWindow(InstancePtr proc, QWidget *parent = 0); + virtual ~InstanceWindow(); - /** - * @brief specify if the window is allowed to close - * @param mayclose - * used to keep it alive while MC runs - */ - void setMayClose(bool mayclose); + bool selectPage(QString pageId) override; + + QString instanceId(); signals: void isClosing(); @@ -48,18 +48,20 @@ slots: void onFailed(QString reason); void onProgressRequested(Task *task); - // FIXME: add handlers for the other MinecraftLauncher signals (pre/post launch command - // failures) + void on_InstanceLaunchTask_changed(std::shared_ptr<LaunchTask> proc); + void on_RunningState_changed(bool running); - void iconActivated(QSystemTrayIcon::ActivationReason); - void toggleConsole(); protected: - void closeEvent(QCloseEvent *); + void closeEvent(QCloseEvent *) override; + +private: + void setKillButton(bool kill); private: std::shared_ptr<LaunchTask> m_proc; + unique_qobject_ptr<LaunchController> m_launchController; + InstancePtr m_instance; bool m_mayclose = true; - QSystemTrayIcon *m_trayIcon = nullptr; PageContainer *m_container = nullptr; QPushButton *m_closeButton = nullptr; QPushButton *m_killButton = nullptr; diff --git a/application/LaunchInteraction.cpp b/application/LaunchInteraction.cpp index 1caa054a..80a3368d 100644 --- a/application/LaunchInteraction.cpp +++ b/application/LaunchInteraction.cpp @@ -1,11 +1,12 @@ #include "LaunchInteraction.h" +#include "MainWindow.h" #include <minecraft/auth/MojangAccountList.h> #include "MultiMC.h" #include "dialogs/CustomMessageBox.h" #include "dialogs/AccountSelectDialog.h" #include "dialogs/ProgressDialog.h" #include "dialogs/EditAccountDialog.h" -#include "ConsoleWindow.h" +#include "InstanceWindow.h" #include "BuildConfig.h" #include "JavaCommon.h" #include "SettingsUI.h" @@ -204,13 +205,20 @@ void LaunchController::launchInstance() return; } - if(m_parentWidget) + auto mainWindow = qobject_cast<MainWindow *>(m_parentWidget); + auto instanceWindow = qobject_cast<InstanceWindow *>(m_parentWidget); + if(mainWindow) { - m_parentWidget->hide(); + m_console = mainWindow->showInstanceWindow(m_instance); + } + else if(instanceWindow) + { + // NOOP + } + else + { + m_console = new InstanceWindow(m_instance); } - - m_console = new ConsoleWindow(m_launcher); - connect(m_console, &ConsoleWindow::isClosing, this, &LaunchController::instanceEnded); connect(m_launcher.get(), &LaunchTask::readyForLaunch, this, &LaunchController::readyForLaunch); m_launcher->prependStep(std::make_shared<TextPrint>(m_launcher.get(), "MultiMC version: " + BuildConfig.printableVersionString() + "\n\n", MessageLevel::MultiMC)); @@ -222,6 +230,7 @@ void LaunchController::readyForLaunch() if (!m_profiler) { m_launcher->proceed(); + emitSucceeded(); return; } @@ -230,6 +239,7 @@ void LaunchController::readyForLaunch() { m_launcher->abort(); QMessageBox::critical(m_parentWidget, tr("Error"), tr("Couldn't start profiler: %1").arg(error)); + emitFailed("Profiler startup failed"); return; } BaseProfiler *profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this); @@ -246,6 +256,7 @@ void LaunchController::readyForLaunch() msg.setModal(true); msg.exec(); m_launcher->proceed(); + emitSucceeded(); }); connect(profilerInstance, &BaseProfiler::abortLaunch, [this](const QString & message) { @@ -257,15 +268,7 @@ void LaunchController::readyForLaunch() msg.setModal(true); msg.exec(); m_launcher->abort(); + emitFailed("Profiler startup failed"); }); profilerInstance->beginProfiling(m_launcher); } - -void LaunchController::instanceEnded() -{ - if(m_parentWidget) - { - m_parentWidget->show(); - } - emitSucceeded(); -} diff --git a/application/LaunchInteraction.h b/application/LaunchInteraction.h index b0932e9b..55cb1e58 100644 --- a/application/LaunchInteraction.h +++ b/application/LaunchInteraction.h @@ -3,7 +3,7 @@ #include <BaseInstance.h> #include <tools/BaseProfiler.h> -class ConsoleWindow; +class InstanceWindow; class LaunchController: public Task { Q_OBJECT @@ -36,14 +36,13 @@ private: private slots: void readyForLaunch(); - void instanceEnded(); private: BaseProfilerFactory *m_profiler = nullptr; bool m_online = true; InstancePtr m_instance; QWidget * m_parentWidget = nullptr; - ConsoleWindow *m_console = nullptr; + InstanceWindow *m_console = nullptr; AuthSessionPtr m_session; std::shared_ptr <LaunchTask> m_launcher; }; diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index 06d165da..88c0fc09 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -67,6 +67,7 @@ #include <updater/UpdateChecker.h> #include <DesktopServices.h> +#include "InstanceWindow.h" #include "InstancePageProvider.h" #include "InstanceProxyModel.h" #include "JavaCommon.h" @@ -1424,24 +1425,62 @@ void MainWindow::on_actionSettings_triggered() update(); } +InstanceWindow *MainWindow::showInstanceWindow(InstancePtr instance, QString page) +{ + if(!instance) + return nullptr; + auto id = instance->id(); + InstanceWindow * window = nullptr; + + auto iter = m_instanceWindows.find(id); + if(iter != m_instanceWindows.end()) + { + window = *iter; + window->raise(); + window->activateWindow(); + } + else + { + window = new InstanceWindow(instance, this); + m_instanceWindows[id] = window; + connect(window, &InstanceWindow::isClosing, this, &MainWindow::on_instanceWindowClose); + } + if(!page.isEmpty()) + { + window->selectPage(page); + } + return window; +} + +void MainWindow::on_instanceWindowClose() +{ + auto senderWindow = qobject_cast<InstanceWindow *>(QObject::sender()); + if(!senderWindow) + { + return; + } + m_instanceWindows.remove(senderWindow->instanceId()); +} + + void MainWindow::on_actionInstanceSettings_triggered() { - SettingsUI::ShowInstancePageDialog(m_selectedInstance, this, "settings"); + showInstanceWindow(m_selectedInstance, "settings"); } void MainWindow::on_actionEditInstNotes_triggered() { - SettingsUI::ShowInstancePageDialog(m_selectedInstance, this, "notes"); + showInstanceWindow(m_selectedInstance, "notes"); } void MainWindow::on_actionEditInstance_triggered() { - SettingsUI::ShowInstancePageDialog(m_selectedInstance, this); + showInstanceWindow(m_selectedInstance); } void MainWindow::on_actionScreenshots_triggered() { - SettingsUI::ShowInstancePageDialog(m_selectedInstance, this, "screenshots"); + showInstanceWindow(m_selectedInstance, "screenshots"); } void MainWindow::on_actionManageAccounts_triggered() @@ -1586,16 +1625,19 @@ void MainWindow::on_actionLaunchInstanceOffline_triggered() |
