aboutsummaryrefslogtreecommitdiff
path: root/launcher/ui
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/ui')
-rw-r--r--launcher/ui/MainWindow.cpp48
-rw-r--r--launcher/ui/MainWindow.h4
-rw-r--r--launcher/ui/dialogs/AboutDialog.cpp4
-rw-r--r--launcher/ui/dialogs/LoginDialog.cpp2
-rw-r--r--launcher/ui/dialogs/MSALoginDialog.cpp2
-rw-r--r--launcher/ui/dialogs/ProfileSetupDialog.cpp10
-rw-r--r--launcher/ui/dialogs/SkinUploadDialog.cpp15
-rw-r--r--launcher/ui/dialogs/UpdateDialog.cpp4
-rw-r--r--launcher/ui/instanceview/InstanceView.cpp9
-rw-r--r--launcher/ui/pages/global/AccountListPage.cpp16
-rw-r--r--launcher/ui/pages/instance/ScreenshotsPage.cpp13
-rw-r--r--launcher/ui/pages/instance/VersionPage.cpp3
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp16
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h16
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp24
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlListModel.h16
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp16
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h16
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp17
-rw-r--r--launcher/ui/pages/modplatform/atlauncher/AtlPage.h3
-rw-r--r--launcher/ui/pages/modplatform/flame/FlameModel.cpp8
-rw-r--r--launcher/ui/pages/modplatform/flame/FlamePage.cpp4
-rw-r--r--launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp16
-rw-r--r--launcher/ui/pages/modplatform/ftb/FtbFilterModel.h16
-rw-r--r--launcher/ui/pages/modplatform/ftb/FtbListModel.cpp31
-rw-r--r--launcher/ui/pages/modplatform/ftb/FtbListModel.h16
-rw-r--r--launcher/ui/pages/modplatform/ftb/FtbPage.cpp17
-rw-r--r--launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp4
-rw-r--r--launcher/ui/pages/modplatform/technic/TechnicModel.cpp8
-rw-r--r--launcher/ui/pages/modplatform/technic/TechnicPage.cpp6
-rw-r--r--launcher/ui/widgets/ErrorFrame.cpp134
-rw-r--r--launcher/ui/widgets/ErrorFrame.h49
-rw-r--r--launcher/ui/widgets/ErrorFrame.ui92
-rw-r--r--launcher/ui/widgets/JavaSettingsWidget.cpp2
34 files changed, 577 insertions, 80 deletions
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp
index 95d9ae5d..b06f3d5a 100644
--- a/launcher/ui/MainWindow.cpp
+++ b/launcher/ui/MainWindow.cpp
@@ -211,8 +211,10 @@ public:
TranslatedAction actionEditInstNotes;
TranslatedAction actionEditInstance;
TranslatedAction actionWorlds;
+ TranslatedAction actionMods;
TranslatedAction actionViewSelectedInstFolder;
TranslatedAction actionViewSelectedMCFolder;
+ TranslatedAction actionViewSelectedModsFolder;
TranslatedAction actionDeleteInstance;
TranslatedAction actionConfig_Folder;
TranslatedAction actionCAT;
@@ -530,6 +532,13 @@ public:
all_actions.append(&actionEditInstNotes);
instanceToolBar->addAction(actionEditInstNotes);
+ actionMods = TranslatedAction(MainWindow);
+ actionMods->setObjectName(QStringLiteral("actionMods"));
+ actionMods.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Mods"));
+ actionMods.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "View the mods of this instance."));
+ all_actions.append(&actionMods);
+ instanceToolBar->addAction(actionMods);
+
actionWorlds = TranslatedAction(MainWindow);
actionWorlds->setObjectName(QStringLiteral("actionWorlds"));
actionWorlds.setTextId(QT_TRANSLATE_NOOP("MainWindow", "View Worlds"));
@@ -560,6 +569,15 @@ public:
all_actions.append(&actionViewSelectedMCFolder);
instanceToolBar->addAction(actionViewSelectedMCFolder);
+ /*
+ actionViewSelectedModsFolder = TranslatedAction(MainWindow);
+ actionViewSelectedModsFolder->setObjectName(QStringLiteral("actionViewSelectedModsFolder"));
+ actionViewSelectedModsFolder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Mods Folder"));
+ actionViewSelectedModsFolder.setTooltipId(QT_TRANSLATE_NOOP("MainWindow", "Open the selected instance's mods folder in a file browser."));
+ all_actions.append(&actionViewSelectedModsFolder);
+ instanceToolBar->addAction(actionViewSelectedModsFolder);
+ */
+
actionConfig_Folder = TranslatedAction(MainWindow);
actionConfig_Folder->setObjectName(QStringLiteral("actionConfig_Folder"));
actionConfig_Folder.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Config Folder"));
@@ -1322,8 +1340,18 @@ void MainWindow::setCatBackground(bool enabled)
if (enabled)
{
QDateTime now = QDateTime::currentDateTime();
+ QDateTime birthday(QDate(now.date().year(), 11, 30), QTime(0, 0));
QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0));
- QString cat = (non_stupid_abs(now.daysTo(xmas)) <= 4) ? "catmas" : "kitteh";
+ QString cat;
+ if(non_stupid_abs(now.daysTo(xmas)) <= 4) {
+ cat = "catmas";
+ }
+ else if (non_stupid_abs(now.daysTo(birthday)) <= 12) {
+ cat = "cattiversary";
+ }
+ else {
+ cat = "kitteh";
+ }
view->setStyleSheet(QString(R"(
InstanceView
{
@@ -1641,6 +1669,11 @@ void MainWindow::on_actionWorlds_triggered()
APPLICATION->showInstanceWindow(m_selectedInstance, "worlds");
}
+void MainWindow::on_actionMods_triggered()
+{
+ APPLICATION->showInstanceWindow(m_selectedInstance, "mods");
+}
+
void MainWindow::on_actionEditInstance_triggered()
{
APPLICATION->showInstanceWindow(m_selectedInstance);
@@ -1751,6 +1784,19 @@ void MainWindow::on_actionViewSelectedMCFolder_triggered()
}
}
+void MainWindow::on_actionViewSelectedModsFolder_triggered()
+{
+ if (m_selectedInstance)
+ {
+ QString str = m_selectedInstance->modsRoot();
+ if (!FS::ensureFilePathExists(str))
+ {
+ // TODO: report error
+ return;
+ }
+ DesktopServices::openDirectory(QDir(str).absolutePath());
+ }
+}
void MainWindow::closeEvent(QCloseEvent *event)
{
diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h
index 7e1256cc..e462c524 100644
--- a/launcher/ui/MainWindow.h
+++ b/launcher/ui/MainWindow.h
@@ -93,6 +93,8 @@ private slots:
void on_actionViewSelectedMCFolder_triggered();
+ void on_actionViewSelectedModsFolder_triggered();
+
void refreshInstances();
void on_actionViewCentralModsFolder_triggered();
@@ -133,6 +135,8 @@ private slots:
void on_actionEditInstNotes_triggered();
+ void on_actionMods_triggered();
+
void on_actionWorlds_triggered();
void on_actionScreenshots_triggered();
diff --git a/launcher/ui/dialogs/AboutDialog.cpp b/launcher/ui/dialogs/AboutDialog.cpp
index 501156d0..9795c38b 100644
--- a/launcher/ui/dialogs/AboutDialog.cpp
+++ b/launcher/ui/dialogs/AboutDialog.cpp
@@ -133,10 +133,10 @@ AboutDialog::~AboutDialog()
void AboutDialog::loadPatronList()
{
- netJob = new NetJob("Patreon Patron List");
+ netJob = new NetJob("Patreon Patron List", APPLICATION->network());
netJob->addNetAction(Net::Download::makeByteArray(QUrl("https://files.multimc.org/patrons.txt"), &dataSink));
connect(netJob.get(), &NetJob::succeeded, this, &AboutDialog::patronListLoaded);
- netJob->start(APPLICATION->network());
+ netJob->start();
}
void AboutDialog::patronListLoaded()
diff --git a/launcher/ui/dialogs/LoginDialog.cpp b/launcher/ui/dialogs/LoginDialog.cpp
index bf0806e1..194315a7 100644
--- a/launcher/ui/dialogs/LoginDialog.cpp
+++ b/launcher/ui/dialogs/LoginDialog.cpp
@@ -43,7 +43,7 @@ void LoginDialog::accept()
// Setup the login task and start it
m_account = MinecraftAccount::createFromUsername(ui->userTextBox->text());
- m_loginTask = m_account->login(nullptr, ui->passTextBox->text());
+ m_loginTask = m_account->login(ui->passTextBox->text());
connect(m_loginTask.get(), &Task::failed, this, &LoginDialog::onTaskFailed);
connect(m_loginTask.get(), &Task::succeeded, this, &LoginDialog::onTaskSucceeded);
connect(m_loginTask.get(), &Task::status, this, &LoginDialog::onTaskStatus);
diff --git a/launcher/ui/dialogs/MSALoginDialog.cpp b/launcher/ui/dialogs/MSALoginDialog.cpp
index 15c04061..f46aa3b9 100644
--- a/launcher/ui/dialogs/MSALoginDialog.cpp
+++ b/launcher/ui/dialogs/MSALoginDialog.cpp
@@ -37,7 +37,7 @@ int MSALoginDialog::exec() {
// Setup the login task and start it
m_account = MinecraftAccount::createBlankMSA();
- m_loginTask = m_account->loginMSA(nullptr);
+ m_loginTask = m_account->loginMSA();
connect(m_loginTask.get(), &Task::failed, this, &MSALoginDialog::onTaskFailed);
connect(m_loginTask.get(), &Task::succeeded, this, &MSALoginDialog::onTaskSucceeded);
connect(m_loginTask.get(), &Task::status, this, &MSALoginDialog::onTaskStatus);
diff --git a/launcher/ui/dialogs/ProfileSetupDialog.cpp b/launcher/ui/dialogs/ProfileSetupDialog.cpp
index d3e2b9a4..76b6af49 100644
--- a/launcher/ui/dialogs/ProfileSetupDialog.cpp
+++ b/launcher/ui/dialogs/ProfileSetupDialog.cpp
@@ -25,8 +25,8 @@
#include "ui/dialogs/ProgressDialog.h"
#include <Application.h>
-#include "minecraft/auth/flows/AuthRequest.h"
-#include "minecraft/auth/flows/Parsers.h"
+#include "minecraft/auth/AuthRequest.h"
+#include "minecraft/auth/Parsers.h"
ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent)
@@ -150,6 +150,9 @@ void ProfileSetupDialog::checkFinished(
QByteArray data,
QList<QNetworkReply::RawHeaderPair> headers
) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
if(error == QNetworkReply::NoError) {
auto doc = QJsonDocument::fromJson(data);
auto root = doc.object();
@@ -231,6 +234,9 @@ void ProfileSetupDialog::setupProfileFinished(
QByteArray data,
QList<QNetworkReply::RawHeaderPair> headers
) {
+ auto requestor = qobject_cast<AuthRequest *>(QObject::sender());
+ requestor->deleteLater();
+
isWorking = false;
if(error == QNetworkReply::NoError) {
/*
diff --git a/launcher/ui/dialogs/SkinUploadDialog.cpp b/launcher/ui/dialogs/SkinUploadDialog.cpp
index 4e6142fa..6a5a324f 100644
--- a/launcher/ui/dialogs/SkinUploadDialog.cpp
+++ b/launcher/ui/dialogs/SkinUploadDialog.cpp
@@ -20,16 +20,6 @@ void SkinUploadDialog::on_buttonBox_rejected()
void SkinUploadDialog::on_buttonBox_accepted()
{
- AuthSessionPtr session = std::make_shared<AuthSession>();
- auto login = m_acct->refresh(session);
- ProgressDialog prog(this);
- if (prog.execWithTask((Task*)login.get()) != QDialog::Accepted)
- {
- //FIXME: recover with password prompt
- CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to login!"), QMessageBox::Warning)->exec();
- close();
- return;
- }
QString fileName;
QString input = ui->skinPathTextBox->text();
QRegExp urlPrefixMatcher("^([a-z]+)://.+$");
@@ -91,11 +81,12 @@ void SkinUploadDialog::on_buttonBox_accepted()
{
model = SkinUpload::ALEX;
}
+ ProgressDialog prog(this);
SequentialTask skinUpload;
- skinUpload.addTask(shared_qobject_ptr<SkinUpload>(new SkinUpload(this, session, FS::read(fileName), model)));
+ skinUpload.addTask(shared_qobject_ptr<SkinUpload>(new SkinUpload(this, m_acct->accessToken(), FS::read(fileName), model)));
auto selectedCape = ui->capeCombo->currentData().toString();
if(selectedCape != m_acct->accountData()->minecraftProfile.currentCape) {
- skinUpload.addTask(shared_qobject_ptr<CapeChange>(new CapeChange(this, session, selectedCape)));
+ skinUpload.addTask(shared_qobject_ptr<CapeChange>(new CapeChange(this, m_acct->accessToken(), selectedCape)));
}
if (prog.execWithTask(&skinUpload) != QDialog::Accepted)
{
diff --git a/launcher/ui/dialogs/UpdateDialog.cpp b/launcher/ui/dialogs/UpdateDialog.cpp
index 4a6a1fdd..c0f6074c 100644
--- a/launcher/ui/dialogs/UpdateDialog.cpp
+++ b/launcher/ui/dialogs/UpdateDialog.cpp
@@ -34,7 +34,7 @@ UpdateDialog::~UpdateDialog()
void UpdateDialog::loadChangelog()
{
auto channel = APPLICATION->settings()->get("UpdateChannel").toString();
- dljob.reset(new NetJob("Changelog"));
+ dljob = new NetJob("Changelog", APPLICATION->network());
QString url;
if(channel == "stable")
{
@@ -49,7 +49,7 @@ void UpdateDialog::loadChangelog()
dljob->addNetAction(Net::Download::makeByteArray(QUrl(url), &changelogData));
connect(dljob.get(), &NetJob::succeeded, this, &UpdateDialog::changelogLoaded);
connect(dljob.get(), &NetJob::failed, this, &UpdateDialog::changelogFailed);
- dljob->start(APPLICATION->network());
+ dljob->start();
}
QString reprocessMarkdown(QByteArray markdown)
diff --git a/launcher/ui/instanceview/InstanceView.cpp b/launcher/ui/instanceview/InstanceView.cpp
index 1f044866..25aec1ab 100644
--- a/launcher/ui/instanceview/InstanceView.cpp
+++ b/launcher/ui/instanceview/InstanceView.cpp
@@ -835,15 +835,6 @@ QModelIndex InstanceView::moveCursor(QAbstractItemView::CursorAction cursorActio
if(group_index < 0)
return current;
- auto real_group = m_groups[group_index];
- int beginning_row = 0;
- for(auto group: m_groups)
- {
- if(group == real_group)
- break;
- beginning_row += group->numRows();
- }
-
QPair<int, int> pos = cat->positionOf(current);
int column = pos.first;
int row = pos.second;
diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp
index 816dce47..d3eb2655 100644
--- a/launcher/ui/pages/global/AccountListPage.cpp
+++ b/launcher/ui/pages/global/AccountListPage.cpp
@@ -170,13 +170,7 @@ void AccountListPage::on_actionRefresh_triggered() {
if (selection.size() > 0) {
QModelIndex selected = selection.first();
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
- AuthSessionPtr session = std::make_shared<AuthSession>();
- auto task = account->refresh(session);
- if (task) {
- ProgressDialog progDialog(this);
- progDialog.execWithTask(task.get());
- // TODO: respond to results of the task
- }
+ m_accounts->requestRefresh(account->internalId());
}
}
@@ -244,15 +238,9 @@ void AccountListPage::on_actionDeleteSkin_triggered()
return;
QModelIndex selected = selection.first();
- AuthSessionPtr session = std::make_shared<AuthSession>();
MinecraftAccountPtr account = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>();
- auto login = account->refresh(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);
+ auto deleteSkinTask = std::make_shared<SkinDelete>(this, account->accessToken());
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/launcher/ui/pages/instance/ScreenshotsPage.cpp b/launcher/ui/pages/instance/ScreenshotsPage.cpp
index ccde78e7..4011d88c 100644
--- a/launcher/ui/pages/instance/ScreenshotsPage.cpp
+++ b/launcher/ui/pages/instance/ScreenshotsPage.cpp
@@ -315,7 +315,7 @@ void ScreenshotsPage::on_actionUpload_triggered()
return;
QList<ScreenShot::Ptr> uploaded;
- auto job = NetJob::Ptr(new NetJob("Screenshot Upload"));
+ auto job = NetJob::Ptr(new NetJob("Screenshot Upload", APPLICATION->network()));
if(selection.size() < 2)
{
auto item = selection.at(0);
@@ -325,6 +325,7 @@ void ScreenshotsPage::on_actionUpload_triggered()
m_uploadActive = true;
ProgressDialog dialog(this);
+
if(dialog.execWithTask(job.get()) != QDialog::Accepted)
{
CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
@@ -356,7 +357,7 @@ void ScreenshotsPage::on_actionUpload_triggered()
job->addNetAction(ImgurUpload::make(screenshot));
}
SequentialTask task;
- auto albumTask = NetJob::Ptr(new NetJob("Imgur Album Creation"));
+ auto albumTask = NetJob::Ptr(new NetJob("Imgur Album Creation", APPLICATION->network()));
auto imgurAlbum = ImgurAlbumCreation::make(uploaded);
albumTask->addNetAction(imgurAlbum);
task.addTask(job);
@@ -365,8 +366,12 @@ void ScreenshotsPage::on_actionUpload_triggered()
ProgressDialog prog(this);
if (prog.execWithTask(&task) != QDialog::Accepted)
{
- CustomMessageBox::selectable(this, tr("Failed to upload screenshots!"),
- tr("Unknown error"), QMessageBox::Warning)->exec();
+ CustomMessageBox::selectable(
+ this,
+ tr("Failed to upload screenshots!"),
+ tr("Unknown error"),
+ QMessageBox::Warning
+ )->exec();
}
else
{
diff --git a/launcher/ui/pages/instance/VersionPage.cpp b/launcher/ui/pages/instance/VersionPage.cpp
index 715059ff..6e57909b 100644
--- a/launcher/ui/pages/instance/VersionPage.cpp
+++ b/launcher/ui/pages/instance/VersionPage.cpp
@@ -215,9 +215,6 @@ void VersionPage::updateVersionControls()
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);
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp
index b5d8f22b..3a97d477 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 "AtlFilterModel.h"
#include <QDebug>
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h
index bd72ad91..5235ccdb 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 <QtCore/QSortFilterProxyModel>
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp
index e8c6deee..ef9a9268 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 "AtlListModel.h"
#include <BuildConfig.h>
@@ -70,11 +86,11 @@ void ListModel::request()
modpacks.clear();
endResetModel();
- auto *netJob = new NetJob("Atl::Request");
+ auto *netJob = new NetJob("Atl::Request", APPLICATION->network());
auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "launcher/json/packsnew.json");
netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response));
jobPtr = netJob;
- jobPtr->start(APPLICATION->network());
+ jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::requestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed);
@@ -167,7 +183,7 @@ void ListModel::requestLogo(QString file, QString url)
}
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("ATLauncherPacks", QString("logos/%1").arg(file.section(".", 0, 0)));
- NetJob *job = new NetJob(QString("ATLauncher Icon Download %1").arg(file));
+ NetJob *job = new NetJob(QString("ATLauncher Icon Download %1").arg(file), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
@@ -185,7 +201,7 @@ void ListModel::requestLogo(QString file, QString url)
emit logoFailed(file);
});
- job->start(APPLICATION->network());
+ job->start();
m_loadingLogos.append(file);
}
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h
index 79aa8180..2574c48d 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlListModel.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 <QAbstractListModel>
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
index 14bbd18b..ac3869dc 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 "AtlOptionalModDialog.h"
#include "ui_AtlOptionalModDialog.h"
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h
index a1df43f6..9832014c 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlOptionalModDialog.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 <QDialog>
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp
index 5f6a1396..af0cc8d6 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ * Copyright 2021 Philip T <me@phit.link>
+ *
+ * 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 "AtlPage.h"
#include "ui_AtlPage.h"
diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlPage.h b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h
index b95b3d9e..5b3f2228 100644
--- a/launcher/ui/pages/modplatform/atlauncher/AtlPage.h
+++ b/launcher/ui/pages/modplatform/atlauncher/AtlPage.h
@@ -1,4 +1,5 @@
-/* Copyright 2013-2019 MultiMC Contributors
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp
index a05ab641..891676cf 100644
--- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp
@@ -100,7 +100,7 @@ void ListModel::requestLogo(QString logo, QString url)
}
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FlamePacks", QString("logos/%1").arg(logo.section(".", 0, 0)));
- NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo));
+ NetJob *job = new NetJob(QString("Flame Icon Download %1").arg(logo), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
@@ -118,7 +118,7 @@ void ListModel::requestLogo(QString logo, QString url)
emit logoFailed(logo);
});
- job->start(APPLICATION->network());
+ job->start();
m_loadingLogos.append(logo);
}
@@ -158,7 +158,7 @@ void ListModel::fetchMore(const QModelIndex& parent)
void ListModel::performPaginatedSearch()
{
- NetJob *netJob = new NetJob("Flame::Search");
+ NetJob *netJob = new NetJob("Flame::Search", APPLICATION->network());
auto searchUrl = QString(
"https://addons-ecs.forgesvc.net/api/v2/addon/search?"
"categoryId=0&"
@@ -171,7 +171,7 @@ void ListModel::performPaginatedSearch()
).arg(nextSearchOffset).arg(currentSearchTerm).arg(currentSort);
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
jobPtr = netJob;
- jobPtr->start(APPLICATION->network());
+ jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed);
}
diff --git a/launcher/ui/pages/modplatform/flame/FlamePage.cpp b/launcher/ui/pages/modplatform/flame/FlamePage.cpp
index cb1185f7..1138a298 100644
--- a/launcher/ui/pages/modplatform/flame/FlamePage.cpp
+++ b/launcher/ui/pages/modplatform/flame/FlamePage.cpp
@@ -109,7 +109,7 @@ void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second)
if (current.versionsLoaded == false)
{
qDebug() << "Loading flame modpack versions";
- NetJob *netJob = new NetJob(QString("Flame::PackVersions(%1)").arg(current.name));
+ NetJob *netJob = new NetJob(QString("Flame::PackVersions(%1)").arg(current.name), APPLICATION->network());
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()));
@@ -140,7 +140,7 @@ void FlamePage::onSelectionChanged(QModelIndex first, QModelIndex second)
suggestCurrent();
});
- netJob->start(APPLICATION->network());
+ netJob->start();
}
else
{
diff --git a/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp
index 793b8769..67e2277c 100644
--- a/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp
+++ b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 "FtbFilterModel.h"
#include <QDebug>
diff --git a/launcher/ui/pages/modplatform/ftb/FtbFilterModel.h b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.h
index 2e712c7d..1be28e99 100644
--- a/launcher/ui/pages/modplatform/ftb/FtbFilterModel.h
+++ b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 <QtCore/QSortFilterProxyModel>
diff --git a/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp b/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp
index 59cd0b85..37244fed 100644
--- a/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp
+++ b/launcher/ui/pages/modplatform/ftb/FtbListModel.cpp
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 "FtbListModel.h"
#include "BuildConfig.h"
@@ -91,11 +107,11 @@ void ListModel::request()
modpacks.clear();
endResetModel();
- auto *netJob = new NetJob("Ftb::Request");
+ auto *netJob = new NetJob("Ftb::Request", APPLICATION->network());
auto url = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/all");
netJob->addNetAction(Net::Download::makeByteArray(QUrl(url), &response));
jobPtr = netJob;
- jobPtr->start(APPLICATION->network());
+ jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::requestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::requestFailed);
@@ -134,12 +150,11 @@ void ListModel::requestFailed(QString reason)
void ListModel::requestPack()
{
- auto *netJob = new NetJob("Ftb::Search");
- auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1")
- .arg(currentPack);
+ auto *netJob = new NetJob("Ftb::Search", APPLICATION->network());
+ 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(APPLICATION->network());
+ jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::packRequestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::packRequestFailed);
@@ -255,7 +270,7 @@ void ListModel::requestLogo(QString logo, QString url)
bool stale = entry->isStale();
- NetJob *job = new NetJob(QString("FTB Icon Download %1").arg(logo));
+ NetJob *job = new NetJob(QString("FTB Icon Download %1").arg(logo), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
@@ -272,7 +287,7 @@ void ListModel::requestLogo(QString logo, QString url)
auto &newLogoEntry = m_logoMap[logo];
newLogoEntry.downloadJob = job;
newLogoEntry.fullpath = fullPath;
- job->start(APPLICATION->network());
+ job->start();
}
}
diff --git a/launcher/ui/pages/modplatform/ftb/FtbListModel.h b/launcher/ui/pages/modplatform/ftb/FtbListModel.h
index e2b73c25..314cb789 100644
--- a/launcher/ui/pages/modplatform/ftb/FtbListModel.h
+++ b/launcher/ui/pages/modplatform/ftb/FtbListModel.h
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ *
+ * 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 <QAbstractListModel>
diff --git a/launcher/ui/pages/modplatform/ftb/FtbPage.cpp b/launcher/ui/pages/modplatform/ftb/FtbPage.cpp
index a82de1d6..b6b5dcd4 100644
--- a/launcher/ui/pages/modplatform/ftb/FtbPage.cpp
+++ b/launcher/ui/pages/modplatform/ftb/FtbPage.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2020-2021 Jamie Mansfield <jmansfield@cadixdev.org>
+ * Copyright 2021 Philip T <me@phit.link>
+ *
+ * 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 "FtbPage.h"
#include "ui_FtbPage.h"
diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp
index 5fa932b7..9c46e887 100644
--- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp
+++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp
@@ -216,7 +216,7 @@ void ListModel::requestLogo(QString file)
}
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("FTBPacks", QString("logos/%1").arg(file.section(".", 0, 0)));
- NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file));
+ NetJob *job = new NetJob(QString("FTB Icon Download for %1").arg(file), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1").arg(file)), entry));
auto fullPath = entry->getFullPath();
@@ -234,7 +234,7 @@ void ListModel::requestLogo(QString file)
emit logoFailed(file);
});
- job->start(APPLICATION->network());
+ job->start();
m_loadingLogos.append(file);
}
diff --git a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp
index 63c2d4c4..0167f746 100644
--- a/launcher/ui/pages/modplatform/technic/TechnicModel.cpp
+++ b/launcher/ui/pages/modplatform/technic/TechnicModel.cpp
@@ -91,7 +91,7 @@ void Technic::ListModel::searchWithTerm(const QString& term)
void Technic::ListModel::performSearch()
{
- NetJob *netJob = new NetJob("Technic::Search");
+ NetJob *netJob = new NetJob("Technic::Search", APPLICATION->network());
QString searchUrl = "";
if (currentSearchTerm.isEmpty()) {
searchUrl = "https://api.technicpack.net/trending?build=multimc";
@@ -104,7 +104,7 @@ void Technic::ListModel::performSearch()
}
netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
jobPtr = netJob;
- jobPtr->start(APPLICATION->network());
+ jobPtr->start();
QObject::connect(netJob, &NetJob::succeeded, this, &ListModel::searchRequestFinished);
QObject::connect(netJob, &NetJob::failed, this, &ListModel::searchRequestFailed);
}
@@ -216,7 +216,7 @@ void Technic::ListModel::requestLogo(QString logo, QString url)
}
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("TechnicPacks", QString("logos/%1").arg(logo));
- NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo));
+ NetJob *job = new NetJob(QString("Technic Icon Download %1").arg(logo), APPLICATION->network());
job->addNetAction(Net::Download::makeCached(QUrl(url), entry));
auto fullPath = entry->getFullPath();
@@ -231,7 +231,7 @@ void Technic::ListModel::requestLogo(QString logo, QString url)
logoFailed(logo);
});
- job->start(APPLICATION->network());
+ job->start();
m_loadingLogos.append(logo);
}
diff --git a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp
index ac69675c..67f6e52c 100644
--- a/launcher/ui/pages/modplatform/technic/TechnicPage.cpp
+++ b/launcher/ui/pages/modplatform/technic/TechnicPage.cpp
@@ -110,8 +110,8 @@ void TechnicPage::suggestCurrent()
metadataLoaded();
return;
}
-
- NetJob *netJob = new NetJob(QString("Technic::PackMeta(%1)").arg(current.name));
+
+ NetJob *netJob = new NetJob(QString("Technic::PackMeta(%1)").arg(current.name), APPLICATION->network());
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()));
@@ -167,7 +167,7 @@ void TechnicPage::suggestCurrent()
current.metadataLoaded = true;
metadataLoaded();
});
- netJob->start(APPLICATION->network());
+ netJob->start();
}
// expects current.metadataLoaded to be true
diff --git a/launcher/ui/widgets/ErrorFrame.cpp b/launcher/ui/widgets/ErrorFrame.cpp
new file mode 100644
index 00000000..b3e41036
--- /dev/null
+++ b/launcher/ui/widgets/ErrorFrame.cpp
@@ -0,0 +1,134 @@
+/* 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 <QMessageBox>
+#include <QtGui>
+
+#include "ErrorFrame.h"
+#include "ui_ErrorFrame.h"
+
+#include "ui/dialogs/CustomMessageBox.h"
+
+void ErrorFrame::clear()
+{
+ setTitle(QString());
+ setDescription(QString());
+}
+
+ErrorFrame::ErrorFrame(QWidget *parent) :
+ QFrame(parent),
+ ui(new Ui::ErrorFrame)
+{
+ ui->setupUi(this);
+ ui->label_Description->setHidden(true);
+ ui->label_Title->setHidden(true);
+ updateHiddenState();
+}
+
+ErrorFrame::~ErrorFrame()
+{
+ delete ui;
+}
+
+void ErrorFrame::updateHiddenState()
+{
+ if(ui->label_Description->isHidden() && ui->label_Title->isHidden())
+ {
+ setHidden(true);
+ }
+ else
+ {
+ setHidden(false);
+ }
+}
+
+void ErrorFrame::setTitle(QString text)
+{
+ if(text.isEmpty())
+ {
+ ui->label_Title->setHidden(true);
+ }
+ else
+ {
+ ui->label_Title->setText(text);
+ ui->label_Title->setHidden(false);
+ }
+ updateHiddenState();
+}
+
+void ErrorFrame::setDescription(QString text)
+{
+ if(text.isEmpty())
+ {
+ ui->label_Description->setHidden(true);
+ updateHiddenState();
+ return;
+ }
+ else
+ {
+ ui->label_Description->setHidden(false);
+ updateHiddenState();
+ }
+ ui->label_Description->setToolTip("");
+ QString intermediatetext = text.trimmed();
+ bool prev(false);
+ QChar rem('\n');
+ QString finaltext;
+ finaltext.reserve(intermediatetext.size());
+ foreach(const QChar& c, intermediatetext)
+ {
+ if(c == rem && prev){
+ continue;
+ }
+ prev = c == rem;
+ finaltext += c;
+ }
+ QString labeltext;
+ labeltext.reserve(300);
+ if(finaltext.length() > 290)
+ {
+ ui->label_Description->setOpenExternalLinks(false);
+ ui->label_Description->setTextFormat(Qt::TextFormat::RichText);
+ desc = text;
+ // This allows injecting HTML here.
+ labeltext.append("<html><body>" + finaltext.left(287) + "<a href=\"#mod_desc\">...</a></body></html>");
+ QObject::connect(ui->label_Description, &QLabel::linkActivated, this, &ErrorFrame::ellipsisHandler);
+ }
+ else
+ {
+ ui->label_Description->setTextFormat(Qt::TextFormat::PlainText);
+ labeltext.append(finaltext);
+ }
+ ui->label_Description->setText(labeltext);
+}
+
+void ErrorFrame::ellipsisHandler(const QString &link)
+{
+ if(!currentBox)
+ {
+ currentBox = CustomMessageBox::selectable(this, QString(), desc);
+ connect(currentBox, &QMessageBox::finished, this, &ErrorFrame::boxClosed);
+ currentBox->show();
+ }
+ else
+ {
+ currentBox->setText(desc);
+ }
+}
+
+void ErrorFrame::boxClosed(int result)
+{
+ currentBox = nullptr;
+}
diff --git a/launcher/ui/widgets/ErrorFrame.h b/launcher/ui/widgets/ErrorFrame.h
new file mode 100644
index 00000000..d5069a14
--- /dev/null
+++ b/launcher/ui/widgets/ErrorFrame.h
@@ -0,0 +1,49 @@
+/* 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 <QFrame>
+
+namespace Ui
+{
+class ErrorFrame;
+}
+
+class ErrorFrame : public QFrame
+{
+ Q_OBJECT
+
+public:
+ explicit ErrorFrame(QWidget *parent = 0);
+ ~ErrorFrame();
+
+ void setTitle(QString text);
+ void setDescription(QString text);
+
+ void clear();
+
+public slots:
+ void ellipsisHandler(const QString& link );
+ void boxClosed(int result);
+
+private:
+ void updateHiddenState();
+
+private:
+ Ui::ErrorFrame *ui;
+ QString desc;
+ class QMessageBox * currentBox = nullptr;
+};
diff --git a/launcher/ui/widgets/ErrorFrame.ui b/launcher/ui/widgets/ErrorFrame.ui
new file mode 100644
index 00000000..0bb56743
--- /dev/null
+++ b/launcher/ui/widgets/ErrorFrame.ui
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ErrorFrame</class>
+ <widget class="QFrame" name="ErrorFrame">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>527</width>
+ <height>113</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>120</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <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="QLabel" name="label_Title">
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_Description">
+ <property name="toolTip">
+ <string notr="true"/>
+ </property>
+ <property name="text">
+ <string notr="true"/>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::RichText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp
index b9d7620c..ed07e082 100644
--- a/launcher/ui/widgets/JavaSettingsWidget.cpp
+++ b/launcher/ui/widgets/JavaSettingsWidget.cpp
@@ -319,7 +319,7 @@ void JavaSettingsWidget::on_javaStatusBtn_clicked()
}
CustomMessageBox::selectable(
this,
- failed ? QObject::tr("Java test success") : QObject::tr("Java test failure"),
+ failed ? QObject::tr("Java test failure") : QObject::tr("Java test success"),
text,
failed ? QMessageBox::Critical : QMessageBox::Information
)->show();