00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "engineexplorer.h"
00021
00022 #include <QApplication>
00023 #include <QStandardItemModel>
00024 #include <QVBoxLayout>
00025 #include <QHBoxLayout>
00026 #include <QSpinBox>
00027 #include <QBitArray>
00028 #include <QBitmap>
00029
00030 #include <KAction>
00031 #include <KIconLoader>
00032 #include <KIconTheme>
00033 #include <KStandardAction>
00034 #include <KStringHandler>
00035
00036 #ifdef FOUND_SOPRANO
00037 #include <Soprano/Node>
00038 Q_DECLARE_METATYPE(Soprano::Node)
00039 #endif // FOUND_SOPRANO
00040
00041 #include "plasma/dataenginemanager.h"
00042
00043 #include "titlecombobox.h"
00044
00045 EngineExplorer::EngineExplorer(QWidget* parent)
00046 : KDialog(parent),
00047 m_engine(0),
00048 m_sourceCount(0),
00049 m_requestingSource(false)
00050 {
00051 setButtons(0);
00052 #ifdef FOUND_SOPRANO
00053 (void) qRegisterMetaType<Soprano::Node>();
00054 #endif
00055 setWindowTitle(i18n("Plasma Engine Explorer"));
00056 QWidget* mainWidget = new QWidget(this);
00057 setMainWidget(mainWidget);
00058 setupUi(mainWidget);
00059
00060 m_engineManager = Plasma::DataEngineManager::self();
00061 m_dataModel = new QStandardItemModel(this);
00062 KIcon pix("plasma");
00063 int size = IconSize(KIconLoader::Dialog);
00064 m_title->setPixmap(pix.pixmap(size, size));
00065 connect(m_engines, SIGNAL(activated(QString)), this, SLOT(showEngine(QString)));
00066 connect(m_sourceRequesterButton, SIGNAL(clicked(bool)), this, SLOT(requestSource()));
00067 m_data->setModel(m_dataModel);
00068
00069 m_searchLine->setTreeView(m_data);
00070 m_searchLine->setClickMessage(i18n("Search"));
00071
00072 listEngines();
00073 m_engines->setFocus();
00074
00075 setButtons(KDialog::Close | KDialog::User1 | KDialog::User2);
00076 setButtonText(KDialog::User1, i18n("Collapse all"));
00077 setButtonText(KDialog::User2, i18n("Expand all"));
00078 connect(this, SIGNAL(user1Clicked()), m_data, SLOT(collapseAll()));
00079 connect(this, SIGNAL(user2Clicked()), m_data, SLOT(expandAll()));
00080 enableButton(KDialog::User1, false);
00081 enableButton(KDialog::User2, false);
00082
00083 addAction(KStandardAction::quit(qApp, SLOT(quit()), this));
00084 }
00085
00086 EngineExplorer::~EngineExplorer()
00087 {
00088 }
00089
00090 void EngineExplorer::setEngine(const QString &engine)
00091 {
00092
00093 int index = m_engines->findText(engine);
00094 if (index != -1) {
00095 kDebug() << "Engine found!";
00096 m_engines->setCurrentIndex(index);
00097 showEngine(engine);
00098 }
00099 }
00100
00101 void EngineExplorer::setInterval(const int interval)
00102 {
00103 m_updateInterval->setValue(interval);
00104 }
00105
00106 void EngineExplorer::dataUpdated(const QString& source, const Plasma::DataEngine::Data& data)
00107 {
00108 QList<QStandardItem*> items = m_dataModel->findItems(source, 0);
00109
00110 if (items.count() < 1) {
00111 return;
00112 }
00113
00114 QStandardItem* parent = items.first();
00115
00116 while (parent->hasChildren()) {
00117 parent->removeRow(0);
00118 }
00119
00120 showData(parent, data);
00121 }
00122
00123 void EngineExplorer::listEngines()
00124 {
00125 m_engines->clear();
00126 QStringList engines = m_engineManager->listAllEngines();
00127 qSort(engines);
00128 m_engines->addItems(engines);
00129 m_engines->setCurrentIndex(-1);
00130 }
00131
00132 void EngineExplorer::showEngine(const QString& name)
00133 {
00134 m_sourceRequester->setEnabled(false);
00135 m_sourceRequesterButton->setEnabled(false);
00136 enableButton(KDialog::User1, false);
00137 enableButton(KDialog::User2, false);
00138 m_dataModel->clear();
00139 m_dataModel->setColumnCount(4);
00140 QStringList headers;
00141 headers << i18n("DataSource") << i18n("Key") << i18n("Value") << i18n("Type");
00142 m_dataModel->setHorizontalHeaderLabels(headers);
00143 m_engine = 0;
00144 m_sourceCount = 0;
00145
00146 if (!m_engineName.isEmpty()) {
00147 m_engineManager->unloadEngine(m_engineName);
00148 }
00149
00150 m_engineName = name;
00151 if (m_engineName.isEmpty()) {
00152 updateTitle();
00153 return;
00154 }
00155
00156 m_engine = m_engineManager->loadEngine(m_engineName);
00157 if (!m_engine) {
00158 m_engineName.clear();
00159 updateTitle();
00160 return;
00161 }
00162
00163 QStringList sources = m_engine->sources();
00164
00165
00166
00167 foreach (const QString& source, sources) {
00168
00169 addSource(source);
00170 }
00171
00172 m_sourceRequesterButton->setEnabled(true);
00173 m_updateInterval->setEnabled(true);
00174 m_sourceRequester->setEnabled(true);
00175 m_sourceRequester->setFocus();
00176 connect(m_engine, SIGNAL(sourceAdded(QString)), this, SLOT(addSource(QString)));
00177 connect(m_engine, SIGNAL(sourceRemoved(QString)), this, SLOT(removeSource(QString)));
00178 updateTitle();
00179 }
00180
00181 void EngineExplorer::addSource(const QString& source)
00182 {
00183 QStandardItem* parent = new QStandardItem(source);
00184 m_dataModel->appendRow(parent);
00185
00186
00187 Plasma::DataEngine::Data data = m_engine->query(source);
00188 showData(parent, data);
00189
00190 if (!m_requestingSource || m_sourceRequester->text() != source) {
00191 m_engine->connectSource(source, this);
00192 }
00193
00194 ++m_sourceCount;
00195 updateTitle();
00196
00197 enableButton(KDialog::User1, true);
00198 enableButton(KDialog::User2, true);
00199 }
00200
00201 void EngineExplorer::removeSource(const QString& source)
00202 {
00203 QList<QStandardItem*> items = m_dataModel->findItems(source, 0);
00204
00205 if (items.count() < 1) {
00206 return;
00207 }
00208
00209 foreach (QStandardItem* item, items) {
00210 m_dataModel->removeRow(item->row());
00211 }
00212
00213 --m_sourceCount;
00214 updateTitle();
00215 }
00216
00217 void EngineExplorer::requestSource()
00218 {
00219 if (!m_engine) {
00220 return;
00221 }
00222
00223 QString source = m_sourceRequester->text();
00224
00225 if (source.isEmpty()) {
00226 return;
00227 }
00228
00229 kDebug() << "request source" << source;
00230 m_requestingSource = true;
00231 m_engine->connectSource(source, this, (uint)m_updateInterval->value());
00232 m_requestingSource = false;
00233 }
00234
00235 QString EngineExplorer::convertToString(const QVariant &value) const
00236 {
00237 switch (value.type())
00238 {
00239 case QVariant::BitArray: {
00240 return i18np("<1 bit>", "<%1 bits>", value.toBitArray().size());
00241 }
00242 case QVariant::Bitmap: {
00243 QBitmap bitmap = value.value<QBitmap>();
00244 return QString("<%1x%2px - %3bpp>").arg(bitmap.width()).arg(bitmap.height()).arg(bitmap.depth());
00245 }
00246 case QVariant::ByteArray: {
00247
00248 if (value.toString().isEmpty()) {
00249 return i18np("<1 byte>", "<%1 bytes>", value.toByteArray().size());
00250 }
00251 else {
00252 return value.toString();
00253 }
00254 }
00255 case QVariant::Image: {
00256 QImage image = value.value<QImage>();
00257 return QString("<%1x%2px - %3bpp>").arg(image.width()).arg(image.height()).arg(image.depth());
00258 }
00259 case QVariant::Line: {
00260 QLine line = value.toLine();
00261 return QString("<x1:%1, y1:%2, x2:%3, y2:%4>").arg(line.x1()).arg(line.y1()).arg(line.x2()).arg(line.y2());
00262 }
00263 case QVariant::LineF: {
00264 QLineF lineF = value.toLineF();
00265 return QString("<x1:%1, y1:%2, x2:%3, y2:%4>").arg(lineF.x1()).arg(lineF.y1()).arg(lineF.x2()).arg(lineF.y2());
00266 }
00267 case QVariant::Locale: {
00268 return QString("%1").arg(value.toLocale().name());
00269 }
00270 case QVariant::Map: {
00271 return i18np("<1 item>", "<%1 items>", value.toMap().size());
00272 }
00273 case QVariant::Pixmap: {
00274 QPixmap pixmap = value.value<QPixmap>();
00275 return QString("<%1x%2px - %3bpp>").arg(pixmap.width()).arg(pixmap.height()).arg(pixmap.depth());
00276 }
00277 case QVariant::Point: {
00278 QPoint point = value.toPoint();
00279 return QString("<x:%1, y:%2>").arg(point.x()).arg(point.y());
00280 }
00281 case QVariant::PointF: {
00282 QPointF pointF = value.toPointF();
00283 return QString("<x:%1, y:%2>").arg(pointF.x()).arg(pointF.y());
00284 }
00285 case QVariant::Rect: {
00286 QRect rect = value.toRect();
00287 return QString("<x:%1, y:%2, w:%3, h:%4>").arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height());
00288 }
00289 case QVariant::RectF: {
00290 QRectF rectF = value.toRectF();
00291 return QString("<x:%1, y:%2, w:%3, h:%4>").arg(rectF.x()).arg(rectF.y()).arg(rectF.width()).arg(rectF.height());
00292 }
00293 case QVariant::RegExp: {
00294 return QString("%1").arg(value.toRegExp().pattern());
00295 }
00296 case QVariant::Region: {
00297 QRect region = value.value<QRegion>().boundingRect();
00298 return QString("<x:%1, y:%2, w:%3, h:%4>").arg(region.x()).arg(region.y()).arg(region.width()).arg(region.height());
00299 }
00300 case QVariant::Size: {
00301 QSize size = value.toSize();
00302 return QString("<w:%1, h:%2>").arg(size.width()).arg(size.height());
00303 }
00304 case QVariant::SizeF: {
00305 QSizeF sizeF = value.toSizeF();
00306 return QString("<w:%1, h:%2>").arg(sizeF.width()).arg(sizeF.height());
00307 }
00308 case QVariant::Url: {
00309 return QString("%1").arg(value.toUrl().toString());
00310 }
00311 default: {
00312 #ifdef FOUND_SOPRANO
00313 if (QLatin1String(value.typeName()) == "Soprano::Node") {
00314 Soprano::Node node = value.value<Soprano::Node>();
00315 if (node.isLiteral()) {
00316 return convertToString(node.literal().variant());
00317 } else if (node.isResource()) {
00318 return node.uri().toString();
00319 } else if (node.isBlank()) {
00320 return QString("_:%1").arg(node.identifier());
00321 }
00322 }
00323 #endif
00324 if (value.canConvert(QVariant::String)) {
00325 if (value.toString().isEmpty()) {
00326 return i18n("<empty>");
00327 }
00328 else {
00329 return value.toString();
00330 }
00331 }
00332
00333 return i18n("<not displayable>");
00334 }
00335 }
00336 }
00337
00338 void EngineExplorer::showData(QStandardItem* parent, Plasma::DataEngine::Data data)
00339 {
00340 int rowCount = 0;
00341 Plasma::DataEngine::DataIterator it(data);
00342
00343
00344 while (it.hasNext()) {
00345 it.next();
00346 parent->setChild(rowCount, 1, new QStandardItem(it.key()));
00347 if (it.value().canConvert(QVariant::List)) {
00348 foreach(const QVariant &var, it.value().toList()) {
00349 QStandardItem *item = new QStandardItem(convertToString(var));
00350 item->setToolTip(item->text());
00351 parent->setChild(rowCount, 2, item);
00352 parent->setChild(rowCount, 3, new QStandardItem(var.typeName()));
00353 ++rowCount;
00354 }
00355 }
00356 else {
00357 QStandardItem *item = new QStandardItem(convertToString(it.value()));
00358 item->setToolTip(item->text());
00359 parent->setChild(rowCount, 2, item);
00360 parent->setChild(rowCount, 3, new QStandardItem(it.value().typeName()));
00361 ++rowCount;
00362 }
00363 }
00364 }
00365
00366 void EngineExplorer::updateTitle()
00367 {
00368 if (!m_engine) {
00369 m_title->setPixmap(KIcon("plasma").pixmap(IconSize(KIconLoader::Dialog)));
00370 m_title->setText(i18n("Plasma DataEngine Explorer"));
00371 return;
00372 }
00373
00374 m_title->setText(ki18ncp("The name of the engine followed by the number of data sources",
00375 "%1 Engine - 1 data source", "%1 Engine - %2 data sources")
00376 .subs(KStringHandler::capwords(m_engine->name()))
00377 .subs(m_sourceCount).toString());
00378 if (m_engine->icon().isEmpty()) {
00379 m_title->setPixmap(KIcon("plasma").pixmap(IconSize(KIconLoader::Dialog)));
00380 } else {
00381
00382 m_title->setPixmap(KIcon(m_engine->icon()).pixmap(IconSize(KIconLoader::Dialog)));
00383 }
00384 }
00385
00386 #include "engineexplorer.moc"
00387