summaryrefslogtreecommitdiffstats
path: root/application/InstanceWindow.cpp
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2016-08-06 15:39:29 +0200
committerPetr Mrázek <peterix@gmail.com>2016-08-07 11:48:15 +0200
commitbc6d1b5304f715ad0d8be27efd6630f820572da4 (patch)
tree6f42bdd351664b6f828247b4860ee3ad723b0971 /application/InstanceWindow.cpp
parentc44d41ee9b132d4f757658bd62d4b115b7887fe3 (diff)
downloadMultiMC-bc6d1b5304f715ad0d8be27efd6630f820572da4.tar
MultiMC-bc6d1b5304f715ad0d8be27efd6630f820572da4.tar.gz
MultiMC-bc6d1b5304f715ad0d8be27efd6630f820572da4.tar.lz
MultiMC-bc6d1b5304f715ad0d8be27efd6630f820572da4.tar.xz
MultiMC-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.
Diffstat (limited to 'application/InstanceWindow.cpp')
-rw-r--r--application/InstanceWindow.cpp226
1 files changed, 226 insertions, 0 deletions
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()
+{
+}