From 4c0dc51110603cbe0e98228c703e26402094a3cc Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Sat, 12 Jul 2014 23:02:52 +0200 Subject: [PATCH] Finish of the OtherLogs page, and (re)format page related files --- .clang-format | 1 + gui/pagedialog/PageDialog.cpp | 30 ++++--- gui/pagedialog/PageDialog.h | 5 +- gui/pages/BasePage.h | 26 ++---- gui/pages/InstanceSettingsPage.cpp | 27 ++----- gui/pages/InstanceSettingsPage.h | 28 +++++-- gui/pages/LegacyJarModPage.cpp | 26 ++---- gui/pages/LegacyJarModPage.h | 25 ++++-- gui/pages/LegacyUpgradePage.cpp | 16 +--- gui/pages/LegacyUpgradePage.h | 25 ++++-- gui/pages/LogPage.cpp | 15 ---- gui/pages/LogPage.h | 30 ++++--- gui/pages/ModFolderPage.cpp | 41 +++------- gui/pages/ModFolderPage.h | 20 +++-- gui/pages/NotesPage.cpp | 15 ---- gui/pages/NotesPage.h | 25 ++++-- gui/pages/OtherLogsPage.cpp | 82 ++++++++++++------- gui/pages/OtherLogsPage.h | 42 ++++++++-- gui/pages/OtherLogsPage.ui | 9 ++- gui/pages/ResourcePackPage.h | 4 +- gui/pages/ScreenshotsPage.cpp | 113 ++++++++++----------------- gui/pages/ScreenshotsPage.h | 35 ++++++--- gui/pages/VersionPage.cpp | 27 ++----- gui/pages/VersionPage.h | 20 +++-- gui/widgets/PageContainer.cpp | 13 ++- gui/widgets/PageContainer.h | 8 +- gui/widgets/PageContainer_p.h | 18 ++++- logic/RecursiveFileSystemWatcher.cpp | 38 +++++---- logic/RecursiveFileSystemWatcher.h | 8 +- resources/multimc/16x16/log.png | Bin 0 -> 630 bytes resources/multimc/24x24/log.png | Bin 0 -> 1117 bytes resources/multimc/32x32/log.png | Bin 0 -> 1460 bytes resources/multimc/48x48/log.png | Bin 0 -> 2825 bytes resources/multimc/64x64/log.png | Bin 0 -> 3686 bytes resources/multimc/multimc.qrc | 7 ++ 35 files changed, 423 insertions(+), 356 deletions(-) create mode 100644 resources/multimc/16x16/log.png create mode 100644 resources/multimc/24x24/log.png create mode 100644 resources/multimc/32x32/log.png create mode 100644 resources/multimc/48x48/log.png create mode 100644 resources/multimc/64x64/log.png diff --git a/.clang-format b/.clang-format index 167a8fa7..4aec119c 100644 --- a/.clang-format +++ b/.clang-format @@ -9,6 +9,7 @@ NamespaceIndentation: None BreakBeforeBraces: Allman AllowShortIfStatementsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None ColumnLimit: 96 MaxEmptyLinesToKeep: 1 diff --git a/gui/pagedialog/PageDialog.cpp b/gui/pagedialog/PageDialog.cpp index 4dd4a811..c0bcdf9f 100644 --- a/gui/pagedialog/PageDialog.cpp +++ b/gui/pagedialog/PageDialog.cpp @@ -14,18 +14,20 @@ */ #include "PageDialog.h" -#include "gui/Platform.h" -#include "MultiMC.h" -#include "logic/settings/SettingsObject.h" -#include -#include #include #include #include -#include +#include -PageDialog::PageDialog(BasePageProviderPtr pageProvider, QString defaultId, QWidget *parent) : QDialog(parent) +#include "MultiMC.h" +#include "logic/settings/SettingsObject.h" +#include "gui/Platform.h" +#include "gui/widgets/IconLabel.h" +#include "gui/widgets/PageContainer.h" + +PageDialog::PageDialog(BasePageProviderPtr pageProvider, QString defaultId, QWidget *parent) + : QDialog(parent) { MultiMCPlatform::fixWM_CLASS(this); setWindowTitle(pageProvider->dialogTitle()); @@ -34,23 +36,25 @@ PageDialog::PageDialog(BasePageProviderPtr pageProvider, QString defaultId, QWid QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(m_container); mainLayout->setSpacing(0); - mainLayout->setContentsMargins(0,0,0,0); + mainLayout->setContentsMargins(0, 0, 0, 0); setLayout(mainLayout); - + QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Close); buttons->button(QDialogButtonBox::Close)->setDefault(true); m_container->addButtons(buttons); connect(buttons->button(QDialogButtonBox::Close), SIGNAL(clicked()), this, SLOT(close())); - connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, SLOT(help())); + connect(buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()), m_container, + SLOT(help())); - restoreGeometry(QByteArray::fromBase64(MMC->settings()->get("PagedGeometry").toByteArray())); + restoreGeometry( + QByteArray::fromBase64(MMC->settings()->get("PagedGeometry").toByteArray())); } -void PageDialog::closeEvent(QCloseEvent * event) +void PageDialog::closeEvent(QCloseEvent *event) { - if(m_container->requestClose(event)) + if (m_container->requestClose(event)) { MMC->settings()->set("PagedGeometry", saveGeometry().toBase64()); QDialog::closeEvent(event); diff --git a/gui/pagedialog/PageDialog.h b/gui/pagedialog/PageDialog.h index 097eac64..19d1b01f 100644 --- a/gui/pagedialog/PageDialog.h +++ b/gui/pagedialog/PageDialog.h @@ -14,8 +14,9 @@ */ #pragma once + #include -#include +#include "gui/pages/BasePageProvider.h" class PageContainer; class PageDialog : public QDialog @@ -24,7 +25,7 @@ class PageDialog : public QDialog public: explicit PageDialog(BasePageProviderPtr pageProvider, QString defaultId = QString(), QWidget *parent = 0); - virtual ~PageDialog() {}; + virtual ~PageDialog() {} private slots: diff --git a/gui/pages/BasePage.h b/gui/pages/BasePage.h index 26c0b9f7..2cc602b7 100644 --- a/gui/pages/BasePage.h +++ b/gui/pages/BasePage.h @@ -14,6 +14,7 @@ */ #pragma once + #include #include #include @@ -21,28 +22,15 @@ class BasePage { public: - virtual ~BasePage(){} + virtual ~BasePage() {} virtual QString id() const = 0; virtual QString displayName() const = 0; virtual QIcon icon() const = 0; - virtual bool apply() - { - return true; - } - virtual bool shouldDisplay() const - { - return true; - } - virtual QString helpPage() const - { - return QString(); - } - virtual void opened() - { - } - virtual void closed() - { - } + virtual bool apply() { return true; } + virtual bool shouldDisplay() const { return true; } + virtual QString helpPage() const { return QString(); } + virtual void opened() {} + virtual void closed() {} int stackIndex = -1; int listIndex = -1; }; diff --git a/gui/pages/InstanceSettingsPage.cpp b/gui/pages/InstanceSettingsPage.cpp index 25fe46e5..34b1b401 100644 --- a/gui/pages/InstanceSettingsPage.cpp +++ b/gui/pages/InstanceSettingsPage.cpp @@ -1,27 +1,14 @@ #include "InstanceSettingsPage.h" -#include -#include "logic/NagUtils.h" -#include -#include "MultiMC.h" -#include -#include -#include #include "ui_InstanceSettingsPage.h" -QString InstanceSettingsPage::displayName() const -{ - return tr("Settings"); -} +#include +#include +#include -QIcon InstanceSettingsPage::icon() const -{ - return QIcon::fromTheme("settings"); -} - -QString InstanceSettingsPage::id() const -{ - return "settings"; -} +#include "gui/dialogs/VersionSelectDialog.h" +#include "logic/NagUtils.h" +#include "logic/java/JavaVersionList.h" +#include "MultiMC.h" InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst) diff --git a/gui/pages/InstanceSettingsPage.h b/gui/pages/InstanceSettingsPage.h index 7052040c..988862cf 100644 --- a/gui/pages/InstanceSettingsPage.h +++ b/gui/pages/InstanceSettingsPage.h @@ -14,11 +14,12 @@ */ #pragma once + #include -#include -#include -#include +#include "logic/OneSixInstance.h" +#include "logic/net/NetJob.h" +#include "logic/java/JavaChecker.h" #include "BasePage.h" class JavaChecker; @@ -34,11 +35,23 @@ class InstanceSettingsPage : public QWidget, public BasePage public: explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0); virtual ~InstanceSettingsPage(); - virtual QString displayName() const override; - virtual QIcon icon() const override; - virtual QString id() const override; + virtual QString displayName() const override + { + return tr("Settings"); + } + virtual QIcon icon() const override + { + return QIcon::fromTheme("settings"); + } + virtual QString id() const override + { + return "settings"; + } virtual bool apply(); - virtual QString helpPage() const override { return "Instance-settings"; } + virtual QString helpPage() const override + { + return "Instance-settings"; + } virtual bool shouldDisplay() const; private slots: void on_javaDetectBtn_clicked(); @@ -51,6 +64,7 @@ private slots: void applySettings(); void loadSettings(); + private: Ui::InstanceSettingsPage *ui; BaseInstance *m_instance; diff --git a/gui/pages/LegacyJarModPage.cpp b/gui/pages/LegacyJarModPage.cpp index 8acb2d50..16a2ff66 100644 --- a/gui/pages/LegacyJarModPage.cpp +++ b/gui/pages/LegacyJarModPage.cpp @@ -15,6 +15,13 @@ #include "LegacyJarModPage.h" #include "ui_LegacyJarModPage.h" + +#include +#include +#include + +#include + #include "gui/dialogs/VersionSelectDialog.h" #include "gui/dialogs/ProgressDialog.h" #include "gui/dialogs/ModEditDialogCommon.h" @@ -23,10 +30,6 @@ #include "logic/forge/ForgeVersion.h" #include "logic/forge/ForgeVersionList.h" #include "MultiMC.h" -#include -#include -#include -#include LegacyJarModPage::LegacyJarModPage(LegacyInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::LegacyJarModPage), m_inst(inst) @@ -49,26 +52,11 @@ LegacyJarModPage::~LegacyJarModPage() delete ui; } -QString LegacyJarModPage::displayName() const -{ - return tr("Jar Mods"); -} - bool LegacyJarModPage::shouldDisplay() const { return !m_inst->isRunning(); } -QIcon LegacyJarModPage::icon() const -{ - return QIcon::fromTheme("plugin-red"); -} - -QString LegacyJarModPage::id() const -{ - return "jarmods"; -} - bool LegacyJarModPage::eventFilter(QObject *obj, QEvent *ev) { if (ev->type() != QEvent::KeyPress || obj != ui->jarModsTreeView) diff --git a/gui/pages/LegacyJarModPage.h b/gui/pages/LegacyJarModPage.h index 261d9020..1a72abf3 100644 --- a/gui/pages/LegacyJarModPage.h +++ b/gui/pages/LegacyJarModPage.h @@ -15,8 +15,9 @@ #pragma once -#include -#include +#include + +#include "logic/net/NetJob.h" #include "BasePage.h" class ModList; @@ -34,10 +35,22 @@ public: explicit LegacyJarModPage(LegacyInstance *inst, QWidget *parent = 0); virtual ~LegacyJarModPage(); - virtual QString displayName() const; - virtual QIcon icon() const; - virtual QString id() const; - virtual QString helpPage() const override { return "Legacy-jar-mods"; } + virtual QString displayName() const + { + return tr("Jar Mods"); + } + virtual QIcon icon() const + { + return QIcon::fromTheme("plugin-red"); + } + virtual QString id() const + { + return "jarmods"; + } + virtual QString helpPage() const override + { + return "Legacy-jar-mods"; + } virtual bool shouldDisplay() const; private diff --git a/gui/pages/LegacyUpgradePage.cpp b/gui/pages/LegacyUpgradePage.cpp index bc800bc8..79478efb 100644 --- a/gui/pages/LegacyUpgradePage.cpp +++ b/gui/pages/LegacyUpgradePage.cpp @@ -1,21 +1,7 @@ #include "LegacyUpgradePage.h" -#include #include "ui_LegacyUpgradePage.h" -QString LegacyUpgradePage::displayName() const -{ - return tr("Upgrade"); -} - -QIcon LegacyUpgradePage::icon() const -{ - return QIcon::fromTheme("checkupdate"); -} - -QString LegacyUpgradePage::id() const -{ - return "upgrade"; -} +#include "logic/LegacyInstance.h" LegacyUpgradePage::LegacyUpgradePage(LegacyInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst) diff --git a/gui/pages/LegacyUpgradePage.h b/gui/pages/LegacyUpgradePage.h index c9eede72..4fd88b5b 100644 --- a/gui/pages/LegacyUpgradePage.h +++ b/gui/pages/LegacyUpgradePage.h @@ -14,10 +14,11 @@ */ #pragma once + #include -#include -#include +#include "logic/OneSixInstance.h" +#include "logic/net/NetJob.h" #include "BasePage.h" class EnabledItemFilter; @@ -33,10 +34,22 @@ class LegacyUpgradePage : public QWidget, public BasePage public: explicit LegacyUpgradePage(LegacyInstance *inst, QWidget *parent = 0); virtual ~LegacyUpgradePage(); - virtual QString displayName() const override; - virtual QIcon icon() const override; - virtual QString id() const override; - virtual QString helpPage() const override { return "Legacy-upgrade"; } + virtual QString displayName() const override + { + return tr("Upgrade"); + } + virtual QIcon icon() const override + { + return QIcon::fromTheme("checkupdate"); + } + virtual QString id() const override + { + return "upgrade"; + } + virtual QString helpPage() const override + { + return "Legacy-upgrade"; + } virtual bool shouldDisplay() const; private slots: diff --git a/gui/pages/LogPage.cpp b/gui/pages/LogPage.cpp index a7a0171f..601c738f 100644 --- a/gui/pages/LogPage.cpp +++ b/gui/pages/LogPage.cpp @@ -7,21 +7,6 @@ #include "logic/MinecraftProcess.h" #include "gui/GuiUtil.h" -QString LogPage::displayName() const -{ - return tr("Minecraft Log"); -} - -QIcon LogPage::icon() const -{ - return QIcon::fromTheme("refresh"); -} - -QString LogPage::id() const -{ - return "console"; -} - LogPage::LogPage(MinecraftProcess *proc, QWidget *parent) : QWidget(parent), ui(new Ui::LogPage), m_process(proc) { diff --git a/gui/pages/LogPage.h b/gui/pages/LogPage.h index 72ca09ec..be5b3a20 100644 --- a/gui/pages/LogPage.h +++ b/gui/pages/LogPage.h @@ -13,13 +13,13 @@ * limitations under the License. */ - #pragma once + #include -#include -#include -#include +#include "logic/BaseInstance.h" +#include "logic/net/NetJob.h" +#include "logic/MinecraftProcess.h" #include "BasePage.h" class EnabledItemFilter; @@ -36,11 +36,23 @@ class LogPage : public QWidget, public BasePage public: explicit LogPage(MinecraftProcess *proc, QWidget *parent = 0); virtual ~LogPage(); - virtual QString displayName() const override; - virtual QIcon icon() const override; - virtual QString id() const override; + virtual QString displayName() const override + { + return tr("Minecraft Log"); + } + virtual QIcon icon() const override + { + return QIcon::fromTheme("log"); + } + virtual QString id() const override + { + return "console"; + } virtual bool apply(); - virtual QString helpPage() const override { return "Minecraft-Log"; } + virtual QString helpPage() const override + { + return "Minecraft-Log"; + } virtual bool shouldDisplay() const; private: @@ -64,7 +76,7 @@ private slots: void on_btnPaste_clicked(); void on_btnCopy_clicked(); void on_btnClear_clicked(); - + private: Ui::LogPage *ui; MinecraftProcess *m_process; diff --git a/gui/pages/ModFolderPage.cpp b/gui/pages/ModFolderPage.cpp index a01e215d..d94696ec 100644 --- a/gui/pages/ModFolderPage.cpp +++ b/gui/pages/ModFolderPage.cpp @@ -13,9 +13,9 @@ * limitations under the License. */ -#include "MultiMC.h" +#include "ModFolderPage.h" +#include "ui_ModFolderPage.h" -#include #include #include #include @@ -23,33 +23,18 @@ #include #include -#include "ModFolderPage.h" -#include "ui_ModFolderPage.h" +#include +#include "MultiMC.h" #include "gui/dialogs/CustomMessageBox.h" #include "gui/dialogs/ModEditDialogCommon.h" - #include "logic/ModList.h" #include "logic/Mod.h" -#include +#include "logic/VersionFilterData.h" -QString ModFolderPage::displayName() const -{ - return m_displayName; -} - -QIcon ModFolderPage::icon() const -{ - return QIcon::fromTheme(m_iconName); -} - -QString ModFolderPage::id() const -{ - return m_id; -} - -ModFolderPage::ModFolderPage(BaseInstance * inst, std::shared_ptr mods, QString id, QString iconName, - QString displayName, QString helpPage, QWidget *parent) +ModFolderPage::ModFolderPage(BaseInstance *inst, std::shared_ptr mods, QString id, + QString iconName, QString displayName, QString helpPage, + QWidget *parent) : QWidget(parent), ui(new Ui::ModFolderPage) { ui->setupUi(this); @@ -82,7 +67,7 @@ ModFolderPage::~ModFolderPage() bool ModFolderPage::shouldDisplay() const { - if(m_inst) + if (m_inst) return !m_inst->isRunning(); return true; } @@ -91,13 +76,13 @@ bool CoreModFolderPage::shouldDisplay() const { if (ModFolderPage::shouldDisplay()) { - auto inst = dynamic_cast(m_inst); - if(!inst) + auto inst = dynamic_cast(m_inst); + if (!inst) return true; auto version = inst->getFullVersion(); - if(!version) + if (!version) return true; - if(version->m_releaseTime < g_VersionFilterData.legacyCutoffDate) + if (version->m_releaseTime < g_VersionFilterData.legacyCutoffDate) { return true; } diff --git a/gui/pages/ModFolderPage.h b/gui/pages/ModFolderPage.h index 2103ce26..4d72fb8b 100644 --- a/gui/pages/ModFolderPage.h +++ b/gui/pages/ModFolderPage.h @@ -14,10 +14,11 @@ */ #pragma once + #include -#include -#include +#include "logic/OneSixInstance.h" +#include "logic/net/NetJob.h" #include "BasePage.h" class EnabledItemFilter; @@ -36,9 +37,18 @@ public: QString iconName, QString displayName, QString helpPage = "", QWidget *parent = 0); virtual ~ModFolderPage(); - virtual QString displayName() const override; - virtual QIcon icon() const override; - virtual QString id() const override; + virtual QString displayName() const override + { + return m_displayName; + } + virtual QIcon icon() const override + { + return QIcon::fromTheme(m_iconName); + } + virtual QString id() const override + { + return m_id; + } virtual QString helpPage() const override { return m_helpName; diff --git a/gui/pages/NotesPage.cpp b/gui/pages/NotesPage.cpp index d99014ff..a2558e3c 100644 --- a/gui/pages/NotesPage.cpp +++ b/gui/pages/NotesPage.cpp @@ -1,21 +1,6 @@ #include "NotesPage.h" #include "ui_NotesPage.h" -QString NotesPage::displayName() const -{ - return tr("Notes"); -} - -QIcon NotesPage::icon() const -{ - return QIcon::fromTheme("news"); -} - -QString NotesPage::id() const -{ - return "notes"; -} - NotesPage::NotesPage(BaseInstance *inst, QWidget *parent) : QWidget(parent), ui(new Ui::NotesPage), m_inst(inst) { diff --git a/gui/pages/NotesPage.h b/gui/pages/NotesPage.h index ad0a7701..81338e57 100644 --- a/gui/pages/NotesPage.h +++ b/gui/pages/NotesPage.h @@ -14,10 +14,11 @@ */ #pragma once + #include -#include -#include +#include "logic/BaseInstance.h" +#include "logic/net/NetJob.h" #include "BasePage.h" class EnabledItemFilter; @@ -33,11 +34,23 @@ class NotesPage : public QWidget, public BasePage public: explicit NotesPage(BaseInstance *inst, QWidget *parent = 0); virtual ~NotesPage(); - virtual QString displayName() const override; - virtual QIcon icon() const override; - virtual QString id() const override; + virtual QString displayName() const override + { + return tr("Notes"); + } + virtual QIcon icon() const override + { + return QIcon::fromTheme("news"); + } + virtual QString id() const override + { + return "notes"; + } virtual bool apply(); - virtual QString helpPage() const override { return "Notes"; } + virtual QString helpPage() const override + { + return "Notes"; + } private: Ui::NotesPage *ui; diff --git a/gui/pages/OtherLogsPage.cpp b/gui/pages/OtherLogsPage.cpp index 3ea1f170..f20b9fef 100644 --- a/gui/pages/OtherLogsPage.cpp +++ b/gui/pages/OtherLogsPage.cpp @@ -1,3 +1,18 @@ +/* Copyright 2014 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 "OtherLogsPage.h" #include "ui_OtherLogsPage.h" @@ -8,28 +23,18 @@ #include "logic/RecursiveFileSystemWatcher.h" #include "logic/BaseInstance.h" -OtherLogsPage::OtherLogsPage(BaseInstance *instance, QWidget *parent) : - QWidget(parent), - ui(new Ui::OtherLogsPage), - m_instance(instance), - m_watcher(new RecursiveFileSystemWatcher(this)) +OtherLogsPage::OtherLogsPage(BaseInstance *instance, QWidget *parent) + : QWidget(parent), ui(new Ui::OtherLogsPage), m_instance(instance), + m_watcher(new RecursiveFileSystemWatcher(this)) { ui->setupUi(this); - connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, [this]() - { - ui->selectLogBox->clear(); - ui->selectLogBox->addItems(m_watcher->files()); - ui->selectLogBox->addItem(tr("&Other"), true); - if (m_currentFile.isNull()) - { - ui->selectLogBox->setCurrentIndex(-1); - } - else - { - const int index = ui->selectLogBox->findText(m_currentFile); - ui->selectLogBox->setCurrentIndex(-1); - } - }); + + m_watcher->setFileExpression(".*\\.log$"); + m_watcher->setRootDir(QDir::current().absoluteFilePath(m_instance->minecraftRoot())); + + connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, this, + &OtherLogsPage::populateSelectLogBox); + populateSelectLogBox(); } OtherLogsPage::~OtherLogsPage() @@ -46,6 +51,22 @@ void OtherLogsPage::closed() m_watcher->disable(); } +void OtherLogsPage::populateSelectLogBox() +{ + ui->selectLogBox->clear(); + ui->selectLogBox->addItems(m_watcher->files()); + ui->selectLogBox->addItem(tr("Other"), true); + if (m_currentFile.isNull()) + { + ui->selectLogBox->setCurrentIndex(-1); + } + else + { + const int index = ui->selectLogBox->findText(m_currentFile); + ui->selectLogBox->setCurrentIndex(index); + } +} + void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) { QString file; @@ -53,7 +74,8 @@ void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) { if (ui->selectLogBox->itemData(index).isValid()) { - file = QFileDialog::getOpenFileName(this, tr("Open log file"), m_instance->minecraftRoot(), tr("*.log;;*.txt;;*")); + file = QFileDialog::getOpenFileName( + this, tr("Open log file"), m_instance->minecraftRoot(), tr("*.log;;*.txt;;*")); } else { @@ -61,9 +83,10 @@ void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) } } - if (file.isEmpty() || !QFile::exists(file)) + if (file.isEmpty() || !QFile::exists(m_instance->minecraftRoot() + "/" + file)) { m_currentFile = QString(); + ui->text->clear(); setControlsEnabled(false); } else @@ -76,13 +99,14 @@ void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index) void OtherLogsPage::on_btnReload_clicked() { - QFile file(m_currentFile); + QFile file(m_instance->minecraftRoot() + "/" + m_currentFile); if (!file.open(QFile::ReadOnly)) { setControlsEnabled(false); ui->btnReload->setEnabled(true); // allow reload m_currentFile = QString(); - QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2").arg(m_currentFile, file.errorString())); + QMessageBox::critical(this, tr("Error"), tr("Unable to open %1 for reading: %2") + .arg(m_currentFile, file.errorString())); } else { @@ -100,15 +124,17 @@ void OtherLogsPage::on_btnCopy_clicked() } void OtherLogsPage::on_btnDelete_clicked() { - if (QMessageBox::question(this, tr("Delete"), tr("Do you really want to delete %1?").arg(m_currentFile), QMessageBox::Yes, QMessageBox::No) - == QMessageBox::No) + if (QMessageBox::question(this, tr("Delete"), + tr("Do you really want to delete %1?").arg(m_currentFile), + QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) { return; } - QFile file(m_currentFile); + QFile file(m_instance->minecraftRoot() + "/" + m_currentFile); if (!file.remove()) { - QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2").arg(m_currentFile, file.errorString())); + QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2") + .arg(m_currentFile, file.errorString())); } } diff --git a/gui/pages/OtherLogsPage.h b/gui/pages/OtherLogsPage.h index e89b3bce..5cabf03f 100644 --- a/gui/pages/OtherLogsPage.h +++ b/gui/pages/OtherLogsPage.h @@ -1,10 +1,26 @@ +/* Copyright 2014 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. + */ + #pragma once #include #include "BasePage.h" -namespace Ui { +namespace Ui +{ class OtherLogsPage; } @@ -20,15 +36,27 @@ public: explicit OtherLogsPage(BaseInstance *instance, QWidget *parent = 0); ~OtherLogsPage(); - QString id() const override { return "logs"; } - QString displayName() const override { return tr("Other logs"); } - QIcon icon() const override { return QIcon(); } // TODO - QString helpPage() const override { return "Minecraft-Logs"; } + QString id() const override + { + return "logs"; + } + QString displayName() const override + { + return tr("Other logs"); + } + QIcon icon() const override + { + return QIcon::fromTheme("log"); + } + QString helpPage() const override + { + return "Minecraft-Logs"; + } void opened() override; void closed() override; -private -slots: +private slots: + void populateSelectLogBox(); void on_selectLogBox_currentIndexChanged(const int index); void on_btnReload_clicked(); void on_btnPaste_clicked(); diff --git a/gui/pages/OtherLogsPage.ui b/gui/pages/OtherLogsPage.ui index 471c7d72..e6ce6397 100644 --- a/gui/pages/OtherLogsPage.ui +++ b/gui/pages/OtherLogsPage.ui @@ -39,7 +39,14 @@ - + + + + 96 + 16777215 + + + diff --git a/gui/pages/ResourcePackPage.h b/gui/pages/ResourcePackPage.h index b3c5df46..1a9039ff 100644 --- a/gui/pages/ResourcePackPage.h +++ b/gui/pages/ResourcePackPage.h @@ -5,8 +5,8 @@ class ResourcePackPage : public ModFolderPage { public: explicit ResourcePackPage(BaseInstance *instance, QWidget *parent = 0) - : ModFolderPage(instance, instance->resourcePackList(), "resourcepacks", "resourcepacks", - tr("Resource packs"), "Resource-packs", parent) + : ModFolderPage(instance, instance->resourcePackList(), "resourcepacks", + "resourcepacks", tr("Resource packs"), "Resource-packs", parent) { } diff --git a/gui/pages/ScreenshotsPage.cpp b/gui/pages/ScreenshotsPage.cpp index 415aa576..004f797b 100644 --- a/gui/pages/ScreenshotsPage.cpp +++ b/gui/pages/ScreenshotsPage.cpp @@ -9,10 +9,11 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include @@ -24,30 +25,25 @@ #include "logic/tasks/SequentialTask.h" #include "logic/RWStorage.h" + typedef RWStorage SharedIconCache; typedef std::shared_ptr SharedIconCachePtr; class ThumbnailingResult : public QObject { Q_OBJECT -public Q_SLOTS: - inline void emitResultsReady(const QString &path) - { - emit resultsReady(path); - } - inline void emitResultsFailed(const QString &path) - { - emit resultsFailed(path); - } -Q_SIGNALS: +public slots: + inline void emitResultsReady(const QString &path) { emit resultsReady(path); } + inline void emitResultsFailed(const QString &path) { emit resultsFailed(path); } +signals: void resultsReady(const QString &path); void resultsFailed(const QString &path); }; -class ThumbnailRunnable: public QRunnable +class ThumbnailRunnable : public QRunnable { public: - ThumbnailRunnable (QString path, SharedIconCachePtr cache) + ThumbnailRunnable(QString path, SharedIconCachePtr cache) { m_path = path; m_cache = cache; @@ -55,14 +51,14 @@ public: void run() { QFileInfo info(m_path); - if(info.isDir()) + if (info.isDir()) return; - if((info.suffix().compare("png", Qt::CaseInsensitive) != 0)) + if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0)) return; int tries = 5; - while(tries) + while (tries) { - if(!m_cache->stale(m_path)) + if (!m_cache->stale(m_path)) return; QImage image(m_path); if (image.isNull()) @@ -72,19 +68,19 @@ public: continue; } QImage small; - if(image.width() > image.height()) + if (image.width() > image.height()) small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation); else small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation); auto smallSize = small.size(); - QPoint offset((256-small.width())/2, (256-small.height())/2); - QImage square(QSize(256,256), QImage::Format_ARGB32); + QPoint offset((256 - small.width()) / 2, (256 - small.height()) / 2); + QImage square(QSize(256, 256), QImage::Format_ARGB32); square.fill(Qt::transparent); - + QPainter painter(&square); painter.drawImage(offset, small); painter.end(); - + QIcon icon(QPixmap::fromImage(square)); m_cache->add(m_path, icon); m_resultEmitter.emitResultsReady(m_path); @@ -97,12 +93,13 @@ public: ThumbnailingResult m_resultEmitter; }; -// this is about as elegant and well written as a bag of bricks with scribbles done by insane asylum patients. +// this is about as elegant and well written as a bag of bricks with scribbles done by insane +// asylum patients. class FilterModel : public QIdentityProxyModel { Q_OBJECT public: - explicit FilterModel(QObject *parent = 0):QIdentityProxyModel(parent) + explicit FilterModel(QObject *parent = 0) : QIdentityProxyModel(parent) { m_thumbnailingPool.setMaxThreadCount(4); m_thumbnailCache = std::make_shared(); @@ -110,10 +107,7 @@ public: connect(&watcher, SIGNAL(fileChanged(QString)), SLOT(fileChanged(QString))); // FIXME: the watched file set is not updated when files are removed } - virtual ~FilterModel() - { - m_thumbnailingPool.waitForDone(500); - } + virtual ~FilterModel() { m_thumbnailingPool.waitForDone(500); } virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const { auto model = sourceModel(); @@ -126,23 +120,24 @@ public: } if (role == Qt::DecorationRole) { - QVariant result = sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole); + QVariant result = + sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole); QString filePath = result.toString(); QIcon temp; - if(!watched.contains(filePath)) + if (!watched.contains(filePath)) { ((QFileSystemWatcher &)watcher).addPath(filePath); ((QSet &)watched).insert(filePath); } - if(m_thumbnailCache->get(filePath, temp)) + if (m_thumbnailCache->get(filePath, temp)) { return temp; } - if(!m_failed.contains(filePath)) + if (!m_failed.contains(filePath)) { ((FilterModel *)this)->thumbnailImage(filePath); } - return(m_thumbnailCache->get("placeholder")); + return (m_thumbnailCache->get("placeholder")); } return sourceModel()->data(mapToSource(proxyIndex), role); } @@ -162,24 +157,20 @@ public: } return model->setData(mapToSource(index), value.toString() + ".png", role); } + private: void thumbnailImage(QString path) { auto runnable = new ThumbnailRunnable(path, m_thumbnailCache); - connect(&(runnable->m_resultEmitter),SIGNAL(resultsReady(QString)), SLOT(thumbnailReady(QString))); - connect(&(runnable->m_resultEmitter),SIGNAL(resultsFailed(QString)), SLOT(thumbnailFailed(QString))); + connect(&(runnable->m_resultEmitter), SIGNAL(resultsReady(QString)), + SLOT(thumbnailReady(QString))); + connect(&(runnable->m_resultEmitter), SIGNAL(resultsFailed(QString)), + SLOT(thumbnailFailed(QString))); ((QThreadPool &)m_thumbnailingPool).start(runnable); } -private -slots: - void thumbnailReady(QString path) - { - emit layoutChanged(); - } - void thumbnailFailed(QString path) - { - m_failed.insert(path); - } +private slots: + void thumbnailReady(QString path) { emit layoutChanged(); } + void thumbnailFailed(QString path) { m_failed.insert(path); } void fileChanged(QString filepath) { m_thumbnailCache->setStale(filepath); @@ -200,12 +191,8 @@ private: class CenteredEditingDelegate : public QStyledItemDelegate { public: - explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) - { - } - virtual ~CenteredEditingDelegate() - { - } + explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {} + virtual ~CenteredEditingDelegate() {} virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { @@ -221,21 +208,6 @@ public: } }; -QString ScreenshotsPage::displayName() const -{ - return tr("Screenshots"); -} - -QIcon ScreenshotsPage::icon() const -{ - return QIcon::fromTheme("screenshots"); -} - -QString ScreenshotsPage::id() const -{ - return "screenshots"; -} - ScreenshotsPage::ScreenshotsPage(BaseInstance *instance, QWidget *parent) : QWidget(parent), ui(new Ui::ScreenshotsPage) { @@ -341,7 +313,8 @@ void ScreenshotsPage::on_uploadBtn_clicked() QDesktopServices::openUrl(link); CustomMessageBox::selectable( this, tr("Upload finished"), - tr("The link to the uploaded album has been opened in the default browser and placed in your clipboard.
Delete hash: %2 (save " + tr("The link to the uploaded album has been opened in the " + "default browser and placed in your clipboard.
Delete hash: %2 (save " "this if you want to be able to edit/delete the album)") .arg(link, imgurAlbum->deleteHash()), QMessageBox::Information)->exec(); diff --git a/gui/pages/ScreenshotsPage.h b/gui/pages/ScreenshotsPage.h index 8b6d1e4d..19ae6cd8 100644 --- a/gui/pages/ScreenshotsPage.h +++ b/gui/pages/ScreenshotsPage.h @@ -14,11 +14,11 @@ */ #pragma once + #include -#include + +#include "logic/OneSixInstance.h" #include "BasePage.h" -#include -#include class QFileSystemModel; class QIdentityProxyModel; @@ -38,21 +38,32 @@ class ScreenshotsPage : public QWidget, public BasePage public: explicit ScreenshotsPage(BaseInstance *instance, QWidget *parent = 0); virtual ~ScreenshotsPage(); - + virtual void opened() override; - + enum { NothingDone = 0x42 }; - + virtual bool eventFilter(QObject *, QEvent *); - virtual QString displayName() const override; - virtual QIcon icon() const override; - virtual QString id() const override; - virtual QString helpPage() const override { return "Screenshots-management"; } -private -slots: + virtual QString displayName() const override + { + return tr("Screenshots"); + } + virtual QIcon icon() const override + { + return QIcon::fromTheme("screenshots"); + } + virtual QString id() const override + { + return "screenshots"; + } + virtual QString helpPage() const override + { + return "Screenshots-management"; + } +private slots: void on_uploadBtn_clicked(); void on_deleteBtn_clicked(); void on_renameBtn_clicked(); diff --git a/gui/pages/VersionPage.cpp b/gui/pages/VersionPage.cpp index 1ea6b262..6e29dd41 100644 --- a/gui/pages/VersionPage.cpp +++ b/gui/pages/VersionPage.cpp @@ -31,6 +31,12 @@ #include "gui/dialogs/ProgressDialog.h" +#include +#include +#include +#include +#include + #include "logic/ModList.h" #include "logic/minecraft/InstanceVersion.h" #include "logic/EnabledItemFilter.h" @@ -40,31 +46,14 @@ #include "logic/liteloader/LiteLoaderInstaller.h" #include "logic/minecraft/VersionBuilder.h" #include "logic/auth/MojangAccountList.h" +#include "logic/Mod.h" +#include "logic/icons/IconList.h" -#include -#include -#include - -#include -#include -#include -#include - -QString VersionPage::displayName() const -{ - return tr("Version"); -} QIcon VersionPage::icon() const { return MMC->icons()->getIcon(m_inst->iconKey()); } - -QString VersionPage::id() const -{ - return "version"; -} - bool VersionPage::shouldDisplay() const { return !m_inst->isRunning(); diff --git a/gui/pages/VersionPage.h b/gui/pages/VersionPage.h index d80b2a2a..93fe7508 100644 --- a/gui/pages/VersionPage.h +++ b/gui/pages/VersionPage.h @@ -14,10 +14,11 @@ */ #pragma once + #include -#include -#include +#include "logic/OneSixInstance.h" +#include "logic/net/NetJob.h" #include "BasePage.h" class EnabledItemFilter; @@ -33,10 +34,19 @@ class VersionPage : public QWidget, public BasePage public: explicit VersionPage(OneSixInstance *inst, QWidget *parent = 0); virtual ~VersionPage(); - virtual QString displayName() const override; + virtual QString displayName() const override + { + return tr("Version"); + } virtual QIcon icon() const override; - virtual QString id() const override; - virtual QString helpPage() const override { return "Instance-version"; } + virtual QString id() const override + { + return "version"; + } + virtual QString helpPage() const override + { + return "Instance-version"; + } virtual bool shouldDisplay() const; private slots: diff --git a/gui/widgets/PageContainer.cpp b/gui/widgets/PageContainer.cpp index d5df72ce..a68f94cd 100644 --- a/gui/widgets/PageContainer.cpp +++ b/gui/widgets/PageContainer.cpp @@ -14,12 +14,11 @@ */ #include "PageContainer.h" -#include "gui/Platform.h" + #include #include #include #include -#include "MultiMC.h" #include #include #include @@ -27,10 +26,12 @@ #include #include #include -#include "logic/settings/SettingsObject.h" +#include "MultiMC.h" +#include "logic/settings/SettingsObject.h" +#include "gui/widgets/IconLabel.h" +#include "gui/Platform.h" #include "PageContainer_p.h" -#include class PageEntryFilterModel : public QSortFilterProxyModel { @@ -197,5 +198,9 @@ bool PageContainer::requestClose(QCloseEvent *event) if (!page->apply()) return false; } + if (m_currentPage) + { + m_currentPage->closed(); + } return true; } diff --git a/gui/widgets/PageContainer.h b/gui/widgets/PageContainer.h index c0f17e90..06498850 100644 --- a/gui/widgets/PageContainer.h +++ b/gui/widgets/PageContainer.h @@ -14,9 +14,11 @@ */ #pragma once + #include #include -#include + +#include "gui/pages/BasePageProvider.h" class QLayout; class IconLabel; @@ -34,7 +36,7 @@ class PageContainer : public QWidget public: explicit PageContainer(BasePageProviderPtr pageProvider, QString defaultId = QString(), QWidget *parent = 0); - virtual ~PageContainer() {}; + virtual ~PageContainer() {} void addButtons(QWidget * buttons); void addButtons(QLayout * buttons); @@ -49,7 +51,7 @@ slots: void help(); private: - BasePage * m_currentPage; + BasePage * m_currentPage = 0; QSortFilterProxyModel *m_proxyModel; PageModel *m_model; QStackedLayout *m_pageStack; diff --git a/gui/widgets/PageContainer_p.h b/gui/widgets/PageContainer_p.h index f10e8f2c..1f68776b 100644 --- a/gui/widgets/PageContainer_p.h +++ b/gui/widgets/PageContainer_p.h @@ -1,4 +1,20 @@ +/* Copyright 2014 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. + */ + #pragma once + #include #include #include @@ -30,7 +46,7 @@ public: empty.fill(Qt::transparent); m_emptyIcon = QIcon(empty); } - virtual ~PageModel() {}; + virtual ~PageModel() {} int rowCount(const QModelIndex &parent = QModelIndex()) const { diff --git a/logic/RecursiveFileSystemWatcher.cpp b/logic/RecursiveFileSystemWatcher.cpp index 5cfa7e4e..39985699 100644 --- a/logic/RecursiveFileSystemWatcher.cpp +++ b/logic/RecursiveFileSystemWatcher.cpp @@ -1,13 +1,15 @@ #include "RecursiveFileSystemWatcher.h" #include +#include RecursiveFileSystemWatcher::RecursiveFileSystemWatcher(QObject *parent) - : QObject(parent), - m_watcher(new QFileSystemWatcher(this)) + : QObject(parent), m_exp(".*"), m_watcher(new QFileSystemWatcher(this)) { - connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &RecursiveFileSystemWatcher::fileChange); - connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &RecursiveFileSystemWatcher::directoryChange); + connect(m_watcher, &QFileSystemWatcher::fileChanged, this, + &RecursiveFileSystemWatcher::fileChange); + connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, + &RecursiveFileSystemWatcher::directoryChange); } void RecursiveFileSystemWatcher::setRootDir(const QDir &root) @@ -34,12 +36,20 @@ void RecursiveFileSystemWatcher::setWatchFiles(const bool watchFiles) void RecursiveFileSystemWatcher::enable() { + if (m_isEnabled) + { + return; + } Q_ASSERT(m_root != QDir::root()); addFilesToWatcherRecursive(m_root); m_isEnabled = true; } void RecursiveFileSystemWatcher::disable() { + if (!m_isEnabled) + { + return; + } m_isEnabled = false; m_watcher->removePaths(m_watcher->files()); m_watcher->removePaths(m_watcher->directories()); @@ -57,9 +67,9 @@ void RecursiveFileSystemWatcher::setFiles(const QStringList &files) void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir &dir) { m_watcher->addPath(dir.absolutePath()); - for (const QFileInfo &info : dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) + for (const QString &directory : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - addFilesToWatcherRecursive(info.absoluteDir()); + addFilesToWatcherRecursive(dir.absoluteFilePath(directory)); } if (m_watchFiles) { @@ -69,19 +79,19 @@ void RecursiveFileSystemWatcher::addFilesToWatcherRecursive(const QDir &dir) } } } -QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir &dir) +QStringList RecursiveFileSystemWatcher::scanRecursive(const QDir &directory) { QStringList ret; QRegularExpression exp(m_exp); - for (const QFileInfo &info : dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files)) + for (const QString &dir : directory.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) { - if (info.isFile() && exp.match(info.absoluteFilePath()).hasMatch()) + ret.append(scanRecursive(directory.absoluteFilePath(dir))); + } + for (const QString &file : directory.entryList(QDir::Files)) + { + if (exp.match(file).hasMatch()) { - ret.append(info.absoluteFilePath()); - } - else if (info.isDir()) - { - ret.append(scanRecursive(info.absoluteDir())); + ret.append(m_root.relativeFilePath(directory.absoluteFilePath(file))); } } return ret; diff --git a/logic/RecursiveFileSystemWatcher.h b/logic/RecursiveFileSystemWatcher.h index 54fc1d12..339172bb 100644 --- a/logic/RecursiveFileSystemWatcher.h +++ b/logic/RecursiveFileSystemWatcher.h @@ -25,8 +25,7 @@ signals: void filesChanged(); void fileChanged(const QString &path); -public -slots: +public slots: void enable(); void disable(); @@ -39,13 +38,12 @@ private: QFileSystemWatcher *m_watcher; QStringList m_files; - void setFiles(const QStringList &scanRecursive); + void setFiles(const QStringList &files); void addFilesToWatcherRecursive(const QDir &dir); QStringList scanRecursive(const QDir &dir); -private -slots: +private slots: void fileChange(const QString &path); void directoryChange(const QString &path); }; diff --git a/resources/multimc/16x16/log.png b/resources/multimc/16x16/log.png new file mode 100644 index 0000000000000000000000000000000000000000..efa2a0b57d3b17ddd38fa79ea39023a87d29da29 GIT binary patch literal 630 zcmV-+0*U>JP)MUn$YP#im|4w3%tB_IEW9B^iKr;z1=x{g))9Lh^+wJ~- z{!M|OZnw)tA`w=hpi`n$D#^>s3&H$&JOV>CcXBOumN0;U9kiTCEmmx7%5*R!f%4 zB{3R}6aZaZTo8l7KvXIfV8YYW)0gY(>z^M0?RJ|B27|012m}Ke$nOY*#0-dDuP2Me z0+7$Qx3|AefJURiIUEjFtyX`q0Dw-XqjPAzUek4+=VygN;WC|03lvbV*Ex^J!)i2| zlXnR37yzIaSVuiXn|vyjVno1^?rb)jTqqPeS-?g)2!ag+B15y;Oh%&-ACJeGWHKoM zs?{pz_xst`mJyT5L<=XMy4&q2aKGPE*lafA#nTxvi#LGN>1449o6!aMmFIwTV{M~2}k+T(M%9Fx!IB|y1c=6pUM zy$2|w#bTlTrx)e5rSCNy4*5hP!8|-XNPtqQ#JOB97D4c8wOYylG#CshK+IeMR4Nrt z{FAV9!OnHQ-tYH+$6~R|PNyRQqS5Flo6Y8tFA}nN|2$ux&*#%#ua`pXA5{KiAkPt` QTmS$707*qoM6N<$f^3~3g8%>k literal 0 HcmV?d00001 diff --git a/resources/multimc/24x24/log.png b/resources/multimc/24x24/log.png new file mode 100644 index 0000000000000000000000000000000000000000..fe3020534e1e756f3c6338f103be0fe3e7276da8 GIT binary patch literal 1117 zcmV-j1fu(iP) zFDULych|%VE4#YeR%Q~4%! z!NEauR#uind@%5VXliQGdU|^Fu&^-2q`@0Bg4c5Pcs%0e#-*l%xd-G*V*=H=y$eF)Ir-mbe`E+sND z(xgXRUthDs@$vEE?(R+@P%|PTLZNq#DlIKdJU>4x$;rtkMPY7jZB^&z=Z}R1XlQ6) zik_aH_##k1p7Pp?gu!5oiHTtVI?KT6>FIoCe}CVzv9VECP*CvW4M2T;z1G#$U0oehL|(9` zv9Yn>SD}wh3V_K0ZQBhIm&d!dpu&|(Zc6NGv0JXKX8X25dS63V= z5=+&=;bQ;Q8TTP+3{YIiR{`C4*B` z4kCvZ2tbysPke|H5rGz~b#Oj*cXy4sxjB^_4g^3I9UUF9Xz+m)(Ea^A3obJ=lcSJB z_M_mjw6wGh01~bZP*G8#_4oJd@DM_i9n?R8{tXrM!2!Hu+fp*`EiW${^Yim66^#v0 zUS6(I*7eQJO@+K=WukHrGW39pECnm1auc~qN=o8p2a1pjR3L+9=#1K=b8 zpSYj}Bo}Q1v$Uf{!(-S%pG>aoT?DYbxVWee3=G%+Wo2dDi>Ly8!jVF=xR+G;(-uIZ z)C5(KL3vOI2M29{($Z3{B9c2-2|NKEpasX#WTG`S`X7?cOq;c(ahB_$;Qa8k45 zNAv5gkbr|M=5?@66QHltGU=K0a;( zTS!%D6vww&scBxZEJO_KNgt&%Ft5H#555dO3G?7>tEH7)80}(;k)9alA()5pMIE6K zF&`B|QE+xfWho_*7tGS~UgptRzcus8!Lz-jv|zKpz0dx>^U+eo$koCVkc<>-Q zBO~Ll17g-5ZDnO;bz)+oC@n4RkKN7*GK0&PFW29=aieH2j@Q@MEuYV4t*)+GpFVwB z7ZCQDGiQGPUI1PJVDAOM+S-~r=UQ4?vSw#z*WbN+_p31a=dJ;imzR4hDk^NDQ6mZt z4%RzYP*9L{@ZdomfBpJZ$7Jf;w{Pn7@ZrOH=iQetU#zgOFiTkQ4Gj(DWM*bI>>9w; zt5@weZ{DaQ7BRH4XmoV60{Q&;vjRAD=#XCg4g=xg;Z{scjJ3G9XdOR(T$vajANRd_ z^(yD=*|QBh0=RVPlK0}pi?&SCh+qH!b8~a*FeD^IBgPT$0mb`c$BtQ%k&*fvm(Xt| zCMIeSfEXPe^$iXV=454MHEat&oO^HGx@9vFgH9sD8Idy93Bm%`W)0w+^i5AsTgl1E z8{!0n=)pHIFp!g-o!zi401=|i0xW3q&%&Xhp&I$r)Rc}fw7}SCgE>$yxeowKnuJMT ze}8{=VPRpDD}W0ZE_g);ngZyDfry9*%{k9UjvP@oaLls-X+V&YlP6DZqynehnPaS@ zqoa3na`NZO%F49>0A*!mD#8yRKIkMIKs^qimIZMP0CLVdE=11$%%cB>?3c zQuU`)YaPHhW@0BZ8?Dy~AYpzYL z6A6(arj(SF?{;oV6f*!^832HkqG|v-$t!nq4dvvJywVR)xY-{7OWL@j7X-%|07i(U z&-9F!FJCGER}GYulz62b+vJZ0nE-VxLXJ)U2ZZU4d;>sOLoWd1&hNYj1m6MZ^y$;q zKiO<;ZEXsms;VjwKv7ZA1_MxNSTLQCMWG)yPMtcXx%GGK zf8WYlTU(vy&!2m$tE=4s2r}DrL1R2`Rhm0R>;~Y)ix=*#*tTumjN}xf5hEa@^0>G- z4j2DT5O8S0G#$o94|F{42$}h?NB#+bhSb&7<;dB4uAs*01UmPf)b?kj39Z( z#nx*UH-g2e8p8_n_y%AA?dj=pq!c}O?%Z()Kp%Mh`n9Up)H?l~h*+5Ss2gKU%Qk06 z?zCyX1)%9Atif*_>AJhS9XX@B6M90`ve03 O0000R|Wo z-KT^QqV_nxe*GGK{P?ly@#DvT>)W^Qze-9RZ!fbpCQKmde3@tZeq?D~rr zFTUQte}CzqL4(rMrcH}~2*A8~^J<7ddjOEvn*n(B>Q(69zduok6ouC}Z{A!sX3Us< zGiT2HO(0qWkXDjKO-)Tvr%s)sPoF+TJbLsf)+gXG3}$16 zJQ_G~VARmiV9e;&ty?pyV6^ybM#FDOWF+I`p+kp;VZ(+QZ4@PQivGq@AOqvi3q*MO z^l2nuudiRfzD)AEPmCxCq8R|820&Wgvd}_-E?v49W$>uLpy5UZuHkXK3q81xa}0+b z{06NAC>k(eK$LLbK3u2dgu&3k|5RGEMQXK{9)Ea;cwE5X}fC$JTmc-P7 zTeoh7%F4=?YZ{#ti69^!&Ye3~EsE}6ym)c^n*hk$7H%SeBC#=ElxJ*nCs5@G;w5A?v}&`GolGS=i0V_Z^ICkzZm3Y_idg%SWn z8C7CU*1~Ad71os#!`{7n>!eJnty{N#ECxUt#ldS7FFcO{P=v4wkf{;HhX`>W#SD*e zode@l7wjDBNmjGZBDLJ-ipE}vu|^rzp7*GPEX7b_yv3^*Sv8O`e?G}m2zwYEi5wZ!%- zFE6)XhNpgyGL`0?XLAq>KkEG`3rCndiTevG4F_3qu92*onQ zD4@UD>I(&ud@eZ|3H1re(Fn#)TqY#Qi>r5iy30jH~BSu)GB_*LF^_pNZM}hm92gdtBaTI`h z02HK90>F|O+Q3s15mn(l;iO3$;U)2s&eS~RiQCfIiNLA0SQii9#jAtF#L0HY8Z&ql5o zc$DvimEuIGy?;U1^^EB_eGLlc<0$LUZV)A^Ep%cHiX&if0?%MeGD}C+r4QUOixbTx+p0+^?Q)#Wh;XSxcrwLUUDZR?#2n@xe7zy?8JnaIV zEZ&E9y5F3Uyb!R)(DQG~lqm*4_Z9{)b?Vfb6DLlj?T2=HwU~S06rTgyIP73q z0II600FXf?7_teskC#b1knQ*JI)A+dhBiqhwsQ+ho|jyF&DlE6vE{pSA^?C*n>G~( zKpAfX4V94@6}j}uOLZU?jRJpB81Ls%5t6;Etjsvv8UQ!CP$6qs)K;!sS*IFQxEoCX zq?0+f)sUht$;;oOXp(rmAXV}`4}}0wa2`;?)SNtdGJ`Io9=-+%=7vL|Z`AzOUHTyI zYoSQcFKOVi!#XbtNP3jaJCT+YVtu0NZA_F5`_usd6r9Ka0EJXw?5zRx@HcTxSm?A0 zjBSQ-(&lWd3}AlO5M&CLJ5r+MTF-I=no-~YLu-<}zBHptN=ocLR1WDKH*Q?4^(+Te zXHwg?ZOad!va*s0q$%;V%gCk|A0(AFJMoeg8?Gr|ObRJP7)@JD0V1JUhre8>ju0r` zN>G9QMVJ>aY6y{{)uz2p>WdXJQ>LLR8>9?|rn^sE{0*+PQOQ zaRBgop`z2C6It##IYb0R*TMiMO_~IS(#RXUW*vX$$zOjz3Z39J(^-2TC>1%NeTxQQ zIY7GrW#GI|WF#j;28BuzYC}nTM}T&P2uP(;wY9bR0aR2}7yv49(y+DUWbXGL;eF9L z003kZ0K0bWDhfcFu=zjE{p!OhgbHOcnc^Zq0m|uBerW_4Zg?-mOnl(Lf&2i<%gbv{ zpFW*Im*IU|np_jfvh>;KPs+&K6L0%egG;?e^A0?7A{;kB-y3a zk55u<{pR#*`8_e}yWex$?Urk+h4?56{Zo~CmB!sqc>$D`mJVuYX!xTPr=;a?zv@r{ zeW_Y-XvvZ#{}YA28!B44(?ii00000NkvXXu0mjfLM%lM literal 0 HcmV?d00001 diff --git a/resources/multimc/64x64/log.png b/resources/multimc/64x64/log.png new file mode 100644 index 0000000000000000000000000000000000000000..0f531cdfcec1eb1fefee55512f18e629a933bc79 GIT binary patch literal 3686 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/noaccount.png 32x32/noaccount.png 48x48/noaccount.png + + + 16x16/log.png + 24x24/log.png + 32x32/log.png + 48x48/log.png + 64x64/log.png scalable/screenshot-placeholder.svg