From db877ba121ff87a4e029daf8555d85dfef45993a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Mon, 9 Feb 2015 01:51:14 +0100 Subject: NOISSUE move everything. --- application/dialogs/AboutDialog.cpp | 127 +++++++ application/dialogs/AboutDialog.h | 47 +++ application/dialogs/AboutDialog.ui | 544 ++++++++++++++++++++++++++++ application/dialogs/AccountSelectDialog.cpp | 85 +++++ application/dialogs/AccountSelectDialog.h | 90 +++++ application/dialogs/AccountSelectDialog.ui | 56 +++ application/dialogs/CopyInstanceDialog.cpp | 101 ++++++ application/dialogs/CopyInstanceDialog.h | 52 +++ application/dialogs/CopyInstanceDialog.ui | 161 ++++++++ application/dialogs/CustomMessageBox.cpp | 35 ++ application/dialogs/CustomMessageBox.h | 26 ++ application/dialogs/EditAccountDialog.cpp | 51 +++ application/dialogs/EditAccountDialog.h | 60 +++ application/dialogs/EditAccountDialog.ui | 94 +++++ application/dialogs/IconPickerDialog.cpp | 156 ++++++++ application/dialogs/IconPickerDialog.h | 48 +++ application/dialogs/IconPickerDialog.ui | 67 ++++ application/dialogs/LoginDialog.cpp | 110 ++++++ application/dialogs/LoginDialog.h | 58 +++ application/dialogs/LoginDialog.ui | 77 ++++ application/dialogs/ModEditDialogCommon.cpp | 40 ++ application/dialogs/ModEditDialogCommon.h | 9 + application/dialogs/NewInstanceDialog.cpp | 207 +++++++++++ application/dialogs/NewInstanceDialog.h | 59 +++ application/dialogs/NewInstanceDialog.ui | 309 ++++++++++++++++ application/dialogs/NotificationDialog.cpp | 84 +++++ application/dialogs/NotificationDialog.h | 44 +++ application/dialogs/NotificationDialog.ui | 85 +++++ application/dialogs/ProgressDialog.cpp | 125 +++++++ application/dialogs/ProgressDialog.h | 65 ++++ application/dialogs/ProgressDialog.ui | 66 ++++ application/dialogs/UpdateDialog.cpp | 186 ++++++++++ application/dialogs/UpdateDialog.h | 61 ++++ application/dialogs/UpdateDialog.ui | 106 ++++++ application/dialogs/VersionSelectDialog.cpp | 177 +++++++++ application/dialogs/VersionSelectDialog.h | 66 ++++ application/dialogs/VersionSelectDialog.ui | 110 ++++++ 37 files changed, 3844 insertions(+) create mode 100644 application/dialogs/AboutDialog.cpp create mode 100644 application/dialogs/AboutDialog.h create mode 100644 application/dialogs/AboutDialog.ui create mode 100644 application/dialogs/AccountSelectDialog.cpp create mode 100644 application/dialogs/AccountSelectDialog.h create mode 100644 application/dialogs/AccountSelectDialog.ui create mode 100644 application/dialogs/CopyInstanceDialog.cpp create mode 100644 application/dialogs/CopyInstanceDialog.h create mode 100644 application/dialogs/CopyInstanceDialog.ui create mode 100644 application/dialogs/CustomMessageBox.cpp create mode 100644 application/dialogs/CustomMessageBox.h create mode 100644 application/dialogs/EditAccountDialog.cpp create mode 100644 application/dialogs/EditAccountDialog.h create mode 100644 application/dialogs/EditAccountDialog.ui create mode 100644 application/dialogs/IconPickerDialog.cpp create mode 100644 application/dialogs/IconPickerDialog.h create mode 100644 application/dialogs/IconPickerDialog.ui create mode 100644 application/dialogs/LoginDialog.cpp create mode 100644 application/dialogs/LoginDialog.h create mode 100644 application/dialogs/LoginDialog.ui create mode 100644 application/dialogs/ModEditDialogCommon.cpp create mode 100644 application/dialogs/ModEditDialogCommon.h create mode 100644 application/dialogs/NewInstanceDialog.cpp create mode 100644 application/dialogs/NewInstanceDialog.h create mode 100644 application/dialogs/NewInstanceDialog.ui create mode 100644 application/dialogs/NotificationDialog.cpp create mode 100644 application/dialogs/NotificationDialog.h create mode 100644 application/dialogs/NotificationDialog.ui create mode 100644 application/dialogs/ProgressDialog.cpp create mode 100644 application/dialogs/ProgressDialog.h create mode 100644 application/dialogs/ProgressDialog.ui create mode 100644 application/dialogs/UpdateDialog.cpp create mode 100644 application/dialogs/UpdateDialog.h create mode 100644 application/dialogs/UpdateDialog.ui create mode 100644 application/dialogs/VersionSelectDialog.cpp create mode 100644 application/dialogs/VersionSelectDialog.h create mode 100644 application/dialogs/VersionSelectDialog.ui (limited to 'application/dialogs') diff --git a/application/dialogs/AboutDialog.cpp b/application/dialogs/AboutDialog.cpp new file mode 100644 index 00000000..abcc76f2 --- /dev/null +++ b/application/dialogs/AboutDialog.cpp @@ -0,0 +1,127 @@ +/* Copyright 2013-2015 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 +#include "MultiMC.h" +#include "Platform.h" +#include "BuildConfig.h" + +#include + +// 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 creditsHtml = QObject::tr( + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "

MultiMC Developers

" + "

Andrew Okin <forkk@forkk.net>

" + "

Petr Mrázek <peterix@gmail.com>

" + "

Sky Welch <multimc@bunnies.io>

" + "

Jan (02JanDal) <02jandal@gmail.com>

" + "" + "

With thanks to

" + "

Orochimarufan <orochimarufan.x3@gmail.com>

" + "

TakSuyu <taksuyu@gmail.com>

" + "

Kilobyte <stiepen22@gmx.de>

" + "

Robotbrain <@skylordelros>

" + "

Rootbear75 <@rootbear75> (build server)

" + "" + "

Patreon Patrons

" + "%1" + "" + "" + ""); + if (patrons.isEmpty()) + return creditsHtml.arg(QObject::tr("

Loading...

")); + else + { + QString patronsStr; + for (QString patron : patrons) + { + patronsStr.append(QString("

%1

").arg(patron)); + } + + return creditsHtml.arg(patronsStr); + } +} + +AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + + QString chtml = getCreditsHtml(QStringList()); + ui->creditsText->setHtml(chtml); + + ui->urlLabel->setOpenExternalLinks(true); + + ui->icon->setPixmap(MMC->getThemedIcon("multimc").pixmap(64)); + ui->title->setText("MultiMC 5"); + + 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); + + connect(ui->closeButton, SIGNAL(clicked()), SLOT(close())); + + connect(ui->aboutQt, &QPushButton::clicked, &QApplication::aboutQt); + + loadPatronList(); +} + +AboutDialog::~AboutDialog() +{ + delete ui; +} + +void AboutDialog::loadPatronList() +{ + NetJob* job = new NetJob("Patreon Patron List"); + patronListDownload = ByteArrayDownload::make(QUrl("http://files.multimc.org/patrons.txt")); + job->addNetAction(patronListDownload); + connect(job, &NetJob::succeeded, this, &AboutDialog::patronListLoaded); + job->start(); +} + +void AboutDialog::patronListLoaded() +{ + QString patronListStr(patronListDownload->m_data); + QString html = getCreditsHtml(patronListStr.split("\n", QString::SkipEmptyParts)); + ui->creditsText->setHtml(html); +} + diff --git a/application/dialogs/AboutDialog.h b/application/dialogs/AboutDialog.h new file mode 100644 index 00000000..1885e9c0 --- /dev/null +++ b/application/dialogs/AboutDialog.h @@ -0,0 +1,47 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +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; + + ByteArrayDownloadPtr patronListDownload; +}; diff --git a/application/dialogs/AboutDialog.ui b/application/dialogs/AboutDialog.ui new file mode 100644 index 00000000..2b5f8b78 --- /dev/null +++ b/application/dialogs/AboutDialog.ui @@ -0,0 +1,544 @@ + + + AboutDialog + + + + 0 + 0 + 707 + 593 + + + + + 450 + 400 + + + + About MultiMC + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 64 + 64 + + + + + 64 + 64 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + 15 + + + + MultiMC 5 + + + Qt::AlignCenter + + + + + + + 0 + + + + + 0 + 0 + 695 + 297 + + + + About + + + + + + Version: + + + Qt::AlignCenter + + + + + + + Platform: + + + Qt::AlignCenter + + + + + + + Build Number: + + + Qt::AlignCenter + + + + + + + Channel: + + + Qt::AlignCenter + + + + + + + true + + + <html><head/><body><p>MultiMC is a custom launcher that makes managing Minecraft easier by allowing you to have multiple instances of Minecraft at once.</p></body></html> + + + Qt::AlignCenter + + + true + + + + + + + + 8 + true + + + + © 2013-2015 MultiMC Contributors + + + Qt::AlignCenter + + + + + + + + 10 + + + + <html><head/><body><p><a href="http://github.com/MultiMC/MultiMC5"><span style=" text-decoration: underline; color:#0000ff;">http://github.com/MultiMC/MultiMC5</span></a></p></body></html> + + + Qt::AlignCenter + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 695 + 297 + + + + Credits + + + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Oxygen-Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> + + + Qt::TextBrowserInteraction + + + + + + + No Language file loaded. + + + true + + + + + + + + + 0 + 0 + 695 + 297 + + + + License + + + + + + + 0 + 0 + + + + + DejaVu Sans Mono + + + + true + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:11pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">MultiMC</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright 2012-2014 MultiMC Contributors</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">you may not use this file except in compliance with the License.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">You may obtain a copy of the License at</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;"> http://www.apache.org/licenses/LICENSE-2.0</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Unless required by applicable law or agreed to in writing, software</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">See the License for the specific language governing permissions and</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">limitations under the License.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">QSLog</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Copyright (c) 2010, Razvan Petru</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">All rights reserved.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Redistribution and use in source and binary forms, with or without modification,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">are permitted provided that the following conditions are met:</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">* Redistributions of source code must retain the above copyright notice, this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> list of conditions and the following disclaimer.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">* Redistributions in binary form must reproduce the above copyright notice, this</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> list of conditions and the following disclaimer in the documentation and/or other</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> materials provided with the distribution.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">* The name of the contributors may not be used to endorse or promote products</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> derived from this software without specific prior written permission.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">OF THE POSSIBILITY OF SUCH DAMAGE.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">Group View (instance view)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> /*</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Copyright (C) 2007 Rafael Fernández López &lt;ereslibre@kde.org&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Copyright (C) 2007 John Tapsell &lt;tapsell@kde.org&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> *</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * This library is free software; you can redistribute it and/or</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * modify it under the terms of the GNU Library General Public</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * License as published by the Free Software Foundation; either</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * version 2 of the License, or (at your option) any later version.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> *</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * This library is distributed in the hope that it will be useful,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Library General Public License for more details.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> *</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * You should have received a copy of the GNU Library General Public License</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * along with this library; see the file COPYING.LIB. If not, write to</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Boston, MA 02110-1301, USA.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> */</span></p> +<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">Batch icon set</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">You are free to use Batch (the &quot;icon set&quot;) or any part thereof (the &quot;icons&quot;)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">in any personal, open-source or commercial work without obligation of payment</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(monetary or otherwise) or attribution. Do not sell the icon set, host</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">the icon set or rent the icon set (either in existing or modified form).</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">While attribution is optional, it is always appreciated.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Intellectual property rights are not transferred with the download of the icons.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL ADAM WHITCROFT</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THE USE OF THE ICONS,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://adamwhitcroft.com/batch/"><span style=" text-decoration: underline; color:#68a0df;">http://adamwhitcroft.com/batch/</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">Pack200</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">The GNU General Public License (GPL)</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Version 2, June 1991</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">+ &quot;CLASSPATH&quot; EXCEPTION TO THE GPL</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Certain source files distributed by Oracle America and/or its affiliates are</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">subject to the following clarification and special exception to the GPL, but</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">only where Oracle has expressly included in the particular source file's header</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">the words &quot;Oracle designates this particular file as subject to the &quot;Classpath&quot;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">exception as provided by Oracle in the LICENSE file that accompanied this code.&quot;</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> Linking this library statically or dynamically with other modules is making</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> a combined work based on this library. Thus, the terms and conditions of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> the GNU General Public License cover the whole combination.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> As a special exception, the copyright holders of this library give you</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> permission to link this library with independent modules to produce an</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> executable, regardless of the license terms of these independent modules,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> and to copy and distribute the resulting executable under terms of your</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> choice, provided that you also meet, for each linked independent module,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> the terms and conditions of the license of that module. An independent</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> module is a module which is not derived from or based on this library. If</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> you modify this library, you may extend this exception to your version of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> the library, but you are not obligated to do so. If you do not wish to do</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> so, delete this exception statement from your version.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">Quazip</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Copyright (C) 2005-2011 Sergey A. Tachenov</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This program is free software; you can redistribute it and/or modify it</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">under the terms of the GNU Lesser General Public License as published by</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">the Free Software Foundation; either version 2 of the License, or (at</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">your option) any later version.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">This program is distributed in the hope that it will be useful, but</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">WITHOUT ANY WARRANTY; without even the implied warranty of</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">General Public License for more details.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">You should have received a copy of the GNU Lesser General Public License</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">along with this program; if not, write to the Free Software Foundation,</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">See COPYING file for the full LGPL text.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Original ZIP package is copyrighted by Gilles Vollant, see</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">quazip/(un)zip.h files for details, basically it's zlib license.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">xz-minidec</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">/*</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * XZ decompressor</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> *</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Authors: Lasse Collin &lt;lasse.collin@tukaani.org&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Igor Pavlov &lt;http://7-zip.org/&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> *</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * This file has been put into the public domain.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * You can do whatever you want with this file.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> */</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">Java IconLoader class</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Copyright (c) 2011, Chris Molini</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">All rights reserved.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Redistribution and use in source and binary forms, with or without</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">modification, are permitted provided that the following conditions are met:</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Redistributions of source code must retain the above copyright</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> notice, this list of conditions and the following disclaimer.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Redistributions in binary form must reproduce the above copyright</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> notice, this list of conditions and the following disclaimer in the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> documentation and/or other materials provided with the distribution.</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Neither the name of the &lt;organization&gt; nor the</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> names of its contributors may be used to endorse or promote products</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> derived from this software without specific prior written permission.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot; AND</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">DISCLAIMED. IN NO EVENT SHALL &lt;COPYRIGHT HOLDER&gt; BE LIABLE FOR ANY</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></p> +<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">ColumnResizer</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">/*</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Copyright 2011 Aurélien Gâteau &lt;agateau@kde.org&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * License: LGPL v2.1 or later (see COPYING)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> */</span></p></body></html> + + + Qt::TextBrowserInteraction + + + + + + + + + 0 + 0 + 695 + 297 + + + + Forking/Redistribution + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Oxygen-Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans';">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.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Bitstream Vera Sans';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans';">Part of the reason for using the Apache license is we don't want people using the &quot;MultiMC&quot; name when redistributing the project. This means people must take the time to go through the source code and remove all references to &quot;MultiMC&quot;, including but not limited to the project icon and the title of windows, (no *MultiMC-fork* in the title).</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Bitstream Vera Sans';"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans';">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 </span><span style=" font-family:'Bitstream Vera Sans'; font-weight:600;">without</span><span style=" font-family:'Bitstream Vera Sans';"> implying that you have our blessing.</span></p></body></html> + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + + false + + + About Qt + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + + + + + + diff --git a/application/dialogs/AccountSelectDialog.cpp b/application/dialogs/AccountSelectDialog.cpp new file mode 100644 index 00000000..3bf83d62 --- /dev/null +++ b/application/dialogs/AccountSelectDialog.cpp @@ -0,0 +1,85 @@ +/* Copyright 2013-2015 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 "AccountSelectDialog.h" +#include "ui_AccountSelectDialog.h" + +#include + +#include + +#include + +#include + +AccountSelectDialog::AccountSelectDialog(const QString &message, int flags, QWidget *parent) + : QDialog(parent), ui(new Ui::AccountSelectDialog) +{ + ui->setupUi(this); + + m_accounts = MMC->accounts(); + ui->listView->setModel(m_accounts.get()); + ui->listView->hideColumn(MojangAccountList::ActiveColumn); + + // 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())); +} + +AccountSelectDialog::~AccountSelectDialog() +{ + delete ui; +} + +MojangAccountPtr AccountSelectDialog::selectedAccount() const +{ + return m_selected; +} + +bool AccountSelectDialog::useAsGlobalDefault() const +{ + return ui->globalDefaultCheck->isChecked(); +} + +bool AccountSelectDialog::useAsInstDefaullt() const +{ + return ui->instDefaultCheck->isChecked(); +} + +void AccountSelectDialog::on_buttonBox_accepted() +{ + QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + if (selection.size() > 0) + { + QModelIndex selected = selection.first(); + m_selected = selected.data(MojangAccountList::PointerRole).value(); + } + close(); +} + +void AccountSelectDialog::on_buttonBox_rejected() +{ + close(); +} diff --git a/application/dialogs/AccountSelectDialog.h b/application/dialogs/AccountSelectDialog.h new file mode 100644 index 00000000..21784032 --- /dev/null +++ b/application/dialogs/AccountSelectDialog.h @@ -0,0 +1,90 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include + +#include "auth/MojangAccountList.h" + +namespace Ui +{ +class AccountSelectDialog; +} + +class AccountSelectDialog : 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 AccountSelectDialog(const QString& message="", int flags=0, QWidget *parent = 0); + ~AccountSelectDialog(); + + /*! + * Gets a pointer to the account that the user selected. + * This is null if the user clicked cancel or hasn't clicked OK yet. + */ + MojangAccountPtr 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: + std::shared_ptr m_accounts; + + //! The account that was selected when the user clicked OK. + MojangAccountPtr m_selected; + +private: + Ui::AccountSelectDialog *ui; +}; diff --git a/application/dialogs/AccountSelectDialog.ui b/application/dialogs/AccountSelectDialog.ui new file mode 100644 index 00000000..7af1512a --- /dev/null +++ b/application/dialogs/AccountSelectDialog.ui @@ -0,0 +1,56 @@ + + + AccountSelectDialog + + + + 0 + 0 + 413 + 300 + + + + Select an Account + + + + + + Select an account. + + + + + + + + + + + + Use as default? + + + + + + + Use as default for this instance only? + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/application/dialogs/CopyInstanceDialog.cpp b/application/dialogs/CopyInstanceDialog.cpp new file mode 100644 index 00000000..7c98978b --- /dev/null +++ b/application/dialogs/CopyInstanceDialog.cpp @@ -0,0 +1,101 @@ +/* Copyright 2013-2015 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 +#include + +#include "MultiMC.h" +#include "CopyInstanceDialog.h" +#include "ui_CopyInstanceDialog.h" + +#include "Platform.h" +#include "dialogs/VersionSelectDialog.h" +#include "dialogs/ProgressDialog.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) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + resize(minimumSizeHint()); + layout()->setSizeConstraint(QLayout::SetFixedSize); + + InstIconKey = original->iconKey(); + ui->iconButton->setIcon(ENV.icons()->getIcon(InstIconKey)); + ui->instNameTextBox->setText(original->name()); + ui->instNameTextBox->setFocus(); + auto groups = MMC->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(m_original->group()); + if(index == -1) + { + index = 0; + } + ui->groupBox->setCurrentIndex(index); + ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); +} + +CopyInstanceDialog::~CopyInstanceDialog() +{ + delete ui; +} + +void CopyInstanceDialog::updateDialogState() +{ + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!instName().isEmpty()); +} + +QString CopyInstanceDialog::instName() const +{ + return ui->instNameTextBox->text(); +} + +QString CopyInstanceDialog::iconKey() const +{ + return InstIconKey; +} + +QString CopyInstanceDialog::instGroup() const +{ + return ui->groupBox->currentText(); +} + +void CopyInstanceDialog::on_iconButton_clicked() +{ + IconPickerDialog dlg(this); + dlg.exec(InstIconKey); + + if (dlg.result() == QDialog::Accepted) + { + InstIconKey = dlg.selectedIconKey; + ui->iconButton->setIcon(ENV.icons()->getIcon(InstIconKey)); + } +} + +void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) +{ + updateDialogState(); +} diff --git a/application/dialogs/CopyInstanceDialog.h b/application/dialogs/CopyInstanceDialog.h new file mode 100644 index 00000000..faa20615 --- /dev/null +++ b/application/dialogs/CopyInstanceDialog.h @@ -0,0 +1,52 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "BaseVersion.h" +#include + +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; + +private +slots: + void on_iconButton_clicked(); + void on_instNameTextBox_textChanged(const QString &arg1); + +private: + Ui::CopyInstanceDialog *ui; + QString InstIconKey; + InstancePtr m_original; +}; diff --git a/application/dialogs/CopyInstanceDialog.ui b/application/dialogs/CopyInstanceDialog.ui new file mode 100644 index 00000000..2615168c --- /dev/null +++ b/application/dialogs/CopyInstanceDialog.ui @@ -0,0 +1,161 @@ + + + CopyInstanceDialog + + + Qt::ApplicationModal + + + + 0 + 0 + 345 + 205 + + + + Copy Instance + + + + :/icons/toolbar/copy:/icons/toolbar/copy + + + true + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + :/icons/instances/infinity:/icons/instances/infinity + + + + 80 + 80 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Name + + + + + + + Qt::Horizontal + + + + + + + + + Group + + + groupBox + + + + + + + + 0 + 0 + + + + true + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + CopyInstanceDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + CopyInstanceDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/application/dialogs/CustomMessageBox.cpp b/application/dialogs/CustomMessageBox.cpp new file mode 100644 index 00000000..0fb5bd19 --- /dev/null +++ b/application/dialogs/CustomMessageBox.cpp @@ -0,0 +1,35 @@ +/* Copyright 2013-2015 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/application/dialogs/CustomMessageBox.h b/application/dialogs/CustomMessageBox.h new file mode 100644 index 00000000..0a7202d7 --- /dev/null +++ b/application/dialogs/CustomMessageBox.h @@ -0,0 +1,26 @@ +/* Copyright 2013-2015 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 + +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/application/dialogs/EditAccountDialog.cpp b/application/dialogs/EditAccountDialog.cpp new file mode 100644 index 00000000..b78cebee --- /dev/null +++ b/application/dialogs/EditAccountDialog.cpp @@ -0,0 +1,51 @@ +/* Copyright 2013-2015 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 +#include + +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->setVisible(flags & UsernameField); + ui->passTextBox->setVisible(flags & PasswordField); +} + +EditAccountDialog::~EditAccountDialog() +{ + delete ui; +} + +void EditAccountDialog::on_label_linkActivated(const QString &link) +{ + QDesktopServices::openUrl(QUrl(link)); +} + +QString EditAccountDialog::username() const +{ + return ui->userTextBox->text(); +} + +QString EditAccountDialog::password() const +{ + return ui->passTextBox->text(); +} diff --git a/application/dialogs/EditAccountDialog.h b/application/dialogs/EditAccountDialog.h new file mode 100644 index 00000000..df8b21bf --- /dev/null +++ b/application/dialogs/EditAccountDialog.h @@ -0,0 +1,60 @@ +/* Copyright 2013-2015 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 + +namespace Ui +{ +class EditAccountDialog; +} + +class EditAccountDialog : public QDialog +{ + Q_OBJECT + +public: + explicit EditAccountDialog(const QString &text = "", QWidget *parent = 0, + int flags = UsernameField | PasswordField); + ~EditAccountDialog(); + + /*! + * Gets the text entered in the dialog's username field. + */ + QString username() const; + + /*! + * Gets the text entered in the dialog's password field. + */ + 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/application/dialogs/EditAccountDialog.ui b/application/dialogs/EditAccountDialog.ui new file mode 100644 index 00000000..5f727bd4 --- /dev/null +++ b/application/dialogs/EditAccountDialog.ui @@ -0,0 +1,94 @@ + + + EditAccountDialog + + + + 0 + 0 + 400 + 148 + + + + Edit Account + + + + + + Message label placeholder. + + + Qt::RichText + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Email / Username + + + + + + + QLineEdit::Password + + + Password + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + EditAccountDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EditAccountDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/application/dialogs/IconPickerDialog.cpp b/application/dialogs/IconPickerDialog.cpp new file mode 100644 index 00000000..cafd47b7 --- /dev/null +++ b/application/dialogs/IconPickerDialog.cpp @@ -0,0 +1,156 @@ +/* Copyright 2013-2015 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 +#include +#include + +#include "MultiMC.h" + +#include "IconPickerDialog.h" +#include "ui_IconPickerDialog.h" + +#include "Platform.h" +#include "groupview/InstanceDelegate.h" + +#include "icons/IconList.h" + +IconPickerDialog::IconPickerDialog(QWidget *parent) + : QDialog(parent), ui(new Ui::IconPickerDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + 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(ENV.icons().get()); + + 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))); +} +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(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 + QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(), + tr("Icons") + "(*.png *.jpg *.jpeg *.ico)"); + ENV.icons()->installIcons(fileNames); +} + +void IconPickerDialog::removeSelectedIcon() +{ + ENV.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::exec(QString selection) +{ + auto list = ENV.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; +} diff --git a/application/dialogs/IconPickerDialog.h b/application/dialogs/IconPickerDialog.h new file mode 100644 index 00000000..610d9306 --- /dev/null +++ b/application/dialogs/IconPickerDialog.h @@ -0,0 +1,48 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include +#include + +namespace Ui +{ +class IconPickerDialog; +} + +class IconPickerDialog : public QDialog +{ + Q_OBJECT + +public: + explicit IconPickerDialog(QWidget *parent = 0); + ~IconPickerDialog(); + int exec(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(); +}; diff --git a/application/dialogs/IconPickerDialog.ui b/application/dialogs/IconPickerDialog.ui new file mode 100644 index 00000000..c548edfb --- /dev/null +++ b/application/dialogs/IconPickerDialog.ui @@ -0,0 +1,67 @@ + + + IconPickerDialog + + + + 0 + 0 + 676 + 555 + + + + Pick icon + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + IconPickerDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + IconPickerDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/application/dialogs/LoginDialog.cpp b/application/dialogs/LoginDialog.cpp new file mode 100644 index 00000000..3af5c702 --- /dev/null +++ b/application/dialogs/LoginDialog.cpp @@ -0,0 +1,110 @@ +/* Copyright 2013-2015 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 "auth/YggdrasilTask.h" + +#include + +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 = MojangAccount::createFromUsername(ui->userTextBox->text()); + m_loginTask = m_account->login(nullptr, ui->passTextBox->text()); + connect(m_loginTask.get(), &ProgressProvider::failed, this, &LoginDialog::onTaskFailed); + connect(m_loginTask.get(), &ProgressProvider::succeeded, this, + &LoginDialog::onTaskSucceeded); + connect(m_loginTask.get(), &ProgressProvider::status, this, &LoginDialog::onTaskStatus); + connect(m_loginTask.get(), &ProgressProvider::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 + ui->label->setText("" + reason + ""); + + // 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 +MojangAccountPtr 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/application/dialogs/LoginDialog.h b/application/dialogs/LoginDialog.h new file mode 100644 index 00000000..63c95fb8 --- /dev/null +++ b/application/dialogs/LoginDialog.h @@ -0,0 +1,58 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "auth/MojangAccount.h" + +namespace Ui +{ +class LoginDialog; +} + +class LoginDialog : public QDialog +{ + Q_OBJECT + +public: + ~LoginDialog(); + + static MojangAccountPtr 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; + MojangAccountPtr m_account; + std::shared_ptr m_loginTask; +}; diff --git a/application/dialogs/LoginDialog.ui b/application/dialogs/LoginDialog.ui new file mode 100644 index 00000000..b24b1c0c --- /dev/null +++ b/application/dialogs/LoginDialog.ui @@ -0,0 +1,77 @@ + + + LoginDialog + + + + 0 + 0 + 400 + 162 + + + + + 0 + 0 + + + + Add Account + + + + + + Message label placeholder. + + + Qt::RichText + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Email / Username + + + + + + + QLineEdit::Password + + + Password + + + + + + + 24 + + + false + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + diff --git a/application/dialogs/ModEditDialogCommon.cpp b/application/dialogs/ModEditDialogCommon.cpp new file mode 100644 index 00000000..4a2115d8 --- /dev/null +++ b/application/dialogs/ModEditDialogCommon.cpp @@ -0,0 +1,40 @@ +#include "ModEditDialogCommon.h" +#include "CustomMessageBox.h" +#include + +bool lastfirst(QModelIndexList &list, int &first, int &last) +{ + if (list.isEmpty()) + return false; + first = last = list[0].row(); + for (auto item : list) + { + int row = item.row(); + if (row < first) + first = row; + if (row > last) + last = row; + } + return true; +} + +void showWebsiteForMod(QWidget *parentDlg, Mod &m) +{ + QString url = m.homeurl(); + if (url.size()) + { + // catch the cases where the protocol is missing + if (!url.startsWith("http")) + { + url = "http://" + url; + } + QDesktopServices::openUrl(url); + } + else + { + CustomMessageBox::selectable( + parentDlg, QObject::tr("How sad!"), + QObject::tr("The mod author didn't provide a website link for this mod."), + QMessageBox::Warning); + } +} diff --git a/application/dialogs/ModEditDialogCommon.h b/application/dialogs/ModEditDialogCommon.h new file mode 100644 index 00000000..e2afb98a --- /dev/null +++ b/application/dialogs/ModEditDialogCommon.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include +#include +#include + +bool lastfirst(QModelIndexList &list, int &first, int &last); + +void showWebsiteForMod(QWidget *parentDlg, Mod &m); diff --git a/application/dialogs/NewInstanceDialog.cpp b/application/dialogs/NewInstanceDialog.cpp new file mode 100644 index 00000000..b3aa805b --- /dev/null +++ b/application/dialogs/NewInstanceDialog.cpp @@ -0,0 +1,207 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MultiMC.h" +#include "NewInstanceDialog.h" +#include "ui_NewInstanceDialog.h" + +#include +#include +#include +#include +#include + +#include "Platform.h" +#include "VersionSelectDialog.h" +#include "ProgressDialog.h" +#include "IconPickerDialog.h" + +#include +#include +#include +#include + +class UrlValidator : public QValidator +{ +public: + using QValidator::QValidator; + + State validate(QString &in, int &pos) const + { + const QUrl url(in); + if (url.isValid() && !url.isRelative() && !url.isEmpty()) + { + return Acceptable; + } + else if (QFile::exists(in)) + { + return Acceptable; + } + else + { + return Intermediate; + } + } +}; + +NewInstanceDialog::NewInstanceDialog(QWidget *parent) + : QDialog(parent), ui(new Ui::NewInstanceDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + resize(minimumSizeHint()); + layout()->setSizeConstraint(QLayout::SetFixedSize); + + setSelectedVersion(MMC->minecraftlist()->getLatestStable(), true); + InstIconKey = "infinity"; + ui->iconButton->setIcon(ENV.icons()->getIcon(InstIconKey)); + + ui->modpackEdit->setValidator(new UrlValidator(ui->modpackEdit)); + connect(ui->modpackEdit, &QLineEdit::textChanged, this, &NewInstanceDialog::updateDialogState); + connect(ui->modpackBox, &QRadioButton::clicked, this, &NewInstanceDialog::updateDialogState); + connect(ui->versionBox, &QRadioButton::clicked, this, &NewInstanceDialog::updateDialogState); + + auto groups = MMC->instances()->getGroups().toSet(); + auto groupList = QStringList(groups.toList()); + groupList.sort(Qt::CaseInsensitive); + groupList.removeOne(""); + QString oldValue = MMC->settings()->get("LastUsedGroupForNewInstance").toString(); + groupList.push_front(oldValue); + groupList.push_front(""); + ui->groupBox->addItems(groupList); + int index = groupList.indexOf(oldValue); + if(index == -1) + { + index = 0; + } + ui->groupBox->setCurrentIndex(index); + ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); +} + +NewInstanceDialog::~NewInstanceDialog() +{ + delete ui; +} + +void NewInstanceDialog::updateDialogState() +{ + bool allowOK = !instName().isEmpty() && + (ui->versionBox->isChecked() && m_selectedVersion || + (ui->modpackBox->isChecked() && ui->modpackEdit->hasAcceptableInput())); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowOK); +} + +void NewInstanceDialog::setSelectedVersion(BaseVersionPtr version, bool initial) +{ + m_selectedVersion = version; + + if (m_selectedVersion) + { + ui->versionTextBox->setText(version->name()); + if(ui->instNameTextBox->text().isEmpty() && !initial) + { + ui->instNameTextBox->setText(version->name()); + } + } + else + { + ui->versionTextBox->setText(""); + } + + updateDialogState(); +} + +QString NewInstanceDialog::instName() const +{ + return ui->instNameTextBox->text(); +} +QString NewInstanceDialog::instGroup() const +{ + return ui->groupBox->currentText(); +} +QString NewInstanceDialog::iconKey() const +{ + return InstIconKey; +} +QUrl NewInstanceDialog::modpackUrl() const +{ + if (ui->modpackBox->isChecked()) + { + const QUrl url(ui->modpackEdit->text()); + if (url.isValid() && !url.isRelative() && !url.host().isEmpty()) + { + return url; + } + else + { + return QUrl::fromLocalFile(ui->modpackEdit->text()); + } + } + else + { + return QUrl(); + } +} + +BaseVersionPtr NewInstanceDialog::selectedVersion() const +{ + return m_selectedVersion; +} + +void NewInstanceDialog::on_btnChangeVersion_clicked() +{ + VersionSelectDialog vselect(MMC->minecraftlist().get(), tr("Change Minecraft version"), + this); + vselect.exec(); + if (vselect.result() == QDialog::Accepted) + { + BaseVersionPtr version = vselect.selectedVersion(); + if (version) + setSelectedVersion(version); + } +} + +void NewInstanceDialog::on_iconButton_clicked() +{ + IconPickerDialog dlg(this); + dlg.exec(InstIconKey); + + if (dlg.result() == QDialog::Accepted) + { + InstIconKey = dlg.selectedIconKey; + ui->iconButton->setIcon(ENV.icons()->getIcon(InstIconKey)); + } +} + +void NewInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) +{ + updateDialogState(); +} + +void NewInstanceDialog::on_modpackBtn_clicked() +{ + const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), tr("Zip (*.zip)")); + if (url.isValid()) + { + if (url.isLocalFile()) + { + ui->modpackEdit->setText(url.toLocalFile()); + } + else + { + ui->modpackEdit->setText(url.toString()); + } + } +} diff --git a/application/dialogs/NewInstanceDialog.h b/application/dialogs/NewInstanceDialog.h new file mode 100644 index 00000000..bc3152b9 --- /dev/null +++ b/application/dialogs/NewInstanceDialog.h @@ -0,0 +1,59 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "BaseVersion.h" + +namespace Ui +{ +class NewInstanceDialog; +} + +class NewInstanceDialog : public QDialog +{ + Q_OBJECT + +public: + explicit NewInstanceDialog(QWidget *parent = 0); + ~NewInstanceDialog(); + + void updateDialogState(); + + void setSelectedVersion(BaseVersionPtr version, bool initial = false); + + void loadVersionList(); + + QString instName() const; + QString instGroup() const; + QString iconKey() const; + QUrl modpackUrl() const; + BaseVersionPtr selectedVersion() const; + +private +slots: + void on_btnChangeVersion_clicked(); + void on_iconButton_clicked(); + void on_modpackBtn_clicked(); + void on_instNameTextBox_textChanged(const QString &arg1); + +private: + Ui::NewInstanceDialog *ui; + + BaseVersionPtr m_selectedVersion; + QString InstIconKey; +}; diff --git a/application/dialogs/NewInstanceDialog.ui b/application/dialogs/NewInstanceDialog.ui new file mode 100644 index 00000000..6cb0c97c --- /dev/null +++ b/application/dialogs/NewInstanceDialog.ui @@ -0,0 +1,309 @@ + + + NewInstanceDialog + + + Qt::ApplicationModal + + + + 0 + 0 + 277 + 404 + + + + New Instance + + + + :/icons/toolbar/new:/icons/toolbar/new + + + true + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + :/icons/instances/infinity:/icons/instances/infinity + + + + 80 + 80 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Name + + + + + + + Qt::Horizontal + + + + + + + + + &Group: + + + groupBox + + + + + + + + 0 + 0 + + + + true + + + + + + + + + + + false + + + ... + + + + + + + false + + + http:// + + + + + + + true + + + + + + + ... + + + + + + + Impor&t Modpack (local file or link): + + + + + + + Vani&lla Minecraft (select version): + + + true + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Qt::Horizontal + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + instNameTextBox + groupBox + versionBox + versionTextBox + btnChangeVersion + modpackBox + modpackEdit + modpackBtn + iconButton + + + + + buttonBox + accepted() + NewInstanceDialog + accept() + + + 257 + 333 + + + 157 + 274 + + + + + buttonBox + rejected() + NewInstanceDialog + reject() + + + 325 + 333 + + + 286 + 274 + + + + + modpackBox + toggled(bool) + modpackEdit + setEnabled(bool) + + + 81 + 229 + + + 236 + 221 + + + + + modpackBox + toggled(bool) + modpackBtn + setEnabled(bool) + + + 129 + 225 + + + 328 + 229 + + + + + versionBox + toggled(bool) + versionTextBox + setEnabled(bool) + + + 93 + 195 + + + 213 + 191 + + + + + versionBox + toggled(bool) + btnChangeVersion + setEnabled(bool) + + + 104 + 198 + + + 322 + 192 + + + + + diff --git a/application/dialogs/NotificationDialog.cpp b/application/dialogs/NotificationDialog.cpp new file mode 100644 index 00000000..8f920371 --- /dev/null +++ b/application/dialogs/NotificationDialog.cpp @@ -0,0 +1,84 @@ +#include "NotificationDialog.h" +#include "ui_NotificationDialog.h" + +#include + +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; + 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/application/dialogs/NotificationDialog.h b/application/dialogs/NotificationDialog.h new file mode 100644 index 00000000..27b9e853 --- /dev/null +++ b/application/dialogs/NotificationDialog.h @@ -0,0 +1,44 @@ +#ifndef NOTIFICATIONDIALOG_H +#define NOTIFICATIONDIALOG_H + +#include + +#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/application/dialogs/NotificationDialog.ui b/application/dialogs/NotificationDialog.ui new file mode 100644 index 00000000..a2a276e9 --- /dev/null +++ b/application/dialogs/NotificationDialog.ui @@ -0,0 +1,85 @@ + + + NotificationDialog + + + + 0 + 0 + 320 + 240 + + + + Dialog + + + + + + + + TextLabel + + + + + + + TextLabel + + + true + + + true + + + Qt::TextBrowserInteraction + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + Don't show again + + + + + + + false + + + Close + + + + + + + + + + diff --git a/application/dialogs/ProgressDialog.cpp b/application/dialogs/ProgressDialog.cpp new file mode 100644 index 00000000..61ebaa28 --- /dev/null +++ b/application/dialogs/ProgressDialog.cpp @@ -0,0 +1,125 @@ +/* Copyright 2013-2015 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 + +#include "tasks/Task.h" +#include "Platform.h" + +ProgressDialog::ProgressDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ProgressDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + this->setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); + setSkipButton(false); + changeProgress(0, 100); +} + +void ProgressDialog::setSkipButton(bool present, QString label) +{ + 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() +{ + resize(QSize(480, minimumSizeHint().height())); +} + +int ProgressDialog::exec(ProgressProvider *task) +{ + this->task = task; + + // 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()) + return QDialog::exec(); + else + return QDialog::Accepted; +} + +ProgressProvider *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 (e->key() == Qt::Key_Escape) + return; + QDialog::keyPressEvent(e); +} + +void ProgressDialog::closeEvent(QCloseEvent *e) +{ + if (task && task->isRunning()) + { + e->ignore(); + } + else + { + QDialog::closeEvent(e); + } +} diff --git a/application/dialogs/ProgressDialog.h b/application/dialogs/ProgressDialog.h new file mode 100644 index 00000000..d5153680 --- /dev/null +++ b/application/dialogs/ProgressDialog.h @@ -0,0 +1,65 @@ +/* Copyright 2013-2015 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 + +class ProgressProvider; + +namespace Ui +{ +class ProgressDialog; +} + +class ProgressDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ProgressDialog(QWidget *parent = 0); + ~ProgressDialog(); + + void updateSize(); + + int exec(ProgressProvider *task); + + void setSkipButton(bool present, QString label = QString()); + + ProgressProvider *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: + Ui::ProgressDialog *ui; + + ProgressProvider *task; +}; diff --git a/application/dialogs/ProgressDialog.ui b/application/dialogs/ProgressDialog.ui new file mode 100644 index 00000000..04b8fef3 --- /dev/null +++ b/application/dialogs/ProgressDialog.ui @@ -0,0 +1,66 @@ + + + ProgressDialog + + + + 0 + 0 + 400 + 100 + + + + + 400 + 0 + + + + + 600 + 16777215 + + + + Please wait... + + + + + + Task Status... + + + true + + + + + + + 24 + + + false + + + + + + + + 0 + 0 + + + + Skip + + + + + + + + diff --git a/application/dialogs/UpdateDialog.cpp b/application/dialogs/UpdateDialog.cpp new file mode 100644 index 00000000..f7e0bcd6 --- /dev/null +++ b/application/dialogs/UpdateDialog.cpp @@ -0,0 +1,186 @@ +#include "UpdateDialog.h" +#include "ui_UpdateDialog.h" +#include "Platform.h" +#include +#include "MultiMC.h" +#include + +UpdateDialog::UpdateDialog(bool hasUpdate, QWidget *parent) : QDialog(parent), ui(new Ui::UpdateDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + auto channel = MMC->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->setDisabled(true); + ui->btnUpdateOnExit->setDisabled(true); + } + loadChangelog(); +} + +UpdateDialog::~UpdateDialog() +{ +} + +void UpdateDialog::loadChangelog() +{ + auto channel = MMC->settings()->get("UpdateChannel").toString(); + dljob.reset(new NetJob("Changelog")); + auto url = QString("https://raw.githubusercontent.com/MultiMC/MultiMC5/%1/changelog.md").arg(channel); + changelogDownload = ByteArrayDownload::make(QUrl(url)); + dljob->addNetAction(changelogDownload); + connect(dljob.get(), &NetJob::succeeded, this, &UpdateDialog::changelogLoaded); + connect(dljob.get(), &NetJob::failed, this, &UpdateDialog::changelogFailed); + dljob->start(); +} + +// TODO: this will be replaced. +QString reprocessMarkdown(QString markdown) +{ + QString htmlData; + QTextStream html(&htmlData); + auto lines = markdown.split(QRegExp("[\r]?[\n]"),QString::KeepEmptyParts); + enum + { + BASE, + LIST1, + LIST2 + }state = BASE; + html << ""; + int i = 0; + auto procLine = [&](QString line) -> QString + { + // [GitHub issues](https://github.com/MultiMC/MultiMC5/issues) + line.replace(QRegExp("\\[([^\\]]+)\\]\\(([^\\)]+)\\)"), "\\1"); + return line; + }; + for(auto line: lines) + { + if(line.isEmpty()) + { + // html << "
\n"; + } + else switch (state) + { + case BASE: + if(line.startsWith("##")) + { + html << "

" << procLine(line.mid(2)) << "

\n"; + } + else if(line.startsWith("#")) + { + html << "

" << procLine(line.mid(1)) << "

\n"; + } + else if(line.startsWith("- ")) + { + state = LIST1; + html << "
    \n"; + html << "
  • " << procLine(line.mid(2)) << "
  • \n"; + } + else qCritical() << "Invalid input on line " << i << ": " << line; + break; + case LIST1: + if(line.startsWith("##")) + { + state = BASE; + html << "
\n"; + html << "

" << procLine(line.mid(2)) << "

\n"; + } + else if(line.startsWith("#")) + { + state = BASE; + html << "\n"; + html << "

" << procLine(line.mid(1)) << "

\n"; + } + else if(line.startsWith("- ")) + { + html << "
  • " << procLine(line.mid(2)) << "
  • \n"; + } + else if(line.startsWith(" - ")) + { + state = LIST2; + html << "
      \n"; + html << "
    • " << procLine(line.mid(4)) << "
    • \n"; + } + else qCritical() << "Invalid input on line " << i << ": " << line; + break; + case LIST2: + if(line.startsWith("##")) + { + state = BASE; + html << "
    \n"; + html << "\n"; + html << "

    " << procLine(line.mid(2)) << "

    \n"; + } + else if(line.startsWith("#")) + { + state = BASE; + html << "\n"; + html << "\n"; + html << "

    " << procLine(line.mid(1)) << "

    \n"; + } + else if(line.startsWith("- ")) + { + state = LIST1; + html << "\n"; + html << "
  • " << procLine(line.mid(2)) << "
  • \n"; + } + else if(line.startsWith(" - ")) + { + html << "
  • " << procLine(line.mid(4)) << "
  • \n"; + } + else qCritical() << "Invalid input on line " << i << ": " << line; + break; + } + i++; + } + if(state == LIST2) + { + html << "\n"; + state = LIST1; + } + if(state == LIST1) + { + html << "\n"; + state = BASE; + } + if (state != BASE) + { + qCritical() << "Reprocessing markdown didn't end in a final state!"; + } + html << "\n"; + qDebug() << htmlData; + return htmlData; +} + +void UpdateDialog::changelogLoaded() +{ + auto rawMarkdown = QString::fromUtf8(changelogDownload->m_data); + auto html = reprocessMarkdown(rawMarkdown); + ui->changelogBrowser->setHtml(html); +} + +void UpdateDialog::changelogFailed() +{ + ui->changelogBrowser->setHtml(tr("

    Failed to fetch changelog...

    ")); +} + +void UpdateDialog::on_btnUpdateLater_clicked() +{ + reject(); +} + +void UpdateDialog::on_btnUpdateNow_clicked() +{ + done(UPDATE_NOW); +} + +void UpdateDialog::on_btnUpdateOnExit_clicked() +{ + done(UPDATE_ONEXIT); +} diff --git a/application/dialogs/UpdateDialog.h b/application/dialogs/UpdateDialog.h new file mode 100644 index 00000000..2ab2ff7c --- /dev/null +++ b/application/dialogs/UpdateDialog.h @@ -0,0 +1,61 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include "net/ByteArrayDownload.h" +#include "net/NetJob.h" + +namespace Ui +{ +class UpdateDialog; +} + +enum UpdateAction +{ + UPDATE_LATER = QDialog::Rejected, + UPDATE_NOW = QDialog::Accepted, + UPDATE_ONEXIT = 2 +}; + +class UpdateDialog : public QDialog +{ + Q_OBJECT + +public: + explicit UpdateDialog(bool hasUpdate = true, QWidget *parent = 0); + ~UpdateDialog(); + +private: + Ui::UpdateDialog *ui; +public slots: + void on_btnUpdateNow_clicked(); + void on_btnUpdateOnExit_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(); + +private: + ByteArrayDownloadPtr changelogDownload; + NetJobPtr dljob; +}; diff --git a/application/dialogs/UpdateDialog.ui b/application/dialogs/UpdateDialog.ui new file mode 100644 index 00000000..06f4f086 --- /dev/null +++ b/application/dialogs/UpdateDialog.ui @@ -0,0 +1,106 @@ + + + UpdateDialog + + + + 0 + 0 + 657 + 673 + + + + MultiMC Update + + + + :/icons/toolbar/checkupdate:/icons/toolbar/checkupdate + + + + + + + + + 14 + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + changelogBrowser + + + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:22pt;">Loading changelog...</span></p></body></html> + + + true + + + + + + + + + + 0 + 0 + + + + Update now + + + + + + + Update after MultiMC closes + + + + + + + + 0 + 0 + + + + Don't update yet + + + + + + + + + changelogBrowser + btnUpdateNow + btnUpdateOnExit + btnUpdateLater + + + + + + diff --git a/application/dialogs/VersionSelectDialog.cpp b/application/dialogs/VersionSelectDialog.cpp new file mode 100644 index 00000000..d1be4ad0 --- /dev/null +++ b/application/dialogs/VersionSelectDialog.cpp @@ -0,0 +1,177 @@ +/* Copyright 2013-2015 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 "ui_VersionSelectDialog.h" + +#include + +#include +#include "Platform.h" + +#include +#include +#include +#include +#include + +class VersionSelectProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + VersionSelectProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) + { + } + + struct Filter + { + QString string; + bool exact = false; + }; + + QHash filters() const + { + return m_filters; + } + void setFilter(const int column, const QString &filter, const bool exact) + { + Filter f; + f.string = filter; + f.exact = exact; + m_filters[column] = f; + invalidateFilter(); + } + void clearFilters() + { + m_filters.clear(); + invalidateFilter(); + } + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const + { + for (auto it = m_filters.begin(); it != m_filters.end(); ++it) + { + const QString version = + sourceModel()->index(source_row, it.key()).data().toString(); + + if (it.value().exact) + { + if (version != it.value().string) + { + return false; + } + continue; + } + + if (!Util::versionIsInInterval(version, it.value().string)) + { + return false; + } + } + return true; + } + + QHash m_filters; +}; + +VersionSelectDialog::VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent, + bool cancelable) + : QDialog(parent), ui(new Ui::VersionSelectDialog) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + setWindowModality(Qt::WindowModal); + setWindowTitle(title); + + m_vlist = vlist; + + m_proxyModel = new VersionSelectProxyModel(this); + m_proxyModel->setSourceModel(vlist); + + ui->listView->setModel(m_proxyModel); + ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); + + if (!cancelable) + { + ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false); + } +} + +void VersionSelectDialog::setEmptyString(QString emptyString) +{ + ui->listView->setEmptyString(emptyString); +} + +VersionSelectDialog::~VersionSelectDialog() +{ + delete ui; +} + +void VersionSelectDialog::setResizeOn(int column) +{ + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::ResizeToContents); + resizeOnColumn = column; + ui->listView->header()->setSectionResizeMode(resizeOnColumn, QHeaderView::Stretch); +} + +int VersionSelectDialog::exec() +{ + QDialog::open(); + if (!m_vlist->isLoaded()) + { + loadList(); + } + m_proxyModel->invalidate(); + return QDialog::exec(); +} + +void VersionSelectDialog::loadList() +{ + Task *loadTask = m_vlist->getLoadTask(); + if (!loadTask) + { + return; + } + ProgressDialog *taskDlg = new ProgressDialog(this); + loadTask->setParent(taskDlg); + taskDlg->exec(loadTask); + delete taskDlg; +} + +BaseVersionPtr VersionSelectDialog::selectedVersion() const +{ + auto currentIndex = ui->listView->selectionModel()->currentIndex(); + auto variant = m_proxyModel->data(currentIndex, BaseVersionList::VersionPointerRole); + return variant.value(); +} + +void VersionSelectDialog::on_refreshButton_clicked() +{ + loadList(); +} + +void VersionSelectDialog::setExactFilter(int column, QString filter) +{ + m_proxyModel->setFilter(column, filter, true); +} + +void VersionSelectDialog::setFuzzyFilter(int column, QString filter) +{ + m_proxyModel->setFilter(column, filter, false); +} + +#include "VersionSelectDialog.moc" diff --git a/application/dialogs/VersionSelectDialog.h b/application/dialogs/VersionSelectDialog.h new file mode 100644 index 00000000..69e52fe6 --- /dev/null +++ b/application/dialogs/VersionSelectDialog.h @@ -0,0 +1,66 @@ +/* Copyright 2013-2015 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "BaseVersion.h" + +class BaseVersionList; + +namespace Ui +{ +class VersionSelectDialog; +} + +class VersionSelectProxyModel; + +class VersionSelectDialog : public QDialog +{ + Q_OBJECT + +public: + explicit VersionSelectDialog(BaseVersionList *vlist, QString title, QWidget *parent = 0, + bool cancelable = true); + ~VersionSelectDialog(); + + virtual int exec(); + + //! Starts a task that loads the list. + void loadList(); + + BaseVersionPtr selectedVersion() const; + + void setFuzzyFilter(int column, QString filter); + void setExactFilter(int column, QString filter); + void setEmptyString(QString emptyString); + void setResizeOn(int column); + void setUseLatest(const bool useLatest); + +private +slots: + void on_refreshButton_clicked(); + +private: + Ui::VersionSelectDialog *ui; + + BaseVersionList *m_vlist; + + VersionSelectProxyModel *m_proxyModel; + + int resizeOnColumn = 0; +}; diff --git a/application/dialogs/VersionSelectDialog.ui b/application/dialogs/VersionSelectDialog.ui new file mode 100644 index 00000000..e4014e11 --- /dev/null +++ b/application/dialogs/VersionSelectDialog.ui @@ -0,0 +1,110 @@ + + + VersionSelectDialog + + + + 0 + 0 + 400 + 347 + + + + Choose Version + + + + + + Qt::ScrollBarAlwaysOff + + + true + + + false + + + false + + + true + + + true + + + false + + + + + + + + + Reloads the version list. + + + &Refresh + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + VersionListView + QTreeView +
    widgets/VersionListView.h
    +
    +
    + + + + buttonBox + accepted() + VersionSelectDialog + accept() + + + 257 + 290 + + + 157 + 274 + + + + + buttonBox + rejected() + VersionSelectDialog + reject() + + + 325 + 290 + + + 286 + 274 + + + + +
    -- cgit v1.2.3