diff options
Diffstat (limited to 'launcher/dialogs')
49 files changed, 0 insertions, 5335 deletions
diff --git a/launcher/dialogs/AboutDialog.cpp b/launcher/dialogs/AboutDialog.cpp deleted file mode 100644 index 501156d0..00000000 --- a/launcher/dialogs/AboutDialog.cpp +++ /dev/null @@ -1,149 +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 "AboutDialog.h" -#include "ui_AboutDialog.h" -#include <QIcon> -#include "Application.h" -#include "BuildConfig.h" - -#include <net/NetJob.h> - -#include "HoeDown.h" - -namespace { -// Credits -// This is a hack, but I can't think of a better way to do this easily without screwing with QTextDocument... -QString getCreditsHtml(QStringList patrons) -{ - QString patronsHeading = QObject::tr("Patrons", "About Credits"); - QString output; - QTextStream stream(&output); - stream.setCodec(QTextCodec::codecForName("UTF-8")); - stream << "<center>\n"; - // TODO: possibly retrieve from git history at build time? - stream << "<h3>" << QObject::tr("Developers", "About Credits") << "</h3>\n"; - stream << "<p>Andrew Okin <<a href='mailto:forkk@forkk.net'>forkk@forkk.net</a>></p>\n"; - stream << "<p>Petr Mrázek <<a href='mailto:peterix@gmail.com'>peterix@gmail.com</a>></p>\n"; - stream << "<p>Sky Welch <<a href='mailto:multimc@bunnies.io'>multimc@bunnies.io</a>></p>\n"; - stream << "<p>Jan (02JanDal) <<a href='mailto:02jandal@gmail.com'>02jandal@gmail.com</a>></p>\n"; - stream << "<p>RoboSky <<a href='https://twitter.com/RoboSky_'>@RoboSky_</a>></p>\n"; - stream << "<br />\n"; - - stream << "<h3>" << QObject::tr("With thanks to", "About Credits") << "</h3>\n"; - stream << "<p>Orochimarufan <<a href='mailto:orochimarufan.x3@gmail.com'>orochimarufan.x3@gmail.com</a>></p>\n"; - stream << "<p>TakSuyu <<a href='mailto:taksuyu@gmail.com'>taksuyu@gmail.com</a>></p>\n"; - stream << "<p>Kilobyte <<a href='mailto:stiepen22@gmx.de'>stiepen22@gmx.de</a>></p>\n"; - stream << "<p>Rootbear75 <<a href='https://twitter.com/rootbear75'>@rootbear75</a>></p>\n"; - stream << "<p>Zeker Zhayard <<a href='https://twitter.com/zeker_zhayard'>@Zeker_Zhayard</a>></p>\n"; - stream << "<br />\n"; - - if(!patrons.isEmpty()) { - stream << "<h3>" << QObject::tr("Patrons", "About Credits") << "</h3>\n"; - for (QString patron : patrons) - { - stream << "<p>" << patron << "</p>\n"; - } - } - stream << "</center>\n"; - return output; -} - -QString getLicenseHtml() -{ - HoeDown hoedown; - QFile dataFile(":/documents/COPYING.md"); - dataFile.open(QIODevice::ReadOnly); - QString output = hoedown.process(dataFile.readAll()); - return output; -} - -} - -AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) -{ - ui->setupUi(this); - - QString launcherName = BuildConfig.LAUNCHER_NAME; - - setWindowTitle(tr("About %1").arg(launcherName)); - - QString chtml = getCreditsHtml(QStringList()); - ui->creditsText->setHtml(chtml); - - QString lhtml = getLicenseHtml(); - ui->licenseText->setHtml(lhtml); - - ui->urlLabel->setOpenExternalLinks(true); - - ui->icon->setPixmap(APPLICATION->getThemedIcon("logo").pixmap(64)); - ui->title->setText(launcherName); - - ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString()); - ui->platformLabel->setText(tr("Platform") +": " + BuildConfig.BUILD_PLATFORM); - - if (BuildConfig.VERSION_BUILD >= 0) - ui->buildNumLabel->setText(tr("Build Number") +": " + QString::number(BuildConfig.VERSION_BUILD)); - else - ui->buildNumLabel->setVisible(false); - - if (!BuildConfig.VERSION_CHANNEL.isEmpty()) - ui->channelLabel->setText(tr("Channel") +": " + BuildConfig.VERSION_CHANNEL); - else - ui->channelLabel->setVisible(false); - - ui->redistributionText->setHtml(tr( -"<p>We keep MultiMC open source because we think it's important to be able to see the source code for a project like this, and we do so using the Apache license.</p>\n" -"<p>Part of the reason for using the Apache license is we don't want people using the "MultiMC" name when redistributing the project. " -"This means people must take the time to go through the source code and remove all references to "MultiMC", including but not limited to the project " -"icon and the title of windows, (no <b>MultiMC-fork</b> in the title).</p>\n" -"<p>The Apache license covers reasonable use for the name - a mention of the project's origins in the About dialog and the license is acceptable. " -"However, it should be abundantly clear that the project is a fork <b>without</b> implying that you have our blessing.</p>" - )); - - QString urlText("<html><head/><body><p><a href=\"%1\">%1</a></p></body></html>"); - ui->urlLabel->setText(urlText.arg(BuildConfig.LAUNCHER_GIT)); - - QString copyText("© 2012-2021 %1"); - ui->copyLabel->setText(copyText.arg(BuildConfig.LAUNCHER_COPYRIGHT)); - - connect(ui->closeButton, SIGNAL(clicked()), SLOT(close())); - - connect(ui->aboutQt, &QPushButton::clicked, &QApplication::aboutQt); - - loadPatronList(); -} - -AboutDialog::~AboutDialog() -{ - delete ui; -} - -void AboutDialog::loadPatronList() -{ - netJob = new NetJob("Patreon Patron List"); - 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()); -} - -void AboutDialog::patronListLoaded() -{ - QString patronListStr(dataSink); - dataSink.clear(); - QString html = getCreditsHtml(patronListStr.split("\n", QString::SkipEmptyParts)); - ui->creditsText->setHtml(html); -} - diff --git a/launcher/dialogs/AboutDialog.h b/launcher/dialogs/AboutDialog.h deleted file mode 100644 index cc4b8850..00000000 --- a/launcher/dialogs/AboutDialog.h +++ /dev/null @@ -1,47 +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 <QDialog> -#include <net/NetJob.h> - -namespace Ui -{ -class AboutDialog; -} - -class AboutDialog : public QDialog -{ - Q_OBJECT - -public: - explicit AboutDialog(QWidget *parent = 0); - ~AboutDialog(); - -public -slots: - /// Starts loading a list of Patreon patrons. - void loadPatronList(); - - /// Slot for when the patron list loads successfully. - void patronListLoaded(); - -private: - Ui::AboutDialog *ui; - - NetJob::Ptr netJob; - QByteArray dataSink; -}; diff --git a/launcher/dialogs/AboutDialog.ui b/launcher/dialogs/AboutDialog.ui deleted file mode 100644 index 422e877b..00000000 --- a/launcher/dialogs/AboutDialog.ui +++ /dev/null @@ -1,316 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>AboutDialog</class> - <widget class="QDialog" name="AboutDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>783</width> - <height>843</height> - </rect> - </property> - <property name="minimumSize"> - <size> - <width>450</width> - <height>400</height> - </size> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <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="QLabel" name="icon"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>64</width> - <height>64</height> - </size> - </property> - <property name="baseSize"> - <size> - <width>64</width> - <height>64</height> - </size> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QLabel" name="title"> - <property name="font"> - <font> - <pointsize>15</pointsize> - </font> - </property> - <property name="text"> - <string notr="true">MultiMC 5</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QTabWidget" name="tabWidget"> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="aboutTab"> - <attribute name="title"> - <string>About</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QLabel" name="aboutLabel"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string><html><head/><body><p>A custom launcher that makes managing Minecraft easier by allowing you to have multiple instances of Minecraft at once.</p></body></html></string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="urlLabel"> - <property name="font"> - <font> - <pointsize>10</pointsize> - </font> - </property> - <property name="text"> - <string notr="true">GIT URL</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="copyLabel"> - <property name="font"> - <font> - <pointsize>8</pointsize> - <kerning>true</kerning> - </font> - </property> - <property name="text"> - <string notr="true">COPYRIGHT</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="versionLabel"> - <property name="text"> - <string>Version:</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="platformLabel"> - <property name="text"> - <string>Platform:</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="buildNumLabel"> - <property name="text"> - <string>Build Number:</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="channelLabel"> - <property name="text"> - <string>Channel:</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </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>212</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - <widget class="QWidget" name="creditsTab"> - <attribute name="title"> - <string>Credits</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QTextEdit" name="creditsText"> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="textInteractionFlags"> - <set>Qt::TextBrowserInteraction</set> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="licenseTab"> - <attribute name="title"> - <string>License</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QTextEdit" name="licenseText"> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="font"> - <font> - <family>DejaVu Sans Mono</family> - </font> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="textInteractionFlags"> - <set>Qt::TextBrowserInteraction</set> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="forkingTab"> - <attribute name="title"> - <string>Forking/Redistribution</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <widget class="QTextEdit" name="redistributionText"> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QPushButton" name="aboutQt"> - <property name="autoFillBackground"> - <bool>false</bool> - </property> - <property name="text"> - <string>About Qt</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_3"> - <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="closeButton"> - <property name="text"> - <string>Close</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <tabstops> - <tabstop>tabWidget</tabstop> - <tabstop>creditsText</tabstop> - <tabstop>licenseText</tabstop> - <tabstop>redistributionText</tabstop> - <tabstop>aboutQt</tabstop> - <tabstop>closeButton</tabstop> - </tabstops> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/CopyInstanceDialog.cpp b/launcher/dialogs/CopyInstanceDialog.cpp deleted file mode 100644 index 1c8d6711..00000000 --- a/launcher/dialogs/CopyInstanceDialog.cpp +++ /dev/null @@ -1,144 +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 <QLayout> -#include <QPushButton> - -#include "Application.h" -#include "CopyInstanceDialog.h" -#include "ui_CopyInstanceDialog.h" - -#include "dialogs/IconPickerDialog.h" - -#include "BaseVersion.h" -#include "icons/IconList.h" -#include "tasks/Task.h" -#include "BaseInstance.h" -#include "InstanceList.h" - -CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) - :QDialog(parent), ui(new Ui::CopyInstanceDialog), m_original(original) -{ - ui->setupUi(this); - resize(minimumSizeHint()); - layout()->setSizeConstraint(QLayout::SetFixedSize); - - InstIconKey = original->iconKey(); - ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); - ui->instNameTextBox->setText(original->name()); - ui->instNameTextBox->setFocus(); - auto groups = APPLICATION->instances()->getGroups().toSet(); - auto groupList = QStringList(groups.toList()); - groupList.sort(Qt::CaseInsensitive); - groupList.removeOne(""); - groupList.push_front(""); - ui->groupBox->addItems(groupList); - int index = groupList.indexOf(APPLICATION->instances()->getInstanceGroup(m_original->id())); - if(index == -1) - { - index = 0; - } - ui->groupBox->setCurrentIndex(index); - ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); - ui->copySavesCheckbox->setChecked(m_copySaves); - ui->keepPlaytimeCheckbox->setChecked(m_keepPlaytime); -} - -CopyInstanceDialog::~CopyInstanceDialog() -{ - delete ui; -} - -void CopyInstanceDialog::updateDialogState() -{ - auto allowOK = !instName().isEmpty(); - auto OkButton = ui->buttonBox->button(QDialogButtonBox::Ok); - if(OkButton->isEnabled() != allowOK) - { - OkButton->setEnabled(allowOK); - } -} - -QString CopyInstanceDialog::instName() const -{ - auto result = ui->instNameTextBox->text().trimmed(); - if(result.size()) - { - return result; - } - return QString(); -} - -QString CopyInstanceDialog::iconKey() const -{ - return InstIconKey; -} - -QString CopyInstanceDialog::instGroup() const -{ - return ui->groupBox->currentText(); -} - -void CopyInstanceDialog::on_iconButton_clicked() -{ - IconPickerDialog dlg(this); - dlg.execWithSelection(InstIconKey); - - if (dlg.result() == QDialog::Accepted) - { - InstIconKey = dlg.selectedIconKey; - ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); - } -} - -void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) -{ - updateDialogState(); -} - -bool CopyInstanceDialog::shouldCopySaves() const -{ - return m_copySaves; -} - -void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state) -{ - if(state == Qt::Unchecked) - { - m_copySaves = false; - } - else if(state == Qt::Checked) - { - m_copySaves = true; - } -} - -bool CopyInstanceDialog::shouldKeepPlaytime() const -{ - return m_keepPlaytime; -} - - -void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) -{ - if(state == Qt::Unchecked) - { - m_keepPlaytime = false; - } - else if(state == Qt::Checked) - { - m_keepPlaytime = true; - } -} diff --git a/launcher/dialogs/CopyInstanceDialog.h b/launcher/dialogs/CopyInstanceDialog.h deleted file mode 100644 index bf3cd920..00000000 --- a/launcher/dialogs/CopyInstanceDialog.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 <QDialog> -#include "BaseVersion.h" -#include <BaseInstance.h> - -class BaseInstance; - -namespace Ui -{ -class CopyInstanceDialog; -} - -class CopyInstanceDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CopyInstanceDialog(InstancePtr original, QWidget *parent = 0); - ~CopyInstanceDialog(); - - void updateDialogState(); - - QString instName() const; - QString instGroup() const; - QString iconKey() const; - bool shouldCopySaves() const; - bool shouldKeepPlaytime() const; - -private -slots: - void on_iconButton_clicked(); - void on_instNameTextBox_textChanged(const QString &arg1); - void on_copySavesCheckbox_stateChanged(int state); - void on_keepPlaytimeCheckbox_stateChanged(int state); - -private: - Ui::CopyInstanceDialog *ui; - QString InstIconKey; - InstancePtr m_original; - bool m_copySaves = true; - bool m_keepPlaytime = true; -}; diff --git a/launcher/dialogs/CopyInstanceDialog.ui b/launcher/dialogs/CopyInstanceDialog.ui deleted file mode 100644 index f4b191e2..00000000 --- a/launcher/dialogs/CopyInstanceDialog.ui +++ /dev/null @@ -1,182 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>CopyInstanceDialog</class> - <widget class="QDialog" name="CopyInstanceDialog"> - <property name="windowModality"> - <enum>Qt::ApplicationModal</enum> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>345</width> - <height>323</height> - </rect> - </property> - <property name="windowTitle"> - <string>Copy Instance</string> - </property> - <property name="windowIcon"> - <iconset> - <normaloff>:/icons/toolbar/copy</normaloff>:/icons/toolbar/copy</iconset> - </property> - <property name="modal"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="iconBtnLayout"> - <item> - <spacer name="iconBtnLeftSpacer"> - <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="QToolButton" name="iconButton"> - <property name="icon"> - <iconset> - <normaloff>:/icons/instances/grass</normaloff>:/icons/instances/grass</iconset> - </property> - <property name="iconSize"> - <size> - <width>80</width> - <height>80</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="iconBtnRightSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <widget class="QLineEdit" name="instNameTextBox"> - <property name="placeholderText"> - <string>Name</string> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="labelVersion_3"> - <property name="text"> - <string>&Group</string> - </property> - <property name="buddy"> - <cstring>groupBox</cstring> - </property> - </widget> - </item> - <item row="0" column="1" colspan="2"> - <widget class="QComboBox" name="groupBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="editable"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QCheckBox" name="copySavesCheckbox"> - <property name="text"> - <string>Copy saves</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="keepPlaytimeCheckbox"> - <property name="text"> - <string>Keep play time</string> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>iconButton</tabstop> - <tabstop>instNameTextBox</tabstop> - <tabstop>groupBox</tabstop> - <tabstop>copySavesCheckbox</tabstop> - <tabstop>keepPlaytimeCheckbox</tabstop> - </tabstops> - <resources> - <include location="../../graphics.qrc"/> - </resources> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>CopyInstanceDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>CopyInstanceDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/launcher/dialogs/CustomMessageBox.cpp b/launcher/dialogs/CustomMessageBox.cpp deleted file mode 100644 index 19029f68..00000000 --- a/launcher/dialogs/CustomMessageBox.cpp +++ /dev/null @@ -1,35 +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 "CustomMessageBox.h" - -namespace CustomMessageBox -{ -QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text, - QMessageBox::Icon icon, QMessageBox::StandardButtons buttons, - QMessageBox::StandardButton defaultButton) -{ - QMessageBox *messageBox = new QMessageBox(parent); - messageBox->setWindowTitle(title); - messageBox->setText(text); - messageBox->setStandardButtons(buttons); - messageBox->setDefaultButton(defaultButton); - messageBox->setTextInteractionFlags(Qt::TextSelectableByMouse); - messageBox->setIcon(icon); - messageBox->setTextInteractionFlags(Qt::TextBrowserInteraction); - - return messageBox; -} -} diff --git a/launcher/dialogs/CustomMessageBox.h b/launcher/dialogs/CustomMessageBox.h deleted file mode 100644 index 712c6518..00000000 --- a/launcher/dialogs/CustomMessageBox.h +++ /dev/null @@ -1,26 +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 <QMessageBox> - -namespace CustomMessageBox -{ -QMessageBox *selectable(QWidget *parent, const QString &title, const QString &text, - QMessageBox::Icon icon = QMessageBox::NoIcon, - QMessageBox::StandardButtons buttons = QMessageBox::Ok, - QMessageBox::StandardButton defaultButton = QMessageBox::NoButton); -} diff --git a/launcher/dialogs/EditAccountDialog.cpp b/launcher/dialogs/EditAccountDialog.cpp deleted file mode 100644 index 002c064b..00000000 --- a/launcher/dialogs/EditAccountDialog.cpp +++ /dev/null @@ -1,61 +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 "EditAccountDialog.h" -#include "ui_EditAccountDialog.h" -#include <DesktopServices.h> -#include <QUrl> - -EditAccountDialog::EditAccountDialog(const QString &text, QWidget *parent, int flags) - : QDialog(parent), ui(new Ui::EditAccountDialog) -{ - ui->setupUi(this); - - ui->label->setText(text); - ui->label->setVisible(!text.isEmpty()); - - ui->userTextBox->setEnabled(flags & UsernameField); - ui->passTextBox->setEnabled(flags & PasswordField); -} - -EditAccountDialog::~EditAccountDialog() -{ - delete ui; -} - -void EditAccountDialog::on_label_linkActivated(const QString &link) -{ - DesktopServices::openUrl(QUrl(link)); -} - -void EditAccountDialog::setUsername(const QString & user) const -{ - ui->userTextBox->setText(user); -} - -QString EditAccountDialog::username() const -{ - return ui->userTextBox->text(); -} - -void EditAccountDialog::setPassword(const QString & pass) const -{ - ui->passTextBox->setText(pass); -} - -QString EditAccountDialog::password() const -{ - return ui->passTextBox->text(); -} diff --git a/launcher/dialogs/EditAccountDialog.h b/launcher/dialogs/EditAccountDialog.h deleted file mode 100644 index 6b5eb4aa..00000000 --- a/launcher/dialogs/EditAccountDialog.h +++ /dev/null @@ -1,56 +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 <QDialog> - -namespace Ui -{ -class EditAccountDialog; -} - -class EditAccountDialog : public QDialog -{ - Q_OBJECT - -public: - explicit EditAccountDialog(const QString &text = "", QWidget *parent = 0, - int flags = UsernameField | PasswordField); - ~EditAccountDialog(); - - void setUsername(const QString & user) const; - void setPassword(const QString & pass) const; - - QString username() const; - QString password() const; - - enum Flags - { - NoFlags = 0, - - //! Specifies that the dialog should have a username field. - UsernameField, - - //! Specifies that the dialog should have a password field. - PasswordField, - }; - -private slots: - void on_label_linkActivated(const QString &link); - -private: - Ui::EditAccountDialog *ui; -}; diff --git a/launcher/dialogs/EditAccountDialog.ui b/launcher/dialogs/EditAccountDialog.ui deleted file mode 100644 index e87509bc..00000000 --- a/launcher/dialogs/EditAccountDialog.ui +++ /dev/null @@ -1,94 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>EditAccountDialog</class> - <widget class="QDialog" name="EditAccountDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>148</height> - </rect> - </property> - <property name="windowTitle"> - <string>Login</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string notr="true">Message label placeholder.</string> - </property> - <property name="textFormat"> - <enum>Qt::RichText</enum> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="userTextBox"> - <property name="placeholderText"> - <string>Email</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="passTextBox"> - <property name="echoMode"> - <enum>QLineEdit::Password</enum> - </property> - <property name="placeholderText"> - <string>Password</string> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>EditAccountDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>EditAccountDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/launcher/dialogs/ExportInstanceDialog.cpp b/launcher/dialogs/ExportInstanceDialog.cpp deleted file mode 100644 index 1a164875..00000000 --- a/launcher/dialogs/ExportInstanceDialog.cpp +++ /dev/null @@ -1,482 +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 "ExportInstanceDialog.h" -#include "ui_ExportInstanceDialog.h" -#include <BaseInstance.h> -#include <MMCZip.h> -#include <QFileDialog> -#include <QMessageBox> -#include <qfilesystemmodel.h> - -#include <QSortFilterProxyModel> -#include <QDebug> -#include <qstack.h> -#include <QSaveFile> -#include "MMCStrings.h" -#include "SeparatorPrefixTree.h" -#include "Application.h" -#include <icons/IconList.h> -#include <FileSystem.h> - -class PackIgnoreProxy : public QSortFilterProxyModel -{ - Q_OBJECT - -public: - PackIgnoreProxy(InstancePtr instance, QObject *parent) : QSortFilterProxyModel(parent) - { - m_instance = instance; - } - // NOTE: Sadly, we have to do sorting ourselves. - bool lessThan(const QModelIndex &left, const QModelIndex &right) const - { - QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel()); - if (!fsm) - { - return QSortFilterProxyModel::lessThan(left, right); - } - bool asc = sortOrder() == Qt::AscendingOrder ? true : false; - - QFileInfo leftFileInfo = fsm->fileInfo(left); - QFileInfo rightFileInfo = fsm->fileInfo(right); - - if (!leftFileInfo.isDir() && rightFileInfo.isDir()) - { - return !asc; - } - if (leftFileInfo.isDir() && !rightFileInfo.isDir()) - { - return asc; - } - - // sort and proxy model breaks the original model... - if (sortColumn() == 0) - { - return Strings::naturalCompare(leftFileInfo.fileName(), rightFileInfo.fileName(), - Qt::CaseInsensitive) < 0; - } - if (sortColumn() == 1) - { - auto leftSize = leftFileInfo.size(); - auto rightSize = rightFileInfo.size(); - if ((leftSize == rightSize) || (leftFileInfo.isDir() && rightFileInfo.isDir())) - { - return Strings::naturalCompare(leftFileInfo.fileName(), - rightFileInfo.fileName(), - Qt::CaseInsensitive) < 0 - ? asc - : !asc; - } - return leftSize < rightSize; - } - return QSortFilterProxyModel::lessThan(left, right); - } - - virtual Qt::ItemFlags flags(const QModelIndex &index) const - { - if (!index.isValid()) - return Qt::NoItemFlags; - - auto sourceIndex = mapToSource(index); - Qt::ItemFlags flags = sourceIndex.flags(); - if (index.column() == 0) - { - flags |= Qt::ItemIsUserCheckable; - if (sourceIndex.model()->hasChildren(sourceIndex)) - { - flags |= Qt::ItemIsTristate; - } - } - - return flags; - } - - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const - { - QModelIndex sourceIndex = mapToSource(index); - - if (index.column() == 0 && role == Qt::CheckStateRole) - { - QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel()); - auto blockedPath = relPath(fsm->filePath(sourceIndex)); - auto cover = blocked.cover(blockedPath); - if (!cover.isNull()) - { - return QVariant(Qt::Unchecked); - } - else if (blocked.exists(blockedPath)) - { - return QVariant(Qt::PartiallyChecked); - } - else - { - return QVariant(Qt::Checked); - } - } - - return sourceIndex.data(role); - } - - virtual bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole) - { - if (index.column() == 0 && role == Qt::CheckStateRole) - { - Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt()); - return setFilterState(index, state); - } - - QModelIndex sourceIndex = mapToSource(index); - return QSortFilterProxyModel::sourceModel()->setData(sourceIndex, value, role); - } - - QString relPath(const QString &path) const - { - QString prefix = QDir().absoluteFilePath(m_instance->instanceRoot()); - prefix += '/'; - if (!path.startsWith(prefix)) - { - return QString(); - } - return path.mid(prefix.size()); - } - - bool setFilterState(QModelIndex index, Qt::CheckState state) - { - QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel()); - - if (!fsm) - { - return false; - } - - QModelIndex sourceIndex = mapToSource(index); - auto blockedPath = relPath(fsm->filePath(sourceIndex)); - bool changed = false; - if (state == Qt::Unchecked) - { - // blocking a path - auto &node = blocked.insert(blockedPath); - // get rid of all blocked nodes below - node.clear(); - changed = true; - } - else if (state == Qt::Checked || state == Qt::PartiallyChecked) - { - if (!blocked.remove(blockedPath)) - { - auto cover = blocked.cover(blockedPath); - qDebug() << "Blocked by cover" << cover; - // uncover - blocked.remove(cover); - // block all contents, except for any cover - QModelIndex rootIndex = - fsm->index(FS::PathCombine(m_instance->instanceRoot(), cover)); - QModelIndex doing = rootIndex; - int row = 0; - QStack<QModelIndex> todo; - while (1) - { - auto node = doing.child(row, 0); - if (!node.isValid()) - { - if (!todo.size()) - { - break; - } - else - { - doing = todo.pop(); - row = 0; - continue; - } - } - auto relpath = relPath(fsm->filePath(node)); - if (blockedPath.startsWith(relpath)) // cover found? - { - // continue processing cover later - todo.push(node); - } - else - { - // or just block this one. - blocked.insert(relpath); - } - row++; - } - } - changed = true; - } - if (changed) - { - // update the thing - emit dataChanged(index, index, {Qt::CheckStateRole}); - // update everything above index - QModelIndex up = index.parent(); - while (1) - { - if (!up.isValid()) - break; - emit dataChanged(up, up, {Qt::CheckStateRole}); - up = up.parent(); - } - // and everything below the index - QModelIndex doing = index; - int row = 0; - QStack<QModelIndex> todo; - while (1) - { - auto node = doing.child(row, 0); - if (!node.isValid()) - { - if (!todo.size()) - { - break; - } - else - { - doing = todo.pop(); - row = 0; - continue; - } - } - emit dataChanged(node, node, {Qt::CheckStateRole}); - todo.push(node); - row++; - } - // siblings and unrelated nodes are ignored - } - return true; - } - - bool shouldExpand(QModelIndex index) - { - QModelIndex sourceIndex = mapToSource(index); - QFileSystemModel *fsm = qobject_cast<QFileSystemModel *>(sourceModel()); - if (!fsm) - { - return false; - } - auto blockedPath = relPath(fsm->filePath(sourceIndex)); - auto found = blocked.find(blockedPath); - if(found) - { - return !found->leaf(); - } - return false; - } - - void setBlockedPaths(QStringList paths) - { - beginResetModel(); - blocked.clear(); - blocked.insert(paths); - endResetModel(); - } - - const SeparatorPrefixTree<'/'> & blockedPaths() const - { - return blocked; - } - -protected: - bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const - { - Q_UNUSED(source_parent) - - // adjust the columns you want to filter out here - // return false for those that will be hidden - if (source_column == 2 || source_column == 3) - return false; - - return true; - } - -private: - InstancePtr m_instance; - SeparatorPrefixTree<'/'> blocked; -}; - -ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent) - : QDialog(parent), ui(new Ui::ExportInstanceDialog), m_instance(instance) -{ - ui->setupUi(this); - auto model = new QFileSystemModel(this); - proxyModel = new PackIgnoreProxy(m_instance, this); - loadPackIgnore(); - proxyModel->setSourceModel(model); - auto root = instance->instanceRoot(); - ui->treeView->setModel(proxyModel); - ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root))); - ui->treeView->sortByColumn(0, Qt::AscendingOrder); - - connect(proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int))); - - model->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); - model->setRootPath(root); - auto headerView = ui->treeView->header(); - headerView->setSectionResizeMode(QHeaderView::ResizeToContents); - headerView->setSectionResizeMode(0, QHeaderView::Stretch); -} - -ExportInstanceDialog::~ExportInstanceDialog() -{ - delete ui; -} - -/// Save icon to instance's folder is needed -void SaveIcon(InstancePtr m_instance) -{ - auto iconKey = m_instance->iconKey(); - auto iconList = APPLICATION->icons(); - auto mmcIcon = iconList->icon(iconKey); - if(!mmcIcon || mmcIcon->isBuiltIn()) { - return; - } - auto path = mmcIcon->getFilePath(); - if(!path.isNull()) { - QFileInfo inInfo (path); - FS::copy(path, FS::PathCombine(m_instance->instanceRoot(), inInfo.fileName())) (); - return; - } - auto & image = mmcIcon->m_images[mmcIcon->type()]; - auto & icon = image.icon; - auto sizes = icon.availableSizes(); - if(sizes.size() == 0) - { - return; - } - auto areaOf = [](QSize size) - { - return size.width() * size.height(); - }; - QSize largest = sizes[0]; - // find variant with largest area - for(auto size: sizes) - { - if(areaOf(largest) < areaOf(size)) - { - largest = size; - } - } - auto pixmap = icon.pixmap(largest); - pixmap.save(FS::PathCombine(m_instance->instanceRoot(), iconKey + ".png")); -} - -bool ExportInstanceDialog::doExport() -{ - auto name = FS::RemoveInvalidFilenameChars(m_instance->name()); - - const QString output = QFileDialog::getSaveFileName( - this, tr("Export %1").arg(m_instance->name()), - FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr, QFileDialog::DontConfirmOverwrite); - if (output.isEmpty()) - { - return false; - } - if (QFile::exists(output)) - { - int ret = - QMessageBox::question(this, tr("Overwrite?"), - tr("This file already exists. Do you want to overwrite it?"), - QMessageBox::No, QMessageBox::Yes); - if (ret == QMessageBox::No) - { - return false; - } - } - - SaveIcon(m_instance); - - auto & blocked = proxyModel->blockedPaths(); - using std::placeholders::_1; - if (!JlCompress::compressDir(output, m_instance->instanceRoot(), name, std::bind(&SeparatorPrefixTree<'/'>::covers, blocked, _1))) - { - QMessageBox::warning(this, tr("Error"), tr("Unable to export instance")); - return false; - } - return true; -} - -void ExportInstanceDialog::done(int result) -{ - savePackIgnore(); - if (result == QDialog::Accepted) - { - if (doExport()) - { - QDialog::done(QDialog::Accepted); - return; - } - else - { - return; - } - } - QDialog::done(result); -} - -void ExportInstanceDialog::rowsInserted(QModelIndex parent, int top, int bottom) -{ - //WARNING: possible off-by-one? - for(int i = top; i < bottom; i++) - { - auto node = parent.child(i, 0); - if(proxyModel->shouldExpand(node)) - { - auto expNode = node.parent(); - if(!expNode.isValid()) - { - continue; - } - ui->treeView->expand(node); - } - } -} - -QString ExportInstanceDialog::ignoreFileName() -{ - return FS::PathCombine(m_instance->instanceRoot(), ".packignore"); -} - -void ExportInstanceDialog::loadPackIgnore() -{ - auto filename = ignoreFileName(); - QFile ignoreFile(filename); - if(!ignoreFile.open(QIODevice::ReadOnly)) - { - return; - } - auto data = ignoreFile.readAll(); - auto string = QString::fromUtf8(data); - proxyModel->setBlockedPaths(string.split('\n', QString::SkipEmptyParts)); -} - -void ExportInstanceDialog::savePackIgnore() -{ - auto data = proxyModel->blockedPaths().toStringList().join('\n').toUtf8(); - auto filename = ignoreFileName(); - try - { - FS::write(filename, data); - } - catch (const Exception &e) - { - qWarning() << e.cause(); - } -} - -#include "ExportInstanceDialog.moc" diff --git a/launcher/dialogs/ExportInstanceDialog.h b/launcher/dialogs/ExportInstanceDialog.h deleted file mode 100644 index dea02d1b..00000000 --- a/launcher/dialogs/ExportInstanceDialog.h +++ /dev/null @@ -1,54 +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 <QDialog> -#include <QModelIndex> -#include <memory> - -class BaseInstance; -class PackIgnoreProxy; -typedef std::shared_ptr<BaseInstance> InstancePtr; - -namespace Ui -{ -class ExportInstanceDialog; -} - -class ExportInstanceDialog : public QDialog -{ - Q_OBJECT - -public: - explicit ExportInstanceDialog(InstancePtr instance, QWidget *parent = 0); - ~ExportInstanceDialog(); - - virtual void done(int result); - -private: - bool doExport(); - void loadPackIgnore(); - void savePackIgnore(); - QString ignoreFileName(); - -private: - Ui::ExportInstanceDialog *ui; - InstancePtr m_instance; - PackIgnoreProxy * proxyModel; - -private slots: - void rowsInserted(QModelIndex parent, int top, int bottom); -}; diff --git a/launcher/dialogs/ExportInstanceDialog.ui b/launcher/dialogs/ExportInstanceDialog.ui deleted file mode 100644 index bcd4e84a..00000000 --- a/launcher/dialogs/ExportInstanceDialog.ui +++ /dev/null @@ -1,83 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ExportInstanceDialog</class> - <widget class="QDialog" name="ExportInstanceDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>720</width> - <height>625</height> - </rect> - </property> - <property name="windowTitle"> - <string>Export Instance</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QTreeView" name="treeView"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - <attribute name="headerStretchLastSection"> - <bool>false</bool> - </attribute> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>treeView</tabstop> - </tabstops> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>ExportInstanceDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>ExportInstanceDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/launcher/dialogs/IconPickerDialog.cpp b/launcher/dialogs/IconPickerDialog.cpp deleted file mode 100644 index af9d0683..00000000 --- a/launcher/dialogs/IconPickerDialog.cpp +++ /dev/null @@ -1,163 +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 <QKeyEvent> -#include <QPushButton> -#include <QFileDialog> - -#include "Application.h" - -#include "IconPickerDialog.h" -#include "ui_IconPickerDialog.h" - -#include "instanceview/InstanceDelegate.h" - -#include "icons/IconList.h" -#include "icons/IconUtils.h" -#include <DesktopServices.h> - -IconPickerDialog::IconPickerDialog(QWidget *parent) - : QDialog(parent), ui(new Ui::IconPickerDialog) -{ - ui->setupUi(this); - setWindowModality(Qt::WindowModal); - - auto contentsWidget = ui->iconView; - contentsWidget->setViewMode(QListView::IconMode); - contentsWidget->setFlow(QListView::LeftToRight); - contentsWidget->setIconSize(QSize(48, 48)); - contentsWidget->setMovement(QListView::Static); - contentsWidget->setResizeMode(QListView::Adjust); - contentsWidget->setSelectionMode(QAbstractItemView::SingleSelection); - contentsWidget->setSpacing(5); - contentsWidget->setWordWrap(false); - contentsWidget->setWrapping(true); - contentsWidget->setUniformItemSizes(true); - contentsWidget->setTextElideMode(Qt::ElideRight); - contentsWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - contentsWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - contentsWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - contentsWidget->setItemDelegate(new ListViewDelegate()); - - // contentsWidget->setAcceptDrops(true); - contentsWidget->setDropIndicatorShown(true); - contentsWidget->viewport()->setAcceptDrops(true); - contentsWidget->setDragDropMode(QAbstractItemView::DropOnly); - contentsWidget->setDefaultDropAction(Qt::CopyAction); - - contentsWidget->installEventFilter(this); - - contentsWidget->setModel(APPLICATION->icons().get()); - - // NOTE: ResetRole forces the button to be on the left, while the OK/Cancel ones are on the right. We win. - auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole); - auto buttonRemove = ui->buttonBox->addButton(tr("Remove Icon"), QDialogButtonBox::ResetRole); - - connect(buttonAdd, SIGNAL(clicked(bool)), SLOT(addNewIcon())); - connect(buttonRemove, SIGNAL(clicked(bool)), SLOT(removeSelectedIcon())); - - connect(contentsWidget, SIGNAL(doubleClicked(QModelIndex)), SLOT(activated(QModelIndex))); - - connect(contentsWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection))); - - auto buttonFolder = ui->buttonBox->addButton(tr("Open Folder"), QDialogButtonBox::ResetRole); - connect(buttonFolder, &QPushButton::clicked, this, &IconPickerDialog::openFolder); -} - -bool IconPickerDialog::eventFilter(QObject *obj, QEvent *evt) -{ - if (obj != ui->iconView) - return QDialog::eventFilter(obj, evt); - if (evt->type() != QEvent::KeyPress) - { - return QDialog::eventFilter(obj, evt); - } - QKeyEvent *keyEvent = static_cast<QKeyEvent *>(evt); - switch (keyEvent->key()) - { - case Qt::Key_Delete: - removeSelectedIcon(); - return true; - case Qt::Key_Plus: - addNewIcon(); - return true; - default: - break; - } - return QDialog::eventFilter(obj, evt); -} - -void IconPickerDialog::addNewIcon() -{ - //: The title of the select icons open file dialog - QString selectIcons = tr("Select Icons"); - //: The type of icon files - auto filter = IconUtils::getIconFilter(); - QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(), tr("Icons %1").arg(filter)); - APPLICATION->icons()->installIcons(fileNames); -} - -void IconPickerDialog::removeSelectedIcon() -{ - APPLICATION->icons()->deleteIcon(selectedIconKey); -} - -void IconPickerDialog::activated(QModelIndex index) -{ - selectedIconKey = index.data(Qt::UserRole).toString(); - accept(); -} - -void IconPickerDialog::selectionChanged(QItemSelection selected, QItemSelection deselected) -{ - if (selected.empty()) - return; - - QString key = selected.first().indexes().first().data(Qt::UserRole).toString(); - if (!key.isEmpty()) { - selectedIconKey = key; - } -} - -int IconPickerDialog::execWithSelection(QString selection) -{ - auto list = APPLICATION->icons(); - auto contentsWidget = ui->iconView; - selectedIconKey = selection; - - int index_nr = list->getIconIndex(selection); - auto model_index = list->index(index_nr); - contentsWidget->selectionModel()->select( - model_index, QItemSelectionModel::Current | QItemSelectionModel::Select); - - QMetaObject::invokeMethod(this, "delayed_scroll", Qt::QueuedConnection, Q_ARG(QModelIndex, model_index)); - return QDialog::exec(); -} - -void IconPickerDialog::delayed_scroll(QModelIndex model_index) -{ - auto contentsWidget = ui->iconView; - contentsWidget->scrollTo(model_index); -} - -IconPickerDialog::~IconPickerDialog() -{ - delete ui; -} - -void IconPickerDialog::openFolder() -{ - DesktopServices::openDirectory(APPLICATION->icons()->getDirectory(), true); -} diff --git a/launcher/dialogs/IconPickerDialog.h b/launcher/dialogs/IconPickerDialog.h deleted file mode 100644 index 9af6a678..00000000 --- a/launcher/dialogs/IconPickerDialog.h +++ /dev/null @@ -1,49 +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 <QDialog> -#include <QItemSelection> - -namespace Ui -{ -class IconPickerDialog; -} - -class IconPickerDialog : public QDialog -{ - Q_OBJECT - -public: - explicit IconPickerDialog(QWidget *parent = 0); - ~IconPickerDialog(); - int execWithSelection(QString selection); - QString selectedIconKey; - -protected: - virtual bool eventFilter(QObject *, QEvent *); - -private: - Ui::IconPickerDialog *ui; - -private -slots: - void selectionChanged(QItemSelection, QItemSelection); - void activated(QModelIndex); - void delayed_scroll(QModelIndex); - void addNewIcon(); - void removeSelectedIcon(); - void openFolder(); -}; diff --git a/launcher/dialogs/IconPickerDialog.ui b/launcher/dialogs/IconPickerDialog.ui deleted file mode 100644 index c548edfb..00000000 --- a/launcher/dialogs/IconPickerDialog.ui +++ /dev/null @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>IconPickerDialog</class> - <widget class="QDialog" name="IconPickerDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>676</width> - <height>555</height> - </rect> - </property> - <property name="windowTitle"> - <string>Pick icon</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QListView" name="iconView"/> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>IconPickerDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>IconPickerDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/launcher/dialogs/LoginDialog.cpp b/launcher/dialogs/LoginDialog.cpp deleted file mode 100644 index bf0806e1..00000000 --- a/launcher/dialogs/LoginDialog.cpp +++ /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. - */ - -#include "LoginDialog.h" -#include "ui_LoginDialog.h" - -#include "minecraft/auth/AccountTask.h" - -#include <QtWidgets/QPushButton> - -LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::LoginDialog) -{ - ui->setupUi(this); - ui->progressBar->setVisible(false); - ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); - - connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); -} - -LoginDialog::~LoginDialog() -{ - delete ui; -} - -// Stage 1: User interaction -void LoginDialog::accept() -{ - setUserInputsEnabled(false); - ui->progressBar->setVisible(true); - - // Setup the login task and start it - m_account = MinecraftAccount::createFromUsername(ui->userTextBox->text()); - m_loginTask = m_account->login(nullptr, 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); - connect(m_loginTask.get(), &Task::progress, this, &LoginDialog::onTaskProgress); - m_loginTask->start(); -} - -void LoginDialog::setUserInputsEnabled(bool enable) -{ - ui->userTextBox->setEnabled(enable); - ui->passTextBox->setEnabled(enable); - ui->buttonBox->setEnabled(enable); -} - -// Enable the OK button only when both textboxes contain something. -void LoginDialog::on_userTextBox_textEdited(const QString &newText) -{ - ui->buttonBox->button(QDialogButtonBox::Ok) - ->setEnabled(!newText.isEmpty() && !ui->passTextBox->text().isEmpty()); -} -void LoginDialog::on_passTextBox_textEdited(const QString &newText) -{ - ui->buttonBox->button(QDialogButtonBox::Ok) - ->setEnabled(!newText.isEmpty() && !ui->userTextBox->text().isEmpty()); -} - -void LoginDialog::onTaskFailed(const QString &reason) -{ - // Set message - auto lines = reason.split('\n'); - QString processed; - for(auto line: lines) { - if(line.size()) { - processed += "<font color='red'>" + line + "</font><br />"; - } - else { - processed += "<br />"; - } - } - ui->label->setText(processed); - - // Re-enable user-interaction - setUserInputsEnabled(true); - ui->progressBar->setVisible(false); -} - -void LoginDialog::onTaskSucceeded() -{ - QDialog::accept(); -} - -void LoginDialog::onTaskStatus(const QString &status) -{ - ui->label->setText(status); -} - -void LoginDialog::onTaskProgress(qint64 current, qint64 total) -{ - ui->progressBar->setMaximum(total); - ui->progressBar->setValue(current); -} - -// Public interface -MinecraftAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg) -{ - LoginDialog dlg(parent); - dlg.ui->label->setText(msg); - if (dlg.exec() == QDialog::Accepted) - { - return dlg.m_account; - } - return 0; -} diff --git a/launcher/dialogs/LoginDialog.h b/launcher/dialogs/LoginDialog.h deleted file mode 100644 index f8101ff5..00000000 --- a/launcher/dialogs/LoginDialog.h +++ /dev/null @@ -1,59 +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 <QtWidgets/QDialog> -#include <QtCore/QEventLoop> - -#include "minecraft/auth/MinecraftAccount.h" -#include "tasks/Task.h" - -namespace Ui -{ -class LoginDialog; -} - -class LoginDialog : public QDialog -{ - Q_OBJECT - -public: - ~LoginDialog(); - - static MinecraftAccountPtr newAccount(QWidget *parent, QString message); - -private: - explicit LoginDialog(QWidget *parent = 0); - - void setUserInputsEnabled(bool enable); - -protected -slots: - void accept(); - - void onTaskFailed(const QString &reason); - void onTaskSucceeded(); - void onTaskStatus(const QString &status); - void onTaskProgress(qint64 current, qint64 total); - - void on_userTextBox_textEdited(const QString &newText); - void on_passTextBox_textEdited(const QString &newText); - -private: - Ui::LoginDialog *ui; - MinecraftAccountPtr m_account; - Task::Ptr m_loginTask; -}; diff --git a/launcher/dialogs/LoginDialog.ui b/launcher/dialogs/LoginDialog.ui deleted file mode 100644 index 8fa4a45d..00000000 --- a/launcher/dialogs/LoginDialog.ui +++ /dev/null @@ -1,77 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>LoginDialog</class> - <widget class="QDialog" name="LoginDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>421</width> - <height>198</height> - </rect> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="windowTitle"> - <string>Add Account</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string notr="true">Message label placeholder.</string> - </property> - <property name="textFormat"> - <enum>Qt::RichText</enum> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="userTextBox"> - <property name="placeholderText"> - <string>Email</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="passTextBox"> - <property name="echoMode"> - <enum>QLineEdit::Password</enum> - </property> - <property name="placeholderText"> - <string>Password</string> - </property> - </widget> - </item> - <item> - <widget class="QProgressBar" name="progressBar"> - <property name="value"> - <number>24</number> - </property> - <property name="textVisible"> - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/MSALoginDialog.cpp b/launcher/dialogs/MSALoginDialog.cpp deleted file mode 100644 index 15c04061..00000000 --- a/launcher/dialogs/MSALoginDialog.cpp +++ /dev/null @@ -1,141 +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 "MSALoginDialog.h" -#include "ui_MSALoginDialog.h" - -#include "minecraft/auth/AccountTask.h" - -#include <QtWidgets/QPushButton> -#include <QUrl> - -MSALoginDialog::MSALoginDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MSALoginDialog) -{ - ui->setupUi(this); - ui->progressBar->setVisible(false); - // ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false); - - connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); -} - -int MSALoginDialog::exec() { - setUserInputsEnabled(false); - ui->progressBar->setVisible(true); - - // Setup the login task and start it - m_account = MinecraftAccount::createBlankMSA(); - m_loginTask = m_account->loginMSA(nullptr); - 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); - connect(m_loginTask.get(), &Task::progress, this, &MSALoginDialog::onTaskProgress); - connect(m_loginTask.get(), &AccountTask::showVerificationUriAndCode, this, &MSALoginDialog::showVerificationUriAndCode); - connect(m_loginTask.get(), &AccountTask::hideVerificationUriAndCode, this, &MSALoginDialog::hideVerificationUriAndCode); - connect(&m_externalLoginTimer, &QTimer::timeout, this, &MSALoginDialog::externalLoginTick); - m_loginTask->start(); - - return QDialog::exec(); -} - - -MSALoginDialog::~MSALoginDialog() -{ - delete ui; -} - -void MSALoginDialog::externalLoginTick() { - m_externalLoginElapsed++; - ui->progressBar->setValue(m_externalLoginElapsed); - ui->progressBar->repaint(); - - if(m_externalLoginElapsed >= m_externalLoginTimeout) { - m_externalLoginTimer.stop(); - } -} - - -void MSALoginDialog::showVerificationUriAndCode(const QUrl& uri, const QString& code, int expiresIn) { - m_externalLoginElapsed = 0; - m_externalLoginTimeout = expiresIn; - - m_externalLoginTimer.setInterval(1000); - m_externalLoginTimer.setSingleShot(false); - m_externalLoginTimer.start(); - - ui->progressBar->setMaximum(expiresIn); - ui->progressBar->setValue(m_externalLoginElapsed); - - QString urlString = uri.toString(); - QString linkString = QString("<a href=\"%1\">%2</a>").arg(urlString, urlString); - ui->label->setText(tr("<p>Please open up %1 in a browser and put in the code <b>%2</b> to proceed with login.</p>").arg(linkString, code)); -} - -void MSALoginDialog::hideVerificationUriAndCode() { - m_externalLoginTimer.stop(); -} - -void MSALoginDialog::setUserInputsEnabled(bool enable) -{ - ui->buttonBox->setEnabled(enable); -} - -void MSALoginDialog::onTaskFailed(const QString &reason) -{ - // Set message - auto lines = reason.split('\n'); - QString processed; - for(auto line: lines) { - if(line.size()) { - processed += "<font color='red'>" + line + "</font><br />"; - } - else { - processed += "<br />"; - } - } - ui->label->setText(processed); - - // Re-enable user-interaction - setUserInputsEnabled(true); - ui->progressBar->setVisible(false); -} - -void MSALoginDialog::onTaskSucceeded() -{ - QDialog::accept(); -} - -void MSALoginDialog::onTaskStatus(const QString &status) -{ - ui->label->setText(status); -} - -void MSALoginDialog::onTaskProgress(qint64 current, qint64 total) -{ - ui->progressBar->setMaximum(total); - ui->progressBar->setValue(current); -} - -// Public interface -MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent, QString msg) -{ - MSALoginDialog dlg(parent); - dlg.ui->label->setText(msg); - if (dlg.exec() == QDialog::Accepted) - { - return dlg.m_account; - } - return 0; -} diff --git a/launcher/dialogs/MSALoginDialog.h b/launcher/dialogs/MSALoginDialog.h deleted file mode 100644 index 4cf146ab..00000000 --- a/launcher/dialogs/MSALoginDialog.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 <QtWidgets/QDialog> -#include <QtCore/QEventLoop> -#include <QTimer> - -#include "minecraft/auth/MinecraftAccount.h" - -namespace Ui -{ -class MSALoginDialog; -} - -class MSALoginDialog : public QDialog -{ - Q_OBJECT - -public: - ~MSALoginDialog(); - - static MinecraftAccountPtr newAccount(QWidget *parent, QString message); - int exec() override; - -private: - explicit MSALoginDialog(QWidget *parent = 0); - - void setUserInputsEnabled(bool enable); - -protected -slots: - void onTaskFailed(const QString &reason); - void onTaskSucceeded(); - void onTaskStatus(const QString &status); - void onTaskProgress(qint64 current, qint64 total); - void showVerificationUriAndCode(const QUrl &uri, const QString &code, int expiresIn); - void hideVerificationUriAndCode(); - - void externalLoginTick(); - -private: - Ui::MSALoginDialog *ui; - MinecraftAccountPtr m_account; - shared_qobject_ptr<AccountTask> m_loginTask; - QTimer m_externalLoginTimer; - int m_externalLoginElapsed = 0; - int m_externalLoginTimeout = 0; -}; - diff --git a/launcher/dialogs/MSALoginDialog.ui b/launcher/dialogs/MSALoginDialog.ui deleted file mode 100644 index 78cbfb26..00000000 --- a/launcher/dialogs/MSALoginDialog.ui +++ /dev/null @@ -1,65 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>MSALoginDialog</class> - <widget class="QDialog" name="MSALoginDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>491</width> - <height>143</height> - </rect> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="windowTitle"> - <string>Add Microsoft Account</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string notr="true">Message label placeholder. - -aaaaa</string> - </property> - <property name="textFormat"> - <enum>Qt::RichText</enum> - </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="QProgressBar" name="progressBar"> - <property name="value"> - <number>24</number> - </property> - <property name="textVisible"> - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/NewComponentDialog.cpp b/launcher/dialogs/NewComponentDialog.cpp deleted file mode 100644 index 1bbafb0c..00000000 --- a/launcher/dialogs/NewComponentDialog.cpp +++ /dev/null @@ -1,106 +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 "Application.h" -#include "NewComponentDialog.h" -#include "ui_NewComponentDialog.h" - -#include <BaseVersion.h> -#include <icons/IconList.h> -#include <tasks/Task.h> -#include <InstanceList.h> - -#include "VersionSelectDialog.h" -#include "ProgressDialog.h" -#include "IconPickerDialog.h" - -#include <QLayout> -#include <QPushButton> -#include <QFileDialog> -#include <QValidator> - -#include <meta/Index.h> -#include <meta/VersionList.h> - -NewComponentDialog::NewComponentDialog(const QString & initialName, const QString & initialUid, QWidget *parent) - : QDialog(parent), ui(new Ui::NewComponentDialog) -{ - ui->setupUi(this); - resize(minimumSizeHint()); - - ui->nameTextBox->setText(initialName); - ui->uidTextBox->setText(initialUid); - - connect(ui->nameTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState); - connect(ui->uidTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState); - - auto groups = APPLICATION->instances()->getGroups().toSet(); - ui->nameTextBox->setFocus(); - - originalPlaceholderText = ui->uidTextBox->placeholderText(); - updateDialogState(); -} - -NewComponentDialog::~NewComponentDialog() -{ - delete ui; -} - -void NewComponentDialog::updateDialogState() -{ - auto protoUid = ui->nameTextBox->text().toLower(); - protoUid.remove(QRegularExpression("[^a-z]")); - if(protoUid.isEmpty()) - { - ui->uidTextBox->setPlaceholderText(originalPlaceholderText); - } - else - { - QString suggestedUid = "org.multimc.custom." + protoUid; - ui->uidTextBox->setPlaceholderText(suggestedUid); - } - bool allowOK = !name().isEmpty() && !uid().isEmpty() && !uidBlacklist.contains(uid()); - ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowOK); -} - -QString NewComponentDialog::name() const -{ - auto result = ui->nameTextBox->text(); - if(result.size()) - { - return result.trimmed(); - } - return QString(); -} - -QString NewComponentDialog::uid() const -{ - auto result = ui->uidTextBox->text(); - if(result.size()) - { - return result.trimmed(); - } - result = ui->uidTextBox->placeholderText(); - if(result.size() && result != originalPlaceholderText) - { - return result.trimmed(); - } - return QString(); -} - -void NewComponentDialog::setBlacklist(QStringList badUids) -{ - uidBlacklist = badUids; -} diff --git a/launcher/dialogs/NewComponentDialog.h b/launcher/dialogs/NewComponentDialog.h deleted file mode 100644 index 8c790beb..00000000 --- a/launcher/dialogs/NewComponentDialog.h +++ /dev/null @@ -1,48 +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 <QDialog> - -#include <QString> -#include <QStringList> - -namespace Ui -{ -class NewComponentDialog; -} - -class NewComponentDialog : public QDialog -{ - Q_OBJECT - -public: - explicit NewComponentDialog(const QString & initialName = QString(), const QString & initialUid = QString(), QWidget *parent = 0); - virtual ~NewComponentDialog(); - void setBlacklist(QStringList badUids); - - QString name() const; - QString uid() const; - -private slots: - void updateDialogState(); - -private: - Ui::NewComponentDialog *ui; - - QString originalPlaceholderText; - QStringList uidBlacklist; -}; diff --git a/launcher/dialogs/NewComponentDialog.ui b/launcher/dialogs/NewComponentDialog.ui deleted file mode 100644 index 03b0d222..00000000 --- a/launcher/dialogs/NewComponentDialog.ui +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>NewComponentDialog</class> - <widget class="QDialog" name="NewComponentDialog"> - <property name="windowModality"> - <enum>Qt::ApplicationModal</enum> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>345</width> - <height>146</height> - </rect> - </property> - <property name="windowTitle"> - <string>Add Empty Component</string> - </property> - <property name="windowIcon"> - <iconset> - <normaloff>:/icons/toolbar/copy</normaloff>:/icons/toolbar/copy</iconset> - </property> - <property name="modal"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLineEdit" name="nameTextBox"> - <property name="placeholderText"> - <string>Name</string> - </property> - </widget> - </item> - <item> - <widget class="QLineEdit" name="uidTextBox"> - <property name="placeholderText"> - <string>uid</string> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>nameTextBox</tabstop> - <tabstop>uidTextBox</tabstop> - </tabstops> - <resources> - <include location="../../graphics.qrc"/> - </resources> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>NewComponentDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel"> - <x>248</x> - <y>254</y> - </hint> - <hint type="destinationlabel"> - <x>157</x> - <y>274</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>NewComponentDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel"> - <x>316</x> - <y>260</y> - </hint> - <hint type="destinationlabel"> - <x>286</x> - <y>274</y> - </hint> - </hints> - </connection> - </connections> -</ui> diff --git a/launcher/dialogs/NewInstanceDialog.cpp b/launcher/dialogs/NewInstanceDialog.cpp deleted file mode 100644 index a19f91b7..00000000 --- a/launcher/dialogs/NewInstanceDialog.cpp +++ /dev/null @@ -1,255 +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 "Application.h" -#include "NewInstanceDialog.h" -#include "ui_NewInstanceDialog.h" - -#include <BaseVersion.h> -#include <icons/IconList.h> -#include <tasks/Task.h> -#include <InstanceList.h> - -#include "VersionSelectDialog.h" -#include "ProgressDialog.h" -#include "IconPickerDialog.h" - -#include <QLayout> -#include <QPushButton> -#include <QFileDialog> -#include <QValidator> -#include <QDialogButtonBox> - -#include "widgets/PageContainer.h" -#include <pages/modplatform/VanillaPage.h> -#include <pages/modplatform/atlauncher/AtlPage.h> -#include <pages/modplatform/ftb/FtbPage.h> -#include <pages/modplatform/legacy_ftb/Page.h> -#include <pages/modplatform/flame/FlamePage.h> -#include <pages/modplatform/ImportPage.h> -#include <pages/modplatform/technic/TechnicPage.h> - - - -NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString & url, QWidget *parent) - : QDialog(parent), ui(new Ui::NewInstanceDialog) -{ - ui->setupUi(this); - - setWindowIcon(APPLICATION->getThemedIcon("new")); - - InstIconKey = "default"; - ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); - - auto groups = APPLICATION->instances()->getGroups().toSet(); - auto groupList = QStringList(groups.toList()); - groupList.sort(Qt::CaseInsensitive); - groupList.removeOne(""); - groupList.push_front(initialGroup); - groupList.push_front(""); - ui->groupBox->addItems(groupList); - int index = groupList.indexOf(initialGroup); - if(index == -1) - { - index = 0; - } - ui->groupBox->setCurrentIndex(index); - ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); - - - // NOTE: m_buttons must be initialized before PageContainer, because it indirectly accesses m_buttons through setSuggestedPack! Do not move this below. - m_buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - - m_container = new PageContainer(this); - m_container->setSizePolicy(QSizePolicy::Policy::Preferred, QSizePolicy::Policy::Expanding); - m_container->layout()->setContentsMargins(0, 0, 0, 0); - ui->verticalLayout->insertWidget(2, m_container); - - m_container->addButtons(m_buttons); - - // Bonk Qt over its stupid head and make sure it understands which button is the default one... - // See: https://stackoverflow.com/questions/24556831/qbuttonbox-set-default-button - auto OkButton = m_buttons->button(QDialogButtonBox::Ok); - OkButton->setDefault(true); - OkButton->setAutoDefault(true); - connect(OkButton, &QPushButton::clicked, this, &NewInstanceDialog::accept); - - auto CancelButton = m_buttons->button(QDialogButtonBox::Cancel); - CancelButton->setDefault(false); - CancelButton->setAutoDefault(false); - connect(CancelButton, &QPushButton::clicked, this, &NewInstanceDialog::reject); - - auto HelpButton = m_buttons->button(QDialogButtonBox::Help); - HelpButton->setDefault(false); - HelpButton->setAutoDefault(false); - connect(HelpButton, &QPushButton::clicked, m_container, &PageContainer::help); - - if(!url.isEmpty()) - { - QUrl actualUrl(url); - m_container->selectPage("import"); - importPage->setUrl(url); - } - - updateDialogState(); - - restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("NewInstanceGeometry").toByteArray())); -} - -void NewInstanceDialog::reject() -{ - APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); - QDialog::reject(); -} - -void NewInstanceDialog::accept() -{ - APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); - importIconNow(); - QDialog::accept(); -} - -QList<BasePage *> NewInstanceDialog::getPages() -{ - importPage = new ImportPage(this); - flamePage = new FlamePage(this); - auto technicPage = new TechnicPage(this); - return - { - new VanillaPage(this), - importPage, - new AtlPage(this), - flamePage, - new FtbPage(this), - new LegacyFTB::Page(this), - technicPage - }; -} - -QString NewInstanceDialog::dialogTitle() -{ - return tr("New Instance"); -} - -NewInstanceDialog::~NewInstanceDialog() -{ - delete ui; -} - -void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task) -{ - creationTask.reset(task); - ui->instNameTextBox->setPlaceholderText(name); - - if(!task) - { - ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default")); - importIcon = false; - } - - auto allowOK = task && !instName().isEmpty(); - m_buttons->button(QDialogButtonBox::Ok)->setEnabled(allowOK); -} - -void NewInstanceDialog::setSuggestedIconFromFile(const QString &path, const QString &name) -{ - importIcon = true; - importIconPath = path; - importIconName = name; - - //Hmm, for some reason they can be to small - ui->iconButton->setIcon(QIcon(path)); -} - -void NewInstanceDialog::setSuggestedIcon(const QString &key) -{ - auto icon = APPLICATION->icons()->getIcon(key); - importIcon = false; - - ui->iconButton->setIcon(icon); -} - -InstanceTask * NewInstanceDialog::extractTask() -{ - InstanceTask * extracted = creationTask.get(); - creationTask.release(); - extracted->setName(instName()); - extracted->setGroup(instGroup()); - extracted->setIcon(iconKey()); - return extracted; -} - -void NewInstanceDialog::updateDialogState() -{ - auto allowOK = creationTask && !instName().isEmpty(); - auto OkButton = m_buttons->button(QDialogButtonBox::Ok); - if(OkButton->isEnabled() != allowOK) - { - OkButton->setEnabled(allowOK); - } -} - -QString NewInstanceDialog::instName() const -{ - auto result = ui->instNameTextBox->text().trimmed(); - if(result.size()) - { - return result; - } - result = ui->instNameTextBox->placeholderText().trimmed(); - if(result.size()) - { - return result; - } - return QString(); -} - -QString NewInstanceDialog::instGroup() const -{ - return ui->groupBox->currentText(); -} -QString NewInstanceDialog::iconKey() const -{ - return InstIconKey; -} - -void NewInstanceDialog::on_iconButton_clicked() -{ - importIconNow(); //so the user can switch back - IconPickerDialog dlg(this); - dlg.execWithSelection(InstIconKey); - - if (dlg.result() == QDialog::Accepted) - { - InstIconKey = dlg.selectedIconKey; - ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey)); - importIcon = false; - } -} - -void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) -{ - updateDialogState(); -} - -void NewInstanceDialog::importIconNow() -{ - if(importIcon) { - APPLICATION->icons()->installIcon(importIconPath, importIconName); - InstIconKey = importIconName; - importIcon = false; - } - APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64()); -} diff --git a/launcher/dialogs/NewInstanceDialog.h b/launcher/dialogs/NewInstanceDialog.h deleted file mode 100644 index 53abf8cf..00000000 --- a/launcher/dialogs/NewInstanceDialog.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 <QDialog> - -#include "BaseVersion.h" -#include "pages/BasePageProvider.h" -#include "InstanceTask.h" - -namespace Ui -{ -class NewInstanceDialog; -} - -class PageContainer; -class QDialogButtonBox; -class ImportPage; -class FlamePage; - -class NewInstanceDialog : public QDialog, public BasePageProvider -{ - Q_OBJECT - -public: - explicit NewInstanceDialog(const QString & initialGroup, const QString & url = QString(), QWidget *parent = 0); - ~NewInstanceDialog(); - - void updateDialogState(); - - void setSuggestedPack(const QString & name = QString(), InstanceTask * task = nullptr); - void setSuggestedIconFromFile(const QString &path, const QString &name); - void setSuggestedIcon(const QString &key); - - InstanceTask * extractTask(); - - QString dialogTitle() override; - QList<BasePage *> getPages() override; - - QString instName() const; - QString instGroup() const; - QString iconKey() const; - -public slots: - void accept() override; - void reject() override; - -private slots: - void on_iconButton_clicked(); - void on_instNameTextBox_textChanged(const QString &arg1); - -private: - Ui::NewInstanceDialog *ui = nullptr; - PageContainer * m_container = nullptr; - QDialogButtonBox * m_buttons = nullptr; - - QString InstIconKey; - ImportPage *importPage = nullptr; - FlamePage *flamePage = nullptr; - std::unique_ptr<InstanceTask> creationTask; - - bool importIcon = false; - QString importIconPath; - QString importIconName; - - void importIconNow(); -}; diff --git a/launcher/dialogs/NewInstanceDialog.ui b/launcher/dialogs/NewInstanceDialog.ui deleted file mode 100644 index 7fb19ff5..00000000 --- a/launcher/dialogs/NewInstanceDialog.ui +++ /dev/null @@ -1,87 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>NewInstanceDialog</class> - <widget class="QDialog" name="NewInstanceDialog"> - <property name="windowModality"> - <enum>Qt::ApplicationModal</enum> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>730</width> - <height>127</height> - </rect> - </property> - <property name="windowTitle"> - <string>New Instance</string> - </property> - <property name="windowIcon"> - <iconset> - <normaloff>:/icons/toolbar/new</normaloff>:/icons/toolbar/new</iconset> - </property> - <property name="modal"> - <bool>true</bool> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="1" column="2"> - <widget class="QComboBox" name="groupBox"> - <property name="editable"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="groupLabel"> - <property name="text"> - <string>&Group:</string> - </property> - <property name="buddy"> - <cstring>groupBox</cstring> - </property> - </widget> - </item> - <item row="0" column="2"> - <widget class="QLineEdit" name="instNameTextBox"/> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="nameLabel"> - <property name="text"> - <string>&Name:</string> - </property> - <property name="buddy"> - <cstring>instNameTextBox</cstring> - </property> - </widget> - </item> - <item row="0" column="0" rowspan="2"> - <widget class="QToolButton" name="iconButton"> - <property name="iconSize"> - <size> - <width>80</width> - <height>80</height> - </size> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </widget> - <tabstops> - <tabstop>iconButton</tabstop> - <tabstop>instNameTextBox</tabstop> - <tabstop>groupBox</tabstop> - </tabstops> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/NotificationDialog.cpp b/launcher/dialogs/NotificationDialog.cpp deleted file mode 100644 index f2a35ae2..00000000 --- a/launcher/dialogs/NotificationDialog.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "NotificationDialog.h" -#include "ui_NotificationDialog.h" - -#include <QTimerEvent> -#include <QStyle> - -NotificationDialog::NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent) : - QDialog(parent, Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::CustomizeWindowHint), - ui(new Ui::NotificationDialog) -{ - ui->setupUi(this); - - QStyle::StandardPixmap icon; - switch (entry.type) - { - case NotificationChecker::NotificationEntry::Critical: - icon = QStyle::SP_MessageBoxCritical; - break; - case NotificationChecker::NotificationEntry::Warning: - icon = QStyle::SP_MessageBoxWarning; - break; - default: - case NotificationChecker::NotificationEntry::Information: - icon = QStyle::SP_MessageBoxInformation; - break; - } - ui->iconLabel->setPixmap(style()->standardPixmap(icon, 0, this)); - ui->messageLabel->setText(entry.message); - - m_dontShowAgainText = tr("Don't show again"); - m_closeText = tr("Close"); - - ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime)); - ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime)); - - startTimer(1000); -} - -NotificationDialog::~NotificationDialog() -{ - delete ui; -} - -void NotificationDialog::timerEvent(QTimerEvent *event) -{ - if (m_dontShowAgainTime > 0) - { - m_dontShowAgainTime--; - if (m_dontShowAgainTime == 0) - { - ui->dontShowAgainBtn->setText(m_dontShowAgainText); - ui->dontShowAgainBtn->setEnabled(true); - } - else - { - ui->dontShowAgainBtn->setText(m_dontShowAgainText + QString(" (%1)").arg(m_dontShowAgainTime)); - } - } - if (m_closeTime > 0) - { - m_closeTime--; - if (m_closeTime == 0) - { - ui->closeBtn->setText(m_closeText); - ui->closeBtn->setEnabled(true); - } - else - { - ui->closeBtn->setText(m_closeText + QString(" (%1)").arg(m_closeTime)); - } - } - - if (m_closeTime == 0 && m_dontShowAgainTime == 0) - { - killTimer(event->timerId()); - } -} - -void NotificationDialog::on_dontShowAgainBtn_clicked() -{ - done(DontShowAgain); -} -void NotificationDialog::on_closeBtn_clicked() -{ - done(Normal); -} diff --git a/launcher/dialogs/NotificationDialog.h b/launcher/dialogs/NotificationDialog.h deleted file mode 100644 index e1cbb9fa..00000000 --- a/launcher/dialogs/NotificationDialog.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef NOTIFICATIONDIALOG_H -#define NOTIFICATIONDIALOG_H - -#include <QDialog> - -#include "notifications/NotificationChecker.h" - -namespace Ui { -class NotificationDialog; -} - -class NotificationDialog : public QDialog -{ - Q_OBJECT - -public: - explicit NotificationDialog(const NotificationChecker::NotificationEntry &entry, QWidget *parent = 0); - ~NotificationDialog(); - - enum ExitCode - { - Normal, - DontShowAgain - }; - -protected: - void timerEvent(QTimerEvent *event); - -private: - Ui::NotificationDialog *ui; - - int m_dontShowAgainTime = 10; - int m_closeTime = 5; - - QString m_dontShowAgainText; - QString m_closeText; - -private -slots: - void on_dontShowAgainBtn_clicked(); - void on_closeBtn_clicked(); -}; - -#endif // NOTIFICATIONDIALOG_H diff --git a/launcher/dialogs/NotificationDialog.ui b/launcher/dialogs/NotificationDialog.ui deleted file mode 100644 index 3e6c22bc..00000000 --- a/launcher/dialogs/NotificationDialog.ui +++ /dev/null @@ -1,85 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>NotificationDialog</class> - <widget class="QDialog" name="NotificationDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>320</width> - <height>240</height> - </rect> - </property> - <property name="windowTitle"> - <string>Notification</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,1"> - <item> - <widget class="QLabel" name="iconLabel"> - <property name="text"> - <string notr="true">TextLabel</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="messageLabel"> - <property name="text"> - <string notr="true">TextLabel</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - <property name="textInteractionFlags"> - <set>Qt::TextBrowserInteraction</set> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <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="dontShowAgainBtn"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Don't show again</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="closeBtn"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Close</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/ProfileSelectDialog.cpp b/launcher/dialogs/ProfileSelectDialog.cpp deleted file mode 100644 index 0e3e493c..00000000 --- a/launcher/dialogs/ProfileSelectDialog.cpp +++ /dev/null @@ -1,116 +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 "ProfileSelectDialog.h" -#include <SkinUtils.h> -#include "ui_ProfileSelectDialog.h" - -#include <QItemSelectionModel> - -#include <QDebug> - -#include <dialogs/ProgressDialog.h> - -#include <Application.h> - -ProfileSelectDialog::ProfileSelectDialog(const QString &message, int flags, QWidget *parent) - : QDialog(parent), ui(new Ui::ProfileSelectDialog) -{ - ui->setupUi(this); - - m_accounts = APPLICATION->accounts(); - auto view = ui->listView; - //view->setModel(m_accounts.get()); - //view->hideColumn(AccountList::ActiveColumn); - view->setColumnCount(1); - view->setRootIsDecorated(false); - // FIXME: use a real model, not this - if(QTreeWidgetItem* header = view->headerItem()) - { - header->setText(0, tr("Name")); - } - else - { - view->setHeaderLabel(tr("Name")); - } - QList <QTreeWidgetItem *> items; - for (int i = 0; i < m_accounts->count(); i++) - { - MinecraftAccountPtr account = m_accounts->at(i); - QString profileLabel; - if(account->isInUse()) { - profileLabel = tr("%1 (in use)").arg(account->profileName()); - } - else { - profileLabel = account->profileName(); - } - auto item = new QTreeWidgetItem(view); - item->setText(0, profileLabel); - item->setIcon(0, account->getFace()); - item->setData(0, AccountList::PointerRole, QVariant::fromValue(account)); - items.append(item); - } - view->addTopLevelItems(items); - - // Set the message label. - ui->msgLabel->setVisible(!message.isEmpty()); - ui->msgLabel->setText(message); - - // Flags... - ui->globalDefaultCheck->setVisible(flags & GlobalDefaultCheckbox); - ui->instDefaultCheck->setVisible(flags & InstanceDefaultCheckbox); - qDebug() << flags; - - // Select the first entry in the list. - ui->listView->setCurrentIndex(ui->listView->model()->index(0, 0)); - - connect(ui->listView, SIGNAL(doubleClicked(QModelIndex)), SLOT(on_buttonBox_accepted())); -} - -ProfileSelectDialog::~ProfileSelectDialog() -{ - delete ui; -} - -MinecraftAccountPtr ProfileSelectDialog::selectedAccount() const -{ - return m_selected; -} - -bool ProfileSelectDialog::useAsGlobalDefault() const -{ - return ui->globalDefaultCheck->isChecked(); -} - -bool ProfileSelectDialog::useAsInstDefaullt() const -{ - return ui->instDefaultCheck->isChecked(); -} - -void ProfileSelectDialog::on_buttonBox_accepted() -{ - QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); - if (selection.size() > 0) - { - QModelIndex selected = selection.first(); - m_selected = selected.data(AccountList::PointerRole).value<MinecraftAccountPtr>(); - } - close(); -} - -void ProfileSelectDialog::on_buttonBox_rejected() -{ - close(); -} diff --git a/launcher/dialogs/ProfileSelectDialog.h b/launcher/dialogs/ProfileSelectDialog.h deleted file mode 100644 index 38aa4249..00000000 --- a/launcher/dialogs/ProfileSelectDialog.h +++ /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. - */ - -#pragma once - -#include <QDialog> - -#include <memory> - -#include "minecraft/auth/AccountList.h" - -namespace Ui -{ -class ProfileSelectDialog; -} - -class ProfileSelectDialog : public QDialog -{ - Q_OBJECT -public: - enum Flags - { - NoFlags = 0, - - /*! - * Shows a check box on the dialog that allows the user to specify that the account - * they've selected should be used as the global default for all instances. - */ - GlobalDefaultCheckbox, - - /*! - * Shows a check box on the dialog that allows the user to specify that the account - * they've selected should be used as the default for the instance they are currently launching. - * This is not currently implemented. - */ - InstanceDefaultCheckbox, - }; - - /*! - * Constructs a new account select dialog with the given parent and message. - * The message will be shown at the top of the dialog. It is an empty string by default. - */ - explicit ProfileSelectDialog(const QString& message="", int flags=0, QWidget *parent = 0); - ~ProfileSelectDialog(); - - /*! - * Gets a pointer to the account that the user selected. - * This is null if the user clicked cancel or hasn't clicked OK yet. - */ - MinecraftAccountPtr selectedAccount() const; - - /*! - * Returns true if the user checked the "use as global default" checkbox. - * If the checkbox wasn't shown, this function returns false. - */ - bool useAsGlobalDefault() const; - - /*! - * Returns true if the user checked the "use as instance default" checkbox. - * If the checkbox wasn't shown, this function returns false. - */ - bool useAsInstDefaullt() const; - -public -slots: - void on_buttonBox_accepted(); - - void on_buttonBox_rejected(); - -protected: - shared_qobject_ptr<AccountList> m_accounts; - - //! The account that was selected when the user clicked OK. - MinecraftAccountPtr m_selected; - -private: - Ui::ProfileSelectDialog *ui; -}; diff --git a/launcher/dialogs/ProfileSelectDialog.ui b/launcher/dialogs/ProfileSelectDialog.ui deleted file mode 100644 index e779b51b..00000000 --- a/launcher/dialogs/ProfileSelectDialog.ui +++ /dev/null @@ -1,62 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ProfileSelectDialog</class> - <widget class="QDialog" name="ProfileSelectDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>465</width> - <height>300</height> - </rect> - </property> - <property name="windowTitle"> - <string>Select an Account</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QLabel" name="msgLabel"> - <property name="text"> - <string>Select a profile.</string> - </property> - </widget> - </item> - <item> - <widget class="QTreeWidget" name="listView"> - <column> - <property name="text"> - <string notr="true">1</string> - </property> - </column> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QCheckBox" name="globalDefaultCheck"> - <property name="text"> - <string>Use as default?</string> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="instDefaultCheck"> - <property name="text"> - <string>Use as default for this instance only?</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/ProfileSetupDialog.cpp b/launcher/dialogs/ProfileSetupDialog.cpp deleted file mode 100644 index 51c20202..00000000 --- a/launcher/dialogs/ProfileSetupDialog.cpp +++ /dev/null @@ -1,250 +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 "ProfileSetupDialog.h" -#include "ui_ProfileSetupDialog.h" - -#include <QPushButton> -#include <QAction> -#include <QRegExpValidator> -#include <QDebug> - -#include <dialogs/ProgressDialog.h> - -#include <Application.h> -#include <minecraft/auth/flows/AuthRequest.h> -#include <minecraft/auth/flows/Parsers.h> - -#include <QJsonDocument> - -ProfileSetupDialog::ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent) - : QDialog(parent), m_accountToSetup(accountToSetup), ui(new Ui::ProfileSetupDialog) -{ - ui->setupUi(this); - ui->errorLabel->setVisible(false); - - goodIcon = APPLICATION->getThemedIcon("status-good"); - yellowIcon = APPLICATION->getThemedIcon("status-yellow"); - badIcon = APPLICATION->getThemedIcon("status-bad"); - - QRegExp permittedNames("[a-zA-Z0-9_]{3,16}"); - auto nameEdit = ui->nameEdit; - nameEdit->setValidator(new QRegExpValidator(permittedNames)); - nameEdit->setClearButtonEnabled(true); - validityAction = nameEdit->addAction(yellowIcon, QLineEdit::LeadingPosition); - connect(nameEdit, &QLineEdit::textEdited, this, &ProfileSetupDialog::nameEdited); - - checkStartTimer.setSingleShot(true); - connect(&checkStartTimer, &QTimer::timeout, this, &ProfileSetupDialog::startCheck); - - setNameStatus(NameStatus::NotSet, QString()); -} - -ProfileSetupDialog::~ProfileSetupDialog() -{ - delete ui; -} - -void ProfileSetupDialog::on_buttonBox_accepted() -{ - setupProfile(currentCheck); -} - -void ProfileSetupDialog::on_buttonBox_rejected() -{ - reject(); -} - -void ProfileSetupDialog::setNameStatus(ProfileSetupDialog::NameStatus status, QString errorString = QString()) -{ - nameStatus = status; - auto okButton = ui->buttonBox->button(QDialogButtonBox::Ok); - switch(nameStatus) - { - case NameStatus::Available: { - validityAction->setIcon(goodIcon); - okButton->setEnabled(true); - } - break; - case NameStatus::NotSet: - case NameStatus::Pending: - validityAction->setIcon(yellowIcon); - okButton->setEnabled(false); - break; - case NameStatus::Exists: - case NameStatus::Error: - validityAction->setIcon(badIcon); - okButton->setEnabled(false); - break; - } - if(!errorString.isEmpty()) { - ui->errorLabel->setText(errorString); - ui->errorLabel->setVisible(true); - } - else { - ui->errorLabel->setVisible(false); - } -} - -void ProfileSetupDialog::nameEdited(const QString& name) -{ - if(!ui->nameEdit->hasAcceptableInput()) { - setNameStatus(NameStatus::NotSet, tr("Name is too short - must be between 3 and 16 characters long.")); - return; - } - scheduleCheck(name); -} - -void ProfileSetupDialog::scheduleCheck(const QString& name) { - queuedCheck = name; - setNameStatus(NameStatus::Pending); - checkStartTimer.start(1000); -} - -void ProfileSetupDialog::startCheck() { - if(isChecking) { - return; - } - if(queuedCheck.isNull()) { - return; - } - checkName(queuedCheck); -} - - -void ProfileSetupDialog::checkName(const QString &name) { - if(isChecking) { - return; - } - - currentCheck = name; - isChecking = true; - - auto token = m_accountToSetup->accessToken(); - - auto url = QString("https://api.minecraftservices.com/minecraft/profile/name/%1/available").arg(name); - QNetworkRequest request = QNetworkRequest(url); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - request.setRawHeader("Accept", "application/json"); - request.setRawHeader("Authorization", QString("Bearer %1").arg(token).toUtf8()); - - AuthRequest *requestor = new AuthRequest(this); - connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::checkFinished); - requestor->get(request); -} - -void ProfileSetupDialog::checkFinished( - QNetworkReply::NetworkError error, - QByteArray data, - QList<QNetworkReply::RawHeaderPair> headers -) { - if(error == QNetworkReply::NoError) { - auto doc = QJsonDocument::fromJson(data); - auto root = doc.object(); - auto statusValue = root.value("status").toString("INVALID"); - if(statusValue == "AVAILABLE") { - setNameStatus(NameStatus::Available); - } - else if (statusValue == "DUPLICATE") { - setNameStatus(NameStatus::Exists, tr("Minecraft profile with name %1 already exists.").arg(currentCheck)); - } - else if (statusValue == "NOT_ALLOWED") { - setNameStatus(NameStatus::Exists, tr("The name %1 is not allowed.").arg(currentCheck)); - } - else { - setNameStatus(NameStatus::Error, tr("Unhandled profile name status: %1").arg(statusValue)); - } - } - else { - setNameStatus(NameStatus::Error, tr("Failed to check name availability.")); - } - isChecking = false; -} - -void ProfileSetupDialog::setupProfile(const QString &profileName) { - if(isWorking) { - return; - } - - auto token = m_accountToSetup->accessToken(); - - auto url = QString("https://api.minecraftservices.com/minecraft/profile"); - QNetworkRequest request = QNetworkRequest(url); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - request.setRawHeader("Accept", "application/json"); - request.setRawHeader("Authorization", QString("Bearer %1").arg(token).toUtf8()); - - QString payloadTemplate("{\"profileName\":\"%1\"}"); - auto data = payloadTemplate.arg(profileName).toUtf8(); - - AuthRequest *requestor = new AuthRequest(this); - connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::setupProfileFinished); - requestor->post(request, data); - isWorking = true; - - auto button = ui->buttonBox->button(QDialogButtonBox::Cancel); - button->setEnabled(false); -} - -namespace { - -struct MojangError{ - static MojangError fromJSON(QByteArray data) { - MojangError out; - out.error = QString::fromUtf8(data); - auto doc = QJsonDocument::fromJson(data, &out.parseError); - auto object = doc.object(); - - out.fullyParsed = true; - out.fullyParsed &= Parsers::getString(object.value("path"), out.path); - out.fullyParsed &= Parsers::getString(object.value("error"), out.error); - out.fullyParsed &= Parsers::getString(object.value("errorMessage"), out.errorMessage); - - return out; - } - - QString rawError; - QJsonParseError parseError; - bool fullyParsed; - - QString path; - QString error; - QString errorMessage; -}; - -} - -void ProfileSetupDialog::setupProfileFinished( - QNetworkReply::NetworkError error, - QByteArray data, - QList<QNetworkReply::RawHeaderPair> headers -) { - isWorking = false; - if(error == QNetworkReply::NoError) { - /* - * data contains the profile in the response - * ... we could parse it and update the account, but let's just return back to the normal login flow instead... - */ - accept(); - } - else { - auto parsedError = MojangError::fromJSON(data); - ui->errorLabel->setVisible(true); - ui->errorLabel->setText(tr("The server returned the following error:") + "\n\n" + parsedError.errorMessage); - qDebug() << parsedError.rawError; - auto button = ui->buttonBox->button(QDialogButtonBox::Cancel); - button->setEnabled(true); - } -} diff --git a/launcher/dialogs/ProfileSetupDialog.h b/launcher/dialogs/ProfileSetupDialog.h deleted file mode 100644 index 6f413ebd..00000000 --- a/launcher/dialogs/ProfileSetupDialog.h +++ /dev/null @@ -1,88 +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 <QDialog> -#include <QIcon> -#include <QTimer> -#include <QNetworkReply> - -#include <memory> -#include <minecraft/auth/MinecraftAccount.h> - -namespace Ui -{ -class ProfileSetupDialog; -} - -class ProfileSetupDialog : public QDialog -{ - Q_OBJECT -public: - - explicit ProfileSetupDialog(MinecraftAccountPtr accountToSetup, QWidget *parent = 0); - ~ProfileSetupDialog(); - - enum class NameStatus - { - NotSet, - Pending, - Available, - Exists, - Error - } nameStatus = NameStatus::NotSet; - -private slots: - void on_buttonBox_accepted(); - void on_buttonBox_rejected(); - - void nameEdited(const QString &name); - void checkFinished( - QNetworkReply::NetworkError error, - QByteArray data, - QList<QNetworkReply::RawHeaderPair> headers - ); - void startCheck(); - - void setupProfileFinished( - QNetworkReply::NetworkError error, - QByteArray data, - QList<QNetworkReply::RawHeaderPair> headers - ); -protected: - void scheduleCheck(const QString &name); - void checkName(const QString &name); - void setNameStatus(NameStatus status, QString errorString); - - void setupProfile(const QString & profileName); - -private: - MinecraftAccountPtr m_accountToSetup; - Ui::ProfileSetupDialog *ui; - QIcon goodIcon; - QIcon yellowIcon; - QIcon badIcon; - QAction * validityAction = nullptr; - - QString queuedCheck; - - bool isChecking = false; - bool isWorking = false; - QString currentCheck; - - QTimer checkStartTimer; -}; - diff --git a/launcher/dialogs/ProfileSetupDialog.ui b/launcher/dialogs/ProfileSetupDialog.ui deleted file mode 100644 index 9dbabb4b..00000000 --- a/launcher/dialogs/ProfileSetupDialog.ui +++ /dev/null @@ -1,74 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ProfileSetupDialog</class> - <widget class="QDialog" name="ProfileSetupDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>615</width> - <height>208</height> - </rect> - </property> - <property name="windowTitle"> - <string>Choose Minecraft name</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0" colspan="2"> - <widget class="QLabel" name="descriptionLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>You just need to take one more step to be able to play Minecraft on this account. - -Choose your name carefully:</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="buddy"> - <cstring>nameEdit</cstring> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLineEdit" name="nameEdit"/> - </item> - <item row="4" column="0" colspan="2"> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="errorLabel"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string notr="true">Errors go here</string> - </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> - <tabstops> - <tabstop>nameEdit</tabstop> - </tabstops> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/ProgressDialog.cpp b/launcher/dialogs/ProgressDialog.cpp deleted file mode 100644 index 4b092859..00000000 --- a/launcher/dialogs/ProgressDialog.cpp +++ /dev/null @@ -1,196 +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 "ProgressDialog.h" -#include "ui_ProgressDialog.h" - -#include <QKeyEvent> -#include <QDebug> - -#include "tasks/Task.h" - -ProgressDialog::ProgressDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ProgressDialog) -{ - ui->setupUi(this); - this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); - setSkipButton(false); - changeProgress(0, 100); -} - -void ProgressDialog::setSkipButton(bool present, QString label) -{ - ui->skipButton->setAutoDefault(false); - ui->skipButton->setDefault(false); - ui->skipButton->setFocusPolicy(Qt::ClickFocus); - ui->skipButton->setEnabled(present); - ui->skipButton->setVisible(present); - ui->skipButton->setText(label); - updateSize(); -} - -void ProgressDialog::on_skipButton_clicked(bool checked) -{ - Q_UNUSED(checked); - task->abort(); -} - -ProgressDialog::~ProgressDialog() -{ - delete ui; -} - -void ProgressDialog::updateSize() -{ - QSize qSize = QSize(480, minimumSizeHint().height()); - resize(qSize); - setFixedSize(qSize); -} - -int ProgressDialog::execWithTask(Task *task) -{ - this->task = task; - QDialog::DialogCode result; - - if(!task) - { - qDebug() << "Programmer error: progress dialog created with null task."; - return Accepted; - } - - if(handleImmediateResult(result)) - { - return result; - } - - // Connect signals. - connect(task, SIGNAL(started()), SLOT(onTaskStarted())); - connect(task, SIGNAL(failed(QString)), SLOT(onTaskFailed(QString))); - connect(task, SIGNAL(succeeded()), SLOT(onTaskSucceeded())); - connect(task, SIGNAL(status(QString)), SLOT(changeStatus(const QString &))); - connect(task, SIGNAL(progress(qint64, qint64)), SLOT(changeProgress(qint64, qint64))); - - // if this didn't connect to an already running task, invoke start - if(!task->isRunning()) - { - task->start(); - } - if(task->isRunning()) - { - changeProgress(task->getProgress(), task->getTotalProgress()); - changeStatus(task->getStatus()); - return QDialog::exec(); - } - else if(handleImmediateResult(result)) - { - return result; - } - else - { - return QDialog::Rejected; - } -} - -// TODO: only provide the unique_ptr overloads -int ProgressDialog::execWithTask(std::unique_ptr<Task> &&task) -{ - connect(this, &ProgressDialog::destroyed, task.get(), &Task::deleteLater); - return execWithTask(task.release()); -} -int ProgressDialog::execWithTask(std::unique_ptr<Task> &task) -{ - connect(this, &ProgressDialog::destroyed, task.get(), &Task::deleteLater); - return execWithTask(task.release()); -} - -bool ProgressDialog::handleImmediateResult(QDialog::DialogCode &result) -{ - if(task->isFinished()) - { - if(task->wasSuccessful()) - { - result = QDialog::Accepted; - } - else - { - result = QDialog::Rejected; - } - return true; - } - return false; -} - -Task *ProgressDialog::getTask() -{ - return task; -} - -void ProgressDialog::onTaskStarted() -{ -} - -void ProgressDialog::onTaskFailed(QString failure) -{ - reject(); -} - -void ProgressDialog::onTaskSucceeded() -{ - accept(); -} - -void ProgressDialog::changeStatus(const QString &status) -{ - ui->statusLabel->setText(status); - updateSize(); -} - -void ProgressDialog::changeProgress(qint64 current, qint64 total) -{ - ui->taskProgressBar->setMaximum(total); - ui->taskProgressBar->setValue(current); -} - -void ProgressDialog::keyPressEvent(QKeyEvent *e) -{ - if(ui->skipButton->isVisible()) - { - if (e->key() == Qt::Key_Escape) - { - on_skipButton_clicked(true); - return; - } - else if(e->key() == Qt::Key_Tab) - { - ui->skipButton->setFocusPolicy(Qt::StrongFocus); - ui->skipButton->setFocus(); - ui->skipButton->setAutoDefault(true); - ui->skipButton->setDefault(true); - return; - } - } - QDialog::keyPressEvent(e); -} - -void ProgressDialog::closeEvent(QCloseEvent *e) -{ - if (task && task->isRunning()) - { - e->ignore(); - } - else - { - QDialog::closeEvent(e); - } -} diff --git a/launcher/dialogs/ProgressDialog.h b/launcher/dialogs/ProgressDialog.h deleted file mode 100644 index b28ad4fa..00000000 --- a/launcher/dialogs/ProgressDialog.h +++ /dev/null @@ -1,71 +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 <QDialog> -#include <memory> - -class Task; - -namespace Ui -{ -class ProgressDialog; -} - -class ProgressDialog : public QDialog -{ - Q_OBJECT - -public: - explicit ProgressDialog(QWidget *parent = 0); - ~ProgressDialog(); - - void updateSize(); - - int execWithTask(Task *task); - int execWithTask(std::unique_ptr<Task> &&task); - int execWithTask(std::unique_ptr<Task> &task); - - void setSkipButton(bool present, QString label = QString()); - - Task *getTask(); - -public -slots: - void onTaskStarted(); - void onTaskFailed(QString failure); - void onTaskSucceeded(); - - void changeStatus(const QString &status); - void changeProgress(qint64 current, qint64 total); - - -private -slots: - void on_skipButton_clicked(bool checked); - -protected: - virtual void keyPressEvent(QKeyEvent *e); - virtual void closeEvent(QCloseEvent *e); - -private: - bool handleImmediateResult(QDialog::DialogCode &result); - -private: - Ui::ProgressDialog *ui; - - Task *task; -}; diff --git a/launcher/dialogs/ProgressDialog.ui b/launcher/dialogs/ProgressDialog.ui deleted file mode 100644 index 04b8fef3..00000000 --- a/launcher/dialogs/ProgressDialog.ui +++ /dev/null @@ -1,66 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>ProgressDialog</class> - <widget class="QDialog" name="ProgressDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>400</width> - <height>100</height> - </rect> - </property> - <property name="minimumSize"> - <size> - <width>400</width> - <height>0</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>600</width> - <height>16777215</height> - </size> - </property> - <property name="windowTitle"> - <string>Please wait...</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QLabel" name="statusLabel"> - <property name="text"> - <string>Task Status...</string> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QProgressBar" name="taskProgressBar"> - <property name="value"> - <number>24</number> - </property> - <property name="textVisible"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QPushButton" name="skipButton"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Skip</string> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/SkinUploadDialog.cpp b/launcher/dialogs/SkinUploadDialog.cpp deleted file mode 100644 index 4e6142fa..00000000 --- a/launcher/dialogs/SkinUploadDialog.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include <QFileInfo> -#include <QFileDialog> -#include <QPainter> - -#include <FileSystem.h> - -#include <minecraft/services/SkinUpload.h> -#include <minecraft/services/CapeChange.h> -#include <tasks/SequentialTask.h> - -#include "SkinUploadDialog.h" -#include "ui_SkinUploadDialog.h" -#include "ProgressDialog.h" -#include "CustomMessageBox.h" - -void SkinUploadDialog::on_buttonBox_rejected() -{ - close(); -} - -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]+)://.+$"); - bool isLocalFile = false; - // it has an URL prefix -> it is an URL - if(urlPrefixMatcher.exactMatch(input)) - { - QUrl fileURL = input; - if(fileURL.isValid()) - { - // local? - if(fileURL.isLocalFile()) - { - isLocalFile = true; - fileName = fileURL.toLocalFile(); - } - else - { - CustomMessageBox::selectable( - this, - tr("Skin Upload"), - tr("Using remote URLs for setting skins is not implemented yet."), - QMessageBox::Warning - )->exec(); - close(); - return; - } - } - else - { - CustomMessageBox::selectable( - this, - tr("Skin Upload"), - tr("You cannot use an invalid URL for uploading skins."), - QMessageBox::Warning - )->exec(); - close(); - return; - } - } - else - { - // just assume it's a path then - isLocalFile = true; - fileName = ui->skinPathTextBox->text(); - } - if (isLocalFile && !QFile::exists(fileName)) - { - CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Skin file does not exist!"), QMessageBox::Warning)->exec(); - close(); - return; - } - SkinUpload::Model model = SkinUpload::STEVE; - if (ui->steveBtn->isChecked()) - { - model = SkinUpload::STEVE; - } - else if (ui->alexBtn->isChecked()) - { - model = SkinUpload::ALEX; - } - SequentialTask skinUpload; - skinUpload.addTask(shared_qobject_ptr<SkinUpload>(new SkinUpload(this, session, 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))); - } - if (prog.execWithTask(&skinUpload) != QDialog::Accepted) - { - CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to upload skin!"), QMessageBox::Warning)->exec(); - close(); - return; - } - CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Success"), QMessageBox::Information)->exec(); - close(); -} - -void SkinUploadDialog::on_skinBrowseBtn_clicked() -{ - QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), "*.png"); - if (raw_path.isEmpty() || !QFileInfo::exists(raw_path)) - { - return; - } - QString cooked_path = FS::NormalizePath(raw_path); - ui->skinPathTextBox->setText(cooked_path); -} - -SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent) - :QDialog(parent), m_acct(acct), ui(new Ui::SkinUploadDialog) -{ - ui->setupUi(this); - - // FIXME: add a model for this, download/refresh the capes on demand - auto &data = *acct->accountData(); - int index = 0; - ui->capeCombo->addItem(tr("No Cape"), QVariant()); - auto currentCape = data.minecraftProfile.currentCape; - if(currentCape.isEmpty()) { - ui->capeCombo->setCurrentIndex(index); - } - - for(auto & cape: data.minecraftProfile.capes) { - index++; - if(cape.data.size()) { - QPixmap capeImage; - if(capeImage.loadFromData(cape.data, "PNG")) { - QPixmap preview = QPixmap(10, 16); - QPainter painter(&preview); - painter.drawPixmap(0, 0, capeImage.copy(1, 1, 10, 16)); - ui->capeCombo->addItem(capeImage, cape.alias, cape.id); - if(currentCape == cape.id) { - ui->capeCombo->setCurrentIndex(index); - } - continue; - } - } - ui->capeCombo->addItem(cape.alias, cape.id); - if(currentCape == cape.id) { - ui->capeCombo->setCurrentIndex(index); - } - } -} diff --git a/launcher/dialogs/SkinUploadDialog.h b/launcher/dialogs/SkinUploadDialog.h deleted file mode 100644 index 84d17dc6..00000000 --- a/launcher/dialogs/SkinUploadDialog.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include <QDialog> -#include <minecraft/auth/MinecraftAccount.h> - -namespace Ui -{ - class SkinUploadDialog; -} - -class SkinUploadDialog : public QDialog { - Q_OBJECT -public: - explicit SkinUploadDialog(MinecraftAccountPtr acct, QWidget *parent = 0); - virtual ~SkinUploadDialog() {}; - -public slots: - void on_buttonBox_accepted(); - - void on_buttonBox_rejected(); - - void on_skinBrowseBtn_clicked(); - -protected: - MinecraftAccountPtr m_acct; - -private: - Ui::SkinUploadDialog *ui; -}; diff --git a/launcher/dialogs/SkinUploadDialog.ui b/launcher/dialogs/SkinUploadDialog.ui deleted file mode 100644 index f4b0ed0a..00000000 --- a/launcher/dialogs/SkinUploadDialog.ui +++ /dev/null @@ -1,97 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>SkinUploadDialog</class> - <widget class="QDialog" name="SkinUploadDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>394</width> - <height>360</height> - </rect> - </property> - <property name="windowTitle"> - <string>Skin Upload</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QGroupBox" name="fileBox"> - <property name="title"> - <string>Skin File</string> - </property> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLineEdit" name="skinPathTextBox"/> - </item> - <item> - <widget class="QPushButton" name="skinBrowseBtn"> - <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> - </widget> - </item> - <item> - <widget class="QGroupBox" name="modelBox"> - <property name="title"> - <string>Player Model</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_1"> - <item> - <widget class="QRadioButton" name="steveBtn"> - <property name="text"> - <string>Steve Model</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QRadioButton" name="alexBtn"> - <property name="text"> - <string>Alex Model</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="capeBox"> - <property name="title"> - <string>Cape</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QComboBox" name="capeCombo"/> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections/> -</ui> diff --git a/launcher/dialogs/UpdateDialog.cpp b/launcher/dialogs/UpdateDialog.cpp deleted file mode 100644 index 4a6a1fdd..00000000 --- a/launcher/dialogs/UpdateDialog.cpp +++ /dev/null @@ -1,182 +0,0 @@ -#include "UpdateDialog.h" -#include "ui_UpdateDialog.h" -#include <QDebug> -#include "Application.h" -#include <settings/SettingsObject.h> -#include <Json.h> - -#include "BuildConfig.h" -#include "HoeDown.h" - -UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDialog) -{ - ui->setupUi(this); - auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); - if(hasUpdate) - { - ui->label->setText(tr("A new %1 update is available!").arg(channel)); - } - else - { - ui->label->setText(tr("No %1 updates found. You are running the latest version.").arg(channel)); - ui->btnUpdateNow->setHidden(true); - ui->btnUpdateLater->setText(tr("Close")); - } - ui->changelogBrowser->setHtml(tr("<center><h1>Loading changelog...</h1></center>")); - loadChangelog(); - restoreGeometry(QByteArray::fromBase64(APPLICATION->settings()->get("UpdateDialogGeometry").toByteArray())); -} - -UpdateDialog::~UpdateDialog() -{ -} - -void UpdateDialog::loadChangelog() -{ - auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); - dljob.reset(new NetJob("Changelog")); - QString url; - if(channel == "stable") - { - url = QString("https://raw.githubusercontent.com/MultiMC/Launcher/%1/changelog.md").arg(channel); - m_changelogType = CHANGELOG_MARKDOWN; - } - else - { - url = QString("https://api.github.com/repos/MultiMC/Launcher/compare/%1...%2").arg(BuildConfig.GIT_COMMIT, channel); - m_changelogType = CHANGELOG_COMMITS; - } - 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()); -} - -QString reprocessMarkdown(QByteArray markdown) -{ - HoeDown hoedown; - QString output = hoedown.process(markdown); - - // HACK: easier than customizing hoedown - output.replace(QRegExp("GH-([0-9]+)"), "<a href=\"https://github.com/MultiMC/Launcher/issues/\\1\">GH-\\1</a>"); - qDebug() << output; - return output; -} - -QString reprocessCommits(QByteArray json) -{ - auto channel = APPLICATION->settings()->get("UpdateChannel").toString(); - try - { - QString result; - auto document = Json::requireDocument(json); - auto rootobject = Json::requireObject(document); - auto status = Json::requireString(rootobject, "status"); - auto diff_url = Json::requireString(rootobject, "html_url"); - - auto print_commits = [&]() - { - result += "<table cellspacing=0 cellpadding=2 style='border-width: 1px; border-style: solid'>"; - auto commitarray = Json::requireArray(rootobject, "commits"); - for(int i = commitarray.size() - 1; i >= 0; i--) - { - const auto & commitval = commitarray[i]; - auto commitobj = Json::requireObject(commitval); - auto parents_info = Json::ensureArray(commitobj, "parents"); - // NOTE: this ignores merge commits, because they have more than one parent - if(parents_info.size() > 1) - { - continue; - } - auto commit_url = Json::requireString(commitobj, "html_url"); - auto commit_info = Json::requireObject(commitobj, "commit"); - auto commit_message = Json::requireString(commit_info, "message"); - auto lines = commit_message.split('\n'); - QRegularExpression regexp("(?<prefix>(GH-(?<issuenr>[0-9]+))|(NOISSUE)|(SCRATCH))? *(?<rest>.*) *"); - auto match = regexp.match(lines.takeFirst(), 0, QRegularExpression::NormalMatch); - auto issuenr = match.captured("issuenr"); - auto prefix = match.captured("prefix"); - auto rest = match.captured("rest"); - result += "<tr><td>"; - if(issuenr.length()) - { - result += QString("<a href=\"https://github.com/MultiMC/Launcher/issues/%1\">GH-%2</a>").arg(issuenr, issuenr); - } - else if(prefix.length()) - { - result += QString("<a href=\"%1\">%2</a>").arg(commit_url, prefix); - } - else - { - result += QString("<a href=\"%1\">NOISSUE</a>").arg(commit_url); - } - result += "</td>"; - lines.prepend(rest); - result += "<td><p>" + lines.join("<br />") + "</p></td></tr>"; - } - result += "</table>"; - }; - - if(status == "identical") - { - return QObject::tr("<p>There are no code changes between your current version and latest %1.</p>").arg(channel); - } - else if(status == "ahead") - { - result += QObject::tr("<p>Following commits were added since last update:</p>"); - print_commits(); - } - else if(status == "diverged") - { - auto commit_ahead = Json::requireInteger(rootobject, "ahead_by"); - auto commit_behind = Json::requireInteger(rootobject, "behind_by"); - result += QObject::tr("<p>The update removes %1 commits and adds the following %2:</p>").arg(commit_behind).arg(commit_ahead); - print_commits(); - } - result += QObject::tr("<p>You can <a href=\"%1\">look at the changes on github</a>.</p>").arg(diff_url); - return result; - } - catch (const JSONValidationError &e) - { - qWarning() << "Got an unparseable commit log from github:" << e.what(); - qDebug() << json; - } - return QString(); -} - -void UpdateDialog::changelogLoaded() -{ - QString result; - switch(m_changelogType) - { - case CHANGELOG_COMMITS: - result = reprocessCommits(changelogData); - break; - case CHANGELOG_MARKDOWN: - result = reprocessMarkdown(changelogData); - break; - } - changelogData.clear(); - ui->changelogBrowser->setHtml(result); -} - -void UpdateDialog::changelogFailed(QString reason) -{ - ui->changelogBrowser->setHtml(tr("<p align=\"center\" <span style=\"font-size:22pt;\">Failed to fetch changelog... Error: %1</span></p>").arg(reason)); -} - -void UpdateDialog::on_btnUpdateLater_clicked() -{ - reject(); -} - -void UpdateDialog::on_btnUpdateNow_clicked() -{ - done(UPDATE_NOW); -} - -void UpdateDialog::closeEvent(QCloseEvent* evt) -{ - APPLICATION->settings()->set("UpdateDialogGeometry", saveGeometry().toBase64()); - QDialog::closeEvent(evt); -} diff --git a/launcher/dialogs/UpdateDialog.h b/launcher/dialogs/UpdateDialog.h deleted file mode 100644 index 07cbe09f..00000000 --- a/launcher/dialogs/UpdateDialog.h +++ /dev/null @@ -1,67 +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 <QDialog> -#include "net/NetJob.h" - -namespace Ui -{ -class UpdateDialog; -} - -enum UpdateAction -{ - UPDATE_LATER = QDialog::Rejected, - UPDATE_NOW = QDialog::Accepted, -}; - -enum ChangelogType -{ - CHANGELOG_MARKDOWN, - CHANGELOG_COMMITS -}; - -class UpdateDialog : public QDialog -{ - Q_OBJECT - -public: - explicit UpdateDialog(bool hasUpdate = true, QWidget *parent = 0); - ~UpdateDialog(); - -public slots: - void on_btnUpdateNow_clicked(); - void on_btnUpdateLater_clicked(); - - /// Starts loading the changelog - void loadChangelog(); - - /// Slot for when the chengelog loads successfully. - void changelogLoaded(); - - /// Slot for when the chengelog fails to load... - void changelogFailed(QString reason); - -protected: - void closeEvent(QCloseEvent * ) override; - -private: - Ui::UpdateDialog *ui; - QByteArray changelogData; - NetJob::Ptr dljob; - ChangelogType m_changelogType = CHANGELOG_MARKDOWN; -}; diff --git a/launcher/dialogs/UpdateDialog.ui b/launcher/dialogs/UpdateDialog.ui deleted file mode 100644 index b0b3dd83..00000000 --- a/launcher/dialogs/UpdateDialog.ui +++ /dev/null @@ -1,91 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>UpdateDialog</class> - <widget class="QDialog" name="UpdateDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>657</width> - <height>673</height> - </rect> - </property> - <property name="windowTitle"> - <string>MultiMC Update</string> - </property> - <property name="windowIcon"> - <iconset> - <normaloff>:/icons/toolbar/checkupdate</normaloff>:/icons/toolbar/checkupdate</iconset> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="label"> - <property name="font"> - <font> - <pointsize>14</pointsize> - </font> - </property> - <property name="text"> - <string/> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> - </property> - <property name="buddy"> - <cstring>changelogBrowser</cstring> - </property> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QTextBrowser" name="changelogBrowser"> - <property name="openExternalLinks"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QPushButton" name="btnUpdateNow"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Update now</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QPushButton" name="btnUpdateLater"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Don't update yet</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <tabstops> - <tabstop>changelogBrowser</tabstop> - <tabstop>btnUpdateNow</tabstop> - <tabstop>btnUpdateLater</tabstop> - </tabstops> - <resources> - <include location="../../resources/multimc/multimc.qrc"/> - </resources> - <connections/> -</ui> diff --git a/launcher/dialogs/VersionSelectDialog.cpp b/launcher/dialogs/VersionSelectDialog.cpp deleted file mode 100644 index a920f6b7..00000000 --- a/launcher/dialogs/VersionSelectDialog.cpp +++ /dev/null @@ -1,141 +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 "VersionSelectDialog.h" - -#include <QtWidgets/QButtonGroup> -#include <QtWidgets/QDialogButtonBox> -#include <QtWidgets/QHBoxLayout> -#include <QtWidgets/QPushButton> -#include <QtWidgets/QVBoxLayout> - -#include <dialogs/ProgressDialog.h> -#include "CustomMessageBox.h" - -#include <BaseVersion.h> -#include <BaseVersionList.h> -#include <tasks/Task.h> -#include <QDebug> -#include "Application.h" -#include <VersionProxyModel.h> -#include <widgets/VersionSelectWidget.h> - -VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, bool cancelable) - : QDialog(parent) -{ - setObjectName(QStringLiteral("VersionSelectDialog")); - resize(400, 347); - m_verticalLayout = new QVBoxLayout(this); - m_verticalLayout->setObjectName(QStringLiteral("verticalLayout")); - - m_versionWidget = new VersionSelectWidget(parent); - m_verticalLayout->addWidget(m_versionWidget); - - m_horizontalLayout = new QHBoxLayout(); - m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); - - m_refreshButton = new QPushButton(this); - m_refreshButton->setObjectName(QStringLiteral("refreshButton")); - m_horizontalLayout->addWidget(m_refreshButton); - - m_buttonBox = new QDialogButtonBox(this); - m_buttonBox->setObjectName(QStringLiteral("buttonBox")); - m_buttonBox->setOrientation(Qt::Horizontal); - m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); - m_horizontalLayout->addWidget(m_buttonBox); - - m_verticalLayout->addLayout(m_horizontalLayout); - - retranslate(); - - QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept())); - QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); - - QMetaObject::connectSlotsByName(this); - setWindowModality(Qt::WindowModal); - setWindowTitle(title); - - m_vlist = vlist; - - if (!cancelable) - { - m_buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false); - } -} - -void VersionSelectDialog::retranslate() -{ - // FIXME: overrides custom title given in constructor! - setWindowTitle(tr("Choose Version")); - m_refreshButton->setToolTip(tr("Reloads the version list.")); - m_refreshButton->setText(tr("&Refresh")); -} - -void VersionSelectDialog::setCurrentVersion(const QString& version) -{ - m_currentVersion = version; - m_versionWidget->setCurrentVersion(version); -} - -void VersionSelectDialog::setEmptyString(QString emptyString) -{ - m_versionWidget->setEmptyString(emptyString); -} - -void VersionSelectDialog::setEmptyErrorString(QString emptyErrorString) -{ - m_versionWidget->setEmptyErrorString(emptyErrorString); -} - -void VersionSelectDialog::setResizeOn(int column) -{ - resizeOnColumn = column; -} - -int VersionSelectDialog::exec() -{ - QDialog::open(); - m_versionWidget->initialize(m_vlist); - if(resizeOnColumn != -1) - { - m_versionWidget->setResizeOn(resizeOnColumn); - } - return QDialog::exec(); -} - -void VersionSelectDialog::selectRecommended() -{ - m_versionWidget->selectRecommended(); -} - -BaseVersionPtr VersionSelectDialog::selectedVersion() const -{ - return m_versionWidget->selectedVersion(); -} - -void VersionSelectDialog::on_refreshButton_clicked() -{ - m_versionWidget->loadList(); -} - -void VersionSelectDialog::setExactFilter(BaseVersionList::ModelRoles role, QString filter) -{ - m_versionWidget->setExactFilter(role, filter); -} - -void VersionSelectDialog::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter) -{ - m_versionWidget->setFuzzyFilter(role, filter); -} diff --git a/launcher/dialogs/VersionSelectDialog.h b/launcher/dialogs/VersionSelectDialog.h deleted file mode 100644 index ed30d3f3..00000000 --- a/launcher/dialogs/VersionSelectDialog.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 <QDialog> -#include <QSortFilterProxyModel> - - -#include "BaseVersionList.h" - -class QVBoxLayout; -class QHBoxLayout; -class QDialogButtonBox; -class VersionSelectWidget; -class QPushButton; - -namespace Ui -{ -class VersionSelectDialog; -} - -class VersionProxyModel; - -class VersionSelectDialog : public QDialog -{ - Q_OBJECT - -public: - explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0, bool cancelable = true); - virtual ~VersionSelectDialog() {}; - - int exec() override; - - BaseVersionPtr selectedVersion() const; - - void setCurrentVersion(const QString & version); - void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); - void setExactFilter(BaseVersionList::ModelRoles role, QString filter); - void setEmptyString(QString emptyString); - void setEmptyErrorString(QString emptyErrorString); - void setResizeOn(int column); - -private slots: - void on_refreshButton_clicked(); - -private: - void retranslate(); - void selectRecommended(); - -private: - QString m_currentVersion; - VersionSelectWidget *m_versionWidget = nullptr; - QVBoxLayout *m_verticalLayout = nullptr; - QHBoxLayout *m_horizontalLayout = nullptr; - QPushButton *m_refreshButton = nullptr; - QDialogButtonBox *m_buttonBox = nullptr; - - BaseVersionList *m_vlist = nullptr; - - VersionProxyModel *m_proxyModel = nullptr; - - int resizeOnColumn = -1; - - Task * loadTask = nullptr; -}; |