- Implemented the "Stop" and "Goto Stream" per stream "nextWhat" options (Goto can only go to first stream for now - not any arbitrary stream)
- StreamListView now has a delegate to display a combobox for "nextWhat" and a checkbox for "status" - StreamListView now has reasonable default widths for its columns
This commit is contained in:
parent
f13b0915d5
commit
53bcc077da
@ -20,6 +20,7 @@ HEADERS += \
|
|||||||
portstatswindow.h \
|
portstatswindow.h \
|
||||||
portswindow.h \
|
portswindow.h \
|
||||||
streamconfigdialog.h \
|
streamconfigdialog.h \
|
||||||
|
streamlistdelegate.h \
|
||||||
streammodel.h
|
streammodel.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
@ -45,6 +46,7 @@ SOURCES += \
|
|||||||
portstatswindow.cpp \
|
portstatswindow.cpp \
|
||||||
portswindow.cpp \
|
portswindow.cpp \
|
||||||
streamconfigdialog.cpp \
|
streamconfigdialog.cpp \
|
||||||
|
streamlistdelegate.cpp \
|
||||||
streammodel.cpp
|
streammodel.cpp
|
||||||
|
|
||||||
# Protocol Buffer Sources
|
# Protocol Buffer Sources
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
#include "portswindow.h"
|
#include "portswindow.h"
|
||||||
|
#include "streamlistdelegate.h"
|
||||||
#include "streamconfigdialog.h"
|
#include "streamconfigdialog.h"
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QItemSelectionModel>
|
#include <QItemSelectionModel>
|
||||||
|
|
||||||
PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
||||||
{
|
{
|
||||||
|
StreamListDelegate *delegate = new StreamListDelegate;
|
||||||
//slm = new StreamListModel();
|
//slm = new StreamListModel();
|
||||||
//plm = new PortGroupList();
|
//plm = new PortGroupList();
|
||||||
plm = pgl;
|
plm = pgl;
|
||||||
|
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
tvStreamList->horizontalHeader()->resizeSections(
|
tvStreamList->setItemDelegate(delegate);
|
||||||
QHeaderView::ResizeToContents);
|
|
||||||
tvStreamList->verticalHeader()->setDefaultSectionSize(
|
tvStreamList->verticalHeader()->setDefaultSectionSize(
|
||||||
tvStreamList->verticalHeader()->minimumSectionSize());
|
tvStreamList->verticalHeader()->minimumSectionSize());
|
||||||
|
|
||||||
@ -53,6 +55,9 @@ PortsWindow::PortsWindow(PortGroupList *pgl, QWidget *parent)
|
|||||||
plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&)));
|
plm->getStreamModel(), SLOT(setCurrentPortIndex(const QModelIndex&)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
tvStreamList->resizeColumnToContents(StreamModel::StreamIcon);
|
||||||
|
tvStreamList->resizeColumnToContents(StreamModel::StreamStatus);
|
||||||
|
|
||||||
// Initially we don't have any ports/streams - so send signal triggers
|
// Initially we don't have any ports/streams - so send signal triggers
|
||||||
when_portView_currentChanged(QModelIndex(), QModelIndex());
|
when_portView_currentChanged(QModelIndex(), QModelIndex());
|
||||||
when_streamView_currentChanged(QModelIndex(), QModelIndex());
|
when_streamView_currentChanged(QModelIndex(), QModelIndex());
|
||||||
|
@ -173,7 +173,8 @@ StreamConfigDialog::StreamConfigDialog(Port &port, uint streamIndex,
|
|||||||
pbPrev->setDisabled(true);
|
pbPrev->setDisabled(true);
|
||||||
pbNext->setDisabled(true);
|
pbNext->setDisabled(true);
|
||||||
//! \todo Support Goto Stream Id
|
//! \todo Support Goto Stream Id
|
||||||
rbActionGotoStream->setDisabled(true);
|
leStreamId->setDisabled(true);
|
||||||
|
disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool)));
|
||||||
//! \todo Support Continuous Mode
|
//! \todo Support Continuous Mode
|
||||||
rbModeContinuous->setDisabled(true);
|
rbModeContinuous->setDisabled(true);
|
||||||
}
|
}
|
||||||
@ -824,10 +825,11 @@ void StreamConfigDialog::LoadCurrentStream()
|
|||||||
|
|
||||||
leNumPackets->setText(QString().setNum(pStream->numPackets()));
|
leNumPackets->setText(QString().setNum(pStream->numPackets()));
|
||||||
leNumBursts->setText(QString().setNum(pStream->numBursts()));
|
leNumBursts->setText(QString().setNum(pStream->numBursts()));
|
||||||
lePacketsPerBurst->setText(QString().setNum(
|
lePacketsPerBurst->setText(QString().setNum(pStream->burstSize()));
|
||||||
pStream->burstSize()));
|
|
||||||
lePacketsPerSec->setText(QString().setNum(pStream->packetRate()));
|
lePacketsPerSec->setText(QString().setNum(pStream->packetRate()));
|
||||||
leBurstsPerSec->setText(QString().setNum(pStream->burstRate()));
|
leBurstsPerSec->setText(QString().setNum(pStream->burstRate()));
|
||||||
|
// TODO(MED): Change this when we support goto to specific stream
|
||||||
|
leStreamId->setText(QString("0"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1915,6 +1915,9 @@ QLineEdit:enabled[inputMask = "HH HH HH HH HH HH; "] { background-color: #ccccff
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="leBurstsPerSec" >
|
<widget class="QLineEdit" name="leBurstsPerSec" >
|
||||||
|
<property name="enabled" >
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="alignment" >
|
<property name="alignment" >
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
|
175
client/streamlistdelegate.cpp
Normal file
175
client/streamlistdelegate.cpp
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
#include <QComboBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
|
||||||
|
#include "streammodel.h"
|
||||||
|
#include "streamlistdelegate.h"
|
||||||
|
|
||||||
|
StreamListDelegate::StreamListDelegate(QObject *parent)
|
||||||
|
: QItemDelegate(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QWidget *StreamListDelegate::createEditor(QWidget *parent,
|
||||||
|
const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
QWidget *editor = NULL;
|
||||||
|
|
||||||
|
switch ((StreamModel::StreamFields) index.column())
|
||||||
|
{
|
||||||
|
case StreamModel::StreamStatus:
|
||||||
|
{
|
||||||
|
editor = new QCheckBox(parent);
|
||||||
|
goto _handled;
|
||||||
|
}
|
||||||
|
case StreamModel::StreamNextWhat:
|
||||||
|
{
|
||||||
|
editor = new QComboBox(parent);
|
||||||
|
static_cast<QComboBox*>(editor)->insertItems(0,
|
||||||
|
StreamModel::nextWhatOptionList());
|
||||||
|
goto _handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
case StreamModel::StreamIcon:
|
||||||
|
case StreamModel::StreamName:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
editor = QItemDelegate::createEditor(parent, option, index);
|
||||||
|
|
||||||
|
_handled:
|
||||||
|
return editor;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StreamListDelegate::setEditorData(QWidget *editor,
|
||||||
|
const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
switch ((StreamModel::StreamFields) index.column())
|
||||||
|
{
|
||||||
|
case StreamModel::StreamStatus:
|
||||||
|
{
|
||||||
|
QCheckBox *cb = static_cast<QCheckBox*>(editor);
|
||||||
|
cb->setChecked(
|
||||||
|
index.model()->data(index, Qt::EditRole).toBool());
|
||||||
|
goto _handled;
|
||||||
|
}
|
||||||
|
case StreamModel::StreamNextWhat:
|
||||||
|
{
|
||||||
|
QComboBox *cb = static_cast<QComboBox*>(editor);
|
||||||
|
cb->setCurrentIndex(
|
||||||
|
index.model()->data(index, Qt::EditRole).toInt());
|
||||||
|
goto _handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
case StreamModel::StreamIcon:
|
||||||
|
case StreamModel::StreamName:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QItemDelegate::setEditorData(editor, index);
|
||||||
|
|
||||||
|
_handled:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StreamListDelegate::setModelData(QWidget *editor,
|
||||||
|
QAbstractItemModel *model, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
switch ((StreamModel::StreamFields) index.column())
|
||||||
|
{
|
||||||
|
case StreamModel::StreamStatus:
|
||||||
|
{
|
||||||
|
QCheckBox *cb = static_cast<QCheckBox*>(editor);
|
||||||
|
model->setData(index, cb->isChecked(), Qt::EditRole);
|
||||||
|
goto _handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
case StreamModel::StreamNextWhat:
|
||||||
|
{
|
||||||
|
QComboBox *cb = static_cast<QComboBox*>(editor);
|
||||||
|
model->setData(index, cb->currentIndex(), Qt::EditRole);
|
||||||
|
goto _handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
case StreamModel::StreamIcon:
|
||||||
|
case StreamModel::StreamName:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QItemDelegate::setModelData(editor, model, index);
|
||||||
|
|
||||||
|
_handled:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StreamListDelegate::updateEditorGeometry(QWidget *editor,
|
||||||
|
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
switch ((StreamModel::StreamFields) index.column())
|
||||||
|
{
|
||||||
|
case StreamModel::StreamStatus:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* extra 'coz QItemDelegate does it - otherwise the editor
|
||||||
|
* placement is incorrect
|
||||||
|
*/
|
||||||
|
int extra = 2 * (qApp->style()->pixelMetric(
|
||||||
|
QStyle::PM_FocusFrameHMargin, 0) + 1);
|
||||||
|
|
||||||
|
editor->setGeometry(option.rect.translated(extra, 0));
|
||||||
|
goto _handled;
|
||||||
|
}
|
||||||
|
case StreamModel::StreamIcon:
|
||||||
|
case StreamModel::StreamName:
|
||||||
|
case StreamModel::StreamNextWhat:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QItemDelegate::updateEditorGeometry(editor, option, index);
|
||||||
|
|
||||||
|
_handled:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool StreamListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||||
|
const QStyleOptionViewItem &option, const QModelIndex &index)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Special Handling so that user can use the "Stream status" checkbox
|
||||||
|
* without double clicking first. Copied from QItemDelegate::editorEvent()
|
||||||
|
* and modified suitably
|
||||||
|
*/
|
||||||
|
if ((StreamModel::StreamFields)index.column() ==
|
||||||
|
StreamModel::StreamStatus)
|
||||||
|
{
|
||||||
|
// make sure that we have the right event type
|
||||||
|
if ((event->type() == QEvent::MouseButtonRelease)
|
||||||
|
|| (event->type() == QEvent::MouseButtonDblClick))
|
||||||
|
{
|
||||||
|
QRect checkRect = check(option, option.rect, Qt::Checked);
|
||||||
|
QRect emptyRect;
|
||||||
|
doLayout(option, &checkRect, &emptyRect, &emptyRect, false);
|
||||||
|
if (!checkRect.contains(static_cast<QMouseEvent*>(event)->pos()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Qt::CheckState state = (static_cast<Qt::CheckState>(index.data(
|
||||||
|
Qt::CheckStateRole).toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked);
|
||||||
|
return model->setData(index, state, Qt::CheckStateRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QItemDelegate::editorEvent(event, model, option, index);
|
||||||
|
}
|
||||||
|
|
29
client/streamlistdelegate.h
Normal file
29
client/streamlistdelegate.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef STREAM_LIST_DELEGATE_H
|
||||||
|
#define STREAM_LIST_DELEGATE_H
|
||||||
|
|
||||||
|
#include <QItemDelegate>
|
||||||
|
#include <QModelIndex>
|
||||||
|
|
||||||
|
class StreamListDelegate : public QItemDelegate
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
StreamListDelegate(QObject *parent = 0);
|
||||||
|
|
||||||
|
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||||
|
const QModelIndex &index) const;
|
||||||
|
|
||||||
|
void setEditorData(QWidget *editor, const QModelIndex &index) const;
|
||||||
|
void setModelData(QWidget *editor, QAbstractItemModel *model,
|
||||||
|
const QModelIndex &index) const;
|
||||||
|
|
||||||
|
void updateEditorGeometry(QWidget *editor,
|
||||||
|
const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||||
|
|
||||||
|
bool editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||||
|
const QStyleOptionViewItem &option, const QModelIndex &index);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "stream.h"
|
||||||
#include "streammodel.h"
|
#include "streammodel.h"
|
||||||
#include "portgrouplist.h"
|
#include "portgrouplist.h"
|
||||||
#include "qicon.h"
|
#include "qicon.h"
|
||||||
@ -38,17 +39,19 @@ Qt::ItemFlags StreamModel::flags(const QModelIndex &index) const
|
|||||||
flags |= Qt::ItemIsEditable;
|
flags |= Qt::ItemIsEditable;
|
||||||
break;
|
break;
|
||||||
case StreamStatus:
|
case StreamStatus:
|
||||||
#if 0
|
flags |= Qt::ItemIsUserCheckable;
|
||||||
flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable;
|
break;
|
||||||
#endif
|
case StreamNextWhat:
|
||||||
flags |= Qt::ItemIsEditable;
|
flags |= Qt::ItemIsEditable;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
//qFatal("Missed case in switch!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant StreamModel::data(const QModelIndex &index, int role) const
|
QVariant StreamModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
// Check for a valid index
|
// Check for a valid index
|
||||||
@ -72,10 +75,6 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
|
|||||||
{
|
{
|
||||||
if (role == Qt::DecorationRole)
|
if (role == Qt::DecorationRole)
|
||||||
return QIcon(":/icons/stream_edit.png");
|
return QIcon(":/icons/stream_edit.png");
|
||||||
#if 0
|
|
||||||
else if ((role == Qt::DisplayRole))
|
|
||||||
return QString("EDIT");
|
|
||||||
#endif
|
|
||||||
else
|
else
|
||||||
return QVariant();
|
return QVariant();
|
||||||
break;
|
break;
|
||||||
@ -90,12 +89,7 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
case StreamStatus:
|
case StreamStatus:
|
||||||
{
|
{
|
||||||
if ((role == Qt::DisplayRole) || (role == Qt::EditRole))
|
if ((role == Qt::CheckStateRole))
|
||||||
return mCurrentPort->streamByIndex(index.row()).isEnabled();
|
|
||||||
else
|
|
||||||
return QVariant();
|
|
||||||
#if 0
|
|
||||||
if ((role == Qt::CheckStateRole) || (role == Qt::EditRole))
|
|
||||||
{
|
{
|
||||||
if (mCurrentPort->streamByIndex(index.row()).isEnabled())
|
if (mCurrentPort->streamByIndex(index.row()).isEnabled())
|
||||||
return Qt::Checked;
|
return Qt::Checked;
|
||||||
@ -104,11 +98,23 @@ QVariant StreamModel::data(const QModelIndex &index, int role) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
return QVariant();
|
return QVariant();
|
||||||
#endif
|
break;
|
||||||
|
}
|
||||||
|
case StreamNextWhat:
|
||||||
|
{
|
||||||
|
int val = mCurrentPort->streamByIndex(index.row()).nextWhat();
|
||||||
|
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return nextWhatOptionList().at(val);
|
||||||
|
else if (role == Qt::EditRole)
|
||||||
|
return val;
|
||||||
|
else
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
qFatal("-------------UNHANDLED STREAM FIELD----------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
@ -119,24 +125,35 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r
|
|||||||
if (mCurrentPort == NULL)
|
if (mCurrentPort == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (index.isValid() && role == Qt::EditRole)
|
if (index.isValid())
|
||||||
{
|
{
|
||||||
// Edit Supported Fields
|
|
||||||
switch (index.column())
|
switch (index.column())
|
||||||
{
|
{
|
||||||
|
// Edit Supported Fields
|
||||||
case StreamName:
|
case StreamName:
|
||||||
mCurrentPort->streamByIndex(index.row()).setName(value.toString());
|
mCurrentPort->streamByIndex(index.row()).setName(value.toString());
|
||||||
|
emit(dataChanged(index, index));
|
||||||
return true;
|
return true;
|
||||||
break;
|
|
||||||
case StreamStatus:
|
case StreamStatus:
|
||||||
mCurrentPort->streamByIndex(index.row()).setIsEnabled(value.toBool());
|
mCurrentPort->streamByIndex(index.row()).setIsEnabled(value.toBool());
|
||||||
|
emit(dataChanged(index, index));
|
||||||
return true;
|
return true;
|
||||||
break;
|
|
||||||
|
case StreamNextWhat:
|
||||||
|
if (role == Qt::EditRole)
|
||||||
|
{
|
||||||
|
mCurrentPort->streamByIndex(index.row()).setNextWhat(
|
||||||
|
(Stream::NextWhat)value.toInt());
|
||||||
|
emit(dataChanged(index, index));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
// Edit Not Supported Fields
|
// Edit Not Supported Fields
|
||||||
case StreamIcon:
|
case StreamIcon:
|
||||||
return false;
|
return false;
|
||||||
break;
|
|
||||||
|
|
||||||
// Unhandled Stream Field
|
// Unhandled Stream Field
|
||||||
default:
|
default:
|
||||||
@ -144,6 +161,7 @@ bool StreamModel::setData(const QModelIndex &index, const QVariant &value, int r
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,13 +175,16 @@ QVariant StreamModel::headerData(int section, Qt::Orientation orientation, int r
|
|||||||
switch(section)
|
switch(section)
|
||||||
{
|
{
|
||||||
case StreamIcon:
|
case StreamIcon:
|
||||||
return QString("Icon");
|
return QString("");
|
||||||
break;
|
break;
|
||||||
case StreamName:
|
case StreamName:
|
||||||
return QString("Name");
|
return QString("Name");
|
||||||
break;
|
break;
|
||||||
case StreamStatus:
|
case StreamStatus:
|
||||||
return QString("Enabled");
|
return QString("");
|
||||||
|
break;
|
||||||
|
case StreamNextWhat:
|
||||||
|
return QString("Goto");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
qDebug("-------------UNHANDLED STREAM FIELD----------------");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef _STREAM_MODEL_H
|
#ifndef _STREAM_MODEL_H
|
||||||
#define _STREAM_MODEL_H
|
#define _STREAM_MODEL_H
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
|
|
||||||
@ -10,14 +11,6 @@ class StreamModel : public QAbstractTableModel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
enum StreamFields {
|
|
||||||
StreamIcon = 0,
|
|
||||||
StreamName,
|
|
||||||
StreamStatus,
|
|
||||||
|
|
||||||
StreamMaxFields
|
|
||||||
};
|
|
||||||
|
|
||||||
Port *mCurrentPort;
|
Port *mCurrentPort;
|
||||||
PortGroupList *pgl;
|
PortGroupList *pgl;
|
||||||
|
|
||||||
@ -43,6 +36,19 @@ class StreamModel : public QAbstractTableModel
|
|||||||
{ return &mCurrentPort->mStreams; }
|
{ return &mCurrentPort->mStreams; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum StreamFields {
|
||||||
|
StreamIcon = 0,
|
||||||
|
StreamName,
|
||||||
|
StreamStatus,
|
||||||
|
StreamNextWhat,
|
||||||
|
|
||||||
|
StreamMaxFields
|
||||||
|
};
|
||||||
|
|
||||||
|
static QStringList nextWhatOptionList()
|
||||||
|
{ return QStringList() << "Stop" << "Next" << "Goto first"; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCurrentPortIndex(const QModelIndex ¤t);
|
void setCurrentPortIndex(const QModelIndex ¤t);
|
||||||
|
|
||||||
|
@ -559,6 +559,7 @@ PortInfo::PortInfo(uint id, pcap_if_t *dev)
|
|||||||
|
|
||||||
// We'll create sendqueue later when required
|
// We'll create sendqueue later when required
|
||||||
sendQueueList.clear();
|
sendQueueList.clear();
|
||||||
|
returnToQIdx = -1;
|
||||||
pcapExtra.txPkts = 0;
|
pcapExtra.txPkts = 0;
|
||||||
pcapExtra.txBytes = 0;
|
pcapExtra.txBytes = 0;
|
||||||
isSendQueueDirty=true;
|
isSendQueueDirty=true;
|
||||||
@ -581,6 +582,8 @@ void PortInfo::update()
|
|||||||
foreach(sendQ, sendQueueList)
|
foreach(sendQ, sendQueueList)
|
||||||
pcap_sendqueue_destroy(sendQ.sendQueue);
|
pcap_sendqueue_destroy(sendQ.sendQueue);
|
||||||
}
|
}
|
||||||
|
sendQueueList.clear();
|
||||||
|
returnToQIdx = -1;
|
||||||
|
|
||||||
// TODO(LOW): calculate sendqueue size
|
// TODO(LOW): calculate sendqueue size
|
||||||
sendQ.sendQueue = pcap_sendqueue_alloc(1*MB);
|
sendQ.sendQueue = pcap_sendqueue_alloc(1*MB);
|
||||||
@ -589,8 +592,11 @@ void PortInfo::update()
|
|||||||
// First sort the streams by ordinalValue
|
// First sort the streams by ordinalValue
|
||||||
qSort(streamList);
|
qSort(streamList);
|
||||||
|
|
||||||
|
pktHdr.ts.tv_sec = 0;
|
||||||
|
pktHdr.ts.tv_usec = 0;
|
||||||
for (int i = 0; i < streamList.size(); i++)
|
for (int i = 0; i < streamList.size(); i++)
|
||||||
{
|
{
|
||||||
|
//_restart:
|
||||||
if (streamList[i].d.core().is_enabled())
|
if (streamList[i].d.core().is_enabled())
|
||||||
{
|
{
|
||||||
long numPackets, numBursts;
|
long numPackets, numBursts;
|
||||||
@ -619,8 +625,6 @@ void PortInfo::update()
|
|||||||
numBursts, numPackets);
|
numBursts, numPackets);
|
||||||
qDebug("ibg = %ld, ipg = %ld\n", ibg, ipg);
|
qDebug("ibg = %ld, ipg = %ld\n", ibg, ipg);
|
||||||
|
|
||||||
pktHdr.ts.tv_sec = 0;
|
|
||||||
pktHdr.ts.tv_usec = 0;
|
|
||||||
for (int j = 0; j < numBursts; j++)
|
for (int j = 0; j < numBursts; j++)
|
||||||
{
|
{
|
||||||
for (int k = 0; k < numPackets; k++)
|
for (int k = 0; k < numPackets; k++)
|
||||||
@ -655,6 +659,9 @@ void PortInfo::update()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug("q(%d, %d, %d) sec = %lu usec = %lu",
|
||||||
|
i, j, k, pktHdr.ts.tv_sec, pktHdr.ts.tv_usec);
|
||||||
|
|
||||||
if (-1 == pcap_sendqueue_queue(sendQ.sendQueue, &pktHdr,
|
if (-1 == pcap_sendqueue_queue(sendQ.sendQueue, &pktHdr,
|
||||||
(u_char*) pktBuf))
|
(u_char*) pktBuf))
|
||||||
{
|
{
|
||||||
@ -664,17 +671,48 @@ void PortInfo::update()
|
|||||||
else
|
else
|
||||||
sendQ.sendQueueCumLen.append(sendQ.sendQueue->len);
|
sendQ.sendQueueCumLen.append(sendQ.sendQueue->len);
|
||||||
}
|
}
|
||||||
}
|
} // for (numPackets)
|
||||||
pktHdr.ts.tv_usec += ibg;
|
pktHdr.ts.tv_usec += ibg;
|
||||||
if (pktHdr.ts.tv_usec > 1000000)
|
if (pktHdr.ts.tv_usec > 1000000)
|
||||||
{
|
{
|
||||||
pktHdr.ts.tv_sec++;
|
pktHdr.ts.tv_sec++;
|
||||||
pktHdr.ts.tv_usec -= 1000000;
|
pktHdr.ts.tv_usec -= 1000000;
|
||||||
}
|
}
|
||||||
}
|
} // for (numBursts)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch(streamList[i].d.control().next())
|
||||||
|
{
|
||||||
|
case ::OstProto::StreamControl::e_nw_stop:
|
||||||
|
goto _stop_no_more_pkts;
|
||||||
|
|
||||||
|
case ::OstProto::StreamControl::e_nw_goto_id:
|
||||||
|
// TODO(MED): define and use
|
||||||
|
// streamList[i].d.control().goto_stream_id();
|
||||||
|
|
||||||
|
// TODO(MED): assumes goto Id is less than current!!!!
|
||||||
|
// To support goto to any id, do
|
||||||
|
// if goto_id > curr_id then
|
||||||
|
// i = goto_id;
|
||||||
|
// goto restart;
|
||||||
|
// else
|
||||||
|
// returnToQIdx = 0;
|
||||||
|
|
||||||
|
returnToQIdx=0;
|
||||||
|
goto _stop_no_more_pkts;
|
||||||
|
|
||||||
|
case ::OstProto::StreamControl::e_nw_goto_next:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
qFatal("---------- %s: Unhandled case (%d) -----------",
|
||||||
|
__FUNCTION__, streamList[i].d.control().next() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // if (stream is enabled)
|
||||||
|
} // for (numStreams)
|
||||||
|
|
||||||
|
_stop_no_more_pkts:
|
||||||
// The last alloc'ed sendQ appended here
|
// The last alloc'ed sendQ appended here
|
||||||
sendQueueList.append(sendQ);
|
sendQueueList.append(sendQ);
|
||||||
|
|
||||||
@ -1061,8 +1099,9 @@ void PortInfo::PortTransmitter::run()
|
|||||||
|
|
||||||
m_stop = 0;
|
m_stop = 0;
|
||||||
ost_pcap_sendqueue_list_transmit(port->devHandleRx, port->sendQueueList,
|
ost_pcap_sendqueue_list_transmit(port->devHandleRx, port->sendQueueList,
|
||||||
true, &m_stop, &port->pcapExtra.txPkts, &port->pcapExtra.txBytes,
|
port->returnToQIdx, true, &m_stop,
|
||||||
QThread::usleep);
|
&port->pcapExtra.txPkts, &port->pcapExtra.txBytes,
|
||||||
|
QThread::usleep);
|
||||||
m_stop = 0;
|
m_stop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,7 @@ class PortInfo
|
|||||||
pcap_t *devHandleRx;
|
pcap_t *devHandleRx;
|
||||||
pcap_t *devHandleTx;
|
pcap_t *devHandleTx;
|
||||||
QList<ost_pcap_send_queue> sendQueueList;
|
QList<ost_pcap_send_queue> sendQueueList;
|
||||||
|
int returnToQIdx; // FIXME(MED): combine with sendQList
|
||||||
bool isSendQueueDirty;
|
bool isSendQueueDirty;
|
||||||
PcapExtra pcapExtra;
|
PcapExtra pcapExtra;
|
||||||
PortMonitorRx monitorRx;
|
PortMonitorRx monitorRx;
|
||||||
|
@ -62,20 +62,32 @@ int pcap_sendqueue_queue (pcap_send_queue *queue,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
u_int ost_pcap_sendqueue_list_transmit(pcap_t *p,
|
u_int ost_pcap_sendqueue_list_transmit(pcap_t *p,
|
||||||
QList<ost_pcap_send_queue> sendQueueList, int sync,
|
QList<ost_pcap_send_queue> sendQueueList, int returnToQIdx, int sync,
|
||||||
int *p_stop, quint64* p_pkts, quint64* p_bytes,
|
int *p_stop, quint64* p_pkts, quint64* p_bytes,
|
||||||
void (*pf_usleep)(ulong))
|
void (*pf_usleep)(ulong))
|
||||||
{
|
{
|
||||||
uint ret = 0;
|
uint i, ret = 0;
|
||||||
|
ost_pcap_send_queue sq;
|
||||||
|
|
||||||
foreach(ost_pcap_send_queue sq, sendQueueList)
|
for(i = 0; i < sendQueueList.size(); i++)
|
||||||
{
|
{
|
||||||
|
_restart:
|
||||||
|
sq = sendQueueList.at(i);
|
||||||
ret += ost_pcap_sendqueue_transmit(p, sq.sendQueue, sync,
|
ret += ost_pcap_sendqueue_transmit(p, sq.sendQueue, sync,
|
||||||
p_stop, p_pkts, p_bytes, pf_usleep);
|
p_stop, p_pkts, p_bytes, pf_usleep);
|
||||||
|
|
||||||
|
if (*p_stop)
|
||||||
|
return ret;
|
||||||
|
|
||||||
// TODO(HI): Timing between subsequent sendQueues
|
// TODO(HI): Timing between subsequent sendQueues
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (returnToQIdx >= 0)
|
||||||
|
{
|
||||||
|
i = returnToQIdx;
|
||||||
|
goto _restart;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ struct ost_pcap_send_queue
|
|||||||
|
|
||||||
// Common for all OS - *nix or Win32
|
// Common for all OS - *nix or Win32
|
||||||
u_int ost_pcap_sendqueue_list_transmit(pcap_t *p,
|
u_int ost_pcap_sendqueue_list_transmit(pcap_t *p,
|
||||||
QList<ost_pcap_send_queue> sendQueueList, int sync,
|
QList<ost_pcap_send_queue> sendQueueList, int returnToQIdx, int sync,
|
||||||
int *p_stop, quint64* p_pkts, quint64* p_bytes,
|
int *p_stop, quint64* p_pkts, quint64* p_bytes,
|
||||||
void (*pf_usleep)(ulong));
|
void (*pf_usleep)(ulong));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user