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

« back to all changes in this revision

Viewing changes to ksysguard/gui/SensorBrowser.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
    KSysGuard, the KDE System Guard
 
3
 
 
4
    Copyright (c) 1999, 2000 Chris Schlaeger <cs@kde.org>
 
5
 
 
6
    This program is free software; you can redistribute it and/or
 
7
    modify it under the terms of the GNU General Public
 
8
    License version 2 or at your option version 3 as published by
 
9
    the Free Software Foundation.
 
10
 
 
11
    This program is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with this program; if not, write to the Free Software
 
18
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
19
 
 
20
*/
 
21
 
 
22
#include <QtGui/QDrag>
 
23
#include <QtGui/QLabel>
 
24
#include <QtGui/QMouseEvent>
 
25
#include <QtGui/QPainter>
 
26
#include <QtGui/QPixmap>
 
27
#include <QtGui/QVBoxLayout>
 
28
#include <QMimeData>
 
29
 
 
30
#include <kdebug.h>
 
31
#include <kicon.h>
 
32
#include <klocale.h>
 
33
#include <kmessagebox.h>
 
34
#include <ksgrd/SensorManager.h>
 
35
#include <kfilterproxysearchline.h>
 
36
 
 
37
#include "SensorBrowser.h"
 
38
//#define SENSOR_MODEL_DO_TEST
 
39
//uncomment the above to test the model
 
40
#ifdef SENSOR_MODEL_DO_TEST
 
41
#include "modeltest.h"
 
42
#endif
 
43
 
 
44
SensorBrowserModel::SensorBrowserModel()
 
45
{
 
46
#ifdef SENSOR_MODEL_DO_TEST
 
47
    new ModelTest(this);
 
48
#endif
 
49
    mIdCount=1;
 
50
}
 
51
SensorBrowserModel::~SensorBrowserModel()
 
52
{
 
53
    qDeleteAll( mHostInfoMap );
 
54
    mHostInfoMap.clear();
 
55
    qDeleteAll( mSensorInfoMap );
 
56
    mSensorInfoMap.clear();
 
57
}
 
58
 
 
59
int SensorBrowserModel::columnCount( const QModelIndex &) const { //virtual
 
60
    return 1;
 
61
}
 
62
 
 
63
QVariant SensorBrowserModel::data( const QModelIndex & index, int role) const { //virtual
 
64
    if(!index.isValid()) return QVariant();
 
65
    switch(role) {
 
66
        case Qt::DisplayRole: {
 
67
            if(index.column()==0) {
 
68
                uint id = index.internalId();
 
69
                if(mSensorInfoMap.contains(id)) {
 
70
                    Q_ASSERT(mSensorInfoMap.value(id));
 
71
                    SensorInfo *sensorInfo = mSensorInfoMap.value(id);
 
72
                    return QString(sensorInfo->description() + " (" +sensorInfo->type() +')' );
 
73
                }
 
74
                if(mTreeNodeNames.contains(id)) return mTreeNodeNames.value(id);
 
75
                if(mHostInfoMap.contains(id)) {
 
76
                    Q_ASSERT(mHostInfoMap.value(id));
 
77
                    return mHostInfoMap.value(id)->hostName();
 
78
                }
 
79
            }
 
80
            return QString();
 
81
        }
 
82
        case Qt::DecorationRole: {
 
83
            if(index.column() == 0) {
 
84
                HostInfo *host = getHostInfo(index.internalId());
 
85
                KSGRD::SensorAgent *agent;
 
86
                if(host != NULL && (agent = host->sensorAgent())) {
 
87
                    if(agent->daemonOnLine())
 
88
                        return KIcon("computer");
 
89
                    else
 
90
                        return KIcon("dialog-warning");
 
91
                } else
 
92
                    return QIcon();
 
93
            } else
 
94
                return QIcon();
 
95
            break;
 
96
        }
 
97
        case Qt::ToolTipRole: {
 
98
            if(index.column() == 0) {
 
99
                HostInfo *host = getHostInfo(index.internalId());
 
100
                KSGRD::SensorAgent *agent;
 
101
                if(host != NULL && (agent = host->sensorAgent())) {
 
102
                    if(agent->daemonOnLine())
 
103
                        return agent->hostName();
 
104
                    else
 
105
                        return agent->reasonForOffline();
 
106
                }
 
107
            }
 
108
            break;
 
109
        }
 
110
 
 
111
    } //switch
 
112
    return QVariant();
 
113
}
 
114
 
 
115
QVariant SensorBrowserModel::headerData ( int section, Qt::Orientation , int role) const { //virtual
 
116
    if(role != Qt::DisplayRole) return QVariant();
 
117
    if(section==0) return i18n("Sensor Browser");
 
118
    return QVariant();
 
119
}
 
120
 
 
121
void  SensorBrowserModel::retranslate() {
 
122
    emit headerDataChanged(Qt::Horizontal, 0,0);
 
123
}
 
124
 
 
125
QModelIndex SensorBrowserModel::index ( int row, int column, const QModelIndex & parent) const { //virtual
 
126
    if(column != 0) return QModelIndex();
 
127
    QList<int> ids;
 
128
    if(!parent.isValid()) {
 
129
        ids = mHostInfoMap.keys();
 
130
    }
 
131
    else {
 
132
        ids = mTreeMap.value(parent.internalId());
 
133
    }
 
134
    if( row >= ids.size() || row< 0) {
 
135
        return QModelIndex();
 
136
    }
 
137
    QModelIndex index = createIndex(row, column, ids[row]);
 
138
    Q_ASSERT(index.isValid());
 
139
    return index;
 
140
}
 
141
 
 
142
QStringList SensorBrowserModel::listHosts() const
 
143
{
 
144
    QStringList hostList;
 
145
 
 
146
    QMapIterator<int, HostInfo*> it( mHostInfoMap );
 
147
    while ( it.hasNext() ) {
 
148
        it.next();
 
149
        Q_ASSERT(it.value());
 
150
        hostList.append( it.value()->hostName() );
 
151
    }
 
152
 
 
153
    return hostList;
 
154
}
 
155
 
 
156
QStringList SensorBrowserModel::listSensors( const QString &hostName ) const
 
157
{
 
158
    QMapIterator<int, HostInfo*> it( mHostInfoMap );
 
159
    while ( it.hasNext() ) {
 
160
        it.next();
 
161
        Q_ASSERT(it.value());
 
162
        if ( it.value()->hostName() == hostName ) {
 
163
            Q_ASSERT(mSensorInfoMap.contains(it.key()));
 
164
            return listSensors( it.key() );
 
165
        }
 
166
    }
 
167
    return QStringList();
 
168
}
 
169
 
 
170
QStringList SensorBrowserModel::listSensors( int parentId) const
 
171
{
 
172
    SensorInfo *sensor=mSensorInfoMap.value(parentId);
 
173
    if(sensor) return QStringList(sensor->name());
 
174
 
 
175
    QStringList childSensors;
 
176
    QList<int> children = mTreeMap.value(parentId);
 
177
    for(int i=0; i < children.size(); i++) {
 
178
        childSensors+= listSensors(children[i]);
 
179
    }
 
180
    return childSensors;
 
181
}
 
182
SensorInfo *SensorBrowserModel::getSensorInfo(QModelIndex index) const
 
183
{
 
184
    if(!index.isValid()) return NULL;
 
185
    return mSensorInfoMap.value(index.internalId());
 
186
}
 
187
int SensorBrowserModel::makeSensor(HostInfo *hostInfo, int parentId, const QString &sensorName, const QString &name, const QString &sensorType) {
 
188
    //sensorName is the full version.  e.g.  mem/free
 
189
    //name is the short version. e.g. free
 
190
    //sensortype is e.g. Integer
 
191
    QList<int> children = mTreeMap.value(parentId);
 
192
    for(int i=0; i<children.size(); i++)
 
193
        if(mSensorInfoMap.contains(children[i])) {
 
194
            Q_ASSERT(mSensorInfoMap.value(children[i]));
 
195
            if(mSensorInfoMap.value(children[i])->name() == sensorName)
 
196
                return children[i];
 
197
        }
 
198
 
 
199
    QModelIndex parentModelIndex;
 
200
    if(hostInfo->id() == parentId) {
 
201
        parentModelIndex = createIndex(mHostInfoMap.keys().indexOf(parentId), 0 , parentId);
 
202
    } else {
 
203
        int parentsParentId = mParentsTreeMap.value(parentId);
 
204
        parentModelIndex = createIndex(mTreeMap.value(parentsParentId).indexOf(parentId), 0, parentId);
 
205
    }
 
206
    Q_ASSERT(parentModelIndex.isValid());
 
207
    QList<int> &parentTreemap = mTreeMap[parentId];
 
208
    SensorInfo *sensorInfo = new SensorInfo(hostInfo, sensorName, name, sensorType);
 
209
    beginInsertRows( parentModelIndex , parentTreemap.size(), parentTreemap.size() );
 
210
    parentTreemap << mIdCount;
 
211
    mParentsTreeMap.insert( mIdCount, parentId );
 
212
    mSensorInfoMap.insert(mIdCount, sensorInfo);
 
213
    mHostSensorsMap[hostInfo->id()].insert(sensorName, true);
 
214
    mIdCount++;
 
215
    endInsertRows();
 
216
    return mIdCount-1;  //NOTE mIdCount is next available number. Se we use it, then increment it, but return the number of the one that we use
 
217
}
 
218
 
 
219
void SensorBrowserModel::removeSensor(HostInfo *hostInfo, int parentId, const QString &sensorName) {
 
220
    //sensorName is the full version.  e.g.  mem/free
 
221
    QList<int> children = mTreeMap.value(parentId);
 
222
    int idCount = -1;
 
223
    int index;
 
224
    for(index=0; index<children.size(); index++)
 
225
        if(mSensorInfoMap.contains(children[index])) {
 
226
            Q_ASSERT(mSensorInfoMap.value(children[index]));
 
227
            if(mSensorInfoMap.value(children[index])->name() == sensorName) {
 
228
                idCount = children[index];
 
229
                break;
 
230
            }
 
231
        }
 
232
    if(idCount == -1) {
 
233
        kDebug(1215) << "removeSensor called for sensor that doesn't exist in the tree: " << sensorName ;
 
234
        return;
 
235
    }
 
236
    QModelIndex parentModelIndex;
 
237
    int parentsParentId = -1;
 
238
    if(hostInfo->id() == parentId) {
 
239
        parentModelIndex = createIndex(mHostInfoMap.keys().indexOf(parentId), 0 , parentId);
 
240
    } else {
 
241
        parentsParentId = mParentsTreeMap.value(parentId);
 
242
        parentModelIndex = createIndex(mTreeMap.value(parentsParentId).indexOf(parentId), 0, parentId);
 
243
    }
 
244
    Q_ASSERT(parentModelIndex.isValid());
 
245
    QList<int> &parentTreemap = mTreeMap[parentId];
 
246
    beginRemoveRows( parentModelIndex, index, index );
 
247
    parentTreemap.removeAll(idCount);
 
248
    mParentsTreeMap.remove(idCount);
 
249
    SensorInfo *sensorInfo = mSensorInfoMap.take(idCount);
 
250
    delete sensorInfo;
 
251
    mHostSensorsMap[hostInfo->id()].remove(sensorName);
 
252
    endRemoveRows();
 
253
 
 
254
    if(parentsParentId != -1)
 
255
        removeEmptyParentTreeBranches(hostInfo->id(), parentId, parentsParentId);
 
256
}
 
257
void SensorBrowserModel::removeEmptyParentTreeBranches(int hostId, int id, int parentId) {
 
258
    if(hostId == id)
 
259
        return;  //We don't want to remove hosts
 
260
 
 
261
    if(!mTreeMap.value(id).isEmpty()) return; // We should have no children
 
262
 
 
263
    QModelIndex parentModelIndex;
 
264
    int parentsParentId = -1;
 
265
    if(hostId == parentId) {
 
266
        parentModelIndex = createIndex(mHostInfoMap.keys().indexOf(parentId), 0 , parentId);
 
267
    } else {
 
268
        parentsParentId = mParentsTreeMap.value(parentId);
 
269
        parentModelIndex = createIndex(mTreeMap.value(parentsParentId).indexOf(parentId), 0, parentId);
 
270
    }
 
271
 
 
272
    int index = mTreeMap.value(parentId).indexOf(id);
 
273
    int idCount = mTreeMap.value(parentId).at(index);
 
274
 
 
275
    QList<int> &parentTreemap = mTreeMap[parentId];
 
276
    beginRemoveRows( parentModelIndex, index, index );
 
277
    parentTreemap.removeAll(idCount);
 
278
    mParentsTreeMap.remove(idCount);
 
279
    mTreeMap.remove(idCount);
 
280
    mTreeNodeNames.remove(idCount);
 
281
    endRemoveRows();
 
282
 
 
283
    if(parentsParentId != -1)
 
284
        removeEmptyParentTreeBranches(hostId, parentId, parentsParentId);
 
285
}
 
286
int SensorBrowserModel::makeTreeBranch(int parentId, const QString &name) {
 
287
    QList<int> children = mTreeMap.value(parentId);
 
288
    for(int i=0; i<children.size(); i++)
 
289
        if(mTreeNodeNames.value(children[i]) == name) return children[i];
 
290
 
 
291
    QModelIndex parentModelIndex;
 
292
    if(mHostInfoMap.contains(parentId)) {
 
293
        parentModelIndex = createIndex(mHostInfoMap.keys().indexOf(parentId), 0 , parentId);
 
294
    } else {
 
295
        int parentsParentId = mParentsTreeMap.value(parentId);
 
296
        parentModelIndex = createIndex(mTreeMap.value(parentsParentId).indexOf(parentId), 0, parentId);
 
297
    }
 
298
    Q_ASSERT(parentModelIndex.isValid());
 
299
    QList<int> &parentTreemap = mTreeMap[parentId];
 
300
    beginInsertRows( parentModelIndex , parentTreemap.size(), parentTreemap.size() );
 
301
    parentTreemap << mIdCount;
 
302
    mParentsTreeMap.insert( mIdCount, parentId );
 
303
    mTreeMap[mIdCount];  //create with empty qlist
 
304
    mTreeNodeNames.insert(mIdCount, name);
 
305
    mIdCount++;
 
306
    endInsertRows();
 
307
 
 
308
    return mIdCount-1;
 
309
}
 
310
 
 
311
void SensorBrowserModel::answerReceived( int hostId,  const QList<QByteArray>&answer )
 
312
{
 
313
    /* An answer has the following example format:
 
314
 
 
315
       cpu/system/idle integer
 
316
       cpu/system/sys  integer
 
317
       cpu/system/nice integer
 
318
       cpu/system/user integer
 
319
       ps       table
 
320
       */
 
321
    HostInfo *hostInfo = getHostInfo(hostId);
 
322
    if(!hostInfo) {
 
323
        kDebug(1215) << "Invalid hostId " << hostId ;
 
324
        return;
 
325
    }
 
326
    /* We keep a copy of the previous sensor names so that we can detect what sensors have been removed */
 
327
    QHash<QString,bool> oldSensorNames = mHostSensorsMap.value(hostId);
 
328
    for ( int i = 0; i < answer.count(); ++i ) {
 
329
        if ( answer[ i ].isEmpty() )
 
330
            continue;
 
331
 
 
332
        QList<QByteArray> words = answer[ i ].split('\t');
 
333
        if(words.size() != 2) {
 
334
            kDebug(1215) << "Invalid data " << answer[i];
 
335
            continue;  /* Something wrong with this line of data */
 
336
        }
 
337
        QString sensorName = QString::fromUtf8(words[ 0 ]);
 
338
        QString sensorType = QString::fromUtf8(words[ 1 ]);
 
339
        oldSensorNames.remove(sensorName);  /* This sensor has not been removed */
 
340
        if ( hasSensor(hostId, sensorName)) {
 
341
            continue;
 
342
        }
 
343
        if(sensorName.isEmpty()) continue;
 
344
 
 
345
        if(sensorType == "string") continue;
 
346
 
 
347
        /* The sensor browser can display sensors in a hierarchical order.
 
348
         * Sensors can be grouped into nodes by seperating the hierarchical
 
349
         * nodes through slashes in the sensor name. E. g. cpu/system/user is
 
350
         * the sensor user in the cpu node. There is no limit for the
 
351
         * depth of nodes. */
 
352
        int currentNodeId = hostId;  //Start from the host branch and work our way down the tree
 
353
        QStringList absolutePath = sensorName.split( '/' );
 
354
        for ( int j = 0; j < absolutePath.count()-1; ++j ) {
 
355
            // Localize the sensor name part by part.
 
356
            QString name = KSGRD::SensorMgr->translateSensorPath( absolutePath[ j ] );
 
357
            currentNodeId = makeTreeBranch(currentNodeId, name);
 
358
        }
 
359
        QString name = KSGRD::SensorMgr->translateSensorPath( absolutePath[ absolutePath.size()-1] );
 
360
        makeSensor(hostInfo, currentNodeId, sensorName, name, sensorType);
 
361
    }
 
362
    /* Now we have to remove sensors that were not found */
 
363
    QHashIterator<QString, bool> it( oldSensorNames );
 
364
    while ( it.hasNext() ) {
 
365
        it.next();
 
366
 
 
367
        int currentNodeId = hostId;  //Start from the host branch and work our way down the tree
 
368
        QStringList absolutePath = it.key().split( '/' );
 
369
        for ( int j = 0; j < absolutePath.count()-1; ++j ) {
 
370
            // Localize the sensor name part by part.
 
371
            QString name = KSGRD::SensorMgr->translateSensorPath( absolutePath[ j ] );
 
372
            currentNodeId = makeTreeBranch(currentNodeId, name);
 
373
        }
 
374
        removeSensor(hostInfo, currentNodeId, it.key());
 
375
    }
 
376
    emit sensorsAddedToHost( createIndex( mHostInfoMap.keys().indexOf(hostId), 0, hostId ) );
 
377
}
 
378
 
 
379
//virtual
 
380
QModelIndex SensorBrowserModel::parent ( const QModelIndex & index ) const {
 
381
    if(!index.isValid() || index.column() != 0)
 
382
        return QModelIndex();
 
383
    if(mHostInfoMap.contains(index.internalId())) return QModelIndex();
 
384
    if(!mParentsTreeMap.contains(index.internalId())) {
 
385
        kDebug(1215) << "Something is wrong with the model.  Doesn't contain " << index.internalId();
 
386
        return QModelIndex();
 
387
    }
 
388
    int parentId = mParentsTreeMap.value(index.internalId());
 
389
 
 
390
    QModelIndex parentModelIndex;
 
391
    if(mHostInfoMap.contains(parentId)) {
 
392
        parentModelIndex = createIndex(mHostInfoMap.keys().indexOf(parentId), 0 , parentId);
 
393
    } else {
 
394
        int parentsParentId = mParentsTreeMap.value(parentId);
 
395
        parentModelIndex = createIndex(mTreeMap.value(parentsParentId).indexOf(parentId), 0, parentId);
 
396
    }
 
397
    Q_ASSERT(parentModelIndex.isValid());
 
398
    return parentModelIndex;
 
399
}
 
400
//virtual
 
401
int SensorBrowserModel::rowCount ( const QModelIndex & parent ) const {
 
402
    if(!parent.isValid()) return mHostInfoMap.size();
 
403
    if(parent.column() != 0) return 0;
 
404
    return mTreeMap.value(parent.internalId()).size();
 
405
}
 
406
//virtual
 
407
Qt::ItemFlags SensorBrowserModel::flags ( const QModelIndex & index ) const {
 
408
    if(!index.isValid()) return 0;
 
409
    if(mSensorInfoMap.contains(index.internalId())) return Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
 
410
    else return Qt::ItemIsEnabled;
 
411
}
 
412
 
 
413
SensorBrowserWidget::SensorBrowserWidget( QWidget* parent, KSGRD::SensorManager* sm ) : QWidget( parent )
 
414
{
 
415
    QVBoxLayout *layout = new QVBoxLayout;
 
416
    m_treeWidget = new SensorBrowserTreeWidget(this, sm);
 
417
    KFilterProxySearchLine * search_line = new KFilterProxySearchLine(this);
 
418
    search_line->setProxy(&m_treeWidget->model());
 
419
    layout->addWidget(search_line);
 
420
    layout->addWidget(m_treeWidget);
 
421
    setLayout(layout);
 
422
}
 
423
SensorBrowserWidget::~SensorBrowserWidget()
 
424
{
 
425
}
 
426
SensorBrowserTreeWidget::SensorBrowserTreeWidget( QWidget* parent, KSGRD::SensorManager* sm ) : QTreeView( parent ), mSensorManager( sm )
 
427
{
 
428
    mSortFilterProxyModel.setSourceModel(&mSensorBrowserModel);
 
429
    mSortFilterProxyModel.setShowAllChildren(true);
 
430
    setModel(&mSortFilterProxyModel);
 
431
    connect( mSensorManager, SIGNAL( update() ), &mSensorBrowserModel, SLOT( update() ) );
 
432
    connect( mSensorManager, SIGNAL(hostAdded(KSGRD::SensorAgent*,const QString &)), &mSensorBrowserModel, SLOT( hostAdded(KSGRD::SensorAgent*,const QString &)) );
 
433
    connect( mSensorManager, SIGNAL(hostConnectionLost(const QString &)), &mSensorBrowserModel, SLOT( hostRemoved(const QString &)) );
 
434
//  connect( mSensorManager, SIGNAL(hostAdded(KSGRD::SensorAgent*,const QString &)), SLOT(updateView()) );
 
435
//  connect( mSensorManager, SIGNAL(hostConnectionLost(const QString &)), SLOT(updateView()) );
 
436
    connect( &mSortFilterProxyModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), SLOT(updateView()) );
 
437
 
 
438
    setDragDropMode(QAbstractItemView::DragOnly);
 
439
    setUniformRowHeights(true);
 
440
 
 
441
    //setMinimumWidth( 1 );
 
442
    retranslateUi();
 
443
    connect( &mSensorBrowserModel, SIGNAL(sensorsAddedToHost(const QModelIndex&)), this, SLOT(expandItem(const QModelIndex&)));
 
444
 
 
445
    KSGRD::SensorManagerIterator it( mSensorManager );
 
446
    while ( it.hasNext() ) {
 
447
        KSGRD::SensorAgent* sensorAgent = it.next().value();
 
448
        QString hostName = mSensorManager->hostName( sensorAgent );
 
449
        mSensorBrowserModel.addHost(sensorAgent, hostName);
 
450
    }
 
451
    updateView();
 
452
}
 
453
 
 
454
SensorBrowserTreeWidget::~SensorBrowserTreeWidget()
 
455
{
 
456
}
 
457
 
 
458
void SensorBrowserTreeWidget::updateView()
 
459
{
 
460
    if(mSensorManager->count() == 1) {
 
461
        setRootIsDecorated( false );
 
462
        //expand the top level
 
463
        for(int i = 0; i < mSortFilterProxyModel.rowCount(); i++)
 
464
            expand(mSortFilterProxyModel.index(i,0));
 
465
    } else
 
466
        setRootIsDecorated( true );
 
467
}
 
468
void SensorBrowserTreeWidget::expandItem(const QModelIndex &model_index)
 
469
{
 
470
    expand(mSortFilterProxyModel.mapFromSource(model_index));
 
471
}
 
472
void SensorBrowserTreeWidget::retranslateUi() {
 
473
 
 
474
    this->setToolTip( i18n( "Drag sensors to empty cells of a worksheet "));
 
475
    this->setWhatsThis( i18n( "The sensor browser lists the connected hosts and the sensors "
 
476
                "that they provide. Click and drag sensors into drop zones "
 
477
                "of a worksheet. A display will appear "
 
478
                "that visualizes the "
 
479
                "values provided by the sensor. Some sensor displays can "
 
480
                "display values of multiple sensors. Simply drag other "
 
481
                "sensors on to the display to add more sensors." ) );
 
482
}
 
483
 
 
484
void SensorBrowserTreeWidget::changeEvent( QEvent * event )
 
485
{
 
486
    if (event->type() == QEvent::LanguageChange) {
 
487
        retranslateUi();
 
488
        mSensorBrowserModel.retranslate();
 
489
        mSensorBrowserModel.update();
 
490
    }
 
491
    QWidget::changeEvent(event);
 
492
}
 
493
 
 
494
void SensorBrowserTreeWidget::disconnect()
 
495
{
 
496
    QModelIndexList indexlist = selectionModel()->selectedRows();
 
497
    for(int i=0; i < indexlist.size(); i++)
 
498
    {
 
499
        mSensorBrowserModel.disconnectHost(indexlist.value(i).internalId());
 
500
    }
 
501
}
 
502
 
 
503
void SensorBrowserTreeWidget::hostReconfigured( const QString& )
 
504
{
 
505
    // TODO: not yet implemented.
 
506
}
 
507
 
 
508
void SensorBrowserModel::clear() {
 
509
    qDeleteAll(mHostInfoMap);
 
510
    mHostInfoMap.clear();
 
511
 
 
512
}
 
513
 
 
514
void SensorBrowserModel::disconnectHost(uint id)
 
515
{
 
516
    disconnectHost(mHostInfoMap.value(id));
 
517
}
 
518
void SensorBrowserModel::disconnectHost(const HostInfo *hostInfo)
 
519
{
 
520
    KSGRD::SensorMgr->disengage( hostInfo->sensorAgent() );
 
521
}
 
522
void SensorBrowserModel::disconnectHost(const QString &hostname)
 
523
{
 
524
    HostInfo* toDelete = findHostInfoByHostName(hostname);
 
525
    if (toDelete != NULL)
 
526
        disconnectHost(toDelete);
 
527
}
 
528
HostInfo* SensorBrowserModel::findHostInfoByHostName(const QString &hostName) const {
 
529
    HostInfo* toReturn = NULL;
 
530
    QMapIterator<int, HostInfo*> it( mHostInfoMap );
 
531
    while (it.hasNext() && toReturn == NULL) {
 
532
        it.next();
 
533
        if (it.value()->hostName() == hostName) {
 
534
            toReturn = it.value();
 
535
        }
 
536
    }
 
537
    return toReturn;
 
538
}
 
539
void SensorBrowserModel::hostAdded(KSGRD::SensorAgent *sensorAgent, const QString &hostName)  {
 
540
    addHost(sensorAgent,hostName);
 
541
    update();
 
542
}
 
543
 
 
544
void SensorBrowserModel::hostRemoved(const QString &hostName)  {
 
545
    HostInfo* toRemove = findHostInfoByHostName(hostName);
 
546
    if (toRemove != NULL)  {
 
547
        beginResetModel();
 
548
        int hostId = toRemove->id();
 
549
        removeAllSensorUnderBranch(toRemove,hostId);
 
550
        removeEmptyParentTreeBranches(hostId,hostId,hostId);
 
551
 
 
552
        delete mHostInfoMap.take(hostId);
 
553
        mTreeMap.take(hostId);
 
554
        mHostSensorsMap.take(hostId);
 
555
        endResetModel();
 
556
    }
 
557
    update();
 
558
}
 
559
 
 
560
void SensorBrowserModel::removeAllSensorUnderBranch(HostInfo* hostInfo, int parentId)  {
 
561
 
 
562
    QList<int> children = mTreeMap.value(parentId);
 
563
 
 
564
    for (int i = 0; i < children.size(); i++) {
 
565
 
 
566
        if (mTreeMap.contains(children[i]))  {
 
567
            //well our children is not a sensor so remove what is under him
 
568
            removeAllSensorUnderBranch(hostInfo,children[i]);
 
569
 
 
570
        } else  {
 
571
            //well this should be a sensor so remove it
 
572
            if (mSensorInfoMap.contains(children[i])) {
 
573
                SensorInfo* sensorToRemove = mSensorInfoMap.value(children[i]);
 
574
                Q_ASSERT(sensorToRemove);
 
575
                removeSensor(hostInfo, parentId, sensorToRemove->name());
 
576
            }
 
577
        }
 
578
    }
 
579
 
 
580
 
 
581
}
 
582
void SensorBrowserModel::addHost(KSGRD::SensorAgent *sensorAgent, const QString &hostName)
 
583
{
 
584
    beginInsertRows( QModelIndex() , mHostInfoMap.size(), mHostInfoMap.size() );
 
585
    HostInfo* hostInfo = new HostInfo( mIdCount, sensorAgent, hostName);
 
586
    mHostInfoMap.insert(mIdCount, hostInfo);
 
587
    mTreeMap.insert(mIdCount, QList<int>());
 
588
    mHostSensorsMap.insert(mIdCount, QHash<QString, bool>());
 
589
    mIdCount++;
 
590
    endInsertRows();
 
591
    hostInfo->sensorAgent()->sendRequest( "monitors", this, mIdCount-1 );
 
592
}
 
593
 
 
594
void SensorBrowserModel::update()
 
595
{
 
596
    QMapIterator<int, HostInfo*> it( mHostInfoMap );
 
597
    while ( it.hasNext() ) {
 
598
        it.next();
 
599
        KSGRD::SensorAgent* sensorAgent = it.value()->sensorAgent();
 
600
        int id = it.key();
 
601
        sensorAgent->sendRequest( "monitors", this, id );
 
602
    }
 
603
}
 
604
QMimeData * SensorBrowserModel::mimeData ( const QModelIndexList & indexes ) const { //virtual
 
605
    QMimeData *mimeData = new QMimeData();
 
606
    if(indexes.size() != 1) return mimeData;
 
607
    SensorInfo *sensor = getSensorInfo(indexes[0]);
 
608
    if(!sensor) return mimeData;
 
609
    // Create text drag object as
 
610
    // "<hostname> <sensorname> <sensortype> <sensordescription>".
 
611
    // Only the description may contain blanks.
 
612
    Q_ASSERT(sensor);
 
613
    Q_ASSERT(sensor->hostInfo());
 
614
    QString mDragText = sensor->hostInfo()->hostName() + ' ' +
 
615
        sensor->name() + ' ' +
 
616
        sensor->type()+ ' ' +
 
617
        sensor->description();
 
618
 
 
619
 
 
620
    mimeData->setData( "application/x-ksysguard", mDragText.toUtf8() );
 
621
    return mimeData;
 
622
}
 
623
 
 
624
SensorInfo::SensorInfo( HostInfo *hostInfo, const QString &name,
 
625
        const QString &desc, const QString &type )
 
626
  : mName( name ), mDesc( desc ), mType( type ), mHostInfo( hostInfo )
 
627
{
 
628
    Q_ASSERT(mHostInfo);
 
629
}
 
630
 
 
631
QString SensorInfo::name() const
 
632
{
 
633
    return mName;
 
634
}
 
635
 
 
636
QString SensorInfo::type() const
 
637
{
 
638
    return mType;
 
639
}
 
640
 
 
641
QString SensorInfo::description() const
 
642
{
 
643
    return mDesc;
 
644
}
 
645
 
 
646
HostInfo *SensorInfo::hostInfo() const
 
647
{
 
648
    return mHostInfo;
 
649
}
 
650
 
 
651
 
 
652
 
 
653
#include "SensorBrowser.moc"