UX: Edit multiple streams in the StreamConfigDialog

The dialog now accepts a list of streams as input and has prev/next
buttons to tranverse through the list making changes in one or more of
the streams
This commit is contained in:
Srivats P 2017-09-17 13:18:44 +05:30
parent 509e9d5398
commit 360fa13c97
4 changed files with 121 additions and 78 deletions

View File

@ -115,12 +115,17 @@ public:
Q_ASSERT(index < mStreams.size()); Q_ASSERT(index < mStreams.size());
return mStreams[index]; return mStreams[index];
} }
Stream* mutableStreamByIndex(int index) Stream* mutableStreamByIndex(int index, bool assumeChange = true)
{ {
Q_ASSERT(index < mStreams.size()); Q_ASSERT(index < mStreams.size());
setDirty(true); // assume - that's the best we can do atm if (assumeChange)
setDirty(true);
return mStreams[index]; return mStreams[index];
} }
void setLocalConfigChanged(bool changed)
{
setDirty(changed);
}
OstProto::LinkState linkState() OstProto::LinkState linkState()
{ return stats.state().link_state(); } { return stats.state().link_state(); }

View File

@ -302,29 +302,26 @@ void PortsWindow::showMyReservedPortsOnly(bool enabled)
void PortsWindow::on_tvStreamList_activated(const QModelIndex & index) void PortsWindow::on_tvStreamList_activated(const QModelIndex & index)
{ {
QModelIndex currentPort = tvPortList->currentIndex();
StreamConfigDialog *scd;
int ret;
if (proxyPortModel)
currentPort = proxyPortModel->mapToSource(currentPort);
if (!index.isValid()) if (!index.isValid())
{ {
qDebug("%s: invalid index", __FUNCTION__); qDebug("%s: invalid index", __FUNCTION__);
return; return;
} }
QList<Stream*> streams;
streams.append(plm->port(currentPort).mutableStreamByIndex(index.row()));
scd = new StreamConfigDialog(streams, plm->port(currentPort), this);
qDebug("stream list activated\n"); qDebug("stream list activated\n");
ret = scd->exec();
if (ret == QDialog::Accepted) Port &curPort = plm->port(proxyPortModel ?
plm->port(currentPort).recalculateAverageRates(); proxyPortModel->mapToSource(tvPortList->currentIndex()) :
tvPortList->currentIndex());
delete scd; QList<Stream*> streams;
streams.append(curPort.mutableStreamByIndex(index.row(), false));
StreamConfigDialog scd(streams, curPort, this);
if (scd.exec() == QDialog::Accepted) {
curPort.recalculateAverageRates();
curPort.setLocalConfigChanged(true);
}
} }
void PortsWindow::when_portView_currentChanged(const QModelIndex& currentIndex, void PortsWindow::when_portView_currentChanged(const QModelIndex& currentIndex,
@ -493,21 +490,15 @@ void PortsWindow::updateStreamViewActions()
tvStreamList->selectionModel()->selection().size()); tvStreamList->selectionModel()->selection().size());
// If more than one non-contiguous ranges selected, // If more than one non-contiguous ranges selected,
// disable "New" and "Edit" // disable "New"
if (tvStreamList->selectionModel()->selection().size() > 1) if (tvStreamList->selectionModel()->selection().size() > 1)
{ {
actionNew_Stream->setDisabled(true); actionNew_Stream->setDisabled(true);
actionEdit_Stream->setDisabled(true);
} }
else else
{ {
actionNew_Stream->setEnabled(true); actionNew_Stream->setEnabled(true);
actionEdit_Stream->setEnabled(true);
// Enable "Edit" only if the single range has a single row
if (tvStreamList->selectionModel()->selection().at(0).height() > 1)
actionEdit_Stream->setDisabled(true);
else
actionEdit_Stream->setEnabled(true);
} }
// Duplicate/Delete are always enabled as long as we have a selection // Duplicate/Delete are always enabled as long as we have a selection
@ -795,12 +786,22 @@ void PortsWindow::on_actionEdit_Stream_triggered()
{ {
qDebug("Edit Stream Action"); qDebug("Edit Stream Action");
// Ensure we have only one range selected which contains only one row QItemSelectionModel* streamModel = tvStreamList->selectionModel();
if ((tvStreamList->selectionModel()->selection().size() == 1) && if (!streamModel->hasSelection())
(tvStreamList->selectionModel()->selection().at(0).height() == 1)) return;
{
on_tvStreamList_activated(tvStreamList->selectionModel()-> Port &curPort = plm->port(proxyPortModel ?
selection().at(0).topLeft()); proxyPortModel->mapToSource(tvPortList->currentIndex()) :
tvPortList->currentIndex());
QList<Stream*> streams;
foreach(QModelIndex index, streamModel->selectedRows())
streams.append(curPort.mutableStreamByIndex(index.row(), false));
StreamConfigDialog scd(streams, curPort, this);
if (scd.exec() == QDialog::Accepted) {
curPort.recalculateAverageRates();
curPort.setLocalConfigChanged(true);
} }
} }

View File

@ -43,17 +43,24 @@ StreamConfigDialog::StreamConfigDialog(
QList<Stream*> &streamList, QList<Stream*> &streamList,
const Port &port, const Port &port,
QWidget *parent) QWidget *parent)
: QDialog (parent), streamList_(streamList), mPort(port) : QDialog (parent), _userStreamList(streamList), mPort(port)
{ {
OstProto::Stream s;
mCurrentStreamIndex = 0; mCurrentStreamIndex = 0;
// FIXME: temporary till we support a list Q_ASSERT(_userStreamList.size() > 0);
Q_ASSERT(streamList_.size() == 1);
mpStream = new Stream; // Create a copy of the user provided stream list
streamList_.at(mCurrentStreamIndex)->protoDataCopyInto(s); // We need a copy because user may edit multiple streams and then
mpStream->protoDataCopyFrom(s); // discard the edit - in this case the user provided stream list
// should not be modified on return
foreach(Stream* stm, _userStreamList) {
OstProto::Stream s;
stm->protoDataCopyInto(s);
_streamList.append(new Stream());
_streamList.last()->protoDataCopyFrom(s);
}
mpStream = _streamList.at(mCurrentStreamIndex);
_iter = mpStream->createProtocolListIterator(); _iter = mpStream->createProtocolListIterator();
isUpdateInProgress = false; isUpdateInProgress = false;
@ -158,8 +165,6 @@ StreamConfigDialog::StreamConfigDialog(
this, SLOT(when_lvSelectedProtocols_currentChanged(const QModelIndex&, this, SLOT(when_lvSelectedProtocols_currentChanged(const QModelIndex&,
const QModelIndex&))); const QModelIndex&)));
variableFieldsWidget->setStream(mpStream);
LoadCurrentStream(); LoadCurrentStream();
mpPacketModel = new PacketModel(this); mpPacketModel = new PacketModel(this);
tvPacketTree->setModel(mpPacketModel); tvPacketTree->setModel(mpPacketModel);
@ -172,10 +177,9 @@ StreamConfigDialog::StreamConfigDialog(
vwPacketDump->setModel(mpPacketModel); vwPacketDump->setModel(mpPacketModel);
vwPacketDump->setSelectionModel(tvPacketTree->selectionModel()); vwPacketDump->setSelectionModel(tvPacketTree->selectionModel());
// TODO(MED): pbPrev->setDisabled(mCurrentStreamIndex == 0);
//! \todo Enable navigation of streams pbNext->setDisabled(int(mCurrentStreamIndex) == (_streamList.size()-1));
pbPrev->setHidden(true);
pbNext->setHidden(true);
//! \todo Support Goto Stream Id //! \todo Support Goto Stream Id
leStreamId->setHidden(true); leStreamId->setHidden(true);
disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool))); disconnect(rbActionGotoStream, SIGNAL(toggled(bool)), leStreamId, SLOT(setEnabled(bool)));
@ -325,7 +329,8 @@ StreamConfigDialog::~StreamConfigDialog()
} }
delete _iter; delete _iter;
delete mpStream; while (!_streamList.isEmpty())
delete _streamList.takeFirst();
} }
void StreamConfigDialog::loadProtocolWidgets() void StreamConfigDialog::loadProtocolWidgets()
@ -406,30 +411,6 @@ void StreamConfigDialog::on_cmbPktLenMode_currentIndexChanged(QString mode)
} }
} }
void StreamConfigDialog::on_pbPrev_clicked()
{
#if 0
StoreCurrentStream(currStreamIdx);
currStreamIdx--;
LoadCurrentStream(currStreamIdx);
pbPrev->setDisabled((currStreamIdx == 0));
pbNext->setDisabled((currStreamIdx == 2));
#endif
}
void StreamConfigDialog::on_pbNext_clicked()
{
#if 0
StoreCurrentStream(currStreamIdx);
currStreamIdx++;
LoadCurrentStream(currStreamIdx);
pbPrev->setDisabled((currStreamIdx == 0));
pbNext->setDisabled((currStreamIdx == 2));
#endif
}
void StreamConfigDialog::on_tbSelectProtocols_currentChanged(int index) void StreamConfigDialog::on_tbSelectProtocols_currentChanged(int index)
{ {
qDebug("%s, index = %d", __FUNCTION__, index); qDebug("%s, index = %d", __FUNCTION__, index);
@ -967,6 +948,7 @@ void StreamConfigDialog::LoadCurrentStream()
QString str; QString str;
qDebug("loading mpStream %p", mpStream); qDebug("loading mpStream %p", mpStream);
variableFieldsWidget->setStream(mpStream);
// Meta Data // Meta Data
{ {
@ -986,6 +968,7 @@ void StreamConfigDialog::LoadCurrentStream()
// Variable Fields // Variable Fields
{ {
variableFieldsWidget->clear();
variableFieldsWidget->load(); variableFieldsWidget->load();
} }
@ -1202,13 +1185,9 @@ void StreamConfigDialog::on_leBitsPerSec_textEdited(const QString &text)
} }
} }
void StreamConfigDialog::on_pbOk_clicked() bool StreamConfigDialog::isCurrentStreamValid()
{ {
QString log; QString log;
OstProto::Stream s;
// Store dialog contents into stream
StoreCurrentStream();
if ((mPort.transmitMode() == OstProto::kInterleavedTransmit) if ((mPort.transmitMode() == OstProto::kInterleavedTransmit)
&& (mpStream->isFrameVariable())) && (mpStream->isFrameVariable()))
@ -1224,12 +1203,68 @@ void StreamConfigDialog::on_pbOk_clicked()
if (QMessageBox::warning(this, "Preflight Check", log + "\nContinue?", if (QMessageBox::warning(this, "Preflight Check", log + "\nContinue?",
QMessageBox::Yes | QMessageBox::No, QMessageBox::No) QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
== QMessageBox::No) == QMessageBox::No)
return; return false;
} }
// Copy the data from the "local working copy of stream" to "actual stream" return true;
mpStream->protoDataCopyInto(s); }
streamList_[mCurrentStreamIndex]->protoDataCopyFrom(s);
void StreamConfigDialog::on_pbPrev_clicked()
{
Q_ASSERT(mCurrentStreamIndex > 0);
StoreCurrentStream();
if (!isCurrentStreamValid())
return;
delete _iter;
mpStream = _streamList.at(--mCurrentStreamIndex);
_iter = mpStream->createProtocolListIterator();
LoadCurrentStream();
on_twTopLevel_currentChanged(twTopLevel->currentIndex());
pbPrev->setDisabled(mCurrentStreamIndex == 0);
pbNext->setDisabled(int(mCurrentStreamIndex) == (_streamList.size()-1));
}
void StreamConfigDialog::on_pbNext_clicked()
{
Q_ASSERT(int(mCurrentStreamIndex) < (_streamList.size()-1));
StoreCurrentStream();
if (!isCurrentStreamValid())
return;
delete _iter;
mpStream = _streamList.at(++mCurrentStreamIndex);
_iter = mpStream->createProtocolListIterator();
LoadCurrentStream();
on_twTopLevel_currentChanged(twTopLevel->currentIndex());
pbPrev->setDisabled(mCurrentStreamIndex == 0);
pbNext->setDisabled(int(mCurrentStreamIndex) == (_streamList.size()-1));
}
void StreamConfigDialog::on_pbOk_clicked()
{
// Store dialog contents into current stream
StoreCurrentStream();
if (!isCurrentStreamValid())
return;
// Copy the working copy of streams to user provided streams
Q_ASSERT(_userStreamList.size() == _streamList.size());
for (int i = 0; i < _streamList.size(); i++) {
OstProto::Stream s;
_streamList.at(i)->protoDataCopyInto(s);
_userStreamList[i]->protoDataCopyFrom(s);
}
qDebug("stream stored"); qDebug("stream stored");

View File

@ -73,7 +73,8 @@ private:
QStringListModel *mpAvailableProtocolsModel; QStringListModel *mpAvailableProtocolsModel;
QStringListModel *mpSelectedProtocolsModel; QStringListModel *mpSelectedProtocolsModel;
QList<Stream*> streamList_; QList<Stream*> _userStreamList;
QList<Stream*> _streamList;
const Port& mPort; const Port& mPort;
uint mCurrentStreamIndex; uint mCurrentStreamIndex;
@ -94,6 +95,7 @@ private:
static int lastProtocolDataIndex; static int lastProtocolDataIndex;
void setupUiExtra(); void setupUiExtra();
bool isCurrentStreamValid();
void LoadCurrentStream(); void LoadCurrentStream();
void StoreCurrentStream(); void StoreCurrentStream();
void loadProtocolWidgets(); void loadProtocolWidgets();