From e5b4dee1c05d0d6ebc0d7b2dd802b93cb8765e63 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Fri, 14 Mar 2014 19:51:56 +0100 Subject: [PATCH] Move version stuff to the model and reimplement reordering --- gui/dialogs/OneSixModEditDialog.cpp | 60 +++++++---- gui/dialogs/OneSixModEditDialog.ui | 9 -- logic/OneSixVersionBuilder.cpp | 13 +-- logic/VersionFinal.cpp | 153 ++++++++++++++++++++++++++-- logic/VersionFinal.h | 16 ++- 5 files changed, 203 insertions(+), 48 deletions(-) diff --git a/gui/dialogs/OneSixModEditDialog.cpp b/gui/dialogs/OneSixModEditDialog.cpp index 78585a05..b5a0d5aa 100644 --- a/gui/dialogs/OneSixModEditDialog.cpp +++ b/gui/dialogs/OneSixModEditDialog.cpp @@ -42,16 +42,6 @@ #include "logic/LiteLoaderInstaller.h" #include "logic/OneSixVersionBuilder.h" -template QMap invert(const QMap &in) -{ - QMap out; - for (auto it = in.begin(); it != in.end(); ++it) - { - out.insert(it.value(), it.key()); - } - return out; -} - OneSixModEditDialog::OneSixModEditDialog(OneSixInstance *inst, QWidget *parent) : QDialog(parent), ui(new Ui::OneSixModEditDialog), m_inst(inst) { @@ -164,25 +154,57 @@ void OneSixModEditDialog::on_removeLibraryBtn_clicked() void OneSixModEditDialog::on_resetLibraryOrderBtn_clicked() { - // FIXME: IMPLEMENT LOGIC IN MODEL. SEE LEGACY DIALOG FOR EXAMPLE(S). + try + { + m_version->resetOrder(); + } + catch (MMCError &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + } } void OneSixModEditDialog::on_moveLibraryUpBtn_clicked() { - // FIXME: IMPLEMENT LOGIC IN MODEL. SEE LEGACY DIALOG FOR EXAMPLE(S). + if (ui->libraryTreeView->selectionModel()->selectedRows().isEmpty()) + { + return; + } + try + { + const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row(); + const int newRow = 0;m_version->move(row, VersionFinal::MoveUp); + //ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), QItemSelectionModel::ClearAndSelect); + } + catch (MMCError &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + } } void OneSixModEditDialog::on_moveLibraryDownBtn_clicked() { - // FIXME: IMPLEMENT LOGIC IN MODEL. SEE LEGACY DIALOG FOR EXAMPLE(S). + if (ui->libraryTreeView->selectionModel()->selectedRows().isEmpty()) + { + return; + } + try + { + const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row(); + const int newRow = 0;m_version->move(row, VersionFinal::MoveDown); + //ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), QItemSelectionModel::ClearAndSelect); + } + catch (MMCError &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + } } void OneSixModEditDialog::on_forgeBtn_clicked() { // FIXME: use actual model, not reloading. Move logic to model. - // FIXME: model::isCustom(); - if (QDir(m_inst->instanceRoot()).exists("custom.json")) + if (m_version->isCustom()) { if (QMessageBox::question(this, tr("Revert?"), tr("This action will remove your custom.json. Continue?")) != @@ -190,8 +212,7 @@ void OneSixModEditDialog::on_forgeBtn_clicked() { return; } - // FIXME: model::revertToBase(); - QDir(m_inst->instanceRoot()).remove("custom.json"); + m_version->revertToBase(); reloadInstanceVersion(); } VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); @@ -242,8 +263,7 @@ void OneSixModEditDialog::on_forgeBtn_clicked() void OneSixModEditDialog::on_liteloaderBtn_clicked() { - // FIXME: model... - if (QDir(m_inst->instanceRoot()).exists("custom.json")) + if (m_version->isCustom()) { if (QMessageBox::question(this, tr("Revert?"), tr("This action will remove your custom.json. Continue?")) != @@ -251,7 +271,7 @@ void OneSixModEditDialog::on_liteloaderBtn_clicked() { return; } - QDir(m_inst->instanceRoot()).remove("custom.json"); + m_version->revertToBase(); reloadInstanceVersion(); } VersionSelectDialog vselect(MMC->liteloaderlist().get(), tr("Select LiteLoader version"), diff --git a/gui/dialogs/OneSixModEditDialog.ui b/gui/dialogs/OneSixModEditDialog.ui index b606dcd2..2c9f70bb 100644 --- a/gui/dialogs/OneSixModEditDialog.ui +++ b/gui/dialogs/OneSixModEditDialog.ui @@ -99,9 +99,6 @@ - - false - This isn't implemented yet. @@ -112,9 +109,6 @@ - - false - This isn't implemented yet. @@ -125,9 +119,6 @@ - - false - This isn't implemented yet. diff --git a/logic/OneSixVersionBuilder.cpp b/logic/OneSixVersionBuilder.cpp index 8eacbce4..35d01a46 100644 --- a/logic/OneSixVersionBuilder.cpp +++ b/logic/OneSixVersionBuilder.cpp @@ -58,13 +58,15 @@ void OneSixVersionBuilder::readJsonAndApplyToVersion(VersionFinal *version, void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringList &external) { - m_version->clear(); + m_version->versionFiles.clear(); QDir root(m_instance->instanceRoot()); QDir patches(root.absoluteFilePath("patches/")); // if we do external files, do just those. if (!external.isEmpty()) + { + int externalOrder = -1; for (auto fileName : external) { QLOG_INFO() << "Reading" << fileName; @@ -72,11 +74,12 @@ void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringLi parseJsonFile(QFileInfo(fileName), false, fileName.endsWith("pack.json")); file->name = QFileInfo(fileName).fileName(); file->fileId = "org.multimc.external." + file->name; + file->order = (externalOrder += 1); file->version = QString(); file->mcVersion = QString(); - file->applyTo(m_version); m_version->versionFiles.append(file); } + } // else, if there's custom json, we just do that. else if (QFile::exists(root.absoluteFilePath("custom.json"))) { @@ -85,8 +88,8 @@ void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringLi file->name = "custom.json"; file->filename = "custom.json"; file->fileId = "org.multimc.custom.json"; + file->order = -1; file->version = QString(); - file->applyTo(m_version); m_version->versionFiles.append(file); // QObject::tr("The version descriptors of this instance are not compatible with the // current version of MultiMC")); @@ -101,9 +104,9 @@ void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringLi auto file = parseJsonFile(QFileInfo(root.absoluteFilePath("version.json")), false); file->name = "Minecraft"; file->fileId = "org.multimc.version.json"; + file->order = -1; file->version = m_instance->intendedVersionId(); file->mcVersion = m_instance->intendedVersionId(); - file->applyTo(m_version); m_version->versionFiles.append(file); // QObject::tr("Error while applying %1. Please check MultiMC-0.log for more // info.").arg(root.absoluteFilePath("version.json"))); @@ -128,9 +131,7 @@ void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringLi } for (auto order : files.keys()) { - QLOG_DEBUG() << "Applying file with order" << order; auto &filePair = files[order]; - filePair.second->applyTo(m_version); m_version->versionFiles.append(filePair.second); } } while (0); diff --git a/logic/VersionFinal.cpp b/logic/VersionFinal.cpp index a057ecdd..2901fcf9 100644 --- a/logic/VersionFinal.cpp +++ b/logic/VersionFinal.cpp @@ -17,8 +17,20 @@ #include #include +#include #include "OneSixVersionBuilder.h" +#include "OneSixInstance.h" + +template QMap invert(const QMap &in) +{ + QMap out; + for (auto it = in.begin(); it != in.end(); ++it) + { + out.insert(it.value(), it.key()); + } + return out; +} VersionFinal::VersionFinal(OneSixInstance *instance, QObject *parent) : QAbstractListModel(parent), m_instance(instance) @@ -31,12 +43,12 @@ bool VersionFinal::reload(const bool onlyVanilla, const QStringList &external) //FIXME: source of epic failure. beginResetModel(); OneSixVersionBuilder::build(this, m_instance, onlyVanilla, external); + reapply(true); endResetModel(); } void VersionFinal::clear() { - beginResetModel(); id.clear(); time.clear(); releaseTime.clear(); @@ -48,8 +60,6 @@ void VersionFinal::clear() mainClass.clear(); libraries.clear(); tweakers.clear(); - versionFiles.clear(); - endResetModel(); } bool VersionFinal::canRemove(const int index) const @@ -60,6 +70,14 @@ bool VersionFinal::canRemove(const int index) const } return false; } +bool VersionFinal::remove(const int index) +{ + if (canRemove(index)) + { + return QFile::remove(versionFiles.at(index)->filename); + } + return false; +} QString VersionFinal::versionFileId(const int index) const { @@ -69,14 +87,16 @@ QString VersionFinal::versionFileId(const int index) const } return versionFiles.at(index)->fileId; } - -bool VersionFinal::remove(const int index) +VersionFilePtr VersionFinal::versionFile(const QString &id) { - if (canRemove(index)) + for (auto file : versionFiles) { - return QFile::remove(versionFiles.at(index)->filename); + if (file->fileId == id) + { + return file; + } } - return false; + return 0; } QList > VersionFinal::getActiveNormalLibs() @@ -91,7 +111,6 @@ QList > VersionFinal::getActiveNormalLibs() } return output; } - QList > VersionFinal::getActiveNativeLibs() { QList > output; @@ -144,7 +163,6 @@ QVariant VersionFinal::data(const QModelIndex &index, int role) const } return QVariant(); } - QVariant VersionFinal::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal) @@ -164,7 +182,6 @@ QVariant VersionFinal::headerData(int section, Qt::Orientation orientation, int } return QVariant(); } - Qt::ItemFlags VersionFinal::flags(const QModelIndex &index) const { if (!index.isValid()) @@ -181,3 +198,117 @@ int VersionFinal::columnCount(const QModelIndex &parent) const { return 2; } + +bool VersionFinal::isCustom() +{ + return QDir(m_instance->instanceRoot()).exists("custom.json"); +} +bool VersionFinal::revertToBase() +{ + return QDir(m_instance->instanceRoot()).remove("custom.json"); +} + +QMap VersionFinal::getExistingOrder() const +{ + + QMap order; + // default + { + for (auto file : versionFiles) + { + order.insert(file->fileId, file->order); + } + } + // overriden + { + QMap overridenOrder = OneSixVersionBuilder::readOverrideOrders(m_instance); + for (auto id : order.keys()) + { + if (overridenOrder.contains(id)) + { + order[id] = overridenOrder[id]; + } + } + } + return order; +} + +void VersionFinal::move(const int index, const MoveDirection direction) +{ + int theirIndex; + if (direction == MoveUp) + { + theirIndex = index - 1; + } + else + { + theirIndex = index + 1; + } + if (theirIndex < 0 || theirIndex >= versionFiles.size()) + { + return; + } + const QString ourId = versionFileId(index); + const QString theirId = versionFileId(theirIndex); + if (ourId.isNull() || ourId.startsWith("org.multimc.") || + theirId.isNull() || theirId.startsWith("org.multimc.")) + { + return; + } + + VersionFilePtr we = versionFiles[index]; + VersionFilePtr them = versionFiles[theirIndex]; + if (!we || !them) + { + return; + } + beginMoveRows(QModelIndex(), index, index, QModelIndex(), theirIndex); + versionFiles.replace(theirIndex, we); + versionFiles.replace(index, them); + endMoveRows(); + + auto order = getExistingOrder(); + order[ourId] = theirIndex; + order[theirId] = index; + + if (!OneSixVersionBuilder::writeOverrideOrders(order, m_instance)) + { + throw MMCError(tr("Couldn't save the new order")); + } + else + { + reapply(); + } +} +void VersionFinal::resetOrder() +{ + QDir(m_instance->instanceRoot()).remove("order.json"); + reapply(); +} + +void VersionFinal::reapply(const bool alreadyReseting) +{ + if (!alreadyReseting) + { + beginResetModel(); + } + + clear(); + + auto existingOrders = getExistingOrder(); + QList orders = existingOrders.values(); + std::sort(orders.begin(), orders.end()); + QList newVersionFiles; + for (auto order : orders) + { + auto file = versionFile(existingOrders.key(order)); + newVersionFiles.append(file); + file->applyTo(this); + } + versionFiles.swap(newVersionFiles); + + if (!alreadyReseting) + { + endResetModel(); + } +} diff --git a/logic/VersionFinal.h b/logic/VersionFinal.h index 99fd5ff0..fcffb3c3 100644 --- a/logic/VersionFinal.h +++ b/logic/VersionFinal.h @@ -41,12 +41,22 @@ public: bool reload(const bool onlyVanilla = false, const QStringList &external = QStringList()); void clear(); - void dump() const; - bool canRemove(const int index) const; QString versionFileId(const int index) const; + // does this instance have an all overriding custom.json + bool isCustom(); + // remove custom.json + bool revertToBase(); + + enum MoveDirection { MoveUp, MoveDown }; + void move(const int index, const MoveDirection direction); + void resetOrder(); + + // clears and reapplies all version files + void reapply(const bool alreadyReseting = false); + public slots: bool remove(const int index); @@ -120,7 +130,9 @@ public: // QList rules; QList versionFiles; + VersionFilePtr versionFile(const QString &id); private: OneSixInstance *m_instance; + QMap getExistingOrder() const; };