LCOV - code coverage report
Current view: top level - servus/qt - itemModel.cpp (source / functions) Hit Total Coverage
Test: Servus Lines: 99 103 96.1 %
Date: 2018-10-03 03:09:57 Functions: 18 19 94.7 %

          Line data    Source code
       1             : /* Copyright (c) 2015, Human Brain Project
       2             :  *                     Daniel.Nachbaur@epfl.ch
       3             :  *
       4             :  * This file is part of Servus <https://github.com/HBPVIS/Servus>
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or modify it under
       7             :  * the terms of the GNU Lesser General Public License version 3.0 as published
       8             :  * by the Free Software Foundation.
       9             :  *
      10             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      11             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      12             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      13             :  * details.
      14             :  *
      15             :  * You should have received a copy of the GNU Lesser General Public License
      16             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      17             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             :  */
      19             : 
      20             : #include "itemModel.h"
      21             : 
      22             : #include <servus/listener.h>
      23             : #include <servus/servus.h>
      24             : 
      25             : #include <QTimer>
      26             : 
      27             : namespace servus
      28             : {
      29             : namespace qt
      30             : {
      31             : class ItemModel::Impl : public Listener
      32             : {
      33             : public:
      34           4 :     Impl(Servus& service_, ItemModel& parent_)
      35           4 :         : parent(parent_)
      36             :         , service(service_)
      37           4 :         , rootItem(new QObject())
      38             :     {
      39           4 :         rootItem->setObjectName(
      40           8 :             QString("Instances for %1")
      41          16 :                 .arg(QString::fromStdString(service.getName())));
      42             : 
      43           4 :         for (const std::string& i : service.getInstances())
      44           0 :             _addInstanceItem(QString::fromStdString(i));
      45             : 
      46           4 :         service.addListener(this);
      47           4 :         service.beginBrowsing(Servus::IF_ALL);
      48             : 
      49           4 :         browseTimer.connect(&browseTimer, &QTimer::timeout,
      50          74 :                             [this]() { service.browse(0); });
      51           4 :         browseTimer.start(100);
      52           4 :     }
      53             : 
      54           8 :     ~Impl()
      55           8 :     {
      56           4 :         browseTimer.stop();
      57           4 :         service.removeListener(this);
      58           4 :         service.endBrowsing();
      59           8 :     }
      60             : 
      61           6 :     void instanceAdded(const std::string& instance) final
      62             :     {
      63           8 :         const QString& qstr = QString::fromStdString(instance);
      64           6 :         if (rootItem->findChild<QObject*>(qstr))
      65           4 :             return;
      66             : 
      67           6 :         parent.beginInsertRows(QModelIndex(), rootItem->children().size(),
      68           6 :                                rootItem->children().size());
      69           2 :         _addInstanceItem(qstr);
      70           2 :         parent.endInsertRows();
      71             :     }
      72             : 
      73           2 :     void instanceRemoved(const std::string& instance) final
      74             :     {
      75           4 :         const QString& qstr = QString::fromStdString(instance);
      76           2 :         QObject* child = rootItem->findChild<QObject*>(qstr);
      77           2 :         if (!child)
      78           0 :             return;
      79             : 
      80           2 :         const QObjectList& children = rootItem->children();
      81           2 :         const int childIdx = children.indexOf(child);
      82           2 :         parent.beginRemoveRows(QModelIndex(), childIdx, childIdx);
      83           2 :         _removeInstanceItem(qstr);
      84           2 :         parent.endRemoveRows();
      85             :     }
      86             : 
      87             :     ItemModel& parent;
      88             :     Servus& service;
      89             :     std::unique_ptr<QObject> rootItem;
      90             :     QTimer browseTimer;
      91             : 
      92             : private:
      93           2 :     void _addInstanceItem(const QString& instance)
      94             :     {
      95           4 :         const std::string& instanceStr = instance.toStdString();
      96           2 :         QObject* instanceItem = new QObject(rootItem.get());
      97           2 :         instanceItem->setObjectName(instance);
      98           4 :         const Strings& keys = service.getKeys(instanceStr);
      99           6 :         for (const std::string& key : keys)
     100             :         {
     101             :             const QString data =
     102           8 :                 QString("%1 = %2")
     103          16 :                     .arg(QString::fromStdString(key))
     104          16 :                     .arg(QString::fromStdString(service.get(instanceStr, key)));
     105           4 :             QObject* kvItem = new QObject(instanceItem);
     106           4 :             kvItem->setObjectName(data);
     107             :         }
     108           2 :     }
     109             : 
     110           2 :     void _removeInstanceItem(const QString& instance)
     111             :     {
     112           2 :         QObject* child = rootItem->findChild<QObject*>(instance);
     113           2 :         delete child;
     114           2 :     }
     115             : };
     116             : 
     117           4 : ItemModel::ItemModel(Servus& service, QObject* parent_)
     118             :     : QAbstractItemModel(parent_)
     119           4 :     , _impl(new Impl(service, *this))
     120             : {
     121           4 : }
     122             : 
     123           4 : ItemModel::~ItemModel()
     124             : {
     125           4 : }
     126             : 
     127           8 : QModelIndex ItemModel::index(const int row, const int column,
     128             :                              const QModelIndex& parent_) const
     129             : {
     130           8 :     if (!hasIndex(row, column, parent_))
     131           2 :         return QModelIndex();
     132             : 
     133             :     QObject* parentItem;
     134           6 :     if (!parent_.isValid())
     135           2 :         parentItem = _impl->rootItem.get();
     136             :     else
     137           4 :         parentItem = static_cast<QObject*>(parent_.internalPointer());
     138             : 
     139           6 :     QObject* childItem = parentItem->children()[row];
     140           6 :     if (childItem)
     141           6 :         return createIndex(row, column, childItem);
     142           0 :     return QModelIndex();
     143             : }
     144             : 
     145           6 : QModelIndex ItemModel::parent(const QModelIndex& index_) const
     146             : {
     147           6 :     if (!index_.isValid())
     148           2 :         return QModelIndex();
     149             : 
     150           4 :     QObject* childItem = static_cast<QObject*>(index_.internalPointer());
     151           4 :     QObject* parentItem = childItem->parent();
     152             : 
     153           4 :     if (parentItem == _impl->rootItem.get())
     154           2 :         return QModelIndex();
     155             : 
     156           2 :     if (!parentItem->parent())
     157           0 :         return createIndex(0, 0, parentItem);
     158           2 :     const int row = parentItem->parent()->children().indexOf(parentItem);
     159           2 :     return createIndex(row, 0, parentItem);
     160             : }
     161             : 
     162          20 : int ItemModel::rowCount(const QModelIndex& parent_) const
     163             : {
     164             :     QObject* parentItem;
     165          20 :     if (!parent_.isValid())
     166          12 :         parentItem = _impl->rootItem.get();
     167             :     else
     168           8 :         parentItem = static_cast<QObject*>(parent_.internalPointer());
     169             : 
     170          20 :     return parentItem->children().size();
     171             : }
     172             : 
     173          10 : int ItemModel::columnCount(const QModelIndex& index_) const
     174             : {
     175             :     Q_UNUSED(index_);
     176          10 :     return 1;
     177             : }
     178             : 
     179          14 : QVariant ItemModel::data(const QModelIndex& index_, const int role) const
     180             : {
     181          14 :     if (!index_.isValid())
     182           2 :         return QVariant();
     183             : 
     184          12 :     QObject* item = static_cast<QObject*>(index_.internalPointer());
     185             : 
     186          12 :     switch (role)
     187             :     {
     188             :     case Qt::DisplayRole:
     189           6 :         return item->objectName();
     190             :     case Qt::ToolTipRole:
     191             :     case Qt::UserRole:
     192           4 :         if (item->children().isEmpty())
     193           2 :             return QVariant();
     194           4 :         return QString::fromStdString(
     195           6 :             _impl->service.getHost(item->objectName().toStdString()));
     196             :     default:
     197           2 :         return QVariant();
     198             :     }
     199             : }
     200             : 
     201           4 : QVariant ItemModel::headerData(const int section,
     202             :                                const Qt::Orientation orientation,
     203             :                                const int role) const
     204             : {
     205             :     Q_UNUSED(section);
     206           4 :     if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
     207           2 :         return _impl->rootItem->objectName();
     208             : 
     209           2 :     return QVariant();
     210             : }
     211             : }
     212          30 : }

Generated by: LCOV version 1.11