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 }