diff options
Diffstat (limited to 'gui')
-rw-r--r-- | gui/ConsoleWindow.cpp | 40 | ||||
-rw-r--r-- | gui/ConsoleWindow.h | 7 | ||||
-rw-r--r-- | gui/MainWindow.cpp | 93 | ||||
-rw-r--r-- | gui/MainWindow.h | 15 | ||||
-rw-r--r-- | gui/dialogs/SettingsDialog.cpp | 4 | ||||
-rw-r--r-- | gui/widgets/IconLabel.cpp | 30 | ||||
-rw-r--r-- | gui/widgets/IconLabel.h | 26 | ||||
-rw-r--r-- | gui/widgets/LineSeparator.cpp | 37 | ||||
-rw-r--r-- | gui/widgets/LineSeparator.h | 18 | ||||
-rw-r--r-- | gui/widgets/ServerStatus.cpp | 115 | ||||
-rw-r--r-- | gui/widgets/ServerStatus.h | 34 |
11 files changed, 311 insertions, 108 deletions
diff --git a/gui/ConsoleWindow.cpp b/gui/ConsoleWindow.cpp index 18a617e0..ac3752c5 100644 --- a/gui/ConsoleWindow.cpp +++ b/gui/ConsoleWindow.cpp @@ -24,9 +24,11 @@ #include <gui/Platform.h> #include <gui/dialogs/CustomMessageBox.h> #include <gui/dialogs/ProgressDialog.h> +#include "dialogs/ScreenshotDialog.h" #include "logic/net/PasteUpload.h" #include "logic/icons/IconList.h" +#include <logic/screenshots/ScreenshotList.h> ConsoleWindow::ConsoleWindow(MinecraftProcess *mcproc, QWidget *parent) : QMainWindow(parent), ui(new Ui::ConsoleWindow), proc(mcproc) @@ -35,14 +37,12 @@ ConsoleWindow::ConsoleWindow(MinecraftProcess *mcproc, QWidget *parent) ui->setupUi(this); connect(mcproc, SIGNAL(log(QString, MessageLevel::Enum)), this, SLOT(write(QString, MessageLevel::Enum))); - connect(mcproc, SIGNAL(ended(BaseInstance *, int, QProcess::ExitStatus)), this, - SLOT(onEnded(BaseInstance *, int, QProcess::ExitStatus))); - connect(mcproc, SIGNAL(prelaunch_failed(BaseInstance *, int, QProcess::ExitStatus)), this, - SLOT(onEnded(BaseInstance *, int, QProcess::ExitStatus))); - connect(mcproc, SIGNAL(launch_failed(BaseInstance *)), this, - SLOT(onLaunchFailed(BaseInstance *))); - - connect(ui->btnScreenshots, &QPushButton::clicked, this, &ConsoleWindow::uploadScreenshots); + connect(mcproc, SIGNAL(ended(InstancePtr, int, QProcess::ExitStatus)), this, + SLOT(onEnded(InstancePtr, int, QProcess::ExitStatus))); + connect(mcproc, SIGNAL(prelaunch_failed(InstancePtr, int, QProcess::ExitStatus)), this, + SLOT(onEnded(InstancePtr, int, QProcess::ExitStatus))); + connect(mcproc, SIGNAL(launch_failed(InstancePtr)), this, + SLOT(onLaunchFailed(InstancePtr))); restoreState( QByteArray::fromBase64(MMC->settings()->get("ConsoleWindowState").toByteArray())); @@ -172,6 +172,26 @@ void ConsoleWindow::on_closeButton_clicked() close(); } +void ConsoleWindow::on_btnScreenshots_clicked() +{ + ScreenshotList *list = new ScreenshotList(proc->instance()); + Task *task = list->load(); + ProgressDialog prog(this); + prog.exec(task); + if (!task->successful()) + { + CustomMessageBox::selectable(this, tr("Failed to load screenshots!"), + task->failReason(), QMessageBox::Warning)->exec(); + return; + } + ScreenshotDialog dialog(list, this); + if (dialog.exec() == ScreenshotDialog::Accepted) + { + CustomMessageBox::selectable(this, tr("Done uploading!"), dialog.message(), + QMessageBox::Information)->exec(); + } +} + void ConsoleWindow::setMayClose(bool mayclose) { if(mayclose) @@ -242,7 +262,7 @@ void ConsoleWindow::on_btnKillMinecraft_clicked() ui->btnKillMinecraft->setEnabled(true); } -void ConsoleWindow::onEnded(BaseInstance *instance, int code, QProcess::ExitStatus status) +void ConsoleWindow::onEnded(InstancePtr instance, int code, QProcess::ExitStatus status) { bool peacefulExit = code == 0 && status != QProcess::CrashExit; ui->btnKillMinecraft->setEnabled(false); @@ -274,7 +294,7 @@ void ConsoleWindow::onEnded(BaseInstance *instance, int code, QProcess::ExitStat } } -void ConsoleWindow::onLaunchFailed(BaseInstance *instance) +void ConsoleWindow::onLaunchFailed(InstancePtr instance) { ui->btnKillMinecraft->setEnabled(false); diff --git a/gui/ConsoleWindow.h b/gui/ConsoleWindow.h index e21da33c..17c64392 100644 --- a/gui/ConsoleWindow.h +++ b/gui/ConsoleWindow.h @@ -51,7 +51,6 @@ private: signals: void isClosing(); - void uploadScreenshots(); public slots: @@ -71,9 +70,11 @@ slots: private slots: void on_closeButton_clicked(); + void on_btnScreenshots_clicked(); void on_btnKillMinecraft_clicked(); - void onEnded(BaseInstance *instance, int code, QProcess::ExitStatus status); - void onLaunchFailed(BaseInstance *instance); + + void onEnded(InstancePtr instance, int code, QProcess::ExitStatus status); + void onLaunchFailed(InstancePtr instance); // FIXME: add handlers for the other MinecraftProcess signals (pre/post launch command // failures) diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index f437f8a3..5ba05b2a 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -47,6 +47,7 @@ #include "gui/Platform.h" #include "gui/widgets/LabeledToolButton.h" +#include "widgets/ServerStatus.h" #include "gui/dialogs/SettingsDialog.h" #include "gui/dialogs/NewInstanceDialog.h" @@ -63,8 +64,8 @@ #include "gui/dialogs/AccountSelectDialog.h" #include "gui/dialogs/UpdateDialog.h" #include "gui/dialogs/EditAccountDialog.h" -#include "gui/dialogs/ScreenshotDialog.h" #include "gui/dialogs/NotificationDialog.h" +#include "dialogs/ScreenshotDialog.h" #include "gui/ConsoleWindow.h" @@ -216,29 +217,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi connect(MMC->instances().get(), SIGNAL(dataIsInvalid()), SLOT(selectionBad())); m_statusLeft = new QLabel(tr("No instance selected"), this); - m_statusRight = new QLabel(tr("No status available"), this); - m_statusRefresh = new QToolButton(this); - m_statusRefresh->setCheckable(true); - m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly); - m_statusRefresh->setIcon(QIcon::fromTheme("refresh")); - + m_statusRight = new ServerStatus(this); statusBar()->addPermanentWidget(m_statusLeft, 1); statusBar()->addPermanentWidget(m_statusRight, 0); - statusBar()->addPermanentWidget(m_statusRefresh, 0); - - // Start status checker - { - connect(MMC->statusChecker().get(), &StatusChecker::statusLoaded, this, - &MainWindow::updateStatusUI); - connect(MMC->statusChecker().get(), &StatusChecker::statusLoadingFailed, this, - &MainWindow::updateStatusFailedUI); - - connect(m_statusRefresh, &QAbstractButton::clicked, this, &MainWindow::reloadStatus); - connect(&statusTimer, &QTimer::timeout, this, &MainWindow::reloadStatus); - statusTimer.setSingleShot(true); - - reloadStatus(); - } // Add "manage accounts" button, right align QWidget *spacer = new QWidget(); @@ -620,60 +601,6 @@ void MainWindow::updateNewsLabel() } } -static QString convertStatus(const QString &status) -{ - QString ret = "?"; - - if (status == "green") - ret = "↑"; - else if (status == "yellow") - ret = "-"; - else if (status == "red") - ret = "↓"; - - return "<span style=\"font-size:11pt; font-weight:600;\">" + ret + "</span>"; -} - -void MainWindow::reloadStatus() -{ - m_statusRefresh->setChecked(true); - MMC->statusChecker()->reloadStatus(); - // updateStatusUI(); -} - -static QString makeStatusString(const QMap<QString, QString> statuses) -{ - QString status = ""; - status += "Web: " + convertStatus(statuses["minecraft.net"]); - status += " Account: " + convertStatus(statuses["account.mojang.com"]); - status += " Skins: " + convertStatus(statuses["skins.minecraft.net"]); - status += " Auth: " + convertStatus(statuses["authserver.mojang.com"]); - status += " Session: " + convertStatus(statuses["sessionserver.mojang.com"]); - - return status; -} - -void MainWindow::updateStatusUI() -{ - auto statusChecker = MMC->statusChecker(); - auto statuses = statusChecker->getStatusEntries(); - - QString status = makeStatusString(statuses); - m_statusRefresh->setChecked(false); - - m_statusRight->setText(status); - - statusTimer.start(60 * 1000); -} - -void MainWindow::updateStatusFailedUI() -{ - m_statusRight->setText(makeStatusString(QMap<QString, QString>())); - m_statusRefresh->setChecked(false); - - statusTimer.start(60 * 1000); -} - void MainWindow::updateAvailable(QString repo, QString versionName, int versionId) { UpdateDialog dlg; @@ -1317,15 +1244,19 @@ void MainWindow::launchInstance(InstancePtr instance, AuthSessionPtr session, Ba Q_ASSERT_X(instance != NULL, "launchInstance", "instance is NULL"); Q_ASSERT_X(session.get() != nullptr, "launchInstance", "session is NULL"); - proc = instance->prepareForLaunch(session); - if (!proc) + QString launchScript; + + if(!instance->prepareForLaunch(session, launchScript)) return; + MinecraftProcess *proc = new MinecraftProcess(instance); + proc->setLaunchScript(launchScript); + proc->setWorkdir(instance->minecraftRoot()); + this->hide(); console = new ConsoleWindow(proc); connect(console, SIGNAL(isClosing()), this, SLOT(instanceEnded())); - connect(console, &ConsoleWindow::uploadScreenshots, this, &MainWindow::on_actionScreenshots_triggered); proc->setLogin(session); proc->arm(); @@ -1347,7 +1278,7 @@ void MainWindow::launchInstance(InstancePtr instance, AuthSessionPtr session, Ba dialog.setLabelText(tr("Waiting for profiler...")); connect(&dialog, &QProgressDialog::canceled, profilerInstance, &BaseProfiler::abortProfiling); dialog.show(); - connect(profilerInstance, &BaseProfiler::readyToLaunch, [&dialog, this](const QString &message) + connect(profilerInstance, &BaseProfiler::readyToLaunch, [&dialog, this, proc](const QString &message) { dialog.accept(); QMessageBox msg; @@ -1360,7 +1291,7 @@ void MainWindow::launchInstance(InstancePtr instance, AuthSessionPtr session, Ba msg.exec(); proc->launch(); }); - connect(profilerInstance, &BaseProfiler::abortLaunch, [&dialog, this](const QString &message) + connect(profilerInstance, &BaseProfiler::abortLaunch, [&dialog, this, proc](const QString &message) { dialog.accept(); QMessageBox msg; diff --git a/gui/MainWindow.h b/gui/MainWindow.h index d610a87d..69cf11b0 100644 --- a/gui/MainWindow.h +++ b/gui/MainWindow.h @@ -111,6 +111,8 @@ slots: void on_actionEditInstNotes_triggered(); + void on_actionScreenshots_triggered(); + /*! * Launches the currently selected instance with the default account. * If no default account is selected, prompts the user to pick an account. @@ -144,8 +146,6 @@ slots: void showInstanceContextMenu(const QPoint &); - void on_actionScreenshots_triggered(); - void updateToolsMenu(); void skinJobFinished(); @@ -171,12 +171,6 @@ slots: void updateNewsLabel(); - void updateStatusUI(); - - void updateStatusFailedUI(); - - void reloadStatus(); - /*! * Runs the DownloadUpdateTask and installs updates. */ @@ -206,12 +200,9 @@ private: Task *m_versionLoadTask; QLabel *m_statusLeft; - QLabel *m_statusRight; - QToolButton *m_statusRefresh; + class ServerStatus *m_statusRight; QMenu *accountMenu; QToolButton *accountMenuButton; QAction *manageAccountsAction; - - QTimer statusTimer; }; diff --git a/gui/dialogs/SettingsDialog.cpp b/gui/dialogs/SettingsDialog.cpp index 7ec48336..2dd19077 100644 --- a/gui/dialogs/SettingsDialog.cpp +++ b/gui/dialogs/SettingsDialog.cpp @@ -407,8 +407,8 @@ void SettingsDialog::loadSettings(SettingsObject *s) // Language ui->languageBox->clear(); ui->languageBox->addItem(tr("English"), QLocale(QLocale::English)); - foreach(const QString & lang, - QDir(MMC->root() + "/translations").entryList(QStringList() << "*.qm", QDir::Files)) + foreach(const QString & lang, QDir(MMC->staticData() + "/translations") + .entryList(QStringList() << "*.qm", QDir::Files)) { QLocale locale(lang.section(QRegExp("[_\.]"), 1)); ui->languageBox->addItem(QLocale::languageToString(locale.language()), locale); diff --git a/gui/widgets/IconLabel.cpp b/gui/widgets/IconLabel.cpp new file mode 100644 index 00000000..1bfe8dc9 --- /dev/null +++ b/gui/widgets/IconLabel.cpp @@ -0,0 +1,30 @@ +#include "IconLabel.h" + +#include <QStyle> +#include <QStyleOption> +#include <QLayout> +#include <QPainter> +#include <QRect> + +IconLabel::IconLabel(QWidget *parent, QIcon icon, QSize size) + : QWidget(parent), m_icon(icon), m_size(size) +{ + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); +} + +QSize IconLabel::sizeHint() const +{ + return m_size; +} + +void IconLabel::setIcon(QIcon icon) +{ + m_icon = icon; + update(); +} + +void IconLabel::paintEvent(QPaintEvent *) +{ + QPainter p(this); + m_icon.paint(&p, contentsRect()); +} diff --git a/gui/widgets/IconLabel.h b/gui/widgets/IconLabel.h new file mode 100644 index 00000000..a2f1eef3 --- /dev/null +++ b/gui/widgets/IconLabel.h @@ -0,0 +1,26 @@ +#pragma once +#include <QWidget> +#include <QIcon> + +class QStyleOption; + +/** + * This is a trivial widget that paints a QIcon of the specified size. + */ +class IconLabel : public QWidget +{ + Q_OBJECT + +public: + /// Create a line separator. orientation is the orientation of the line. + explicit IconLabel(QWidget *parent, QIcon icon, QSize size); + + virtual QSize sizeHint() const; + virtual void paintEvent(QPaintEvent *); + + void setIcon(QIcon icon); + +private: + QSize m_size; + QIcon m_icon; +}; diff --git a/gui/widgets/LineSeparator.cpp b/gui/widgets/LineSeparator.cpp new file mode 100644 index 00000000..f4ee173d --- /dev/null +++ b/gui/widgets/LineSeparator.cpp @@ -0,0 +1,37 @@ +#include "LineSeparator.h" + +#include <QStyle> +#include <QStyleOption> +#include <QLayout> +#include <QPainter> + +void LineSeparator::initStyleOption(QStyleOption *option) const +{ + option->initFrom(this); + // in a horizontal layout, the line is vertical (and vice versa) + if (m_orientation == Qt::Vertical) + option->state |= QStyle::State_Horizontal; +} + +LineSeparator::LineSeparator(QWidget *parent, Qt::Orientation orientation) + : QWidget(parent), m_orientation(orientation) +{ + setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); +} + +QSize LineSeparator::sizeHint() const +{ + QStyleOption opt; + initStyleOption(&opt); + const int extent = + style()->pixelMetric(QStyle::PM_ToolBarSeparatorExtent, &opt, parentWidget()); + return QSize(extent, extent); +} + +void LineSeparator::paintEvent(QPaintEvent *) +{ + QPainter p(this); + QStyleOption opt; + initStyleOption(&opt); + style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, &opt, &p, parentWidget()); +} diff --git a/gui/widgets/LineSeparator.h b/gui/widgets/LineSeparator.h new file mode 100644 index 00000000..376f2056 --- /dev/null +++ b/gui/widgets/LineSeparator.h @@ -0,0 +1,18 @@ +#pragma once +#include <QWidget> + +class QStyleOption; + +class LineSeparator : public QWidget +{ + Q_OBJECT + +public: + /// Create a line separator. orientation is the orientation of the line. + explicit LineSeparator(QWidget *parent, Qt::Orientation orientation = Qt::Vertical); + QSize sizeHint() const; + void paintEvent(QPaintEvent *); + void initStyleOption(QStyleOption *option) const; +private: + Qt::Orientation m_orientation = Qt::Vertical; +}; diff --git a/gui/widgets/ServerStatus.cpp b/gui/widgets/ServerStatus.cpp new file mode 100644 index 00000000..e540a301 --- /dev/null +++ b/gui/widgets/ServerStatus.cpp @@ -0,0 +1,115 @@ +#include "ServerStatus.h" +#include "LineSeparator.h" +#include "IconLabel.h" +#include "logic/status/StatusChecker.h" + +#include "MultiMC.h" + +#include <QHBoxLayout> +#include <QFrame> +#include <QLabel> +#include <QMap> +#include <QToolButton> +#include <QAction> + +ServerStatus::ServerStatus(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f) +{ + layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + goodIcon = QIcon::fromTheme("status-good"); + badIcon = QIcon::fromTheme("status-bad"); + + addStatus("minecraft.net", tr("Web")); + addLine(); + addStatus("account.mojang.com", tr("Account")); + addLine(); + addStatus("skins.minecraft.net", tr("Skins")); + addLine(); + addStatus("authserver.mojang.com", tr("Auth")); + addLine(); + addStatus("sessionserver.mojang.com", tr("Session")); + + m_statusRefresh = new QToolButton(this); + m_statusRefresh->setCheckable(true); + m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly); + m_statusRefresh->setIcon(QIcon::fromTheme("refresh")); + layout->addWidget(m_statusRefresh); + + setLayout(layout); + + // Start status checker + { + auto reloader = MMC->statusChecker().get(); + connect(reloader, &StatusChecker::statusChanged, this, &ServerStatus::StatusChanged); + connect(reloader, &StatusChecker::statusLoading, this, &ServerStatus::StatusReloading); + connect(m_statusRefresh, &QAbstractButton::clicked, this, &ServerStatus::reloadStatus); + MMC->statusChecker()->startTimer(60000); + reloadStatus(); + } +} + +ServerStatus::~ServerStatus() +{ +} + +void ServerStatus::reloadStatus() +{ + MMC->statusChecker()->reloadStatus(); +} + +void ServerStatus::addLine() +{ + layout->addWidget(new LineSeparator(this)); +} + +void ServerStatus::addStatus(QString key, QString name) +{ + { + auto label = new IconLabel(this, badIcon, QSize(16, 16)); + label->setToolTip(key); + serverLabels[key] = label; + layout->addWidget(label); + } + { + auto label = new QLabel(this); + label->setText(name); + label->setToolTip(key); + layout->addWidget(label); + } +} + +void ServerStatus::setStatus(QString key, bool value) +{ + if (!serverLabels.contains(key)) + return; + IconLabel *label = serverLabels[key]; + label->setIcon(value ? goodIcon : badIcon); +} + +void ServerStatus::StatusChanged(const QMap<QString, QString> statusEntries) +{ + auto convertStatus = [&](QString status)->bool + { + if (status == "green") + return true; + else if (status == "yellow") + return false; + else if (status == "red") + return false; + return false; + } + ; + auto iter = statusEntries.begin(); + while (iter != statusEntries.end()) + { + QString key = iter.key(); + bool value = convertStatus(iter.value()); + setStatus(key, value); + iter++; + } +} + +void ServerStatus::StatusReloading(bool is_reloading) +{ + m_statusRefresh->setChecked(is_reloading); +} diff --git a/gui/widgets/ServerStatus.h b/gui/widgets/ServerStatus.h new file mode 100644 index 00000000..2244031b --- /dev/null +++ b/gui/widgets/ServerStatus.h @@ -0,0 +1,34 @@ +#pragma once +#include <QString> +#include <QWidget> +#include <QMap> +#include <QIcon> +#include <memory> + +class IconLabel; +class QToolButton; +class QHBoxLayout; + +class ServerStatus: public QWidget +{ + Q_OBJECT +public: + explicit ServerStatus(QWidget *parent = nullptr, Qt::WindowFlags f = 0); + virtual ~ServerStatus(); + ; +public slots: + void reloadStatus(); + void StatusChanged(const QMap<QString, QString> statuses); + void StatusReloading(bool is_reloading); + +private: /* methods */ + void addLine(); + void addStatus(QString key, QString name); + void setStatus(QString key, bool value); +private: /* data */ + QHBoxLayout * layout = nullptr; + QToolButton *m_statusRefresh = nullptr; + QMap<QString, IconLabel *> serverLabels; + QIcon goodIcon; + QIcon badIcon; +}; |