diff options
Diffstat (limited to 'application/dialogs')
34 files changed, 799 insertions, 77 deletions
diff --git a/application/dialogs/AboutDialog.cpp b/application/dialogs/AboutDialog.cpp index 3d16f5c3..8f2e72c2 100644 --- a/application/dialogs/AboutDialog.cpp +++ b/application/dialogs/AboutDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -93,7 +93,7 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia ui->urlLabel->setOpenExternalLinks(true); - ui->icon->setPixmap(MMC->getThemedIcon("multimc").pixmap(64)); + ui->icon->setPixmap(MMC->getThemedIcon("logo").pixmap(64)); ui->title->setText("MultiMC 5"); ui->versionLabel->setText(tr("Version") +": " + BuildConfig.printableVersionString()); diff --git a/application/dialogs/AboutDialog.h b/application/dialogs/AboutDialog.h index 65c3628d..9768b866 100644 --- a/application/dialogs/AboutDialog.h +++ b/application/dialogs/AboutDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/AboutDialog.ui b/application/dialogs/AboutDialog.ui index d1cafcb2..5e8e3e68 100644 --- a/application/dialogs/AboutDialog.ui +++ b/application/dialogs/AboutDialog.ui @@ -165,7 +165,7 @@ </font> </property> <property name="text"> - <string>© 2012-2017 MultiMC Contributors</string> + <string>© 2012-2018 MultiMC Contributors</string> </property> <property name="alignment"> <set>Qt::AlignCenter</set> @@ -180,7 +180,7 @@ </font> </property> <property name="text"> - <string notr="true"><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></string> + <string notr="true"><html><head/><body><p><a href="http://github.com/MultiMC/MultiMC5">http://github.com/MultiMC/MultiMC5</a></p></body></html></string> </property> <property name="alignment"> <set>Qt::AlignCenter</set> diff --git a/application/dialogs/ChooseFtbPackDialog.cpp b/application/dialogs/ChooseFtbPackDialog.cpp new file mode 100644 index 00000000..ae7c72e1 --- /dev/null +++ b/application/dialogs/ChooseFtbPackDialog.cpp @@ -0,0 +1,64 @@ +#include "ChooseFtbPackDialog.h" +#include "widgets/FtbModpackListItem.h" + +ChooseFtbPackDialog::ChooseFtbPackDialog(FtbModpackList modpacks) : ui(new Ui::ChooseFtbPackDialog) { + ui->setupUi(this); + + for(int i = 0; i < modpacks.size(); i++) { + FtbModpackListItem *item = new FtbModpackListItem(ui->packList, modpacks.at(i)); + + item->setText(modpacks.at(i).name); + } + + //TODO: Use a model/view instead of a widget + connect(ui->packList, &QListWidget::itemClicked, this, &ChooseFtbPackDialog::onListItemClicked); + connect(ui->packVersionSelection, &QComboBox::currentTextChanged, this, &ChooseFtbPackDialog::onVersionSelectionItemChanged); + + ui->modpackInfo->setOpenExternalLinks(true); + +} + +ChooseFtbPackDialog::~ChooseFtbPackDialog(){ + delete ui; +} + +void ChooseFtbPackDialog::onListItemClicked(QListWidgetItem *item){ + ui->packVersionSelection->clear(); + FtbModpack selectedPack = static_cast<FtbModpackListItem*>(item)->getModpack(); + + ui->modpackInfo->setHtml("Pack by <b>" + selectedPack.author + "</b>" + "<br>Minecraft " + selectedPack.mcVersion + "<br>" + "<br>" + selectedPack.description + "<ul><li>" + selectedPack.mods.replace(";", "</li><li>") + "</li></ul>"); + + bool currentAdded = false; + + for(int i = 0; i < selectedPack.oldVersions.size(); i++) { + if(selectedPack.currentVersion == selectedPack.oldVersions.at(i)) { + currentAdded = true; + } + ui->packVersionSelection->addItem(selectedPack.oldVersions.at(i)); + } + + if(!currentAdded) { + ui->packVersionSelection->addItem(selectedPack.currentVersion); + } + + selected = selectedPack; + +} + +void ChooseFtbPackDialog::onVersionSelectionItemChanged(QString data) { + if(data.isNull() || data.isEmpty()) { + selectedVersion = ""; + return; + } + + selectedVersion = data; +} + +FtbModpack ChooseFtbPackDialog::getSelectedModpack() { + return selected; +} + +QString ChooseFtbPackDialog::getSelectedVersion() { + return selectedVersion; +} diff --git a/application/dialogs/ChooseFtbPackDialog.h b/application/dialogs/ChooseFtbPackDialog.h new file mode 100644 index 00000000..212aa27b --- /dev/null +++ b/application/dialogs/ChooseFtbPackDialog.h @@ -0,0 +1,32 @@ +#pragma once + +#include <QDialog> +#include <net/NetJob.h> +#include <modplatform/PackHelpers.h> +#include "ui_ChooseFtbPackDialog.h" +#include <modplatform/PackHelpers.h> + +namespace Ui { + class ChooseFtbPackDialog; +} + +class ChooseFtbPackDialog : public QDialog { + + Q_OBJECT + +private: + Ui::ChooseFtbPackDialog *ui; + FtbModpack selected; + QString selectedVersion; + +private slots: + void onListItemClicked(QListWidgetItem *item); + void onVersionSelectionItemChanged(QString data); + +public: + ChooseFtbPackDialog(FtbModpackList packs); + ~ChooseFtbPackDialog(); + + FtbModpack getSelectedModpack(); + QString getSelectedVersion(); +}; diff --git a/application/dialogs/ChooseFtbPackDialog.ui b/application/dialogs/ChooseFtbPackDialog.ui new file mode 100644 index 00000000..fdf845a9 --- /dev/null +++ b/application/dialogs/ChooseFtbPackDialog.ui @@ -0,0 +1,163 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ChooseFtbPackDialog</class> + <widget class="QDialog" name="ChooseFtbPackDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>730</width> + <height>437</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="geometry"> + <rect> + <x>540</x> + <y>400</y> + <width>176</width> + <height>25</height> + </rect> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + <widget class="QScrollArea" name="scrollArea"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>261</width> + <height>381</height> + </rect> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>259</width> + <height>379</height> + </rect> + </property> + <widget class="QListWidget" name="packList"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>261</width> + <height>381</height> + </rect> + </property> + </widget> + </widget> + </widget> + <widget class="QScrollArea" name="scrollArea_2"> + <property name="geometry"> + <rect> + <x>280</x> + <y>10</y> + <width>441</width> + <height>381</height> + </rect> + </property> + <property name="widgetResizable"> + <bool>true</bool> + </property> + <widget class="QWidget" name="scrollAreaWidgetContents_2"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>439</width> + <height>379</height> + </rect> + </property> + <widget class="QTextBrowser" name="modpackInfo"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>441</width> + <height>381</height> + </rect> + </property> + </widget> + </widget> + </widget> + <widget class="QComboBox" name="packVersionSelection"> + <property name="geometry"> + <rect> + <x>450</x> + <y>400</y> + <width>72</width> + <height>25</height> + </rect> + </property> + </widget> + <widget class="QLabel" name="selectedVersionLabel"> + <property name="geometry"> + <rect> + <x>340</x> + <y>400</y> + <width>101</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string>Version selected:</string> + </property> + <property name="alignment"> + <set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set> + </property> + </widget> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>ChooseFtbPackDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>666</x> + <y>422</y> + </hint> + <hint type="destinationlabel"> + <x>889</x> + <y>501</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>ChooseFtbPackDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>680</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>524</x> + <y>458</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/application/dialogs/CopyInstanceDialog.cpp b/application/dialogs/CopyInstanceDialog.cpp index 1cf13144..72ef00fa 100644 --- a/application/dialogs/CopyInstanceDialog.cpp +++ b/application/dialogs/CopyInstanceDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/CopyInstanceDialog.h b/application/dialogs/CopyInstanceDialog.h index 5a0f41f1..809552eb 100644 --- a/application/dialogs/CopyInstanceDialog.h +++ b/application/dialogs/CopyInstanceDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/CustomMessageBox.cpp b/application/dialogs/CustomMessageBox.cpp index 007c941a..a7d75263 100644 --- a/application/dialogs/CustomMessageBox.cpp +++ b/application/dialogs/CustomMessageBox.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/CustomMessageBox.h b/application/dialogs/CustomMessageBox.h index 85059153..f9c0ad4e 100644 --- a/application/dialogs/CustomMessageBox.h +++ b/application/dialogs/CustomMessageBox.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/EditAccountDialog.cpp b/application/dialogs/EditAccountDialog.cpp index 4f12c70c..e43be1d8 100644 --- a/application/dialogs/EditAccountDialog.cpp +++ b/application/dialogs/EditAccountDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/EditAccountDialog.h b/application/dialogs/EditAccountDialog.h index 3365dd1a..f121a111 100644 --- a/application/dialogs/EditAccountDialog.h +++ b/application/dialogs/EditAccountDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/ExportInstanceDialog.cpp b/application/dialogs/ExportInstanceDialog.cpp index be859994..0e19b758 100644 --- a/application/dialogs/ExportInstanceDialog.cpp +++ b/application/dialogs/ExportInstanceDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -321,9 +321,11 @@ ExportInstanceDialog::ExportInstanceDialog(InstancePtr instance, QWidget *parent auto root = instance->instanceRoot(); ui->treeView->setModel(proxyModel); ui->treeView->setRootIndex(proxyModel->mapFromSource(model->index(root))); + ui->treeView->sortByColumn(0, Qt::AscendingOrder); connect(proxyModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int))); + model->setFilter(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs | QDir::Hidden); model->setRootPath(root); auto headerView = ui->treeView->header(); headerView->setSectionResizeMode(QHeaderView::ResizeToContents); @@ -387,7 +389,7 @@ bool ExportInstanceDialog::doExport() const QString output = QFileDialog::getSaveFileName( this, tr("Export %1").arg(m_instance->name()), FS::PathCombine(QDir::homePath(), name + ".zip"), "Zip (*.zip)", nullptr, QFileDialog::DontConfirmOverwrite); - if (output.isNull()) + if (output.isEmpty()) { return false; } diff --git a/application/dialogs/ExportInstanceDialog.h b/application/dialogs/ExportInstanceDialog.h index 0e136ad8..7b9c6726 100644 --- a/application/dialogs/ExportInstanceDialog.h +++ b/application/dialogs/ExportInstanceDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/IconPickerDialog.cpp b/application/dialogs/IconPickerDialog.cpp index 70649b72..4ffd12bc 100644 --- a/application/dialogs/IconPickerDialog.cpp +++ b/application/dialogs/IconPickerDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ #include "groupview/InstanceDelegate.h" #include "icons/IconList.h" +#include <DesktopServices.h> IconPickerDialog::IconPickerDialog(QWidget *parent) : QDialog(parent), ui(new Ui::IconPickerDialog) @@ -59,19 +60,21 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) contentsWidget->setModel(MMC->icons().get()); + // NOTE: ResetRole forces the button to be on the left, while the OK/Cancel ones are on the right. We win. auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"), QDialogButtonBox::ResetRole); - auto buttonRemove = - ui->buttonBox->addButton(tr("Remove Icon"), QDialogButtonBox::ResetRole); + 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))); + connect(contentsWidget->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection))); + + auto buttonFolder = ui->buttonBox->addButton(tr("Open Folder"), QDialogButtonBox::ResetRole); + connect(buttonFolder, &QPushButton::clicked, this, &IconPickerDialog::openFolder); } + bool IconPickerDialog::eventFilter(QObject *obj, QEvent *evt) { if (obj != ui->iconView) @@ -101,7 +104,7 @@ void IconPickerDialog::addNewIcon() QString selectIcons = tr("Select Icons"); //: The type of icon files QStringList fileNames = QFileDialog::getOpenFileNames(this, selectIcons, QString(), - tr("Icons") + "(*.png *.jpg *.jpeg *.ico)"); + tr("Icons") + "(*.png *.jpg *.jpeg *.ico *.svg)"); MMC->icons()->installIcons(fileNames); } @@ -152,3 +155,8 @@ IconPickerDialog::~IconPickerDialog() { delete ui; } + +void IconPickerDialog::openFolder() +{ + DesktopServices::openDirectory(MMC->icons()->getDirectory(), true); +} diff --git a/application/dialogs/IconPickerDialog.h b/application/dialogs/IconPickerDialog.h index a2a657ed..9053ec61 100644 --- a/application/dialogs/IconPickerDialog.h +++ b/application/dialogs/IconPickerDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -45,4 +45,5 @@ slots: void delayed_scroll(QModelIndex); void addNewIcon(); void removeSelectedIcon(); + void openFolder(); }; diff --git a/application/dialogs/LoginDialog.cpp b/application/dialogs/LoginDialog.cpp index 37e26045..b2020372 100644 --- a/application/dialogs/LoginDialog.cpp +++ b/application/dialogs/LoginDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/LoginDialog.h b/application/dialogs/LoginDialog.h index 571da778..27b97cb0 100644 --- a/application/dialogs/LoginDialog.h +++ b/application/dialogs/LoginDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/NewComponentDialog.cpp b/application/dialogs/NewComponentDialog.cpp new file mode 100644 index 00000000..514aa938 --- /dev/null +++ b/application/dialogs/NewComponentDialog.cpp @@ -0,0 +1,106 @@ +/* Copyright 2013-2018 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 "NewComponentDialog.h" +#include "ui_NewComponentDialog.h" + +#include <BaseVersion.h> +#include <icons/IconList.h> +#include <tasks/Task.h> +#include <InstanceList.h> + +#include "VersionSelectDialog.h" +#include "ProgressDialog.h" +#include "IconPickerDialog.h" + +#include <QLayout> +#include <QPushButton> +#include <QFileDialog> +#include <QValidator> + +#include <meta/Index.h> +#include <meta/VersionList.h> + +NewComponentDialog::NewComponentDialog(const QString & initialName, const QString & initialUid, QWidget *parent) + : QDialog(parent), ui(new Ui::NewComponentDialog) +{ + ui->setupUi(this); + resize(minimumSizeHint()); + + ui->nameTextBox->setText(initialName); + ui->uidTextBox->setText(initialUid); + + connect(ui->nameTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState); + connect(ui->uidTextBox, &QLineEdit::textChanged, this, &NewComponentDialog::updateDialogState); + + auto groups = MMC->instances()->getGroups().toSet(); + ui->nameTextBox->setFocus(); + + originalPlaceholderText = ui->uidTextBox->placeholderText(); + updateDialogState(); +} + +NewComponentDialog::~NewComponentDialog() +{ + delete ui; +} + +void NewComponentDialog::updateDialogState() +{ + auto protoUid = ui->nameTextBox->text().toLower(); + protoUid.remove(QRegularExpression("[^a-z]")); + if(protoUid.isEmpty()) + { + ui->uidTextBox->setPlaceholderText(originalPlaceholderText); + } + else + { + QString suggestedUid = "org.multimc.custom." + protoUid; + ui->uidTextBox->setPlaceholderText(suggestedUid); + } + bool allowOK = !name().isEmpty() && !uid().isEmpty() && !uidBlacklist.contains(uid()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowOK); +} + +QString NewComponentDialog::name() const +{ + auto result = ui->nameTextBox->text(); + if(result.size()) + { + return result.trimmed(); + } + return QString(); +} + +QString NewComponentDialog::uid() const +{ + auto result = ui->uidTextBox->text(); + if(result.size()) + { + return result.trimmed(); + } + result = ui->uidTextBox->placeholderText(); + if(result.size() && result != originalPlaceholderText) + { + return result.trimmed(); + } + return QString(); +} + +void NewComponentDialog::setBlacklist(QStringList badUids) +{ + uidBlacklist = badUids; +} diff --git a/application/dialogs/NewComponentDialog.h b/application/dialogs/NewComponentDialog.h new file mode 100644 index 00000000..70caec0f --- /dev/null +++ b/application/dialogs/NewComponentDialog.h @@ -0,0 +1,48 @@ +/* Copyright 2013-2018 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <QDialog> + +#include <QString> +#include <QStringList> + +namespace Ui +{ +class NewComponentDialog; +} + +class NewComponentDialog : public QDialog +{ + Q_OBJECT + +public: + explicit NewComponentDialog(const QString & initialName = QString(), const QString & initialUid = QString(), QWidget *parent = 0); + virtual ~NewComponentDialog(); + void setBlacklist(QStringList badUids); + + QString name() const; + QString uid() const; + +private slots: + void updateDialogState(); + +private: + Ui::NewComponentDialog *ui; + + QString originalPlaceholderText; + QStringList uidBlacklist; +}; diff --git a/application/dialogs/NewComponentDialog.ui b/application/dialogs/NewComponentDialog.ui new file mode 100644 index 00000000..b30c2431 --- /dev/null +++ b/application/dialogs/NewComponentDialog.ui @@ -0,0 +1,101 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>NewComponentDialog</class> + <widget class="QDialog" name="NewComponentDialog"> + <property name="windowModality"> + <enum>Qt::ApplicationModal</enum> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>345</width> + <height>146</height> + </rect> + </property> + <property name="windowTitle"> + <string>Copy Instance</string> + </property> + <property name="windowIcon"> + <iconset> + <normaloff>:/icons/toolbar/copy</normaloff>:/icons/toolbar/copy</iconset> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLineEdit" name="nameTextBox"> + <property name="placeholderText"> + <string>Name</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="uidTextBox"> + <property name="placeholderText"> + <string>uid</string> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>nameTextBox</tabstop> + <tabstop>uidTextBox</tabstop> + </tabstops> + <resources> + <include location="../../graphics.qrc"/> + </resources> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>NewComponentDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>NewComponentDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/application/dialogs/NewInstanceDialog.cpp b/application/dialogs/NewInstanceDialog.cpp index d1a2bbfa..5faf57ac 100644 --- a/application/dialogs/NewInstanceDialog.cpp +++ b/application/dialogs/NewInstanceDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ #include "VersionSelectDialog.h" #include "ProgressDialog.h" #include "IconPickerDialog.h" +#include "ChooseFtbPackDialog.h" #include <QLayout> #include <QPushButton> @@ -71,7 +72,7 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString } else { - vlist->load(); + vlist->load(Net::Mode::Online); auto task = vlist->getLoadTask(); if(vlist->isLoaded()) { @@ -92,9 +93,12 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString connect(ui->modpackEdit, &QLineEdit::textChanged, this, &NewInstanceDialog::updateDialogState); connect(ui->modpackBox, &QRadioButton::clicked, this, &NewInstanceDialog::updateDialogState); + connect(ui->versionBox, &QRadioButton::clicked, this, &NewInstanceDialog::updateDialogState); connect(ui->versionTextBox, &QLineEdit::textChanged, this, &NewInstanceDialog::updateDialogState); + connect(ui->ftbBox, &QRadioButton::clicked, this, &NewInstanceDialog::updateDialogState); + auto groups = MMC->instances()->getGroups().toSet(); auto groupList = QStringList(groups.toList()); groupList.sort(Qt::CaseInsensitive); @@ -117,6 +121,14 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString ui->modpackBox->setChecked(true); ui->modpackEdit->setText(url); } + + ftbPackDownloader = new FtbPackDownloader(); + + connect(ftbPackDownloader, &FtbPackDownloader::ready, this, &NewInstanceDialog::ftbPackDataDownloadSuccessfully); + connect(ftbPackDownloader, &FtbPackDownloader::packFetchFailed, this, &NewInstanceDialog::ftbPackDataDownloadFailed); + + ftbPackDownloader->fetchModpacks(false); + updateDialogState(); } @@ -147,6 +159,17 @@ void NewInstanceDialog::updateDialogState() QFileInfo fi(url.fileName()); suggestedName = fi.completeBaseName(); } + else if (ui->ftbBox->isChecked()) + { + if(ftbPackDownloader->isValidPackSelected()) { + suggestedName = ftbPackDownloader->getSuggestedInstanceName(); + ui->labelFtbPack->setText(selectedPack.name); + } + + } + + ftbModpackRequested = ui->ftbBox->isChecked(); + if(suggestedName.isEmpty()) { ui->instNameTextBox->setPlaceholderText(originalPlaceholderText); @@ -156,9 +179,10 @@ void NewInstanceDialog::updateDialogState() ui->instNameTextBox->setPlaceholderText(suggestedName); } bool allowOK = !instName().isEmpty() && ( - (ui->versionBox->isChecked() && m_selectedVersion) || - (ui->modpackBox->isChecked() && ui->modpackEdit->hasAcceptableInput()) - ); + (ui->versionBox->isChecked() && m_selectedVersion) || + (ui->modpackBox->isChecked() && ui->modpackEdit->hasAcceptableInput()) || + (ui->ftbBox->isChecked() && ftbPackDownloader && ftbPackDownloader->isValidPackSelected() ) + ); ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(allowOK); } @@ -271,3 +295,34 @@ void NewInstanceDialog::on_modpackBtn_clicked() } } } + +bool NewInstanceDialog::isFtbModpackRequested() { + return ftbModpackRequested; +} + +FtbPackDownloader *NewInstanceDialog::getFtbPackDownloader() { + return ftbPackDownloader; +} + +void NewInstanceDialog::on_btnChooseFtbPack_clicked() { + ChooseFtbPackDialog dl(ftbPackDownloader->getModpacks()); + dl.exec(); + if(dl.result() == QDialog::Accepted) { + selectedPack = dl.getSelectedModpack(); + ftbPackDownloader->selectPack(selectedPack, dl.getSelectedVersion()); + } + updateDialogState(); +} + +void NewInstanceDialog::ftbPackDataDownloadSuccessfully() { + ui->packDataDownloadStatus->setText(tr("(Pack data download complete)")); + // ui->labelFtbPack->setText(tr("Disabled for now... not completed!")); + + // Disable for PR + ui->ftbBox->setEnabled(true); +} + +void NewInstanceDialog::ftbPackDataDownloadFailed() { + ui->packDataDownloadStatus->setText(tr("(Pack data download failed)")); +} + diff --git a/application/dialogs/NewInstanceDialog.h b/application/dialogs/NewInstanceDialog.h index 000b6a06..9b0f7f53 100644 --- a/application/dialogs/NewInstanceDialog.h +++ b/application/dialogs/NewInstanceDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ #include <QDialog> #include "BaseVersion.h" +#include "modplatform/FtbPackDownloader.h" +#include "modplatform/PackHelpers.h" namespace Ui { @@ -42,19 +44,31 @@ public: QUrl modpackUrl() const; BaseVersionPtr selectedVersion() const; + bool isFtbModpackRequested(); + FtbPackDownloader* getFtbPackDownloader(); + private slots: void on_btnChangeVersion_clicked(); void on_iconButton_clicked(); void on_modpackBtn_clicked(); + void on_btnChooseFtbPack_clicked(); void on_instNameTextBox_textChanged(const QString &arg1); void versionListUpdated(); + void ftbPackDataDownloadSuccessfully(); + void ftbPackDataDownloadFailed(); + private: Ui::NewInstanceDialog *ui; bool m_versionSetByUser = false; + bool ftbModpackRequested = false; + BaseVersionPtr m_selectedVersion; QString InstIconKey; QString originalPlaceholderText; + + FtbPackDownloader* ftbPackDownloader; + FtbModpack selectedPack; }; diff --git a/application/dialogs/NewInstanceDialog.ui b/application/dialogs/NewInstanceDialog.ui index 6b875ff4..428b9c57 100644 --- a/application/dialogs/NewInstanceDialog.ui +++ b/application/dialogs/NewInstanceDialog.ui @@ -10,7 +10,7 @@ <x>0</x> <y>0</y> <width>281</width> - <height>404</height> + <height>407</height> </rect> </property> <property name="windowTitle"> @@ -107,37 +107,50 @@ </item> <item> <layout class="QGridLayout" name="gridLayout"> - <item row="4" column="2"> - <widget class="QToolButton" name="modpackBtn"> + <item row="5" column="0"> + <widget class="QRadioButton" name="ftbBox"> <property name="enabled"> <bool>false</bool> </property> <property name="text"> + <string>Install FTB Pack</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QToolButton" name="btnChangeVersion"> + <property name="text"> <string notr="true">...</string> </property> </widget> </item> - <item row="4" column="0" colspan="2"> - <widget class="FocusLineEdit" name="modpackEdit"> + <item row="7" column="2"> + <widget class="QToolButton" name="btnChooseFtbPack"> <property name="enabled"> <bool>false</bool> </property> <property name="text"> - <string notr="true">http://</string> + <string>...</string> </property> </widget> </item> - <item row="2" column="0" colspan="2"> - <widget class="QLineEdit" name="versionTextBox"> - <property name="readOnly"> - <bool>true</bool> + <item row="4" column="2"> + <widget class="QToolButton" name="modpackBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string notr="true">...</string> </property> </widget> </item> - <item row="2" column="2"> - <widget class="QToolButton" name="btnChangeVersion"> + <item row="7" column="0" colspan="2"> + <widget class="QLabel" name="labelFtbPack"> + <property name="enabled"> + <bool>false</bool> + </property> <property name="text"> - <string notr="true">...</string> + <string> No Pack choosen</string> </property> </widget> </item> @@ -158,6 +171,30 @@ </property> </widget> </item> + <item row="2" column="0" colspan="2"> + <widget class="QLineEdit" name="versionTextBox"> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="FocusLineEdit" name="modpackEdit"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string notr="true">http://</string> + </property> + </widget> + </item> + <item row="5" column="1" colspan="2"> + <widget class="QLabel" name="packDataDownloadStatus"> + <property name="text"> + <string>(Loading Pack data...)</string> + </property> + </widget> + </item> </layout> </item> <item> @@ -219,8 +256,8 @@ <slot>accept()</slot> <hints> <hint type="sourcelabel"> - <x>257</x> - <y>333</y> + <x>266</x> + <y>378</y> </hint> <hint type="destinationlabel"> <x>157</x> @@ -235,11 +272,11 @@ <slot>reject()</slot> <hints> <hint type="sourcelabel"> - <x>325</x> - <y>333</y> + <x>271</x> + <y>378</y> </hint> <hint type="destinationlabel"> - <x>286</x> + <x>280</x> <y>274</y> </hint> </hints> @@ -251,12 +288,12 @@ <slot>setEnabled(bool)</slot> <hints> <hint type="sourcelabel"> - <x>81</x> - <y>229</y> + <x>91</x> + <y>251</y> </hint> <hint type="destinationlabel"> - <x>236</x> - <y>221</y> + <x>240</x> + <y>278</y> </hint> </hints> </connection> @@ -267,12 +304,12 @@ <slot>setEnabled(bool)</slot> <hints> <hint type="sourcelabel"> - <x>129</x> - <y>225</y> + <x>139</x> + <y>251</y> </hint> <hint type="destinationlabel"> - <x>328</x> - <y>229</y> + <x>270</x> + <y>278</y> </hint> </hints> </connection> @@ -287,8 +324,8 @@ <y>195</y> </hint> <hint type="destinationlabel"> - <x>213</x> - <y>191</y> + <x>223</x> + <y>224</y> </hint> </hints> </connection> @@ -303,8 +340,40 @@ <y>198</y> </hint> <hint type="destinationlabel"> - <x>322</x> - <y>192</y> + <x>270</x> + <y>224</y> + </hint> + </hints> + </connection> + <connection> + <sender>ftbBox</sender> + <signal>toggled(bool)</signal> + <receiver>btnChooseFtbPack</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>67</x> + <y>301</y> + </hint> + <hint type="destinationlabel"> + <x>254</x> + <y>327</y> + </hint> + </hints> + </connection> + <connection> + <sender>ftbBox</sender> + <signal>toggled(bool)</signal> + <receiver>labelFtbPack</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>81</x> + <y>310</y> + </hint> + <hint type="destinationlabel"> + <x>73</x> + <y>334</y> </hint> </hints> </connection> diff --git a/application/dialogs/NotificationDialog.cpp b/application/dialogs/NotificationDialog.cpp index 8f920371..d61bf6bd 100644 --- a/application/dialogs/NotificationDialog.cpp +++ b/application/dialogs/NotificationDialog.cpp @@ -18,6 +18,7 @@ NotificationDialog::NotificationDialog(const NotificationChecker::NotificationEn case NotificationChecker::NotificationEntry::Warning: icon = QStyle::SP_MessageBoxWarning; break; + default: case NotificationChecker::NotificationEntry::Information: icon = QStyle::SP_MessageBoxInformation; break; diff --git a/application/dialogs/ProfileSelectDialog.cpp b/application/dialogs/ProfileSelectDialog.cpp index 16ffe51f..f1b335f9 100644 --- a/application/dialogs/ProfileSelectDialog.cpp +++ b/application/dialogs/ProfileSelectDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/ProfileSelectDialog.h b/application/dialogs/ProfileSelectDialog.h index c8ef5959..b1268743 100644 --- a/application/dialogs/ProfileSelectDialog.h +++ b/application/dialogs/ProfileSelectDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/ProgressDialog.cpp b/application/dialogs/ProgressDialog.cpp index db973c5a..9bf54a52 100644 --- a/application/dialogs/ProgressDialog.cpp +++ b/application/dialogs/ProgressDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -116,7 +116,7 @@ bool ProgressDialog::handleImmediateResult(QDialog::DialogCode &result) { if(task->isFinished()) { - if(task->successful()) + if(task->wasSuccessful()) { result = QDialog::Accepted; } diff --git a/application/dialogs/ProgressDialog.h b/application/dialogs/ProgressDialog.h index 28de8247..f27b71e1 100644 --- a/application/dialogs/ProgressDialog.h +++ b/application/dialogs/ProgressDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/SkinUploadDialog.cpp b/application/dialogs/SkinUploadDialog.cpp index ebbab785..93414c6e 100644 --- a/application/dialogs/SkinUploadDialog.cpp +++ b/application/dialogs/SkinUploadDialog.cpp @@ -20,14 +20,59 @@ void SkinUploadDialog::on_buttonBox_accepted() if (prog.execWithTask((Task*)login.get()) != QDialog::Accepted) { //FIXME: recover with password prompt - CustomMessageBox::selectable(this, tr("Failed to login!"), tr("Unknown error"), QMessageBox::Warning)->exec(); + CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to login!"), QMessageBox::Warning)->exec(); close(); return; } - QString fileName = ui->skinPathTextBox->text(); - if (!QFile::exists(fileName)) + QString fileName; + QString input = ui->skinPathTextBox->text(); + QRegExp urlPrefixMatcher("^([a-z]+)://.+$"); + bool isLocalFile = false; + // it has an URL prefix -> it is an URL + if(urlPrefixMatcher.exactMatch(input)) { - CustomMessageBox::selectable(this, tr("Skin file does not exist!"), tr("Unknown error"), QMessageBox::Warning)->exec(); + QUrl fileURL = input; + if(fileURL.isValid()) + { + // local? + if(fileURL.isLocalFile()) + { + isLocalFile = true; + fileName = fileURL.toLocalFile(); + } + else + { + CustomMessageBox::selectable( + this, + tr("Skin Upload"), + tr("Using remote URLs for setting skins is not implemented yet."), + QMessageBox::Warning + )->exec(); + close(); + return; + } + } + else + { + CustomMessageBox::selectable( + this, + tr("Skin Upload"), + tr("You cannot use an invalid URL for uploading skins."), + QMessageBox::Warning + )->exec(); + close(); + return; + } + } + else + { + // just assume it's a path then + isLocalFile = true; + fileName = ui->skinPathTextBox->text(); + } + if (isLocalFile && !QFile::exists(fileName)) + { + CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Skin file does not exist!"), QMessageBox::Warning)->exec(); close(); return; } @@ -43,22 +88,22 @@ void SkinUploadDialog::on_buttonBox_accepted() SkinUploadPtr upload = std::make_shared<SkinUpload>(this, session, FS::read(fileName), model); if (prog.execWithTask((Task*)upload.get()) != QDialog::Accepted) { - CustomMessageBox::selectable(this, tr("Failed to upload skin!"), tr("Unknown error"), QMessageBox::Warning)->exec(); + CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Failed to upload skin!"), QMessageBox::Warning)->exec(); close(); return; } - CustomMessageBox::selectable(this, tr("Skin uploaded!"), tr("Success"), QMessageBox::Information)->exec(); + CustomMessageBox::selectable(this, tr("Skin Upload"), tr("Success"), QMessageBox::Information)->exec(); close(); } void SkinUploadDialog::on_skinBrowseBtn_clicked() { QString raw_path = QFileDialog::getOpenFileName(this, tr("Select Skin Texture"), QString(), "*.png"); - QString cooked_path = FS::NormalizePath(raw_path); - if (cooked_path.isEmpty() || !QFileInfo::exists(cooked_path)) + if (raw_path.isEmpty() || !QFileInfo::exists(raw_path)) { return; } + QString cooked_path = FS::NormalizePath(raw_path); ui->skinPathTextBox->setText(cooked_path); } diff --git a/application/dialogs/UpdateDialog.cpp b/application/dialogs/UpdateDialog.cpp index c935ec3b..30c7173d 100644 --- a/application/dialogs/UpdateDialog.cpp +++ b/application/dialogs/UpdateDialog.cpp @@ -81,6 +81,12 @@ QString reprocessCommits(QByteArray json) { const auto & commitval = commitarray[i]; auto commitobj = Json::requireObject(commitval); + auto parents_info = Json::ensureArray(commitobj, "parents"); + // NOTE: this ignores merge commits, because they have more than one parent + if(parents_info.size() > 1) + { + continue; + } auto commit_url = Json::requireString(commitobj, "html_url"); auto commit_info = Json::requireObject(commitobj, "commit"); auto commit_message = Json::requireString(commit_info, "message"); diff --git a/application/dialogs/UpdateDialog.h b/application/dialogs/UpdateDialog.h index 8099464b..78960c99 100644 --- a/application/dialogs/UpdateDialog.h +++ b/application/dialogs/UpdateDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/application/dialogs/VersionSelectDialog.cpp b/application/dialogs/VersionSelectDialog.cpp index de525d89..a44572cc 100644 --- a/application/dialogs/VersionSelectDialog.cpp +++ b/application/dialogs/VersionSelectDialog.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,6 +83,12 @@ void VersionSelectDialog::retranslate() m_refreshButton->setText(tr("&Refresh")); } +void VersionSelectDialog::setCurrentVersion(const QString& version) +{ + m_currentVersion = version; + m_versionWidget->setCurrentVersion(version); +} + void VersionSelectDialog::setEmptyString(QString emptyString) { m_versionWidget->setEmptyString(emptyString); diff --git a/application/dialogs/VersionSelectDialog.h b/application/dialogs/VersionSelectDialog.h index 4b13a57b..c8b00c65 100644 --- a/application/dialogs/VersionSelectDialog.h +++ b/application/dialogs/VersionSelectDialog.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,12 +46,12 @@ public: BaseVersionPtr selectedVersion() const; + void setCurrentVersion(const QString & version); void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter); void setExactFilter(BaseVersionList::ModelRoles role, QString filter); void setEmptyString(QString emptyString); void setEmptyErrorString(QString emptyErrorString); void setResizeOn(int column); - void setUseLatest(const bool useLatest); private slots: void on_refreshButton_clicked(); @@ -61,6 +61,7 @@ private: void selectRecommended(); private: + QString m_currentVersion; VersionSelectWidget *m_versionWidget = nullptr; QVBoxLayout *m_verticalLayout = nullptr; QHBoxLayout *m_horizontalLayout = nullptr; |