File indexing completed on 2024-05-05 17:43:03

0001 /*
0002  *   SPDX-FileCopyrightText: 2008 Aaron Seigo <aseigo@kde.org>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "serviceviewer.h"
0008 
0009 #include <KLocalizedString>
0010 #include <KMessageBox>
0011 #include <KStringHandler>
0012 #include <QDebug>
0013 #include <QDialogButtonBox>
0014 
0015 #include <Plasma/DataEngine>
0016 #include <Plasma/Service>
0017 #include <Plasma/ServiceJob>
0018 
0019 #include "engineexplorer.h"
0020 
0021 ServiceViewer::ServiceViewer(Plasma::DataEngine *engine, const QString &source, QWidget *parent)
0022     : QDialog(parent)
0023     , m_engine(engine)
0024     , m_service(nullptr)
0025     , m_source(source)
0026     , m_operationCount(0)
0027     , m_operationButton(new QPushButton(i18n("Start Operation"), this))
0028 {
0029     setAttribute(Qt::WA_DeleteOnClose);
0030     QWidget *mainWidget = new QWidget(this);
0031     QVBoxLayout *layout = new QVBoxLayout();
0032 
0033     QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
0034     buttonBox->addButton(m_operationButton, QDialogButtonBox::ActionRole);
0035     buttonBox->addButton(QDialogButtonBox::Close);
0036 
0037     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0038 
0039     layout->addWidget(mainWidget);
0040     layout->addWidget(buttonBox);
0041     setLayout(layout);
0042 
0043     setupUi(mainWidget);
0044     m_operationStatus->hide();
0045 
0046     connect(m_operationButton, &QAbstractButton::clicked, this, &ServiceViewer::startOperation);
0047     m_operationButton->setEnabled(false);
0048 
0049     connect(m_operations, SIGNAL(currentIndexChanged(QString)), this, SLOT(operationSelected(QString)));
0050 
0051     QString engineName = i18nc("Plasma engine with unknown name", "Unknown");
0052     QString serviceName = i18nc("Plasma service with unknown name", "Unknown");
0053 
0054     if (m_engine) {
0055         if (m_engine->metadata().isValid()) {
0056             engineName = KStringHandler::capwords(m_engine->metadata().name());
0057         }
0058         qDebug() << "Requesting service for source" << m_source;
0059         m_service = m_engine->serviceForSource(m_source);
0060 
0061         if (m_service != nullptr) {
0062             serviceName = m_service->name();
0063             updateOperations();
0064             connect(m_service, SIGNAL(operationsChanged()), this, SLOT(updateOperations()));
0065             connect(m_engine, &QObject::destroyed, this, &ServiceViewer::engineDestroyed);
0066         } else {
0067             KMessageBox::error(this, i18n("No valid service was returned. Verify that a service is available for this source."));
0068             close();
0069         }
0070     }
0071 
0072     setWindowTitle(i18nc("%1 is a Plasma service name", "%1 Service Explorer", serviceName));
0073 
0074     QString title = i18nc("Source: name of the data, Service: writes data instead of fetching",
0075                           "Engine: <b>%1</b>; Source: <b>%2</b>; Service: <b>%3</b>",
0076                           engineName,
0077                           m_source,
0078                           serviceName);
0079     m_title->setText(title);
0080     m_operations->setFocus();
0081 }
0082 
0083 ServiceViewer::~ServiceViewer()
0084 {
0085     delete m_service;
0086     m_engine = nullptr;
0087 }
0088 
0089 void ServiceViewer::updateOperations()
0090 {
0091     if (!m_engine) {
0092         return;
0093     }
0094 
0095     bool enable = false;
0096 
0097     m_operations->clear();
0098     m_operationDescription->clear();
0099 
0100     if (m_service) {
0101         const QStringList operations = m_service->operationNames();
0102 
0103         if (!operations.isEmpty()) {
0104             enable = true;
0105 
0106             for (const QString &operation : operations) {
0107                 m_operations->addItem(operation);
0108             }
0109         }
0110     }
0111 
0112     m_operations->setEnabled(enable);
0113     m_operationsLabel->setEnabled(enable);
0114     m_operationDescription->setEnabled(enable);
0115 }
0116 
0117 void ServiceViewer::startOperation()
0118 {
0119     if (!m_service) {
0120         return;
0121     }
0122 
0123     QString operation = m_operations->currentText();
0124     QVariantMap desc = m_service->operationDescription(operation);
0125     for (int i = 0; i < m_operationDescription->rowCount(); ++i) {
0126         QTableWidgetItem *item = m_operationDescription->item(i, 1);
0127         QString value = item->text();
0128 
0129         if (value.isEmpty()) {
0130             continue;
0131         }
0132 
0133         item = m_operationDescription->item(i, 0);
0134         QString key = item->text();
0135         desc[key] = value;
0136     }
0137 
0138     updateJobCount(1);
0139     Plasma::ServiceJob *job = m_service->startOperationCall(desc);
0140     connect(job, &KJob::finished, this, &ServiceViewer::operationResult);
0141 }
0142 
0143 void ServiceViewer::operationSelected(const QString &operation)
0144 {
0145     if (!m_service) {
0146         return;
0147     }
0148 
0149     m_operationButton->setEnabled(true);
0150     QStringList headers;
0151     headers << i18n("Key") << i18n("Value");
0152     m_operationDescription->setHorizontalHeaderLabels(headers);
0153 
0154     QVariantMap desc = m_service->operationDescription(operation);
0155     int i = 0;
0156     const QStringList keys = desc.keys();
0157     m_operationDescription->setRowCount(keys.count());
0158     for (const QString &key : keys) {
0159         QTableWidgetItem *item = new QTableWidgetItem(key);
0160         item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
0161         m_operationDescription->setItem(i, 0, item);
0162 
0163         item = new QTableWidgetItem(desc[key].toString());
0164         m_operationDescription->setItem(i, 1, item);
0165 
0166         ++i;
0167     }
0168 }
0169 
0170 void ServiceViewer::operationResult(KJob *j)
0171 {
0172     if (!m_service) {
0173         return;
0174     }
0175 
0176     Plasma::ServiceJob *job = qobject_cast<Plasma::ServiceJob *>(j);
0177     if (!job) {
0178         return;
0179     }
0180 
0181     updateJobCount(-1);
0182 
0183     if (job->error()) {
0184         KMessageBox::information(this,
0185                                  i18n("<b>'%1'</b> operation with destination <b>'%2'</b> failed. "
0186                                       "<p>The error was: <b>'%3: %4'</b></p>",
0187                                       job->operationName(),
0188                                       job->destination(),
0189                                       job->error(),
0190                                       job->errorString()),
0191                                  i18n("Operation Result"));
0192     } else {
0193         QString result = EngineExplorer::convertToString(job->result());
0194         if (result.isEmpty()) {
0195             result = i18n("No response from job.");
0196         }
0197 
0198         KMessageBox::information(this,
0199                                  i18n("<b>'%1'</b> operation with destination <b>'%2'</b> returned successfully. "
0200                                       "<p>The result was: <b>'%3'</b></p>",
0201                                       job->operationName(),
0202                                       job->destination(),
0203                                       result),
0204                                  i18n("Operation Result"));
0205     }
0206 
0207     qDebug() << "operation results are in!";
0208 }
0209 
0210 void ServiceViewer::engineDestroyed()
0211 {
0212     m_service = nullptr;
0213     m_engine = nullptr;
0214     hide();
0215     deleteLater();
0216 }
0217 
0218 void ServiceViewer::updateJobCount(int numberOfJobs)
0219 {
0220     m_operationCount += numberOfJobs;
0221 
0222     if (m_operationCount < 1) {
0223         m_operationCount = 0;
0224         m_operationStatus->hide();
0225     } else {
0226         m_operationStatus->setText(i18np("One active operation…", "%1 operations active…", m_operationCount));
0227         m_operationStatus->show();
0228     }
0229 }