~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to plasma/generic/tools/engineexplorer/engineexplorer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   Copyright 2007 Aaron Seigo <aseigo@kde.org>
 
3
 *
 
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.
 
8
 *
 
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
 
13
 *
 
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.
 
18
 */
 
19
 
 
20
#include "engineexplorer.h"
 
21
 
 
22
#include <QApplication>
 
23
#include <QStandardItemModel>
 
24
#include <QBitmap>
 
25
#include <QBitArray>
 
26
 
 
27
#include <KIconLoader>
 
28
#include <KIconTheme>
 
29
#include <KMenu>
 
30
#include <KStandardAction>
 
31
#include <KStringHandler>
 
32
#include <KAction>
 
33
 
 
34
#ifdef FOUND_SOPRANO
 
35
#include <Soprano/Node>
 
36
Q_DECLARE_METATYPE(Soprano::Node)
 
37
#endif // FOUND_SOPRANO
 
38
Q_DECLARE_METATYPE(Plasma::DataEngine::Data)
 
39
 
 
40
#include <Plasma/DataEngineManager>
 
41
 
 
42
#include "serviceviewer.h"
 
43
#include "titlecombobox.h"
 
44
 
 
45
EngineExplorer::EngineExplorer(QWidget* parent)
 
46
    : KDialog(parent),
 
47
      m_engine(0),
 
48
      m_sourceCount(0),
 
49
      m_requestingSource(false)
 
50
{
 
51
#ifdef FOUND_SOPRANO
 
52
    (void) qRegisterMetaType<Soprano::Node>();
 
53
#endif
 
54
    setWindowTitle(i18n("Plasma Engine Explorer"));
 
55
    QWidget* mainWidget = new QWidget(this);
 
56
    setMainWidget(mainWidget);
 
57
    setupUi(mainWidget);
 
58
 
 
59
    m_engineManager = Plasma::DataEngineManager::self();
 
60
    m_dataModel = new QStandardItemModel(this);
 
61
    KIcon pix("plasma");
 
62
    int size = IconSize(KIconLoader::Dialog);
 
63
    m_title->setPixmap(pix.pixmap(size, size));
 
64
    connect(m_engines, SIGNAL(activated(QString)), this, SLOT(showEngine(QString)));
 
65
    connect(m_sourceRequesterButton, SIGNAL(clicked(bool)), this, SLOT(requestSource()));
 
66
    m_data->setModel(m_dataModel);
 
67
    m_data->setWordWrap(true);
 
68
 
 
69
    m_searchLine->setTreeView(m_data);
 
70
    m_searchLine->setClickMessage(i18n("Search"));
 
71
 
 
72
    listEngines();
 
73
    m_engines->setFocus();
 
74
 
 
75
    setButtons(KDialog::Close | KDialog::User1 | KDialog::User2);
 
76
    setButtonText(KDialog::User1, i18n("Collapse All"));
 
77
    setButtonText(KDialog::User2, i18n("Expand All"));
 
78
    connect(this, SIGNAL(user1Clicked()), m_data, SLOT(collapseAll()));
 
79
    connect(this, SIGNAL(user2Clicked()), m_data, SLOT(expandAll()));
 
80
    enableButton(KDialog::User1, false);
 
81
    enableButton(KDialog::User2, false);
 
82
 
 
83
    addAction(KStandardAction::quit(qApp, SLOT(quit()), this));
 
84
 
 
85
    connect(m_data, SIGNAL(customContextMenuRequested(QPoint)),
 
86
            this, SLOT(showDataContextMenu(QPoint)));
 
87
    m_data->setContextMenuPolicy(Qt::CustomContextMenu);
 
88
    connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanUp()));
 
89
}
 
90
 
 
91
EngineExplorer::~EngineExplorer()
 
92
{
 
93
}
 
94
 
 
95
void EngineExplorer::cleanUp()
 
96
{
 
97
    if (!m_engineName.isEmpty()) {
 
98
        m_engineManager->unloadEngine(m_engineName);
 
99
    }
 
100
}
 
101
 
 
102
void EngineExplorer::setApp(const QString &app)
 
103
{
 
104
    m_app = app;
 
105
 
 
106
    if (m_engines->count() > 0) {
 
107
        listEngines();
 
108
    }
 
109
}
 
110
 
 
111
void EngineExplorer::setEngine(const QString &engine)
 
112
{
 
113
    //find the engine in the combo box
 
114
    int index = m_engines->findText(engine);
 
115
    if (index != -1) {
 
116
        kDebug() << QString("Engine %1 found!").arg(engine);
 
117
        m_engines->setCurrentIndex(index);
 
118
        showEngine(engine);
 
119
    }
 
120
}
 
121
 
 
122
void EngineExplorer::setInterval(const int interval)
 
123
{
 
124
    m_updateInterval->setValue(interval);
 
125
}
 
126
 
 
127
void EngineExplorer::dataUpdated(const QString& source, const Plasma::DataEngine::Data& data)
 
128
{
 
129
    QList<QStandardItem*> items = m_dataModel->findItems(source, 0);
 
130
 
 
131
    if (items.isEmpty()) {
 
132
        return;
 
133
    }
 
134
 
 
135
    QStandardItem* parent = items.first();
 
136
 
 
137
    int rows = showData(parent, data);
 
138
 
 
139
    while (parent->rowCount() > rows) {
 
140
        parent->removeRow(rows);
 
141
    }
 
142
}
 
143
 
 
144
void EngineExplorer::listEngines()
 
145
{
 
146
    m_engines->clear();
 
147
    QStringList engines = m_engineManager->listAllEngines(m_app);
 
148
    qSort(engines);
 
149
    m_engines->addItems(engines);
 
150
    m_engines->setCurrentIndex(-1);
 
151
}
 
152
 
 
153
void EngineExplorer::showEngine(const QString& name)
 
154
{
 
155
    m_sourceRequester->setEnabled(false);
 
156
    m_sourceRequesterButton->setEnabled(false);
 
157
    enableButton(KDialog::User1, false);
 
158
    enableButton(KDialog::User2, false);
 
159
    m_dataModel->clear();
 
160
    m_dataModel->setColumnCount(4);
 
161
    QStringList headers;
 
162
    headers << i18n("DataSource") << i18n("Key") << i18n("Value") << i18n("Type");
 
163
    m_dataModel->setHorizontalHeaderLabels(headers);
 
164
    m_engine = 0;
 
165
    m_sourceCount = 0;
 
166
 
 
167
    if (!m_engineName.isEmpty()) {
 
168
        m_engineManager->unloadEngine(m_engineName);
 
169
    }
 
170
 
 
171
    m_engineName = name;
 
172
    if (m_engineName.isEmpty()) {
 
173
        updateTitle();
 
174
        return;
 
175
    }
 
176
 
 
177
    m_engine = m_engineManager->loadEngine(m_engineName);
 
178
    if (!m_engine) {
 
179
        m_engineName.clear();
 
180
        updateTitle();
 
181
        return;
 
182
    }
 
183
 
 
184
    //kDebug() << "showing engine " << m_engine->objectName();
 
185
    //kDebug() << "we have " << sources.count() << " data sources";
 
186
    connect(m_engine, SIGNAL(sourceAdded(QString)), this, SLOT(addSource(QString)));
 
187
    connect(m_engine, SIGNAL(sourceRemoved(QString)), this, SLOT(removeSource(QString)));
 
188
    foreach (const QString& source, m_engine->sources()) {
 
189
        //kDebug() << "adding " << source;
 
190
        addSource(source);
 
191
    }
 
192
 
 
193
    m_sourceRequesterButton->setEnabled(true);
 
194
    m_updateInterval->setEnabled(true);
 
195
    m_sourceRequester->setEnabled(true);
 
196
    m_sourceRequester->setFocus();
 
197
    updateTitle();
 
198
}
 
199
 
 
200
void EngineExplorer::addSource(const QString& source)
 
201
{
 
202
    kDebug() << "adding" << source;
 
203
    QList<QStandardItem*> items = m_dataModel->findItems(source, 0);
 
204
    if (!items.isEmpty()) {
 
205
        kDebug() << "er... already there?";
 
206
        return;
 
207
    }
 
208
 
 
209
    QStandardItem* parent = new QStandardItem(source);
 
210
    m_dataModel->appendRow(parent);
 
211
 
 
212
    kDebug() << "getting data for source " << source;
 
213
 
 
214
    if (!m_requestingSource || m_sourceRequester->text() != source) {
 
215
        kDebug() << "connecting up now";
 
216
        m_engine->connectSource(source, this);
 
217
    }
 
218
 
 
219
    ++m_sourceCount;
 
220
    updateTitle();
 
221
 
 
222
    enableButton(KDialog::User1, true);
 
223
    enableButton(KDialog::User2, true);
 
224
}
 
225
 
 
226
void EngineExplorer::removeSource(const QString& source)
 
227
{
 
228
    QList<QStandardItem*> items = m_dataModel->findItems(source, 0);
 
229
 
 
230
    if (items.count() < 1) {
 
231
        return;
 
232
    }
 
233
 
 
234
    foreach (QStandardItem* item, items) {
 
235
        m_dataModel->removeRow(item->row());
 
236
    }
 
237
 
 
238
    --m_sourceCount;
 
239
    m_engine->disconnectSource(source, this);
 
240
    updateTitle();
 
241
}
 
242
 
 
243
void EngineExplorer::requestSource()
 
244
{
 
245
    requestSource(m_sourceRequester->text());
 
246
}
 
247
 
 
248
void EngineExplorer::requestSource(const QString &source)
 
249
{
 
250
    if (!m_engine || source.isEmpty()) {
 
251
        return;
 
252
    }
 
253
 
 
254
    kDebug() << "request source" << source;
 
255
    m_requestingSource = true;
 
256
    m_engine->connectSource(source, this, (uint)m_updateInterval->value());
 
257
    m_requestingSource = false;
 
258
}
 
259
 
 
260
void EngineExplorer::showDataContextMenu(const QPoint &point)
 
261
{
 
262
    QModelIndex index = m_data->indexAt(point);
 
263
    if (index.isValid()) {
 
264
        if (index.parent().isValid()) {
 
265
            index = index.parent();
 
266
        }
 
267
 
 
268
        if (index.column() != 0) {
 
269
            index = m_dataModel->index(index.row(), 0);
 
270
        }
 
271
 
 
272
        const QString source = index.data().toString();
 
273
        KMenu menu;
 
274
        menu.addTitle(source);
 
275
        QAction *service = menu.addAction(i18n("Get associated service"));
 
276
        QAction *update = menu.addAction(i18n("Update source now"));
 
277
        QAction *remove = menu.addAction(i18n("Remove source"));
 
278
 
 
279
        QAction *activated = menu.exec(m_data->viewport()->mapToGlobal(point));
 
280
        if (activated == service) {
 
281
            ServiceViewer *viewer = new ServiceViewer(m_engine, source);
 
282
            viewer->show();
 
283
        } else if (activated == update) {
 
284
            m_engine->connectSource(source, this);
 
285
            Plasma::DataEngine::Data data = m_engine->query(source);
 
286
        } else if (activated == remove) {
 
287
            removeSource(source);
 
288
        }
 
289
    }
 
290
}
 
291
 
 
292
QString EngineExplorer::convertToString(const QVariant &value)
 
293
{
 
294
    switch (value.type())
 
295
    {
 
296
        case QVariant::BitArray: {
 
297
            return i18np("&lt;1 bit&gt;", "&lt;%1 bits&gt;", value.toBitArray().size());
 
298
        }
 
299
        case QVariant::Bitmap: {
 
300
            QBitmap bitmap = value.value<QBitmap>();
 
301
            return QString("<%1x%2px - %3bpp>").arg(bitmap.width()).arg(bitmap.height()).arg(bitmap.depth());
 
302
        }
 
303
        case QVariant::ByteArray: {
 
304
            // Return the array size if it is not displayable
 
305
            if (value.toString().isEmpty()) {
 
306
                return i18np("&lt;1 byte&gt;", "&lt;%1 bytes&gt;", value.toByteArray().size());
 
307
            }
 
308
            else {
 
309
                return value.toString();
 
310
            }
 
311
        }
 
312
        case QVariant::Image: {
 
313
            QImage image = value.value<QImage>();
 
314
            return QString("<%1x%2px - %3bpp>").arg(image.width()).arg(image.height()).arg(image.depth());
 
315
        }
 
316
        case QVariant::Line: {
 
317
           QLine line = value.toLine();
 
318
           return QString("<x1:%1, y1:%2, x2:%3, y2:%4>").arg(line.x1()).arg(line.y1()).arg(line.x2()).arg(line.y2());
 
319
        }
 
320
        case QVariant::LineF: {
 
321
           QLineF lineF = value.toLineF();
 
322
           return QString("<x1:%1, y1:%2, x2:%3, y2:%4>").arg(lineF.x1()).arg(lineF.y1()).arg(lineF.x2()).arg(lineF.y2());
 
323
        }
 
324
        case QVariant::Locale: {
 
325
            return QString("%1").arg(value.toLocale().name());
 
326
        }
 
327
        case QVariant::Map: {
 
328
            QVariantMap map = value.toMap();
 
329
            QString str = i18np("&lt;1 item&gt;", "&lt;%1 items&gt;", map.size());
 
330
 
 
331
            QMapIterator<QString, QVariant> it(map);
 
332
            while (it.hasNext()) {
 
333
                it.next();
 
334
                str += "\n" + it.key() + ": " + convertToString(it.value());
 
335
            }
 
336
 
 
337
            return str;
 
338
        }
 
339
        case QVariant::Pixmap: {
 
340
            QPixmap pixmap = value.value<QPixmap>();
 
341
            return QString("<%1x%2px - %3bpp>").arg(pixmap.width()).arg(pixmap.height()).arg(pixmap.depth());
 
342
        }
 
343
        case QVariant::Point: {
 
344
           QPoint point = value.toPoint();
 
345
           return QString("<x:%1, y:%2>").arg(point.x()).arg(point.y());
 
346
        }
 
347
        case QVariant::PointF: {
 
348
           QPointF pointF = value.toPointF();
 
349
           return QString("<x:%1, y:%2>").arg(pointF.x()).arg(pointF.y());
 
350
        }
 
351
        case QVariant::Rect: {
 
352
            QRect rect = value.toRect();
 
353
            return QString("<x:%1, y:%2, w:%3, h:%4>").arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height());
 
354
        }
 
355
        case QVariant::RectF: {
 
356
            QRectF rectF = value.toRectF();
 
357
            return QString("<x:%1, y:%2, w:%3, h:%4>").arg(rectF.x()).arg(rectF.y()).arg(rectF.width()).arg(rectF.height());
 
358
        }
 
359
        case QVariant::RegExp: {
 
360
            return QString("%1").arg(value.toRegExp().pattern());
 
361
        }
 
362
        case QVariant::Region: {
 
363
            QRect region = value.value<QRegion>().boundingRect();
 
364
            return QString("<x:%1, y:%2, w:%3, h:%4>").arg(region.x()).arg(region.y()).arg(region.width()).arg(region.height());
 
365
        }
 
366
        case QVariant::Size: {
 
367
            QSize size = value.toSize();
 
368
            return QString("<w:%1, h:%2>").arg(size.width()).arg(size.height());
 
369
        }
 
370
        case QVariant::SizeF: {
 
371
            QSizeF sizeF = value.toSizeF();
 
372
            return QString("<w:%1, h:%2>").arg(sizeF.width()).arg(sizeF.height());
 
373
        }
 
374
        case QVariant::Url: {
 
375
            return QString("%1").arg(value.toUrl().toString());
 
376
        }
 
377
        default: {
 
378
#ifdef FOUND_SOPRANO
 
379
            if (QLatin1String(value.typeName()) == "Soprano::Node") {
 
380
                Soprano::Node node = value.value<Soprano::Node>();
 
381
                if (node.isLiteral()) {
 
382
                    return convertToString(node.literal().variant());
 
383
                } else if (node.isResource()) {
 
384
                    return node.uri().toString();
 
385
                } else if (node.isBlank()) {
 
386
                    return QString("_:%1").arg(node.identifier());
 
387
                }
 
388
            }
 
389
#endif
 
390
            Plasma::DataEngine::Data data = value.value<Plasma::DataEngine::Data>();
 
391
            if (!data.isEmpty()) {
 
392
                QStringList result;
 
393
                QHashIterator<QString, QVariant> it(data);
 
394
 
 
395
                while (it.hasNext()) {
 
396
                    it.next();
 
397
                    result << (it.key() + ": " + it.value().toString());
 
398
                }
 
399
 
 
400
                return result.join("\n");
 
401
            } else if (value.canConvert(QVariant::String)) {
 
402
                if (value.toString().isEmpty()) {
 
403
                    return i18nc("The user did a query to a dataengine and it returned empty data", "<empty>");
 
404
                }
 
405
                else {
 
406
                    return value.toString();
 
407
                }
 
408
            }
 
409
 
 
410
            return i18nc("A the dataengine returned something that the humble view on the engineexplorer can't display, like a picture", "<not displayable>");
 
411
        }
 
412
    }
 
413
}
 
414
 
 
415
int EngineExplorer::showData(QStandardItem* parent, Plasma::DataEngine::Data data)
 
416
{
 
417
    int rowCount = 0;
 
418
    Plasma::DataEngine::DataIterator it(data);
 
419
//    parent->insertRows(0, data.count());
 
420
//    parent->setColumnCount(3);
 
421
    while (it.hasNext()) {
 
422
        it.next();
 
423
        parent->setChild(rowCount, 1, new QStandardItem(it.key()));
 
424
        if (it.value().canConvert(QVariant::List)) {
 
425
            foreach(const QVariant &var, it.value().toList()) {
 
426
                QStandardItem *item = new QStandardItem(convertToString(var));
 
427
                item->setToolTip(item->text());
 
428
                parent->setChild(rowCount, 2, item);
 
429
                parent->setChild(rowCount, 3, new QStandardItem(var.typeName()));
 
430
                ++rowCount;
 
431
            }
 
432
        } else {
 
433
            QStandardItem *item;
 
434
            if (it.value().canConvert<QIcon>()) {
 
435
                item = new QStandardItem(it.value().value<QIcon>(), "");
 
436
            } else {
 
437
                item = new QStandardItem(convertToString(it.value()));
 
438
            }
 
439
 
 
440
            item->setToolTip(item->text());
 
441
            parent->setChild(rowCount, 2, item);
 
442
            parent->setChild(rowCount, 3, new QStandardItem(it.value().typeName()));
 
443
            ++rowCount;
 
444
        }
 
445
    }
 
446
 
 
447
    return rowCount;
 
448
}
 
449
 
 
450
void EngineExplorer::updateTitle()
 
451
{
 
452
    if (!m_engine) {
 
453
        m_title->setPixmap(KIcon("plasma").pixmap(IconSize(KIconLoader::Dialog)));
 
454
        m_title->setText(i18n("Plasma DataEngine Explorer"));
 
455
        return;
 
456
    }
 
457
 
 
458
    m_title->setText(ki18ncp("The name of the engine followed by the number of data sources",
 
459
                             "%1 Engine - 1 data source", "%1 Engine - %2 data sources")
 
460
                              .subs(KStringHandler::capwords(m_engine->name()))
 
461
                              .subs(m_sourceCount).toString());
 
462
 
 
463
    if (m_engine->icon().isEmpty()) {
 
464
        m_title->setPixmap(KIcon("plasma").pixmap(IconSize(KIconLoader::Dialog)));
 
465
    } else {
 
466
        //m_title->setPixmap(KIcon("alarmclock").pixmap(IconSize(KIconLoader::Dialog)));
 
467
        m_title->setPixmap(KIcon(m_engine->icon()).pixmap(IconSize(KIconLoader::Dialog)));
 
468
    }
 
469
}
 
470
 
 
471
#include "engineexplorer.moc"
 
472