aboutsummaryrefslogtreecommitdiff
path: root/application/pages
diff options
context:
space:
mode:
Diffstat (limited to 'application/pages')
-rw-r--r--application/pages/BasePage.h58
-rw-r--r--application/pages/BasePageContainer.h10
-rw-r--r--application/pages/BasePageProvider.h68
-rw-r--r--application/pages/global/AccountListPage.cpp217
-rw-r--r--application/pages/global/AccountListPage.h84
-rw-r--r--application/pages/global/AccountListPage.ui98
-rw-r--r--application/pages/global/CustomCommandsPage.cpp51
-rw-r--r--application/pages/global/CustomCommandsPage.h55
-rw-r--r--application/pages/global/ExternalToolsPage.cpp233
-rw-r--r--application/pages/global/ExternalToolsPage.h74
-rw-r--r--application/pages/global/ExternalToolsPage.ui194
-rw-r--r--application/pages/global/JavaPage.cpp153
-rw-r--r--application/pages/global/JavaPage.h72
-rw-r--r--application/pages/global/JavaPage.ui260
-rw-r--r--application/pages/global/LanguagePage.cpp51
-rw-r--r--application/pages/global/LanguagePage.h60
-rw-r--r--application/pages/global/MinecraftPage.cpp90
-rw-r--r--application/pages/global/MinecraftPage.h70
-rw-r--r--application/pages/global/MinecraftPage.ui189
-rw-r--r--application/pages/global/MultiMCPage.cpp467
-rw-r--r--application/pages/global/MultiMCPage.h103
-rw-r--r--application/pages/global/MultiMCPage.ui584
-rw-r--r--application/pages/global/PasteEEPage.cpp81
-rw-r--r--application/pages/global/PasteEEPage.h62
-rw-r--r--application/pages/global/PasteEEPage.ui128
-rw-r--r--application/pages/global/ProxyPage.cpp101
-rw-r--r--application/pages/global/ProxyPage.h66
-rw-r--r--application/pages/global/ProxyPage.ui203
-rw-r--r--application/pages/instance/GameOptionsPage.cpp37
-rw-r--r--application/pages/instance/GameOptionsPage.h63
-rw-r--r--application/pages/instance/GameOptionsPage.ui88
-rw-r--r--application/pages/instance/InstanceSettingsPage.cpp338
-rw-r--r--application/pages/instance/InstanceSettingsPage.h76
-rw-r--r--application/pages/instance/InstanceSettingsPage.ui548
-rw-r--r--application/pages/instance/LegacyUpgradePage.cpp50
-rw-r--r--application/pages/instance/LegacyUpgradePage.h64
-rw-r--r--application/pages/instance/LegacyUpgradePage.ui47
-rw-r--r--application/pages/instance/LogPage.cpp312
-rw-r--r--application/pages/instance/LogPage.h86
-rw-r--r--application/pages/instance/LogPage.ui182
-rw-r--r--application/pages/instance/ModFolderPage.cpp363
-rw-r--r--application/pages/instance/ModFolderPage.h119
-rw-r--r--application/pages/instance/ModFolderPage.ui164
-rw-r--r--application/pages/instance/NotesPage.cpp21
-rw-r--r--application/pages/instance/NotesPage.h60
-rw-r--r--application/pages/instance/NotesPage.ui49
-rw-r--r--application/pages/instance/OtherLogsPage.cpp313
-rw-r--r--application/pages/instance/OtherLogsPage.h81
-rw-r--r--application/pages/instance/OtherLogsPage.ui150
-rw-r--r--application/pages/instance/ResourcePackPage.h23
-rw-r--r--application/pages/instance/ScreenshotsPage.cpp422
-rw-r--r--application/pages/instance/ScreenshotsPage.h89
-rw-r--r--application/pages/instance/ScreenshotsPage.ui87
-rw-r--r--application/pages/instance/ServersPage.cpp768
-rw-r--r--application/pages/instance/ServersPage.h94
-rw-r--r--application/pages/instance/ServersPage.ui194
-rw-r--r--application/pages/instance/TexturePackPage.h22
-rw-r--r--application/pages/instance/VersionPage.cpp642
-rw-r--r--application/pages/instance/VersionPage.h104
-rw-r--r--application/pages/instance/VersionPage.ui285
-rw-r--r--application/pages/instance/WorldListPage.cpp408
-rw-r--r--application/pages/instance/WorldListPage.h99
-rw-r--r--application/pages/instance/WorldListPage.ui161
-rw-r--r--application/pages/modplatform/ImportPage.cpp130
-rw-r--r--application/pages/modplatform/ImportPage.h70
-rw-r--r--application/pages/modplatform/ImportPage.ui52
-rw-r--r--application/pages/modplatform/VanillaPage.cpp104
-rw-r--r--application/pages/modplatform/VanillaPage.h75
-rw-r--r--application/pages/modplatform/VanillaPage.ui169
-rw-r--r--application/pages/modplatform/atlauncher/AtlFilterModel.cpp81
-rw-r--r--application/pages/modplatform/atlauncher/AtlFilterModel.h34
-rw-r--r--application/pages/modplatform/atlauncher/AtlListModel.cpp194
-rw-r--r--application/pages/modplatform/atlauncher/AtlListModel.h52
-rw-r--r--application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp209
-rw-r--r--application/pages/modplatform/atlauncher/AtlOptionalModDialog.h66
-rw-r--r--application/pages/modplatform/atlauncher/AtlOptionalModDialog.ui65
-rw-r--r--application/pages/modplatform/atlauncher/AtlPage.cpp175
-rw-r--r--application/pages/modplatform/atlauncher/AtlPage.h87
-rw-r--r--application/pages/modplatform/atlauncher/AtlPage.ui97
-rw-r--r--application/pages/modplatform/flame/FlameModel.cpp259
-rw-r--r--application/pages/modplatform/flame/FlameModel.h76
-rw-r--r--application/pages/modplatform/flame/FlamePage.cpp185
-rw-r--r--application/pages/modplatform/flame/FlamePage.h80
-rw-r--r--application/pages/modplatform/flame/FlamePage.ui90
-rw-r--r--application/pages/modplatform/ftb/FtbFilterModel.cpp64
-rw-r--r--application/pages/modplatform/ftb/FtbFilterModel.h33
-rw-r--r--application/pages/modplatform/ftb/FtbListModel.cpp304
-rw-r--r--application/pages/modplatform/ftb/FtbListModel.h69
-rw-r--r--application/pages/modplatform/ftb/FtbPage.cpp145
-rw-r--r--application/pages/modplatform/ftb/FtbPage.h80
-rw-r--r--application/pages/modplatform/ftb/FtbPage.ui84
-rw-r--r--application/pages/modplatform/legacy_ftb/ListModel.cpp260
-rw-r--r--application/pages/modplatform/legacy_ftb/ListModel.h78
-rw-r--r--application/pages/modplatform/legacy_ftb/Page.cpp369
-rw-r--r--application/pages/modplatform/legacy_ftb/Page.h119
-rw-r--r--application/pages/modplatform/legacy_ftb/Page.ui135
-rw-r--r--application/pages/modplatform/technic/TechnicData.h42
-rw-r--r--application/pages/modplatform/technic/TechnicModel.cpp238
-rw-r--r--application/pages/modplatform/technic/TechnicModel.h70
-rw-r--r--application/pages/modplatform/technic/TechnicPage.cpp198
-rw-r--r--application/pages/modplatform/technic/TechnicPage.h78
-rw-r--r--application/pages/modplatform/technic/TechnicPage.ui95
102 files changed, 0 insertions, 15302 deletions
diff --git a/application/pages/BasePage.h b/application/pages/BasePage.h
deleted file mode 100644
index 408965d0..00000000
--- a/application/pages/BasePage.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Copyright 2013-2021 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 <QString>
-#include <QIcon>
-#include <memory>
-
-#include "BasePageContainer.h"
-
-class BasePage
-{
-public:
- 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(); }
- void opened()
- {
- isOpened = true;
- openedImpl();
- }
- void closed()
- {
- isOpened = false;
- closedImpl();
- }
- virtual void openedImpl() {}
- virtual void closedImpl() {}
- virtual void setParentContainer(BasePageContainer * container)
- {
- m_container = container;
- };
-public:
- int stackIndex = -1;
- int listIndex = -1;
-protected:
- BasePageContainer * m_container = nullptr;
- bool isOpened = false;
-};
-
-typedef std::shared_ptr<BasePage> BasePagePtr;
diff --git a/application/pages/BasePageContainer.h b/application/pages/BasePageContainer.h
deleted file mode 100644
index f8c7adeb..00000000
--- a/application/pages/BasePageContainer.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-class BasePageContainer
-{
-public:
- virtual ~BasePageContainer(){};
- virtual bool selectPage(QString pageId) = 0;
- virtual void refreshContainer() = 0;
- virtual bool requestClose() = 0;
-};
diff --git a/application/pages/BasePageProvider.h b/application/pages/BasePageProvider.h
deleted file mode 100644
index 7bfaaf3b..00000000
--- a/application/pages/BasePageProvider.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright 2013-2021 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 "pages/BasePage.h"
-#include <memory>
-#include <functional>
-
-class BasePageProvider
-{
-public:
- virtual QList<BasePage *> getPages() = 0;
- virtual QString dialogTitle() = 0;
-};
-
-class GenericPageProvider : public BasePageProvider
-{
- typedef std::function<BasePage *()> PageCreator;
-public:
- explicit GenericPageProvider(const QString &dialogTitle)
- : m_dialogTitle(dialogTitle)
- {
- }
- virtual ~GenericPageProvider() {}
-
- QList<BasePage *> getPages() override
- {
- QList<BasePage *> pages;
- for (PageCreator creator : m_creators)
- {
- pages.append(creator());
- }
- return pages;
- }
- QString dialogTitle() override { return m_dialogTitle; }
-
- void setDialogTitle(const QString &title)
- {
- m_dialogTitle = title;
- }
- void addPageCreator(PageCreator page)
- {
- m_creators.append(page);
- }
-
- template<typename PageClass>
- void addPage()
- {
- addPageCreator([](){return new PageClass();});
- }
-
-private:
- QList<PageCreator> m_creators;
- QString m_dialogTitle;
-};
diff --git a/application/pages/global/AccountListPage.cpp b/application/pages/global/AccountListPage.cpp
deleted file mode 100644
index ff3736ed..00000000
--- a/application/pages/global/AccountListPage.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/* Copyright 2013-2021 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 "AccountListPage.h"
-#include "ui_AccountListPage.h"
-
-#include <QItemSelectionModel>
-#include <QMenu>
-
-#include <QDebug>
-
-#include "net/NetJob.h"
-#include "Env.h"
-
-#include "dialogs/ProgressDialog.h"
-#include "dialogs/LoginDialog.h"
-#include "dialogs/CustomMessageBox.h"
-#include "dialogs/SkinUploadDialog.h"
-#include "tasks/Task.h"
-#include "minecraft/auth/YggdrasilTask.h"
-#include "minecraft/services/SkinDelete.h"
-
-#include "MultiMC.h"
-
-#include "BuildConfig.h"
-
-AccountListPage::AccountListPage(QWidget *parent)
- : QMainWindow(parent), ui(new Ui::AccountListPage)
-{
- ui->setupUi(this);
- ui->listView->setEmptyString(tr(
- "Welcome!\n"
- "If you're new here, you can click the \"Add\" button to add your Mojang or Minecraft account."
- ));
- ui->listView->setEmptyMode(VersionListView::String);
- ui->listView->setContextMenuPolicy(Qt::CustomContextMenu);
-
- m_accounts = MMC->accounts();
-
- ui->listView->setModel(m_accounts.get());
- ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
- ui->listView->setSelectionMode(QAbstractItemView::SingleSelection);
-
- // Expand the account column
- ui->listView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
-
- QItemSelectionModel *selectionModel = ui->listView->selectionModel();
-
- connect(selectionModel, &QItemSelectionModel::selectionChanged, [this](const QItemSelection &sel, const QItemSelection &dsel) {
- updateButtonStates();
- });
- connect(ui->listView, &VersionListView::customContextMenuRequested, this, &AccountListPage::ShowContextMenu);
-
- connect(m_accounts.get(), SIGNAL(listChanged()), SLOT(listChanged()));
- connect(m_accounts.get(), SIGNAL(activeAccountChanged()), SLOT(listChanged()));
-
- updateButtonStates();
-}
-
-AccountListPage::~AccountListPage()
-{
- delete ui;
-}
-
-void AccountListPage::ShowContextMenu(const QPoint& pos)
-{
- auto menu = ui->toolBar->createContextMenu(this, tr("Context menu"));
- menu->exec(ui->listView->mapToGlobal(pos));
- delete menu;
-}
-
-void AccountListPage::changeEvent(QEvent* event)
-{
- if (event->type() == QEvent::LanguageChange)
- {
- ui->retranslateUi(this);
- }
- QMainWindow::changeEvent(event);
-}
-
-QMenu * AccountListPage::createPopupMenu()
-{
- QMenu* filteredMenu = QMainWindow::createPopupMenu();
- filteredMenu->removeAction(ui->toolBar->toggleViewAction() );
- return filteredMenu;
-}
-
-
-void AccountListPage::listChanged()
-{
- updateButtonStates();
-}
-
-void AccountListPage::on_actionAdd_triggered()
-{
- addAccount(tr("Please enter your Minecraft account email and password to add your account."));
-}
-
-void AccountListPage::on_actionRemove_triggered()
-{
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.size() > 0)
- {
- QModelIndex selected = selection.first();
- m_accounts->removeAccount(selected);
- }
-}
-
-void AccountListPage::on_actionSetDefault_triggered()
-{
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.size() > 0)
- {
- QModelIndex selected = selection.first();
- MojangAccountPtr account =
- selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
- m_accounts->setActiveAccount(account->username());
- }
-}
-
-void AccountListPage::on_actionNoDefault_triggered()
-{
- m_accounts->setActiveAccount("");
-}
-
-void AccountListPage::updateButtonStates()
-{
- // If there is no selection, disable buttons that require something selected.
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
-
- ui->actionRemove->setEnabled(selection.size() > 0);
- ui->actionSetDefault->setEnabled(selection.size() > 0);
- ui->actionUploadSkin->setEnabled(selection.size() > 0);
- ui->actionDeleteSkin->setEnabled(selection.size() > 0);
-
- if(m_accounts->activeAccount().get() == nullptr) {
- ui->actionNoDefault->setEnabled(false);
- ui->actionNoDefault->setChecked(true);
- }
- else {
- ui->actionNoDefault->setEnabled(true);
- ui->actionNoDefault->setChecked(false);
- }
-
-}
-
-void AccountListPage::addAccount(const QString &errMsg)
-{
- // TODO: The login dialog isn't quite done yet
- MojangAccountPtr account = LoginDialog::newAccount(this, errMsg);
-
- if (account != nullptr)
- {
- m_accounts->addAccount(account);
- if (m_accounts->count() == 1)
- m_accounts->setActiveAccount(account->username());
-
- // Grab associated player skins
- auto job = new NetJob("Player skins: " + account->username());
-
- for (AccountProfile profile : account->profiles())
- {
- auto meta = Env::getInstance().metacache()->resolveEntry("skins", profile.id + ".png");
- auto action = Net::Download::makeCached(QUrl(BuildConfig.SKINS_BASE + profile.id + ".png"), meta);
- job->addNetAction(action);
- meta->setStale(true);
- }
-
- job->start();
- }
-}
-
-void AccountListPage::on_actionUploadSkin_triggered()
-{
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.size() > 0)
- {
- QModelIndex selected = selection.first();
- MojangAccountPtr account = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
- SkinUploadDialog dialog(account, this);
- dialog.exec();
- }
-}
-
-void AccountListPage::on_actionDeleteSkin_triggered()
-{
- QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.size() <= 0)
- return;
-
- QModelIndex selected = selection.first();
- AuthSessionPtr session = std::make_shared<AuthSession>();
- MojangAccountPtr account = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
- auto login = account->login(session);
- ProgressDialog prog(this);
- if (prog.execWithTask((Task*)login.get()) != QDialog::Accepted) {
- CustomMessageBox::selectable(this, tr("Skin Delete"), tr("Failed to login!"), QMessageBox::Warning)->exec();
- return;
- }
- auto deleteSkinTask = std::make_shared<SkinDelete>(this, session);
- if (prog.execWithTask((Task*)deleteSkinTask.get()) != QDialog::Accepted) {
- CustomMessageBox::selectable(this, tr("Skin Delete"), tr("Failed to delete current skin!"), QMessageBox::Warning)->exec();
- return;
- }
-}
diff --git a/application/pages/global/AccountListPage.h b/application/pages/global/AccountListPage.h
deleted file mode 100644
index fba1833f..00000000
--- a/application/pages/global/AccountListPage.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* Copyright 2013-2021 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 <QMainWindow>
-#include <memory>
-
-#include "pages/BasePage.h"
-
-#include "minecraft/auth/MojangAccountList.h"
-#include "MultiMC.h"
-
-namespace Ui
-{
-class AccountListPage;
-}
-
-class AuthenticateTask;
-
-class AccountListPage : public QMainWindow, public BasePage
-{
- Q_OBJECT
-public:
- explicit AccountListPage(QWidget *parent = 0);
- ~AccountListPage();
-
- QString displayName() const override
- {
- return tr("Accounts");
- }
- QIcon icon() const override
- {
- auto icon = MMC->getThemedIcon("accounts");
- if(icon.isNull())
- {
- icon = MMC->getThemedIcon("noaccount");
- }
- return icon;
- }
- QString id() const override
- {
- return "accounts";
- }
- QString helpPage() const override
- {
- return "Getting-Started#adding-an-account";
- }
-
-public slots:
- void on_actionAdd_triggered();
- void on_actionRemove_triggered();
- void on_actionSetDefault_triggered();
- void on_actionNoDefault_triggered();
- void on_actionUploadSkin_triggered();
- void on_actionDeleteSkin_triggered();
-
- void listChanged();
-
- //! Updates the states of the dialog's buttons.
- void updateButtonStates();
-
-protected slots:
- void ShowContextMenu(const QPoint &pos);
- void addAccount(const QString& errMsg="");
-
-private:
- void changeEvent(QEvent * event) override;
- QMenu * createPopupMenu() override;
- std::shared_ptr<MojangAccountList> m_accounts;
- Ui::AccountListPage *ui;
-};
diff --git a/application/pages/global/AccountListPage.ui b/application/pages/global/AccountListPage.ui
deleted file mode 100644
index 71647db3..00000000
--- a/application/pages/global/AccountListPage.ui
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>AccountListPage</class>
- <widget class="QMainWindow" name="AccountListPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>800</width>
- <height>600</height>
- </rect>
- </property>
- <widget class="QWidget" name="centralwidget">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="VersionListView" name="listView"/>
- </item>
- </layout>
- </widget>
- <widget class="WideBar" name="toolBar">
- <attribute name="toolBarArea">
- <enum>RightToolBarArea</enum>
- </attribute>
- <attribute name="toolBarBreak">
- <bool>false</bool>
- </attribute>
- <addaction name="actionAdd"/>
- <addaction name="actionRemove"/>
- <addaction name="actionSetDefault"/>
- <addaction name="actionNoDefault"/>
- <addaction name="separator"/>
- <addaction name="actionUploadSkin"/>
- <addaction name="actionDeleteSkin"/>
- </widget>
- <action name="actionAdd">
- <property name="text">
- <string>Add</string>
- </property>
- </action>
- <action name="actionRemove">
- <property name="text">
- <string>Remove</string>
- </property>
- </action>
- <action name="actionSetDefault">
- <property name="text">
- <string>Set Default</string>
- </property>
- </action>
- <action name="actionNoDefault">
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="text">
- <string>No Default</string>
- </property>
- </action>
- <action name="actionUploadSkin">
- <property name="text">
- <string>Upload Skin</string>
- </property>
- </action>
- <action name="actionDeleteSkin">
- <property name="text">
- <string>Delete Skin</string>
- </property>
- <property name="toolTip">
- <string>Delete the currently active skin and go back to the default one</string>
- </property>
- </action>
- </widget>
- <customwidgets>
- <customwidget>
- <class>VersionListView</class>
- <extends>QTreeView</extends>
- <header>widgets/VersionListView.h</header>
- </customwidget>
- <customwidget>
- <class>WideBar</class>
- <extends>QToolBar</extends>
- <header>widgets/WideBar.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/global/CustomCommandsPage.cpp b/application/pages/global/CustomCommandsPage.cpp
deleted file mode 100644
index 3b182319..00000000
--- a/application/pages/global/CustomCommandsPage.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "CustomCommandsPage.h"
-#include <QVBoxLayout>
-#include <QTabWidget>
-#include <QTabBar>
-
-CustomCommandsPage::CustomCommandsPage(QWidget* parent): QWidget(parent)
-{
-
- auto verticalLayout = new QVBoxLayout(this);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
- verticalLayout->setContentsMargins(0, 0, 0, 0);
-
- auto tabWidget = new QTabWidget(this);
- tabWidget->setObjectName(QStringLiteral("tabWidget"));
- commands = new CustomCommands(this);
- commands->setContentsMargins(6, 6, 6, 6);
- tabWidget->addTab(commands, "Foo");
- tabWidget->tabBar()->hide();
- verticalLayout->addWidget(tabWidget);
- loadSettings();
-}
-
-CustomCommandsPage::~CustomCommandsPage()
-{
-}
-
-bool CustomCommandsPage::apply()
-{
- applySettings();
- return true;
-}
-
-void CustomCommandsPage::applySettings()
-{
- auto s = MMC->settings();
- s->set("PreLaunchCommand", commands->prelaunchCommand());
- s->set("WrapperCommand", commands->wrapperCommand());
- s->set("PostExitCommand", commands->postexitCommand());
-}
-
-void CustomCommandsPage::loadSettings()
-{
- auto s = MMC->settings();
- commands->initialize(
- false,
- true,
- s->get("PreLaunchCommand").toString(),
- s->get("WrapperCommand").toString(),
- s->get("PostExitCommand").toString()
- );
-}
diff --git a/application/pages/global/CustomCommandsPage.h b/application/pages/global/CustomCommandsPage.h
deleted file mode 100644
index 414c3259..00000000
--- a/application/pages/global/CustomCommandsPage.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Copyright 2018-2021 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 <memory>
-#include <QDialog>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "widgets/CustomCommands.h"
-
-class CustomCommandsPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit CustomCommandsPage(QWidget *parent = 0);
- ~CustomCommandsPage();
-
- QString displayName() const override
- {
- return tr("Custom Commands");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("custom-commands");
- }
- QString id() const override
- {
- return "custom-commands";
- }
- QString helpPage() const override
- {
- return "Custom-commands";
- }
- bool apply() override;
-
-private:
- void applySettings();
- void loadSettings();
- CustomCommands * commands;
-};
diff --git a/application/pages/global/ExternalToolsPage.cpp b/application/pages/global/ExternalToolsPage.cpp
deleted file mode 100644
index 6a0a38be..00000000
--- a/application/pages/global/ExternalToolsPage.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/* Copyright 2013-2021 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 "ExternalToolsPage.h"
-#include "ui_ExternalToolsPage.h"
-
-#include <QMessageBox>
-#include <QFileDialog>
-#include <QStandardPaths>
-#include <QTabBar>
-
-#include "settings/SettingsObject.h"
-#include "tools/BaseProfiler.h"
-#include <FileSystem.h>
-#include "MultiMC.h"
-#include <tools/MCEditTool.h>
-
-ExternalToolsPage::ExternalToolsPage(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::ExternalToolsPage)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
-
- #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
- ui->jsonEditorTextBox->setClearButtonEnabled(true);
- #endif
-
- ui->mceditLink->setOpenExternalLinks(true);
- ui->jvisualvmLink->setOpenExternalLinks(true);
- ui->jprofilerLink->setOpenExternalLinks(true);
- loadSettings();
-}
-
-ExternalToolsPage::~ExternalToolsPage()
-{
- delete ui;
-}
-
-void ExternalToolsPage::loadSettings()
-{
- auto s = MMC->settings();
- ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString());
- ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString());
- ui->mceditPathEdit->setText(s->get("MCEditPath").toString());
-
- // Editors
- ui->jsonEditorTextBox->setText(s->get("JsonEditor").toString());
-}
-void ExternalToolsPage::applySettings()
-{
- auto s = MMC->settings();
-
- s->set("JProfilerPath", ui->jprofilerPathEdit->text());
- s->set("JVisualVMPath", ui->jvisualvmPathEdit->text());
- s->set("MCEditPath", ui->mceditPathEdit->text());
-
- // Editors
- QString jsonEditor = ui->jsonEditorTextBox->text();
- if (!jsonEditor.isEmpty() &&
- (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable()))
- {
- QString found = QStandardPaths::findExecutable(jsonEditor);
- if (!found.isEmpty())
- {
- jsonEditor = found;
- }
- }
- s->set("JsonEditor", jsonEditor);
-}
-
-void ExternalToolsPage::on_jprofilerPathBtn_clicked()
-{
- QString raw_dir = ui->jprofilerPathEdit->text();
- QString error;
- do
- {
- raw_dir = QFileDialog::getExistingDirectory(this, tr("JProfiler Folder"), raw_dir);
- if (raw_dir.isEmpty())
- {
- break;
- }
- QString cooked_dir = FS::NormalizePath(raw_dir);
- if (!MMC->profilers()["jprofiler"]->check(cooked_dir, &error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
- continue;
- }
- else
- {
- ui->jprofilerPathEdit->setText(cooked_dir);
- break;
- }
- } while (1);
-}
-void ExternalToolsPage::on_jprofilerCheckBtn_clicked()
-{
- QString error;
- if (!MMC->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking JProfiler install:\n%1").arg(error));
- }
- else
- {
- QMessageBox::information(this, tr("OK"), tr("JProfiler setup seems to be OK"));
- }
-}
-
-void ExternalToolsPage::on_jvisualvmPathBtn_clicked()
-{
- QString raw_dir = ui->jvisualvmPathEdit->text();
- QString error;
- do
- {
- raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir);
- if (raw_dir.isEmpty())
- {
- break;
- }
- QString cooked_dir = FS::NormalizePath(raw_dir);
- if (!MMC->profilers()["jvisualvm"]->check(cooked_dir, &error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
- continue;
- }
- else
- {
- ui->jvisualvmPathEdit->setText(cooked_dir);
- break;
- }
- } while (1);
-}
-void ExternalToolsPage::on_jvisualvmCheckBtn_clicked()
-{
- QString error;
- if (!MMC->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking JVisualVM install:\n%1").arg(error));
- }
- else
- {
- QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK"));
- }
-}
-
-void ExternalToolsPage::on_mceditPathBtn_clicked()
-{
- QString raw_dir = ui->mceditPathEdit->text();
- QString error;
- do
- {
-#ifdef Q_OS_OSX
- raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Application"), raw_dir);
-#else
- raw_dir = QFileDialog::getExistingDirectory(this, tr("MCEdit Folder"), raw_dir);
-#endif
- if (raw_dir.isEmpty())
- {
- break;
- }
- QString cooked_dir = FS::NormalizePath(raw_dir);
- if (!MMC->mcedit()->check(cooked_dir, error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
- continue;
- }
- else
- {
- ui->mceditPathEdit->setText(cooked_dir);
- break;
- }
- } while (1);
-}
-void ExternalToolsPage::on_mceditCheckBtn_clicked()
-{
- QString error;
- if (!MMC->mcedit()->check(ui->mceditPathEdit->text(), error))
- {
- QMessageBox::critical(this, tr("Error"), tr("Error while checking MCEdit install:\n%1").arg(error));
- }
- else
- {
- QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK"));
- }
-}
-
-void ExternalToolsPage::on_jsonEditorBrowseBtn_clicked()
-{
- QString raw_file = QFileDialog::getOpenFileName(
- this, tr("JSON Editor"),
- ui->jsonEditorTextBox->text().isEmpty()
-#if defined(Q_OS_LINUX)
- ? QString("/usr/bin")
-#else
- ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first()
-#endif
- : ui->jsonEditorTextBox->text());
-
- if (raw_file.isEmpty())
- {
- return;
- }
- QString cooked_file = FS::NormalizePath(raw_file);
-
- // it has to exist and be an executable
- if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable())
- {
- ui->jsonEditorTextBox->setText(cooked_file);
- }
- else
- {
- QMessageBox::warning(this, tr("Invalid"),
- tr("The file chosen does not seem to be an executable"));
- }
-}
-
-bool ExternalToolsPage::apply()
-{
- applySettings();
- return true;
-}
diff --git a/application/pages/global/ExternalToolsPage.h b/application/pages/global/ExternalToolsPage.h
deleted file mode 100644
index 0fc8ebe1..00000000
--- a/application/pages/global/ExternalToolsPage.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-namespace Ui {
-class ExternalToolsPage;
-}
-
-class ExternalToolsPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit ExternalToolsPage(QWidget *parent = 0);
- ~ExternalToolsPage();
-
- QString displayName() const override
- {
- return tr("External Tools");
- }
- QIcon icon() const override
- {
- auto icon = MMC->getThemedIcon("externaltools");
- if(icon.isNull())
- {
- icon = MMC->getThemedIcon("loadermods");
- }
- return icon;
- }
- QString id() const override
- {
- return "external-tools";
- }
- QString helpPage() const override
- {
- return "Tools";
- }
- virtual bool apply() override;
-
-private:
- void loadSettings();
- void applySettings();
-
-private:
- Ui::ExternalToolsPage *ui;
-
-private
-slots:
- void on_jprofilerPathBtn_clicked();
- void on_jprofilerCheckBtn_clicked();
- void on_jvisualvmPathBtn_clicked();
- void on_jvisualvmCheckBtn_clicked();
- void on_mceditPathBtn_clicked();
- void on_mceditCheckBtn_clicked();
- void on_jsonEditorBrowseBtn_clicked();
-};
diff --git a/application/pages/global/ExternalToolsPage.ui b/application/pages/global/ExternalToolsPage.ui
deleted file mode 100644
index e79e9388..00000000
--- a/application/pages/global/ExternalToolsPage.ui
+++ /dev/null
@@ -1,194 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ExternalToolsPage</class>
- <widget class="QWidget" name="ExternalToolsPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>673</width>
- <height>751</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string notr="true">Tab 1</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string notr="true">JProfiler</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_10">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_4">
- <item>
- <widget class="QLineEdit" name="jprofilerPathEdit"/>
- </item>
- <item>
- <widget class="QPushButton" name="jprofilerPathBtn">
- <property name="text">
- <string notr="true">...</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QPushButton" name="jprofilerCheckBtn">
- <property name="text">
- <string>Check</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="jprofilerLink">
- <property name="text">
- <string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://www.ej-technologies.com/products/jprofiler/overview.html&quot;&gt;https://www.ej-technologies.com/products/jprofiler/overview.html&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string notr="true">JVisualVM</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_11">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_5">
- <item>
- <widget class="QLineEdit" name="jvisualvmPathEdit"/>
- </item>
- <item>
- <widget class="QPushButton" name="jvisualvmPathBtn">
- <property name="text">
- <string notr="true">...</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QPushButton" name="jvisualvmCheckBtn">
- <property name="text">
- <string>Check</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="jvisualvmLink">
- <property name="text">
- <string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://visualvm.github.io/&quot;&gt;https://visualvm.github.io/&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_4">
- <property name="title">
- <string notr="true">MCEdit</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_12">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_6">
- <item>
- <widget class="QLineEdit" name="mceditPathEdit"/>
- </item>
- <item>
- <widget class="QPushButton" name="mceditPathBtn">
- <property name="text">
- <string notr="true">...</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QPushButton" name="mceditCheckBtn">
- <property name="text">
- <string>Check</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="mceditLink">
- <property name="text">
- <string notr="true">&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://www.mcedit.net/&quot;&gt;https://www.mcedit.net/&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="editorsBox">
- <property name="title">
- <string>External Editors (leave empty for system default)</string>
- </property>
- <layout class="QGridLayout" name="foldersBoxLayout_2">
- <item row="0" column="1">
- <widget class="QLineEdit" name="jsonEditorTextBox"/>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="labelJsonEditor">
- <property name="text">
- <string>Text Editor:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QToolButton" name="jsonEditorBrowseBtn">
- <property name="text">
- <string notr="true">...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>216</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/global/JavaPage.cpp b/application/pages/global/JavaPage.cpp
deleted file mode 100644
index cde0e035..00000000
--- a/application/pages/global/JavaPage.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/* Copyright 2013-2021 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 "JavaPage.h"
-#include "JavaCommon.h"
-#include "ui_JavaPage.h"
-
-#include <QFileDialog>
-#include <QMessageBox>
-#include <QDir>
-#include <QTabBar>
-
-#include "dialogs/VersionSelectDialog.h"
-
-#include "java/JavaUtils.h"
-#include "java/JavaInstallList.h"
-
-#include "settings/SettingsObject.h"
-#include <FileSystem.h>
-#include "MultiMC.h"
-#include <sys.h>
-
-JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
-
- auto sysMiB = Sys::getSystemRam() / Sys::mebibyte;
- ui->maxMemSpinBox->setMaximum(sysMiB);
- loadSettings();
-}
-
-JavaPage::~JavaPage()
-{
- delete ui;
-}
-
-bool JavaPage::apply()
-{
- applySettings();
- return true;
-}
-
-void JavaPage::applySettings()
-{
- auto s = MMC->settings();
-
- // Memory
- int min = ui->minMemSpinBox->value();
- int max = ui->maxMemSpinBox->value();
- if(min < max)
- {
- s->set("MinMemAlloc", min);
- s->set("MaxMemAlloc", max);
- }
- else
- {
- s->set("MinMemAlloc", max);
- s->set("MaxMemAlloc", min);
- }
- s->set("PermGen", ui->permGenSpinBox->value());
-
- // Java Settings
- s->set("JavaPath", ui->javaPathTextBox->text());
- s->set("JvmArgs", ui->jvmArgsTextBox->text());
- JavaCommon::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget());
-}
-void JavaPage::loadSettings()
-{
- auto s = MMC->settings();
- // Memory
- int min = s->get("MinMemAlloc").toInt();
- int max = s->get("MaxMemAlloc").toInt();
- if(min < max)
- {
- ui->minMemSpinBox->setValue(min);
- ui->maxMemSpinBox->setValue(max);
- }
- else
- {
- ui->minMemSpinBox->setValue(max);
- ui->maxMemSpinBox->setValue(min);
- }
- ui->permGenSpinBox->setValue(s->get("PermGen").toInt());
-
- // Java Settings
- ui->javaPathTextBox->setText(s->get("JavaPath").toString());
- ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString());
-}
-
-void JavaPage::on_javaDetectBtn_clicked()
-{
- JavaInstallPtr java;
-
- VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
- vselect.setResizeOn(2);
- vselect.exec();
-
- if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
- {
- java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
- ui->javaPathTextBox->setText(java->path);
- }
-}
-
-void JavaPage::on_javaBrowseBtn_clicked()
-{
- QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if(raw_path.isEmpty())
- {
- return;
- }
-
- QString cooked_path = FS::NormalizePath(raw_path);
- QFileInfo javaInfo(cooked_path);;
- if(!javaInfo.exists() || !javaInfo.isExecutable())
- {
- return;
- }
- ui->javaPathTextBox->setText(cooked_path);
-}
-
-void JavaPage::on_javaTestBtn_clicked()
-{
- if(checker)
- {
- return;
- }
- checker.reset(new JavaCommon::TestCheck(
- this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->text(),
- ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
- connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
- checker->run();
-}
-
-void JavaPage::checkerFinished()
-{
- checker.reset();
-}
diff --git a/application/pages/global/JavaPage.h b/application/pages/global/JavaPage.h
deleted file mode 100644
index 832f460b..00000000
--- a/application/pages/global/JavaPage.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright 2013-2021 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 <memory>
-#include <QDialog>
-#include "pages/BasePage.h"
-#include "JavaCommon.h"
-#include <MultiMC.h>
-#include <QObjectPtr.h>
-
-class SettingsObject;
-
-namespace Ui
-{
-class JavaPage;
-}
-
-class JavaPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit JavaPage(QWidget *parent = 0);
- ~JavaPage();
-
- QString displayName() const override
- {
- return tr("Java");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("java");
- }
- QString id() const override
- {
- return "java-settings";
- }
- QString helpPage() const override
- {
- return "Java-settings";
- }
- bool apply() override;
-
-private:
- void applySettings();
- void loadSettings();
-
-private
-slots:
- void on_javaDetectBtn_clicked();
- void on_javaTestBtn_clicked();
- void on_javaBrowseBtn_clicked();
- void checkerFinished();
-
-private:
- Ui::JavaPage *ui;
- unique_qobject_ptr<JavaCommon::TestCheck> checker;
-};
diff --git a/application/pages/global/JavaPage.ui b/application/pages/global/JavaPage.ui
deleted file mode 100644
index b67e9994..00000000
--- a/application/pages/global/JavaPage.ui
+++ /dev/null
@@ -1,260 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>JavaPage</class>
- <widget class="QWidget" name="JavaPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>545</width>
- <height>580</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string notr="true">Tab 1</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QGroupBox" name="memoryGroupBox">
- <property name="title">
- <string>Memory</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="1" column="1">
- <widget class="QSpinBox" name="maxMemSpinBox">
- <property name="toolTip">
- <string>The maximum amount of memory Minecraft is allowed to use.</string>
- </property>
- <property name="suffix">
- <string notr="true"> MiB</string>
- </property>
- <property name="minimum">
- <number>128</number>
- </property>
- <property name="maximum">
- <number>65536</number>
- </property>
- <property name="singleStep">
- <number>128</number>
- </property>
- <property name="value">
- <number>1024</number>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="labelMinMem">
- <property name="text">
- <string>Minimum memory allocation:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="labelMaxMem">
- <property name="text">
- <string>Maximum memory allocation:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="minMemSpinBox">
- <property name="toolTip">
- <string>The amount of memory Minecraft is started with.</string>
- </property>
- <property name="suffix">
- <string notr="true"> MiB</string>
- </property>
- <property name="minimum">
- <number>128</number>
- </property>
- <property name="maximum">
- <number>65536</number>
- </property>
- <property name="singleStep">
- <number>128</number>
- </property>
- <property name="value">
- <number>256</number>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="labelPermGen">
- <property name="text">
- <string notr="true">PermGen:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="permGenSpinBox">
- <property name="toolTip">
- <string>The amount of memory available to store loaded Java classes.</string>
- </property>
- <property name="suffix">
- <string notr="true"> MiB</string>
- </property>
- <property name="minimum">
- <number>64</number>
- </property>
- <property name="maximum">
- <number>999999999</number>
- </property>
- <property name="singleStep">
- <number>8</number>
- </property>
- <property name="value">
- <number>64</number>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="javaSettingsGroupBox">
- <property name="title">
- <string>Java Runtime</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <widget class="QLabel" name="labelJavaPath">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Java path:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" colspan="2">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLineEdit" name="javaPathTextBox"/>
- </item>
- <item>
- <widget class="QPushButton" name="javaBrowseBtn">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>28</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="text">
- <string notr="true">...</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="1" colspan="2">
- <widget class="QLineEdit" name="jvmArgsTextBox"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="labelJVMArgs">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>JVM arguments:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QPushButton" name="javaDetectBtn">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Auto-detect...</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QPushButton" name="javaTestBtn">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Test</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>minMemSpinBox</tabstop>
- <tabstop>maxMemSpinBox</tabstop>
- <tabstop>permGenSpinBox</tabstop>
- <tabstop>javaBrowseBtn</tabstop>
- <tabstop>javaPathTextBox</tabstop>
- <tabstop>jvmArgsTextBox</tabstop>
- <tabstop>javaDetectBtn</tabstop>
- <tabstop>javaTestBtn</tabstop>
- <tabstop>tabWidget</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/global/LanguagePage.cpp b/application/pages/global/LanguagePage.cpp
deleted file mode 100644
index ae3168cc..00000000
--- a/application/pages/global/LanguagePage.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "LanguagePage.h"
-
-#include "widgets/LanguageSelectionWidget.h"
-#include <QVBoxLayout>
-
-LanguagePage::LanguagePage(QWidget* parent) :
- QWidget(parent)
-{
- setObjectName(QStringLiteral("languagePage"));
- auto layout = new QVBoxLayout(this);
- mainWidget = new LanguageSelectionWidget(this);
- layout->setContentsMargins(0,0,0,0);
- layout->addWidget(mainWidget);
- retranslate();
-}
-
-LanguagePage::~LanguagePage()
-{
-}
-
-bool LanguagePage::apply()
-{
- applySettings();
- return true;
-}
-
-void LanguagePage::applySettings()
-{
- auto settings = MMC->settings();
- QString key = mainWidget->getSelectedLanguageKey();
- settings->set("Language", key);
-}
-
-void LanguagePage::loadSettings()
-{
- // NIL
-}
-
-void LanguagePage::retranslate()
-{
- mainWidget->retranslate();
-}
-
-void LanguagePage::changeEvent(QEvent* event)
-{
- if (event->type() == QEvent::LanguageChange)
- {
- retranslate();
- }
- QWidget::changeEvent(event);
-}
diff --git a/application/pages/global/LanguagePage.h b/application/pages/global/LanguagePage.h
deleted file mode 100644
index ca8eecc6..00000000
--- a/application/pages/global/LanguagePage.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright 2013-2021 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 <memory>
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include <QWidget>
-
-class LanguageSelectionWidget;
-
-class LanguagePage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit LanguagePage(QWidget *parent = 0);
- virtual ~LanguagePage();
-
- QString displayName() const override
- {
- return tr("Language");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("language");
- }
- QString id() const override
- {
- return "language-settings";
- }
- QString helpPage() const override
- {
- return "Language-settings";
- }
- bool apply() override;
-
- void changeEvent(QEvent * ) override;
-
-private:
- void applySettings();
- void loadSettings();
- void retranslate();
-
-private:
- LanguageSelectionWidget *mainWidget;
-};
diff --git a/application/pages/global/MinecraftPage.cpp b/application/pages/global/MinecraftPage.cpp
deleted file mode 100644
index 6c9bd307..00000000
--- a/application/pages/global/MinecraftPage.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright 2013-2021 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 "MinecraftPage.h"
-#include "ui_MinecraftPage.h"
-
-#include <QMessageBox>
-#include <QDir>
-#include <QTabBar>
-
-#include "settings/SettingsObject.h"
-#include "MultiMC.h"
-
-MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- loadSettings();
- updateCheckboxStuff();
-}
-
-MinecraftPage::~MinecraftPage()
-{
- delete ui;
-}
-
-bool MinecraftPage::apply()
-{
- applySettings();
- return true;
-}
-
-void MinecraftPage::updateCheckboxStuff()
-{
- ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked());
- ui->windowHeightSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked());
-}
-
-void MinecraftPage::on_maximizedCheckBox_clicked(bool checked)
-{
- Q_UNUSED(checked);
- updateCheckboxStuff();
-}
-
-
-void MinecraftPage::applySettings()
-{
- auto s = MMC->settings();
-
- // Window Size
- s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
- s->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
- s->set("MinecraftWinHeight", ui->windowHeightSpinBox->value());
-
- // Native library workarounds
- s->set("UseNativeOpenAL", ui->useNativeOpenALCheck->isChecked());
- s->set("UseNativeGLFW", ui->useNativeGLFWCheck->isChecked());
-
- // Game time
- s->set("ShowGameTime", ui->showGameTime->isChecked());
- s->set("RecordGameTime", ui->recordGameTime->isChecked());
-}
-
-void MinecraftPage::loadSettings()
-{
- auto s = MMC->settings();
-
- // Window Size
- ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool());
- ui->windowWidthSpinBox->setValue(s->get("MinecraftWinWidth").toInt());
- ui->windowHeightSpinBox->setValue(s->get("MinecraftWinHeight").toInt());
-
- ui->useNativeOpenALCheck->setChecked(s->get("UseNativeOpenAL").toBool());
- ui->useNativeGLFWCheck->setChecked(s->get("UseNativeGLFW").toBool());
-
- ui->showGameTime->setChecked(s->get("ShowGameTime").toBool());
- ui->recordGameTime->setChecked(s->get("RecordGameTime").toBool());
-}
diff --git a/application/pages/global/MinecraftPage.h b/application/pages/global/MinecraftPage.h
deleted file mode 100644
index 5e781aed..00000000
--- a/application/pages/global/MinecraftPage.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2013-2021 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 <memory>
-#include <QDialog>
-
-#include "java/JavaChecker.h"
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-class SettingsObject;
-
-namespace Ui
-{
-class MinecraftPage;
-}
-
-class MinecraftPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit MinecraftPage(QWidget *parent = 0);
- ~MinecraftPage();
-
- QString displayName() const override
- {
- return tr("Minecraft");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("minecraft");
- }
- QString id() const override
- {
- return "minecraft-settings";
- }
- QString helpPage() const override
- {
- return "Minecraft-settings";
- }
- bool apply() override;
-
-private:
- void updateCheckboxStuff();
- void applySettings();
- void loadSettings();
-
-private
-slots:
- void on_maximizedCheckBox_clicked(bool checked);
-
-private:
- Ui::MinecraftPage *ui;
-
-};
diff --git a/application/pages/global/MinecraftPage.ui b/application/pages/global/MinecraftPage.ui
deleted file mode 100644
index 2abd4bd4..00000000
--- a/application/pages/global/MinecraftPage.ui
+++ /dev/null
@@ -1,189 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MinecraftPage</class>
- <widget class="QWidget" name="MinecraftPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>936</width>
- <height>1134</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QVBoxLayout" name="mainLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="tabShape">
- <enum>QTabWidget::Rounded</enum>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="minecraftTab">
- <attribute name="title">
- <string notr="true">Minecraft</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QGroupBox" name="windowSizeGroupBox">
- <property name="title">
- <string>Window Size</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <widget class="QCheckBox" name="maximizedCheckBox">
- <property name="text">
- <string>Start Minecraft maximized?</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayoutWindowSize">
- <item row="1" column="0">
- <widget class="QLabel" name="labelWindowHeight">
- <property name="text">
- <string>Window hei&amp;ght:</string>
- </property>
- <property name="buddy">
- <cstring>windowHeightSpinBox</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="labelWindowWidth">
- <property name="text">
- <string>W&amp;indow width:</string>
- </property>
- <property name="buddy">
- <cstring>windowWidthSpinBox</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="windowWidthSpinBox">
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>65536</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>854</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="windowHeightSpinBox">
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>65536</number>
- </property>
- <property name="value">
- <number>480</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="nativeLibWorkaroundGroupBox">
- <property name="title">
- <string>Native library workarounds</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <widget class="QCheckBox" name="useNativeGLFWCheck">
- <property name="text">
- <string>Use system installation of GLFW</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="useNativeOpenALCheck">
- <property name="text">
- <string>Use system installation of OpenAL</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="gameTimeGroupBox">
- <property name="title">
- <string>Game time</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_6">
- <item>
- <widget class="QCheckBox" name="showGameTime">
- <property name="text">
- <string>Show time spent playing instances</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="recordGameTime">
- <property name="text">
- <string>Record time spent playing instances</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacerMinecraft">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>maximizedCheckBox</tabstop>
- <tabstop>windowWidthSpinBox</tabstop>
- <tabstop>windowHeightSpinBox</tabstop>
- <tabstop>useNativeGLFWCheck</tabstop>
- <tabstop>useNativeOpenALCheck</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/global/MultiMCPage.cpp b/application/pages/global/MultiMCPage.cpp
deleted file mode 100644
index d383e6ed..00000000
--- a/application/pages/global/MultiMCPage.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/* Copyright 2013-2021 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 "MultiMCPage.h"
-#include "ui_MultiMCPage.h"
-
-#include <QFileDialog>
-#include <QMessageBox>
-#include <QDir>
-#include <QTextCharFormat>
-
-#include "updater/UpdateChecker.h"
-
-#include "settings/SettingsObject.h"
-#include <FileSystem.h>
-#include "MultiMC.h"
-#include "BuildConfig.h"
-#include "themes/ITheme.h"
-
-#include <QApplication>
-#include <QProcess>
-
-// FIXME: possibly move elsewhere
-enum InstSortMode
-{
- // Sort alphabetically by name.
- Sort_Name,
- // Sort by which instance was launched most recently.
- Sort_LastLaunch
-};
-
-MultiMCPage::MultiMCPage(QWidget *parent) : QWidget(parent), ui(new Ui::MultiMCPage)
-{
- ui->setupUi(this);
- auto origForeground = ui->fontPreview->palette().color(ui->fontPreview->foregroundRole());
- auto origBackground = ui->fontPreview->palette().color(ui->fontPreview->backgroundRole());
- m_colors.reset(new LogColorCache(origForeground, origBackground));
-
- ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name);
- ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch);
-
- defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat());
-
- m_languageModel = MMC->translations();
- loadSettings();
-
- if(BuildConfig.UPDATER_ENABLED)
- {
- QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this,
- &MultiMCPage::refreshUpdateChannelList);
-
- if (MMC->updateChecker()->hasChannels())
- {
- refreshUpdateChannelList();
- }
- else
- {
- MMC->updateChecker()->updateChanList(false);
- }
- }
- else
- {
- ui->updateSettingsBox->setHidden(true);
- }
- // Analytics
- if(BuildConfig.ANALYTICS_ID.isEmpty())
- {
- ui->tabWidget->removeTab(ui->tabWidget->indexOf(ui->analyticsTab));
- }
- connect(ui->fontSizeBox, SIGNAL(valueChanged(int)), SLOT(refreshFontPreview()));
- connect(ui->consoleFont, SIGNAL(currentFontChanged(QFont)), SLOT(refreshFontPreview()));
-
- //move mac data button
- QFile file(QDir::current().absolutePath() + "/dontmovemacdata");
- if (!file.exists())
- {
- ui->migrateDataFolderMacBtn->setVisible(false);
- }
-}
-
-MultiMCPage::~MultiMCPage()
-{
- delete ui;
- delete defaultFormat;
-}
-
-bool MultiMCPage::apply()
-{
- applySettings();
- return true;
-}
-
-void MultiMCPage::on_instDirBrowseBtn_clicked()
-{
- QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Folder"), ui->instDirTextBox->text());
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
- {
- QString cooked_dir = FS::NormalizePath(raw_dir);
- if (FS::checkProblemticPathJava(QDir(cooked_dir)))
- {
- QMessageBox warning;
- warning.setText(tr("You're trying to specify an instance folder which\'s path "
- "contains at least one \'!\'. "
- "Java is known to cause problems if that is the case, your "
- "instances (probably) won't start!"));
- warning.setInformativeText(
- tr("Do you really want to use this path? "
- "Selecting \"No\" will close this and not alter your instance path."));
- warning.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- int result = warning.exec();
- if (result == QMessageBox::Yes)
- {
- ui->instDirTextBox->setText(cooked_dir);
- }
- }
- else
- {
- ui->instDirTextBox->setText(cooked_dir);
- }
- }
-}
-
-void MultiMCPage::on_iconsDirBrowseBtn_clicked()
-{
- QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Folder"), ui->iconsDirTextBox->text());
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
- {
- QString cooked_dir = FS::NormalizePath(raw_dir);
- ui->iconsDirTextBox->setText(cooked_dir);
- }
-}
-void MultiMCPage::on_modsDirBrowseBtn_clicked()
-{
- QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Folder"), ui->modsDirTextBox->text());
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if (!raw_dir.isEmpty() && QDir(raw_dir).exists())
- {
- QString cooked_dir = FS::NormalizePath(raw_dir);
- ui->modsDirTextBox->setText(cooked_dir);
- }
-}
-void MultiMCPage::on_migrateDataFolderMacBtn_clicked()
-{
- QFile file(QDir::current().absolutePath() + "/dontmovemacdata");
- file.remove();
- QProcess::startDetached(qApp->arguments()[0]);
- qApp->quit();
-}
-
-void MultiMCPage::refreshUpdateChannelList()
-{
- // Stop listening for selection changes. It's going to change a lot while we update it and
- // we don't need to update the
- // description label constantly.
- QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this,
- SLOT(updateChannelSelectionChanged(int)));
-
- QList<UpdateChecker::ChannelListEntry> channelList = MMC->updateChecker()->getChannelList();
- ui->updateChannelComboBox->clear();
- int selection = -1;
- for (int i = 0; i < channelList.count(); i++)
- {
- UpdateChecker::ChannelListEntry entry = channelList.at(i);
-
- // When it comes to selection, we'll rely on the indexes of a channel entry being the
- // same in the
- // combo box as it is in the update checker's channel list.
- // This probably isn't very safe, but the channel list doesn't change often enough (or
- // at all) for
- // this to be a big deal. Hope it doesn't break...
- ui->updateChannelComboBox->addItem(entry.name);
-
- // If the update channel we just added was the selected one, set the current index in
- // the combo box to it.
- if (entry.id == m_currentUpdateChannel)
- {
- qDebug() << "Selected index" << i << "channel id" << m_currentUpdateChannel;
- selection = i;
- }
- }
-
- ui->updateChannelComboBox->setCurrentIndex(selection);
-
- // Start listening for selection changes again and update the description label.
- QObject::connect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this,
- SLOT(updateChannelSelectionChanged(int)));
- refreshUpdateChannelDesc();
-
- // Now that we've updated the channel list, we can enable the combo box.
- // It starts off disabled so that if the channel list hasn't been loaded, it will be
- // disabled.
- ui->updateChannelComboBox->setEnabled(true);
-}
-
-void MultiMCPage::updateChannelSelectionChanged(int index)
-{
- refreshUpdateChannelDesc();
-}
-
-void MultiMCPage::refreshUpdateChannelDesc()
-{
- // Get the channel list.
- QList<UpdateChecker::ChannelListEntry> channelList = MMC->updateChecker()->getChannelList();
- int selectedIndex = ui->updateChannelComboBox->currentIndex();
- if (selectedIndex < 0)
- {
- return;
- }
- if (selectedIndex < channelList.count())
- {
- // Find the channel list entry with the given index.
- UpdateChecker::ChannelListEntry selected = channelList.at(selectedIndex);
-
- // Set the description text.
- ui->updateChannelDescLabel->setText(selected.description);
-
- // Set the currently selected channel ID.
- m_currentUpdateChannel = selected.id;
- }
-}
-
-void MultiMCPage::applySettings()
-{
- auto s = MMC->settings();
-
- if (ui->resetNotificationsBtn->isChecked())
- {
- s->set("ShownNotifications", QString());
- }
-
- // Updates
- s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked());
- s->set("UpdateChannel", m_currentUpdateChannel);
- auto original = s->get("IconTheme").toString();
- //FIXME: make generic
- switch (ui->themeComboBox->currentIndex())
- {
- case 1:
- s->set("IconTheme", "pe_dark");
- break;
- case 2:
- s->set("IconTheme", "pe_light");
- break;
- case 3:
- s->set("IconTheme", "pe_blue");
- break;
- case 4:
- s->set("IconTheme", "pe_colored");
- break;
- case 5:
- s->set("IconTheme", "OSX");
- break;
- case 6:
- s->set("IconTheme", "iOS");
- break;
- case 7:
- s->set("IconTheme", "flat");
- break;
- case 8:
- s->set("IconTheme", "custom");
- break;
- case 0:
- default:
- s->set("IconTheme", "multimc");
- break;
- }
-
- if(original != s->get("IconTheme"))
- {
- MMC->setIconTheme(s->get("IconTheme").toString());
- }
-
- auto originalAppTheme = s->get("ApplicationTheme").toString();
- auto newAppTheme = ui->themeComboBoxColors->currentData().toString();
- if(originalAppTheme != newAppTheme)
- {
- s->set("ApplicationTheme", newAppTheme);
- MMC->setApplicationTheme(newAppTheme, false);
- }
-
- // Console settings
- s->set("ShowConsole", ui->showConsoleCheck->isChecked());
- s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
- s->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked());
- QString consoleFontFamily = ui->consoleFont->currentFont().family();
- s->set("ConsoleFont", consoleFontFamily);
- s->set("ConsoleFontSize", ui->fontSizeBox->value());
- s->set("ConsoleMaxLines", ui->lineLimitSpinBox->value());
- s->set("ConsoleOverflowStop", ui->checkStopLogging->checkState() != Qt::Unchecked);
-
- // Folders
- // TODO: Offer to move instances to new instance folder.
- s->set("InstanceDir", ui->instDirTextBox->text());
- s->set("CentralModsDir", ui->modsDirTextBox->text());
- s->set("IconsDir", ui->iconsDirTextBox->text());
-
- auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId();
- switch (sortMode)
- {
- case Sort_LastLaunch:
- s->set("InstSortMode", "LastLaunch");
- break;
- case Sort_Name:
- default:
- s->set("InstSortMode", "Name");
- break;
- }
-
- // Analytics
- if(!BuildConfig.ANALYTICS_ID.isEmpty())
- {
- s->set("Analytics", ui->analyticsCheck->isChecked());
- }
-}
-void MultiMCPage::loadSettings()
-{
- auto s = MMC->settings();
- // Updates
- ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool());
- m_currentUpdateChannel = s->get("UpdateChannel").toString();
- //FIXME: make generic
- auto theme = s->get("IconTheme").toString();
- if (theme == "pe_dark")
- {
- ui->themeComboBox->setCurrentIndex(1);
- }
- else if (theme == "pe_light")
- {
- ui->themeComboBox->setCurrentIndex(2);
- }
- else if (theme == "pe_blue")
- {
- ui->themeComboBox->setCurrentIndex(3);
- }
- else if (theme == "pe_colored")
- {
- ui->themeComboBox->setCurrentIndex(4);
- }
- else if (theme == "OSX")
- {
- ui->themeComboBox->setCurrentIndex(5);
- }
- else if (theme == "iOS")
- {
- ui->themeComboBox->setCurrentIndex(6);
- }
- else if (theme == "flat")
- {
- ui->themeComboBox->setCurrentIndex(7);
- }
- else if (theme == "custom")
- {
- ui->themeComboBox->setCurrentIndex(8);
- }
- else
- {
- ui->themeComboBox->setCurrentIndex(0);
- }
-
- {
- auto currentTheme = s->get("ApplicationTheme").toString();
- auto themes = MMC->getValidApplicationThemes();
- int idx = 0;
- for(auto &theme: themes)
- {
- ui->themeComboBoxColors->addItem(theme->name(), theme->id());
- if(currentTheme == theme->id())
- {
- ui->themeComboBoxColors->setCurrentIndex(idx);
- }
- idx++;
- }
- }
-
- // Console settings
- ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool());
- ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool());
- ui->showConsoleErrorCheck->setChecked(s->get("ShowConsoleOnError").toBool());
- QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
- QFont consoleFont(fontFamily);
- ui->consoleFont->setCurrentFont(consoleFont);
-
- bool conversionOk = true;
- int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
- if(!conversionOk)
- {
- fontSize = 11;
- }
- ui->fontSizeBox->setValue(fontSize);
- refreshFontPreview();
- ui->lineLimitSpinBox->setValue(s->get("ConsoleMaxLines").toInt());
- ui->checkStopLogging->setChecked(s->get("ConsoleOverflowStop").toBool());
-
- // Folders
- ui->instDirTextBox->setText(s->get("InstanceDir").toString());
- ui->modsDirTextBox->setText(s->get("CentralModsDir").toString());
- ui->iconsDirTextBox->setText(s->get("IconsDir").toString());
-
- QString sortMode = s->get("InstSortMode").toString();
-
- if (sortMode == "LastLaunch")
- {
- ui->sortLastLaunchedBtn->setChecked(true);
- }
- else
- {
- ui->sortByNameBtn->setChecked(true);
- }
-
- // Analytics
- if(!BuildConfig.ANALYTICS_ID.isEmpty())
- {
- ui->analyticsCheck->setChecked(s->get("Analytics").toBool());
- }
-}
-
-void MultiMCPage::refreshFontPreview()
-{
- int fontSize = ui->fontSizeBox->value();
- QString fontFamily = ui->consoleFont->currentFont().family();
- ui->fontPreview->clear();
- defaultFormat->setFont(QFont(fontFamily, fontSize));
- {
- QTextCharFormat format(*defaultFormat);
- format.setForeground(m_colors->getFront(MessageLevel::Error));
- // append a paragraph/line
- auto workCursor = ui->fontPreview->textCursor();
- workCursor.movePosition(QTextCursor::End);
- workCursor.insertText(tr("[Something/ERROR] A spooky error!"), format);
- workCursor.insertBlock();
- }
- {
- QTextCharFormat format(*defaultFormat);
- format.setForeground(m_colors->getFront(MessageLevel::Message));
- // append a paragraph/line
- auto workCursor = ui->fontPreview->textCursor();
- workCursor.movePosition(QTextCursor::End);
- workCursor.insertText(tr("[Test/INFO] A harmless message..."), format);
- workCursor.insertBlock();
- }
- {
- QTextCharFormat format(*defaultFormat);
- format.setForeground(m_colors->getFront(MessageLevel::Warning));
- // append a paragraph/line
- auto workCursor = ui->fontPreview->textCursor();
- workCursor.movePosition(QTextCursor::End);
- workCursor.insertText(tr("[Something/WARN] A not so spooky warning."), format);
- workCursor.insertBlock();
- }
-}
diff --git a/application/pages/global/MultiMCPage.h b/application/pages/global/MultiMCPage.h
deleted file mode 100644
index fae75bf2..00000000
--- a/application/pages/global/MultiMCPage.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* Copyright 2013-2021 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 <memory>
-#include <QDialog>
-
-#include "java/JavaChecker.h"
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "ColorCache.h"
-#include <translations/TranslationsModel.h>
-
-class QTextCharFormat;
-class SettingsObject;
-
-namespace Ui
-{
-class MultiMCPage;
-}
-
-class MultiMCPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit MultiMCPage(QWidget *parent = 0);
- ~MultiMCPage();
-
- QString displayName() const override
- {
- return "MultiMC";
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("multimc");
- }
- QString id() const override
- {
- return "multimc-settings";
- }
- QString helpPage() const override
- {
- return "MultiMC-settings";
- }
- bool apply() override;
-
-private:
- void applySettings();
- void loadSettings();
-
-private
-slots:
- void on_instDirBrowseBtn_clicked();
- void on_modsDirBrowseBtn_clicked();
- void on_iconsDirBrowseBtn_clicked();
- void on_migrateDataFolderMacBtn_clicked();
-
- /*!
- * Updates the list of update channels in the combo box.
- */
- void refreshUpdateChannelList();
-
- /*!
- * Updates the channel description label.
- */
- void refreshUpdateChannelDesc();
-
- /*!
- * Updates the font preview
- */
- void refreshFontPreview();
-
- void updateChannelSelectionChanged(int index);
-
-private:
- Ui::MultiMCPage *ui;
-
- /*!
- * Stores the currently selected update channel.
- */
- QString m_currentUpdateChannel;
-
- // default format for the font preview...
- QTextCharFormat *defaultFormat;
-
- std::unique_ptr<LogColorCache> m_colors;
-
- std::shared_ptr<TranslationsModel> m_languageModel;
-};
diff --git a/application/pages/global/MultiMCPage.ui b/application/pages/global/MultiMCPage.ui
deleted file mode 100644
index 4ad20242..00000000
--- a/application/pages/global/MultiMCPage.ui
+++ /dev/null
@@ -1,584 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MultiMCPage</class>
- <widget class="QWidget" name="MultiMCPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>514</width>
- <height>629</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QVBoxLayout" name="mainLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="toolTip">
- <string notr="true"/>
- </property>
- <property name="tabShape">
- <enum>QTabWidget::Rounded</enum>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="featuresTab">
- <attribute name="title">
- <string>Features</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_9">
- <item>
- <widget class="QGroupBox" name="updateSettingsBox">
- <property name="title">
- <string>Update Settings</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_7">
- <item>
- <widget class="QCheckBox" name="autoUpdateCheckBox">
- <property name="text">
- <string>Check for updates when MultiMC starts?</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="updateChannelLabel">
- <property name="text">
- <string>Up&amp;date Channel:</string>
- </property>
- <property name="buddy">
- <cstring>updateChannelComboBox</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="updateChannelComboBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="updateChannelDescLabel">
- <property name="text">
- <string>No channel selected.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="foldersBox">
- <property name="title">
- <string>Folders</string>
- </property>
- <layout class="QGridLayout" name="foldersBoxLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="labelInstDir">
- <property name="text">
- <string>I&amp;nstances:</string>
- </property>
- <property name="buddy">
- <cstring>instDirTextBox</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="instDirTextBox"/>
- </item>
- <item row="0" column="2">
- <widget class="QToolButton" name="instDirBrowseBtn">
- <property name="text">
- <string notr="true">...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="labelModsDir">
- <property name="text">
- <string>&amp;Mods:</string>
- </property>
- <property name="buddy">
- <cstring>modsDirTextBox</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="modsDirTextBox"/>
- </item>
- <item row="1" column="2">
- <widget class="QToolButton" name="modsDirBrowseBtn">
- <property name="text">
- <string notr="true">...</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="iconsDirTextBox"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="labelIconsDir">
- <property name="text">
- <string>&amp;Icons:</string>
- </property>
- <property name="buddy">
- <cstring>iconsDirTextBox</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QToolButton" name="iconsDirBrowseBtn">
- <property name="text">
- <string notr="true">...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="migrateDataFolderMacBtn">
- <property name="text">
- <string>Move MultiMC data to new location (will restart MultiMC)</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="generalTab">
- <attribute name="title">
- <string>User Interface</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_6">
- <item>
- <widget class="QGroupBox" name="groupBox_3">
- <property name="title">
- <string>MultiMC notifications</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <widget class="QPushButton" name="resetNotificationsBtn">
- <property name="text">
- <string>Reset hidden notifications</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="sortingModeBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>Instance view sorting mode</string>
- </property>
- <layout class="QHBoxLayout" name="sortingModeBoxLayout">
- <item>
- <widget class="QRadioButton" name="sortLastLaunchedBtn">
- <property name="text">
- <string>By &amp;last launched</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">sortingModeGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="sortByNameBtn">
- <property name="text">
- <string>By &amp;name</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">sortingModeGroup</string>
- </attribute>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="themeBox">
- <property name="title">
- <string>Theme</string>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>&amp;Icons</string>
- </property>
- <property name="buddy">
- <cstring>themeComboBox</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QComboBox" name="themeComboBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <item>
- <property name="text">
- <string>Default</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Simple (Dark Icons)</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Simple (Light Icons)</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Simple (Blue Icons)</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Simple (Colored Icons)</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">OSX</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">iOS</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string notr="true">Flat</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Custom</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QComboBox" name="themeComboBoxColors">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Colors</string>
- </property>
- <property name="buddy">
- <cstring>themeComboBoxColors</cstring>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="generalTabSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="consoleTab">
- <attribute name="title">
- <string>Console</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QGroupBox" name="consoleSettingsBox">
- <property name="title">
- <string>Console Settings</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QCheckBox" name="showConsoleCheck">
- <property name="text">
- <string>Show console while the game is running?</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="autoCloseConsoleCheck">
- <property name="text">
- <string>Automatically close console when the game quits?</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="showConsoleErrorCheck">
- <property name="text">
- <string>Show console when the game crashes?</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_4">
- <property name="title">
- <string>History limit</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="1" column="0">
- <widget class="QCheckBox" name="checkStopLogging">
- <property name="text">
- <string>Stop logging when log overflows</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QSpinBox" name="lineLimitSpinBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="suffix">
- <string> lines</string>
- </property>
- <property name="minimum">
- <number>10000</number>
- </property>
- <property name="maximum">
- <number>1000000</number>
- </property>
- <property name="singleStep">
- <number>10000</number>
- </property>
- <property name="value">
- <number>100000</number>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="themeBox_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title">
- <string>Console font</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="1" column="0" colspan="2">
- <widget class="QTextEdit" name="fontPreview">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="undoRedoEnabled">
- <bool>false</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QFontComboBox" name="consoleFont">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="fontSizeBox">
- <property name="minimum">
- <number>5</number>
- </property>
- <property name="maximum">
- <number>16</number>
- </property>
- <property name="value">
- <number>11</number>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="analyticsTab">
- <attribute name="title">
- <string>Analytics</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_8">
- <item>
- <widget class="QGroupBox" name="consoleSettingsBox_2">
- <property name="title">
- <string>Analytics Settings</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <widget class="QCheckBox" name="analyticsCheck">
- <property name="text">
- <string>Send anonymous usage statistics?</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;
-&lt;body&gt;
-&lt;p&gt;MultiMC sends anonymous usage statistics on every start of the application.&lt;/p&gt;&lt;p&gt;The following data is collected:&lt;/p&gt;
-&lt;ul&gt;
-&lt;li&gt;MultiMC version.&lt;/li&gt;
-&lt;li&gt;Operating system name, version and architecture.&lt;/li&gt;
-&lt;li&gt;CPU architecture (kernel architecture on linux).&lt;/li&gt;
-&lt;li&gt;Size of system memory.&lt;/li&gt;
-&lt;li&gt;Java version, architecture and memory settings.&lt;/li&gt;
-&lt;/ul&gt;
-&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>autoUpdateCheckBox</tabstop>
- <tabstop>updateChannelComboBox</tabstop>
- <tabstop>instDirTextBox</tabstop>
- <tabstop>instDirBrowseBtn</tabstop>
- <tabstop>modsDirTextBox</tabstop>
- <tabstop>modsDirBrowseBtn</tabstop>
- <tabstop>iconsDirTextBox</tabstop>
- <tabstop>iconsDirBrowseBtn</tabstop>
- <tabstop>resetNotificationsBtn</tabstop>
- <tabstop>sortLastLaunchedBtn</tabstop>
- <tabstop>sortByNameBtn</tabstop>
- <tabstop>themeComboBox</tabstop>
- <tabstop>themeComboBoxColors</tabstop>
- <tabstop>showConsoleCheck</tabstop>
- <tabstop>autoCloseConsoleCheck</tabstop>
- <tabstop>showConsoleErrorCheck</tabstop>
- <tabstop>lineLimitSpinBox</tabstop>
- <tabstop>checkStopLogging</tabstop>
- <tabstop>consoleFont</tabstop>
- <tabstop>fontSizeBox</tabstop>
- <tabstop>fontPreview</tabstop>
- </tabstops>
- <resources/>
- <connections/>
- <buttongroups>
- <buttongroup name="sortingModeGroup"/>
- </buttongroups>
-</ui>
diff --git a/application/pages/global/PasteEEPage.cpp b/application/pages/global/PasteEEPage.cpp
deleted file mode 100644
index f932dede..00000000
--- a/application/pages/global/PasteEEPage.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Copyright 2013-2021 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 "PasteEEPage.h"
-#include "ui_PasteEEPage.h"
-
-#include <QMessageBox>
-#include <QFileDialog>
-#include <QStandardPaths>
-#include <QTabBar>
-
-#include "settings/SettingsObject.h"
-#include "tools/BaseProfiler.h"
-#include "MultiMC.h"
-
-PasteEEPage::PasteEEPage(QWidget *parent) :
- QWidget(parent),
- ui(new Ui::PasteEEPage)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();\
- connect(ui->customAPIkeyEdit, &QLineEdit::textEdited, this, &PasteEEPage::textEdited);
- loadSettings();
-}
-
-PasteEEPage::~PasteEEPage()
-{
- delete ui;
-}
-
-void PasteEEPage::loadSettings()
-{
- auto s = MMC->settings();
- QString keyToUse = s->get("PasteEEAPIKey").toString();
- if(keyToUse == "multimc")
- {
- ui->multimcButton->setChecked(true);
- }
- else
- {
- ui->customButton->setChecked(true);
- ui->customAPIkeyEdit->setText(keyToUse);
- }
-}
-
-void PasteEEPage::applySettings()
-{
- auto s = MMC->settings();
-
- QString pasteKeyToUse;
- if (ui->customButton->isChecked())
- pasteKeyToUse = ui->customAPIkeyEdit->text();
- else
- {
- pasteKeyToUse = "multimc";
- }
- s->set("PasteEEAPIKey", pasteKeyToUse);
-}
-
-bool PasteEEPage::apply()
-{
- applySettings();
- return true;
-}
-
-void PasteEEPage::textEdited(const QString& text)
-{
- ui->customButton->setChecked(true);
-}
diff --git a/application/pages/global/PasteEEPage.h b/application/pages/global/PasteEEPage.h
deleted file mode 100644
index 001decdb..00000000
--- a/application/pages/global/PasteEEPage.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-namespace Ui {
-class PasteEEPage;
-}
-
-class PasteEEPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit PasteEEPage(QWidget *parent = 0);
- ~PasteEEPage();
-
- QString displayName() const override
- {
- return tr("Log Upload");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("log");
- }
- QString id() const override
- {
- return "log-upload";
- }
- QString helpPage() const override
- {
- return "Log-Upload";
- }
- virtual bool apply() override;
-
-private:
- void loadSettings();
- void applySettings();
-
-private slots:
- void textEdited(const QString &text);
-
-private:
- Ui::PasteEEPage *ui;
-};
diff --git a/application/pages/global/PasteEEPage.ui b/application/pages/global/PasteEEPage.ui
deleted file mode 100644
index 10883781..00000000
--- a/application/pages/global/PasteEEPage.ui
+++ /dev/null
@@ -1,128 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>PasteEEPage</class>
- <widget class="QWidget" name="PasteEEPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>491</width>
- <height>474</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string notr="true">Tab 1</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string>paste.ee API key</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_10">
- <item>
- <widget class="QRadioButton" name="multimcButton">
- <property name="text">
- <string>MultiMC key - 12MB &amp;upload limit</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">pasteButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="customButton">
- <property name="text">
- <string>&amp;Your own key - 12MB upload limit:</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">pasteButtonGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="customAPIkeyEdit">
- <property name="echoMode">
- <enum>QLineEdit::Password</enum>
- </property>
- <property name="placeholderText">
- <string>Paste your API key here!</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;https://paste.ee&quot;&gt;paste.ee&lt;/a&gt; is used by MultiMC for log uploads. If you have a &lt;a href=&quot;https://paste.ee&quot;&gt;paste.ee&lt;/a&gt; account, you can add your API key here and have your uploaded logs paired with your account.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="textFormat">
- <enum>Qt::RichText</enum>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>216</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>multimcButton</tabstop>
- <tabstop>customButton</tabstop>
- <tabstop>customAPIkeyEdit</tabstop>
- </tabstops>
- <resources/>
- <connections/>
- <buttongroups>
- <buttongroup name="pasteButtonGroup"/>
- </buttongroups>
-</ui>
diff --git a/application/pages/global/ProxyPage.cpp b/application/pages/global/ProxyPage.cpp
deleted file mode 100644
index 809059ff..00000000
--- a/application/pages/global/ProxyPage.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright 2013-2021 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 "ProxyPage.h"
-#include "ui_ProxyPage.h"
-
-#include <QTabBar>
-
-#include "settings/SettingsObject.h"
-#include "MultiMC.h"
-#include "Env.h"
-
-ProxyPage::ProxyPage(QWidget *parent) : QWidget(parent), ui(new Ui::ProxyPage)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- loadSettings();
- updateCheckboxStuff();
-
- connect(ui->proxyGroup, SIGNAL(buttonClicked(int)), SLOT(proxyChanged(int)));
-}
-
-ProxyPage::~ProxyPage()
-{
- delete ui;
-}
-
-bool ProxyPage::apply()
-{
- applySettings();
- return true;
-}
-
-void ProxyPage::updateCheckboxStuff()
-{
- ui->proxyAddrBox->setEnabled(!ui->proxyNoneBtn->isChecked() &&
- !ui->proxyDefaultBtn->isChecked());
- ui->proxyAuthBox->setEnabled(!ui->proxyNoneBtn->isChecked() &&
- !ui->proxyDefaultBtn->isChecked());
-}
-
-void ProxyPage::proxyChanged(int)
-{
- updateCheckboxStuff();
-}
-
-void ProxyPage::applySettings()
-{
- auto s = MMC->settings();
-
- // Proxy
- QString proxyType = "None";
- if (ui->proxyDefaultBtn->isChecked())
- proxyType = "Default";
- else if (ui->proxyNoneBtn->isChecked())
- proxyType = "None";
- else if (ui->proxySOCKS5Btn->isChecked())
- proxyType = "SOCKS5";
- else if (ui->proxyHTTPBtn->isChecked())
- proxyType = "HTTP";
-
- s->set("ProxyType", proxyType);
- s->set("ProxyAddr", ui->proxyAddrEdit->text());
- s->set("ProxyPort", ui->proxyPortEdit->value());
- s->set("ProxyUser", ui->proxyUserEdit->text());
- s->set("ProxyPass", ui->proxyPassEdit->text());
-
- ENV.updateProxySettings(proxyType, ui->proxyAddrEdit->text(), ui->proxyPortEdit->value(),
- ui->proxyUserEdit->text(), ui->proxyPassEdit->text());
-}
-void ProxyPage::loadSettings()
-{
- auto s = MMC->settings();
- // Proxy
- QString proxyType = s->get("ProxyType").toString();
- if (proxyType == "Default")
- ui->proxyDefaultBtn->setChecked(true);
- else if (proxyType == "None")
- ui->proxyNoneBtn->setChecked(true);
- else if (proxyType == "SOCKS5")
- ui->proxySOCKS5Btn->setChecked(true);
- else if (proxyType == "HTTP")
- ui->proxyHTTPBtn->setChecked(true);
-
- ui->proxyAddrEdit->setText(s->get("ProxyAddr").toString());
- ui->proxyPortEdit->setValue(s->get("ProxyPort").value<uint16_t>());
- ui->proxyUserEdit->setText(s->get("ProxyUser").toString());
- ui->proxyPassEdit->setText(s->get("ProxyPass").toString());
-}
diff --git a/application/pages/global/ProxyPage.h b/application/pages/global/ProxyPage.h
deleted file mode 100644
index ff94ec49..00000000
--- a/application/pages/global/ProxyPage.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright 2013-2021 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 <memory>
-#include <QDialog>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-namespace Ui
-{
-class ProxyPage;
-}
-
-class ProxyPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit ProxyPage(QWidget *parent = 0);
- ~ProxyPage();
-
- QString displayName() const override
- {
- return tr("Proxy");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("proxy");
- }
- QString id() const override
- {
- return "proxy-settings";
- }
- QString helpPage() const override
- {
- return "Proxy-settings";
- }
- bool apply() override;
-
-private:
- void updateCheckboxStuff();
- void applySettings();
- void loadSettings();
-
-private
-slots:
- void proxyChanged(int);
-
-private:
- Ui::ProxyPage *ui;
-};
diff --git a/application/pages/global/ProxyPage.ui b/application/pages/global/ProxyPage.ui
deleted file mode 100644
index 69fcef1e..00000000
--- a/application/pages/global/ProxyPage.ui
+++ /dev/null
@@ -1,203 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ProxyPage</class>
- <widget class="QWidget" name="ProxyPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>598</width>
- <height>617</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <widget class="QWidget" name="tabWidgetPage1">
- <attribute name="title">
- <string notr="true"/>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="proxyPlainTextWarningLabel_2">
- <property name="text">
- <string>This only applies to MultiMC. Minecraft does not accept proxy settings.</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="proxyTypeBox">
- <property name="title">
- <string>Type</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QRadioButton" name="proxyDefaultBtn">
- <property name="toolTip">
- <string>Uses your system's default proxy settings.</string>
- </property>
- <property name="text">
- <string>&amp;Default</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">proxyGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="proxyNoneBtn">
- <property name="text">
- <string>&amp;None</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">proxyGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="proxySOCKS5Btn">
- <property name="text">
- <string>SOC&amp;KS5</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">proxyGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="proxyHTTPBtn">
- <property name="text">
- <string>H&amp;TTP</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">proxyGroup</string>
- </attribute>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="proxyAddrBox">
- <property name="title">
- <string>Address and Port</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLineEdit" name="proxyAddrEdit">
- <property name="placeholderText">
- <string notr="true">127.0.0.1</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="proxyPortEdit">
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- <property name="buttonSymbols">
- <enum>QAbstractSpinBox::PlusMinus</enum>
- </property>
- <property name="maximum">
- <number>65535</number>
- </property>
- <property name="value">
- <number>8080</number>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="proxyAuthBox">
- <property name="title">
- <string>Authentication</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_5">
- <item row="0" column="1">
- <widget class="QLineEdit" name="proxyUserEdit"/>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="proxyUsernameLabel">
- <property name="text">
- <string>Username:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="proxyPasswordLabel">
- <property name="text">
- <string>Password:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="proxyPassEdit">
- <property name="echoMode">
- <enum>QLineEdit::Password</enum>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="2">
- <widget class="QLabel" name="proxyPlainTextWarningLabel">
- <property name="text">
- <string>Note: Proxy username and password are stored in plain text inside MultiMC's configuration file!</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
- <buttongroups>
- <buttongroup name="proxyGroup"/>
- </buttongroups>
-</ui>
diff --git a/application/pages/instance/GameOptionsPage.cpp b/application/pages/instance/GameOptionsPage.cpp
deleted file mode 100644
index 782f2ab3..00000000
--- a/application/pages/instance/GameOptionsPage.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-#include "GameOptionsPage.h"
-#include "ui_GameOptionsPage.h"
-#include "minecraft/MinecraftInstance.h"
-#include "minecraft/gameoptions/GameOptions.h"
-
-GameOptionsPage::GameOptionsPage(MinecraftInstance * inst, QWidget* parent)
- : QWidget(parent), ui(new Ui::GameOptionsPage)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- m_model = inst->gameOptionsModel();
- ui->optionsView->setModel(m_model.get());
- auto head = ui->optionsView->header();
- if(head->count())
- {
- head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
- for(int i = 1; i < head->count(); i++)
- {
- head->setSectionResizeMode(i, QHeaderView::Stretch);
- }
- }
-}
-
-GameOptionsPage::~GameOptionsPage()
-{
- // m_model->save();
-}
-
-void GameOptionsPage::openedImpl()
-{
- // m_model->observe();
-}
-
-void GameOptionsPage::closedImpl()
-{
- // m_model->unobserve();
-}
diff --git a/application/pages/instance/GameOptionsPage.h b/application/pages/instance/GameOptionsPage.h
deleted file mode 100644
index 0fd2fbff..00000000
--- a/application/pages/instance/GameOptionsPage.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-#include <QString>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-namespace Ui
-{
-class GameOptionsPage;
-}
-
-class GameOptions;
-class MinecraftInstance;
-
-class GameOptionsPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit GameOptionsPage(MinecraftInstance *inst, QWidget *parent = 0);
- virtual ~GameOptionsPage();
-
- void openedImpl() override;
- void closedImpl() override;
-
- virtual QString displayName() const override
- {
- return tr("Game Options");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("settings");
- }
- virtual QString id() const override
- {
- return "gameoptions";
- }
- virtual QString helpPage() const override
- {
- return "Game-Options-management";
- }
-
-private: // data
- Ui::GameOptionsPage *ui = nullptr;
- std::shared_ptr<GameOptions> m_model;
-};
diff --git a/application/pages/instance/GameOptionsPage.ui b/application/pages/instance/GameOptionsPage.ui
deleted file mode 100644
index f0a5ce0e..00000000
--- a/application/pages/instance/GameOptionsPage.ui
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>GameOptionsPage</class>
- <widget class="QWidget" name="GameOptionsPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>706</width>
- <height>575</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="0" column="0">
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <attribute name="title">
- <string notr="true">Tab 1</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0" colspan="2">
- <widget class="QTreeView" name="optionsView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="acceptDrops">
- <bool>true</bool>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="selectionMode">
- <enum>QAbstractItemView::SingleSelection</enum>
- </property>
- <property name="selectionBehavior">
- <enum>QAbstractItemView::SelectRows</enum>
- </property>
- <property name="iconSize">
- <size>
- <width>64</width>
- <height>64</height>
- </size>
- </property>
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <attribute name="headerStretchLastSection">
- <bool>false</bool>
- </attribute>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>optionsView</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/InstanceSettingsPage.cpp b/application/pages/instance/InstanceSettingsPage.cpp
deleted file mode 100644
index 7bd424c0..00000000
--- a/application/pages/instance/InstanceSettingsPage.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-#include "InstanceSettingsPage.h"
-#include "ui_InstanceSettingsPage.h"
-
-#include <QFileDialog>
-#include <QDialog>
-#include <QMessageBox>
-
-#include "dialogs/VersionSelectDialog.h"
-#include "JavaCommon.h"
-#include "MultiMC.h"
-
-#include <java/JavaInstallList.h>
-#include <FileSystem.h>
-#include <sys.h>
-#include <widgets/CustomCommands.h>
-
-InstanceSettingsPage::InstanceSettingsPage(BaseInstance *inst, QWidget *parent)
- : QWidget(parent), ui(new Ui::InstanceSettingsPage), m_instance(inst)
-{
- m_settings = inst->settings();
- ui->setupUi(this);
- auto sysMB = Sys::getSystemRam() / Sys::mebibyte;
- ui->maxMemSpinBox->setMaximum(sysMB);
- connect(ui->openGlobalJavaSettingsButton, &QCommandLinkButton::clicked, this, &InstanceSettingsPage::globalSettingsButtonClicked);
- connect(MMC, &MultiMC::globalSettingsAboutToOpen, this, &InstanceSettingsPage::applySettings);
- connect(MMC, &MultiMC::globalSettingsClosed, this, &InstanceSettingsPage::loadSettings);
- loadSettings();
-}
-
-bool InstanceSettingsPage::shouldDisplay() const
-{
- return !m_instance->isRunning();
-}
-
-InstanceSettingsPage::~InstanceSettingsPage()
-{
- delete ui;
-}
-
-void InstanceSettingsPage::globalSettingsButtonClicked(bool)
-{
- switch(ui->settingsTabs->currentIndex()) {
- case 0:
- MMC->ShowGlobalSettings(this, "java-settings");
- return;
- case 1:
- MMC->ShowGlobalSettings(this, "minecraft-settings");
- return;
- case 2:
- MMC->ShowGlobalSettings(this, "custom-commands");
- return;
- }
-}
-
-bool InstanceSettingsPage::apply()
-{
- applySettings();
- return true;
-}
-
-void InstanceSettingsPage::applySettings()
-{
- SettingsObject::Lock lock(m_settings);
-
- // Console
- bool console = ui->consoleSettingsBox->isChecked();
- m_settings->set("OverrideConsole", console);
- if (console)
- {
- m_settings->set("ShowConsole", ui->showConsoleCheck->isChecked());
- m_settings->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
- m_settings->set("ShowConsoleOnError", ui->showConsoleErrorCheck->isChecked());
- }
- else
- {
- m_settings->reset("ShowConsole");
- m_settings->reset("AutoCloseConsole");
- m_settings->reset("ShowConsoleOnError");
- }
-
- // Window Size
- bool window = ui->windowSizeGroupBox->isChecked();
- m_settings->set("OverrideWindow", window);
- if (window)
- {
- m_settings->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
- m_settings->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
- m_settings->set("MinecraftWinHeight", ui->windowHeightSpinBox->value());
- }
- else
- {
- m_settings->reset("LaunchMaximized");
- m_settings->reset("MinecraftWinWidth");
- m_settings->reset("MinecraftWinHeight");
- }
-
- // Memory
- bool memory = ui->memoryGroupBox->isChecked();
- m_settings->set("OverrideMemory", memory);
- if (memory)
- {
- int min = ui->minMemSpinBox->value();
- int max = ui->maxMemSpinBox->value();
- if(min < max)
- {
- m_settings->set("MinMemAlloc", min);
- m_settings->set("MaxMemAlloc", max);
- }
- else
- {
- m_settings->set("MinMemAlloc", max);
- m_settings->set("MaxMemAlloc", min);
- }
- m_settings->set("PermGen", ui->permGenSpinBox->value());
- }
- else
- {
- m_settings->reset("MinMemAlloc");
- m_settings->reset("MaxMemAlloc");
- m_settings->reset("PermGen");
- }
-
- // Java Install Settings
- bool javaInstall = ui->javaSettingsGroupBox->isChecked();
- m_settings->set("OverrideJavaLocation", javaInstall);
- if (javaInstall)
- {
- m_settings->set("JavaPath", ui->javaPathTextBox->text());
- }
- else
- {
- m_settings->reset("JavaPath");
- }
-
- // Java arguments
- bool javaArgs = ui->javaArgumentsGroupBox->isChecked();
- m_settings->set("OverrideJavaArgs", javaArgs);
- if(javaArgs)
- {
- m_settings->set("JvmArgs", ui->jvmArgsTextBox->toPlainText().replace("\n", " "));
- JavaCommon::checkJVMArgs(m_settings->get("JvmArgs").toString(), this->parentWidget());
- }
- else
- {
- m_settings->reset("JvmArgs");
- }
-
- // old generic 'override both' is removed.
- m_settings->reset("OverrideJava");
-
- // Custom Commands
- bool custcmd = ui->customCommands->checked();
- m_settings->set("OverrideCommands", custcmd);
- if (custcmd)
- {
- m_settings->set("PreLaunchCommand", ui->customCommands->prelaunchCommand());
- m_settings->set("WrapperCommand", ui->customCommands->wrapperCommand());
- m_settings->set("PostExitCommand", ui->customCommands->postexitCommand());
- }
- else
- {
- m_settings->reset("PreLaunchCommand");
- m_settings->reset("WrapperCommand");
- m_settings->reset("PostExitCommand");
- }
-
- // Workarounds
- bool workarounds = ui->nativeWorkaroundsGroupBox->isChecked();
- m_settings->set("OverrideNativeWorkarounds", workarounds);
- if(workarounds)
- {
- m_settings->set("UseNativeOpenAL", ui->useNativeOpenALCheck->isChecked());
- m_settings->set("UseNativeGLFW", ui->useNativeGLFWCheck->isChecked());
- }
- else
- {
- m_settings->reset("UseNativeOpenAL");
- m_settings->reset("UseNativeGLFW");
- }
-
- // Game time
- bool gameTime = ui->gameTimeGroupBox->isChecked();
- m_settings->set("OverrideGameTime", gameTime);
- if (gameTime)
- {
- m_settings->set("ShowGameTime", ui->showGameTime->isChecked());
- m_settings->set("RecordGameTime", ui->recordGameTime->isChecked());
- }
- else
- {
- m_settings->reset("ShowGameTime");
- m_settings->reset("RecordGameTime");
- }
-
- // Join server on launch
- bool joinServerOnLaunch = ui->serverJoinGroupBox->isChecked();
- m_settings->set("JoinServerOnLaunch", joinServerOnLaunch);
- if (joinServerOnLaunch)
- {
- m_settings->set("JoinServerOnLaunchAddress", ui->serverJoinAddress->text());
- }
- else
- {
- m_settings->reset("JoinServerOnLaunchAddress");
- }
-}
-
-void InstanceSettingsPage::loadSettings()
-{
- // Console
- ui->consoleSettingsBox->setChecked(m_settings->get("OverrideConsole").toBool());
- ui->showConsoleCheck->setChecked(m_settings->get("ShowConsole").toBool());
- ui->autoCloseConsoleCheck->setChecked(m_settings->get("AutoCloseConsole").toBool());
- ui->showConsoleErrorCheck->setChecked(m_settings->get("ShowConsoleOnError").toBool());
-
- // Window Size
- ui->windowSizeGroupBox->setChecked(m_settings->get("OverrideWindow").toBool());
- ui->maximizedCheckBox->setChecked(m_settings->get("LaunchMaximized").toBool());
- ui->windowWidthSpinBox->setValue(m_settings->get("MinecraftWinWidth").toInt());
- ui->windowHeightSpinBox->setValue(m_settings->get("MinecraftWinHeight").toInt());
-
- // Memory
- ui->memoryGroupBox->setChecked(m_settings->get("OverrideMemory").toBool());
- int min = m_settings->get("MinMemAlloc").toInt();
- int max = m_settings->get("MaxMemAlloc").toInt();
- if(min < max)
- {
- ui->minMemSpinBox->setValue(min);
- ui->maxMemSpinBox->setValue(max);
- }
- else
- {
- ui->minMemSpinBox->setValue(max);
- ui->maxMemSpinBox->setValue(min);
- }
- ui->permGenSpinBox->setValue(m_settings->get("PermGen").toInt());
- bool permGenVisible = m_settings->get("PermGenVisible").toBool();
- ui->permGenSpinBox->setVisible(permGenVisible);
- ui->labelPermGen->setVisible(permGenVisible);
- ui->labelPermgenNote->setVisible(permGenVisible);
-
-
- // Java Settings
- bool overrideJava = m_settings->get("OverrideJava").toBool();
- bool overrideLocation = m_settings->get("OverrideJavaLocation").toBool() || overrideJava;
- bool overrideArgs = m_settings->get("OverrideJavaArgs").toBool() || overrideJava;
-
- ui->javaSettingsGroupBox->setChecked(overrideLocation);
- ui->javaPathTextBox->setText(m_settings->get("JavaPath").toString());
-
- ui->javaArgumentsGroupBox->setChecked(overrideArgs);
- ui->jvmArgsTextBox->setPlainText(m_settings->get("JvmArgs").toString());
-
- // Custom commands
- ui->customCommands->initialize(
- true,
- m_settings->get("OverrideCommands").toBool(),
- m_settings->get("PreLaunchCommand").toString(),
- m_settings->get("WrapperCommand").toString(),
- m_settings->get("PostExitCommand").toString()
- );
-
- // Workarounds
- ui->nativeWorkaroundsGroupBox->setChecked(m_settings->get("OverrideNativeWorkarounds").toBool());
- ui->useNativeGLFWCheck->setChecked(m_settings->get("UseNativeGLFW").toBool());
- ui->useNativeOpenALCheck->setChecked(m_settings->get("UseNativeOpenAL").toBool());
-
- // Miscellanous
- ui->gameTimeGroupBox->setChecked(m_settings->get("OverrideGameTime").toBool());
- ui->showGameTime->setChecked(m_settings->get("ShowGameTime").toBool());
- ui->recordGameTime->setChecked(m_settings->get("RecordGameTime").toBool());
-
- ui->serverJoinGroupBox->setChecked(m_settings->get("JoinServerOnLaunch").toBool());
- ui->serverJoinAddress->setText(m_settings->get("JoinServerOnLaunchAddress").toString());
-}
-
-void InstanceSettingsPage::on_javaDetectBtn_clicked()
-{
- JavaInstallPtr java;
-
- VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
- vselect.setResizeOn(2);
- vselect.exec();
-
- if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
- {
- java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
- ui->javaPathTextBox->setText(java->path);
- bool visible = java->id.requiresPermGen() && m_settings->get("OverrideMemory").toBool();
- ui->permGenSpinBox->setVisible(visible);
- ui->labelPermGen->setVisible(visible);
- ui->labelPermgenNote->setVisible(visible);
- m_settings->set("PermGenVisible", visible);
- }
-}
-
-void InstanceSettingsPage::on_javaBrowseBtn_clicked()
-{
- QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
-
- // do not allow current dir - it's dirty. Do not allow dirs that don't exist
- if(raw_path.isEmpty())
- {
- return;
- }
- QString cooked_path = FS::NormalizePath(raw_path);
-
- QFileInfo javaInfo(cooked_path);
- if(!javaInfo.exists() || !javaInfo.isExecutable())
- {
- return;
- }
- ui->javaPathTextBox->setText(cooked_path);
-
- // custom Java could be anything... enable perm gen option
- ui->permGenSpinBox->setVisible(true);
- ui->labelPermGen->setVisible(true);
- ui->labelPermgenNote->setVisible(true);
- m_settings->set("PermGenVisible", true);
-}
-
-void InstanceSettingsPage::on_javaTestBtn_clicked()
-{
- if(checker)
- {
- return;
- }
- checker.reset(new JavaCommon::TestCheck(
- this, ui->javaPathTextBox->text(), ui->jvmArgsTextBox->toPlainText().replace("\n", " "),
- ui->minMemSpinBox->value(), ui->maxMemSpinBox->value(), ui->permGenSpinBox->value()));
- connect(checker.get(), SIGNAL(finished()), SLOT(checkerFinished()));
- checker->run();
-}
-
-void InstanceSettingsPage::checkerFinished()
-{
- checker.reset();
-}
diff --git a/application/pages/instance/InstanceSettingsPage.h b/application/pages/instance/InstanceSettingsPage.h
deleted file mode 100644
index 068213a8..00000000
--- a/application/pages/instance/InstanceSettingsPage.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "java/JavaChecker.h"
-#include "BaseInstance.h"
-#include <QObjectPtr.h>
-#include "pages/BasePage.h"
-#include "JavaCommon.h"
-#include "MultiMC.h"
-
-class JavaChecker;
-namespace Ui
-{
-class InstanceSettingsPage;
-}
-
-class InstanceSettingsPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit InstanceSettingsPage(BaseInstance *inst, QWidget *parent = 0);
- virtual ~InstanceSettingsPage();
- virtual QString displayName() const override
- {
- return tr("Settings");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("instance-settings");
- }
- virtual QString id() const override
- {
- return "settings";
- }
- virtual bool apply() override;
- virtual QString helpPage() const override
- {
- return "Instance-settings";
- }
- virtual bool shouldDisplay() const override;
-
-private slots:
- void on_javaDetectBtn_clicked();
- void on_javaTestBtn_clicked();
- void on_javaBrowseBtn_clicked();
-
- void applySettings();
- void loadSettings();
-
- void checkerFinished();
-
- void globalSettingsButtonClicked(bool checked);
-
-private:
- Ui::InstanceSettingsPage *ui;
- BaseInstance *m_instance;
- SettingsObjectPtr m_settings;
- unique_qobject_ptr<JavaCommon::TestCheck> checker;
-};
diff --git a/application/pages/instance/InstanceSettingsPage.ui b/application/pages/instance/InstanceSettingsPage.ui
deleted file mode 100644
index e569ce56..00000000
--- a/application/pages/instance/InstanceSettingsPage.ui
+++ /dev/null
@@ -1,548 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>InstanceSettingsPage</class>
- <widget class="QWidget" name="InstanceSettingsPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>691</width>
- <height>581</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QCommandLinkButton" name="openGlobalJavaSettingsButton">
- <property name="text">
- <string>Open Global Settings</string>
- </property>
- <property name="description">
- <string>The settings here are overrides for global settings.</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTabWidget" name="settingsTabs">
- <property name="tabShape">
- <enum>QTabWidget::Rounded</enum>
- </property>
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="minecraftTab">
- <attribute name="title">
- <string notr="true">Java</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <item>
- <widget class="QGroupBox" name="javaSettingsGroupBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>Java insta&amp;llation</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0" colspan="3">
- <widget class="QLineEdit" name="javaPathTextBox"/>
- </item>
- <item row="1" column="0">
- <widget class="QPushButton" name="javaDetectBtn">
- <property name="text">
- <string>Auto-detect...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QPushButton" name="javaBrowseBtn">
- <property name="text">
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="javaTestBtn">
- <property name="text">
- <string>Test</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="memoryGroupBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>Memor&amp;y</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="labelMinMem">
- <property name="text">
- <string>Minimum memory allocation:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="maxMemSpinBox">
- <property name="toolTip">
- <string>The maximum amount of memory Minecraft is allowed to use.</string>
- </property>
- <property name="suffix">
- <string notr="true"> MiB</string>
- </property>
- <property name="minimum">
- <number>128</number>
- </property>
- <property name="maximum">
- <number>65536</number>
- </property>
- <property name="singleStep">
- <number>128</number>
- </property>
- <property name="value">
- <number>1024</number>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="minMemSpinBox">
- <property name="toolTip">
- <string>The amount of memory Minecraft is started with.</string>
- </property>
- <property name="suffix">
- <string notr="true"> MiB</string>
- </property>
- <property name="minimum">
- <number>128</number>
- </property>
- <property name="maximum">
- <number>65536</number>
- </property>
- <property name="singleStep">
- <number>128</number>
- </property>
- <property name="value">
- <number>256</number>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="permGenSpinBox">
- <property name="toolTip">
- <string>The amount of memory available to store loaded Java classes.</string>
- </property>
- <property name="suffix">
- <string notr="true"> MiB</string>
- </property>
- <property name="minimum">
- <number>64</number>
- </property>
- <property name="maximum">
- <number>999999999</number>
- </property>
- <property name="singleStep">
- <number>8</number>
- </property>
- <property name="value">
- <number>64</number>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="labelPermGen">
- <property name="text">
- <string notr="true">PermGen:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="labelMaxMem">
- <property name="text">
- <string>Maximum memory allocation:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0" colspan="2">
- <widget class="QLabel" name="labelPermgenNote">
- <property name="text">
- <string>Note: Permgen is set automatically by Java 8 and later</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="javaArgumentsGroupBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>Java argumen&amp;ts</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <layout class="QGridLayout" name="gridLayout_5">
- <item row="1" column="1">
- <widget class="QPlainTextEdit" name="jvmArgsTextBox"/>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="javaTab">
- <attribute name="title">
- <string>Game windows</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_3">
- <item>
- <widget class="QGroupBox" name="windowSizeGroupBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>Game Window</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <widget class="QCheckBox" name="maximizedCheckBox">
- <property name="text">
- <string>Start Minecraft maximized?</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayoutWindowSize">
- <item row="1" column="0">
- <widget class="QLabel" name="labelWindowHeight">
- <property name="text">
- <string>Window height:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="labelWindowWidth">
- <property name="text">
- <string>Window width:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QSpinBox" name="windowWidthSpinBox">
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>65536</number>
- </property>
- <property name="singleStep">
- <number>1</number>
- </property>
- <property name="value">
- <number>854</number>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QSpinBox" name="windowHeightSpinBox">
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>65536</number>
- </property>
- <property name="value">
- <number>480</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="consoleSettingsBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>Conso&amp;le Settings</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QCheckBox" name="showConsoleCheck">
- <property name="text">
- <string>Show console while the game is running?</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="autoCloseConsoleCheck">
- <property name="text">
- <string>Automatically close console when the game quits?</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="showConsoleErrorCheck">
- <property name="text">
- <string>Show console when the game crashes?</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacerMinecraft_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>88</width>
- <height>125</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>Custom commands</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_6">
- <item>
- <widget class="CustomCommands" name="customCommands" native="true"/>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="workaroundsPage">
- <attribute name="title">
- <string>Workarounds</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_8">
- <item>
- <widget class="QGroupBox" name="nativeWorkaroundsGroupBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>Native libraries</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_7">
- <item>
- <widget class="QCheckBox" name="useNativeGLFWCheck">
- <property name="text">
- <string>Use system installation of GLFW</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="useNativeOpenALCheck">
- <property name="text">
- <string>Use system installation of OpenAL</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="miscellanousPage">
- <attribute name="title">
- <string>Miscellanous</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_9">
- <item>
- <widget class="QGroupBox" name="gameTimeGroupBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="title">
- <string>Override global game time settings</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_10">
- <item>
- <widget class="QCheckBox" name="showGameTime">
- <property name="text">
- <string>Show time spent playing this instance</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="recordGameTime">
- <property name="text">
- <string>Record time spent playing this instance</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="serverJoinGroupBox">
- <property name="title">
- <string>Set a server to join on launch</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>false</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_11">
- <item>
- <layout class="QGridLayout" name="serverJoinLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="serverJoinAddressLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Server address:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="serverJoinAddress"/>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacerMiscellanous">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>CustomCommands</class>
- <extends>QWidget</extends>
- <header>widgets/CustomCommands.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>openGlobalJavaSettingsButton</tabstop>
- <tabstop>settingsTabs</tabstop>
- <tabstop>javaSettingsGroupBox</tabstop>
- <tabstop>javaPathTextBox</tabstop>
- <tabstop>javaDetectBtn</tabstop>
- <tabstop>javaBrowseBtn</tabstop>
- <tabstop>javaTestBtn</tabstop>
- <tabstop>memoryGroupBox</tabstop>
- <tabstop>minMemSpinBox</tabstop>
- <tabstop>maxMemSpinBox</tabstop>
- <tabstop>permGenSpinBox</tabstop>
- <tabstop>javaArgumentsGroupBox</tabstop>
- <tabstop>jvmArgsTextBox</tabstop>
- <tabstop>windowSizeGroupBox</tabstop>
- <tabstop>maximizedCheckBox</tabstop>
- <tabstop>windowWidthSpinBox</tabstop>
- <tabstop>windowHeightSpinBox</tabstop>
- <tabstop>consoleSettingsBox</tabstop>
- <tabstop>showConsoleCheck</tabstop>
- <tabstop>autoCloseConsoleCheck</tabstop>
- <tabstop>showConsoleErrorCheck</tabstop>
- <tabstop>nativeWorkaroundsGroupBox</tabstop>
- <tabstop>useNativeGLFWCheck</tabstop>
- <tabstop>useNativeOpenALCheck</tabstop>
- <tabstop>showGameTime</tabstop>
- <tabstop>recordGameTime</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/LegacyUpgradePage.cpp b/application/pages/instance/LegacyUpgradePage.cpp
deleted file mode 100644
index af800b03..00000000
--- a/application/pages/instance/LegacyUpgradePage.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include "LegacyUpgradePage.h"
-#include "ui_LegacyUpgradePage.h"
-
-#include "InstanceList.h"
-#include "minecraft/legacy/LegacyInstance.h"
-#include "minecraft/legacy/LegacyUpgradeTask.h"
-#include "MultiMC.h"
-#include "dialogs/CustomMessageBox.h"
-#include "dialogs/ProgressDialog.h"
-
-LegacyUpgradePage::LegacyUpgradePage(InstancePtr inst, QWidget *parent)
- : QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
-{
- ui->setupUi(this);
-}
-
-LegacyUpgradePage::~LegacyUpgradePage()
-{
- delete ui;
-}
-
-void LegacyUpgradePage::runModalTask(Task *task)
-{
- connect(task, &Task::failed, [this](QString reason)
- {
- CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Warning)->show();
- });
- ProgressDialog loadDialog(this);
- loadDialog.setSkipButton(true, tr("Abort"));
- if(loadDialog.execWithTask(task) == QDialog::Accepted)
- {
- m_container->requestClose();
- }
-}
-
-void LegacyUpgradePage::on_upgradeButton_clicked()
-{
- QString newName = tr("%1 (Migrated)").arg(m_inst->name());
- auto upgradeTask = new LegacyUpgradeTask(m_inst);
- upgradeTask->setName(newName);
- upgradeTask->setGroup(MMC->instances()->getInstanceGroup(m_inst->id()));
- upgradeTask->setIcon(m_inst->iconKey());
- unique_qobject_ptr<Task> task(MMC->instances()->wrapInstanceTask(upgradeTask));
- runModalTask(task.get());
-}
-
-bool LegacyUpgradePage::shouldDisplay() const
-{
- return !m_inst->isRunning();
-}
diff --git a/application/pages/instance/LegacyUpgradePage.h b/application/pages/instance/LegacyUpgradePage.h
deleted file mode 100644
index df34e33a..00000000
--- a/application/pages/instance/LegacyUpgradePage.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "minecraft/legacy/LegacyInstance.h"
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "tasks/Task.h"
-
-namespace Ui
-{
-class LegacyUpgradePage;
-}
-
-class LegacyUpgradePage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit LegacyUpgradePage(InstancePtr inst, QWidget *parent = 0);
- virtual ~LegacyUpgradePage();
- virtual QString displayName() const override
- {
- return tr("Upgrade");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("checkupdate");
- }
- virtual QString id() const override
- {
- return "upgrade";
- }
- virtual QString helpPage() const override
- {
- return "Legacy-upgrade";
- }
- virtual bool shouldDisplay() const override;
-
-private slots:
- void on_upgradeButton_clicked();
-
-private:
- void runModalTask(Task *task);
-
-private:
- Ui::LegacyUpgradePage *ui;
- InstancePtr m_inst;
-};
diff --git a/application/pages/instance/LegacyUpgradePage.ui b/application/pages/instance/LegacyUpgradePage.ui
deleted file mode 100644
index a94ee039..00000000
--- a/application/pages/instance/LegacyUpgradePage.ui
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>LegacyUpgradePage</class>
- <widget class="QWidget" name="LegacyUpgradePage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>546</width>
- <height>405</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTextBrowser" name="textBrowser">
- <property name="html">
- <string>&lt;html&gt;&lt;body&gt;&lt;h1&gt;Upgrade is required&lt;/h1&gt;&lt;p&gt;MultiMC now supports old Minecraft versions and all the required features in the new (OneSix) instance format. As a consequence, the old (Legacy) format has been entirely disabled and old instances need to be upgraded.&lt;/p&gt;&lt;p&gt;The upgrade will create a new instance with the same contents as the current one, in the new format. The original instance will remain untouched, in case anything goes wrong in the process.&lt;/p&gt;&lt;p&gt;Please report any issues on our &lt;a href=&quot;https://github.com/MultiMC/MultiMC5/issues&quot;&gt;github issues page&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;There is also a &lt;a href=&quot;https://discord.gg/GtPmv93&quot;&gt;discord channel for testing here&lt;/a&gt;.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCommandLinkButton" name="upgradeButton">
- <property name="text">
- <string>Upgrade the instance</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/LogPage.cpp b/application/pages/instance/LogPage.cpp
deleted file mode 100644
index 3d2085c6..00000000
--- a/application/pages/instance/LogPage.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-#include "LogPage.h"
-#include "ui_LogPage.h"
-
-#include "MultiMC.h"
-
-#include <QIcon>
-#include <QScrollBar>
-#include <QShortcut>
-
-#include "launch/LaunchTask.h"
-#include <settings/Setting.h>
-#include "GuiUtil.h"
-#include <ColorCache.h>
-
-class LogFormatProxyModel : public QIdentityProxyModel
-{
-public:
- LogFormatProxyModel(QObject* parent = nullptr) : QIdentityProxyModel(parent)
- {
- }
- QVariant data(const QModelIndex &index, int role) const override
- {
- switch(role)
- {
- case Qt::FontRole:
- return m_font;
- case Qt::TextColorRole:
- {
- MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
- return m_colors->getFront(level);
- }
- case Qt::BackgroundRole:
- {
- MessageLevel::Enum level = (MessageLevel::Enum) QIdentityProxyModel::data(index, LogModel::LevelRole).toInt();
- return m_colors->getBack(level);
- }
- default:
- return QIdentityProxyModel::data(index, role);
- }
- }
-
- void setFont(QFont font)
- {
- m_font = font;
- }
-
- void setColors(LogColorCache* colors)
- {
- m_colors.reset(colors);
- }
-
- QModelIndex find(const QModelIndex &start, const QString &value, bool reverse) const
- {
- QModelIndex parentIndex = parent(start);
- auto compare = [&](int r) -> QModelIndex
- {
- QModelIndex idx = index(r, start.column(), parentIndex);
- if (!idx.isValid() || idx == start)
- {
- return QModelIndex();
- }
- QVariant v = data(idx, Qt::DisplayRole);
- QString t = v.toString();
- if (t.contains(value, Qt::CaseInsensitive))
- return idx;
- return QModelIndex();
- };
- if(reverse)
- {
- int from = start.row();
- int to = 0;
-
- for (int i = 0; i < 2; ++i)
- {
- for (int r = from; (r >= to); --r)
- {
- auto idx = compare(r);
- if(idx.isValid())
- return idx;
- }
- // prepare for the next iteration
- from = rowCount() - 1;
- to = start.row();
- }
- }
- else
- {
- int from = start.row();
- int to = rowCount(parentIndex);
-
- for (int i = 0; i < 2; ++i)
- {
- for (int r = from; (r < to); ++r)
- {
- auto idx = compare(r);
- if(idx.isValid())
- return idx;
- }
- // prepare for the next iteration
- from = 0;
- to = start.row();
- }
- }
- return QModelIndex();
- }
-private:
- QFont m_font;
- std::unique_ptr<LogColorCache> m_colors;
-};
-
-LogPage::LogPage(InstancePtr instance, QWidget *parent)
- : QWidget(parent), ui(new Ui::LogPage), m_instance(instance)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
-
- m_proxy = new LogFormatProxyModel(this);
- // set up text colors in the log proxy and adapt them to the current theme foreground and background
- {
- auto origForeground = ui->text->palette().color(ui->text->foregroundRole());
- auto origBackground = ui->text->palette().color(ui->text->backgroundRole());
- m_proxy->setColors(new LogColorCache(origForeground, origBackground));
- }
-
- // set up fonts in the log proxy
- {
- QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
- bool conversionOk = false;
- int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
- if(!conversionOk)
- {
- fontSize = 11;
- }
- m_proxy->setFont(QFont(fontFamily, fontSize));
- }
-
- ui->text->setModel(m_proxy);
-
- // set up instance and launch process recognition
- {
- auto launchTask = m_instance->getLaunchTask();
- if(launchTask)
- {
- setInstanceLaunchTaskChanged(launchTask, true);
- }
- connect(m_instance.get(), &BaseInstance::launchTaskChanged, this, &LogPage::onInstanceLaunchTaskChanged);
- }
-
- auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
- connect(findShortcut, SIGNAL(activated()), SLOT(findActivated()));
- auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
- connect(findNextShortcut, SIGNAL(activated()), SLOT(findNextActivated()));
- connect(ui->searchBar, SIGNAL(returnPressed()), SLOT(on_findButton_clicked()));
- auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
- connect(findPreviousShortcut, SIGNAL(activated()), SLOT(findPreviousActivated()));
-}
-
-LogPage::~LogPage()
-{
- delete ui;
-}
-
-void LogPage::modelStateToUI()
-{
- if(m_model->wrapLines())
- {
- ui->text->setWordWrap(true);
- ui->wrapCheckbox->setCheckState(Qt::Checked);
- }
- else
- {
- ui->text->setWordWrap(false);
- ui->wrapCheckbox->setCheckState(Qt::Unchecked);
- }
- if(m_model->suspended())
- {
- ui->trackLogCheckbox->setCheckState(Qt::Unchecked);
- }
- else
- {
- ui->trackLogCheckbox->setCheckState(Qt::Checked);
- }
-}
-
-void LogPage::UIToModelState()
-{
- if(!m_model)
- {
- return;
- }
- m_model->setLineWrap(ui->wrapCheckbox->checkState() == Qt::Checked);
- m_model->suspend(ui->trackLogCheckbox->checkState() != Qt::Checked);
-}
-
-void LogPage::setInstanceLaunchTaskChanged(shared_qobject_ptr<LaunchTask> proc, bool initial)
-{
- m_process = proc;
- if(m_process)
- {
- m_model = proc->getLogModel();
- m_proxy->setSourceModel(m_model.get());
- if(initial)
- {
- modelStateToUI();
- }
- else
- {
- UIToModelState();
- }
- }
- else
- {
- m_proxy->setSourceModel(nullptr);
- m_model.reset();
- }
-}
-
-void LogPage::onInstanceLaunchTaskChanged(shared_qobject_ptr<LaunchTask> proc)
-{
- setInstanceLaunchTaskChanged(proc, false);
-}
-
-bool LogPage::apply()
-{
- return true;
-}
-
-bool LogPage::shouldDisplay() const
-{
- return m_instance->isRunning() || m_proxy->rowCount() > 0;
-}
-
-void LogPage::on_btnPaste_clicked()
-{
- if(!m_model)
- return;
-
- //FIXME: turn this into a proper task and move the upload logic out of GuiUtil!
- m_model->append(MessageLevel::MultiMC, QString("MultiMC: Log upload triggered at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
- auto url = GuiUtil::uploadPaste(m_model->toPlainText(), this);
- if(!url.isEmpty())
- {
- m_model->append(MessageLevel::MultiMC, QString("MultiMC: Log uploaded to: %1").arg(url));
- }
- else
- {
- m_model->append(MessageLevel::Error, "MultiMC: Log upload failed!");
- }
-}
-
-void LogPage::on_btnCopy_clicked()
-{
- if(!m_model)
- return;
- m_model->append(MessageLevel::MultiMC, QString("Clipboard copy at: %1").arg(QDateTime::currentDateTime().toString(Qt::RFC2822Date)));
- GuiUtil::setClipboardText(m_model->toPlainText());
-}
-
-void LogPage::on_btnClear_clicked()
-{
- if(!m_model)
- return;
- m_model->clear();
- m_container->refreshContainer();
-}
-
-void LogPage::on_btnBottom_clicked()
-{
- ui->text->scrollToBottom();
-}
-
-void LogPage::on_trackLogCheckbox_clicked(bool checked)
-{
- if(!m_model)
- return;
- m_model->suspend(!checked);
-}
-
-void LogPage::on_wrapCheckbox_clicked(bool checked)
-{
- ui->text->setWordWrap(checked);
- if(!m_model)
- return;
- m_model->setLineWrap(checked);
-}
-
-void LogPage::on_findButton_clicked()
-{
- auto modifiers = QApplication::keyboardModifiers();
- bool reverse = modifiers & Qt::ShiftModifier;
- ui->text->findNext(ui->searchBar->text(), reverse);
-}
-
-void LogPage::findNextActivated()
-{
- ui->text->findNext(ui->searchBar->text(), false);
-}
-
-void LogPage::findPreviousActivated()
-{
- ui->text->findNext(ui->searchBar->text(), true);
-}
-
-void LogPage::findActivated()
-{
- // focus the search bar if it doesn't have focus
- if (!ui->searchBar->hasFocus())
- {
- ui->searchBar->setFocus();
- ui->searchBar->selectAll();
- }
-}
diff --git a/application/pages/instance/LogPage.h b/application/pages/instance/LogPage.h
deleted file mode 100644
index b0b0e04b..00000000
--- a/application/pages/instance/LogPage.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "BaseInstance.h"
-#include "launch/LaunchTask.h"
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-namespace Ui
-{
-class LogPage;
-}
-class QTextCharFormat;
-class LogFormatProxyModel;
-
-class LogPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit LogPage(InstancePtr instance, QWidget *parent = 0);
- virtual ~LogPage();
- virtual QString displayName() const override
- {
- return tr("Minecraft Log");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("log");
- }
- virtual QString id() const override
- {
- return "console";
- }
- virtual bool apply() override;
- virtual QString helpPage() const override
- {
- return "Minecraft-Logs";
- }
- virtual bool shouldDisplay() const override;
-
-private slots:
- void on_btnPaste_clicked();
- void on_btnCopy_clicked();
- void on_btnClear_clicked();
- void on_btnBottom_clicked();
-
- void on_trackLogCheckbox_clicked(bool checked);
- void on_wrapCheckbox_clicked(bool checked);
-
- void on_findButton_clicked();
- void findActivated();
- void findNextActivated();
- void findPreviousActivated();
-
- void onInstanceLaunchTaskChanged(shared_qobject_ptr<LaunchTask> proc);
-
-private:
- void modelStateToUI();
- void UIToModelState();
- void setInstanceLaunchTaskChanged(shared_qobject_ptr<LaunchTask> proc, bool initial);
-
-private:
- Ui::LogPage *ui;
- InstancePtr m_instance;
- shared_qobject_ptr<LaunchTask> m_process;
-
- LogFormatProxyModel * m_proxy;
- shared_qobject_ptr <LogModel> m_model;
-};
diff --git a/application/pages/instance/LogPage.ui b/application/pages/instance/LogPage.ui
deleted file mode 100644
index 4843d7c3..00000000
--- a/application/pages/instance/LogPage.ui
+++ /dev/null
@@ -1,182 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>LogPage</class>
- <widget class="QWidget" name="LogPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>825</width>
- <height>782</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string notr="true">Tab 1</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="0" colspan="5">
- <widget class="LogView" name="text">
- <property name="undoRedoEnabled">
- <bool>false</bool>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="plainText">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- <property name="centerOnScroll">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="5">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QCheckBox" name="trackLogCheckbox">
- <property name="text">
- <string>Keep updating</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="wrapCheckbox">
- <property name="text">
- <string>Wrap lines</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="btnCopy">
- <property name="toolTip">
- <string>Copy the whole log into the clipboard</string>
- </property>
- <property name="text">
- <string>&amp;Copy</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnPaste">
- <property name="toolTip">
- <string>Upload the log to paste.ee - it will stay online for a month</string>
- </property>
- <property name="text">
- <string>Upload</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnClear">
- <property name="toolTip">
- <string>Clear the log</string>
- </property>
- <property name="text">
- <string>Clear</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Search:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QPushButton" name="findButton">
- <property name="text">
- <string>Find</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="searchBar"/>
- </item>
- <item row="2" column="4">
- <widget class="QPushButton" name="btnBottom">
- <property name="toolTip">
- <string>Scroll all the way to bottom</string>
- </property>
- <property name="text">
- <string>Bottom</string>
- </property>
- </widget>
- </item>
- <item row="2" column="3">
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>LogView</class>
- <extends>QPlainTextEdit</extends>
- <header>widgets/LogView.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>trackLogCheckbox</tabstop>
- <tabstop>wrapCheckbox</tabstop>
- <tabstop>btnCopy</tabstop>
- <tabstop>btnPaste</tabstop>
- <tabstop>btnClear</tabstop>
- <tabstop>text</tabstop>
- <tabstop>searchBar</tabstop>
- <tabstop>findButton</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/ModFolderPage.cpp b/application/pages/instance/ModFolderPage.cpp
deleted file mode 100644
index 98f20e77..00000000
--- a/application/pages/instance/ModFolderPage.cpp
+++ /dev/null
@@ -1,363 +0,0 @@
-/* Copyright 2013-2021 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 "ModFolderPage.h"
-#include "ui_ModFolderPage.h"
-
-#include <QMessageBox>
-#include <QEvent>
-#include <QKeyEvent>
-#include <QAbstractItemModel>
-#include <QMenu>
-
-#include "MultiMC.h"
-#include "dialogs/CustomMessageBox.h"
-#include <GuiUtil.h>
-#include "minecraft/mod/ModFolderModel.h"
-#include "minecraft/mod/Mod.h"
-#include "minecraft/VersionFilterData.h"
-#include "minecraft/PackProfile.h"
-#include <DesktopServices.h>
-
-#include <QSortFilterProxyModel>
-#include "Version.h"
-
-namespace {
- // FIXME: wasteful
- void RemoveThePrefix(QString & string) {
- QRegularExpression regex(QStringLiteral("^(([Tt][Hh][eE])|([Tt][eE][Hh])) +"));
- string.remove(regex);
- string = string.trimmed();
- }
-}
-
-class ModSortProxy : public QSortFilterProxyModel
-{
-public:
- explicit ModSortProxy(QObject *parent = 0) : QSortFilterProxyModel(parent)
- {
- }
-
-protected:
- bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override {
- ModFolderModel *model = qobject_cast<ModFolderModel *>(sourceModel());
- if(!model) {
- return false;
- }
- const auto &mod = model->at(source_row);
- if(mod.name().contains(filterRegExp())) {
- return true;
- }
- if(mod.description().contains(filterRegExp())) {
- return true;
- }
- for(auto & author: mod.authors()) {
- if (author.contains(filterRegExp())) {
- return true;
- }
- }
- return false;
- }
-
- bool lessThan(const QModelIndex & source_left, const QModelIndex & source_right) const override
- {
- ModFolderModel *model = qobject_cast<ModFolderModel *>(sourceModel());
- if(
- !model ||
- !source_left.isValid() ||
- !source_right.isValid() ||
- source_left.column() != source_right.column()
- ) {
- return QSortFilterProxyModel::lessThan(source_left, source_right);
- }
-
- // we are now guaranteed to have two valid indexes in the same column... we love the provided invariants unconditionally and proceed.
-
- auto column = (ModFolderModel::Columns) source_left.column();
- bool invert = false;
- switch(column) {
- // GH-2550 - sort by enabled/disabled
- case ModFolderModel::ActiveColumn: {
- auto dataL = source_left.data(Qt::CheckStateRole).toBool();
- auto dataR = source_right.data(Qt::CheckStateRole).toBool();
- if(dataL != dataR) {
- return dataL > dataR;
- }
- // fallthrough
- invert = sortOrder() == Qt::DescendingOrder;
- }
- // GH-2722 - sort mod names in a way that discards "The" prefixes
- case ModFolderModel::NameColumn: {
- auto dataL = model->data(model->index(source_left.row(), ModFolderModel::NameColumn)).toString();
- RemoveThePrefix(dataL);
- auto dataR = model->data(model->index(source_right.row(), ModFolderModel::NameColumn)).toString();
- RemoveThePrefix(dataR);
-
- auto less = dataL.compare(dataR, sortCaseSensitivity());
- if(less != 0) {
- return invert ? (less > 0) : (less < 0);
- }
- // fallthrough
- invert = sortOrder() == Qt::DescendingOrder;
- }
- // GH-2762 - sort versions by parsing them as versions
- case ModFolderModel::VersionColumn: {
- auto dataL = Version(model->data(model->index(source_left.row(), ModFolderModel::VersionColumn)).toString());
- auto dataR = Version(model->data(model->index(source_right.row(), ModFolderModel::VersionColumn)).toString());
- return invert ? (dataL > dataR) : (dataL < dataR);
- }
- default: {
- return QSortFilterProxyModel::lessThan(source_left, source_right);
- }
- }
- }
-};
-
-ModFolderPage::ModFolderPage(
- BaseInstance *inst,
- std::shared_ptr<ModFolderModel> mods,
- QString id,
- QString iconName,
- QString displayName,
- QString helpPage,
- QWidget *parent
-) :
- QMainWindow(parent),
- ui(new Ui::ModFolderPage)
-{
- ui->setupUi(this);
- ui->actionsToolbar->insertSpacer(ui->actionView_configs);
-
- m_inst = inst;
- on_RunningState_changed(m_inst && m_inst->isRunning());
- m_mods = mods;
- m_id = id;
- m_displayName = displayName;
- m_iconName = iconName;
- m_helpName = helpPage;
- m_fileSelectionFilter = "%1 (*.zip *.jar)";
- m_filterModel = new ModSortProxy(this);
- m_filterModel->setDynamicSortFilter(true);
- m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
- m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
- m_filterModel->setSourceModel(m_mods.get());
- m_filterModel->setFilterKeyColumn(-1);
- ui->modTreeView->setModel(m_filterModel);
- ui->modTreeView->installEventFilter(this);
- ui->modTreeView->sortByColumn(1, Qt::AscendingOrder);
- ui->modTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(ui->modTreeView, &ModListView::customContextMenuRequested, this, &ModFolderPage::ShowContextMenu);
- connect(ui->modTreeView, &ModListView::activated, this, &ModFolderPage::modItemActivated);
-
- auto smodel = ui->modTreeView->selectionModel();
- connect(smodel, &QItemSelectionModel::currentChanged, this, &ModFolderPage::modCurrent);
- connect(ui->filterEdit, &QLineEdit::textChanged, this, &ModFolderPage::on_filterTextChanged);
- connect(m_inst, &BaseInstance::runningStatusChanged, this, &ModFolderPage::on_RunningState_changed);
-}
-
-void ModFolderPage::modItemActivated(const QModelIndex&)
-{
- if(!m_controlsEnabled) {
- return;
- }
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->setModStatus(selection.indexes(), ModFolderModel::Toggle);
-}
-
-QMenu * ModFolderPage::createPopupMenu()
-{
- QMenu* filteredMenu = QMainWindow::createPopupMenu();
- filteredMenu->removeAction(ui->actionsToolbar->toggleViewAction() );
- return filteredMenu;
-}
-
-void ModFolderPage::ShowContextMenu(const QPoint& pos)
-{
- auto menu = ui->actionsToolbar->createContextMenu(this, tr("Context menu"));
- menu->exec(ui->modTreeView->mapToGlobal(pos));
- delete menu;
-}
-
-void ModFolderPage::openedImpl()
-{
- m_mods->startWatching();
-}
-
-void ModFolderPage::closedImpl()
-{
- m_mods->stopWatching();
-}
-
-void ModFolderPage::on_filterTextChanged(const QString& newContents)
-{
- m_viewFilter = newContents;
- m_filterModel->setFilterFixedString(m_viewFilter);
-}
-
-
-CoreModFolderPage::CoreModFolderPage(BaseInstance *inst, std::shared_ptr<ModFolderModel> mods,
- QString id, QString iconName, QString displayName,
- QString helpPage, QWidget *parent)
- : ModFolderPage(inst, mods, id, iconName, displayName, helpPage, parent)
-{
-}
-
-ModFolderPage::~ModFolderPage()
-{
- m_mods->stopWatching();
- delete ui;
-}
-
-void ModFolderPage::on_RunningState_changed(bool running)
-{
- if(m_controlsEnabled == !running) {
- return;
- }
- m_controlsEnabled = !running;
- ui->actionAdd->setEnabled(m_controlsEnabled);
- ui->actionDisable->setEnabled(m_controlsEnabled);
- ui->actionEnable->setEnabled(m_controlsEnabled);
- ui->actionRemove->setEnabled(m_controlsEnabled);
-}
-
-bool ModFolderPage::shouldDisplay() const
-{
- return true;
-}
-
-bool CoreModFolderPage::shouldDisplay() const
-{
- if (ModFolderPage::shouldDisplay())
- {
- auto inst = dynamic_cast<MinecraftInstance *>(m_inst);
- if (!inst)
- return true;
- auto version = inst->getPackProfile();
- if (!version)
- return true;
- if(!version->getComponent("net.minecraftforge"))
- {
- return false;
- }
- if(!version->getComponent("net.minecraft"))
- {
- return false;
- }
- if(version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate)
- {
- return true;
- }
- }
- return false;
-}
-
-bool ModFolderPage::modListFilter(QKeyEvent *keyEvent)
-{
- switch (keyEvent->key())
- {
- case Qt::Key_Delete:
- on_actionRemove_triggered();
- return true;
- case Qt::Key_Plus:
- on_actionAdd_triggered();
- return true;
- default:
- break;
- }
- return QWidget::eventFilter(ui->modTreeView, keyEvent);
-}
-
-bool ModFolderPage::eventFilter(QObject *obj, QEvent *ev)
-{
- if (ev->type() != QEvent::KeyPress)
- {
- return QWidget::eventFilter(obj, ev);
- }
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
- if (obj == ui->modTreeView)
- return modListFilter(keyEvent);
- return QWidget::eventFilter(obj, ev);
-}
-
-void ModFolderPage::on_actionAdd_triggered()
-{
- if(!m_controlsEnabled) {
- return;
- }
- auto list = GuiUtil::BrowseForFiles(
- m_helpName,
- tr("Select %1",
- "Select whatever type of files the page contains. Example: 'Loader Mods'")
- .arg(m_displayName),
- m_fileSelectionFilter.arg(m_displayName), MMC->settings()->get("CentralModsDir").toString(),
- this->parentWidget());
- if (!list.empty())
- {
- for (auto filename : list)
- {
- m_mods->installMod(filename);
- }
- }
-}
-
-void ModFolderPage::on_actionEnable_triggered()
-{
- if(!m_controlsEnabled) {
- return;
- }
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->setModStatus(selection.indexes(), ModFolderModel::Enable);
-}
-
-void ModFolderPage::on_actionDisable_triggered()
-{
- if(!m_controlsEnabled) {
- return;
- }
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->setModStatus(selection.indexes(), ModFolderModel::Disable);
-}
-
-void ModFolderPage::on_actionRemove_triggered()
-{
- if(!m_controlsEnabled) {
- return;
- }
- auto selection = m_filterModel->mapSelectionToSource(ui->modTreeView->selectionModel()->selection());
- m_mods->deleteMods(selection.indexes());
-}
-
-void ModFolderPage::on_actionView_configs_triggered()
-{
- DesktopServices::openDirectory(m_inst->instanceConfigFolder(), true);
-}
-
-void ModFolderPage::on_actionView_Folder_triggered()
-{
- DesktopServices::openDirectory(m_mods->dir().absolutePath(), true);
-}
-
-void ModFolderPage::modCurrent(const QModelIndex &current, const QModelIndex &previous)
-{
- if (!current.isValid())
- {
- ui->frame->clear();
- return;
- }
- auto sourceCurrent = m_filterModel->mapToSource(current);
- int row = sourceCurrent.row();
- Mod &m = m_mods->operator[](row);
- ui->frame->updateWithMod(m);
-}
diff --git a/application/pages/instance/ModFolderPage.h b/application/pages/instance/ModFolderPage.h
deleted file mode 100644
index f653a8c0..00000000
--- a/application/pages/instance/ModFolderPage.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright 2013-2021 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 <QMainWindow>
-
-#include "minecraft/MinecraftInstance.h"
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-class ModFolderModel;
-namespace Ui
-{
-class ModFolderPage;
-}
-
-class ModFolderPage : public QMainWindow, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit ModFolderPage(
- BaseInstance *inst,
- std::shared_ptr<ModFolderModel> mods,
- QString id,
- QString iconName,
- QString displayName,
- QString helpPage = "",
- QWidget *parent = 0
- );
- virtual ~ModFolderPage();
-
- void setFilter(const QString & filter)
- {
- m_fileSelectionFilter = filter;
- }
-
- virtual QString displayName() const override
- {
- return m_displayName;
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon(m_iconName);
- }
- virtual QString id() const override
- {
- return m_id;
- }
- virtual QString helpPage() const override
- {
- return m_helpName;
- }
- virtual bool shouldDisplay() const override;
-
- virtual void openedImpl() override;
- virtual void closedImpl() override;
-protected:
- bool eventFilter(QObject *obj, QEvent *ev) override;
- bool modListFilter(QKeyEvent *ev);
- QMenu * createPopupMenu() override;
-
-protected:
- BaseInstance *m_inst = nullptr;
-
-protected:
- Ui::ModFolderPage *ui = nullptr;
- std::shared_ptr<ModFolderModel> m_mods;
- QSortFilterProxyModel *m_filterModel = nullptr;
- QString m_iconName;
- QString m_id;
- QString m_displayName;
- QString m_helpName;
- QString m_fileSelectionFilter;
- QString m_viewFilter;
- bool m_controlsEnabled = true;
-
-public
-slots:
- void modCurrent(const QModelIndex &current, const QModelIndex &previous);
-
-private
-slots:
- void modItemActivated(const QModelIndex &index);
- void on_filterTextChanged(const QString & newContents);
- void on_RunningState_changed(bool running);
- void on_actionAdd_triggered();
- void on_actionRemove_triggered();
- void on_actionEnable_triggered();
- void on_actionDisable_triggered();
- void on_actionView_Folder_triggered();
- void on_actionView_configs_triggered();
- void ShowContextMenu(const QPoint &pos);
-};
-
-class CoreModFolderPage : public ModFolderPage
-{
-public:
- explicit CoreModFolderPage(BaseInstance *inst, std::shared_ptr<ModFolderModel> mods, QString id,
- QString iconName, QString displayName, QString helpPage = "",
- QWidget *parent = 0);
- virtual ~CoreModFolderPage()
- {
- }
- virtual bool shouldDisplay() const;
-};
diff --git a/application/pages/instance/ModFolderPage.ui b/application/pages/instance/ModFolderPage.ui
deleted file mode 100644
index 954a0167..00000000
--- a/application/pages/instance/ModFolderPage.ui
+++ /dev/null
@@ -1,164 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ModFolderPage</class>
- <widget class="QMainWindow" name="ModFolderPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>1042</width>
- <height>501</height>
- </rect>
- </property>
- <widget class="QWidget" name="centralwidget">
- <layout class="QGridLayout" name="gridLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item row="4" column="1" colspan="3">
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="1">
- <widget class="QLineEdit" name="filterEdit">
- <property name="clearButtonEnabled">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="filterLabel">
- <property name="text">
- <string>Filter:</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="1" colspan="3">
- <widget class="MCModInfoFrame" name="frame">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="1" column="1" colspan="3">
- <widget class="ModListView" name="modTreeView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="acceptDrops">
- <bool>true</bool>
- </property>
- <property name="dragDropMode">
- <enum>QAbstractItemView::DropOnly</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="WideBar" name="actionsToolbar">
- <property name="windowTitle">
- <string>Actions</string>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextOnly</enum>
- </property>
- <attribute name="toolBarArea">
- <enum>RightToolBarArea</enum>
- </attribute>
- <attribute name="toolBarBreak">
- <bool>false</bool>
- </attribute>
- <addaction name="actionAdd"/>
- <addaction name="separator"/>
- <addaction name="actionRemove"/>
- <addaction name="actionEnable"/>
- <addaction name="actionDisable"/>
- <addaction name="actionView_configs"/>
- <addaction name="actionView_Folder"/>
- </widget>
- <action name="actionAdd">
- <property name="text">
- <string>&amp;Add</string>
- </property>
- <property name="toolTip">
- <string>Add mods</string>
- </property>
- </action>
- <action name="actionRemove">
- <property name="text">
- <string>&amp;Remove</string>
- </property>
- <property name="toolTip">
- <string>Remove selected mods</string>
- </property>
- </action>
- <action name="actionEnable">
- <property name="text">
- <string>&amp;Enable</string>
- </property>
- <property name="toolTip">
- <string>Enable selected mods</string>
- </property>
- </action>
- <action name="actionDisable">
- <property name="text">
- <string>&amp;Disable</string>
- </property>
- <property name="toolTip">
- <string>Disable selected mods</string>
- </property>
- </action>
- <action name="actionView_configs">
- <property name="text">
- <string>View &amp;Configs</string>
- </property>
- <property name="toolTip">
- <string>Open the 'config' folder in the system file manager.</string>
- </property>
- </action>
- <action name="actionView_Folder">
- <property name="text">
- <string>View &amp;Folder</string>
- </property>
- </action>
- </widget>
- <customwidgets>
- <customwidget>
- <class>ModListView</class>
- <extends>QTreeView</extends>
- <header>widgets/ModListView.h</header>
- </customwidget>
- <customwidget>
- <class>MCModInfoFrame</class>
- <extends>QFrame</extends>
- <header>widgets/MCModInfoFrame.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>WideBar</class>
- <extends>QToolBar</extends>
- <header>widgets/WideBar.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>modTreeView</tabstop>
- <tabstop>filterEdit</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/NotesPage.cpp b/application/pages/instance/NotesPage.cpp
deleted file mode 100644
index fa966c91..00000000
--- a/application/pages/instance/NotesPage.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "NotesPage.h"
-#include "ui_NotesPage.h"
-#include <QTabBar>
-
-NotesPage::NotesPage(BaseInstance *inst, QWidget *parent)
- : QWidget(parent), ui(new Ui::NotesPage), m_inst(inst)
-{
- ui->setupUi(this);
- ui->noteEditor->setText(m_inst->notes());
-}
-
-NotesPage::~NotesPage()
-{
- delete ui;
-}
-
-bool NotesPage::apply()
-{
- m_inst->setNotes(ui->noteEditor->toPlainText());
- return true;
-}
diff --git a/application/pages/instance/NotesPage.h b/application/pages/instance/NotesPage.h
deleted file mode 100644
index d0c00ac1..00000000
--- a/application/pages/instance/NotesPage.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "BaseInstance.h"
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-namespace Ui
-{
-class NotesPage;
-}
-
-class NotesPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit NotesPage(BaseInstance *inst, QWidget *parent = 0);
- virtual ~NotesPage();
- virtual QString displayName() const override
- {
- return tr("Notes");
- }
- virtual QIcon icon() const override
- {
- auto icon = MMC->getThemedIcon("notes");
- if(icon.isNull())
- icon = MMC->getThemedIcon("news");
- return icon;
- }
- virtual QString id() const override
- {
- return "notes";
- }
- virtual bool apply() override;
- virtual QString helpPage() const override
- {
- return "Notes";
- }
-
-private:
- Ui::NotesPage *ui;
- BaseInstance *m_inst;
-};
diff --git a/application/pages/instance/NotesPage.ui b/application/pages/instance/NotesPage.ui
deleted file mode 100644
index 67cb261c..00000000
--- a/application/pages/instance/NotesPage.ui
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>NotesPage</class>
- <widget class="QWidget" name="NotesPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>731</width>
- <height>538</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTextEdit" name="noteEditor">
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOn</enum>
- </property>
- <property name="tabChangesFocus">
- <bool>true</bool>
- </property>
- <property name="acceptRichText">
- <bool>false</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>noteEditor</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/OtherLogsPage.cpp b/application/pages/instance/OtherLogsPage.cpp
deleted file mode 100644
index b67b84bd..00000000
--- a/application/pages/instance/OtherLogsPage.cpp
+++ /dev/null
@@ -1,313 +0,0 @@
-/* Copyright 2013-2021 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"
-
-#include <QMessageBox>
-
-#include "GuiUtil.h"
-#include "RecursiveFileSystemWatcher.h"
-#include <GZip.h>
-#include <FileSystem.h>
-#include <QShortcut>
-
-OtherLogsPage::OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent)
- : QWidget(parent), ui(new Ui::OtherLogsPage), m_path(path), m_fileFilter(fileFilter),
- m_watcher(new RecursiveFileSystemWatcher(this))
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
-
- m_watcher->setMatcher(fileFilter);
- m_watcher->setRootDir(QDir::current().absoluteFilePath(m_path));
-
- connect(m_watcher, &RecursiveFileSystemWatcher::filesChanged, this, &OtherLogsPage::populateSelectLogBox);
- populateSelectLogBox();
-
- auto findShortcut = new QShortcut(QKeySequence(QKeySequence::Find), this);
- connect(findShortcut, &QShortcut::activated, this, &OtherLogsPage::findActivated);
-
- auto findNextShortcut = new QShortcut(QKeySequence(QKeySequence::FindNext), this);
- connect(findNextShortcut, &QShortcut::activated, this, &OtherLogsPage::findNextActivated);
-
- auto findPreviousShortcut = new QShortcut(QKeySequence(QKeySequence::FindPrevious), this);
- connect(findPreviousShortcut, &QShortcut::activated, this, &OtherLogsPage::findPreviousActivated);
-
- connect(ui->searchBar, &QLineEdit::returnPressed, this, &OtherLogsPage::on_findButton_clicked);
-}
-
-OtherLogsPage::~OtherLogsPage()
-{
- delete ui;
-}
-
-void OtherLogsPage::openedImpl()
-{
- m_watcher->enable();
-}
-void OtherLogsPage::closedImpl()
-{
- m_watcher->disable();
-}
-
-void OtherLogsPage::populateSelectLogBox()
-{
- ui->selectLogBox->clear();
- ui->selectLogBox->addItems(m_watcher->files());
- if (m_currentFile.isEmpty())
- {
- setControlsEnabled(false);
- ui->selectLogBox->setCurrentIndex(-1);
- }
- else
- {
- const int index = ui->selectLogBox->findText(m_currentFile);
- if (index != -1)
- {
- ui->selectLogBox->setCurrentIndex(index);
- setControlsEnabled(true);
- }
- else
- {
- setControlsEnabled(false);
- }
- }
-}
-
-void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index)
-{
- QString file;
- if (index != -1)
- {
- file = ui->selectLogBox->itemText(index);
- }
-
- if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_path, file)))
- {
- m_currentFile = QString();
- ui->text->clear();
- setControlsEnabled(false);
- }
- else
- {
- m_currentFile = file;
- on_btnReload_clicked();
- setControlsEnabled(true);
- }
-}
-
-void OtherLogsPage::on_btnReload_clicked()
-{
- if(m_currentFile.isEmpty())
- {
- setControlsEnabled(false);
- return;
- }
- QFile file(FS::PathCombine(m_path, 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()));
- }
- else
- {
- auto setPlainText = [&](const QString & text)
- {
- QString fontFamily = MMC->settings()->get("ConsoleFont").toString();
- bool conversionOk = false;
- int fontSize = MMC->settings()->get("ConsoleFontSize").toInt(&conversionOk);
- if(!conversionOk)
- {
- fontSize = 11;
- }
- QTextDocument *doc = ui->text->document();
- doc->setDefaultFont(QFont(fontFamily, fontSize));
- ui->text->setPlainText(text);
- };
- auto showTooBig = [&]()
- {
- setPlainText(
- tr("The file (%1) is too big. You may want to open it in a viewer optimized "
- "for large files.").arg(file.fileName()));
- };
- if(file.size() > (1024ll * 1024ll * 12ll))
- {
- showTooBig();
- return;
- }
- QString content;
- if(file.fileName().endsWith(".gz"))
- {
- QByteArray temp;
- if(!GZip::unzip(file.readAll(), temp))
- {
- setPlainText(
- tr("The file (%1) is not readable.").arg(file.fileName()));
- return;
- }
- content = QString::fromUtf8(temp);
- }
- else
- {
- content = QString::fromUtf8(file.readAll());
- }
- if (content.size() >= 50000000ll)
- {
- showTooBig();
- return;
- }
- setPlainText(content);
- }
-}
-
-void OtherLogsPage::on_btnPaste_clicked()
-{
- GuiUtil::uploadPaste(ui->text->toPlainText(), this);
-}
-
-void OtherLogsPage::on_btnCopy_clicked()
-{
- GuiUtil::setClipboardText(ui->text->toPlainText());
-}
-
-void OtherLogsPage::on_btnDelete_clicked()
-{
- if(m_currentFile.isEmpty())
- {
- setControlsEnabled(false);
- return;
- }
- 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(FS::PathCombine(m_path, m_currentFile));
- if (!file.remove())
- {
- QMessageBox::critical(this, tr("Error"), tr("Unable to delete %1: %2")
- .arg(m_currentFile, file.errorString()));
- }
-}
-
-
-
-void OtherLogsPage::on_btnClean_clicked()
-{
- auto toDelete = m_watcher->files();
- if(toDelete.isEmpty())
- {
- return;
- }
- QMessageBox *messageBox = new QMessageBox(this);
- messageBox->setWindowTitle(tr("Clean up"));
- if(toDelete.size() > 5)
- {
- messageBox->setText(tr("Do you really want to delete all log files?"));
- messageBox->setDetailedText(toDelete.join('\n'));
- }
- else
- {
- messageBox->setText(tr("Do you really want to delete these files?\n%1").arg(toDelete.join('\n')));
- }
- messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
- messageBox->setDefaultButton(QMessageBox::Ok);
- messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
- messageBox->setIcon(QMessageBox::Question);
- messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
-
- if (messageBox->exec() != QMessageBox::Ok)
- {
- return;
- }
- QStringList failed;
- for(auto item: toDelete)
- {
- QFile file(FS::PathCombine(m_path, item));
- if (!file.remove())
- {
- failed.push_back(item);
- }
- }
- if(!failed.empty())
- {
- QMessageBox *messageBox = new QMessageBox(this);
- messageBox->setWindowTitle(tr("Error"));
- if(failed.size() > 5)
- {
- messageBox->setText(tr("Couldn't delete some files!"));
- messageBox->setDetailedText(failed.join('\n'));
- }
- else
- {
- messageBox->setText(tr("Couldn't delete some files:\n%1").arg(failed.join('\n')));
- }
- messageBox->setStandardButtons(QMessageBox::Ok);
- messageBox->setDefaultButton(QMessageBox::Ok);
- messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse);
- messageBox->setIcon(QMessageBox::Critical);
- messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction);
- messageBox->exec();
- }
-}
-
-
-void OtherLogsPage::setControlsEnabled(const bool enabled)
-{
- ui->btnReload->setEnabled(enabled);
- ui->btnDelete->setEnabled(enabled);
- ui->btnCopy->setEnabled(enabled);
- ui->btnPaste->setEnabled(enabled);
- ui->text->setEnabled(enabled);
- ui->btnClean->setEnabled(enabled);
-}
-
-// FIXME: HACK, use LogView instead?
-static void findNext(QPlainTextEdit * _this, const QString& what, bool reverse)
-{
- _this->find(what, reverse ? QTextDocument::FindFlag::FindBackward : QTextDocument::FindFlag(0));
-}
-
-void OtherLogsPage::on_findButton_clicked()
-{
- auto modifiers = QApplication::keyboardModifiers();
- bool reverse = modifiers & Qt::ShiftModifier;
- findNext(ui->text, ui->searchBar->text(), reverse);
-}
-
-void OtherLogsPage::findNextActivated()
-{
- findNext(ui->text, ui->searchBar->text(), false);
-}
-
-void OtherLogsPage::findPreviousActivated()
-{
- findNext(ui->text, ui->searchBar->text(), true);
-}
-
-void OtherLogsPage::findActivated()
-{
- // focus the search bar if it doesn't have focus
- if (!ui->searchBar->hasFocus())
- {
- ui->searchBar->setFocus();
- ui->searchBar->selectAll();
- }
-}
diff --git a/application/pages/instance/OtherLogsPage.h b/application/pages/instance/OtherLogsPage.h
deleted file mode 100644
index 7f21c0fa..00000000
--- a/application/pages/instance/OtherLogsPage.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include <pathmatcher/IPathMatcher.h>
-
-namespace Ui
-{
-class OtherLogsPage;
-}
-
-class RecursiveFileSystemWatcher;
-
-class OtherLogsPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit OtherLogsPage(QString path, IPathMatcher::Ptr fileFilter, QWidget *parent = 0);
- ~OtherLogsPage();
-
- QString id() const override
- {
- return "logs";
- }
- QString displayName() const override
- {
- return tr("Other logs");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("log");
- }
- QString helpPage() const override
- {
- return "Minecraft-Logs";
- }
- void openedImpl() override;
- void closedImpl() override;
-
-private slots:
- void populateSelectLogBox();
- void on_selectLogBox_currentIndexChanged(const int index);
- void on_btnReload_clicked();
- void on_btnPaste_clicked();
- void on_btnCopy_clicked();
- void on_btnDelete_clicked();
- void on_btnClean_clicked();
-
- void on_findButton_clicked();
- void findActivated();
- void findNextActivated();
- void findPreviousActivated();
-
-private:
- void setControlsEnabled(const bool enabled);
-
-private:
- Ui::OtherLogsPage *ui;
- QString m_path;
- QString m_currentFile;
- IPathMatcher::Ptr m_fileFilter;
- RecursiveFileSystemWatcher *m_watcher;
-};
diff --git a/application/pages/instance/OtherLogsPage.ui b/application/pages/instance/OtherLogsPage.ui
deleted file mode 100644
index 56ff3b62..00000000
--- a/application/pages/instance/OtherLogsPage.ui
+++ /dev/null
@@ -1,150 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>OtherLogsPage</class>
- <widget class="QWidget" name="OtherLogsPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>657</width>
- <height>538</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string notr="true">Tab 1</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="2" column="1">
- <widget class="QLineEdit" name="searchBar"/>
- </item>
- <item row="2" column="2">
- <widget class="QPushButton" name="findButton">
- <property name="text">
- <string>Find</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="4">
- <widget class="QPlainTextEdit" name="text">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOn</enum>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="4">
- <layout class="QGridLayout" name="gridLayout">
- <item row="3" column="1">
- <widget class="QPushButton" name="btnCopy">
- <property name="toolTip">
- <string>Copy the whole log into the clipboard</string>
- </property>
- <property name="text">
- <string>&amp;Copy</string>
- </property>
- </widget>
- </item>
- <item row="3" column="3">
- <widget class="QPushButton" name="btnDelete">
- <property name="toolTip">
- <string>Clear the log</string>
- </property>
- <property name="text">
- <string>Delete</string>
- </property>
- </widget>
- </item>
- <item row="3" column="2">
- <widget class="QPushButton" name="btnPaste">
- <property name="toolTip">
- <string>Upload the log to paste.ee - it will stay online for a month</string>
- </property>
- <property name="text">
- <string>Upload</string>
- </property>
- </widget>
- </item>
- <item row="3" column="4">
- <widget class="QPushButton" name="btnClean">
- <property name="toolTip">
- <string>Clear the log</string>
- </property>
- <property name="text">
- <string>Clean</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QPushButton" name="btnReload">
- <property name="text">
- <string>Reload</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="5">
- <widget class="QComboBox" name="selectLogBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Search:</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>selectLogBox</tabstop>
- <tabstop>btnReload</tabstop>
- <tabstop>btnCopy</tabstop>
- <tabstop>btnPaste</tabstop>
- <tabstop>btnDelete</tabstop>
- <tabstop>btnClean</tabstop>
- <tabstop>text</tabstop>
- <tabstop>searchBar</tabstop>
- <tabstop>findButton</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/ResourcePackPage.h b/application/pages/instance/ResourcePackPage.h
deleted file mode 100644
index 1486bf52..00000000
--- a/application/pages/instance/ResourcePackPage.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include "ModFolderPage.h"
-#include "ui_ModFolderPage.h"
-
-class ResourcePackPage : public ModFolderPage
-{
- Q_OBJECT
-public:
- explicit ResourcePackPage(MinecraftInstance *instance, QWidget *parent = 0)
- : ModFolderPage(instance, instance->resourcePackList(), "resourcepacks",
- "resourcepacks", tr("Resource packs"), "Resource-packs", parent)
- {
- ui->actionView_configs->setVisible(false);
- }
- virtual ~ResourcePackPage() {}
-
- virtual bool shouldDisplay() const override
- {
- return !m_inst->traits().contains("no-texturepacks") &&
- !m_inst->traits().contains("texturepacks");
- }
-};
diff --git a/application/pages/instance/ScreenshotsPage.cpp b/application/pages/instance/ScreenshotsPage.cpp
deleted file mode 100644
index efa0f9f2..00000000
--- a/application/pages/instance/ScreenshotsPage.cpp
+++ /dev/null
@@ -1,422 +0,0 @@
-#include "ScreenshotsPage.h"
-#include "ui_ScreenshotsPage.h"
-
-#include <QModelIndex>
-#include <QMutableListIterator>
-#include <QMap>
-#include <QSet>
-#include <QFileIconProvider>
-#include <QFileSystemModel>
-#include <QStyledItemDelegate>
-#include <QLineEdit>
-#include <QEvent>
-#include <QPainter>
-#include <QClipboard>
-#include <QKeyEvent>
-#include <QMenu>
-
-#include <MultiMC.h>
-
-#include "dialogs/ProgressDialog.h"
-#include "dialogs/CustomMessageBox.h"
-#include "net/NetJob.h"
-#include "screenshots/ImgurUpload.h"
-#include "screenshots/ImgurAlbumCreation.h"
-#include "tasks/SequentialTask.h"
-
-#include "RWStorage.h"
-#include <FileSystem.h>
-#include <DesktopServices.h>
-
-typedef RWStorage<QString, QIcon> SharedIconCache;
-typedef std::shared_ptr<SharedIconCache> SharedIconCachePtr;
-
-class ThumbnailingResult : public QObject
-{
- Q_OBJECT
-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
-{
-public:
- ThumbnailRunnable(QString path, SharedIconCachePtr cache)
- {
- m_path = path;
- m_cache = cache;
- }
- void run()
- {
- QFileInfo info(m_path);
- if (info.isDir())
- return;
- if ((info.suffix().compare("png", Qt::CaseInsensitive) != 0))
- return;
- int tries = 5;
- while (tries)
- {
- if (!m_cache->stale(m_path))
- return;
- QImage image(m_path);
- if (image.isNull())
- {
- QThread::msleep(500);
- tries--;
- continue;
- }
- QImage small;
- if (image.width() > image.height())
- small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation);
- else
- small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation);
- 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);
- return;
- }
- m_resultEmitter.emitResultsFailed(m_path);
- }
- QString m_path;
- SharedIconCachePtr m_cache;
- ThumbnailingResult m_resultEmitter;
-};
-
-// 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)
- {
- m_thumbnailingPool.setMaxThreadCount(4);
- m_thumbnailCache = std::make_shared<SharedIconCache>();
- m_thumbnailCache->add("placeholder", MMC->getThemedIcon("screenshot-placeholder"));
- 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 QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const
- {
- auto model = sourceModel();
- if (!model)
- return QVariant();
- if (role == Qt::DisplayRole || role == Qt::EditRole)
- {
- QVariant result = sourceModel()->data(mapToSource(proxyIndex), role);
- return result.toString().remove(QRegExp("\\.png$"));
- }
- if (role == Qt::DecorationRole)
- {
- QVariant result =
- sourceModel()->data(mapToSource(proxyIndex), QFileSystemModel::FilePathRole);
- QString filePath = result.toString();
- QIcon temp;
- if (!watched.contains(filePath))
- {
- ((QFileSystemWatcher &)watcher).addPath(filePath);
- ((QSet<QString> &)watched).insert(filePath);
- }
- if (m_thumbnailCache->get(filePath, temp))
- {
- return temp;
- }
- if (!m_failed.contains(filePath))
- {
- ((FilterModel *)this)->thumbnailImage(filePath);
- }
- return (m_thumbnailCache->get("placeholder"));
- }
- return sourceModel()->data(mapToSource(proxyIndex), role);
- }
- virtual bool setData(const QModelIndex &index, const QVariant &value,
- int role = Qt::EditRole)
- {
- auto model = sourceModel();
- if (!model)
- return false;
- if (role != Qt::EditRole)
- return false;
- // FIXME: this is a workaround for a bug in QFileSystemModel, where it doesn't
- // sort after renames
- {
- ((QFileSystemModel *)model)->setNameFilterDisables(true);
- ((QFileSystemModel *)model)->setNameFilterDisables(false);
- }
- 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)));
- ((QThreadPool &)m_thumbnailingPool).start(runnable);
- }
-private slots:
- void thumbnailReady(QString path) { emit layoutChanged(); }
- void thumbnailFailed(QString path) { m_failed.insert(path); }
- void fileChanged(QString filepath)
- {
- m_thumbnailCache->setStale(filepath);
- thumbnailImage(filepath);
- // reinsert the path...
- watcher.removePath(filepath);
- watcher.addPath(filepath);
- }
-
-private:
- SharedIconCachePtr m_thumbnailCache;
- QThreadPool m_thumbnailingPool;
- QSet<QString> m_failed;
- QSet<QString> watched;
- QFileSystemWatcher watcher;
-};
-
-class CenteredEditingDelegate : public QStyledItemDelegate
-{
-public:
- explicit CenteredEditingDelegate(QObject *parent = 0) : QStyledItemDelegate(parent) {}
- virtual ~CenteredEditingDelegate() {}
- virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
- const QModelIndex &index) const
- {
- auto widget = QStyledItemDelegate::createEditor(parent, option, index);
- auto foo = dynamic_cast<QLineEdit *>(widget);
- if (foo)
- {
- foo->setAlignment(Qt::AlignHCenter);
- foo->setFrame(true);
- foo->setMaximumWidth(192);
- }
- return widget;
- }
-};
-
-ScreenshotsPage::ScreenshotsPage(QString path, QWidget *parent)
- : QMainWindow(parent), ui(new Ui::ScreenshotsPage)
-{
- m_model.reset(new QFileSystemModel());
- m_filterModel.reset(new FilterModel());
- m_filterModel->setSourceModel(m_model.get());
- m_model->setFilter(QDir::Files | QDir::Writable | QDir::Readable);
- m_model->setReadOnly(false);
- m_model->setNameFilters({"*.png"});
- m_model->setNameFilterDisables(false);
- m_folder = path;
- m_valid = FS::ensureFolderPathExists(m_folder);
-
- ui->setupUi(this);
- ui->toolBar->insertSpacer(ui->actionView_Folder);
-
- ui->listView->setIconSize(QSize(128, 128));
- ui->listView->setGridSize(QSize(192, 160));
- ui->listView->setSpacing(9);
- // ui->listView->setUniformItemSizes(true);
- ui->listView->setLayoutMode(QListView::Batched);
- ui->listView->setViewMode(QListView::IconMode);
- ui->listView->setResizeMode(QListView::Adjust);
- ui->listView->installEventFilter(this);
- ui->listView->setEditTriggers(0);
- ui->listView->setItemDelegate(new CenteredEditingDelegate(this));
- ui->listView->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(ui->listView, &QListView::customContextMenuRequested, this, &ScreenshotsPage::ShowContextMenu);
- connect(ui->listView, SIGNAL(activated(QModelIndex)), SLOT(onItemActivated(QModelIndex)));
-}
-
-bool ScreenshotsPage::eventFilter(QObject *obj, QEvent *evt)
-{
- if (obj != ui->listView)
- return QWidget::eventFilter(obj, evt);
- if (evt->type() != QEvent::KeyPress)
- {
- return QWidget::eventFilter(obj, evt);
- }
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt);
- switch (keyEvent->key())
- {
- case Qt::Key_Delete:
- on_actionDelete_triggered();
- return true;
- case Qt::Key_F2:
- on_actionRename_triggered();
- return true;
- default:
- break;
- }
- return QWidget::eventFilter(obj, evt);
-}
-
-ScreenshotsPage::~ScreenshotsPage()
-{
- delete ui;
-}
-
-void ScreenshotsPage::ShowContextMenu(const QPoint& pos)
-{
- auto menu = ui->toolBar->createContextMenu(this, tr("Context menu"));
- menu->exec(ui->listView->mapToGlobal(pos));
- delete menu;
-}
-
-QMenu * ScreenshotsPage::createPopupMenu()
-{
- QMenu* filteredMenu = QMainWindow::createPopupMenu();
- filteredMenu->removeAction( ui->toolBar->toggleViewAction() );
- return filteredMenu;
-}
-
-void ScreenshotsPage::onItemActivated(QModelIndex index)
-{
- if (!index.isValid())
- return;
- auto info = m_model->fileInfo(index);
- QString fileName = info.absoluteFilePath();
- DesktopServices::openFile(info.absoluteFilePath());
-}
-
-void ScreenshotsPage::on_actionView_Folder_triggered()
-{
- DesktopServices::openDirectory(m_folder, true);
-}
-
-void ScreenshotsPage::on_actionUpload_triggered()
-{
- auto selection = ui->listView->selectionModel()->selectedRows();
- if (selection.isEmpty())
- return;
-
- QList<ScreenshotPtr> uploaded;
- auto job = NetJobPtr(new NetJob("Screenshot Upload"));
- if(selection.size() < 2)
- {
- auto item = selection.at(0);
- auto info = m_model->fileInfo(item);
- auto screenshot = std::make_shared<ScreenShot>(info);
- job->addNetAction(ImgurUpload::make(screenshot));
-
- m_uploadActive = true;
- ProgressDialog dialog(this);
- if(dialog.execWithTask(job.get()) != QDialog::Accepted)
- {
- CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
- tr("Unknown error"), QMessageBox::Warning)->exec();
- }
- else
- {
- auto link = screenshot->m_url;
- QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(link);
- CustomMessageBox::selectable(
- this,
- tr("Upload finished"),
- tr("The <a href=\"%1\">link to the uploaded screenshot</a> has been placed in your clipboard.")
- .arg(link),
- QMessageBox::Information
- )->exec();
- }
-
- m_uploadActive = false;
- return;
- }
-
- for (auto item : selection)
- {
- auto info = m_model->fileInfo(item);
- auto screenshot = std::make_shared<ScreenShot>(info);
- uploaded.push_back(screenshot);
- job->addNetAction(ImgurUpload::make(screenshot));
- }
- SequentialTask task;
- auto albumTask = NetJobPtr(new NetJob("Imgur Album Creation"));
- auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
- albumTask->addNetAction(imgurAlbum);
- task.addTask(job.unwrap());
- task.addTask(albumTask.unwrap());
- m_uploadActive = true;
- ProgressDialog prog(this);
- if (prog.execWithTask(&task) != QDialog::Accepted)
- {
- CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
- tr("Unknown error"), QMessageBox::Warning)->exec();
- }
- else
- {
- auto link = QString("https://imgur.com/a/%1").arg(imgurAlbum->id());
- QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(link);
- CustomMessageBox::selectable(
- this,
- tr("Upload finished"),
- tr("The <a href=\"%1\">link to the uploaded album</a> has been placed in your clipboard.") .arg(link),
- QMessageBox::Information
- )->exec();
- }
- m_uploadActive = false;
-}
-
-void ScreenshotsPage::on_actionDelete_triggered()
-{
- auto mbox = CustomMessageBox::selectable(
- this, tr("Are you sure?"), tr("This will delete all selected screenshots."),
- QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No);
- std::unique_ptr<QMessageBox> box(mbox);
-
- if (box->exec() != QMessageBox::Yes)
- return;
-
- auto selected = ui->listView->selectionModel()->selectedIndexes();
- for (auto item : selected)
- {
- m_model->remove(item);
- }
-}
-
-void ScreenshotsPage::on_actionRename_triggered()
-{
- auto selection = ui->listView->selectionModel()->selectedIndexes();
- if (selection.isEmpty())
- return;
- ui->listView->edit(selection[0]);
- // TODO: mass renaming
-}
-
-void ScreenshotsPage::openedImpl()
-{
- if(!m_valid)
- {
- m_valid = FS::ensureFolderPathExists(m_folder);
- }
- if (m_valid)
- {
- QString path = QDir(m_folder).absolutePath();
- auto idx = m_model->setRootPath(path);
- if(idx.isValid())
- {
- ui->listView->setModel(m_filterModel.get());
- ui->listView->setRootIndex(m_filterModel->mapFromSource(idx));
- }
- else
- {
- ui->listView->setModel(nullptr);
- }
- }
-}
-
-#include "ScreenshotsPage.moc"
diff --git a/application/pages/instance/ScreenshotsPage.h b/application/pages/instance/ScreenshotsPage.h
deleted file mode 100644
index 03a809de..00000000
--- a/application/pages/instance/ScreenshotsPage.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Copyright 2013-2021 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 <QMainWindow>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-class QFileSystemModel;
-class QIdentityProxyModel;
-namespace Ui
-{
-class ScreenshotsPage;
-}
-
-struct ScreenShot;
-class ScreenshotList;
-class ImgurAlbumCreation;
-
-class ScreenshotsPage : public QMainWindow, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit ScreenshotsPage(QString path, QWidget *parent = 0);
- virtual ~ScreenshotsPage();
-
- virtual void openedImpl() override;
-
- enum
- {
- NothingDone = 0x42
- };
-
- virtual bool eventFilter(QObject *, QEvent *) override;
- virtual QString displayName() const override
- {
- return tr("Screenshots");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("screenshots");
- }
- virtual QString id() const override
- {
- return "screenshots";
- }
- virtual QString helpPage() const override
- {
- return "Screenshots-management";
- }
- virtual bool apply() override
- {
- return !m_uploadActive;
- }
-
-protected:
- QMenu * createPopupMenu() override;
-
-private slots:
- void on_actionUpload_triggered();
- void on_actionDelete_triggered();
- void on_actionRename_triggered();
- void on_actionView_Folder_triggered();
- void onItemActivated(QModelIndex);
- void ShowContextMenu(const QPoint &pos);
-
-private:
- Ui::ScreenshotsPage *ui;
- std::shared_ptr<QFileSystemModel> m_model;
- std::shared_ptr<QIdentityProxyModel> m_filterModel;
- QString m_folder;
- bool m_valid = false;
- bool m_uploadActive = false;
-};
diff --git a/application/pages/instance/ScreenshotsPage.ui b/application/pages/instance/ScreenshotsPage.ui
deleted file mode 100644
index f11f4cd4..00000000
--- a/application/pages/instance/ScreenshotsPage.ui
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ScreenshotsPage</class>
- <widget class="QMainWindow" name="ScreenshotsPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>800</width>
- <height>600</height>
- </rect>
- </property>
- <widget class="QWidget" name="centralwidget">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QListView" name="listView">
- <property name="selectionMode">
- <enum>QAbstractItemView::ExtendedSelection</enum>
- </property>
- <property name="selectionBehavior">
- <enum>QAbstractItemView::SelectRows</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="WideBar" name="toolBar">
- <property name="windowTitle">
- <string>Actions</string>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextOnly</enum>
- </property>
- <attribute name="toolBarArea">
- <enum>RightToolBarArea</enum>
- </attribute>
- <attribute name="toolBarBreak">
- <bool>false</bool>
- </attribute>
- <addaction name="actionUpload"/>
- <addaction name="actionDelete"/>
- <addaction name="actionRename"/>
- <addaction name="actionView_Folder"/>
- </widget>
- <action name="actionUpload">
- <property name="text">
- <string>Upload</string>
- </property>
- </action>
- <action name="actionDelete">
- <property name="text">
- <string>Delete</string>
- </property>
- </action>
- <action name="actionRename">
- <property name="text">
- <string>Rename</string>
- </property>
- </action>
- <action name="actionView_Folder">
- <property name="text">
- <string>View Folder</string>
- </property>
- </action>
- </widget>
- <customwidgets>
- <customwidget>
- <class>WideBar</class>
- <extends>QToolBar</extends>
- <header>widgets/WideBar.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/ServersPage.cpp b/application/pages/instance/ServersPage.cpp
deleted file mode 100644
index d63c6e70..00000000
--- a/application/pages/instance/ServersPage.cpp
+++ /dev/null
@@ -1,768 +0,0 @@
-#include "ServersPage.h"
-#include "ui_ServersPage.h"
-
-#include <FileSystem.h>
-#include <sstream>
-#include <io/stream_reader.h>
-#include <tag_string.h>
-#include <tag_primitive.h>
-#include <tag_list.h>
-#include <tag_compound.h>
-#include <minecraft/MinecraftInstance.h>
-
-#include <QFileSystemWatcher>
-#include <QMenu>
-
-static const int COLUMN_COUNT = 2; // 3 , TBD: latency and other nice things.
-
-struct Server
-{
- // Types
- enum class AcceptsTextures : int
- {
- ASK = 0,
- ALWAYS = 1,
- NEVER = 2
- };
-
- // Methods
- Server()
- {
- m_name = QObject::tr("Minecraft Server");
- }
- Server(const QString & name, const QString & address)
- {
- m_name = name;
- m_address = address;
- }
- Server(nbt::tag_compound& server)
- {
- std::string addressStr(server["ip"]);
- m_address = QString::fromUtf8(addressStr.c_str());
-
- std::string nameStr(server["name"]);
- m_name = QString::fromUtf8(nameStr.c_str());
-
- if(server["icon"])
- {
- std::string base64str(server["icon"]);
- m_icon = QByteArray::fromBase64(base64str.c_str());
- }
-
- if(server.has_key("acceptTextures", nbt::tag_type::Byte))
- {
- bool value = server["acceptTextures"].as<nbt::tag_byte>().get();
- if(value)
- {
- m_acceptsTextures = AcceptsTextures::ALWAYS;
- }
- else
- {
- m_acceptsTextures = AcceptsTextures::NEVER;
- }
- }
- }
-
- void serialize(nbt::tag_compound& server)
- {
- server.insert("name", m_name.trimmed().toUtf8().toStdString());
- server.insert("ip", m_address.trimmed().toUtf8().toStdString());
- if(m_icon.size())
- {
- server.insert("icon", m_icon.toBase64().toStdString());
- }
- if(m_acceptsTextures != AcceptsTextures::ASK)
- {
- server.insert("acceptTextures", nbt::tag_byte(m_acceptsTextures == AcceptsTextures::ALWAYS));
- }
- }
-
- // Data - persistent and user changeable
- QString m_name;
- QString m_address;
- AcceptsTextures m_acceptsTextures = AcceptsTextures::ASK;
-
- // Data - persistent and automatically updated
- QByteArray m_icon;
-
- // Data - temporary
- bool m_checked = false;
- bool m_up = false;
- QString m_motd; // https://mctools.org/motd-creator
- int m_ping = 0;
- int m_currentPlayers = 0;
- int m_maxPlayers = 0;
-};
-
-static std::unique_ptr <nbt::tag_compound> parseServersDat(const QString& filename)
-{
- try
- {
- QByteArray input = FS::read(filename);
- std::istringstream foo(std::string(input.constData(), input.size()));
- auto pair = nbt::io::read_compound(foo);
-
- if(pair.first != "")
- return nullptr;
-
- if(pair.second == nullptr)
- return nullptr;
-
- return std::move(pair.second);
- }
- catch (...)
- {
- return nullptr;
- }
-}
-
-static bool serializeServerDat(const QString& filename, nbt::tag_compound * levelInfo)
-{
- try
- {
- if(!FS::ensureFilePathExists(filename))
- {
- return false;
- }
- std::ostringstream s;
- nbt::io::write_tag("", *levelInfo, s);
- QByteArray val(s.str().data(), (int) s.str().size() );
- FS::write(filename, val);
- return true;
- }
- catch (...)
- {
- return false;
- }
-}
-
-class ServersModel: public QAbstractListModel
-{
- Q_OBJECT
-public:
- enum Roles
- {
- ServerPtrRole = Qt::UserRole,
- };
- explicit ServersModel(const QString &path, QObject *parent = 0)
- : QAbstractListModel(parent)
- {
- m_path = path;
- m_watcher = new QFileSystemWatcher(this);
- connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &ServersModel::fileChanged);
- connect(m_watcher, &QFileSystemWatcher::directoryChanged, this, &ServersModel::dirChanged);
- m_saveTimer.setSingleShot(true);
- m_saveTimer.setInterval(5000);
- connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal);
- }
- virtual ~ServersModel() {};
-
- void observe()
- {
- if(m_observed)
- {
- return;
- }
- m_observed = true;
-
- if(!m_loaded)
- {
- load();
- }
-
- updateFSObserver();
- }
-
- void unobserve()
- {
- if(!m_observed)
- {
- return;
- }
- m_observed = false;
-
- updateFSObserver();
- }
-
- void lock()
- {
- if(m_locked)
- {
- return;
- }
- saveNow();
-
- m_locked = true;
- updateFSObserver();
- }
-
- void unlock()
- {
- if(!m_locked)
- {
- return;
- }
- m_locked = false;
-
- updateFSObserver();
- }
-
- int addEmptyRow(int position)
- {
- if(m_locked)
- {
- return -1;
- }
- if(position < 0 || position >= rowCount())
- {
- position = rowCount();
- }
- beginInsertRows(QModelIndex(), position, position);
- m_servers.insert(position, Server());
- endInsertRows();
- scheduleSave();
- return position;
- }
-
- bool removeRow(int row)
- {
- if(m_locked)
- {
- return false;
- }
- if(row < 0 || row >= rowCount())
- {
- return false;
- }
- beginRemoveRows(QModelIndex(), row, row);
- m_servers.removeAt(row);
- endRemoveRows(); // does absolutely nothing, the selected server stays as the next line...
- scheduleSave();
- return true;
- }
-
- bool moveUp(int row)
- {
- if(m_locked)
- {
- return false;
- }
- if(row <= 0)
- {
- return false;
- }
- beginMoveRows(QModelIndex(), row, row, QModelIndex(), row - 1);
- m_servers.swap(row-1, row);
- endMoveRows();
- scheduleSave();
- return true;
- }
-
- bool moveDown(int row)
- {
- if(m_locked)
- {
- return false;
- }
- int count = rowCount();
- if(row + 1 >= count)
- {
- return false;
- }
- beginMoveRows(QModelIndex(), row, row, QModelIndex(), row + 2);
- m_servers.swap(row+1, row);
- endMoveRows();
- scheduleSave();
- return true;
- }
-
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override
- {
- if (section < 0 || section >= COLUMN_COUNT)
- return QVariant();
-
- if(role == Qt::DisplayRole)
- {
- switch(section)
- {
- case 0:
- return tr("Name");
- case 1:
- return tr("Address");
- case 2:
- return tr("Latency");
- }
- }
-
- return QAbstractListModel::headerData(section, orientation, role);
- }
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
- {
- if (!index.isValid())
- return QVariant();
-
- int row = index.row();
- int column = index.column();
- if(column < 0 || column >= COLUMN_COUNT)
- return QVariant();
-
- if (row < 0 || row >= m_servers.size())
- return QVariant();
-
- switch(column)
- {
- case 0:
- switch (role)
- {
- case Qt::DecorationRole:
- {
- auto & bytes = m_servers[row].m_icon;
- if(bytes.size())
- {
- QPixmap px;
- if(px.loadFromData(bytes))
- return QIcon(px);
- }
- return MMC->getThemedIcon("unknown_server");
- }
- case Qt::DisplayRole:
- return m_servers[row].m_name;
- case ServerPtrRole:
- return QVariant::fromValue<void *>((void *)&m_servers[row]);
- default:
- return QVariant();
- }
- case 1:
- switch (role)
- {
- case Qt::DisplayRole:
- return m_servers[row].m_address;
- default:
- return QVariant();
- }
- case 2:
- switch (role)
- {
- case Qt::DisplayRole:
- return m_servers[row].m_ping;
- default:
- return QVariant();
- }
- default:
- return QVariant();
- }
- }
-
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override
- {
- return m_servers.size();
- }
- int columnCount(const QModelIndex & parent) const override
- {
- return COLUMN_COUNT;
- }
-
- Server * at(int index)
- {
- if(index < 0 || index >= rowCount())
- {
- return nullptr;
- }
- return &m_servers[index];
- }
-
- void setName(int row, const QString & name)
- {
- if(m_locked)
- {
- return;
- }
- auto server = at(row);
- if(!server || server->m_name == name)
- {
- return;
- }
- server->m_name = name;
- emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
- scheduleSave();
- }
-
- void setAddress(int row, const QString & address)
- {
- if(m_locked)
- {
- return;
- }
- auto server = at(row);
- if(!server || server->m_address == address)
- {
- return;
- }
- server->m_address = address;
- emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
- scheduleSave();
- }
-
- void setAcceptsTextures(int row, Server::AcceptsTextures textures)
- {
- if(m_locked)
- {
- return;
- }
- auto server = at(row);
- if(!server || server->m_acceptsTextures == textures)
- {
- return;
- }
- server->m_acceptsTextures = textures;
- emit dataChanged(index(row, 0), index(row, COLUMN_COUNT - 1));
- scheduleSave();
- }
-
- void load()
- {
- cancelSave();
- beginResetModel();
- QList<Server> servers;
- auto serversDat = parseServersDat(serversPath());
- if(serversDat)
- {
- auto &serversList = serversDat->at("servers").as<nbt::tag_list>();
- for(auto iter = serversList.begin(); iter != serversList.end(); iter++)
- {
- auto & serverTag = (*iter).as<nbt::tag_compound>();
- Server s(serverTag);
- servers.append(s);
- }
- }
- m_servers.swap(servers);
- m_loaded = true;
- endResetModel();
- }
-
- void saveNow()
- {
- if(saveIsScheduled())
- {
- save_internal();
- }
- }
-
-
-public slots:
- void dirChanged(const QString& path)
- {
- qDebug() << "Changed:" << path;
- load();
- }
- void fileChanged(const QString& path)
- {
- qDebug() << "Changed:" << path;
- }
-
-private slots:
- void save_internal()
- {
- cancelSave();
- QString path = serversPath();
- qDebug() << "Server list about to be saved to" << path;
-
- nbt::tag_compound out;
- nbt::tag_list list;
- for(auto & server: m_servers)
- {
- nbt::tag_compound serverNbt;
- server.serialize(serverNbt);
- list.push_back(std::move(serverNbt));
- }
- out.insert("servers", nbt::value(std::move(list)));
-
- if(!serializeServerDat(path, &out))
- {
- qDebug() << "Failed to save server list:" << path << "Will try again.";
- scheduleSave();
- }
- }
-
-private:
- void scheduleSave()
- {
- if(!m_loaded)
- {
- qDebug() << "Server list should never save if it didn't successfully load, path:" << m_path;
- return;
- }
- if(!m_dirty)
- {
- m_dirty = true;
- qDebug() << "Server list save is scheduled for" << m_path;
- }
- m_saveTimer.start();
- }
-
- void cancelSave()
- {
- m_dirty = false;
- m_saveTimer.stop();
- }
-
- bool saveIsScheduled() const
- {
- return m_dirty;
- }
-
- void updateFSObserver()
- {
- bool observingFS = m_watcher->directories().contains(m_path);
- if(m_observed && m_locked)
- {
- if(!observingFS)
- {
- qWarning() << "Will watch" << m_path;
- if(!m_watcher->addPath(m_path))
- {
- qWarning() << "Failed to start watching" << m_path;
- }
- }
- }
- else
- {
- if(observingFS)
- {
- qWarning() << "Will stop watching" << m_path;
- if(!m_watcher->removePath(m_path))
- {
- qWarning() << "Failed to stop watching" << m_path;
- }
- }
- }
- }
-
- QString serversPath()
- {
- QFileInfo foo(FS::PathCombine(m_path, "servers.dat"));
- return foo.filePath();
- }
-
-private:
- bool m_loaded = false;
- bool m_locked = false;
- bool m_observed = false;
- bool m_dirty = false;
- QString m_path;
- QList<Server> m_servers;
- QFileSystemWatcher *m_watcher = nullptr;
- QTimer m_saveTimer;
-};
-
-ServersPage::ServersPage(InstancePtr inst, QWidget* parent)
- : QMainWindow(parent), ui(new Ui::ServersPage)
-{
- ui->setupUi(this);
- m_inst = inst;
- m_model = new ServersModel(inst->gameRoot(), this);
- ui->serversView->setIconSize(QSize(64,64));
- ui->serversView->setModel(m_model);
- ui->serversView->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(ui->serversView, &QTreeView::customContextMenuRequested, this, &ServersPage::ShowContextMenu);
-
- auto head = ui->serversView->header();
- if(head->count())
- {
- head->setSectionResizeMode(0, QHeaderView::Stretch);
- for(int i = 1; i < head->count(); i++)
- {
- head->setSectionResizeMode(i, QHeaderView::ResizeToContents);
- }
- }
-
- auto selectionModel = ui->serversView->selectionModel();
- connect(selectionModel, &QItemSelectionModel::currentChanged, this, &ServersPage::currentChanged);
- connect(m_inst.get(), &MinecraftInstance::runningStatusChanged, this, &ServersPage::on_RunningState_changed);
- connect(ui->nameLine, &QLineEdit::textEdited, this, &ServersPage::nameEdited);
- connect(ui->addressLine, &QLineEdit::textEdited, this, &ServersPage::addressEdited);
- connect(ui->resourceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(resourceIndexChanged(int)));
- connect(m_model, &QAbstractItemModel::rowsRemoved, this, &ServersPage::rowsRemoved);
-
- m_locked = m_inst->isRunning();
- if(m_locked)
- {
- m_model->lock();
- }
-
- updateState();
-}
-
-ServersPage::~ServersPage()
-{
- m_model->saveNow();
- delete ui;
-}
-
-void ServersPage::ShowContextMenu(const QPoint& pos)
-{
- auto menu = ui->toolBar->createContextMenu(this, tr("Context menu"));
- menu->exec(ui->serversView->mapToGlobal(pos));
- delete menu;
-}
-
-QMenu * ServersPage::createPopupMenu()
-{
- QMenu* filteredMenu = QMainWindow::createPopupMenu();
- filteredMenu->removeAction( ui->toolBar->toggleViewAction() );
- return filteredMenu;
-}
-
-void ServersPage::on_RunningState_changed(bool running)
-{
- if(m_locked == running)
- {
- return;
- }
- m_locked = running;
- if(m_locked)
- {
- m_model->lock();
- }
- else
- {
- m_model->unlock();
- }
- updateState();
-}
-
-void ServersPage::currentChanged(const QModelIndex &current, const QModelIndex &previous)
-{
- int nextServer = -1;
- if (!current.isValid())
- {
- nextServer = -1;
- }
- else
- {
- nextServer = current.row();
- }
- currentServer = nextServer;
- updateState();
-}
-
-// WARNING: this is here because currentChanged is not accurate when removing rows. the current item needs to be fixed up after removal.
-void ServersPage::rowsRemoved(const QModelIndex& parent, int first, int last)
-{
- if(currentServer < first)
- {
- // current was before the removal
- return;
- }
- else if(currentServer >= first && currentServer <= last)
- {
- // current got removed...
- return;
- }
- else
- {
- // current was past the removal
- int count = last - first + 1;
- currentServer -= count;
- }
-}
-
-void ServersPage::nameEdited(const QString& name)
-{
- m_model->setName(currentServer, name);
-}
-
-void ServersPage::addressEdited(const QString& address)
-{
- m_model->setAddress(currentServer, address);
-}
-
-void ServersPage::resourceIndexChanged(int index)
-{
- auto acceptsTextures = Server::AcceptsTextures(index);
- m_model->setAcceptsTextures(currentServer, acceptsTextures);
-}
-
-void ServersPage::updateState()
-{
- auto server = m_model->at(currentServer);
-
- bool serverEditEnabled = server && !m_locked;
- ui->addressLine->setEnabled(serverEditEnabled);
- ui->nameLine->setEnabled(serverEditEnabled);
- ui->resourceComboBox->setEnabled(serverEditEnabled);
- ui->actionMove_Down->setEnabled(serverEditEnabled);
- ui->actionMove_Up->setEnabled(serverEditEnabled);
- ui->actionRemove->setEnabled(serverEditEnabled);
- ui->actionJoin->setEnabled(serverEditEnabled);
-
- if(server)
- {
- ui->addressLine->setText(server->m_address);
- ui->nameLine->setText(server->m_name);
- ui->resourceComboBox->setCurrentIndex(int(server->m_acceptsTextures));
- }
- else
- {
- ui->addressLine->setText(QString());
- ui->nameLine->setText(QString());
- ui->resourceComboBox->setCurrentIndex(0);
- }
-
- ui->actionAdd->setDisabled(m_locked);
-}
-
-void ServersPage::openedImpl()
-{
- m_model->observe();
-}
-
-void ServersPage::closedImpl()
-{
- m_model->unobserve();
-}
-
-void ServersPage::on_actionAdd_triggered()
-{
- int position = m_model->addEmptyRow(currentServer + 1);
- if(position < 0)
- {
- return;
- }
- // select the new row
- ui->serversView->selectionModel()->setCurrentIndex(
- m_model->index(position),
- QItemSelectionModel::SelectCurrent | QItemSelectionModel::Clear | QItemSelectionModel::Rows
- );
- currentServer = position;
-}
-
-void ServersPage::on_actionRemove_triggered()
-{
- m_model->removeRow(currentServer);
-}
-
-void ServersPage::on_actionMove_Up_triggered()
-{
- if(m_model->moveUp(currentServer))
- {
- currentServer --;
- }
-}
-
-void ServersPage::on_actionMove_Down_triggered()
-{
- if(m_model->moveDown(currentServer))
- {
- currentServer ++;
- }
-}
-
-void ServersPage::on_actionJoin_triggered()
-{
- const auto &address = m_model->at(currentServer)->m_address;
- MMC->launch(m_inst, true, nullptr, std::make_shared<MinecraftServerTarget>(MinecraftServerTarget::parse(address)));
-}
-
-#include "ServersPage.moc"
diff --git a/application/pages/instance/ServersPage.h b/application/pages/instance/ServersPage.h
deleted file mode 100644
index 8c5b7eb8..00000000
--- a/application/pages/instance/ServersPage.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Copyright 2013-2021 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 <QMainWindow>
-#include <QString>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-
-namespace Ui
-{
-class ServersPage;
-}
-
-struct Server;
-class ServersModel;
-class MinecraftInstance;
-
-class ServersPage : public QMainWindow, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit ServersPage(InstancePtr inst, QWidget *parent = 0);
- virtual ~ServersPage();
-
- void openedImpl() override;
- void closedImpl() override;
-
- virtual QString displayName() const override
- {
- return tr("Servers");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("unknown_server");
- }
- virtual QString id() const override
- {
- return "servers";
- }
- virtual QString helpPage() const override
- {
- return "Servers-management";
- }
-
-protected:
- QMenu * createPopupMenu() override;
-
-private:
- void updateState();
- void scheduleSave();
- bool saveIsScheduled() const;
-
-private slots:
- void currentChanged(const QModelIndex &current, const QModelIndex &previous);
- void rowsRemoved(const QModelIndex &parent, int first, int last);
-
- void on_actionAdd_triggered();
- void on_actionRemove_triggered();
- void on_actionMove_Up_triggered();
- void on_actionMove_Down_triggered();
- void on_actionJoin_triggered();
-
- void on_RunningState_changed(bool running);
-
- void nameEdited(const QString & name);
- void addressEdited(const QString & address);
- void resourceIndexChanged(int index);\
-
- void ShowContextMenu(const QPoint &pos);
-
-private: // data
- int currentServer = -1;
- bool m_locked = true;
- Ui::ServersPage *ui = nullptr;
- ServersModel * m_model = nullptr;
- InstancePtr m_inst = nullptr;
-};
-
diff --git a/application/pages/instance/ServersPage.ui b/application/pages/instance/ServersPage.ui
deleted file mode 100644
index d89b7cba..00000000
--- a/application/pages/instance/ServersPage.ui
+++ /dev/null
@@ -1,194 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ServersPage</class>
- <widget class="QMainWindow" name="ServersPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>1318</width>
- <height>879</height>
- </rect>
- </property>
- <widget class="QWidget" name="centralwidget">
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTreeView" name="serversView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="acceptDrops">
- <bool>true</bool>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="selectionMode">
- <enum>QAbstractItemView::SingleSelection</enum>
- </property>
- <property name="selectionBehavior">
- <enum>QAbstractItemView::SelectRows</enum>
- </property>
- <property name="iconSize">
- <size>
- <width>64</width>
- <height>64</height>
- </size>
- </property>
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <attribute name="headerStretchLastSection">
- <bool>false</bool>
- </attribute>
- </widget>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="leftMargin">
- <number>6</number>
- </property>
- <property name="rightMargin">
- <number>6</number>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="nameLabel">
- <property name="text">
- <string>&amp;Name</string>
- </property>
- <property name="buddy">
- <cstring>nameLine</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="nameLine"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="addressLabel">
- <property name="text">
- <string>Address</string>
- </property>
- <property name="buddy">
- <cstring>addressLine</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="addressLine"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="resourcesLabel">
- <property name="text">
- <string>Reso&amp;urces</string>
- </property>
- <property name="buddy">
- <cstring>resourceComboBox</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QComboBox" name="resourceComboBox">
- <item>
- <property name="text">
- <string>Ask to download</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Always download</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Never download</string>
- </property>
- </item>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <widget class="WideBar" name="toolBar">
- <property name="windowTitle">
- <string>Actions</string>
- </property>
- <property name="allowedAreas">
- <set>Qt::LeftToolBarArea|Qt::RightToolBarArea</set>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextOnly</enum>
- </property>
- <property name="floatable">
- <bool>false</bool>
- </property>
- <attribute name="toolBarArea">
- <enum>RightToolBarArea</enum>
- </attribute>
- <attribute name="toolBarBreak">
- <bool>false</bool>
- </attribute>
- <addaction name="actionAdd"/>
- <addaction name="actionRemove"/>
- <addaction name="actionMove_Up"/>
- <addaction name="actionMove_Down"/>
- <addaction name="actionJoin"/>
- </widget>
- <action name="actionAdd">
- <property name="text">
- <string>Add</string>
- </property>
- </action>
- <action name="actionRemove">
- <property name="text">
- <string>Remove</string>
- </property>
- </action>
- <action name="actionMove_Up">
- <property name="text">
- <string>Move Up</string>
- </property>
- </action>
- <action name="actionMove_Down">
- <property name="text">
- <string>Move Down</string>
- </property>
- </action>
- <action name="actionJoin">
- <property name="text">
- <string>Join</string>
- </property>
- </action>
- </widget>
- <customwidgets>
- <customwidget>
- <class>WideBar</class>
- <extends>QToolBar</extends>
- <header>widgets/WideBar.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>serversView</tabstop>
- <tabstop>nameLine</tabstop>
- <tabstop>addressLine</tabstop>
- <tabstop>resourceComboBox</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/TexturePackPage.h b/application/pages/instance/TexturePackPage.h
deleted file mode 100644
index 3f04997d..00000000
--- a/application/pages/instance/TexturePackPage.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include "ModFolderPage.h"
-#include "ui_ModFolderPage.h"
-
-class TexturePackPage : public ModFolderPage
-{
- Q_OBJECT
-public:
- explicit TexturePackPage(MinecraftInstance *instance, QWidget *parent = 0)
- : ModFolderPage(instance, instance->texturePackList(), "texturepacks", "resourcepacks",
- tr("Texture packs"), "Texture-packs", parent)
- {
- ui->actionView_configs->setVisible(false);
- }
- virtual ~TexturePackPage() {}
-
- virtual bool shouldDisplay() const override
- {
- return m_inst->traits().contains("texturepacks");
- }
-};
diff --git a/application/pages/instance/VersionPage.cpp b/application/pages/instance/VersionPage.cpp
deleted file mode 100644
index a98bfb7d..00000000
--- a/application/pages/instance/VersionPage.cpp
+++ /dev/null
@@ -1,642 +0,0 @@
-/* Copyright 2013-2021 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 "MultiMC.h"
-
-#include <QMessageBox>
-#include <QLabel>
-#include <QEvent>
-#include <QKeyEvent>
-#include <QMenu>
-
-#include "VersionPage.h"
-#include "ui_VersionPage.h"
-
-#include "dialogs/CustomMessageBox.h"
-#include "dialogs/VersionSelectDialog.h"
-#include "dialogs/NewComponentDialog.h"
-
-#include "dialogs/ProgressDialog.h"
-#include <GuiUtil.h>
-
-#include <QAbstractItemModel>
-#include <QMessageBox>
-#include <QListView>
-#include <QString>
-#include <QUrl>
-
-#include "minecraft/PackProfile.h"
-#include "minecraft/auth/MojangAccountList.h"
-#include "minecraft/mod/Mod.h"
-#include "icons/IconList.h"
-#include "Exception.h"
-#include "Version.h"
-#include "DesktopServices.h"
-
-#include <meta/Index.h>
-#include <meta/VersionList.h>
-
-class IconProxy : public QIdentityProxyModel
-{
- Q_OBJECT
-public:
-
- IconProxy(QWidget *parentWidget) : QIdentityProxyModel(parentWidget)
- {
- connect(parentWidget, &QObject::destroyed, this, &IconProxy::widgetGone);
- m_parentWidget = parentWidget;
- }
-
- virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override
- {
- QVariant var = QIdentityProxyModel::data(proxyIndex, role);
- int column = proxyIndex.column();
- if(column == 0 && role == Qt::DecorationRole && m_parentWidget)
- {
- if(!var.isNull())
- {
- auto string = var.toString();
- if(string == "warning")
- {
- return MMC->getThemedIcon("status-yellow");
- }
- else if(string == "error")
- {
- return MMC->getThemedIcon("status-bad");
- }
- }
- return MMC->getThemedIcon("status-good");
- }
- return var;
- }
-private slots:
- void widgetGone()
- {
- m_parentWidget = nullptr;
- }
-
-private:
- QWidget *m_parentWidget = nullptr;
-};
-
-QIcon VersionPage::icon() const
-{
- return MMC->icons()->getIcon(m_inst->iconKey());
-}
-bool VersionPage::shouldDisplay() const
-{
- return true;
-}
-
-QMenu * VersionPage::createPopupMenu()
-{
- QMenu* filteredMenu = QMainWindow::createPopupMenu();
- filteredMenu->removeAction( ui->toolBar->toggleViewAction() );
- return filteredMenu;
-}
-
-VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent)
- : QMainWindow(parent), ui(new Ui::VersionPage), m_inst(inst)
-{
- ui->setupUi(this);
-
- ui->toolBar->insertSpacer(ui->actionReload);
-
- m_profile = m_inst->getPackProfile();
-
- reloadPackProfile();
-
- auto proxy = new IconProxy(ui->packageView);
- proxy->setSourceModel(m_profile.get());
-
- m_filterModel = new QSortFilterProxyModel();
- m_filterModel->setDynamicSortFilter(true);
- m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
- m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive);
- m_filterModel->setSourceModel(proxy);
- m_filterModel->setFilterKeyColumn(-1);
-
- ui->packageView->setModel(m_filterModel);
- ui->packageView->installEventFilter(this);
- ui->packageView->setSelectionMode(QAbstractItemView::SingleSelection);
- ui->packageView->setContextMenuPolicy(Qt::CustomContextMenu);
-
- connect(ui->packageView->selectionModel(), &QItemSelectionModel::currentChanged, this, &VersionPage::versionCurrent);
- auto smodel = ui->packageView->selectionModel();
- connect(smodel, &QItemSelectionModel::currentChanged, this, &VersionPage::packageCurrent);
-
- connect(m_profile.get(), &PackProfile::minecraftChanged, this, &VersionPage::updateVersionControls);
- controlsEnabled = !m_inst->isRunning();
- updateVersionControls();
- preselect(0);
- connect(m_inst, &BaseInstance::runningStatusChanged, this, &VersionPage::updateRunningStatus);
- connect(ui->packageView, &ModListView::customContextMenuRequested, this, &VersionPage::showContextMenu);
- connect(ui->filterEdit, &QLineEdit::textChanged, this, &VersionPage::onFilterTextChanged);
-}
-
-VersionPage::~VersionPage()
-{
- delete ui;
-}
-
-void VersionPage::showContextMenu(const QPoint& pos)
-{
- auto menu = ui->toolBar->createContextMenu(this, tr("Context menu"));
- menu->exec(ui->packageView->mapToGlobal(pos));
- delete menu;
-}
-
-void VersionPage::packageCurrent(const QModelIndex &current, const QModelIndex &previous)
-{
- if (!current.isValid())
- {
- ui->frame->clear();
- return;
- }
- int row = current.row();
- auto patch = m_profile->getComponent(row);
- auto severity = patch->getProblemSeverity();
- switch(severity)
- {
- case ProblemSeverity::Warning:
- ui->frame->setModText(tr("%1 possibly has issues.").arg(patch->getName()));
- break;
- case ProblemSeverity::Error:
- ui->frame->setModText(tr("%1 has issues!").arg(patch->getName()));
- break;
- default:
- case ProblemSeverity::None:
- ui->frame->clear();
- return;
- }
-
- auto &problems = patch->getProblems();
- QString problemOut;
- for (auto &problem: problems)
- {
- if(problem.m_severity == ProblemSeverity::Error)
- {
- problemOut += tr("Error: ");
- }
- else if(problem.m_severity == ProblemSeverity::Warning)
- {
- problemOut += tr("Warning: ");
- }
- problemOut += problem.m_description;
- problemOut += "\n";
- }
- ui->frame->setModDescription(problemOut);
-}
-
-void VersionPage::updateRunningStatus(bool running)
-{
- if(controlsEnabled == running) {
- controlsEnabled = !running;
- updateVersionControls();
- }
-}
-
-void VersionPage::updateVersionControls()
-{
- // FIXME: this is a dirty hack
- auto minecraftVersion = Version(m_profile->getComponentVersion("net.minecraft"));
-
- bool supportsFabric = minecraftVersion >= Version("1.14");
- ui->actionInstall_Fabric->setEnabled(controlsEnabled && supportsFabric);
-
- bool supportsForge = minecraftVersion <= Version("1.16.5");
- ui->actionInstall_Forge->setEnabled(controlsEnabled && supportsForge);
-
- bool supportsLiteLoader = minecraftVersion <= Version("1.12.2");
- ui->actionInstall_LiteLoader->setEnabled(controlsEnabled && supportsLiteLoader);
-
- updateButtons();
-}
-
-void VersionPage::updateButtons(int row)
-{
- if(row == -1)
- row = currentRow();
- auto patch = m_profile->getComponent(row);
- ui->actionRemove->setEnabled(controlsEnabled && patch && patch->isRemovable());
- ui->actionMove_down->setEnabled(controlsEnabled && patch && patch->isMoveable());
- ui->actionMove_up->setEnabled(controlsEnabled && patch && patch->isMoveable());
- ui->actionChange_version->setEnabled(controlsEnabled && patch && patch->isVersionChangeable());
- ui->actionEdit->setEnabled(controlsEnabled && patch && patch->isCustom());
- ui->actionCustomize->setEnabled(controlsEnabled && patch && patch->isCustomizable());
- ui->actionRevert->setEnabled(controlsEnabled && patch && patch->isRevertible());
- ui->actionDownload_All->setEnabled(controlsEnabled);
- ui->actionAdd_Empty->setEnabled(controlsEnabled);
- ui->actionReload->setEnabled(controlsEnabled);
- ui->actionInstall_mods->setEnabled(controlsEnabled);
- ui->actionReplace_Minecraft_jar->setEnabled(controlsEnabled);
- ui->actionAdd_to_Minecraft_jar->setEnabled(controlsEnabled);
-}
-
-bool VersionPage::reloadPackProfile()
-{
- try
- {
- m_profile->reload(Net::Mode::Online);
- return true;
- }
- catch (const Exception &e)
- {
- QMessageBox::critical(this, tr("Error"), e.cause());
- return false;
- }
- catch (...)
- {
- QMessageBox::critical(
- this, tr("Error"),
- tr("Couldn't load the instance profile."));
- return false;
- }
-}
-
-void VersionPage::on_actionReload_triggered()
-{
- reloadPackProfile();
- m_container->refreshContainer();
-}
-
-void VersionPage::on_actionRemove_triggered()
-{
- if (ui->packageView->currentIndex().isValid())
- {
- // FIXME: use actual model, not reloading.
- if (!m_profile->remove(ui->packageView->currentIndex().row()))
- {
- QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file"));
- }
- }
- updateButtons();
- reloadPackProfile();
- m_container->refreshContainer();
-}
-
-void VersionPage::on_actionInstall_mods_triggered()
-{
- if(m_container)
- {
- m_container->selectPage("mods");
- }
-}
-
-void VersionPage::on_actionAdd_to_Minecraft_jar_triggered()
-{
- auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
- if(!list.empty())
- {
- m_profile->installJarMods(list);
- }
- updateButtons();
-}
-
-void VersionPage::on_actionReplace_Minecraft_jar_triggered()
-{
- auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
- if(!jarPath.isEmpty())
- {
- m_profile->installCustomJar(jarPath);
- }
- updateButtons();
-}
-
-void VersionPage::on_actionMove_up_triggered()
-{
- try
- {
- m_profile->move(currentRow(), PackProfile::MoveUp);
- }
- catch (const Exception &e)
- {
- QMessageBox::critical(this, tr("Error"), e.cause());
- }
- updateButtons();
-}
-
-void VersionPage::on_actionMove_down_triggered()
-{
- try
- {
- m_profile->move(currentRow(), PackProfile::MoveDown);
- }
- catch (const Exception &e)
- {
- QMessageBox::critical(this, tr("Error"), e.cause());
- }
- updateButtons();
-}
-
-void VersionPage::on_actionChange_version_triggered()
-{
- auto versionRow = currentRow();
- if(versionRow == -1)
- {
- return;
- }
- auto patch = m_profile->getComponent(versionRow);
- auto name = patch->getName();
- auto list = patch->getVersionList();
- if(!list)
- {
- return;
- }
- auto uid = list->uid();
- // FIXME: this is a horrible HACK. Get version filtering information from the actual metadata...
- if(uid == "net.minecraftforge")
- {
- on_actionInstall_Forge_triggered();
- return;
- }
- else if (uid == "com.mumfrey.liteloader")
- {
- on_actionInstall_LiteLoader_triggered();
- return;
- }
- VersionSelectDialog vselect(list.get(), tr("Change %1 version").arg(name), this);
- if (uid == "net.fabricmc.intermediary")
- {
- vselect.setEmptyString(tr("No intermediary mappings versions are currently available."));
- vselect.setEmptyErrorString(tr("Couldn't load or download the intermediary mappings version lists!"));
- vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
- }
- auto currentVersion = patch->getVersion();
- if(!currentVersion.isEmpty())
- {
- vselect.setCurrentVersion(currentVersion);
- }
- if (!vselect.exec() || !vselect.selectedVersion())
- return;
-
- qDebug() << "Change" << uid << "to" << vselect.selectedVersion()->descriptor();
- bool important = false;
- if(uid == "net.minecraft")
- {
- important = true;
- }
- m_profile->setComponentVersion(uid, vselect.selectedVersion()->descriptor(), important);
- m_profile->resolve(Net::Mode::Online);
- m_container->refreshContainer();
-}
-
-void VersionPage::on_actionDownload_All_triggered()
-{
- if (!MMC->accounts()->anyAccountIsValid())
- {
- CustomMessageBox::selectable(
- this, tr("Error"),
- tr("MultiMC cannot download Minecraft or update instances unless you have at least "
- "one account added.\nPlease add your Mojang or Minecraft account."),
- QMessageBox::Warning)->show();
- return;
- }
-
- auto updateTask = m_inst->createUpdateTask(Net::Mode::Online);
- if (!updateTask)
- {
- return;
- }
- ProgressDialog tDialog(this);
- connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString)));
- // FIXME: unused return value
- tDialog.execWithTask(updateTask.get());
- updateButtons();
- m_container->refreshContainer();
-}
-
-void VersionPage::on_actionInstall_Forge_triggered()
-{
- auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
- if(!vlist)
- {
- return;
- }
- VersionSelectDialog vselect(vlist.get(), tr("Select Forge version"), this);
- vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
- vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
- vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!"));
-
- auto currentVersion = m_profile->getComponentVersion("net.minecraftforge");
- if(!currentVersion.isEmpty())
- {
- vselect.setCurrentVersion(currentVersion);
- }
-
- if (vselect.exec() && vselect.selectedVersion())
- {
- auto vsn = vselect.selectedVersion();
- m_profile->setComponentVersion("net.minecraftforge", vsn->descriptor());
- m_profile->resolve(Net::Mode::Online);
- // m_profile->installVersion();
- preselect(m_profile->rowCount(QModelIndex())-1);
- m_container->refreshContainer();
- }
-}
-
-void VersionPage::on_actionInstall_Fabric_triggered()
-{
- auto vlist = ENV.metadataIndex()->get("net.fabricmc.fabric-loader");
- if(!vlist)
- {
- return;
- }
- VersionSelectDialog vselect(vlist.get(), tr("Select Fabric Loader version"), this);
- vselect.setEmptyString(tr("No Fabric Loader versions are currently available."));
- vselect.setEmptyErrorString(tr("Couldn't load or download the Fabric Loader version lists!"));
-
- auto currentVersion = m_profile->getComponentVersion("net.fabricmc.fabric-loader");
- if(!currentVersion.isEmpty())
- {
- vselect.setCurrentVersion(currentVersion);
- }
-
- if (vselect.exec() && vselect.selectedVersion())
- {
- auto vsn = vselect.selectedVersion();
- m_profile->setComponentVersion("net.fabricmc.fabric-loader", vsn->descriptor());
- m_profile->resolve(Net::Mode::Online);
- preselect(m_profile->rowCount(QModelIndex())-1);
- m_container->refreshContainer();
- }
-}
-
-void VersionPage::on_actionAdd_Empty_triggered()
-{
- NewComponentDialog compdialog(QString(), QString(), this);
- QStringList blacklist;
- for(int i = 0; i < m_profile->rowCount(); i++)
- {
- auto comp = m_profile->getComponent(i);
- blacklist.push_back(comp->getID());
- }
- compdialog.setBlacklist(blacklist);
- if (compdialog.exec())
- {
- qDebug() << "name:" << compdialog.name();
- qDebug() << "uid:" << compdialog.uid();
- m_profile->installEmpty(compdialog.uid(), compdialog.name());
- }
-}
-
-void VersionPage::on_actionInstall_LiteLoader_triggered()
-{
- auto vlist = ENV.metadataIndex()->get("com.mumfrey.liteloader");
- if(!vlist)
- {
- return;
- }
- VersionSelectDialog vselect(vlist.get(), tr("Select LiteLoader version"), this);
- vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft"));
- vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft"));
- vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!"));
-
- auto currentVersion = m_profile->getComponentVersion("com.mumfrey.liteloader");
- if(!currentVersion.isEmpty())
- {
- vselect.setCurrentVersion(currentVersion);
- }
-
- if (vselect.exec() && vselect.selectedVersion())
- {
- auto vsn = vselect.selectedVersion();
- m_profile->setComponentVersion("com.mumfrey.liteloader", vsn->descriptor());
- m_profile->resolve(Net::Mode::Online);
- // m_profile->installVersion(vselect.selectedVersion());
- preselect(m_profile->rowCount(QModelIndex())-1);
- m_container->refreshContainer();
- }
-}
-
-void VersionPage::on_actionLibrariesFolder_triggered()
-{
- DesktopServices::openDirectory(m_inst->getLocalLibraryPath(), true);
-}
-
-void VersionPage::on_actionMinecraftFolder_triggered()
-{
- DesktopServices::openDirectory(m_inst->gameRoot(), true);
-}
-
-void VersionPage::versionCurrent(const QModelIndex &current, const QModelIndex &previous)
-{
- currentIdx = current.row();
- updateButtons(currentIdx);
-}
-
-void VersionPage::preselect(int row)
-{
- if(row < 0)
- {
- row = 0;
- }
- if(row >= m_profile->rowCount(QModelIndex()))
- {
- row = m_profile->rowCount(QModelIndex()) - 1;
- }
- if(row < 0)
- {
- return;
- }
- auto model_index = m_profile->index(row);
- ui->packageView->selectionModel()->select(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
- updateButtons(row);
-}
-
-void VersionPage::onGameUpdateError(QString error)
-{
- CustomMessageBox::selectable(this, tr("Error updating instance"), error, QMessageBox::Warning)->show();
-}
-
-Component * VersionPage::current()
-{
- auto row = currentRow();
- if(row < 0)
- {
- return nullptr;
- }
- return m_profile->getComponent(row);
-}
-
-int VersionPage::currentRow()
-{
- if (ui->packageView->selectionModel()->selectedRows().isEmpty())
- {
- return -1;
- }
- return ui->packageView->selectionModel()->selectedRows().first().row();
-}
-
-void VersionPage::on_actionCustomize_triggered()
-{
- auto version = currentRow();
- if(version == -1)
- {
- return;
- }
- auto patch = m_profile->getComponent(version);
- if(!patch->getVersionFile())
- {
- // TODO: wait for the update task to finish here...
- return;
- }
- if(!m_profile->customize(version))
- {
- // TODO: some error box here
- }
- updateButtons();
- preselect(currentIdx);
-}
-
-void VersionPage::on_actionEdit_triggered()
-{
- auto version = current();
- if(!version)
- {
- return;
- }
- auto filename = version->getFilename();
- if(!QFileInfo::exists(filename))
- {
- qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!";
- return;
- }
- MMC->openJsonEditor(filename);
-}
-
-void VersionPage::on_actionRevert_triggered()
-{
- auto version = currentRow();
- if(version == -1)
- {
- return;
- }
- if(!m_profile->revertToBase(version))
- {
- // TODO: some error box here
- }
- updateButtons();
- preselect(currentIdx);
- m_container->refreshContainer();
-}
-
-void VersionPage::onFilterTextChanged(const QString &newContents)
-{
- m_filterModel->setFilterFixedString(newContents);
-}
-
-#include "VersionPage.moc"
-
diff --git a/application/pages/instance/VersionPage.h b/application/pages/instance/VersionPage.h
deleted file mode 100644
index b5b4a6f5..00000000
--- a/application/pages/instance/VersionPage.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Copyright 2013-2021 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 <QMainWindow>
-
-#include "minecraft/MinecraftInstance.h"
-#include "minecraft/PackProfile.h"
-#include "pages/BasePage.h"
-
-namespace Ui
-{
-class VersionPage;
-}
-
-class VersionPage : public QMainWindow, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit VersionPage(MinecraftInstance *inst, QWidget *parent = 0);
- virtual ~VersionPage();
- virtual QString displayName() const override
- {
- return tr("Version");
- }
- virtual QIcon icon() const override;
- virtual QString id() const override
- {
- return "version";
- }
- virtual QString helpPage() const override
- {
- return "Instance-Version";
- }
- virtual bool shouldDisplay() const override;
-
-private slots:
- void on_actionChange_version_triggered();
- void on_actionInstall_Forge_triggered();
- void on_actionInstall_Fabric_triggered();
- void on_actionAdd_Empty_triggered();
- void on_actionInstall_LiteLoader_triggered();
- void on_actionReload_triggered();
- void on_actionRemove_triggered();
- void on_actionMove_up_triggered();
- void on_actionMove_down_triggered();
- void on_actionAdd_to_Minecraft_jar_triggered();
- void on_actionReplace_Minecraft_jar_triggered();
- void on_actionRevert_triggered();
- void on_actionEdit_triggered();
- void on_actionInstall_mods_triggered();
- void on_actionCustomize_triggered();
- void on_actionDownload_All_triggered();
-
- void on_actionMinecraftFolder_triggered();
- void on_actionLibrariesFolder_triggered();
-
- void updateVersionControls();
-
-private:
- Component * current();
- int currentRow();
- void updateButtons(int row = -1);
- void preselect(int row = 0);
- int doUpdate();
-
-protected:
- QMenu * createPopupMenu() override;
-
- /// FIXME: this shouldn't be necessary!
- bool reloadPackProfile();
-
-private:
- Ui::VersionPage *ui;
- QSortFilterProxyModel *m_filterModel;
- std::shared_ptr<PackProfile> m_profile;
- MinecraftInstance *m_inst;
- int currentIdx = 0;
- bool controlsEnabled = false;
-
-public slots:
- void versionCurrent(const QModelIndex &current, const QModelIndex &previous);
-
-private slots:
- void updateRunningStatus(bool running);
- void onGameUpdateError(QString error);
- void packageCurrent(const QModelIndex &current, const QModelIndex &previous);
- void showContextMenu(const QPoint &pos);
- void onFilterTextChanged(const QString & newContents);
-};
diff --git a/application/pages/instance/VersionPage.ui b/application/pages/instance/VersionPage.ui
deleted file mode 100644
index 84d06e2e..00000000
--- a/application/pages/instance/VersionPage.ui
+++ /dev/null
@@ -1,285 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>VersionPage</class>
- <widget class="QMainWindow" name="VersionPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>961</width>
- <height>1091</height>
- </rect>
- </property>
- <widget class="QWidget" name="centralwidget">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="ModListView" name="packageView">
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOn</enum>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="sortingEnabled">
- <bool>false</bool>
- </property>
- <property name="headerHidden">
- <bool>false</bool>
- </property>
- <attribute name="headerVisible">
- <bool>true</bool>
- </attribute>
- </widget>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="1">
- <widget class="QLineEdit" name="filterEdit">
- <property name="clearButtonEnabled">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="filterLabel">
- <property name="text">
- <string>Filter:</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="MCModInfoFrame" name="frame">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <widget class="WideBar" name="toolBar">
- <property name="windowTitle">
- <string>Actions</string>
- </property>
- <property name="allowedAreas">
- <set>Qt::LeftToolBarArea|Qt::RightToolBarArea</set>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextOnly</enum>
- </property>
- <property name="floatable">
- <bool>false</bool>
- </property>
- <attribute name="toolBarArea">
- <enum>RightToolBarArea</enum>
- </attribute>
- <attribute name="toolBarBreak">
- <bool>false</bool>
- </attribute>
- <addaction name="actionChange_version"/>
- <addaction name="actionMove_up"/>
- <addaction name="actionMove_down"/>
- <addaction name="actionRemove"/>
- <addaction name="separator"/>
- <addaction name="actionCustomize"/>
- <addaction name="actionEdit"/>
- <addaction name="actionRevert"/>
- <addaction name="separator"/>
- <addaction name="actionInstall_Forge"/>
- <addaction name="actionInstall_Fabric"/>
- <addaction name="actionInstall_LiteLoader"/>
- <addaction name="actionInstall_mods"/>
- <addaction name="separator"/>
- <addaction name="actionAdd_to_Minecraft_jar"/>
- <addaction name="actionReplace_Minecraft_jar"/>
- <addaction name="actionAdd_Empty"/>
- <addaction name="separator"/>
- <addaction name="actionMinecraftFolder"/>
- <addaction name="actionLibrariesFolder"/>
- <addaction name="separator"/>
- <addaction name="actionReload"/>
- <addaction name="actionDownload_All"/>
- </widget>
- <action name="actionChange_version">
- <property name="text">
- <string>Change version</string>
- </property>
- <property name="toolTip">
- <string>Change version of the selected package.</string>
- </property>
- </action>
- <action name="actionMove_up">
- <property name="text">
- <string>Move up</string>
- </property>
- <property name="toolTip">
- <string>Make the selected package apply sooner.</string>
- </property>
- </action>
- <action name="actionMove_down">
- <property name="text">
- <string>Move down</string>
- </property>
- <property name="toolTip">
- <string>Make the selected package apply later.</string>
- </property>
- </action>
- <action name="actionRemove">
- <property name="text">
- <string>Remove</string>
- </property>
- <property name="toolTip">
- <string>Remove selected package from the instance.</string>
- </property>
- </action>
- <action name="actionCustomize">
- <property name="text">
- <string>Customize</string>
- </property>
- <property name="toolTip">
- <string>Customize selected package.</string>
- </property>
- </action>
- <action name="actionEdit">
- <property name="text">
- <string>Edit</string>
- </property>
- <property name="toolTip">
- <string>Edit selected package.</string>
- </property>
- </action>
- <action name="actionRevert">
- <property name="text">
- <string>Revert</string>
- </property>
- <property name="toolTip">
- <string>Revert the selected package to default.</string>
- </property>
- </action>
- <action name="actionInstall_Forge">
- <property name="text">
- <string>Install Forge</string>
- </property>
- <property name="toolTip">
- <string>Install the Minecraft Forge package.</string>
- </property>
- </action>
- <action name="actionInstall_Fabric">
- <property name="text">
- <string>Install Fabric</string>
- </property>
- <property name="toolTip">
- <string>Install the Fabric Loader package.</string>
- </property>
- </action>
- <action name="actionInstall_LiteLoader">
- <property name="text">
- <string>Install LiteLoader</string>
- </property>
- <property name="toolTip">
- <string>Install the LiteLoader package.</string>
- </property>
- </action>
- <action name="actionInstall_mods">
- <property name="text">
- <string>Install mods</string>
- </property>
- <property name="toolTip">
- <string>Install normal mods.</string>
- </property>
- </action>
- <action name="actionAdd_to_Minecraft_jar">
- <property name="text">
- <string>Add to Minecraft.jar</string>
- </property>
- <property name="toolTip">
- <string>Add a mod into the Minecraft jar file.</string>
- </property>
- </action>
- <action name="actionReplace_Minecraft_jar">
- <property name="text">
- <string>Replace Minecraft.jar</string>
- </property>
- </action>
- <action name="actionAdd_Empty">
- <property name="text">
- <string>Add Empty</string>
- </property>
- <property name="toolTip">
- <string>Add an empty custom package.</string>
- </property>
- </action>
- <action name="actionReload">
- <property name="text">
- <string>Reload</string>
- </property>
- <property name="toolTip">
- <string>Reload all packages.</string>
- </property>
- </action>
- <action name="actionDownload_All">
- <property name="text">
- <string>Download All</string>
- </property>
- <property name="toolTip">
- <string>Download the files needed to launch the instance now.</string>
- </property>
- </action>
- <action name="actionMinecraftFolder">
- <property name="text">
- <string>Open .minecraft</string>
- </property>
- <property name="toolTip">
- <string>Open the instance's .minecraft folder.</string>
- </property>
- </action>
- <action name="actionLibrariesFolder">
- <property name="text">
- <string>Open libraries</string>
- </property>
- <property name="toolTip">
- <string>Open the instance's local libraries folder.</string>
- </property>
- </action>
- </widget>
- <customwidgets>
- <customwidget>
- <class>ModListView</class>
- <extends>QTreeView</extends>
- <header>widgets/ModListView.h</header>
- </customwidget>
- <customwidget>
- <class>MCModInfoFrame</class>
- <extends>QFrame</extends>
- <header>widgets/MCModInfoFrame.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>WideBar</class>
- <extends>QToolBar</extends>
- <header>widgets/WideBar.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/instance/WorldListPage.cpp b/application/pages/instance/WorldListPage.cpp
deleted file mode 100644
index 119cff3e..00000000
--- a/application/pages/instance/WorldListPage.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/* Copyright 2015-2021 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 "WorldListPage.h"
-#include "ui_WorldListPage.h"
-#include "minecraft/WorldList.h"
-#include <DesktopServices.h>
-#include <QEvent>
-#include <QMenu>
-#include <QKeyEvent>
-#include <QClipboard>
-#include <QMessageBox>
-#include <QTreeView>
-#include <QInputDialog>
-#include <tools/MCEditTool.h>
-
-#include "MultiMC.h"
-#include <GuiUtil.h>
-#include <QProcess>
-#include <FileSystem.h>
-
-class WorldListProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-
-public:
- WorldListProxyModel(QObject *parent) : QSortFilterProxyModel(parent) {}
-
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
- {
- QModelIndex sourceIndex = mapToSource(index);
-
- if (index.column() == 0 && role == Qt::DecorationRole)
- {
- WorldList *worlds = qobject_cast<WorldList *>(sourceModel());
- auto iconFile = worlds->data(sourceIndex, WorldList::IconFileRole).toString();
- if(iconFile.isNull()) {
- // NOTE: Minecraft uses the same placeholder for servers AND worlds
- return MMC->getThemedIcon("unknown_server");
- }
- return QIcon(iconFile);
- }
-
- return sourceIndex.data(role);
- }
-};
-
-
-WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QWidget *parent)
- : QMainWindow(parent), m_inst(inst), ui(new Ui::WorldListPage), m_worlds(worlds)
-{
- ui->setupUi(this);
-
- ui->toolBar->insertSpacer(ui->actionRefresh);
-
- WorldListProxyModel * proxy = new WorldListProxyModel(this);
- proxy->setSortCaseSensitivity(Qt::CaseInsensitive);
- proxy->setSourceModel(m_worlds.get());
- ui->worldTreeView->setSortingEnabled(true);
- ui->worldTreeView->setModel(proxy);
- ui->worldTreeView->installEventFilter(this);
- ui->worldTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
- ui->worldTreeView->setIconSize(QSize(64,64));
- connect(ui->worldTreeView, &QTreeView::customContextMenuRequested, this, &WorldListPage::ShowContextMenu);
-
- auto head = ui->worldTreeView->header();
- head->setSectionResizeMode(0, QHeaderView::Stretch);
- head->setSectionResizeMode(1, QHeaderView::ResizeToContents);
-
- connect(ui->worldTreeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &WorldListPage::worldChanged);
- worldChanged(QModelIndex(), QModelIndex());
-}
-
-void WorldListPage::openedImpl()
-{
- m_worlds->startWatching();
-}
-
-void WorldListPage::closedImpl()
-{
- m_worlds->stopWatching();
-}
-
-WorldListPage::~WorldListPage()
-{
- m_worlds->stopWatching();
- delete ui;
-}
-
-void WorldListPage::ShowContextMenu(const QPoint& pos)
-{
- auto menu = ui->toolBar->createContextMenu(this, tr("Context menu"));
- menu->exec(ui->worldTreeView->mapToGlobal(pos));
- delete menu;
-}
-
-QMenu * WorldListPage::createPopupMenu()
-{
- QMenu* filteredMenu = QMainWindow::createPopupMenu();
- filteredMenu->removeAction( ui->toolBar->toggleViewAction() );
- return filteredMenu;
-}
-
-bool WorldListPage::shouldDisplay() const
-{
- return true;
-}
-
-bool WorldListPage::worldListFilter(QKeyEvent *keyEvent)
-{
- switch (keyEvent->key())
- {
- case Qt::Key_Delete:
- on_actionRemove_triggered();
- return true;
- default:
- break;
- }
- return QWidget::eventFilter(ui->worldTreeView, keyEvent);
-}
-
-bool WorldListPage::eventFilter(QObject *obj, QEvent *ev)
-{
- if (ev->type() != QEvent::KeyPress)
- {
- return QWidget::eventFilter(obj, ev);
- }
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
- if (obj == ui->worldTreeView)
- return worldListFilter(keyEvent);
- return QWidget::eventFilter(obj, ev);
-}
-
-void WorldListPage::on_actionRemove_triggered()
-{
- auto proxiedIndex = getSelectedWorld();
-
- if(!proxiedIndex.isValid())
- return;
-
- auto result = QMessageBox::question(this,
- tr("Are you sure?"),
- tr("This will remove the selected world permenantly.\n"
- "The world will be gone forever (A LONG TIME).\n"
- "\n"
- "Do you want to continue?"));
- if(result != QMessageBox::Yes)
- {
- return;
- }
- m_worlds->stopWatching();
- m_worlds->deleteWorld(proxiedIndex.row());
- m_worlds->startWatching();
-}
-
-void WorldListPage::on_actionView_Folder_triggered()
-{
- DesktopServices::openDirectory(m_worlds->dir().absolutePath(), true);
-}
-
-void WorldListPage::on_actionDatapacks_triggered()
-{
- QModelIndex index = getSelectedWorld();
-
- if (!index.isValid())
- {
- return;
- }
-
- if(!worldSafetyNagQuestion())
- return;
-
- auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();
-
- DesktopServices::openDirectory(FS::PathCombine(fullPath, "datapacks"), true);
-}
-
-
-void WorldListPage::on_actionReset_Icon_triggered()
-{
- auto proxiedIndex = getSelectedWorld();
-
- if(!proxiedIndex.isValid())
- return;
-
- if(m_worlds->resetIcon(proxiedIndex.row())) {
- ui->actionReset_Icon->setEnabled(false);
- }
-}
-
-
-QModelIndex WorldListPage::getSelectedWorld()
-{
- auto index = ui->worldTreeView->selectionModel()->currentIndex();
-
- auto proxy = (QSortFilterProxyModel *) ui->worldTreeView->model();
- return proxy->mapToSource(index);
-}
-
-void WorldListPage::on_actionCopy_Seed_triggered()
-{
- QModelIndex index = getSelectedWorld();
-
- if (!index.isValid())
- {
- return;
- }
- int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong();
- MMC->clipboard()->setText(QString::number(seed));
-}
-
-void WorldListPage::on_actionMCEdit_triggered()
-{
- if(m_mceditStarting)
- return;
-
- auto mcedit = MMC->mcedit();
-
- const QString mceditPath = mcedit->path();
-
- QModelIndex index = getSelectedWorld();
-
- if (!index.isValid())
- {
- return;
- }
-
- if(!worldSafetyNagQuestion())
- return;
-
- auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();
-
- auto program = mcedit->getProgramPath();
- if(program.size())
- {
-#ifdef Q_OS_WIN32
- if(!QProcess::startDetached(program, {fullPath}, mceditPath))
- {
- mceditError();
- }
-#else
- m_mceditProcess.reset(new LoggedProcess());
- m_mceditProcess->setDetachable(true);
- connect(m_mceditProcess.get(), &LoggedProcess::stateChanged, this, &WorldListPage::mceditState);
- m_mceditProcess->start(program, {fullPath});
- m_mceditProcess->setWorkingDirectory(mceditPath);
- m_mceditStarting = true;
-#endif
- }
- else
- {
- QMessageBox::warning(
- this->parentWidget(),
- tr("No MCEdit found or set up!"),
- tr("You do not have MCEdit set up or it was moved.\nYou can set it up in the global settings.")
- );
- }
-}
-
-void WorldListPage::mceditError()
-{
- QMessageBox::warning(
- this->parentWidget(),
- tr("MCEdit failed to start!"),
- tr("MCEdit failed to start.\nIt may be necessary to reinstall it.")
- );
-}
-
-void WorldListPage::mceditState(LoggedProcess::State state)
-{
- bool failed = false;
- switch(state)
- {
- case LoggedProcess::NotRunning:
- case LoggedProcess::Starting:
- return;
- case LoggedProcess::FailedToStart:
- case LoggedProcess::Crashed:
- case LoggedProcess::Aborted:
- {
- failed = true;
- }
- case LoggedProcess::Running:
- case LoggedProcess::Finished:
- {
- m_mceditStarting = false;
- break;
- }
- }
- if(failed)
- {
- mceditError();
- }
-}
-
-void WorldListPage::worldChanged(const QModelIndex &current, const QModelIndex &previous)
-{
- QModelIndex index = getSelectedWorld();
- bool enable = index.isValid();
- ui->actionCopy_Seed->setEnabled(enable);
- ui->actionMCEdit->setEnabled(enable);
- ui->actionRemove->setEnabled(enable);
- ui->actionCopy->setEnabled(enable);
- ui->actionRename->setEnabled(enable);
- ui->actionDatapacks->setEnabled(enable);
- bool hasIcon = !index.data(WorldList::IconFileRole).isNull();
- ui->actionReset_Icon->setEnabled(enable && hasIcon);
-}
-
-void WorldListPage::on_actionAdd_triggered()
-{
- auto list = GuiUtil::BrowseForFiles(
- displayName(),
- tr("Select a Minecraft world zip"),
- tr("Minecraft World Zip File (*.zip)"), QString(), this->parentWidget());
- if (!list.empty())
- {
- m_worlds->stopWatching();
- for (auto filename : list)
- {
- m_worlds->installWorld(QFileInfo(filename));
- }
- m_worlds->startWatching();
- }
-}
-
-bool WorldListPage::isWorldSafe(QModelIndex)
-{
- return !m_inst->isRunning();
-}
-
-bool WorldListPage::worldSafetyNagQuestion()
-{
- if(!isWorldSafe(getSelectedWorld()))
- {
- auto result = QMessageBox::question(this, tr("Copy World"), tr("Changing a world while Minecraft is running is potentially unsafe.\nDo you wish to proceed?"));
- if(result == QMessageBox::No)
- {
- return false;
- }
- }
- return true;
-}
-
-
-void WorldListPage::on_actionCopy_triggered()
-{
- QModelIndex index = getSelectedWorld();
- if (!index.isValid())
- {
- return;
- }
-
- if(!worldSafetyNagQuestion())
- return;
-
- auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
- auto world = (World *) worldVariant.value<void *>();
- bool ok = false;
- QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new name for the copy."), QLineEdit::Normal, world->name(), &ok);
-
- if (ok && name.length() > 0)
- {
- world->install(m_worlds->dir().absolutePath(), name);
- }
-}
-
-void WorldListPage::on_actionRename_triggered()
-{
- QModelIndex index = getSelectedWorld();
- if (!index.isValid())
- {
- return;
- }
-
- if(!worldSafetyNagQuestion())
- return;
-
- auto worldVariant = m_worlds->data(index, WorldList::ObjectRole);
- auto world = (World *) worldVariant.value<void *>();
-
- bool ok = false;
- QString name = QInputDialog::getText(this, tr("World name"), tr("Enter a new world name."), QLineEdit::Normal, world->name(), &ok);
-
- if (ok && name.length() > 0)
- {
- world->rename(name);
- }
-}
-
-void WorldListPage::on_actionRefresh_triggered()
-{
- m_worlds->update();
-}
-
-#include "WorldListPage.moc"
diff --git a/application/pages/instance/WorldListPage.h b/application/pages/instance/WorldListPage.h
deleted file mode 100644
index 4fc9aa09..00000000
--- a/application/pages/instance/WorldListPage.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Copyright 2015-2021 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 <QMainWindow>
-
-#include "minecraft/MinecraftInstance.h"
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include <LoggedProcess.h>
-
-class WorldList;
-namespace Ui
-{
-class WorldListPage;
-}
-
-class WorldListPage : public QMainWindow, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit WorldListPage(
- BaseInstance *inst,
- std::shared_ptr<WorldList> worlds,
- QWidget *parent = 0
- );
- virtual ~WorldListPage();
-
- virtual QString displayName() const override
- {
- return tr("Worlds");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("worlds");
- }
- virtual QString id() const override
- {
- return "worlds";
- }
- virtual QString helpPage() const override
- {
- return "Worlds";
- }
- virtual bool shouldDisplay() const override;
-
- virtual void openedImpl() override;
- virtual void closedImpl() override;
-
-protected:
- bool eventFilter(QObject *obj, QEvent *ev) override;
- bool worldListFilter(QKeyEvent *ev);
- QMenu * createPopupMenu() override;
-
-protected:
- BaseInstance *m_inst;
-
-private:
- QModelIndex getSelectedWorld();
- bool isWorldSafe(QModelIndex index);
- bool worldSafetyNagQuestion();
- void mceditError();
-
-private:
- Ui::WorldListPage *ui;
- std::shared_ptr<WorldList> m_worlds;
- unique_qobject_ptr<LoggedProcess> m_mceditProcess;
- bool m_mceditStarting = false;
-
-private slots:
- void on_actionCopy_Seed_triggered();
- void on_actionMCEdit_triggered();
- void on_actionRemove_triggered();
- void on_actionAdd_triggered();
- void on_actionCopy_triggered();
- void on_actionRename_triggered();
- void on_actionRefresh_triggered();
- void on_actionView_Folder_triggered();
- void on_actionDatapacks_triggered();
- void on_actionReset_Icon_triggered();
- void worldChanged(const QModelIndex &current, const QModelIndex &previous);
- void mceditState(LoggedProcess::State state);
-
- void ShowContextMenu(const QPoint &pos);
-};
diff --git a/application/pages/instance/WorldListPage.ui b/application/pages/instance/WorldListPage.ui
deleted file mode 100644
index ed078d94..00000000
--- a/application/pages/instance/WorldListPage.ui
+++ /dev/null
@@ -1,161 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>WorldListPage</class>
- <widget class="QMainWindow" name="WorldListPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>800</width>
- <height>600</height>
- </rect>
- </property>
- <widget class="QWidget" name="centralwidget">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTreeView" name="worldTreeView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="acceptDrops">
- <bool>true</bool>
- </property>
- <property name="dragDropMode">
- <enum>QAbstractItemView::DragDrop</enum>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <property name="itemsExpandable">
- <bool>false</bool>
- </property>
- <property name="sortingEnabled">
- <bool>true</bool>
- </property>
- <property name="allColumnsShowFocus">
- <bool>true</bool>
- </property>
- <attribute name="headerStretchLastSection">
- <bool>false</bool>
- </attribute>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="WideBar" name="toolBar">
- <property name="windowTitle">
- <string>Actions</string>
- </property>
- <property name="allowedAreas">
- <set>Qt::LeftToolBarArea|Qt::RightToolBarArea</set>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextOnly</enum>
- </property>
- <property name="floatable">
- <bool>false</bool>
- </property>
- <attribute name="toolBarArea">
- <enum>RightToolBarArea</enum>
- </attribute>
- <attribute name="toolBarBreak">
- <bool>false</bool>
- </attribute>
- <addaction name="actionAdd"/>
- <addaction name="separator"/>
- <addaction name="actionRename"/>
- <addaction name="actionCopy"/>
- <addaction name="actionRemove"/>
- <addaction name="actionMCEdit"/>
- <addaction name="actionDatapacks"/>
- <addaction name="actionReset_Icon"/>
- <addaction name="separator"/>
- <addaction name="actionCopy_Seed"/>
- <addaction name="actionRefresh"/>
- <addaction name="actionView_Folder"/>
- </widget>
- <action name="actionAdd">
- <property name="text">
- <string>Add</string>
- </property>
- </action>
- <action name="actionRename">
- <property name="text">
- <string>Rename</string>
- </property>
- </action>
- <action name="actionCopy">
- <property name="text">
- <string>Copy</string>
- </property>
- </action>
- <action name="actionRemove">
- <property name="text">
- <string>Remove</string>
- </property>
- </action>
- <action name="actionMCEdit">
- <property name="text">
- <string>MCEdit</string>
- </property>
- </action>
- <action name="actionCopy_Seed">
- <property name="text">
- <string>Copy Seed</string>
- </property>
- </action>
- <action name="actionRefresh">
- <property name="text">
- <string>Refresh</string>
- </property>
- </action>
- <action name="actionView_Folder">
- <property name="text">
- <string>View Folder</string>
- </property>
- </action>
- <action name="actionReset_Icon">
- <property name="text">
- <string>Reset Icon</string>
- </property>
- <property name="toolTip">
- <string>Remove world icon to make the game re-generate it on next load.</string>
- </property>
- </action>
- <action name="actionDatapacks">
- <property name="text">
- <string>Datapacks</string>
- </property>
- <property name="toolTip">
- <string>Manage datapacks inside the world.</string>
- </property>
- </action>
- </widget>
- <customwidgets>
- <customwidget>
- <class>WideBar</class>
- <extends>QToolBar</extends>
- <header>widgets/WideBar.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/modplatform/ImportPage.cpp b/application/pages/modplatform/ImportPage.cpp
deleted file mode 100644
index c2369bdc..00000000
--- a/application/pages/modplatform/ImportPage.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-#include "ImportPage.h"
-#include "ui_ImportPage.h"
-
-#include "MultiMC.h"
-#include "dialogs/NewInstanceDialog.h"
-#include <QFileDialog>
-#include <QValidator>
-#include <InstanceImportTask.h>
-
-class UrlValidator : public QValidator
-{
-public:
- using QValidator::QValidator;
-
- State validate(QString &in, int &pos) const
- {
- const QUrl url(in);
- if (url.isValid() && !url.isRelative() && !url.isEmpty())
- {
- return Acceptable;
- }
- else if (QFile::exists(in))
- {
- return Acceptable;
- }
- else
- {
- return Intermediate;
- }
- }
-};
-
-ImportPage::ImportPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::ImportPage), dialog(dialog)
-{
- ui->setupUi(this);
- ui->modpackEdit->setValidator(new UrlValidator(ui->modpackEdit));
- connect(ui->modpackEdit, &QLineEdit::textChanged, this, &ImportPage::updateState);
-}
-
-ImportPage::~ImportPage()
-{
- delete ui;
-}
-
-bool ImportPage::shouldDisplay() const
-{
- return true;
-}
-
-void ImportPage::openedImpl()
-{
- updateState();
-}
-
-void ImportPage::updateState()
-{
- if(!isOpened)
- {
- return;
- }
- if(ui->modpackEdit->hasAcceptableInput())
- {
- QString input = ui->modpackEdit->text();
- auto url = QUrl::fromUserInput(input);
- if(url.isLocalFile())
- {
- // FIXME: actually do some validation of what's inside here... this is fake AF
- QFileInfo fi(input);
- if(fi.exists() && fi.suffix() == "zip")
- {
- QFileInfo fi(url.fileName());
- dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
- dialog->setSuggestedIcon("default");
- }
- }
- else
- {
- if(input.endsWith("?client=y")) {
- input.chop(9);
- input.append("/file");
- url = QUrl::fromUserInput(input);
- }
- // hook, line and sinker.
- QFileInfo fi(url.fileName());
- dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url));
- dialog->setSuggestedIcon("default");
- }
- }
- else
- {
- dialog->setSuggestedPack();
- }
-}
-
-void ImportPage::setUrl(const QString& url)
-{
- ui->modpackEdit->setText(url);
- updateState();
-}
-
-void ImportPage::on_modpackBtn_clicked()
-{
- const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), tr("Zip (*.zip)"));
- if (url.isValid())
- {
- if (url.isLocalFile())
- {
- ui->modpackEdit->setText(url.toLocalFile());
- }
- else
- {
- ui->modpackEdit->setText(url.toString());
- }
- }
-}
-
-
-QUrl ImportPage::modpackUrl() const
-{
- const QUrl url(ui->modpackEdit->text());
- if (url.isValid() && !url.isRelative() && !url.host().isEmpty())
- {
- return url;
- }
- else
- {
- return QUrl::fromLocalFile(ui->modpackEdit->text());
- }
-}
diff --git a/application/pages/modplatform/ImportPage.h b/application/pages/modplatform/ImportPage.h
deleted file mode 100644
index 67e3c201..00000000
--- a/application/pages/modplatform/ImportPage.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "tasks/Task.h"
-
-namespace Ui
-{
-class ImportPage;
-}
-
-class NewInstanceDialog;
-
-class ImportPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit ImportPage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~ImportPage();
- virtual QString displayName() const override
- {
- return tr("Import from zip");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("viewfolder");
- }
- virtual QString id() const override
- {
- return "import";
- }
- virtual QString helpPage() const override
- {
- return "Zip-import";
- }
- virtual bool shouldDisplay() const override;
-
- void setUrl(const QString & url);
- void openedImpl() override;
-
-private slots:
- void on_modpackBtn_clicked();
- void updateState();
-
-private:
- QUrl modpackUrl() const;
-
-private:
- Ui::ImportPage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
-};
-
diff --git a/application/pages/modplatform/ImportPage.ui b/application/pages/modplatform/ImportPage.ui
deleted file mode 100644
index eb63cbe9..00000000
--- a/application/pages/modplatform/ImportPage.ui
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>ImportPage</class>
- <widget class="QWidget" name="ImportPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>546</width>
- <height>405</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="1">
- <widget class="QPushButton" name="modpackBtn">
- <property name="text">
- <string>Browse</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLineEdit" name="modpackEdit">
- <property name="placeholderText">
- <string notr="true">http://</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="2">
- <widget class="QLabel" name="modpackLabel">
- <property name="text">
- <string>Local file or link to a direct download:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="2">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/modplatform/VanillaPage.cpp b/application/pages/modplatform/VanillaPage.cpp
deleted file mode 100644
index 02638315..00000000
--- a/application/pages/modplatform/VanillaPage.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "VanillaPage.h"
-#include "ui_VanillaPage.h"
-
-#include "MultiMC.h"
-
-#include <meta/Index.h>
-#include <meta/VersionList.h>
-#include <dialogs/NewInstanceDialog.h>
-#include <Filter.h>
-#include <Env.h>
-#include <InstanceCreationTask.h>
-#include <QTabBar>
-
-VanillaPage::VanillaPage(NewInstanceDialog *dialog, QWidget *parent)
- : QWidget(parent), dialog(dialog), ui(new Ui::VanillaPage)
-{
- ui->setupUi(this);
- ui->tabWidget->tabBar()->hide();
- connect(ui->versionList, &VersionSelectWidget::selectedVersionChanged, this, &VanillaPage::setSelectedVersion);
- filterChanged();
- connect(ui->alphaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->betaFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->snapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->oldSnapshotFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->releaseFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->experimentsFilter, &QCheckBox::stateChanged, this, &VanillaPage::filterChanged);
- connect(ui->refreshBtn, &QPushButton::clicked, this, &VanillaPage::refresh);
-}
-
-void VanillaPage::openedImpl()
-{
- if(!initialized)
- {
- auto vlist = ENV.metadataIndex()->get("net.minecraft");
- ui->versionList->initialize(vlist.get());
- initialized = true;
- }
- else
- {
- suggestCurrent();
- }
-}
-
-void VanillaPage::refresh()
-{
- ui->versionList->loadList();
-}
-
-void VanillaPage::filterChanged()
-{
- QStringList out;
- if(ui->alphaFilter->isChecked())
- out << "(old_alpha)";
- if(ui->betaFilter->isChecked())
- out << "(old_beta)";
- if(ui->snapshotFilter->isChecked())
- out << "(snapshot)";
- if(ui->oldSnapshotFilter->isChecked())
- out << "(old_snapshot)";
- if(ui->releaseFilter->isChecked())
- out << "(release)";
- if(ui->experimentsFilter->isChecked())
- out << "(experiment)";
- auto regexp = out.join('|');
- ui->versionList->setFilter(BaseVersionList::TypeRole, new RegexpFilter(regexp, false));
-}
-
-VanillaPage::~VanillaPage()
-{
- delete ui;
-}
-
-bool VanillaPage::shouldDisplay() const
-{
- return true;
-}
-
-BaseVersionPtr VanillaPage::selectedVersion() const
-{
- return m_selectedVersion;
-}
-
-void VanillaPage::suggestCurrent()
-{
- if (!isOpened)
- {
- return;
- }
-
- if(!m_selectedVersion)
- {
- dialog->setSuggestedPack();
- return;
- }
-
- dialog->setSuggestedPack(m_selectedVersion->descriptor(), new InstanceCreationTask(m_selectedVersion));
- dialog->setSuggestedIcon("default");
-}
-
-void VanillaPage::setSelectedVersion(BaseVersionPtr version)
-{
- m_selectedVersion = version;
- suggestCurrent();
-}
diff --git a/application/pages/modplatform/VanillaPage.h b/application/pages/modplatform/VanillaPage.h
deleted file mode 100644
index af6fd392..00000000
--- a/application/pages/modplatform/VanillaPage.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "tasks/Task.h"
-
-namespace Ui
-{
-class VanillaPage;
-}
-
-class NewInstanceDialog;
-
-class VanillaPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit VanillaPage(NewInstanceDialog *dialog, QWidget *parent = 0);
- virtual ~VanillaPage();
- virtual QString displayName() const override
- {
- return tr("Vanilla");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("minecraft");
- }
- virtual QString id() const override
- {
- return "vanilla";
- }
- virtual QString helpPage() const override
- {
- return "Vanilla-platform";
- }
- virtual bool shouldDisplay() const override;
- void openedImpl() override;
-
- BaseVersionPtr selectedVersion() const;
-
-public slots:
- void setSelectedVersion(BaseVersionPtr version);
-
-private slots:
- void filterChanged();
-
-private:
- void refresh();
- void suggestCurrent();
-
-private:
- bool initialized = false;
- NewInstanceDialog *dialog = nullptr;
- Ui::VanillaPage *ui = nullptr;
- bool m_versionSetByUser = false;
- BaseVersionPtr m_selectedVersion;
-};
diff --git a/application/pages/modplatform/VanillaPage.ui b/application/pages/modplatform/VanillaPage.ui
deleted file mode 100644
index 47effc86..00000000
--- a/application/pages/modplatform/VanillaPage.ui
+++ /dev/null
@@ -1,169 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>VanillaPage</class>
- <widget class="QWidget" name="VanillaPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>815</width>
- <height>607</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string notr="true"/>
- </attribute>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="1">
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Filter</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="releaseFilter">
- <property name="text">
- <string>Releases</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="snapshotFilter">
- <property name="text">
- <string>Snapshots</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="oldSnapshotFilter">
- <property name="text">
- <string>Old Snapshots</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="betaFilter">
- <property name="text">
- <string>Betas</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="alphaFilter">
- <property name="text">
- <string>Alphas</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="experimentsFilter">
- <property name="text">
- <string>Experiments</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="refreshBtn">
- <property name="text">
- <string>Refresh</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="0">
- <widget class="VersionSelectWidget" name="versionList" native="true">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>VersionSelectWidget</class>
- <extends>QWidget</extends>
- <header>widgets/VersionSelectWidget.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>tabWidget</tabstop>
- <tabstop>releaseFilter</tabstop>
- <tabstop>snapshotFilter</tabstop>
- <tabstop>oldSnapshotFilter</tabstop>
- <tabstop>betaFilter</tabstop>
- <tabstop>alphaFilter</tabstop>
- <tabstop>experimentsFilter</tabstop>
- <tabstop>refreshBtn</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/modplatform/atlauncher/AtlFilterModel.cpp b/application/pages/modplatform/atlauncher/AtlFilterModel.cpp
deleted file mode 100644
index b5d8f22b..00000000
--- a/application/pages/modplatform/atlauncher/AtlFilterModel.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-#include "AtlFilterModel.h"
-
-#include <QDebug>
-
-#include <modplatform/atlauncher/ATLPackIndex.h>
-#include <Version.h>
-#include <MMCStrings.h>
-
-namespace Atl {
-
-FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent)
-{
- currentSorting = Sorting::ByPopularity;
- sortings.insert(tr("Sort by popularity"), Sorting::ByPopularity);
- sortings.insert(tr("Sort by name"), Sorting::ByName);
- sortings.insert(tr("Sort by game version"), Sorting::ByGameVersion);
-
- searchTerm = "";
-}
-
-const QMap<QString, FilterModel::Sorting> FilterModel::getAvailableSortings()
-{
- return sortings;
-}
-
-QString FilterModel::translateCurrentSorting()
-{
- return sortings.key(currentSorting);
-}
-
-void FilterModel::setSorting(Sorting sorting)
-{
- currentSorting = sorting;
- invalidate();
-}
-
-FilterModel::Sorting FilterModel::getCurrentSorting()
-{
- return currentSorting;
-}
-
-void FilterModel::setSearchTerm(const QString term)
-{
- searchTerm = term.trimmed();
- invalidate();
-}
-
-bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
-{
- if (searchTerm.isEmpty()) {
- return true;
- }
-
- QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
- ATLauncher::IndexedPack pack = sourceModel()->data(index, Qt::UserRole).value<ATLauncher::IndexedPack>();
- return pack.name.contains(searchTerm, Qt::CaseInsensitive);
-}
-
-bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
-{
- ATLauncher::IndexedPack leftPack = sourceModel()->data(left, Qt::UserRole).value<ATLauncher::IndexedPack>();
- ATLauncher::IndexedPack rightPack = sourceModel()->data(right, Qt::UserRole).value<ATLauncher::IndexedPack>();
-
- if (currentSorting == ByPopularity) {
- return leftPack.position > rightPack.position;
- }
- else if (currentSorting == ByGameVersion) {
- Version lv(leftPack.versions.at(0).minecraft);
- Version rv(rightPack.versions.at(0).minecraft);
- return lv < rv;
- }
- else if (currentSorting == ByName) {
- return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0;
- }
-
- // Invalid sorting set, somehow...
- qWarning() << "Invalid sorting set!";
- return true;
-}
-
-}
diff --git a/application/pages/modplatform/atlauncher/AtlFilterModel.h b/application/pages/modplatform/atlauncher/AtlFilterModel.h
deleted file mode 100644
index bd72ad91..00000000
--- a/application/pages/modplatform/atlauncher/AtlFilterModel.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-
-#include <QtCore/QSortFilterProxyModel>
-
-namespace Atl {
-
-class FilterModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- FilterModel(QObject* parent = Q_NULLPTR);
- enum Sorting {
- ByPopularity,
- ByGameVersion,
- ByName,
- };
- const QMap<QString, Sorting> getAvailableSortings();
- QString translateCurrentSorting();
- void setSorting(Sorting sorting);
- Sorting getCurrentSorting();
- void setSearchTerm(QString term);
-
-protected:
- bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
- bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
-
-private:
- QMap<QString, Sorting> sortings;
- Sorting currentSorting;
- QString searchTerm;
-
-};
-
-}
diff --git a/application/pages/modplatform/atlauncher/AtlListModel.cpp b/application/pages/modplatform/atlauncher/AtlListModel.cpp
deleted file mode 100644
index f3be6198..00000000
--- a/application/pages/modplatform/atlauncher/AtlListModel.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-#include "AtlListModel.h"
-
-#include <BuildConfig.h>
-#include <MultiMC.h>
-#include <Env.h>
-#include <Json.h>
-
-namespace Atl {
-
-ListModel::ListModel(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-ListModel::~ListModel()
-{
-}
-
-int ListModel::rowCount(const QModelIndex &parent) const
-{
- return modpacks.size();
-}
-
-int ListModel::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-QVariant ListModel::data(const QModelIndex &index, int role) const
-{
- int pos = index.row();
- if(pos >= modpacks.size() || pos < 0 || !index.isValid())
- {
- return QString("INVALID INDEX %1").arg(pos);
- }
-
- ATLauncher::IndexedPack pack = modpacks.at(pos);
- if(role == Qt::DisplayRole)
- {
- return pack.name;
- }
- else if (role == Qt::ToolTipRole)
- {
- return pack.name;
- }
- else if(role == Qt::DecorationRole)
- {
- if(m_logoMap.contains(pack.safeName))
- {
- return (m_logoMap.value(pack.safeName));
- }
- auto icon = MMC->getThemedIcon("atlauncher-placeholder");
-
- auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(pack.safeName.toLower());
- ((ListModel *)this)->requestLogo(pack.safeName, url);
-
- return icon;
- }
- else if(role == Qt::UserRole)
- {
- QVariant v;
- v.setValue(pack);
- return v;
- }
-
- return QVariant();
-}
-
-void ListModel::request()
-{
- beginResetModel();
- modpacks.clear();
- endResetModel();
-
- auto *netJob = new NetJob("Atl::Request");
- auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/json/packsnew.json");
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response));
- jobPtr = netJob;
- jobPtr->start();
-
- QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::requestFinished);
- QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed);
-}
-
-void ListModel::requestFinished()
-{
- jobPtr.reset();
-
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from ATL at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
- return;
- }
-
- QList<ATLauncher::IndexedPack> newList;
-
- auto packs = doc.array();
- for(auto packRaw : packs) {
- auto packObj = packRaw.toObject();
-
- ATLauncher::IndexedPack pack;
-
- try {
- ATLauncher::loadIndexedPack(pack, packObj);
- }
- catch (const JSONValidationError &e) {
- qDebug() << QString::fromUtf8(response);
- qWarning() << "Error while reading pack manifest from ATLauncher: " << e.cause();
- return;
- }
-
- // ignore packs without a published version
- if(pack.versions.length() == 0) continue;
- // only display public packs (for now)
- if(pack.type != ATLauncher::PackType::Public) continue;
- // ignore "system" packs (Vanilla, Vanilla with Forge, etc)
- if(pack.system) continue;
-
- newList.append(pack);
- }
-
- beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + newList.size() - 1);
- modpacks.append(newList);
- endInsertRows();
-}
-
-void ListModel::requestFailed(QString reason)
-{
- jobPtr.reset();
-}
-
-void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback)
-{
- if(m_logoMap.contains(logo))
- {
- callback(ENV.metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath());
- }
- else
- {
- requestLogo(logo, logoUrl);
- }
-}
-
-void ListModel::logoFailed(QString logo)
-{
- m_failedLogos.append(logo);
- m_loadingLogos.removeAll(logo);
-}
-
-void ListModel::logoLoaded(QString logo, QIcon out)
-{
- m_loadingLogos.removeAll(logo);
- m_logoMap.insert(logo, out);
-
- for(int i = 0; i < modpacks.size(); i++) {
- if(modpacks[i].safeName == logo) {
- emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole});
- }
- }
-}
-
-void ListModel::requestLogo(QString file, QString url)
-{
- if(m_loadingLogos.contains(file) || m_failedLogos.contains(file))
- {
- return;
- }
-
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file.section(".", 0, 0)));
- NetJob *job = new NetJob(QString("ATLauncher Icon Download %1").arg(file));
- job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
-
- auto fullPath = entry->getFullPath();
- QObject::connect(job, &NetJob::succeeded, this, [this, file, fullPath]
- {
- emit logoLoaded(file, QIcon(fullPath));
- if(waitingCallbacks.contains(file))
- {
- waitingCallbacks.value(file)(fullPath);
- }
- });
-
- QObject::connect(job, &NetJob::failed, this, [this, file]
- {
- emit logoFailed(file);
- });
-
- job->start();
-
- m_loadingLogos.append(file);
-}
-
-}
diff --git a/application/pages/modplatform/atlauncher/AtlListModel.h b/application/pages/modplatform/atlauncher/AtlListModel.h
deleted file mode 100644
index 2d30a64e..00000000
--- a/application/pages/modplatform/atlauncher/AtlListModel.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#pragma once
-
-#include <QAbstractListModel>
-
-#include "net/NetJob.h"
-#include <QIcon>
-#include <modplatform/atlauncher/ATLPackIndex.h>
-
-namespace Atl {
-
-typedef QMap<QString, QIcon> LogoMap;
-typedef std::function<void(QString)> LogoCallback;
-
-class ListModel : public QAbstractListModel
-{
- Q_OBJECT
-
-public:
- ListModel(QObject *parent);
- virtual ~ListModel();
-
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
-
- void request();
-
- void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback);
-
-private slots:
- void requestFinished();
- void requestFailed(QString reason);
-
- void logoFailed(QString logo);
- void logoLoaded(QString logo, QIcon out);
-
-private:
- void requestLogo(QString file, QString url);
-
-private:
- QList<ATLauncher::IndexedPack> modpacks;
-
- QStringList m_failedLogos;
- QStringList m_loadingLogos;
- LogoMap m_logoMap;
- QMap<QString, LogoCallback> waitingCallbacks;
-
- NetJobPtr jobPtr;
- QByteArray response;
-};
-
-}
diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
deleted file mode 100644
index 14bbd18b..00000000
--- a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-#include "AtlOptionalModDialog.h"
-#include "ui_AtlOptionalModDialog.h"
-
-AtlOptionalModListModel::AtlOptionalModListModel(QWidget *parent, QVector<ATLauncher::VersionMod> mods)
- : QAbstractListModel(parent), m_mods(mods) {
-
- // fill mod index
- for (int i = 0; i < m_mods.size(); i++) {
- auto mod = m_mods.at(i);
- m_index[mod.name] = i;
- }
- // set initial state
- for (int i = 0; i < m_mods.size(); i++) {
- auto mod = m_mods.at(i);
- m_selection[mod.name] = false;
- setMod(mod, i, mod.selected, false);
- }
-}
-
-QVector<QString> AtlOptionalModListModel::getResult() {
- QVector<QString> result;
-
- for (const auto& mod : m_mods) {
- if (m_selection[mod.name]) {
- result.push_back(mod.name);
- }
- }
-
- return result;
-}
-
-int AtlOptionalModListModel::rowCount(const QModelIndex &parent) const {
- return m_mods.size();
-}
-
-int AtlOptionalModListModel::columnCount(const QModelIndex &parent) const {
- // Enabled, Name, Description
- return 3;
-}
-
-QVariant AtlOptionalModListModel::data(const QModelIndex &index, int role) const {
- auto row = index.row();
- auto mod = m_mods.at(row);
-
- if (role == Qt::DisplayRole) {
- if (index.column() == NameColumn) {
- return mod.name;
- }
- if (index.column() == DescriptionColumn) {
- return mod.description;
- }
- }
- else if (role == Qt::ToolTipRole) {
- if (index.column() == DescriptionColumn) {
- return mod.description;
- }
- }
- else if (role == Qt::CheckStateRole) {
- if (index.column() == EnabledColumn) {
- return m_selection[mod.name] ? Qt::Checked : Qt::Unchecked;
- }
- }
-
- return QVariant();
-}
-
-bool AtlOptionalModListModel::setData(const QModelIndex &index, const QVariant &value, int role) {
- if (role == Qt::CheckStateRole) {
- auto row = index.row();
- auto mod = m_mods.at(row);
-
- toggleMod(mod, row);
- return true;
- }
-
- return false;
-}
-
-QVariant AtlOptionalModListModel::headerData(int section, Qt::Orientation orientation, int role) const {
- if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
- switch (section) {
- case EnabledColumn:
- return QString();
- case NameColumn:
- return QString("Name");
- case DescriptionColumn:
- return QString("Description");
- }
- }
-
- return QVariant();
-}
-
-Qt::ItemFlags AtlOptionalModListModel::flags(const QModelIndex &index) const {
- auto flags = QAbstractListModel::flags(index);
- if (index.isValid() && index.column() == EnabledColumn) {
- flags |= Qt::ItemIsUserCheckable;
- }
- return flags;
-}
-
-void AtlOptionalModListModel::selectRecommended() {
- for (const auto& mod : m_mods) {
- m_selection[mod.name] = mod.recommended;
- }
-
- emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn),
- AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn));
-}
-
-void AtlOptionalModListModel::clearAll() {
- for (const auto& mod : m_mods) {
- m_selection[mod.name] = false;
- }
-
- emit dataChanged(AtlOptionalModListModel::index(0, EnabledColumn),
- AtlOptionalModListModel::index(m_mods.size() - 1, EnabledColumn));
-}
-
-void AtlOptionalModListModel::toggleMod(ATLauncher::VersionMod mod, int index) {
- setMod(mod, index, !m_selection[mod.name]);
-}
-
-void AtlOptionalModListModel::setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit) {
- if (m_selection[mod.name] == enable) return;
-
- m_selection[mod.name] = enable;
-
- // disable other mods in the group, if applicable
- if (enable && !mod.group.isEmpty()) {
- for (int i = 0; i < m_mods.size(); i++) {
- if (index == i) continue;
- auto other = m_mods.at(i);
-
- if (mod.group == other.group) {
- setMod(other, i, false, shouldEmit);
- }
- }
- }
-
- for (const auto& dependencyName : mod.depends) {
- auto dependencyIndex = m_index[dependencyName];
- auto dependencyMod = m_mods.at(dependencyIndex);
-
- // enable/disable dependencies
- if (enable) {
- setMod(dependencyMod, dependencyIndex, true, shouldEmit);
- }
-
- // if the dependency is 'effectively hidden', then track which mods
- // depend on it - so we can efficiently disable it when no more dependents
- // depend on it.
- auto dependants = m_dependants[dependencyName];
-
- if (enable) {
- dependants.append(mod.name);
- }
- else {
- dependants.removeAll(mod.name);
-
- // if there are no longer any dependents, let's disable the mod
- if (dependencyMod.effectively_hidden && dependants.isEmpty()) {
- setMod(dependencyMod, dependencyIndex, false, shouldEmit);
- }
- }
- }
-
- // disable mods that depend on this one, if disabling
- if (!enable) {
- auto dependants = m_dependants[mod.name];
- for (const auto& dependencyName : dependants) {
- auto dependencyIndex = m_index[dependencyName];
- auto dependencyMod = m_mods.at(dependencyIndex);
-
- setMod(dependencyMod, dependencyIndex, false, shouldEmit);
- }
- }
-
- if (shouldEmit) {
- emit dataChanged(AtlOptionalModListModel::index(index, EnabledColumn),
- AtlOptionalModListModel::index(index, EnabledColumn));
- }
-}
-
-
-AtlOptionalModDialog::AtlOptionalModDialog(QWidget *parent, QVector<ATLauncher::VersionMod> mods)
- : QDialog(parent), ui(new Ui::AtlOptionalModDialog) {
- ui->setupUi(this);
-
- listModel = new AtlOptionalModListModel(this, mods);
- ui->treeView->setModel(listModel);
-
- ui->treeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- ui->treeView->header()->setSectionResizeMode(
- AtlOptionalModListModel::NameColumn, QHeaderView::ResizeToContents);
- ui->treeView->header()->setSectionResizeMode(
- AtlOptionalModListModel::DescriptionColumn, QHeaderView::Stretch);
-
- connect(ui->selectRecommendedButton, &QPushButton::pressed,
- listModel, &AtlOptionalModListModel::selectRecommended);
- connect(ui->clearAllButton, &QPushButton::pressed,
- listModel, &AtlOptionalModListModel::clearAll);
- connect(ui->installButton, &QPushButton::pressed,
- this, &QDialog::close);
-}
-
-AtlOptionalModDialog::~AtlOptionalModDialog() {
- delete ui;
-}
diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h
deleted file mode 100644
index a1df43f6..00000000
--- a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#pragma once
-
-#include <QDialog>
-#include <QAbstractListModel>
-
-#include "modplatform/atlauncher/ATLPackIndex.h"
-
-namespace Ui {
-class AtlOptionalModDialog;
-}
-
-class AtlOptionalModListModel : public QAbstractListModel {
- Q_OBJECT
-
-public:
- enum Columns
- {
- EnabledColumn = 0,
- NameColumn,
- DescriptionColumn,
- };
-
- AtlOptionalModListModel(QWidget *parent, QVector<ATLauncher::VersionMod> mods);
-
- QVector<QString> getResult();
-
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
-
- QVariant data(const QModelIndex &index, int role) const override;
- bool setData(const QModelIndex &index, const QVariant &value, int role) override;
- QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
-
- Qt::ItemFlags flags(const QModelIndex &index) const override;
-
-public slots:
- void selectRecommended();
- void clearAll();
-
-private:
- void toggleMod(ATLauncher::VersionMod mod, int index);
- void setMod(ATLauncher::VersionMod mod, int index, bool enable, bool shouldEmit = true);
-
-private:
- QVector<ATLauncher::VersionMod> m_mods;
- QMap<QString, bool> m_selection;
- QMap<QString, int> m_index;
- QMap<QString, QVector<QString>> m_dependants;
-};
-
-class AtlOptionalModDialog : public QDialog {
- Q_OBJECT
-
-public:
- AtlOptionalModDialog(QWidget *parent, QVector<ATLauncher::VersionMod> mods);
- ~AtlOptionalModDialog() override;
-
- QVector<QString> getResult() {
- return listModel->getResult();
- }
-
-private:
- Ui::AtlOptionalModDialog *ui;
-
- AtlOptionalModListModel *listModel;
-};
diff --git a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.ui b/application/pages/modplatform/atlauncher/AtlOptionalModDialog.ui
deleted file mode 100644
index 5d3193a4..00000000
--- a/application/pages/modplatform/atlauncher/AtlOptionalModDialog.ui
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>AtlOptionalModDialog</class>
- <widget class="QDialog" name="AtlOptionalModDialog">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>550</width>
- <height>310</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Select Mods To Install</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="1" column="3">
- <widget class="QPushButton" name="installButton">
- <property name="text">
- <string>Install</string>
- </property>
- <property name="default">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QPushButton" name="selectRecommendedButton">
- <property name="text">
- <string>Select Recommended</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QPushButton" name="shareCodeButton">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Use Share Code</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="clearAllButton">
- <property name="text">
- <string>Clear All</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="4">
- <widget class="ModListView" name="treeView"/>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>ModListView</class>
- <extends>QTreeView</extends>
- <header>widgets/ModListView.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/modplatform/atlauncher/AtlPage.cpp b/application/pages/modplatform/atlauncher/AtlPage.cpp
deleted file mode 100644
index 9fdf111f..00000000
--- a/application/pages/modplatform/atlauncher/AtlPage.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-#include "AtlPage.h"
-#include "ui_AtlPage.h"
-
-#include "dialogs/NewInstanceDialog.h"
-#include "AtlOptionalModDialog.h"
-#include <modplatform/atlauncher/ATLPackInstallTask.h>
-#include <BuildConfig.h>
-#include <dialogs/VersionSelectDialog.h>
-
-AtlPage::AtlPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::AtlPage), dialog(dialog)
-{
- ui->setupUi(this);
-
- filterModel = new Atl::FilterModel(this);
- listModel = new Atl::ListModel(this);
- filterModel->setSourceModel(listModel);
- ui->packView->setModel(filterModel);
- ui->packView->setSortingEnabled(true);
-
- ui->packView->header()->hide();
- ui->packView->setIndentation(0);
-
- ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300);
-
- for(int i = 0; i < filterModel->getAvailableSortings().size(); i++)
- {
- ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i));
- }
- ui->sortByBox->setCurrentText(filterModel->translateCurrentSorting());
-
- connect(ui->searchEdit, &QLineEdit::textChanged, this, &AtlPage::triggerSearch);
- connect(ui->resetButton, &QPushButton::clicked, this, &AtlPage::resetSearch);
- connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &AtlPage::onSortingSelectionChanged);
- connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &AtlPage::onSelectionChanged);
- connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &AtlPage::onVersionSelectionChanged);
-}
-
-AtlPage::~AtlPage()
-{
- delete ui;
-}
-
-bool AtlPage::shouldDisplay() const
-{
- return true;
-}
-
-void AtlPage::openedImpl()
-{
- if(!initialized)
- {
- listModel->request();
- initialized = true;
- }
-
- suggestCurrent();
-}
-
-void AtlPage::suggestCurrent()
-{
- if(!isOpened)
- {
- return;
- }
-
- if (selectedVersion.isEmpty())
- {
- dialog->setSuggestedPack();
- return;
- }
-
- dialog->setSuggestedPack(selected.name, new ATLauncher::PackInstallTask(this, selected.safeName, selectedVersion));
- auto editedLogoName = selected.safeName;
- auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/images/%1.png").arg(selected.safeName.toLower());
- listModel->getLogo(selected.safeName, url, [this, editedLogoName](QString logo)
- {
- dialog->setSuggestedIconFromFile(logo, editedLogoName);
- });
-}
-
-void AtlPage::triggerSearch()
-{
- filterModel->setSearchTerm(ui->searchEdit->text());
-}
-
-void AtlPage::resetSearch()
-{
- ui->searchEdit->setText("");
-}
-
-void AtlPage::onSortingSelectionChanged(QString data)
-{
- auto toSet = filterModel->getAvailableSortings().value(data);
- filterModel->setSorting(toSet);
-}
-
-void AtlPage::onSelectionChanged(QModelIndex first, QModelIndex second)
-{
- ui->versionSelectionBox->clear();
-
- if(!first.isValid())
- {
- if(isOpened)
- {
- dialog->setSuggestedPack();
- }
- return;
- }
-
- selected = filterModel->data(first, Qt::UserRole).value<ATLauncher::IndexedPack>();
-
- ui->packDescription->setHtml(selected.description.replace("\n", "<br>"));
-
- for(const auto& version : selected.versions) {
- ui->versionSelectionBox->addItem(version.version);
- }
-
- suggestCurrent();
-}
-
-void AtlPage::onVersionSelectionChanged(QString data)
-{
- if(data.isNull() || data.isEmpty())
- {
- selectedVersion = "";
- return;
- }
-
- selectedVersion = data;
- suggestCurrent();
-}
-
-QVector<QString> AtlPage::chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) {
- AtlOptionalModDialog optionalModDialog(this, mods);
- optionalModDialog.exec();
- return optionalModDialog.getResult();
-}
-
-QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) {
- VersionSelectDialog vselect(vlist.get(), "Choose Version", MMC->activeWindow(), false);
- if (minecraftVersion != Q_NULLPTR) {
- vselect.setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion);
- vselect.setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion));
- }
- else {
- vselect.setEmptyString(tr("No versions are currently available"));
- }
- vselect.setEmptyErrorString(tr("Couldn't load or download the version lists!"));
-
- // select recommended build
- for (int i = 0; i < vlist->versions().size(); i++) {
- auto version = vlist->versions().at(i);
- auto reqs = version->requires();
-
- // filter by minecraft version, if the loader depends on a certain version.
- if (minecraftVersion != Q_NULLPTR) {
- auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require &req) {
- return req.uid == "net.minecraft";
- });
- if (iter == reqs.end()) continue;
- if (iter->equalsVersion != minecraftVersion) continue;
- }
-
- // first recommended build we find, we use.
- if (version->isRecommended()) {
- vselect.setCurrentVersion(version->descriptor());
- break;
- }
- }
-
- vselect.exec();
- return vselect.selectedVersion()->descriptor();
-}
diff --git a/application/pages/modplatform/atlauncher/AtlPage.h b/application/pages/modplatform/atlauncher/AtlPage.h
deleted file mode 100644
index 932ec6a6..00000000
--- a/application/pages/modplatform/atlauncher/AtlPage.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* Copyright 2013-2019 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 "AtlFilterModel.h"
-#include "AtlListModel.h"
-
-#include <QWidget>
-#include <modplatform/atlauncher/ATLPackInstallTask.h>
-
-#include "MultiMC.h"
-#include "pages/BasePage.h"
-#include "tasks/Task.h"
-
-namespace Ui
-{
- class AtlPage;
-}
-
-class NewInstanceDialog;
-
-class AtlPage : public QWidget, public BasePage, public ATLauncher::UserInteractionSupport
-{
-Q_OBJECT
-
-public:
- explicit AtlPage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~AtlPage();
- virtual QString displayName() const override
- {
- return tr("ATLauncher");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("atlauncher");
- }
- virtual QString id() const override
- {
- return "atl";
- }
- virtual QString helpPage() const override
- {
- return "ATL-platform";
- }
- virtual bool shouldDisplay() const override;
-
- void openedImpl() override;
-
-private:
- void suggestCurrent();
-
- QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override;
- QVector<QString> chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) override;
-
-private slots:
- void triggerSearch();
- void resetSearch();
-
- void onSortingSelectionChanged(QString data);
-
- void onSelectionChanged(QModelIndex first, QModelIndex second);
- void onVersionSelectionChanged(QString data);
-
-private:
- Ui::AtlPage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
- Atl::ListModel* listModel = nullptr;
- Atl::FilterModel* filterModel = nullptr;
-
- ATLauncher::IndexedPack selected;
- QString selectedVersion;
-
- bool initialized = false;
-};
diff --git a/application/pages/modplatform/atlauncher/AtlPage.ui b/application/pages/modplatform/atlauncher/AtlPage.ui
deleted file mode 100644
index f16c24b8..00000000
--- a/application/pages/modplatform/atlauncher/AtlPage.ui
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>AtlPage</class>
- <widget class="QWidget" name="AtlPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>837</width>
- <height>685</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="1" column="0">
- <widget class="QTreeView" name="packView">
- <property name="iconSize">
- <size>
- <width>96</width>
- <height>48</height>
- </size>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QTextBrowser" name="packDescription">
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- <property name="openLinks">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="2">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Warning: This is still a work in progress. If you run into issues with the imported modpack, it may be a bug.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0" columnminimumwidth="0,0,0">
- <item row="0" column="2">
- <widget class="QComboBox" name="versionSelectionBox"/>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Version selected:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QComboBox" name="sortByBox"/>
- </item>
- </layout>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="resetButton">
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLineEdit" name="searchEdit">
- <property name="placeholderText">
- <string>Search and filter ...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>searchEdit</tabstop>
- <tabstop>resetButton</tabstop>
- <tabstop>packView</tabstop>
- <tabstop>packDescription</tabstop>
- <tabstop>sortByBox</tabstop>
- <tabstop>versionSelectionBox</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/modplatform/flame/FlameModel.cpp b/application/pages/modplatform/flame/FlameModel.cpp
deleted file mode 100644
index 228a88c5..00000000
--- a/application/pages/modplatform/flame/FlameModel.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-#include "FlameModel.h"
-#include "MultiMC.h"
-#include <Json.h>
-
-#include <MMCStrings.h>
-#include <Version.h>
-
-#include <QtMath>
-#include <QLabel>
-
-#include <RWStorage.h>
-#include <Env.h>
-
-namespace Flame {
-
-ListModel::ListModel(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-ListModel::~ListModel()
-{
-}
-
-int ListModel::rowCount(const QModelIndex &parent) const
-{
- return modpacks.size();
-}
-
-int ListModel::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-QVariant ListModel::data(const QModelIndex &index, int role) const
-{
- int pos = index.row();
- if(pos >= modpacks.size() || pos < 0 || !index.isValid())
- {
- return QString("INVALID INDEX %1").arg(pos);
- }
-
- IndexedPack pack = modpacks.at(pos);
- if(role == Qt::DisplayRole)
- {
- return pack.name;
- }
- else if (role == Qt::ToolTipRole)
- {
- if(pack.description.length() > 100)
- {
- //some magic to prevent to long tooltips and replace html linebreaks
- QString edit = pack.description.left(97);
- edit = edit.left(edit.lastIndexOf("<br>")).left(edit.lastIndexOf(" ")).append("...");
- return edit;
-
- }
- return pack.description;
- }
- else if(role == Qt::DecorationRole)
- {
- if(m_logoMap.contains(pack.logoName))
- {
- return (m_logoMap.value(pack.logoName));
- }
- QIcon icon = MMC->getThemedIcon("screenshot-placeholder");
- ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl);
- return icon;
- }
- else if(role == Qt::UserRole)
- {
- QVariant v;
- v.setValue(pack);
- return v;
- }
-
- return QVariant();
-}
-
-void ListModel::logoLoaded(QString logo, QIcon out)
-{
- m_loadingLogos.removeAll(logo);
- m_logoMap.insert(logo, out);
- for(int i = 0; i < modpacks.size(); i++) {
- if(modpacks[i].logoName == logo) {
- emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole});
- }
- }
-}
-
-void ListModel::logoFailed(QString logo)
-{
- m_failedLogos.append(logo);
- m_loadingLogos.removeAll(logo);
-}
-
-void ListModel::requestLogo(QString logo, QString url)
-{
- if(m_loadingLogos.contains(logo) || m_failedLogos.contains(logo))
- {
- return;
- }
-
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)));
- NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo));
- job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
-
- auto fullPath = entry->getFullPath();
- QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath]
- {
- emit logoLoaded(logo, QIcon(fullPath));
- if(waitingCallbacks.contains(logo))
- {
- waitingCallbacks.value(logo)(fullPath);
- }
- });
-
- QObject::connect(job, &NetJob::failed, this, [this, logo]
- {
- emit logoFailed(logo);
- });
-
- job->start();
-
- m_loadingLogos.append(logo);
-}
-
-void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback)
-{
- if(m_logoMap.contains(logo))
- {
- callback(ENV.metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath());
- }
- else
- {
- requestLogo(logo, logoUrl);
- }
-}
-
-Qt::ItemFlags ListModel::flags(const QModelIndex &index) const
-{
- return QAbstractListModel::flags(index);
-}
-
-bool ListModel::canFetchMore(const QModelIndex& parent) const
-{
- return searchState == CanPossiblyFetchMore;
-}
-
-void ListModel::fetchMore(const QModelIndex& parent)
-{
- if (parent.isValid())
- return;
- if(nextSearchOffset == 0) {
- qWarning() << "fetchMore with 0 offset is wrong...";
- return;
- }
- performPaginatedSearch();
-}
-
-void ListModel::performPaginatedSearch()
-{
- NetJob *netJob = new NetJob("Flame::Search");
- auto searchUrl = QString(
- "https://addons-ecs.forgesvc.net/api/v2/addon/search?"
- "categoryId=0&"
- "gameId=432&"
- "index=%1&"
- "pageSize=25&"
- "searchFilter=%2&"
- "sectionId=4471&"
- "sort=%3"
- ).arg(nextSearchOffset).arg(currentSearchTerm).arg(currentSort);
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
- jobPtr = netJob;
- jobPtr->start();
- QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished);
- QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed);
-}
-
-void ListModel::searchWithTerm(const QString& term, int sort)
-{
- if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull() && currentSort == sort) {
- return;
- }
- currentSearchTerm = term;
- currentSort = sort;
- if(jobPtr) {
- jobPtr->abort();
- searchState = ResetRequested;
- return;
- }
- else {
- beginResetModel();
- modpacks.clear();
- endResetModel();
- searchState = None;
- }
- nextSearchOffset = 0;
- performPaginatedSearch();
-}
-
-void Flame::ListModel::searchRequestFinished()
-{
- jobPtr.reset();
-
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from CurseForge at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
- return;
- }
-
- QList<Flame::IndexedPack> newList;
- auto packs = doc.array();
- for(auto packRaw : packs) {
- auto packObj = packRaw.toObject();
-
- Flame::IndexedPack pack;
- try
- {
- Flame::loadIndexedPack(pack, packObj);
- newList.append(pack);
- }
- catch(const JSONValidationError &e)
- {
- qWarning() << "Error while loading pack from CurseForge: " << e.cause();
- continue;
- }
- }
- if(packs.size() < 25) {
- searchState = Finished;
- } else {
- nextSearchOffset += 25;
- searchState = CanPossiblyFetchMore;
- }
- beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + newList.size() - 1);
- modpacks.append(newList);
- endInsertRows();
-}
-
-void Flame::ListModel::searchRequestFailed(QString reason)
-{
- jobPtr.reset();
-
- if(searchState == ResetRequested) {
- beginResetModel();
- modpacks.clear();
- endResetModel();
-
- nextSearchOffset = 0;
- performPaginatedSearch();
- } else {
- searchState = Finished;
- }
-}
-
-}
-
diff --git a/application/pages/modplatform/flame/FlameModel.h b/application/pages/modplatform/flame/FlameModel.h
deleted file mode 100644
index 24383db0..00000000
--- a/application/pages/modplatform/flame/FlameModel.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#pragma once
-
-#include <RWStorage.h>
-
-#include <QAbstractListModel>
-#include <QSortFilterProxyModel>
-#include <QThreadPool>
-#include <QIcon>
-#include <QStyledItemDelegate>
-#include <QList>
-#include <QString>
-#include <QStringList>
-#include <QMetaType>
-
-#include <functional>
-#include <net/NetJob.h>
-
-#include <modplatform/flame/FlamePackIndex.h>
-
-namespace Flame {
-
-
-typedef QMap<QString, QIcon> LogoMap;
-typedef std::function<void(QString)> LogoCallback;
-
-class ListModel : public QAbstractListModel
-{
- Q_OBJECT
-
-public:
- ListModel(QObject *parent);
- virtual ~ListModel();
-
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
- bool canFetchMore(const QModelIndex & parent) const override;
- void fetchMore(const QModelIndex & parent) override;
-
- void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback);
- void searchWithTerm(const QString & term, const int sort);
-
-private slots:
- void performPaginatedSearch();
-
- void logoFailed(QString logo);
- void logoLoaded(QString logo, QIcon out);
-
- void searchRequestFinished();
- void searchRequestFailed(QString reason);
-
-private:
- void requestLogo(QString file, QString url);
-
-private:
- QList<IndexedPack> modpacks;
- QStringList m_failedLogos;
- QStringList m_loadingLogos;
- LogoMap m_logoMap;
- QMap<QString, LogoCallback> waitingCallbacks;
-
- QString currentSearchTerm;
- int currentSort = 0;
- int nextSearchOffset = 0;
- enum SearchState {
- None,
- CanPossiblyFetchMore,
- ResetRequested,
- Finished
- } searchState = None;
- NetJobPtr jobPtr;
- QByteArray response;
-};
-
-}
diff --git a/application/pages/modplatform/flame/FlamePage.cpp b/application/pages/modplatform/flame/FlamePage.cpp
deleted file mode 100644
index ade58431..00000000
--- a/application/pages/modplatform/flame/FlamePage.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-#include "FlamePage.h"
-#include "ui_FlamePage.h"
-
-#include "MultiMC.h"
-#include <Json.h>
-#include "dialogs/NewInstanceDialog.h"
-#include <InstanceImportTask.h>
-#include "FlameModel.h"
-#include <QKeyEvent>
-
-FlamePage::FlamePage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::FlamePage), dialog(dialog)
-{
- ui->setupUi(this);
- connect(ui->searchButton, &QPushButton::clicked, this, &FlamePage::triggerSearch);
- ui->searchEdit->installEventFilter(this);
- listModel = new Flame::ListModel(this);
- ui->packView->setModel(listModel);
-
- ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300);
-
- // index is used to set the sorting with the curseforge api
- ui->sortByBox->addItem(tr("Sort by featured"));
- ui->sortByBox->addItem(tr("Sort by popularity"));
- ui->sortByBox->addItem(tr("Sort by last updated"));
- ui->sortByBox->addItem(tr("Sort by name"));
- ui->sortByBox->addItem(tr("Sort by author"));
- ui->sortByBox->addItem(tr("Sort by total downloads"));
-
- connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch()));
- connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlamePage::onSelectionChanged);
- connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FlamePage::onVersionSelectionChanged);
-}
-
-FlamePage::~FlamePage()
-{
- delete ui;
-}
-
-bool FlamePage::eventFilter(QObject* watched, QEvent* event)
-{
- if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) {
- QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
- if (keyEvent->key() == Qt::Key_Return) {
- triggerSearch();
- keyEvent->accept();
- return true;
- }
- }
- return QWidget::eventFilter(watched, event);
-}
-
-bool FlamePage::shouldDisplay() const
-{
- return true;
-}
-
-void FlamePage::openedImpl()
-{
- suggestCurrent();
- triggerSearch();
-}
-
-void FlamePage::triggerSearch()
-{
- listModel->searchWithTerm(ui->searchEdit->text(), ui->sortByBox->currentIndex());
-}
-
-void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second)
-{
- ui->versionSelectionBox->clear();
-
- if(!first.isValid())
- {
- if(isOpened)
- {
- dialog->setSuggestedPack();
- }
- return;
- }
-
- current = listModel->data(first, Qt::UserRole).value<Flame::IndexedPack>();
- QString text = "";
- QString name = current.name;
-
- if (current.websiteUrl.isEmpty())
- text = name;
- else
- text = "<a href=\"" + current.websiteUrl + "\">" + name + "</a>";
- if (!current.authors.empty()) {
- auto authorToStr = [](Flame::ModpackAuthor & author) {
- if(author.url.isEmpty()) {
- return author.name;
- }
- return QString("<a href=\"%1\">%2</a>").arg(author.url, author.name);
- };
- QStringList authorStrs;
- for(auto & author: current.authors) {
- authorStrs.push_back(authorToStr(author));
- }
- text += "<br>" + tr(" by ") + authorStrs.join(", ");
- }
- text += "<br><br>";
-
- ui->packDescription->setHtml(text + current.description);
-
- if (current.versionsLoaded == false)
- {
- qDebug() << "Loading flame modpack versions";
- NetJob *netJob = new NetJob(QString("Flame::PackVersions(%1)").arg(current.name));
- std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
- int addonId = current.addonId;
- netJob->addNetAction(Net::Download::makeByteArray(QString("https://addons-ecs.forgesvc.net/api/v2/addon/%1/files").arg(addonId), response.get()));
-
- QObject::connect(netJob, &NetJob::succeeded, this, [this, response]
- {
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from CurseForge at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << *response;
- return;
- }
- QJsonArray arr = doc.array();
- try
- {
- Flame::loadIndexedPackVersions(current, arr);
- }
- catch(const JSONValidationError &e)
- {
- qDebug() << *response;
- qWarning() << "Error while reading flame modpack version: " << e.cause();
- }
-
- for(auto version : current.versions) {
- ui->versionSelectionBox->addItem(version.version, QVariant(version.downloadUrl));
- }
-
- suggestCurrent();
- });
- netJob->start();
- }
- else
- {
- for(auto version : current.versions) {
- ui->versionSelectionBox->addItem(version.version, QVariant(version.downloadUrl));
- }
-
- suggestCurrent();
- }
-}
-
-void FlamePage::suggestCurrent()
-{
- if(!isOpened)
- {
- return;
- }
-
- if (selectedVersion.isEmpty())
- {
- dialog->setSuggestedPack();
- return;
- }
-
- dialog->setSuggestedPack(current.name, new InstanceImportTask(selectedVersion));
- QString editedLogoName;
- editedLogoName = "curseforge_" + current.logoName.section(".", 0, 0);
- listModel->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo)
- {
- dialog->setSuggestedIconFromFile(logo, editedLogoName);
- });
-}
-
-void FlamePage::onVersionSelectionChanged(QString data)
-{
- if(data.isNull() || data.isEmpty())
- {
- selectedVersion = "";
- return;
- }
- selectedVersion = ui->versionSelectionBox->currentData().toString();
- suggestCurrent();
-}
diff --git a/application/pages/modplatform/flame/FlamePage.h b/application/pages/modplatform/flame/FlamePage.h
deleted file mode 100644
index 467bb44b..00000000
--- a/application/pages/modplatform/flame/FlamePage.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "tasks/Task.h"
-#include <modplatform/flame/FlamePackIndex.h>
-
-namespace Ui
-{
-class FlamePage;
-}
-
-class NewInstanceDialog;
-
-namespace Flame {
- class ListModel;
-}
-
-class FlamePage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit FlamePage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~FlamePage();
- virtual QString displayName() const override
- {
- return tr("CurseForge");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("flame");
- }
- virtual QString id() const override
- {
- return "flame";
- }
- virtual QString helpPage() const override
- {
- return "Flame-platform";
- }
- virtual bool shouldDisplay() const override;
-
- void openedImpl() override;
-
- bool eventFilter(QObject * watched, QEvent * event) override;
-
-private:
- void suggestCurrent();
-
-private slots:
- void triggerSearch();
- void onSelectionChanged(QModelIndex first, QModelIndex second);
- void onVersionSelectionChanged(QString data);
-
-private:
- Ui::FlamePage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
- Flame::ListModel* listModel = nullptr;
- Flame::IndexedPack current;
-
- QString selectedVersion;
-};
diff --git a/application/pages/modplatform/flame/FlamePage.ui b/application/pages/modplatform/flame/FlamePage.ui
deleted file mode 100644
index 9723815a..00000000
--- a/application/pages/modplatform/flame/FlamePage.ui
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>FlamePage</class>
- <widget class="QWidget" name="FlamePage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>837</width>
- <height>685</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="1" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="1" column="0">
- <widget class="QListView" name="packView">
- <property name="iconSize">
- <size>
- <width>48</width>
- <height>48</height>
- </size>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QTextBrowser" name="packDescription">
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- <property name="openLinks">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0" columnminimumwidth="0,0,0">
- <item row="0" column="2">
- <widget class="QComboBox" name="versionSelectionBox"/>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Version selected:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QComboBox" name="sortByBox"/>
- </item>
- </layout>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="searchButton">
- <property name="text">
- <string>Search</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLineEdit" name="searchEdit">
- <property name="placeholderText">
- <string>Search and filter ...</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>searchEdit</tabstop>
- <tabstop>searchButton</tabstop>
- <tabstop>packView</tabstop>
- <tabstop>packDescription</tabstop>
- <tabstop>sortByBox</tabstop>
- <tabstop>versionSelectionBox</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/modplatform/ftb/FtbFilterModel.cpp b/application/pages/modplatform/ftb/FtbFilterModel.cpp
deleted file mode 100644
index dec3a017..00000000
--- a/application/pages/modplatform/ftb/FtbFilterModel.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "FtbFilterModel.h"
-
-#include <QDebug>
-
-#include "modplatform/modpacksch/FTBPackManifest.h"
-#include <MMCStrings.h>
-
-namespace Ftb {
-
-FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent)
-{
- currentSorting = Sorting::ByPlays;
- sortings.insert(tr("Sort by plays"), Sorting::ByPlays);
- sortings.insert(tr("Sort by installs"), Sorting::ByInstalls);
- sortings.insert(tr("Sort by name"), Sorting::ByName);
-}
-
-const QMap<QString, FilterModel::Sorting> FilterModel::getAvailableSortings()
-{
- return sortings;
-}
-
-QString FilterModel::translateCurrentSorting()
-{
- return sortings.key(currentSorting);
-}
-
-void FilterModel::setSorting(Sorting sorting)
-{
- currentSorting = sorting;
- invalidate();
-}
-
-FilterModel::Sorting FilterModel::getCurrentSorting()
-{
- return currentSorting;
-}
-
-bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
-{
- return true;
-}
-
-bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
-{
- ModpacksCH::Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value<ModpacksCH::Modpack>();
- ModpacksCH::Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value<ModpacksCH::Modpack>();
-
- if (currentSorting == ByPlays) {
- return leftPack.plays < rightPack.plays;
- }
- else if (currentSorting == ByInstalls) {
- return leftPack.installs < rightPack.installs;
- }
- else if (currentSorting == ByName) {
- return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0;
- }
-
- // Invalid sorting set, somehow...
- qWarning() << "Invalid sorting set!";
- return true;
-}
-
-}
diff --git a/application/pages/modplatform/ftb/FtbFilterModel.h b/application/pages/modplatform/ftb/FtbFilterModel.h
deleted file mode 100644
index 4fe2a274..00000000
--- a/application/pages/modplatform/ftb/FtbFilterModel.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <QtCore/QSortFilterProxyModel>
-
-namespace Ftb {
-
-class FilterModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-
-public:
- FilterModel(QObject* parent = Q_NULLPTR);
- enum Sorting {
- ByPlays,
- ByInstalls,
- ByName,
- };
- const QMap<QString, Sorting> getAvailableSortings();
- QString translateCurrentSorting();
- void setSorting(Sorting sorting);
- Sorting getCurrentSorting();
-
-protected:
- bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
- bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
-
-private:
- QMap<QString, Sorting> sortings;
- Sorting currentSorting;
-
-};
-
-}
diff --git a/application/pages/modplatform/ftb/FtbListModel.cpp b/application/pages/modplatform/ftb/FtbListModel.cpp
deleted file mode 100644
index 98973f2e..00000000
--- a/application/pages/modplatform/ftb/FtbListModel.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-#include "FtbListModel.h"
-
-#include "BuildConfig.h"
-#include "Env.h"
-#include "MultiMC.h"
-#include "Json.h"
-
-#include <QPainter>
-
-namespace Ftb {
-
-ListModel::ListModel(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-ListModel::~ListModel()
-{
-}
-
-int ListModel::rowCount(const QModelIndex &parent) const
-{
- return modpacks.size();
-}
-
-int ListModel::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-QVariant ListModel::data(const QModelIndex &index, int role) const
-{
- int pos = index.row();
- if(pos >= modpacks.size() || pos < 0 || !index.isValid())
- {
- return QString("INVALID INDEX %1").arg(pos);
- }
-
- ModpacksCH::Modpack pack = modpacks.at(pos);
- if(role == Qt::DisplayRole)
- {
- return pack.name;
- }
- else if (role == Qt::ToolTipRole)
- {
- return pack.synopsis;
- }
- else if(role == Qt::DecorationRole)
- {
- QIcon placeholder = MMC->getThemedIcon("screenshot-placeholder");
-
- auto iter = m_logoMap.find(pack.name);
- if (iter != m_logoMap.end()) {
- auto & logo = *iter;
- if(!logo.result.isNull()) {
- return logo.result;
- }
- return placeholder;
- }
-
- for(auto art : pack.art) {
- if(art.type == "square") {
- ((ListModel *)this)->requestLogo(pack.name, art.url);
- }
- }
- return placeholder;
- }
- else if(role == Qt::UserRole)
- {
- QVariant v;
- v.setValue(pack);
- return v;
- }
-
- return QVariant();
-}
-
-void ListModel::performSearch()
-{
- auto *netJob = new NetJob("Ftb::Search");
- QString searchUrl;
- if(currentSearchTerm.isEmpty()) {
- searchUrl = BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/all";
- }
- else {
- searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/search/25?term=%1")
- .arg(currentSearchTerm);
- }
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
- jobPtr = netJob;
- jobPtr->start();
- QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished);
- QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed);
-}
-
-void ListModel::getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback)
-{
- if(m_logoMap.contains(logo))
- {
- callback(ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath());
- }
- else
- {
- requestLogo(logo, logoUrl);
- }
-}
-
-void ListModel::searchWithTerm(const QString &term)
-{
- if(searchState != Failed && currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) {
- // unless the search has failed, then there is no need to perform an identical search.
- return;
- }
- currentSearchTerm = term;
-
- if(jobPtr) {
- jobPtr->abort();
- jobPtr.reset();
- }
-
- beginResetModel();
- modpacks.clear();
- endResetModel();
- searchState = None;
-
- performSearch();
-}
-
-void ListModel::searchRequestFinished()
-{
- jobPtr.reset();
- remainingPacks.clear();
-
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from FTB at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
- return;
- }
-
- auto packs = doc.object().value("packs").toArray();
- for(auto pack : packs) {
- auto packId = pack.toInt();
- remainingPacks.append(packId);
- }
-
- if(!remainingPacks.isEmpty()) {
- currentPack = remainingPacks.at(0);
- requestPack();
- }
-}
-
-void ListModel::searchRequestFailed(QString reason)
-{
- jobPtr.reset();
- remainingPacks.clear();
-
- searchState = Failed;
-}
-
-void ListModel::requestPack()
-{
- auto *netJob = new NetJob("Ftb::Search");
- auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1")
- .arg(currentPack);
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
- jobPtr = netJob;
- jobPtr->start();
-
- QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::packRequestFinished);
- QObject::connect(netJob, &NetJob::failed, this, &ListModel::packRequestFailed);
-}
-
-void ListModel::packRequestFinished()
-{
- jobPtr.reset();
- remainingPacks.removeOne(currentPack);
-
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
-
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from FTB at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
- return;
- }
-
- auto obj = doc.object();
-
- ModpacksCH::Modpack pack;
- try
- {
- ModpacksCH::loadModpack(pack, obj);
- }
- catch (const JSONValidationError &e)
- {
- qDebug() << QString::fromUtf8(response);
- qWarning() << "Error while reading pack manifest from FTB: " << e.cause();
- return;
- }
-
- // Since there is no guarantee that packs have a version, this will just
- // ignore those "dud" packs.
- if (pack.versions.empty())
- {
- qWarning() << "FTB Pack " << pack.id << " ignored. reason: lacking any versions";
- }
- else
- {
- beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size());
- modpacks.append(pack);
- endInsertRows();
- }
-
- if(!remainingPacks.isEmpty()) {
- currentPack = remainingPacks.at(0);
- requestPack();
- }
-}
-
-void ListModel::packRequestFailed(QString reason)
-{
- jobPtr.reset();
- remainingPacks.removeOne(currentPack);
-}
-
-void ListModel::logoLoaded(QString logo, bool stale)
-{
- auto & logoObj = m_logoMap[logo];
- logoObj.downloadJob.reset();
- QString smallPath = logoObj.fullpath + ".small";
-
- QFileInfo smallInfo(smallPath);
-
- if(stale || !smallInfo.exists()) {
- QImage image(logoObj.fullpath);
- if (image.isNull())
- {
- logoObj.failed = true;
- return;
- }
- QImage small;
- if (image.width() > image.height()) {
- small = image.scaledToWidth(512).scaledToWidth(256, Qt::SmoothTransformation);
- }
- else {
- small = image.scaledToHeight(512).scaledToHeight(256, Qt::SmoothTransformation);
- }
- 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();
-
- square.save(logoObj.fullpath + ".small", "PNG");
- }
-
- logoObj.result = QIcon(logoObj.fullpath + ".small");
- for(int i = 0; i < modpacks.size(); i++) {
- if(modpacks[i].name == logo) {
- emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole});
- }
- }
-}
-
-void ListModel::logoFailed(QString logo)
-{
- m_logoMap[logo].failed = true;
- m_logoMap[logo].downloadJob.reset();
-}
-
-void ListModel::requestLogo(QString logo, QString url)
-{
- if(m_logoMap.contains(logo)) {
- return;
- }
-
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", QString("logos/%1").arg(logo.section(".", 0, 0)));
-
- bool stale = entry->isStale();
-
- NetJob *job = new NetJob(QString("FTB Icon Download %1").arg(logo));
- job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
-
- auto fullPath = entry->getFullPath();
- QObject::connect(job, &NetJob::finished, this, [this, logo, fullPath, stale]
- {
- logoLoaded(logo, stale);
- });
-
- QObject::connect(job, &NetJob::failed, this, [this, logo]
- {
- logoFailed(logo);
- });
-
- auto &newLogoEntry = m_logoMap[logo];
- newLogoEntry.downloadJob = job;
- newLogoEntry.fullpath = fullPath;
- job->start();
-}
-
-}
diff --git a/application/pages/modplatform/ftb/FtbListModel.h b/application/pages/modplatform/ftb/FtbListModel.h
deleted file mode 100644
index de94e6ba..00000000
--- a/application/pages/modplatform/ftb/FtbListModel.h
+++ /dev/null
@@ -1,69 +0,0 @@
-#pragma once
-
-#include <QAbstractListModel>
-
-#include "modplatform/modpacksch/FTBPackManifest.h"
-#include "net/NetJob.h"
-#include <QIcon>
-
-namespace Ftb {
-
-struct Logo {
- QString fullpath;
- NetJobPtr downloadJob;
- QIcon result;
- bool failed = false;
-};
-
-typedef QMap<QString, Logo> LogoMap;
-typedef std::function<void(QString)> LogoCallback;
-
-class ListModel : public QAbstractListModel
-{
- Q_OBJECT
-
-public:
- ListModel(QObject *parent);
- virtual ~ListModel();
-
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
-
- void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback);
- void searchWithTerm(const QString & term);
-
-private slots:
- void performSearch();
- void searchRequestFinished();
- void searchRequestFailed(QString reason);
-
- void requestPack();
- void packRequestFinished();
- void packRequestFailed(QString reason);
-
- void logoFailed(QString logo);
- void logoLoaded(QString logo, bool stale);
-
-private:
- void requestLogo(QString file, QString url);
-
-private:
- QList<ModpacksCH::Modpack> modpacks;
- LogoMap m_logoMap;
-
- QString currentSearchTerm;
- enum SearchState {
- None,
- CanPossiblyFetchMore,
- ResetRequested,
- Finished,
- Failed,
- } searchState = None;
- NetJobPtr jobPtr;
- int currentPack;
- QList<int> remainingPacks;
- QByteArray response;
-};
-
-}
diff --git a/application/pages/modplatform/ftb/FtbPage.cpp b/application/pages/modplatform/ftb/FtbPage.cpp
deleted file mode 100644
index b7f35c5d..00000000
--- a/application/pages/modplatform/ftb/FtbPage.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-#include "FtbPage.h"
-#include "ui_FtbPage.h"
-
-#include <QKeyEvent>
-
-#include "dialogs/NewInstanceDialog.h"
-#include "modplatform/modpacksch/FTBPackInstallTask.h"
-
-#include "HoeDown.h"
-
-FtbPage::FtbPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::FtbPage), dialog(dialog)
-{
- ui->setupUi(this);
-
- filterModel = new Ftb::FilterModel(this);
- listModel = new Ftb::ListModel(this);
- filterModel->setSourceModel(listModel);
- ui->packView->setModel(filterModel);
- ui->packView->setSortingEnabled(true);
- ui->packView->header()->hide();
- ui->packView->setIndentation(0);
-
- ui->searchEdit->installEventFilter(this);
-
- ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300);
-
- for(int i = 0; i < filterModel->getAvailableSortings().size(); i++)
- {
- ui->sortByBox->addItem(filterModel->getAvailableSortings().keys().at(i));
- }
- ui->sortByBox->setCurrentText(filterModel->translateCurrentSorting());
-
- connect(ui->searchButton, &QPushButton::clicked, this, &FtbPage::triggerSearch);
- connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &FtbPage::onSortingSelectionChanged);
- connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FtbPage::onSelectionChanged);
- connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &FtbPage::onVersionSelectionChanged);
-}
-
-FtbPage::~FtbPage()
-{
- delete ui;
-}
-
-bool FtbPage::eventFilter(QObject* watched, QEvent* event)
-{
- if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) {
- QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
- if (keyEvent->key() == Qt::Key_Return) {
- triggerSearch();
- keyEvent->accept();
- return true;
- }
- }
- return QWidget::eventFilter(watched, event);
-}
-
-bool FtbPage::shouldDisplay() const
-{
- return true;
-}
-
-void FtbPage::openedImpl()
-{
- triggerSearch();
- suggestCurrent();
-}
-
-void FtbPage::suggestCurrent()
-{
- if(!isOpened)
- {
- return;
- }
-
- if (selectedVersion.isEmpty())
- {
- dialog->setSuggestedPack();
- return;
- }
-
- dialog->setSuggestedPack(selected.name, new ModpacksCH::PackInstallTask(selected, selectedVersion));
- for(auto art : selected.art) {
- if(art.type == "square") {
- QString editedLogoName;
- editedLogoName = selected.name;
-
- listModel->getLogo(selected.name, art.url, [this, editedLogoName](QString logo)
- {
- dialog->setSuggestedIconFromFile(logo + ".small", editedLogoName);
- });
- }
- }
-}
-
-void FtbPage::triggerSearch()
-{
- listModel->searchWithTerm(ui->searchEdit->text());
-}
-
-void FtbPage::onSortingSelectionChanged(QString data)
-{
- auto toSet = filterModel->getAvailableSortings().value(data);
- filterModel->setSorting(toSet);
-}
-
-void FtbPage::onSelectionChanged(QModelIndex first, QModelIndex second)
-{
- ui->versionSelectionBox->clear();
-
- if(!first.isValid())
- {
- if(isOpened)
- {
- dialog->setSuggestedPack();
- }
- return;
- }
-
- selected = filterModel->data(first, Qt::UserRole).value<ModpacksCH::Modpack>();
-
- HoeDown hoedown;
- QString output = hoedown.process(selected.description.toUtf8());
- ui->packDescription->setHtml(output);
-
- // reverse foreach, so that the newest versions are first
- for (auto i = selected.versions.size(); i--;) {
- ui->versionSelectionBox->addItem(selected.versions.at(i).name);
- }
-
- suggestCurrent();
-}
-
-void FtbPage::onVersionSelectionChanged(QString data)
-{
- if(data.isNull() || data.isEmpty())
- {
- selectedVersion = "";
- return;
- }
-
- selectedVersion = data;
- suggestCurrent();
-}
diff --git a/application/pages/modplatform/ftb/FtbPage.h b/application/pages/modplatform/ftb/FtbPage.h
deleted file mode 100644
index c9c93897..00000000
--- a/application/pages/modplatform/ftb/FtbPage.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright 2013-2021 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 "FtbFilterModel.h"
-#include "FtbListModel.h"
-
-#include <QWidget>
-
-#include "MultiMC.h"
-#include "pages/BasePage.h"
-#include "tasks/Task.h"
-
-namespace Ui
-{
- class FtbPage;
-}
-
-class NewInstanceDialog;
-
-class FtbPage : public QWidget, public BasePage
-{
-Q_OBJECT
-
-public:
- explicit FtbPage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~FtbPage();
- virtual QString displayName() const override
- {
- return tr("FTB");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("ftb_logo");
- }
- virtual QString id() const override
- {
- return "ftb";
- }
- virtual QString helpPage() const override
- {
- return "FTB-platform";
- }
- virtual bool shouldDisplay() const override;
-
- void openedImpl() override;
-
- bool eventFilter(QObject * watched, QEvent * event) override;
-
-private:
- void suggestCurrent();
-
-private slots:
- void triggerSearch();
- void onSortingSelectionChanged(QString data);
- void onSelectionChanged(QModelIndex first, QModelIndex second);
- void onVersionSelectionChanged(QString data);
-
-private:
- Ui::FtbPage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
- Ftb::ListModel* listModel = nullptr;
- Ftb::FilterModel* filterModel = nullptr;
-
- ModpacksCH::Modpack selected;
- QString selectedVersion;
-};
diff --git a/application/pages/modplatform/ftb/FtbPage.ui b/application/pages/modplatform/ftb/FtbPage.ui
deleted file mode 100644
index 135afc6d..00000000
--- a/application/pages/modplatform/ftb/FtbPage.ui
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>FtbPage</class>
- <widget class="QWidget" name="FtbPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>875</width>
- <height>745</height>
- </rect>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="2" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_4" columnstretch="0,0,0" rowminimumheight="0" columnminimumwidth="0,0,0">
- <item row="0" column="2">
- <widget class="QComboBox" name="versionSelectionBox"/>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Version selected:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QComboBox" name="sortByBox"/>
- </item>
- </layout>
- </item>
- <item row="0" column="0">
- <widget class="QLineEdit" name="searchEdit">
- <property name="placeholderText">
- <string>Search and filter ...</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QPushButton" name="searchButton">
- <property name="text">
- <string>Search</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2">
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="0">
- <widget class="QTreeView" name="packView">
- <property name="iconSize">
- <size>
- <width>48</width>
- <height>48</height>
- </size>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QTextBrowser" name="packDescription">
- <property name="openExternalLinks">
- <bool>true</bool>
- </property>
- <property name="openLinks">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <tabstops>
- <tabstop>searchEdit</tabstop>
- <tabstop>searchButton</tabstop>
- <tabstop>versionSelectionBox</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/modplatform/legacy_ftb/ListModel.cpp b/application/pages/modplatform/legacy_ftb/ListModel.cpp
deleted file mode 100644
index 32596fb3..00000000
--- a/application/pages/modplatform/legacy_ftb/ListModel.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-#include "ListModel.h"
-#include "MultiMC.h"
-
-#include <MMCStrings.h>
-#include <Version.h>
-
-#include <QtMath>
-#include <QLabel>
-
-#include <RWStorage.h>
-#include <Env.h>
-
-#include <BuildConfig.h>
-
-namespace LegacyFTB {
-
-FilterModel::FilterModel(QObject *parent) : QSortFilterProxyModel(parent)
-{
- currentSorting = Sorting::ByGameVersion;
- sortings.insert(tr("Sort by name"), Sorting::ByName);
- sortings.insert(tr("Sort by game version"), Sorting::ByGameVersion);
-}
-
-bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
-{
- Modpack leftPack = sourceModel()->data(left, Qt::UserRole).value<Modpack>();
- Modpack rightPack = sourceModel()->data(right, Qt::UserRole).value<Modpack>();
-
- if(currentSorting == Sorting::ByGameVersion) {
- Version lv(leftPack.mcVersion);
- Version rv(rightPack.mcVersion);
- return lv < rv;
-
- } else if(currentSorting == Sorting::ByName) {
- return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0;
- }
-
- //UHM, some inavlid value set?!
- qWarning() << "Invalid sorting set!";
- return true;
-}
-
-bool FilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
-{
- return true;
-}
-
-const QMap<QString, FilterModel::Sorting> FilterModel::getAvailableSortings()
-{
- return sortings;
-}
-
-QString FilterModel::translateCurrentSorting()
-{
- return sortings.key(currentSorting);
-}
-
-void FilterModel::setSorting(Sorting s)
-{
- currentSorting = s;
- invalidate();
-}
-
-FilterModel::Sorting FilterModel::getCurrentSorting()
-{
- return currentSorting;
-}
-
-ListModel::ListModel(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-ListModel::~ListModel()
-{
-}
-
-QString ListModel::translatePackType(PackType type) const
-{
- switch(type)
- {
- case PackType::Public:
- return tr("Public Modpack");
- case PackType::ThirdParty:
- return tr("Third Party Modpack");
- case PackType::Private:
- return tr("Private Modpack");
- }
- qWarning() << "Unknown FTB modpack type:" << int(type);
- return QString();
-}
-
-int ListModel::rowCount(const QModelIndex &parent) const
-{
- return modpacks.size();
-}
-
-int ListModel::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-QVariant ListModel::data(const QModelIndex &index, int role) const
-{
- int pos = index.row();
- if(pos >= modpacks.size() || pos < 0 || !index.isValid())
- {
- return QString("INVALID INDEX %1").arg(pos);
- }
-
- Modpack pack = modpacks.at(pos);
- if(role == Qt::DisplayRole)
- {
- return pack.name + "\n" + translatePackType(pack.type);
- }
- else if (role == Qt::ToolTipRole)
- {
- if(pack.description.length() > 100)
- {
- //some magic to prevent to long tooltips and replace html linebreaks
- QString edit = pack.description.left(97);
- edit = edit.left(edit.lastIndexOf("<br>")).left(edit.lastIndexOf(" ")).append("...");
- return edit;
-
- }
- return pack.description;
- }
- else if(role == Qt::DecorationRole)
- {
- if(m_logoMap.contains(pack.logo))
- {
- return (m_logoMap.value(pack.logo));
- }
- QIcon icon = MMC->getThemedIcon("screenshot-placeholder");
- ((ListModel *)this)->requestLogo(pack.logo);
- return icon;
- }
- else if(role == Qt::TextColorRole)
- {
- if(pack.broken)
- {
- //FIXME: Hardcoded color
- return QColor(255, 0, 50);
- }
- else if(pack.bugged)
- {
- //FIXME: Hardcoded color
- //bugged pack, currently only indicates bugged xml
- return QColor(244, 229, 66);
- }
- }
- else if(role == Qt::UserRole)
- {
- QVariant v;
- v.setValue(pack);
- return v;
- }
-
- return QVariant();
-}
-
-void ListModel::fill(ModpackList modpacks)
-{
- beginResetModel();
- this->modpacks = modpacks;
- endResetModel();
-}
-
-void ListModel::addPack(Modpack modpack)
-{
- beginResetModel();
- this->modpacks.append(modpack);
- endResetModel();
-}
-
-void ListModel::clear()
-{
- beginResetModel();
- modpacks.clear();
- endResetModel();
-}
-
-Modpack ListModel::at(int row)
-{
- return modpacks.at(row);
-}
-
-void ListModel::remove(int row)
-{
- if(row < 0 || row >= modpacks.size())
- {
- qWarning() << "Attempt to remove FTB modpacks with invalid row" << row;
- return;
- }
- beginRemoveRows(QModelIndex(), row, row);
- modpacks.removeAt(row);
- endRemoveRows();
-}
-
-void ListModel::logoLoaded(QString logo, QIcon out)
-{
- m_loadingLogos.removeAll(logo);
- m_logoMap.insert(logo, out);
- emit dataChanged(createIndex(0, 0), createIndex(1, 0));
-}
-
-void ListModel::logoFailed(QString logo)
-{
- m_failedLogos.append(logo);
- m_loadingLogos.removeAll(logo);
-}
-
-void ListModel::requestLogo(QString file)
-{
- if(m_loadingLogos.contains(file) || m_failedLogos.contains(file))
- {
- return;
- }
-
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0)));
- NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file));
- job->addNetAction(Net::Download::makeCached(QUrl(QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1").arg(file)), entry));
-
- auto fullPath = entry->getFullPath();
- QObject::connect(job, &NetJob::finished, this, [this, file, fullPath]
- {
- emit logoLoaded(file, QIcon(fullPath));
- if(waitingCallbacks.contains(file))
- {
- waitingCallbacks.value(file)(fullPath);
- }
- });
-
- QObject::connect(job, &NetJob::failed, this, [this, file]
- {
- emit logoFailed(file);
- });
-
- job->start();
-
- m_loadingLogos.append(file);
-}
-
-void ListModel::getLogo(const QString &logo, LogoCallback callback)
-{
- if(m_logoMap.contains(logo))
- {
- callback(ENV.metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(logo.section(".", 0, 0)))->getFullPath());
- }
- else
- {
- requestLogo(logo);
- }
-}
-
-Qt::ItemFlags ListModel::flags(const QModelIndex &index) const
-{
- return QAbstractListModel::flags(index);
-}
-
-}
diff --git a/application/pages/modplatform/legacy_ftb/ListModel.h b/application/pages/modplatform/legacy_ftb/ListModel.h
deleted file mode 100644
index c55df000..00000000
--- a/application/pages/modplatform/legacy_ftb/ListModel.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#pragma once
-
-#include <modplatform/legacy_ftb/PackHelpers.h>
-#include <RWStorage.h>
-
-#include <QAbstractListModel>
-#include <QSortFilterProxyModel>
-#include <QThreadPool>
-#include <QIcon>
-#include <QStyledItemDelegate>
-
-#include <functional>
-
-namespace LegacyFTB {
-
-typedef QMap<QString, QIcon> FTBLogoMap;
-typedef std::function<void(QString)> LogoCallback;
-
-class FilterModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- FilterModel(QObject* parent = Q_NULLPTR);
- enum Sorting {
- ByName,
- ByGameVersion
- };
- const QMap<QString, Sorting> getAvailableSortings();
- QString translateCurrentSorting();
- void setSorting(Sorting sorting);
- Sorting getCurrentSorting();
-
-protected:
- bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
- bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
-
-private:
- QMap<QString, Sorting> sortings;
- Sorting currentSorting;
-
-};
-
-class ListModel : public QAbstractListModel
-{
- Q_OBJECT
-private:
- ModpackList modpacks;
- QStringList m_failedLogos;
- QStringList m_loadingLogos;
- FTBLogoMap m_logoMap;
- QMap<QString, LogoCallback> waitingCallbacks;
-
- void requestLogo(QString file);
- QString translatePackType(PackType type) const;
-
-
-private slots:
- void logoFailed(QString logo);
- void logoLoaded(QString logo, QIcon out);
-
-public:
- ListModel(QObject *parent);
- ~ListModel();
- int rowCount(const QModelIndex &parent) const override;
- int columnCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
-
- void fill(ModpackList modpacks);
- void addPack(Modpack modpack);
- void clear();
- void remove(int row);
-
- Modpack at(int row);
- void getLogo(const QString &logo, LogoCallback callback);
-};
-
-}
diff --git a/application/pages/modplatform/legacy_ftb/Page.cpp b/application/pages/modplatform/legacy_ftb/Page.cpp
deleted file mode 100644
index a438f76c..00000000
--- a/application/pages/modplatform/legacy_ftb/Page.cpp
+++ /dev/null
@@ -1,369 +0,0 @@
-#include "Page.h"
-#include "ui_Page.h"
-
-#include <QInputDialog>
-
-#include "MultiMC.h"
-#include "dialogs/CustomMessageBox.h"
-#include "dialogs/NewInstanceDialog.h"
-#include "modplatform/legacy_ftb/PackFetchTask.h"
-#include "modplatform/legacy_ftb/PackInstallTask.h"
-#include "modplatform/legacy_ftb/PrivatePackManager.h"
-#include "ListModel.h"
-
-namespace LegacyFTB {
-
-Page::Page(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), dialog(dialog), ui(new Ui::Page)
-{
- ftbFetchTask.reset(new PackFetchTask());
- ftbPrivatePacks.reset(new PrivatePackManager());
-
- ui->setupUi(this);
-
- {
- publicFilterModel = new FilterModel(this);
- publicListModel = new ListModel(this);
- publicFilterModel->setSourceModel(publicListModel);
-
- ui->publicPackList->setModel(publicFilterModel);
- ui->publicPackList->setSortingEnabled(true);
- ui->publicPackList->header()->hide();
- ui->publicPackList->setIndentation(0);
- ui->publicPackList->setIconSize(QSize(42, 42));
-
- for(int i = 0; i < publicFilterModel->getAvailableSortings().size(); i++)
- {
- ui->sortByBox->addItem(publicFilterModel->getAvailableSortings().keys().at(i));
- }
-
- ui->sortByBox->setCurrentText(publicFilterModel->translateCurrentSorting());
- }
-
- {
- thirdPartyFilterModel = new FilterModel(this);
- thirdPartyModel = new ListModel(this);
- thirdPartyFilterModel->setSourceModel(thirdPartyModel);
-
- ui->thirdPartyPackList->setModel(thirdPartyFilterModel);
- ui->thirdPartyPackList->setSortingEnabled(true);
- ui->thirdPartyPackList->header()->hide();
- ui->thirdPartyPackList->setIndentation(0);
- ui->thirdPartyPackList->setIconSize(QSize(42, 42));
-
- thirdPartyFilterModel->setSorting(publicFilterModel->getCurrentSorting());
- }
-
- {
- privateFilterModel = new FilterModel(this);
- privateListModel = new ListModel(this);
- privateFilterModel->setSourceModel(privateListModel);
-
- ui->privatePackList->setModel(privateFilterModel);
- ui->privatePackList->setSortingEnabled(true);
- ui->privatePackList->header()->hide();
- ui->privatePackList->setIndentation(0);
- ui->privatePackList->setIconSize(QSize(42, 42));
-
- privateFilterModel->setSorting(publicFilterModel->getCurrentSorting());
- }
-
- ui->versionSelectionBox->view()->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- ui->versionSelectionBox->view()->parentWidget()->setMaximumHeight(300);
-
- connect(ui->sortByBox, &QComboBox::currentTextChanged, this, &Page::onSortingSelectionChanged);
- connect(ui->versionSelectionBox, &QComboBox::currentTextChanged, this, &Page::onVersionSelectionItemChanged);
-
- connect(ui->publicPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onPublicPackSelectionChanged);
- connect(ui->thirdPartyPackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onThirdPartyPackSelectionChanged);
- connect(ui->privatePackList->selectionModel(), &QItemSelectionModel::currentChanged, this, &Page::onPrivatePackSelectionChanged);
-
- connect(ui->addPackBtn, &QPushButton::pressed, this, &Page::onAddPackClicked);
- connect(ui->removePackBtn, &QPushButton::pressed, this, &Page::onRemovePackClicked);
-
- connect(ui->tabWidget, &QTabWidget::currentChanged, this, &Page::onTabChanged);
-
- // ui->modpackInfo->setOpenExternalLinks(true);
-
- ui->publicPackList->selectionModel()->reset();
- ui->thirdPartyPackList->selectionModel()->reset();
- ui->privatePackList->selectionModel()->reset();
-
- onTabChanged(ui->tabWidget->currentIndex());
-}
-
-Page::~Page()
-{
- delete ui;
-}
-
-bool Page::shouldDisplay() const
-{
- return true;
-}
-
-void Page::openedImpl()
-{
- if(!initialized)
- {
- connect(ftbFetchTask.get(), &PackFetchTask::finished, this, &Page::ftbPackDataDownloadSuccessfully);
- connect(ftbFetchTask.get(), &PackFetchTask::failed, this, &Page::ftbPackDataDownloadFailed);
-
- connect(ftbFetchTask.get(), &PackFetchTask::privateFileDownloadFinished, this, &Page::ftbPrivatePackDataDownloadSuccessfully);
- connect(ftbFetchTask.get(), &PackFetchTask::privateFileDownloadFailed, this, &Page::ftbPrivatePackDataDownloadFailed);
-
- ftbFetchTask->fetch();
- ftbPrivatePacks->load();
- ftbFetchTask->fetchPrivate(ftbPrivatePacks->getCurrentPackCodes().toList());
- initialized = true;
- }
- suggestCurrent();
-}
-
-void Page::suggestCurrent()
-{
- if(!isOpened)
- {
- return;
- }
-
- if(selected.broken || selectedVersion.isEmpty())
- {
- dialog->setSuggestedPack();
- return;
- }
-
- dialog->setSuggestedPack(selected.name, new PackInstallTask(selected, selectedVersion));
- QString editedLogoName;
- if(selected.logo.toLower().startsWith("ftb"))
- {
- editedLogoName = selected.logo;
- }
- else
- {
- editedLogoName = "ftb_" + selected.logo;
- }
-
- editedLogoName = editedLogoName.left(editedLogoName.lastIndexOf(".png"));
-
- if(selected.type == PackType::Public)
- {
- publicListModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
- {
- dialog->setSuggestedIconFromFile(logo, editedLogoName);
- });
- }
- else if (selected.type == PackType::ThirdParty)
- {
- thirdPartyModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
- {
- dialog->setSuggestedIconFromFile(logo, editedLogoName);
- });
- }
- else if (selected.type == PackType::Private)
- {
- privateListModel->getLogo(selected.logo, [this, editedLogoName](QString logo)
- {
- dialog->setSuggestedIconFromFile(logo, editedLogoName);
- });
- }
-}
-
-void Page::ftbPackDataDownloadSuccessfully(ModpackList publicPacks, ModpackList thirdPartyPacks)
-{
- publicListModel->fill(publicPacks);
- thirdPartyModel->fill(thirdPartyPacks);
-}
-
-void Page::ftbPackDataDownloadFailed(QString reason)
-{
- //TODO: Display the error
-}
-
-void Page::ftbPrivatePackDataDownloadSuccessfully(Modpack pack)
-{
- privateListModel->addPack(pack);
-}
-
-void Page::ftbPrivatePackDataDownloadFailed(QString reason, QString packCode)
-{
- auto reply = QMessageBox::question(
- this,
- tr("FTB private packs"),
- tr("Failed to download pack information for code %1.\nShould it be removed now?").arg(packCode)
- );
- if(reply == QMessageBox::Yes)
- {
- ftbPrivatePacks->remove(packCode);
- }
-}
-
-void Page::onPublicPackSelectionChanged(QModelIndex now, QModelIndex prev)
-{
- if(!now.isValid())
- {
- onPackSelectionChanged();
- return;
- }
- Modpack selectedPack = publicFilterModel->data(now, Qt::UserRole).value<Modpack>();
- onPackSelectionChanged(&selectedPack);
-}
-
-void Page::onThirdPartyPackSelectionChanged(QModelIndex now, QModelIndex prev)
-{
- if(!now.isValid())
- {
- onPackSelectionChanged();
- return;
- }
- Modpack selectedPack = thirdPartyFilterModel->data(now, Qt::UserRole).value<Modpack>();
- onPackSelectionChanged(&selectedPack);
-}
-
-void Page::onPrivatePackSelectionChanged(QModelIndex now, QModelIndex prev)
-{
- if(!now.isValid())
- {
- onPackSelectionChanged();
- return;
- }
- Modpack selectedPack = privateFilterModel->data(now, Qt::UserRole).value<Modpack>();
- onPackSelectionChanged(&selectedPack);
-}
-
-void Page::onPackSelectionChanged(Modpack* pack)
-{
- ui->versionSelectionBox->clear();
- if(pack)
- {
- currentModpackInfo->setHtml("Pack by <b>" + pack->author + "</b>" +
- "<br>Minecraft " + pack->mcVersion + "<br>" + "<br>" + pack->description + "<ul><li>" + pack->mods.replace(";", "</li><li>")
- + "</li></ul>");
- bool currentAdded = false;
-
- for(int i = 0; i < pack->oldVersions.size(); i++)
- {
- if(pack->currentVersion == pack->oldVersions.at(i))
- {
- currentAdded = true;
- }
- ui->versionSelectionBox->addItem(pack->oldVersions.at(i));
- }
-
- if(!currentAdded)
- {
- ui->versionSelectionBox->addItem(pack->currentVersion);
- }
- selected = *pack;
- }
- else
- {
- currentModpackInfo->setHtml("");
- ui->versionSelectionBox->clear();
- if(isOpened)
- {
- dialog->setSuggestedPack();
- }
- return;
- }
- suggestCurrent();
-}
-
-void Page::onVersionSelectionItemChanged(QString data)
-{
- if(data.isNull() || data.isEmpty())
- {
- selectedVersion = "";
- return;
- }
-
- selectedVersion = data;
- suggestCurrent();
-}
-
-void Page::onSortingSelectionChanged(QString data)
-{
- FilterModel::Sorting toSet = publicFilterModel->getAvailableSortings().value(data);
- publicFilterModel->setSorting(toSet);
- thirdPartyFilterModel->setSorting(toSet);
- privateFilterModel->setSorting(toSet);
-}
-
-void Page::onTabChanged(int tab)
-{
- if(tab == 1)
- {
- currentModel = thirdPartyFilterModel;
- currentList = ui->thirdPartyPackList;
- currentModpackInfo = ui->thirdPartyPackDescription;
- }
- else if(tab == 2)
- {
- currentModel = privateFilterModel;
- currentList = ui->privatePackList;
- currentModpackInfo = ui->privatePackDescription;
- }
- else
- {
- currentModel = publicFilterModel;
- currentList = ui->publicPackList;
- currentModpackInfo = ui->publicPackDescription;
- }
-
- currentList->selectionModel()->reset();
- QModelIndex idx = currentList->currentIndex();
- if(idx.isValid())
- {
- auto pack = currentModel->data(idx, Qt::UserRole).value<Modpack>();
- onPackSelectionChanged(&pack);
- }
- else
- {
- onPackSelectionChanged();
- }
-}
-
-void Page::onAddPackClicked()
-{
- bool ok;
- QString text = QInputDialog::getText(
- this,
- tr("Add FTB pack"),
- tr("Enter pack code:"),
- QLineEdit::Normal,
- QString(),
- &ok
- );
- if(ok && !text.isEmpty())
- {
- ftbPrivatePacks->add(text);
- ftbFetchTask->fetchPrivate({text});
- }
-}
-
-void Page::onRemovePackClicked()
-{
- auto index = ui->privatePackList->currentIndex();
- if(!index.isValid())
- {
- return;
- }
- auto row = index.row();
- Modpack pack = privateListModel->at(row);
- auto answer = QMessageBox::question(
- this,
- tr("Remove pack"),
- tr("Are you sure you want to remove pack %1?").arg(pack.name),
- QMessageBox::Yes | QMessageBox::No
- );
- if(answer != QMessageBox::Yes)
- {
- return;
- }
-
- ftbPrivatePacks->remove(pack.packCode);
- privateListModel->remove(row);
- onPackSelectionChanged();
-}
-
-}
diff --git a/application/pages/modplatform/legacy_ftb/Page.h b/application/pages/modplatform/legacy_ftb/Page.h
deleted file mode 100644
index e840216e..00000000
--- a/application/pages/modplatform/legacy_ftb/Page.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-#include <QTreeView>
-#include <QTextBrowser>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "tasks/Task.h"
-#include "modplatform/legacy_ftb/PackHelpers.h"
-#include "modplatform/legacy_ftb/PackFetchTask.h"
-#include "QObjectPtr.h"
-
-class NewInstanceDialog;
-
-namespace LegacyFTB {
-
-namespace Ui
-{
-class Page;
-}
-
-class ListModel;
-class FilterModel;
-class PrivatePackListModel;
-class PrivatePackFilterModel;
-class PrivatePackManager;
-
-class Page : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit Page(NewInstanceDialog * dialog, QWidget *parent = 0);
- virtual ~Page();
- QString displayName() const override
- {
- return tr("FTB Legacy");
- }
- QIcon icon() const override
- {
- return MMC->getThemedIcon("ftb_logo");
- }
- QString id() const override
- {
- return "legacy_ftb";
- }
- QString helpPage() const override
- {
- return "FTB-platform";
- }
- bool shouldDisplay() const override;
- void openedImpl() override;
-
-private:
- void suggestCurrent();
- void onPackSelectionChanged(Modpack *pack = nullptr);
-
-private slots:
- void ftbPackDataDownloadSuccessfully(ModpackList publicPacks, ModpackList thirdPartyPacks);
- void ftbPackDataDownloadFailed(QString reason);
-
- void ftbPrivatePackDataDownloadSuccessfully(Modpack pack);
- void ftbPrivatePackDataDownloadFailed(QString reason, QString packCode);
-
- void onSortingSelectionChanged(QString data);
- void onVersionSelectionItemChanged(QString data);
-
- void onPublicPackSelectionChanged(QModelIndex first, QModelIndex second);
- void onThirdPartyPackSelectionChanged(QModelIndex first, QModelIndex second);
- void onPrivatePackSelectionChanged(QModelIndex first, QModelIndex second);
-
- void onTabChanged(int tab);
-
- void onAddPackClicked();
- void onRemovePackClicked();
-
-private:
- FilterModel* currentModel = nullptr;
- QTreeView* currentList = nullptr;
- QTextBrowser* currentModpackInfo = nullptr;
-
- bool initialized = false;
- Modpack selected;
- QString selectedVersion;
-
- ListModel* publicListModel = nullptr;
- FilterModel* publicFilterModel = nullptr;
-
- ListModel *thirdPartyModel = nullptr;
- FilterModel *thirdPartyFilterModel = nullptr;
-
- ListModel *privateListModel = nullptr;
- FilterModel *privateFilterModel = nullptr;
-
- unique_qobject_ptr<PackFetchTask> ftbFetchTask;
- std::unique_ptr<PrivatePackManager> ftbPrivatePacks;
-
- NewInstanceDialog* dialog = nullptr;
-
- Ui::Page *ui = nullptr;
-};
-
-}
diff --git a/application/pages/modplatform/legacy_ftb/Page.ui b/application/pages/modplatform/legacy_ftb/Page.ui
deleted file mode 100644
index 15e5d432..00000000
--- a/application/pages/modplatform/legacy_ftb/Page.ui
+++ /dev/null
@@ -1,135 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>LegacyFTB::Page</class>
- <widget class="QWidget" name="LegacyFTB::Page">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>709</width>
- <height>602</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>Public</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QTreeView" name="publicPackList">
- <property name="maximumSize">
- <size>
- <width>250</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QTextBrowser" name="publicPackDescription"/>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_2">
- <attribute name="title">
- <string>3rd Party</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout_3">
- <item row="0" column="1">
- <widget class="QTextBrowser" name="thirdPartyPackDescription"/>
- </item>
- <item row="0" column="0">
- <widget class="QTreeView" name="thirdPartyPackList">
- <property name="maximumSize">
- <size>
- <width>250</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_3">
- <attribute name="title">
- <string>Private</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QTreeView" name="privatePackList">
- <property name="maximumSize">
- <size>
- <width>250</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QPushButton" name="addPackBtn">
- <property name="text">
- <string>Add pack</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QPushButton" name="removePackBtn">
- <property name="text">
- <string>Remove selected pack</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" rowspan="3">
- <widget class="QTextBrowser" name="privatePackDescription"/>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
- <item>
- <layout class="QGridLayout" name="gridLayout_4">
- <item row="0" column="1">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Version selected:</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QComboBox" name="versionSelectionBox"/>
- </item>
- <item row="0" column="0">
- <widget class="QComboBox" name="sortByBox">
- <property name="minimumSize">
- <size>
- <width>265</width>
- <height>0</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/application/pages/modplatform/technic/TechnicData.h b/application/pages/modplatform/technic/TechnicData.h
deleted file mode 100644
index 50fd75e8..00000000
--- a/application/pages/modplatform/technic/TechnicData.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2020-2021 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 <QList>
-#include <QString>
-
-namespace Technic {
-struct Modpack {
- QString slug;
-
- QString name;
- QString logoUrl;
- QString logoName;
-
- bool broken = true;
-
- QString url;
- bool isSolder = false;
- QString minecraftVersion;
-
- bool metadataLoaded = false;
- QString websiteUrl;
- QString author;
- QString description;
-};
-}
-
-Q_DECLARE_METATYPE(Technic::Modpack)
diff --git a/application/pages/modplatform/technic/TechnicModel.cpp b/application/pages/modplatform/technic/TechnicModel.cpp
deleted file mode 100644
index def30783..00000000
--- a/application/pages/modplatform/technic/TechnicModel.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/* Copyright 2020-2021 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 "TechnicModel.h"
-#include "Env.h"
-#include "MultiMC.h"
-#include "Json.h"
-
-#include <QIcon>
-
-Technic::ListModel::ListModel(QObject *parent) : QAbstractListModel(parent)
-{
-}
-
-Technic::ListModel::~ListModel()
-{
-}
-
-QVariant Technic::ListModel::data(const QModelIndex& index, int role) const
-{
- int pos = index.row();
- if(pos >= modpacks.size() || pos < 0 || !index.isValid())
- {
- return QString("INVALID INDEX %1").arg(pos);
- }
-
- Modpack pack = modpacks.at(pos);
- if(role == Qt::DisplayRole)
- {
- return pack.name;
- }
- else if(role == Qt::DecorationRole)
- {
- if(m_logoMap.contains(pack.logoName))
- {
- return (m_logoMap.value(pack.logoName));
- }
- QIcon icon = MMC->getThemedIcon("screenshot-placeholder");
- ((ListModel *)this)->requestLogo(pack.logoName, pack.logoUrl);
- return icon;
- }
- else if(role == Qt::UserRole)
- {
- QVariant v;
- v.setValue(pack);
- return v;
- }
- return QVariant();
-}
-
-int Technic::ListModel::columnCount(const QModelIndex&) const
-{
- return 1;
-}
-
-int Technic::ListModel::rowCount(const QModelIndex&) const
-{
- return modpacks.size();
-}
-
-void Technic::ListModel::searchWithTerm(const QString& term)
-{
- if(currentSearchTerm == term && currentSearchTerm.isNull() == term.isNull()) {
- return;
- }
- currentSearchTerm = term;
- if(jobPtr) {
- jobPtr->abort();
- searchState = ResetRequested;
- return;
- }
- else {
- beginResetModel();
- modpacks.clear();
- endResetModel();
- searchState = None;
- }
- performSearch();
-}
-
-void Technic::ListModel::performSearch()
-{
- NetJob *netJob = new NetJob("Technic::Search");
- QString searchUrl = "";
- if (currentSearchTerm.isEmpty()) {
- searchUrl = "https://api.technicpack.net/trending?build=multimc";
- }
- else
- {
- searchUrl = QString(
- "https://api.technicpack.net/search?build=multimc&q=%1"
- ).arg(currentSearchTerm);
- }
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
- jobPtr = netJob;
- jobPtr->start();
- QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished);
- QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed);
-}
-
-void Technic::ListModel::searchRequestFinished()
-{
- jobPtr.reset();
-
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError)
- {
- qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
- return;
- }
-
- QList<Modpack> newList;
- try {
- auto root = Json::requireObject(doc);
- auto objs = Json::requireArray(root, "modpacks");
- for (auto technicPack: objs) {
- Modpack pack;
- auto technicPackObject = Json::requireObject(technicPack);
- pack.name = Json::requireString(technicPackObject, "name");
- pack.slug = Json::requireString(technicPackObject, "slug");
- if (pack.slug == "vanilla")
- continue;
-
- auto rawURL = Json::ensureString(technicPackObject, "iconUrl", "null");
- if(rawURL == "null") {
- pack.logoUrl = "null";
- pack.logoName = "null";
- }
- else {
- pack.logoUrl = rawURL;
- pack.logoName = rawURL.section(QLatin1Char('/'), -1).section(QLatin1Char('.'), 0, 0);
- }
- pack.broken = false;
- newList.append(pack);
- }
- }
- catch (const JSONValidationError &err)
- {
- qCritical() << "Couldn't parse technic search results:" << err.cause() ;
- return;
- }
- searchState = Finished;
- beginInsertRows(QModelIndex(), modpacks.size(), modpacks.size() + newList.size() - 1);
- modpacks.append(newList);
- endInsertRows();
-}
-
-void Technic::ListModel::getLogo(const QString& logo, const QString& logoUrl, Technic::LogoCallback callback)
-{
- if(m_logoMap.contains(logo))
- {
- callback(ENV.metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo))->getFullPath());
- }
- else
- {
- requestLogo(logo, logoUrl);
- }
-}
-
-void Technic::ListModel::searchRequestFailed()
-{
- jobPtr.reset();
-
- if(searchState == ResetRequested)
- {
- beginResetModel();
- modpacks.clear();
- endResetModel();
-
- performSearch();
- }
- else
- {
- searchState = Finished;
- }
-}
-
-
-void Technic::ListModel::logoLoaded(QString logo, QString out)
-{
- m_loadingLogos.removeAll(logo);
- m_logoMap.insert(logo, QIcon(out));
- for(int i = 0; i < modpacks.size(); i++)
- {
- if(modpacks[i].logoName == logo)
- {
- emit dataChanged(createIndex(i, 0), createIndex(i, 0), {Qt::DecorationRole});
- }
- }
-}
-
-void Technic::ListModel::logoFailed(QString logo)
-{
- m_failedLogos.append(logo);
- m_loadingLogos.removeAll(logo);
-}
-
-void Technic::ListModel::requestLogo(QString logo, QString url)
-{
- if(m_loadingLogos.contains(logo) || m_failedLogos.contains(logo) || logo == "null")
- {
- return;
- }
-
- MetaEntryPtr entry = ENV.metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo));
- NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo));
- job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
-
- auto fullPath = entry->getFullPath();
-
- QObject::connect(job, &NetJob::succeeded, this, [this, logo, fullPath]
- {
- logoLoaded(logo, fullPath);
- });
-
- QObject::connect(job, &NetJob::failed, this, [this, logo]
- {
- logoFailed(logo);
- });
-
- job->start();
-
- m_loadingLogos.append(logo);
-}
diff --git a/application/pages/modplatform/technic/TechnicModel.h b/application/pages/modplatform/technic/TechnicModel.h
deleted file mode 100644
index 82a03842..00000000
--- a/application/pages/modplatform/technic/TechnicModel.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2020-2021 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 <QModelIndex>
-
-#include "TechnicData.h"
-#include "net/NetJob.h"
-
-namespace Technic {
-
-typedef std::function<void(QString)> LogoCallback;
-
-class ListModel : public QAbstractListModel
-{
- Q_OBJECT
-
-public:
- ListModel(QObject *parent);
- virtual ~ListModel();
-
- virtual QVariant data(const QModelIndex& index, int role) const;
- virtual int columnCount(const QModelIndex& parent) const;
- virtual int rowCount(const QModelIndex& parent) const;
-
- void getLogo(const QString &logo, const QString &logoUrl, LogoCallback callback);
- void searchWithTerm(const QString & term);
-
-private slots:
- void searchRequestFinished();
- void searchRequestFailed();
-
- void logoFailed(QString logo);
- void logoLoaded(QString logo, QString out);
-
-private:
- void performSearch();
- void requestLogo(QString logo, QString url);
-
-private:
- QList<Modpack> modpacks;
- QStringList m_failedLogos;
- QStringList m_loadingLogos;
- QMap<QString, QIcon> m_logoMap;
- QMap<QString, LogoCallback> waitingCallbacks;
-
- QString currentSearchTerm;
- enum SearchState {
- None,
- ResetRequested,
- Finished
- } searchState = None;
- NetJobPtr jobPtr;
- QByteArray response;
-};
-
-}
diff --git a/application/pages/modplatform/technic/TechnicPage.cpp b/application/pages/modplatform/technic/TechnicPage.cpp
deleted file mode 100644
index e836f767..00000000
--- a/application/pages/modplatform/technic/TechnicPage.cpp
+++ /dev/null
@@ -1,198 +0,0 @@
-/* Copyright 2013-2021 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 "TechnicPage.h"
-#include "ui_TechnicPage.h"
-
-#include "MultiMC.h"
-#include "dialogs/NewInstanceDialog.h"
-#include "TechnicModel.h"
-#include <QKeyEvent>
-#include "modplatform/technic/SingleZipPackInstallTask.h"
-#include "modplatform/technic/SolderPackInstallTask.h"
-#include "Json.h"
-
-TechnicPage::TechnicPage(NewInstanceDialog* dialog, QWidget *parent)
- : QWidget(parent), ui(new Ui::TechnicPage), dialog(dialog)
-{
- ui->setupUi(this);
- connect(ui->searchButton, &QPushButton::clicked, this, &TechnicPage::triggerSearch);
- ui->searchEdit->installEventFilter(this);
- model = new Technic::ListModel(this);
- ui->packView->setModel(model);
- connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TechnicPage::onSelectionChanged);
-}
-
-bool TechnicPage::eventFilter(QObject* watched, QEvent* event)
-{
- if (watched == ui->searchEdit && event->type() == QEvent::KeyPress) {
- QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
- if (keyEvent->key() == Qt::Key_Return) {
- triggerSearch();
- keyEvent->accept();
- return true;
- }
- }
- return QWidget::eventFilter(watched, event);
-}
-
-TechnicPage::~TechnicPage()
-{
- delete ui;
-}
-
-bool TechnicPage::shouldDisplay() const
-{
- return true;
-}
-
-void TechnicPage::openedImpl()
-{
- suggestCurrent();
- triggerSearch();
-}
-
-void TechnicPage::triggerSearch() {
- model->searchWithTerm(ui->searchEdit->text());
-}
-
-void TechnicPage::onSelectionChanged(QModelIndex first, QModelIndex second)
-{
- if(!first.isValid())
- {
- if(isOpened)
- {
- dialog->setSuggestedPack();
- }
- //ui->frame->clear();
- return;
- }
-
- current = model->data(first, Qt::UserRole).value<Technic::Modpack>();
- suggestCurrent();
-}
-
-void TechnicPage::suggestCurrent()
-{
- if (!isOpened)
- {
- return;
- }
- if (current.broken)
- {
- dialog->setSuggestedPack();
- return;
- }
-
- QString editedLogoName = "technic_" + current.logoName.section(".", 0, 0);
- model->getLogo(current.logoName, current.logoUrl, [this, editedLogoName](QString logo)
- {
- dialog->setSuggestedIconFromFile(logo, editedLogoName);
- });
-
- if (current.metadataLoaded)
- {
- metadataLoaded();
- return;
- }
-
- NetJob *netJob = new NetJob(QString("Technic::PackMeta(%1)").arg(current.name));
- std::shared_ptr<QByteArray> response = std::make_shared<QByteArray>();
- QString slug = current.slug;
- netJob->addNetAction(Net::Download::makeByteArray(QString("https://api.technicpack.net/modpack/%1?build=multimc").arg(slug), response.get()));
- QObject::connect(netJob, &NetJob::succeeded, this, [this, response, slug]
- {
- if (current.slug != slug)
- {
- return;
- }
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error);
- QJsonObject obj = doc.object();
- if(parse_error.error != QJsonParseError::NoError)
- {
- qWarning() << "Error while parsing JSON response from Technic at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << *response;
- return;
- }
- if (!obj.contains("url"))
- {
- qWarning() << "Json doesn't contain an url key";
- return;
- }
- QJsonValueRef url = obj["url"];
- if (url.isString())
- {
- current.url = url.toString();
- }
- else
- {
- if (!obj.contains("solder"))
- {
- qWarning() << "Json doesn't contain a valid url or solder key";
- return;
- }
- QJsonValueRef solderUrl = obj["solder"];
- if (solderUrl.isString())
- {
- current.url = solderUrl.toString();
- current.isSolder = true;
- }
- else
- {
- qWarning() << "Json doesn't contain a valid url or solder key";
- return;
- }
- }
-
- current.minecraftVersion = Json::ensureString(obj, "minecraft", QString(), "__placeholder__");
- current.websiteUrl = Json::ensureString(obj, "platformUrl", QString(), "__placeholder__");
- current.author = Json::ensureString(obj, "user", QString(), "__placeholder__");
- current.description = Json::ensureString(obj, "description", QString(), "__placeholder__");
- current.metadataLoaded = true;
- metadataLoaded();
- });
- netJob->start();
-}
-
-// expects current.metadataLoaded to be true
-void TechnicPage::metadataLoaded()
-{
- QString text = "";
- QString name = current.name;
-
- if (current.websiteUrl.isEmpty())
- // This allows injecting HTML here.
- text = name;
- else
- // URL not properly escaped for inclusion in HTML. The name allows for injecting HTML.
- text = "<a href=\"" + current.websiteUrl + "\">" + name + "</a>";
- if (!current.author.isEmpty()) {
- // This allows injecting HTML here
- text += tr(" by ") + current.author;
- }
-
- ui->frame->setModText(text);
- ui->frame->setModDescription(current.description);
- if (!current.isSolder)
- {
- dialog->setSuggestedPack(current.name, new Technic::SingleZipPackInstallTask(current.url, current.minecraftVersion));
- }
- else
- {
- while (current.url.endsWith('/')) current.url.chop(1);
- dialog->setSuggestedPack(current.name, new Technic::SolderPackInstallTask(current.url + "/modpack/" + current.slug, current.minecraftVersion));
- }
-}
diff --git a/application/pages/modplatform/technic/TechnicPage.h b/application/pages/modplatform/technic/TechnicPage.h
deleted file mode 100644
index 27e1258a..00000000
--- a/application/pages/modplatform/technic/TechnicPage.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright 2013-2021 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 <QWidget>
-
-#include "pages/BasePage.h"
-#include <MultiMC.h>
-#include "tasks/Task.h"
-#include "TechnicData.h"
-
-namespace Ui
-{
-class TechnicPage;
-}
-
-class NewInstanceDialog;
-
-namespace Technic {
- class ListModel;
-}
-
-class TechnicPage : public QWidget, public BasePage
-{
- Q_OBJECT
-
-public:
- explicit TechnicPage(NewInstanceDialog* dialog, QWidget *parent = 0);
- virtual ~TechnicPage();
- virtual QString displayName() const override
- {
- return tr("Technic");
- }
- virtual QIcon icon() const override
- {
- return MMC->getThemedIcon("technic");
- }
- virtual QString id() const override
- {
- return "technic";
- }
- virtual QString helpPage() const override
- {
- return "Technic-platform";
- }
- virtual bool shouldDisplay() const override;
-
- void openedImpl() override;
-
- bool eventFilter(QObject* watched, QEvent* event) override;
-
-private:
- void suggestCurrent();
- void metadataLoaded();
-
-private slots:
- void triggerSearch();
- void onSelectionChanged(QModelIndex first, QModelIndex second);
-
-private:
- Ui::TechnicPage *ui = nullptr;
- NewInstanceDialog* dialog = nullptr;
- Technic::ListModel* model = nullptr;
- Technic::Modpack current;
-};
diff --git a/application/pages/modplatform/technic/TechnicPage.ui b/application/pages/modplatform/technic/TechnicPage.ui
deleted file mode 100644
index 2ca45dd2..00000000
--- a/application/pages/modplatform/technic/TechnicPage.ui
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>TechnicPage</class>
- <widget class="QWidget" name="TechnicPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>546</width>
- <height>405</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QWidget" name="widget" native="true">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QLineEdit" name="searchEdit">
- <property name="placeholderText">
- <string>Search and filter ...</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="searchButton">
- <property name="text">
- <string>Search</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QListView" name="packView">
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="iconSize">
- <size>
- <width>48</width>
- <height>48</height>
- </size>
- </property>
- </widget>
- </item>
- <item>
- <widget class="MCModInfoFrame" name="frame">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>MCModInfoFrame</class>
- <extends>QFrame</extends>
- <header>widgets/MCModInfoFrame.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>searchEdit</tabstop>
- <tabstop>searchButton</tabstop>
- <tabstop>packView</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>