diff options
Diffstat (limited to 'application')
-rw-r--r-- | application/MainWindow.cpp | 270 | ||||
-rw-r--r-- | application/MainWindow.h | 68 | ||||
-rw-r--r-- | application/pages/InstanceSettingsPage.h | 2 | ||||
-rw-r--r-- | application/pages/global/JavaPage.h | 2 | ||||
-rw-r--r-- | application/resources/multimc/multimc.qrc | 7 |
5 files changed, 143 insertions, 206 deletions
diff --git a/application/MainWindow.cpp b/application/MainWindow.cpp index 2469f983..ced644e4 100644 --- a/application/MainWindow.cpp +++ b/application/MainWindow.cpp @@ -21,8 +21,14 @@ #include "MainWindow.h" - #include <QtCore/QVariant> +#include <QtCore/QUrl> +#include <QtCore/QDir> +#include <QtCore/QFileInfo> + +#include <QtGui/QDesktopServices> +#include <QtGui/QKeyEvent> + #include <QtWidgets/QAction> #include <QtWidgets/QApplication> #include <QtWidgets/QButtonGroup> @@ -32,8 +38,61 @@ #include <QtWidgets/QStatusBar> #include <QtWidgets/QToolBar> #include <QtWidgets/QWidget> +#include <QtWidgets/QMenu> +#include <QtWidgets/QMessageBox> +#include <QtWidgets/QInputDialog> +#include <QtWidgets/QLabel> +#include <QtWidgets/QToolButton> +#include <QtWidgets/QWidgetAction> +#include <QtWidgets/QProgressDialog> +#include <QtWidgets/QShortcut> + +#include <BaseInstance.h> +#include <Env.h> +#include <InstanceList.h> +#include <MMCZip.h> +#include <auth/flows/AuthenticateTask.h> +#include <auth/flows/RefreshTask.h> +#include <icons/IconList.h> +#include <java/JavaUtils.h> +#include <java/JavaVersionList.h> +#include <launch/LaunchTask.h> +#include <minecraft/MinecraftVersionList.h> +#include <minecraft/LwjglVersionList.h> +#include <minecraft/SkinUtils.h> +#include <net/URLConstants.h> +#include <net/NetJob.h> +#include <net/CacheDownload.h> +#include <news/NewsChecker.h> +#include <notifications/NotificationChecker.h> +#include <resources/Resource.h> +#include <tools/BaseProfiler.h> +#include <updater/DownloadTask.h> +#include <updater/UpdateChecker.h> -class Ui_MainWindow +#include "InstancePageProvider.h" +#include "InstanceProxyModel.h" +#include "JavaCommon.h" +#include "LaunchInteraction.h" +#include "SettingsUI.h" +#include "groupview/GroupView.h" +#include "groupview/InstanceDelegate.h" +#include "widgets/LabeledToolButton.h" +#include "widgets/ServerStatus.h" +#include "dialogs/NewInstanceDialog.h" +#include "dialogs/ProgressDialog.h" +#include "dialogs/AboutDialog.h" +#include "dialogs/VersionSelectDialog.h" +#include "dialogs/CustomMessageBox.h" +#include "dialogs/IconPickerDialog.h" +#include "dialogs/CopyInstanceDialog.h" +#include "dialogs/AccountSelectDialog.h" +#include "dialogs/UpdateDialog.h" +#include "dialogs/EditAccountDialog.h" +#include "dialogs/NotificationDialog.h" +#include "dialogs/ExportInstanceDialog.h" + +class MainWindow::Ui { public: QAction *actionAddInstance; @@ -310,91 +369,15 @@ public: }; -namespace Ui { - class MainWindow: public Ui_MainWindow {}; -} // namespace Ui - -#include <QMenu> -#include <QMessageBox> -#include <QInputDialog> - -#include <QDesktopServices> -#include <QKeyEvent> -#include <QUrl> -#include <QDir> -#include <QFileInfo> -#include <QLabel> -#include <QToolButton> -#include <QWidgetAction> -#include <QProgressDialog> -#include <QShortcut> - -#include <MMCZip.h> - -#include "groupview/GroupView.h" -#include "groupview/InstanceDelegate.h" -#include "InstanceProxyModel.h" - -#include "widgets/LabeledToolButton.h" -#include "widgets/ServerStatus.h" - -#include "dialogs/NewInstanceDialog.h" -#include "dialogs/ProgressDialog.h" -#include "dialogs/AboutDialog.h" -#include "dialogs/VersionSelectDialog.h" -#include "dialogs/CustomMessageBox.h" -#include "dialogs/IconPickerDialog.h" -#include "dialogs/CopyInstanceDialog.h" -#include "dialogs/AccountSelectDialog.h" -#include "dialogs/UpdateDialog.h" -#include "dialogs/EditAccountDialog.h" -#include "dialogs/NotificationDialog.h" -#include "dialogs/ExportInstanceDialog.h" - -#include "InstanceList.h" -#include "minecraft/MinecraftVersionList.h" -#include "minecraft/LwjglVersionList.h" -#include "icons/IconList.h" -#include "java/JavaVersionList.h" - -#include "auth/flows/AuthenticateTask.h" -#include "auth/flows/RefreshTask.h" - -#include "updater/DownloadTask.h" - -#include "news/NewsChecker.h" - -#include "net/URLConstants.h" -#include "net/NetJob.h" -#include "Env.h" - -#include "BaseInstance.h" -#include "launch/LaunchTask.h" -#include "java/JavaUtils.h" -#include "JavaCommon.h" -#include "InstancePageProvider.h" -#include "LaunchInteraction.h" -#include "SettingsUI.h" -#include "minecraft/SkinUtils.h" -#include "resources/Resource.h" - -#include <updater/UpdateChecker.h> -#include <notifications/NotificationChecker.h> -#include <net/CacheDownload.h> - -#include "tools/BaseProfiler.h" - -MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow::Ui) { ui->setupUi(this); - // initialize the news checker - m_newsChecker.reset(new NewsChecker(BuildConfig.NEWS_RSS_URL)); - - QString winTitle = - QString("MultiMC 5 - Version %1").arg(BuildConfig.printableVersionString()); + QString winTitle = tr("MultiMC 5 - Version %1").arg(BuildConfig.printableVersionString()); if (!BuildConfig.BUILD_PLATFORM.isEmpty()) - winTitle += " on " + BuildConfig.BUILD_PLATFORM; + { + winTitle += tr(" on ") + BuildConfig.BUILD_PLATFORM; + } setWindowTitle(winTitle); // OSX magic. @@ -424,6 +407,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // Add the news label to the news toolbar. { + m_newsChecker.reset(new NewsChecker(BuildConfig.NEWS_RSS_URL)); newsLabel = new QToolButton(); newsLabel->setIcon(MMC->getThemedIcon("news")); newsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -441,41 +425,21 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi view = new GroupView(ui->centralWidget); view->setSelectionMode(QAbstractItemView::SingleSelection); - // view->setCategoryDrawer(drawer); - // view->setCollapsibleBlocks(true); - // view->setViewMode(QListView::IconMode); - // view->setFlow(QListView::LeftToRight); - // view->setWordWrap(true); - // view->setMouseTracking(true); - // view->viewport()->setAttribute(Qt::WA_Hover); - auto delegate = new ListViewDelegate(); - view->setItemDelegate(delegate); - // view->setSpacing(10); - // view->setUniformItemWidths(true); - + view->setItemDelegate(new ListViewDelegate()); + view->setFrameShape(QFrame::NoFrame); // do not show ugly blue border on the mac view->setAttribute(Qt::WA_MacShowFocusRect, false); view->installEventFilter(this); + view->setContextMenuPolicy(Qt::CustomContextMenu); + connect(view, &QWidget::customContextMenuRequested, this, &MainWindow::showInstanceContextMenu); proxymodel = new InstanceProxyModel(this); - // proxymodel->setSortRole(KCategorizedSortFilterProxyModel::CategorySortRole); - // proxymodel->setFilterRole(KCategorizedSortFilterProxyModel::CategorySortRole); - // proxymodel->setDynamicSortFilter ( true ); - - // FIXME: instList should be global-ish, or at least not tied to the main window... - // maybe the application itself? proxymodel->setSourceModel(MMC->instances().get()); proxymodel->sort(0); - view->setFrameShape(QFrame::NoFrame); - view->setModel(proxymodel); - - connect(proxymodel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), SLOT(instanceDataChanged(QModelIndex,QModelIndex))); - - view->setContextMenuPolicy(Qt::CustomContextMenu); - connect(view, SIGNAL(customContextMenuRequested(const QPoint &)), this, - SLOT(showInstanceContextMenu(const QPoint &))); + connect(proxymodel, &InstanceProxyModel::dataChanged, this, &MainWindow::instanceDataChanged); + view->setModel(proxymodel); ui->horizontalLayout->addWidget(view); } // The cat background @@ -486,19 +450,16 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi setCatBackground(cat_enable); } // start instance when double-clicked - connect(view, SIGNAL(doubleClicked(const QModelIndex &)), this, - SLOT(instanceActivated(const QModelIndex &))); + connect(view, &GroupView::doubleClicked, this, &MainWindow::instanceActivated); + // track the selection -- update the instance toolbar - connect(view->selectionModel(), - SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, - SLOT(instanceChanged(const QModelIndex &, const QModelIndex &))); + connect(view->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::instanceChanged); // track icon changes and update the toolbar! - connect(ENV.icons().get(), SIGNAL(iconUpdated(QString)), SLOT(iconUpdated(QString))); + connect(ENV.icons().get(), &IconList::iconUpdated, this, &MainWindow::iconUpdated); // model reset -> selection is invalid. All the instance pointers are wrong. - // FIXME: stop using POINTERS everywhere - connect(MMC->instances().get(), SIGNAL(dataIsInvalid()), SLOT(selectionBad())); + connect(MMC->instances().get(), &InstanceList::dataIsInvalid, this, &MainWindow::selectionBad); m_statusLeft = new QLabel(tr("No instance selected"), this); m_statusRight = new ServerStatus(this); @@ -513,6 +474,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi accountMenu = new QMenu(this); manageAccountsAction = new QAction(tr("Manage Accounts"), this); manageAccountsAction->setCheckable(false); + manageAccountsAction->setIcon(MMC->getThemedIcon("accounts")); connect(manageAccountsAction, SIGNAL(triggered(bool)), this, SLOT(on_actionManageAccounts_triggered())); @@ -547,16 +509,17 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi for (int i = 0; i < accounts->count(); i++) { auto account = accounts->at(i); - if (account != nullptr) + if (!account) { - for (auto profile : account->profiles()) - { - auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.id + ".png"); - auto action = CacheDownload::make( - QUrl("https://" + URLConstants::SKINS_BASE + profile.id + ".png"), meta); - skin_dls.append(action); - meta->stale = true; - } + qWarning() << "Null account at index" << i; + continue; + } + for (auto profile : account->profiles()) + { + auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.id + ".png"); + auto action = CacheDownload::make(QUrl("https://" + URLConstants::SKINS_BASE + profile.id + ".png"), meta); + skin_dls.append(action); + meta->stale = true; } } if (!skin_dls.isEmpty()) @@ -620,8 +583,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi MainWindow::~MainWindow() { - delete ui; - delete proxymodel; } void MainWindow::skinJobFinished() @@ -760,14 +721,6 @@ void MainWindow::repopulateAccountsMenu() for (int i = 0; i < accounts->count(); i++) { MojangAccountPtr account = accounts->at(i); - - // Styling hack - /* - QAction *section = new QAction(account->username(), this); - section->setEnabled(false); - accountMenu->addAction(section); - */ - for (auto profile : account->profiles()) { QAction *action = new QAction(profile.name, this); @@ -1459,15 +1412,18 @@ void MainWindow::on_mainToolBar_visibilityChanged(bool) void MainWindow::on_actionDeleteInstance_triggered() { - if (m_selectedInstance) + if (!m_selectedInstance) { - auto response = CustomMessageBox::selectable( - this, tr("CAREFUL!"), tr("About to delete: %1\nThis is permanent and will completely erase all data, even for tracked instances!\nAre you sure?").arg(m_selectedInstance->name()), - QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No)->exec(); - if (response == QMessageBox::Yes) - { - m_selectedInstance->nuke(); - } + return; + } + auto response = CustomMessageBox::selectable(this, tr("CAREFUL!"), tr("About to delete: %1\nThis is permanent and will completely erase " + "all data, even for tracked instances!\nAre you sure?") + .arg(m_selectedInstance->name()), + QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No) + ->exec(); + if (response == QMessageBox::Yes) + { + m_selectedInstance->nuke(); } } @@ -1520,17 +1476,7 @@ void MainWindow::closeEvent(QCloseEvent *event) QMainWindow::closeEvent(event); QApplication::exit(); } -/* -void MainWindow::on_instanceView_customContextMenuRequested(const QPoint &pos) -{ - QMenu *instContextMenu = new QMenu("Instance", this); - // Add the actions from the toolbar to the context menu. - instContextMenu->addActions(ui->instanceToolBar->actions()); - - instContextMenu->exec(view->mapToGlobal(pos)); -} -*/ void MainWindow::instanceActivated(QModelIndex index) { if (!index.isValid()) @@ -1561,7 +1507,7 @@ void MainWindow::on_actionLaunchInstanceOffline_triggered() void MainWindow::launch(InstancePtr instance, bool online, BaseProfilerFactory* profiler) { - m_launchController = std::make_shared<LaunchController>(); + m_launchController.reset(new LaunchController()); m_launchController->setInstance(instance); m_launchController->setOnline(online); m_launchController->setParentWidget(this); @@ -1569,19 +1515,6 @@ void MainWindow::launch(InstancePtr instance, bool online, BaseProfilerFactory* m_launchController->launch(); } - -/* -void MainWindow::onGameUpdateError(QString error) -{ - CustomMessageBox::selectable(this, tr("Error updating instance"), error, - QMessageBox::Warning)->show(); -} -*/ -void MainWindow::taskStart() -{ - // Nothing to do here yet. -} - void MainWindow::taskEnd() { QObject *sender = QObject::sender(); @@ -1593,7 +1526,6 @@ void MainWindow::taskEnd() void MainWindow::startTask(Task *task) { - connect(task, SIGNAL(started()), SLOT(taskStart())); connect(task, SIGNAL(succeeded()), SLOT(taskEnd())); connect(task, SIGNAL(failed(QString)), SLOT(taskEnd())); task->start(); diff --git a/application/MainWindow.h b/application/MainWindow.h index 7f3f4c63..0685c9f8 100644 --- a/application/MainWindow.h +++ b/application/MainWindow.h @@ -15,6 +15,8 @@ #pragma once +#include <memory> + #include <QMainWindow> #include <QProcess> #include <QTimer> @@ -33,32 +35,26 @@ class LabeledToolButton; class QLabel; class MinecraftLauncher; class BaseProfilerFactory; - -namespace Ui -{ -class MainWindow; -} +class GroupView; +class ServerStatus; class MainWindow : public QMainWindow { Q_OBJECT + class Ui; + public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - void closeEvent(QCloseEvent *event); - - // Browser Dialog - void openWebPage(QUrl url); + virtual bool eventFilter(QObject *obj, QEvent *ev) override; + virtual void closeEvent(QCloseEvent *event) override; void checkSetDefaultJava(); void checkInstancePathForProblems(); -private -slots: - void setSelectedInstanceById(const QString &id); - +private slots: void onCatToggled(bool); void on_actionAbout_triggered(); @@ -101,8 +97,6 @@ slots: void on_mainToolBar_visibilityChanged(bool); - // void on_instanceView_customContextMenuRequested(const QPoint &pos); - void on_actionLaunchInstance_triggered(); void on_actionLaunchInstanceOffline_triggered(); @@ -119,19 +113,19 @@ slots: void on_actionScreenshots_triggered(); - void taskStart(); void taskEnd(); - // called when an icon is changed in the icon model. + /** + * called when an icon is changed in the icon model. + */ void iconUpdated(QString); void showInstanceContextMenu(const QPoint &); void updateToolsMenu(); - void skinJobFinished(); -public -slots: + void skinJobFinished(); + void instanceActivated(QModelIndex); void instanceChanged(const QModelIndex ¤t, const QModelIndex &previous); @@ -161,10 +155,10 @@ slots: */ void downloadUpdates(GoUpdate::Status status); -protected: - bool eventFilter(QObject *obj, QEvent *ev); +private: void setCatBackground(bool enabled); void updateInstanceToolIcon(QString new_icon); + void setSelectedInstanceById(const QString &id); void waitForMinecraftVersions(); InstancePtr instanceFromVersion(QString instName, QString instGroup, QString instIcon, BaseVersionPtr version); @@ -172,28 +166,32 @@ protected: void finalizeInstance(InstancePtr inst); void launch(InstancePtr instance, bool online = true, BaseProfilerFactory *profiler = nullptr); + /// open a web page in the default browser + void openWebPage(QUrl url); + private: - Ui::MainWindow *ui; - class GroupView *view; + std::unique_ptr<Ui> ui; + + // these are managed by Qt's memory management model! + GroupView *view; InstanceProxyModel *proxymodel; - NetJobPtr skin_download_job; LabeledToolButton *renameButton; QToolButton *changeIconButton; QToolButton *newsLabel; + QLabel *m_statusLeft; + ServerStatus *m_statusRight; + QMenu *accountMenu; + QToolButton *accountMenuButton; + QAction *manageAccountsAction; - std::shared_ptr<NewsChecker> m_newsChecker; - std::shared_ptr<NotificationChecker> m_notificationChecker; - std::shared_ptr<LaunchController> m_launchController; + unique_qobject_ptr<NetJob> skin_download_job; + unique_qobject_ptr<NewsChecker> m_newsChecker; + unique_qobject_ptr<NotificationChecker> m_notificationChecker; + unique_qobject_ptr<LaunchController> m_launchController; InstancePtr m_selectedInstance; QString m_currentInstIcon; + // managed by the application object Task *m_versionLoadTask; - - QLabel *m_statusLeft; - class ServerStatus *m_statusRight; - - QMenu *accountMenu; - QToolButton *accountMenuButton; - QAction *manageAccountsAction; }; diff --git a/application/pages/InstanceSettingsPage.h b/application/pages/InstanceSettingsPage.h index 1fc0bdfe..33efe6c3 100644 --- a/application/pages/InstanceSettingsPage.h +++ b/application/pages/InstanceSettingsPage.h @@ -70,5 +70,5 @@ private: Ui::InstanceSettingsPage *ui; BaseInstance *m_instance; SettingsObjectPtr m_settings; - QObjectPtr<JavaCommon::TestCheck> checker; + unique_qobject_ptr<JavaCommon::TestCheck> checker; }; diff --git a/application/pages/global/JavaPage.h b/application/pages/global/JavaPage.h index 4dd2b306..7ae068ab 100644 --- a/application/pages/global/JavaPage.h +++ b/application/pages/global/JavaPage.h @@ -68,5 +68,5 @@ slots: private: Ui::JavaPage *ui; - QObjectPtr<JavaCommon::TestCheck> checker; + unique_qobject_ptr<JavaCommon::TestCheck> checker; }; diff --git a/application/resources/multimc/multimc.qrc b/application/resources/multimc/multimc.qrc index 76559282..1300bdd7 100644 --- a/application/resources/multimc/multimc.qrc +++ b/application/resources/multimc/multimc.qrc @@ -210,6 +210,13 @@ <file>32x32/noaccount.png</file> <file>48x48/noaccount.png</file> + <!-- and the same again. TODO: make a nice accounts icon --> + <file alias="8x8/accounts.png">8x8/noaccount.png</file> + <file alias="16x16/accounts.png">16x16/noaccount.png</file> + <file alias="24x24/accounts.png">24x24/noaccount.png</file> + <file alias="32x32/accounts.png">32x32/noaccount.png</file> + <file alias="48x48/accounts.png">48x48/noaccount.png</file> + <!-- Log file, LGPL, http://www.iconarchive.com/show/crystal-clear-icons-by-everaldo/Mimetype-text-icon.html --> <file>16x16/log.png</file> <file>24x24/log.png</file> |