summaryrefslogtreecommitdiff
path: root/meshmc/launcher/meta/Index.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'meshmc/launcher/meta/Index.cpp')
-rw-r--r--meshmc/launcher/meta/Index.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/meshmc/launcher/meta/Index.cpp b/meshmc/launcher/meta/Index.cpp
new file mode 100644
index 0000000000..ace01c3b84
--- /dev/null
+++ b/meshmc/launcher/meta/Index.cpp
@@ -0,0 +1,162 @@
+/* SPDX-FileCopyrightText: 2026 Project Tick
+ * SPDX-FileContributor: Project Tick
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ * MeshMC - A Custom Launcher for Minecraft
+ * Copyright (C) 2026 Project Tick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright 2015-2021 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Index.h"
+
+#include "VersionList.h"
+#include "JsonFormat.h"
+
+namespace Meta
+{
+ Index::Index(QObject* parent) : QAbstractListModel(parent) {}
+ Index::Index(const QVector<VersionListPtr>& lists, QObject* parent)
+ : QAbstractListModel(parent), m_lists(lists)
+ {
+ for (int i = 0; i < m_lists.size(); ++i) {
+ m_uids.insert(m_lists.at(i)->uid(), m_lists.at(i));
+ connectVersionList(i, m_lists.at(i));
+ }
+ }
+
+ QVariant Index::data(const QModelIndex& index, int role) const
+ {
+ if (index.parent().isValid() || index.row() < 0 ||
+ index.row() >= m_lists.size()) {
+ return QVariant();
+ }
+
+ VersionListPtr list = m_lists.at(index.row());
+ switch (role) {
+ case Qt::DisplayRole:
+ switch (index.column()) {
+ case 0:
+ return list->humanReadable();
+ default:
+ break;
+ }
+ case UidRole:
+ return list->uid();
+ case NameRole:
+ return list->name();
+ case ListPtrRole:
+ return QVariant::fromValue(list);
+ }
+ return QVariant();
+ }
+ int Index::rowCount(const QModelIndex& parent) const
+ {
+ return m_lists.size();
+ }
+ int Index::columnCount(const QModelIndex& parent) const
+ {
+ return 1;
+ }
+ QVariant Index::headerData(int section, Qt::Orientation orientation,
+ int role) const
+ {
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole &&
+ section == 0) {
+ return tr("Name");
+ } else {
+ return QVariant();
+ }
+ }
+
+ bool Index::hasUid(const QString& uid) const
+ {
+ return m_uids.contains(uid);
+ }
+
+ VersionListPtr Index::get(const QString& uid)
+ {
+ VersionListPtr out = m_uids.value(uid, nullptr);
+ if (!out) {
+ out = std::make_shared<VersionList>(uid);
+ m_uids[uid] = out;
+ }
+ return out;
+ }
+
+ VersionPtr Index::get(const QString& uid, const QString& version)
+ {
+ auto list = get(uid);
+ return list->getVersion(version);
+ }
+
+ void Index::parse(const QJsonObject& obj)
+ {
+ parseIndex(obj, this);
+ }
+
+ void Index::merge(const std::shared_ptr<Index>& other)
+ {
+ const QVector<VersionListPtr> lists =
+ std::dynamic_pointer_cast<Index>(other)->m_lists;
+ // initial load, no need to merge
+ if (m_lists.isEmpty()) {
+ beginResetModel();
+ m_lists = lists;
+ for (int i = 0; i < lists.size(); ++i) {
+ m_uids.insert(lists.at(i)->uid(), lists.at(i));
+ connectVersionList(i, lists.at(i));
+ }
+ endResetModel();
+ } else {
+ for (const VersionListPtr& list : lists) {
+ if (m_uids.contains(list->uid())) {
+ m_uids[list->uid()]->mergeFromIndex(list);
+ } else {
+ beginInsertRows(QModelIndex(), m_lists.size(),
+ m_lists.size());
+ connectVersionList(m_lists.size(), list);
+ m_lists.append(list);
+ m_uids.insert(list->uid(), list);
+ endInsertRows();
+ }
+ }
+ }
+ }
+
+ void Index::connectVersionList(const int row, const VersionListPtr& list)
+ {
+ connect(list.get(), &VersionList::nameChanged, this, [this, row]() {
+ emit dataChanged(index(row), index(row),
+ QVector<int>() << Qt::DisplayRole);
+ });
+ }
+} // namespace Meta