not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / plasma / tools / engineexplorer / engineexplorer.cpp
blobf5ea0c41dc260587e09aecc68549f9dedc594059
1 /*
2 * Copyright 2007 Aaron Seigo <aseigo@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "engineexplorer.h"
22 #include <QApplication>
23 #include <QStandardItemModel>
24 #include <QVBoxLayout>
25 #include <QHBoxLayout>
26 #include <QSpinBox>
27 #include <QBitArray>
28 #include <QBitmap>
30 #include <KAction>
31 #include <KIconLoader>
32 #include <KIconTheme>
33 #include <KMenu>
34 #include <KStandardAction>
35 #include <KStringHandler>
37 #ifdef FOUND_SOPRANO
38 #include <Soprano/Node>
39 Q_DECLARE_METATYPE(Soprano::Node)
40 #endif // FOUND_SOPRANO
41 Q_DECLARE_METATYPE(Plasma::DataEngine::Data)
43 #include <Plasma/DataEngineManager>
45 #include "serviceviewer.h"
46 #include "titlecombobox.h"
48 EngineExplorer::EngineExplorer(QWidget* parent)
49 : KDialog(parent),
50 m_engine(0),
51 m_sourceCount(0),
52 m_requestingSource(false)
54 #ifdef FOUND_SOPRANO
55 (void) qRegisterMetaType<Soprano::Node>();
56 #endif
57 setWindowTitle(i18n("Plasma Engine Explorer"));
58 QWidget* mainWidget = new QWidget(this);
59 setMainWidget(mainWidget);
60 setupUi(mainWidget);
62 m_engineManager = Plasma::DataEngineManager::self();
63 m_dataModel = new QStandardItemModel(this);
64 KIcon pix("plasma");
65 int size = IconSize(KIconLoader::Dialog);
66 m_title->setPixmap(pix.pixmap(size, size));
67 connect(m_engines, SIGNAL(activated(QString)), this, SLOT(showEngine(QString)));
68 connect(m_sourceRequesterButton, SIGNAL(clicked(bool)), this, SLOT(requestSource()));
69 m_data->setModel(m_dataModel);
70 m_data->setWordWrap(true);
72 m_searchLine->setTreeView(m_data);
73 m_searchLine->setClickMessage(i18n("Search"));
75 listEngines();
76 m_engines->setFocus();
78 setButtons(KDialog::Close | KDialog::User1 | KDialog::User2);
79 setButtonText(KDialog::User1, i18n("Collapse All"));
80 setButtonText(KDialog::User2, i18n("Expand All"));
81 connect(this, SIGNAL(user1Clicked()), m_data, SLOT(collapseAll()));
82 connect(this, SIGNAL(user2Clicked()), m_data, SLOT(expandAll()));
83 enableButton(KDialog::User1, false);
84 enableButton(KDialog::User2, false);
86 addAction(KStandardAction::quit(qApp, SLOT(quit()), this));
88 connect(m_data, SIGNAL(customContextMenuRequested(QPoint)),
89 this, SLOT(showDataContextMenu(QPoint)));
90 m_data->setContextMenuPolicy(Qt::CustomContextMenu);
93 EngineExplorer::~EngineExplorer()
97 void EngineExplorer::setApp(const QString &app)
99 m_app = app;
101 if (m_engines->count() > 0) {
102 listEngines();
106 void EngineExplorer::setEngine(const QString &engine)
108 //find the engine in the combo box
109 int index = m_engines->findText(engine);
110 if (index != -1) {
111 kDebug() << QString("Engine %1 found!").arg(engine);
112 m_engines->setCurrentIndex(index);
113 showEngine(engine);
117 void EngineExplorer::setInterval(const int interval)
119 m_updateInterval->setValue(interval);
122 void EngineExplorer::dataUpdated(const QString& source, const Plasma::DataEngine::Data& data)
124 QList<QStandardItem*> items = m_dataModel->findItems(source, 0);
126 if (items.count() < 1) {
127 return;
130 QStandardItem* parent = items.first();
132 while (parent->hasChildren()) {
133 parent->removeRow(0);
136 showData(parent, data);
139 void EngineExplorer::listEngines()
141 m_engines->clear();
142 QStringList engines = m_engineManager->listAllEngines(m_app);
143 qSort(engines);
144 m_engines->addItems(engines);
145 m_engines->setCurrentIndex(-1);
148 void EngineExplorer::showEngine(const QString& name)
150 m_sourceRequester->setEnabled(false);
151 m_sourceRequesterButton->setEnabled(false);
152 enableButton(KDialog::User1, false);
153 enableButton(KDialog::User2, false);
154 m_dataModel->clear();
155 m_dataModel->setColumnCount(4);
156 QStringList headers;
157 headers << i18n("DataSource") << i18n("Key") << i18n("Value") << i18n("Type");
158 m_dataModel->setHorizontalHeaderLabels(headers);
159 m_engine = 0;
160 m_sourceCount = 0;
162 if (!m_engineName.isEmpty()) {
163 m_engineManager->unloadEngine(m_engineName);
166 m_engineName = name;
167 if (m_engineName.isEmpty()) {
168 updateTitle();
169 return;
172 m_engine = m_engineManager->loadEngine(m_engineName);
173 if (!m_engine) {
174 m_engineName.clear();
175 updateTitle();
176 return;
179 QStringList sources = m_engine->sources();
181 //kDebug() << "showing engine " << m_engine->objectName();
182 //kDebug() << "we have " << sources.count() << " data sources";
183 foreach (const QString& source, sources) {
184 //kDebug() << "adding " << source;
185 addSource(source);
188 m_sourceRequesterButton->setEnabled(true);
189 m_updateInterval->setEnabled(true);
190 m_sourceRequester->setEnabled(true);
191 m_sourceRequester->setFocus();
192 connect(m_engine, SIGNAL(sourceAdded(QString)), this, SLOT(addSource(QString)));
193 connect(m_engine, SIGNAL(sourceRemoved(QString)), this, SLOT(removeSource(QString)));
194 updateTitle();
197 void EngineExplorer::addSource(const QString& source)
199 QStandardItem* parent = new QStandardItem(source);
200 m_dataModel->appendRow(parent);
202 //kDebug() << "getting data for source " << source;
203 Plasma::DataEngine::Data data = m_engine->query(source);
204 showData(parent, data);
206 if (!m_requestingSource || m_sourceRequester->text() != source) {
207 m_engine->connectSource(source, this);
210 ++m_sourceCount;
211 updateTitle();
213 enableButton(KDialog::User1, true);
214 enableButton(KDialog::User2, true);
217 void EngineExplorer::removeSource(const QString& source)
219 QList<QStandardItem*> items = m_dataModel->findItems(source, 0);
221 if (items.count() < 1) {
222 return;
225 foreach (QStandardItem* item, items) {
226 m_dataModel->removeRow(item->row());
229 --m_sourceCount;
230 m_engine->disconnectSource(source, this);
231 updateTitle();
234 void EngineExplorer::requestSource()
236 requestSource(m_sourceRequester->text());
239 void EngineExplorer::requestSource(const QString &source)
241 if (!m_engine || source.isEmpty()) {
242 return;
245 kDebug() << "request source" << source;
246 m_requestingSource = true;
247 m_engine->connectSource(source, this, (uint)m_updateInterval->value());
248 m_requestingSource = false;
251 void EngineExplorer::showDataContextMenu(const QPoint &point)
253 QModelIndex index = m_data->indexAt(point);
254 if (index.isValid()) {
255 if (index.parent().isValid()) {
256 index = index.parent();
259 if (index.column() != 0) {
260 index = m_dataModel->index(index.row(), 0);
263 QString source = index.data().toString();
264 KMenu menu;
265 menu.addTitle(source);
266 QAction *service = menu.addAction(i18n("Get associated service"));
267 QAction *update = menu.addAction(i18n("Update source now"));
268 QAction *remove = menu.addAction(i18n("Remove source"));
270 QAction *activated = menu.exec(m_data->viewport()->mapToGlobal(point));
271 if (activated == service) {
272 ServiceViewer *viewer = new ServiceViewer(m_engine, source);
273 viewer->show();
274 } else if (activated == update) {
275 m_engine->connectSource(source, this);
276 Plasma::DataEngine::Data data = m_engine->query(source);
277 } else if (activated == remove) {
278 removeSource(source);
283 QString EngineExplorer::convertToString(const QVariant &value) const
285 switch (value.type())
287 case QVariant::BitArray: {
288 return i18np("&lt;1 bit&gt;", "&lt;%1 bits&gt;", value.toBitArray().size());
290 case QVariant::Bitmap: {
291 QBitmap bitmap = value.value<QBitmap>();
292 return QString("<%1x%2px - %3bpp>").arg(bitmap.width()).arg(bitmap.height()).arg(bitmap.depth());
294 case QVariant::ByteArray: {
295 // Return the array size if it is not displayable
296 if (value.toString().isEmpty()) {
297 return i18np("&lt;1 byte&gt;", "&lt;%1 bytes&gt;", value.toByteArray().size());
299 else {
300 return value.toString();
303 case QVariant::Image: {
304 QImage image = value.value<QImage>();
305 return QString("<%1x%2px - %3bpp>").arg(image.width()).arg(image.height()).arg(image.depth());
307 case QVariant::Line: {
308 QLine line = value.toLine();
309 return QString("<x1:%1, y1:%2, x2:%3, y2:%4>").arg(line.x1()).arg(line.y1()).arg(line.x2()).arg(line.y2());
311 case QVariant::LineF: {
312 QLineF lineF = value.toLineF();
313 return QString("<x1:%1, y1:%2, x2:%3, y2:%4>").arg(lineF.x1()).arg(lineF.y1()).arg(lineF.x2()).arg(lineF.y2());
315 case QVariant::Locale: {
316 return QString("%1").arg(value.toLocale().name());
318 case QVariant::Map: {
319 return i18np("&lt;1 item&gt;", "&lt;%1 items&gt;", value.toMap().size());
321 case QVariant::Pixmap: {
322 QPixmap pixmap = value.value<QPixmap>();
323 return QString("<%1x%2px - %3bpp>").arg(pixmap.width()).arg(pixmap.height()).arg(pixmap.depth());
325 case QVariant::Point: {
326 QPoint point = value.toPoint();
327 return QString("<x:%1, y:%2>").arg(point.x()).arg(point.y());
329 case QVariant::PointF: {
330 QPointF pointF = value.toPointF();
331 return QString("<x:%1, y:%2>").arg(pointF.x()).arg(pointF.y());
333 case QVariant::Rect: {
334 QRect rect = value.toRect();
335 return QString("<x:%1, y:%2, w:%3, h:%4>").arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height());
337 case QVariant::RectF: {
338 QRectF rectF = value.toRectF();
339 return QString("<x:%1, y:%2, w:%3, h:%4>").arg(rectF.x()).arg(rectF.y()).arg(rectF.width()).arg(rectF.height());
341 case QVariant::RegExp: {
342 return QString("%1").arg(value.toRegExp().pattern());
344 case QVariant::Region: {
345 QRect region = value.value<QRegion>().boundingRect();
346 return QString("<x:%1, y:%2, w:%3, h:%4>").arg(region.x()).arg(region.y()).arg(region.width()).arg(region.height());
348 case QVariant::Size: {
349 QSize size = value.toSize();
350 return QString("<w:%1, h:%2>").arg(size.width()).arg(size.height());
352 case QVariant::SizeF: {
353 QSizeF sizeF = value.toSizeF();
354 return QString("<w:%1, h:%2>").arg(sizeF.width()).arg(sizeF.height());
356 case QVariant::Url: {
357 return QString("%1").arg(value.toUrl().toString());
359 default: {
360 #ifdef FOUND_SOPRANO
361 if (QLatin1String(value.typeName()) == "Soprano::Node") {
362 Soprano::Node node = value.value<Soprano::Node>();
363 if (node.isLiteral()) {
364 return convertToString(node.literal().variant());
365 } else if (node.isResource()) {
366 return node.uri().toString();
367 } else if (node.isBlank()) {
368 return QString("_:%1").arg(node.identifier());
371 #endif
372 Plasma::DataEngine::Data data = value.value<Plasma::DataEngine::Data>();
373 if (!data.isEmpty()) {
374 QStringList result;
375 QHashIterator<QString, QVariant> it(data);
377 while (it.hasNext()) {
378 it.next();
379 result << (it.key() + ": " + it.value().toString());
382 return result.join("\n");
383 } else if (value.canConvert(QVariant::String)) {
384 if (value.toString().isEmpty()) {
385 return i18nc("The user did a query to a dataengine and it returned empty data", "<empty>");
387 else {
388 return value.toString();
392 return i18nc("A the dataengine returned something that the humble view on the engineexplorer can't display, like a picture", "<not displayable>");
397 void EngineExplorer::showData(QStandardItem* parent, Plasma::DataEngine::Data data)
399 int rowCount = 0;
400 Plasma::DataEngine::DataIterator it(data);
401 // parent->insertRows(0, data.count());
402 // parent->setColumnCount(3);
403 while (it.hasNext()) {
404 it.next();
405 parent->setChild(rowCount, 1, new QStandardItem(it.key()));
406 if (it.value().canConvert(QVariant::List)) {
407 foreach(const QVariant &var, it.value().toList()) {
408 QStandardItem *item = new QStandardItem(convertToString(var));
409 item->setToolTip(item->text());
410 parent->setChild(rowCount, 2, item);
411 parent->setChild(rowCount, 3, new QStandardItem(var.typeName()));
412 ++rowCount;
415 else {
416 QStandardItem *item = new QStandardItem(convertToString(it.value()));
417 item->setToolTip(item->text());
418 parent->setChild(rowCount, 2, item);
419 parent->setChild(rowCount, 3, new QStandardItem(it.value().typeName()));
420 ++rowCount;
425 void EngineExplorer::updateTitle()
427 if (!m_engine) {
428 m_title->setPixmap(KIcon("plasma").pixmap(IconSize(KIconLoader::Dialog)));
429 m_title->setText(i18n("Plasma DataEngine Explorer"));
430 return;
433 m_title->setText(ki18ncp("The name of the engine followed by the number of data sources",
434 "%1 Engine - 1 data source", "%1 Engine - %2 data sources")
435 .subs(KStringHandler::capwords(m_engine->name()))
436 .subs(m_sourceCount).toString());
437 if (m_engine->icon().isEmpty()) {
438 m_title->setPixmap(KIcon("plasma").pixmap(IconSize(KIconLoader::Dialog)));
439 } else {
440 //m_title->setPixmap(KIcon("alarmclock").pixmap(IconSize(KIconLoader::Dialog)));
441 m_title->setPixmap(KIcon(m_engine->icon()).pixmap(IconSize(KIconLoader::Dialog)));
445 #include "engineexplorer.moc"