Device Emulation (contd.): Added DeviceGroupModel on the GUI client

This commit is contained in:
Srivats P 2016-02-12 19:10:19 +05:30
parent 6fddf0436c
commit c569328bb3
8 changed files with 247 additions and 14 deletions

173
client/devicegroupmodel.cpp Normal file
View File

@ -0,0 +1,173 @@
/*
Copyright (C) 2016 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#include "devicegroupmodel.h"
#include "port.h"
#include "emulproto.pb.h"
enum {
kName,
kCount,
kVlan,
kIp,
kFieldCount
};
static QStringList columns_ = QStringList()
<< "Name"
<< "Count"
<< "Vlan"
<< "IP";
DeviceGroupModel::DeviceGroupModel(QObject *parent)
: QAbstractTableModel(parent)
{
port_ = NULL;
}
int DeviceGroupModel::rowCount(const QModelIndex &parent) const
{
if (!port_ || parent.isValid())
return 0;
return port_->numDeviceGroups();
}
int DeviceGroupModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return columns_.size();
}
QVariant DeviceGroupModel::headerData(
int section,
Qt::Orientation orientation,
int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
switch (orientation) {
case Qt::Horizontal:
return columns_[section];
case Qt::Vertical:
return QString("%1").arg(section + 1);
default:
Q_ASSERT(false); // Unreachable
}
return QVariant();
}
QVariant DeviceGroupModel::data(const QModelIndex &index, int role) const
{
if (!port_ || !index.isValid())
return QVariant();
int dgIdx = index.row();
int field = index.column();
Q_ASSERT(dgIdx < port_->numDeviceGroups());
Q_ASSERT(field < kFieldCount);
OstProto::DeviceGroup *devGrp = port_->deviceGroupByIndex(dgIdx);
switch (field) {
case kName:
switch (role) {
case Qt::DisplayRole:
return QString::fromStdString(devGrp->core().name());
default:
break;
}
return QVariant();
case kCount:
switch (role) {
case Qt::DisplayRole:
return devGrp->device_count();
case Qt::TextAlignmentRole:
return Qt::AlignRight;
default:
break;
}
return QVariant();
case kVlan:
switch (role) {
case Qt::CheckStateRole:
if (devGrp->has_encap()
&& devGrp->encap().HasExtension(OstEmul::vlan)
&& devGrp->encap().GetExtension(OstEmul::vlan)
.stack_size())
return Qt::Checked;
return Qt::Unchecked;
case Qt::TextAlignmentRole:
return Qt::AlignCenter;
default:
break;
}
return QVariant();
case kIp:
switch (role) {
case Qt::DisplayRole:
if (devGrp->HasExtension(OstEmul::ip4))
if (devGrp->HasExtension(OstEmul::ip6))
return QString("Dual Stack");
else
return QString("IPv4");
else if (devGrp->HasExtension(OstEmul::ip6))
return QString("IPv6");
else
return QString("None");
default:
break;
}
return QVariant();
default:
break;
}
qWarning("%s: Unsupported field #%d", __FUNCTION__, field);
return QVariant();
}
bool DeviceGroupModel::setData(
const QModelIndex &index,
const QVariant &value,
int role)
{
if (!port_)
return false;
// FIXME
return false;
}
void DeviceGroupModel::setPort(Port *port)
{
port_ = port;
reset();
}

49
client/devicegroupmodel.h Normal file
View File

@ -0,0 +1,49 @@
/*
Copyright (C) 2016 Srivats P.
This file is part of "Ostinato"
This is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#ifndef _DEVICE_GROUP_MODEL_H
#define _DEVICE_GROUP_MODEL_H
#include <QAbstractTableModel>
#include <QStringList>
class Port;
class DeviceGroupModel: public QAbstractTableModel
{
Q_OBJECT
public:
DeviceGroupModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QVariant data(const QModelIndex &index, int role) const;
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole);
void setPort(Port *port);
private:
Port *port_;
};
#endif

View File

@ -33,6 +33,7 @@ LIBS += -lprotobuf
LIBS += -L"../extra/qhexedit2/$(OBJECTS_DIR)/" -lqhexedit2
RESOURCES += ostinato.qrc
HEADERS += \
devicegroupmodel.h \
dumpview.h \
hexlineedit.h \
mainwindow.h \
@ -67,6 +68,7 @@ FORMS += \
variablefieldswidget.ui
SOURCES += \
devicegroupmodel.cpp \
dumpview.cpp \
stream.cpp \
hexlineedit.cpp \

View File

@ -25,7 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
PortGroupList::PortGroupList()
: mPortGroupListModel(this),
mStreamListModel(this),
mPortStatsModel(this, this)
mPortStatsModel(this, this),
mDeviceGroupModel(this)
{
PortGroup *pg;
@ -33,10 +34,12 @@ PortGroupList::PortGroupList()
streamModelTester_ = NULL;
portModelTester_ = NULL;
portStatsModelTester_ = NULL;
deviceGroupModelTester_ = NULL;
#else
streamModelTester_ = new ModelTest(getStreamModel());
portModelTester_ = new ModelTest(getPortModel());
portStatsModelTester_ = new ModelTest(getPortStatsModel());
deviceGroupModelTester_ = new ModelTest(getPortStatsModel());
#endif
// Add the "Local" Port Group
@ -49,10 +52,10 @@ PortGroupList::~PortGroupList()
delete portStatsModelTester_;
delete portModelTester_;
delete streamModelTester_;
delete deviceGroupModelTester_;
while (!mPortGroups.isEmpty())
delete mPortGroups.takeFirst();
}
bool PortGroupList::isPortGroup(const QModelIndex& index)

View File

@ -20,12 +20,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#ifndef _PORT_GROUP_LIST_H
#define _PORT_GROUP_LIST_H
#include "devicegroupmodel.h"
#include "portgroup.h"
#include <QAbstractItemModel>
#include <QItemSelection>
#include "portmodel.h"
#include "streammodel.h"
#include "portstatsmodel.h"
#include "streammodel.h"
class PortModel;
class StreamModel;
@ -42,10 +41,12 @@ class PortGroupList : public QObject {
PortModel mPortGroupListModel;
StreamModel mStreamListModel;
PortStatsModel mPortStatsModel;
DeviceGroupModel mDeviceGroupModel;
QObject *streamModelTester_;
QObject *portModelTester_;
QObject *portStatsModelTester_;
QObject *deviceGroupModelTester_;
// Methods
public:
@ -55,6 +56,7 @@ public:
PortModel* getPortModel() { return &mPortGroupListModel; }
PortStatsModel* getPortStatsModel() { return &mPortStatsModel; }
StreamModel* getStreamModel() { return &mStreamListModel; }
DeviceGroupModel* getDeviceGroupModel() { return &mDeviceGroupModel; }
bool isPortGroup(const QModelIndex& index);
bool isPort(const QModelIndex& index);

View File

@ -51,6 +51,8 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
tvStreamList->verticalHeader()->setDefaultSectionSize(
tvStreamList->verticalHeader()->minimumSectionSize());
deviceGroupList->verticalHeader()->setDefaultSectionSize(
deviceGroupList->verticalHeader()->minimumSectionSize());
// Populate PortList Context Menu Actions
tvPortList->addAction(actionNew_Port_Group);
@ -82,6 +84,7 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
addActions(tvStreamList->actions());
tvStreamList->setModel(plm->getStreamModel());
deviceGroupList->setModel(plm->getDeviceGroupModel());
// XXX: It would be ideal if we only needed to do the below to
// get the proxy model to do its magic. However, the QModelIndex
@ -128,6 +131,10 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
tvStreamList->resizeColumnToContents(StreamModel::StreamIcon);
tvStreamList->resizeColumnToContents(StreamModel::StreamStatus);
// FIXME: hardcoding
deviceGroupList->resizeColumnToContents(1);
deviceGroupList->resizeColumnToContents(2);
// Initially we don't have any ports/streams - so send signal triggers
when_portView_currentChanged(QModelIndex(), QModelIndex());
updateStreamViewActions();
@ -203,6 +210,7 @@ void PortsWindow::when_portView_currentChanged(const QModelIndex& currentIndex,
{
QModelIndex current = currentIndex;
QModelIndex previous = previousIndex;
Port *port = NULL;
if (proxyPortModel) {
current = proxyPortModel->mapToSource(current);
@ -215,6 +223,10 @@ void PortsWindow::when_portView_currentChanged(const QModelIndex& currentIndex,
qDebug("In %s", __FUNCTION__);
if (plm->isPort(current))
port = &(plm->port(current));
plm->getDeviceGroupModel()->setPort(port);
if (previous.isValid() && plm->isPort(previous))
{
disconnect(&(plm->port(previous)), SIGNAL(portRateChanged(int, int)),
@ -801,5 +813,3 @@ _retry:
_exit:
return;
}

View File

@ -25,12 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
#include "ui_portswindow.h"
#include "portgrouplist.h"
/* TODO
HIGH
MED
LOW
*/
class QAbstractItemDelegate;
class QSortFilterProxyModel;

View File

@ -56,7 +56,7 @@ message Ip4Emulation {
optional uint32 prefix_length = 2;
optional uint32 default_gateway = 3;
optional uint64 step = 10 [default = 1];
optional uint32 step = 10 [default = 1];
// FIXME: step for gateway?
}