File indexing completed on 2025-01-05 04:55:03

0001 /*
0002     Copyright (c) 2018 Christian Mollekopf <mollekopf@kolabsys.com>
0003 
0004     This library is free software; you can redistribute it and/or modify it
0005     under the terms of the GNU Library General Public License as published by
0006     the Free Software Foundation; either version 2 of the License, or (at your
0007     option) any later version.
0008 
0009     This library is distributed in the hope that it will be useful, but WITHOUT
0010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
0012     License for more details.
0013 
0014     You should have received a copy of the GNU Library General Public License
0015     along with this library; see the file COPYING.LIB.  If not, write to the
0016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0017     02110-1301, USA.
0018 */
0019 #include "extensionmodel.h"
0020 #include <QStandardItemModel>
0021 #include <QQmlEngine>
0022 #include <QDir>
0023 #include <QDebug>
0024 #include <QTimer>
0025 #include <QJsonDocument>
0026 #include <QJsonObject>
0027 
0028 using namespace Kube;
0029 
0030 ExtensionModel::ExtensionModel(QObject *parent)
0031     : QSortFilterProxyModel(parent)
0032 {
0033     setDynamicSortFilter(true);
0034     sort(0, Qt::DescendingOrder);
0035     setFilterCaseSensitivity(Qt::CaseInsensitive);
0036     QTimer::singleShot(0, this, &ExtensionModel::load);
0037 }
0038 
0039 QHash<int, QByteArray> ExtensionModel::roleNames() const
0040 {
0041     return {
0042         {Name, "name"},
0043         {Tooltip, "tooltip"},
0044         {Icon, "icon"}
0045     };
0046 }
0047 
0048 void ExtensionModel::load()
0049 {
0050     if (auto m = sourceModel()) {
0051         setSourceModel(nullptr);
0052         delete m;
0053     }
0054     auto engine = qmlEngine(this);
0055     if (!engine) {
0056         return;
0057     }
0058     auto model = new QStandardItemModel(this);
0059     for (const auto &path : engine->importPathList()) {
0060         QDir dir{path + "/org/kube/" + mExtensionPoint};
0061         for (const auto &pluginName : dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
0062             const auto pluginPath = dir.path() + "/" + pluginName;
0063             mPaths.insert(pluginName, QUrl::fromLocalFile(pluginPath));
0064             auto item = new QStandardItem;
0065             item->setData(pluginName, Name);
0066             item->setData(pluginName, Tooltip);
0067             item->setData("kdocumentinfo-inverted", Icon);
0068 
0069             if (QFileInfo::exists(pluginPath + "/metadata.json")) {
0070                 QFile file{pluginPath + "/metadata.json"};
0071                 file.open(QIODevice::ReadOnly);
0072                 auto json = QJsonDocument::fromJson(file.readAll());
0073                 auto map = json.object().toVariantMap();
0074                 item->setData(map.value("icon").toString(), Icon);
0075                 item->setData(map.value("tooltip").toString(), Tooltip);
0076                 if (map.value("hidden", false).toBool()) {
0077                     delete item;
0078                     continue;
0079                 }
0080             }
0081 
0082             model->appendRow(item);
0083         }
0084     }
0085     setSourceModel(model);
0086 }
0087 
0088 QUrl ExtensionModel::findSource(const QString &extensionName, const QString &sourceName)
0089 {
0090     if (mPaths.isEmpty()) {
0091         load();
0092     }
0093     return mPaths.value(extensionName).resolved(QUrl{extensionName + "/" + sourceName});
0094 }
0095 
0096 void ExtensionModel::setSortOrder(const QVariantList &order)
0097 {
0098     mSortOrder.clear();
0099     for (const auto &e : order) {
0100         mSortOrder << e.toString();
0101     }
0102 }
0103 
0104 QVariantList ExtensionModel::sortOrder() const
0105 {
0106     return {};
0107 }
0108 
0109 void ExtensionModel::setExtensionPoint(const QString &extensionPoint)
0110 {
0111     mExtensionPoint = extensionPoint;
0112     QTimer::singleShot(0, this, &ExtensionModel::load);
0113 }
0114 
0115 QString ExtensionModel::extensionPoint() const
0116 {
0117     return mExtensionPoint;
0118 }
0119 
0120 QVariant ExtensionModel::data(const QModelIndex &idx, int role) const
0121 {
0122     return QSortFilterProxyModel::data(idx, role);
0123 }
0124 
0125 bool ExtensionModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
0126 {
0127     auto leftIndex = mSortOrder.indexOf(left.data(Name).toString());
0128     auto rightIndex = mSortOrder.indexOf(right.data(Name).toString());
0129     if (leftIndex >= 0 && rightIndex >= 0) {
0130         //Higher index is less than
0131         return leftIndex > rightIndex;
0132     }
0133     if (leftIndex < 0 && rightIndex < 0) {
0134         return QSortFilterProxyModel::lessThan(left, right);
0135     }
0136     return leftIndex < rightIndex;
0137 }