File indexing completed on 2025-01-05 05:09:31

0001 /*
0002     SPDX-FileCopyrightText: 2010-2018 Daniel Nicoletti <dantti12@gmail.com>
0003     SPDX-FileCopyrightText: 2023 Mike Noe <noeerover@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "PPDModel.h"
0009 #include "kcupslib_log.h"
0010 
0011 #include <KLocalizedString>
0012 
0013 #include <KCupsRequest.h>
0014 
0015 PPDModel::PPDModel(QObject *parent)
0016     : QStandardItemModel(parent)
0017 {
0018     m_roles = QStandardItemModel::roleNames();
0019     m_roles[PPDName] = "ppdName";
0020     m_roles[PPDMake] = "ppdMake";
0021     m_roles[PPDMakeAndModel] = "ppdMakeModel";
0022 }
0023 
0024 QHash<int, QByteArray> PPDModel::roleNames() const
0025 {
0026     return m_roles;
0027 }
0028 
0029 void PPDModel::setPPDs(const QList<QVariantMap> &ppds, const DriverMatchList &driverMatch)
0030 {
0031     clear();
0032 
0033     QStandardItem *recommended = nullptr;
0034     for (const DriverMatch &driver : driverMatch) {
0035         // Find the matched PPD on the PPDs list
0036         for (const QVariantMap &ppd : ppds) {
0037             if (ppd[QLatin1String("ppd-name")].toString() == driver.ppd) {
0038                 // Create the PPD
0039                 QStandardItem *ppdItem = createPPDItem(ppd, true);
0040 
0041                 if (recommended == nullptr) {
0042                     recommended = new QStandardItem;
0043                     recommended->setText(i18n("Recommended Drivers"));
0044                     appendRow(recommended);
0045                 }
0046                 recommended->appendRow(ppdItem);
0047 
0048                 break;
0049             }
0050         }
0051     }
0052 
0053     for (const QVariantMap &ppd : ppds) {
0054         // Find or create the PPD parent (printer Make)
0055         QStandardItem *makeItem = findCreateMake(ppd[QLatin1String("ppd-make")].toString());
0056 
0057         // Create the PPD
0058         QStandardItem *ppdItem = createPPDItem(ppd, false);
0059         makeItem->appendRow(ppdItem);
0060     }
0061 }
0062 
0063 QStandardItem *PPDModel::findCreateMake(const QString &make)
0064 {
0065     for (int i = 0; i < rowCount(); ++i) {
0066         QStandardItem *makeItem = item(i);
0067         if (makeItem->text() == make) {
0068             return makeItem;
0069         }
0070     }
0071 
0072     auto makeItem = new QStandardItem(make);
0073     appendRow(makeItem);
0074     return makeItem;
0075 }
0076 
0077 Qt::ItemFlags PPDModel::flags(const QModelIndex &index) const
0078 {
0079     Q_UNUSED(index)
0080     return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
0081 }
0082 
0083 void PPDModel::load()
0084 {
0085     qCDebug(LIBKCUPS) << "LOADING PPD Model";
0086 
0087     const auto req = new KCupsRequest;
0088     connect(req, &KCupsRequest::finished, this, [this](KCupsRequest *request) {
0089         if (request->hasError()) {
0090             Q_EMIT error(request->errorMsg());
0091             qCDebug(LIBKCUPS) << "PPD Model:" << request->errorMsg();
0092         } else {
0093             const auto ppds = request->ppds();
0094             if (!ppds.isEmpty()) {
0095                 setPPDs(ppds);
0096             } else {
0097                 Q_EMIT error(i18n("Empty ppd model"));
0098             }
0099             qCDebug(LIBKCUPS) << "PPD Model Loaded";
0100         }
0101         request->deleteLater();
0102         Q_EMIT loaded();
0103     });
0104 
0105     req->getPPDS();
0106 }
0107 
0108 QStandardItem *PPDModel::createPPDItem(const QVariantMap &ppd, bool recommended)
0109 {
0110     auto ret = new QStandardItem;
0111 
0112     QString make = ppd[QLatin1String("ppd-make")].toString();
0113     QString makeAndModel = ppd[QLatin1String("ppd-make-and-model")].toString();
0114     QString naturalLanguage = ppd[QLatin1String("ppd-natural-language")].toString();
0115     QString ppdName = ppd[QLatin1String("ppd-name")].toString();
0116 
0117     // Set this data before we change the makeAndModel
0118     ret->setData(ppdName, PPDName);
0119     ret->setData(make, PPDMake);
0120     ret->setData(makeAndModel, PPDMakeAndModel);
0121 
0122     QString text;
0123     if (recommended) {
0124         text = makeAndModel % QLatin1String(" (") % naturalLanguage % QLatin1Char(')');
0125     } else {
0126         // Removes the Make part of the string
0127         if (makeAndModel.startsWith(make)) {
0128             makeAndModel.remove(0, make.size() + 1);
0129         }
0130 
0131         // Create the PPD
0132         text = makeAndModel.trimmed() % QLatin1String(" (") % naturalLanguage % QLatin1Char(')');
0133     }
0134     ret->setText(text);
0135 
0136     return ret;
0137 }
0138 
0139 #include "moc_PPDModel.cpp"