From 439e17b149918df3fd11e0ee74f10d302a1e45cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sun, 11 May 2014 23:48:01 +0200 Subject: Add back legacy mod edit, add checksums for all legacy jars --- gui/dialogs/InstanceEditDialog.cpp | 38 +--- gui/dialogs/InstanceEditDialog.ui | 5 +- gui/dialogs/LegacyModEditDialog.cpp | 393 ++++++++++++++++++++++++++++++++++++ gui/dialogs/LegacyModEditDialog.h | 78 +++++++ gui/dialogs/LegacyModEditDialog.ui | 354 ++++++++++++++++++++++++++++++++ gui/dialogs/ModEditDialogCommon.cpp | 40 ++++ gui/dialogs/ModEditDialogCommon.h | 9 + 7 files changed, 879 insertions(+), 38 deletions(-) create mode 100644 gui/dialogs/LegacyModEditDialog.cpp create mode 100644 gui/dialogs/LegacyModEditDialog.h create mode 100644 gui/dialogs/LegacyModEditDialog.ui create mode 100644 gui/dialogs/ModEditDialogCommon.cpp create mode 100644 gui/dialogs/ModEditDialogCommon.h (limited to 'gui/dialogs') diff --git a/gui/dialogs/InstanceEditDialog.cpp b/gui/dialogs/InstanceEditDialog.cpp index 010410fd..5bd923e3 100644 --- a/gui/dialogs/InstanceEditDialog.cpp +++ b/gui/dialogs/InstanceEditDialog.cpp @@ -29,6 +29,7 @@ #include "gui/Platform.h" #include "gui/dialogs/CustomMessageBox.h" #include "gui/dialogs/VersionSelectDialog.h" +#include "gui/dialogs/ModEditDialogCommon.h" #include "gui/dialogs/ProgressDialog.h" #include "InstanceSettings.h" @@ -52,43 +53,6 @@ #include #include -bool lastfirst(QModelIndexList &list, int &first, int &last) -{ - if (!list.size()) - 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); - } -} - InstanceEditDialog::InstanceEditDialog(OneSixInstance *inst, QWidget *parent) : QDialog(parent), ui(new Ui::InstanceEditDialog), m_inst(inst) { diff --git a/gui/dialogs/InstanceEditDialog.ui b/gui/dialogs/InstanceEditDialog.ui index 85e93686..a079d3c6 100644 --- a/gui/dialogs/InstanceEditDialog.ui +++ b/gui/dialogs/InstanceEditDialog.ui @@ -53,8 +53,11 @@ Qt::ScrollBarAlwaysOff - + false + + + true diff --git a/gui/dialogs/LegacyModEditDialog.cpp b/gui/dialogs/LegacyModEditDialog.cpp new file mode 100644 index 00000000..20e1a98c --- /dev/null +++ b/gui/dialogs/LegacyModEditDialog.cpp @@ -0,0 +1,393 @@ +/* Copyright 2013 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 "LegacyModEditDialog.h" +#include "ModEditDialogCommon.h" +#include "VersionSelectDialog.h" +#include "ProgressDialog.h" +#include "ui_LegacyModEditDialog.h" +#include "logic/ModList.h" +#include "logic/forge/ForgeVersionList.h" +#include "gui/Platform.h" + +#include +#include +//#include +#include +#include +#include + +LegacyModEditDialog::LegacyModEditDialog(LegacyInstance *inst, QWidget *parent) + : QDialog(parent), ui(new Ui::LegacyModEditDialog), m_inst(inst) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + + // Jar mods + { + ensureFolderPathExists(m_inst->jarModsDir()); + m_jarmods = m_inst->jarModList(); + ui->jarModsTreeView->setModel(m_jarmods.get()); +#ifndef Q_OS_LINUX + // FIXME: internal DnD causes segfaults later + ui->jarModsTreeView->setDragDropMode(QAbstractItemView::DragDrop); + // FIXME: DnD is glitched with contiguous (we move only first item in selection) + ui->jarModsTreeView->setSelectionMode(QAbstractItemView::SingleSelection); +#endif + ui->jarModsTreeView->installEventFilter(this); + m_jarmods->startWatching(); + auto smodel = ui->jarModsTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(jarCurrent(QModelIndex, QModelIndex))); + } + // Core mods + { + ensureFolderPathExists(m_inst->coreModsDir()); + m_coremods = m_inst->coreModList(); + ui->coreModsTreeView->setModel(m_coremods.get()); + ui->coreModsTreeView->installEventFilter(this); + m_coremods->startWatching(); + auto smodel = ui->coreModsTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(coreCurrent(QModelIndex, QModelIndex))); + } + // Loader mods + { + ensureFolderPathExists(m_inst->loaderModsDir()); + m_mods = m_inst->loaderModList(); + ui->loaderModTreeView->setModel(m_mods.get()); + ui->loaderModTreeView->installEventFilter(this); + m_mods->startWatching(); + auto smodel = ui->loaderModTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(loaderCurrent(QModelIndex, QModelIndex))); + } + // texture packs + { + ensureFolderPathExists(m_inst->texturePacksDir()); + m_texturepacks = m_inst->texturePackList(); + ui->texPackTreeView->setModel(m_texturepacks.get()); + ui->texPackTreeView->installEventFilter(this); + m_texturepacks->startWatching(); + } +} + +LegacyModEditDialog::~LegacyModEditDialog() +{ + m_mods->stopWatching(); + m_coremods->stopWatching(); + m_jarmods->stopWatching(); + m_texturepacks->stopWatching(); + delete ui; +} + +bool LegacyModEditDialog::coreListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_rmCoreBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addCoreBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter(ui->coreModsTreeView, keyEvent); +} + +bool LegacyModEditDialog::jarListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Up: + { + if (keyEvent->modifiers() & Qt::ControlModifier) + { + on_moveJarUpBtn_clicked(); + return true; + } + break; + } + case Qt::Key_Down: + { + if (keyEvent->modifiers() & Qt::ControlModifier) + { + on_moveJarDownBtn_clicked(); + return true; + } + break; + } + case Qt::Key_Delete: + on_rmJarBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addJarBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter(ui->jarModsTreeView, keyEvent); +} + +bool LegacyModEditDialog::loaderListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_rmModBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addModBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter(ui->loaderModTreeView, keyEvent); +} + +bool LegacyModEditDialog::texturePackListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_rmTexPackBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addTexPackBtn_clicked(); + return true; + default: + break; + } + return QDialog::eventFilter(ui->texPackTreeView, keyEvent); +} + +bool LegacyModEditDialog::eventFilter(QObject *obj, QEvent *ev) +{ + if (ev->type() != QEvent::KeyPress) + { + return QDialog::eventFilter(obj, ev); + } + QKeyEvent *keyEvent = static_cast(ev); + if (obj == ui->jarModsTreeView) + return jarListFilter(keyEvent); + if (obj == ui->coreModsTreeView) + return coreListFilter(keyEvent); + if (obj == ui->loaderModTreeView) + return loaderListFilter(keyEvent); + if (obj == ui->texPackTreeView) + return texturePackListFilter(keyEvent); + return QDialog::eventFilter(obj, ev); +} + +void LegacyModEditDialog::on_addCoreBtn_clicked() +{ + //: Title of core mod selection dialog + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Core Mods")); + for (auto filename : fileNames) + { + m_coremods->stopWatching(); + m_coremods->installMod(QFileInfo(filename)); + m_coremods->startWatching(); + } +} +void LegacyModEditDialog::on_addForgeBtn_clicked() +{ + VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); + vselect.setExactFilter(1, m_inst->intendedVersionId()); + if (vselect.exec() && vselect.selectedVersion()) + { + ForgeVersionPtr forge = + std::dynamic_pointer_cast(vselect.selectedVersion()); + if (!forge) + return; + auto entry = MMC->metacache()->resolveEntry("minecraftforge", forge->filename()); + if (entry->stale) + { + NetJob *fjob = new NetJob("Forge download"); + fjob->addNetAction(CacheDownload::make(forge->universal_url, entry)); + ProgressDialog dlg(this); + dlg.exec(fjob); + if (dlg.result() == QDialog::Accepted) + { + m_jarmods->stopWatching(); + m_jarmods->installMod(QFileInfo(entry->getFullPath())); + m_jarmods->startWatching(); + } + else + { + // failed to download forge :/ + } + } + else + { + m_jarmods->stopWatching(); + m_jarmods->installMod(QFileInfo(entry->getFullPath())); + m_jarmods->startWatching(); + } + } +} +void LegacyModEditDialog::on_addJarBtn_clicked() +{ + //: Title of jar mod selection dialog + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Jar Mods")); + for (auto filename : fileNames) + { + m_jarmods->stopWatching(); + m_jarmods->installMod(QFileInfo(filename)); + m_jarmods->startWatching(); + } +} +void LegacyModEditDialog::on_addModBtn_clicked() +{ + //: Title of regular mod selection dialog + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Loader Mods")); + for (auto filename : fileNames) + { + m_mods->stopWatching(); + m_mods->installMod(QFileInfo(filename)); + m_mods->startWatching(); + } +} +void LegacyModEditDialog::on_addTexPackBtn_clicked() +{ + //: Title of texture pack selection dialog + QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Texture Packs")); + for (auto filename : fileNames) + { + m_texturepacks->stopWatching(); + m_texturepacks->installMod(QFileInfo(filename)); + m_texturepacks->startWatching(); + } +} + +void LegacyModEditDialog::on_moveJarDownBtn_clicked() +{ + int first, last; + auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + + m_jarmods->moveModsDown(first, last); +} +void LegacyModEditDialog::on_moveJarUpBtn_clicked() +{ + int first, last; + auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_jarmods->moveModsUp(first, last); +} +void LegacyModEditDialog::on_rmCoreBtn_clicked() +{ + int first, last; + auto list = ui->coreModsTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_coremods->stopWatching(); + m_coremods->deleteMods(first, last); + m_coremods->startWatching(); +} +void LegacyModEditDialog::on_rmJarBtn_clicked() +{ + int first, last; + auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_jarmods->stopWatching(); + m_jarmods->deleteMods(first, last); + m_jarmods->startWatching(); +} +void LegacyModEditDialog::on_rmModBtn_clicked() +{ + int first, last; + auto list = ui->loaderModTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_mods->stopWatching(); + m_mods->deleteMods(first, last); + m_mods->startWatching(); +} +void LegacyModEditDialog::on_rmTexPackBtn_clicked() +{ + int first, last; + auto list = ui->texPackTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_texturepacks->stopWatching(); + m_texturepacks->deleteMods(first, last); + m_texturepacks->startWatching(); +} +void LegacyModEditDialog::on_viewCoreBtn_clicked() +{ + openDirInDefaultProgram(m_inst->coreModsDir(), true); +} +void LegacyModEditDialog::on_viewModBtn_clicked() +{ + openDirInDefaultProgram(m_inst->loaderModsDir(), true); +} +void LegacyModEditDialog::on_viewTexPackBtn_clicked() +{ + openDirInDefaultProgram(m_inst->texturePacksDir(), true); +} + +void LegacyModEditDialog::on_buttonBox_rejected() +{ + close(); +} + +void LegacyModEditDialog::jarCurrent(QModelIndex current, QModelIndex previous) +{ + if (!current.isValid()) + { + ui->jarMIFrame->clear(); + return; + } + int row = current.row(); + Mod &m = m_jarmods->operator[](row); + ui->jarMIFrame->updateWithMod(m); +} + +void LegacyModEditDialog::coreCurrent(QModelIndex current, QModelIndex previous) +{ + if (!current.isValid()) + { + ui->coreMIFrame->clear(); + return; + } + int row = current.row(); + Mod &m = m_coremods->operator[](row); + ui->coreMIFrame->updateWithMod(m); +} + +void LegacyModEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous) +{ + if (!current.isValid()) + { + ui->loaderMIFrame->clear(); + return; + } + int row = current.row(); + Mod &m = m_mods->operator[](row); + ui->loaderMIFrame->updateWithMod(m); +} diff --git a/gui/dialogs/LegacyModEditDialog.h b/gui/dialogs/LegacyModEditDialog.h new file mode 100644 index 00000000..d5582aef --- /dev/null +++ b/gui/dialogs/LegacyModEditDialog.h @@ -0,0 +1,78 @@ +/* Copyright 2013 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 "logic/LegacyInstance.h" +#include + +namespace Ui +{ +class LegacyModEditDialog; +} + +class LegacyModEditDialog : public QDialog +{ + Q_OBJECT + +public: + explicit LegacyModEditDialog(LegacyInstance *inst, QWidget *parent = 0); + ~LegacyModEditDialog(); + +private +slots: + + void on_addJarBtn_clicked(); + void on_rmJarBtn_clicked(); + void on_addForgeBtn_clicked(); + void on_moveJarUpBtn_clicked(); + void on_moveJarDownBtn_clicked(); + + void on_addCoreBtn_clicked(); + void on_rmCoreBtn_clicked(); + void on_viewCoreBtn_clicked(); + + void on_addModBtn_clicked(); + void on_rmModBtn_clicked(); + void on_viewModBtn_clicked(); + + void on_addTexPackBtn_clicked(); + void on_rmTexPackBtn_clicked(); + void on_viewTexPackBtn_clicked(); + + // Questionable: SettingsDialog doesn't need this for some reason? + void on_buttonBox_rejected(); + + void jarCurrent(QModelIndex current, QModelIndex previous); + void coreCurrent(QModelIndex current, QModelIndex previous); + void loaderCurrent(QModelIndex current, QModelIndex previous); + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + bool jarListFilter(QKeyEvent *ev); + bool coreListFilter(QKeyEvent *ev); + bool loaderListFilter(QKeyEvent *ev); + bool texturePackListFilter(QKeyEvent *ev); + +private: + Ui::LegacyModEditDialog *ui; + std::shared_ptr m_mods; + std::shared_ptr m_coremods; + std::shared_ptr m_jarmods; + std::shared_ptr m_texturepacks; + LegacyInstance *m_inst; + NetJobPtr forgeJob; +}; diff --git a/gui/dialogs/LegacyModEditDialog.ui b/gui/dialogs/LegacyModEditDialog.ui new file mode 100644 index 00000000..52336847 --- /dev/null +++ b/gui/dialogs/LegacyModEditDialog.ui @@ -0,0 +1,354 @@ + + + LegacyModEditDialog + + + + 0 + 0 + 542 + 431 + + + + Edit Mods + + + + + + 0 + + + + Upgrade + + + + + + <!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 style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:18pt; font-weight:600;">New format is available</span></p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">MultiMC now supports old Minecraft versions in the new (OneSix) instance format. The old format won't be getting any new features and only the most critical bugfixes. As a consequence, you should upgrade this instance.</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The upgrade will create a new instance with the same contents as the current one, in the new format. The original instance will remain untouched, in case anything goes wrong in the process.</p> +<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Please report any issues on our <a href="https://github.com/MultiMC/MultiMC5/issues"><img src=":/icons/multimc/22x22/bug.png" /></a><a href="https://github.com/MultiMC/MultiMC5/issues"><span style=" text-decoration: underline; color:#68a0df;">github issues page</span></a>.</p></body></html> + + + true + + + + + + + Start the upgrade! + + + + + + + + Jar Mods + + + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + + + + + + + &Add + + + + + + + &Remove + + + + + + + MCForge + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Move &Up + + + + + + + Move &Down + + + + + + + + + + + QFrame::Plain + + + + + + + + Core Mods + + + + + + + + QAbstractItemView::DropOnly + + + + + + + + + &Add + + + + + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + &View Folder + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + Loader Mods + + + + + + + + true + + + QAbstractItemView::DropOnly + + + + + + + + + &Add + + + + + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + &View Folder + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + false + + + Texture Packs + + + + + + true + + + QAbstractItemView::DropOnly + + + + + + + + + &Add + + + + + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + &View Folder + + + + + + + + + + + + + QDialogButtonBox::Close + + + + + + + + ModListView + QTreeView +
gui/widgets/ModListView.h
+
+ + MCModInfoFrame + QFrame +
gui/widgets/MCModInfoFrame.h
+ 1 +
+
+ + + + +
diff --git a/gui/dialogs/ModEditDialogCommon.cpp b/gui/dialogs/ModEditDialogCommon.cpp new file mode 100644 index 00000000..35942374 --- /dev/null +++ b/gui/dialogs/ModEditDialogCommon.cpp @@ -0,0 +1,40 @@ +#include "ModEditDialogCommon.h" +#include "CustomMessageBox.h" +#include + +bool lastfirst(QModelIndexList &list, int &first, int &last) +{ + if (!list.size()) + 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); + } +} \ No newline at end of file diff --git a/gui/dialogs/ModEditDialogCommon.h b/gui/dialogs/ModEditDialogCommon.h new file mode 100644 index 00000000..3ccfbf6b --- /dev/null +++ b/gui/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); -- cgit v1.2.3