File indexing completed on 2024-05-05 05:37:10

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 <Plasma5Support/DataEngine>
0016 #include <Plasma5Support/Service>
0017 #include <Plasma5Support/ServiceJob>
0018 
0019 #include "engineexplorer.h"
0020 
0021 ServiceViewer::ServiceViewer(Plasma5Support::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, &KComboBox::currentIndexChanged, this, [this](int index) {
0050         operationSelected(m_operations->itemText(index));
0051     });
0052 
0053     QString engineName = i18nc("Plasma engine with unknown name", "Unknown");
0054     QString serviceName = i18nc("Plasma service with unknown name", "Unknown");
0055 
0056     if (m_engine) {
0057         if (m_engine->metadata().isValid()) {
0058             engineName = KStringHandler::capwords(m_engine->metadata().name());
0059         }
0060         qDebug() << "Requesting service for source" << m_source;
0061         m_service = m_engine->serviceForSource(m_source);
0062 
0063         if (m_service != nullptr) {
0064             serviceName = m_service->name();
0065             updateOperations();
0066             connect(m_service, SIGNAL(operationsChanged()), this, SLOT(updateOperations()));
0067             connect(m_engine, &QObject::destroyed, this, &ServiceViewer::engineDestroyed);
0068         } else {
0069             KMessageBox::error(this, i18n("No valid service was returned. Verify that a service is available for this source."));
0070             close();
0071         }
0072     }
0073 
0074     setWindowTitle(i18nc("%1 is a Plasma service name", "%1 Service Explorer", serviceName));
0075 
0076     QString title = i18nc("Source: name of the data, Service: writes data instead of fetching",
0077                           "Engine: <b>%1</b>; Source: <b>%2</b>; Service: <b>%3</b>",
0078                           engineName,
0079                           m_source,
0080                           serviceName);
0081     m_title->setText(title);
0082     m_operations->setFocus();
0083 }
0084 
0085 ServiceViewer::~ServiceViewer()
0086 {
0087     delete m_service;
0088     m_engine = nullptr;
0089 }
0090 
0091 void ServiceViewer::updateOperations()
0092 {
0093     if (!m_engine) {
0094         return;
0095     }
0096 
0097     bool enable = false;
0098 
0099     m_operations->clear();
0100     m_operationDescription->clear();
0101 
0102     if (m_service) {
0103         const QStringList operations = m_service->operationNames();
0104 
0105         if (!operations.isEmpty()) {
0106             enable = true;
0107 
0108             for (const QString &operation : operations) {
0109                 m_operations->addItem(operation);
0110             }
0111         }
0112     }
0113 
0114     m_operations->setEnabled(enable);
0115     m_operationsLabel->setEnabled(enable);
0116     m_operationDescription->setEnabled(enable);
0117 }
0118 
0119 void ServiceViewer::startOperation()
0120 {
0121     if (!m_service) {
0122         return;
0123     }
0124 
0125     QString operation = m_operations->currentText();
0126     QVariantMap desc = m_service->operationDescription(operation);
0127     for (int i = 0; i < m_operationDescription->rowCount(); ++i) {
0128         QTableWidgetItem *item = m_operationDescription->item(i, 1);
0129         QString value = item->text();
0130 
0131         if (value.isEmpty()) {
0132             continue;
0133         }
0134 
0135         item = m_operationDescription->item(i, 0);
0136         QString key = item->text();
0137         desc[key] = value;
0138     }
0139 
0140     updateJobCount(1);
0141     Plasma5Support::ServiceJob *job = m_service->startOperationCall(desc);
0142     connect(job, &KJob::finished, this, &ServiceViewer::operationResult);
0143 }
0144 
0145 void ServiceViewer::operationSelected(const QString &operation)
0146 {
0147     if (!m_service) {
0148         return;
0149     }
0150 
0151     m_operationButton->setEnabled(true);
0152     QStringList headers;
0153     headers << i18n("Key") << i18n("Value");
0154     m_operationDescription->setHorizontalHeaderLabels(headers);
0155 
0156     QVariantMap desc = m_service->operationDescription(operation);
0157     int i = 0;
0158     const QStringList keys = desc.keys();
0159     m_operationDescription->setRowCount(keys.count());
0160     for (const QString &key : keys) {
0161         QTableWidgetItem *item = new QTableWidgetItem(key);
0162         item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
0163         m_operationDescription->setItem(i, 0, item);
0164 
0165         item = new QTableWidgetItem(desc[key].toString());
0166         m_operationDescription->setItem(i, 1, item);
0167 
0168         ++i;
0169     }
0170 }
0171 
0172 void ServiceViewer::operationResult(KJob *j)
0173 {
0174     if (!m_service) {
0175         return;
0176     }
0177 
0178     Plasma5Support::ServiceJob *job = qobject_cast<Plasma5Support::ServiceJob *>(j);
0179     if (!job) {
0180         return;
0181     }
0182 
0183     updateJobCount(-1);
0184 
0185     if (job->error()) {
0186         KMessageBox::information(this,
0187                                  i18n("<b>'%1'</b> operation with destination <b>'%2'</b> failed. "
0188                                       "<p>The error was: <b>'%3: %4'</b></p>",
0189                                       job->operationName(),
0190                                       job->destination(),
0191                                       job->error(),
0192                                       job->errorString()),
0193                                  i18n("Operation Result"));
0194     } else {
0195         QString result = EngineExplorer::convertToString(job->result());
0196         if (result.isEmpty()) {
0197             result = i18n("No response from job.");
0198         }
0199 
0200         KMessageBox::information(this,
0201                                  i18n("<b>'%1'</b> operation with destination <b>'%2'</b> returned successfully. "
0202                                       "<p>The result was: <b>'%3'</b></p>",
0203                                       job->operationName(),
0204                                       job->destination(),
0205                                       result),
0206                                  i18n("Operation Result"));
0207     }
0208 
0209     qDebug() << "operation results are in!";
0210 }
0211 
0212 void ServiceViewer::engineDestroyed()
0213 {
0214     m_service = nullptr;
0215     m_engine = nullptr;
0216     hide();
0217     deleteLater();
0218 }
0219 
0220 void ServiceViewer::updateJobCount(int numberOfJobs)
0221 {
0222     m_operationCount += numberOfJobs;
0223 
0224     if (m_operationCount < 1) {
0225         m_operationCount = 0;
0226         m_operationStatus->hide();
0227     } else {
0228         m_operationStatus->setText(i18np("One active operation…", "%1 operations active…", m_operationCount));
0229         m_operationStatus->show();
0230     }
0231 }
0232 
0233 #include "moc_serviceviewer.cpp"