ostinato/client/portstatswindow.cpp
Srivats P 1e1e0b0c48 Clear current and selection when restoring default view
This is done for all top level windows - ports, stats, logs

At startup, the local portgroup would automatically become current with
the result that the welcome page would not be visible. Not sure why but
an explicit setFocus of ports window seems to avoid it.
2020-05-07 18:40:31 +05:30

385 lines
12 KiB
C++

/*
Copyright (C) 2010 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 "portstatswindow.h"
#include "icononlydelegate.h"
#include "portstatsfilterdialog.h"
#include "portstatsmodel.h"
#include "portstatsproxymodel.h"
#include "streamstatsmodel.h"
#include "streamstatswindow.h"
#include "settings.h"
#include <QDockWidget>
#include <QHeaderView>
#include <QMainWindow>
extern QMainWindow *mainWindow;
PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent)
: QWidget(parent), proxyStatsModel(NULL)
{
setupUi(this);
this->pgl = pgl;
model = pgl->getPortStatsModel();
proxyStatsModel = new PortStatsProxyModel(this);
if (proxyStatsModel) {
proxyStatsModel->setSourceModel(model);
tvPortStats->setModel(proxyStatsModel);
}
else
tvPortStats->setModel(model);
tvPortStats->setAlternatingRowColors(true);
tvPortStats->verticalHeader()->setHighlightSections(false);
tvPortStats->verticalHeader()->setDefaultSectionSize(
tvPortStats->verticalHeader()->minimumSectionSize());
statusDelegate = new IconOnlyDelegate(this);
#if 0
// XXX: Ideally we should use this, but it doesn't work because in
// this constructor, the port model is empty and model->index() returns
// an invalid index ...
tvPortStats->setItemDelegateForRow(
proxyStatsModel ?
proxyStatsModel->mapFromSource(model->index(e_COMBO_STATE, 0))
.row() :
e_COMBO_STATE,
statusDelegate);
#else
// ... so we use this hard-coded hack
tvPortStats->setItemDelegateForRow(
proxyStatsModel ? e_COMBO_STATE-1 : e_COMBO_STATE,
statusDelegate);
#endif
connect(tvPortStats->selectionModel(),
SIGNAL(selectionChanged(
const QItemSelection&, const QItemSelection&)),
SLOT(when_tvPortStats_selectionChanged(
const QItemSelection&, const QItemSelection&)));
when_tvPortStats_selectionChanged(QItemSelection(), QItemSelection());
}
PortStatsWindow::~PortStatsWindow()
{
delete proxyStatsModel;
delete statusDelegate;
}
/* ------------- SLOTS (public) -------------- */
void PortStatsWindow::clearCurrentSelection()
{
tvPortStats->selectionModel()->clearCurrentIndex();
tvPortStats->clearSelection();
}
void PortStatsWindow::showMyReservedPortsOnly(bool enabled)
{
if (!proxyStatsModel)
return;
if (enabled) {
QString rx(appSettings->value(kUserKey, kUserDefaultValue).toString());
proxyStatsModel->setFilterRegExp(QRegExp::escape(rx));
}
else
proxyStatsModel->setFilterRegExp(QRegExp(".*")); // match all
}
/* ------------- SLOTS (private) -------------- */
void PortStatsWindow::when_tvPortStats_selectionChanged(
const QItemSelection& /*selected*/,
const QItemSelection& /*deselected*/)
{
QModelIndexList indexList =
tvPortStats->selectionModel()->selectedColumns();
if (proxyStatsModel) {
selectedColumns.clear();
foreach(QModelIndex index, indexList)
selectedColumns.append(proxyStatsModel->mapToSource(index));
}
else
selectedColumns = indexList;
bool isEmpty = selectedColumns.isEmpty();
tbStartTransmit->setDisabled(isEmpty);
tbStopTransmit->setDisabled(isEmpty);
tbStartCapture->setDisabled(isEmpty);
tbStopCapture->setDisabled(isEmpty);
tbViewCapture->setDisabled(isEmpty);
tbClear->setDisabled(isEmpty);
tbGetStreamStats->setDisabled(isEmpty);
tbResolveNeighbors->setDisabled(isEmpty);
tbClearNeighbors->setDisabled(isEmpty);
}
void PortStatsWindow::on_tbStartTransmit_clicked()
{
QList<PortStatsModel::PortGroupAndPortList> pgpl;
// Get selected ports
model->portListFromIndex(selectedColumns, pgpl);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < pgpl.size(); i++)
{
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
startTx(&pgpl[i].portList);
}
}
void PortStatsWindow::on_tbStopTransmit_clicked()
{
QList<PortStatsModel::PortGroupAndPortList> pgpl;
// Get selected ports
model->portListFromIndex(selectedColumns, pgpl);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < pgpl.size(); i++)
{
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
stopTx(&pgpl[i].portList);
}
}
void PortStatsWindow::on_tbStartCapture_clicked()
{
// TODO(MED)
QList<PortStatsModel::PortGroupAndPortList> pgpl;
// Get selected ports
model->portListFromIndex(selectedColumns, pgpl);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < pgpl.size(); i++)
{
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
startCapture(&pgpl[i].portList);
}
}
void PortStatsWindow::on_tbStopCapture_clicked()
{
// TODO(MED)
QList<PortStatsModel::PortGroupAndPortList> pgpl;
// Get selected ports
model->portListFromIndex(selectedColumns, pgpl);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < pgpl.size(); i++)
{
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
stopCapture(&pgpl[i].portList);
}
}
void PortStatsWindow::on_tbViewCapture_clicked()
{
// TODO(MED)
QList<PortStatsModel::PortGroupAndPortList> pgpl;
// Get selected ports
model->portListFromIndex(selectedColumns, pgpl);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < pgpl.size(); i++)
{
pgl->portGroupByIndex(pgpl.at(i).portGroupId).
viewCapture(&pgpl[i].portList);
}
}
void PortStatsWindow::on_tbResolveNeighbors_clicked()
{
QList<PortStatsModel::PortGroupAndPortList> portList;
// Get selected ports
model->portListFromIndex(selectedColumns, portList);
// Resolve ARP/ND for selected ports, portgroup by portgroup
for (int i = 0; i < portList.size(); i++)
{
pgl->portGroupByIndex(portList.at(i).portGroupId).
resolveDeviceNeighbors(&portList[i].portList);
// Update device info for the just processed portgroup
for (int j = 0; j < portList[i].portList.size(); j++)
{
pgl->portGroupByIndex(portList.at(i).portGroupId).
getDeviceInfo(portList[i].portList[j]);
}
}
}
void PortStatsWindow::on_tbClearNeighbors_clicked()
{
QList<PortStatsModel::PortGroupAndPortList> portList;
// Get selected ports
model->portListFromIndex(selectedColumns, portList);
// Clear ARP/ND for ports, portgroup by portgroup
for (int i = 0; i < portList.size(); i++)
{
pgl->portGroupByIndex(portList.at(i).portGroupId).
clearDeviceNeighbors(&portList[i].portList);
// Update device info for the just processed portgroup
for (int j = 0; j < portList[i].portList.size(); j++)
{
pgl->portGroupByIndex(portList.at(i).portGroupId).
getDeviceInfo(portList[i].portList[j]);
}
}
}
void PortStatsWindow::on_tbClear_clicked()
{
QList<PortStatsModel::PortGroupAndPortList> portList;
// Get selected ports
model->portListFromIndex(selectedColumns, portList);
// Clear selected ports, portgroup by portgroup
for (int i = 0; i < portList.size(); i++)
{
pgl->portGroupByIndex(portList.at(i).portGroupId).
clearPortStats(&portList[i].portList);
pgl->portGroupByIndex(portList.at(i).portGroupId).
clearStreamStats(&portList[i].portList);
}
}
// 'All' => all ports currently visible, not all ports in all portgroups
void PortStatsWindow::on_tbClearAll_clicked()
{
QAbstractItemModel *mdl = tvPortStats->model();
QModelIndexList shownColumns;
QList<PortStatsModel::PortGroupAndPortList> portList;
// Find the 'visible' columns
for(int vi = 0; vi < mdl->columnCount(); vi++) {
int li = tvPortStats->horizontalHeader()->logicalIndex(vi);
if (!tvPortStats->isColumnHidden(li)) {
shownColumns.append(mdl->index(0, li));
}
}
if (proxyStatsModel) {
for(QModelIndex &index : shownColumns)
index = proxyStatsModel->mapToSource(index);
}
// Get ports corresponding to the shown columns
model->portListFromIndex(shownColumns, portList);
// Clear shown ports, portgroup by portgroup
for (int i = 0; i < portList.size(); i++)
{
pgl->portGroupByIndex(portList.at(i).portGroupId)
.clearPortStats(&portList[i].portList);
pgl->portGroupByIndex(portList.at(i).portGroupId)
.clearStreamStats(&portList[i].portList);
}
}
void PortStatsWindow::on_tbGetStreamStats_clicked()
{
QList<PortStatsModel::PortGroupAndPortList> portList;
StreamStatsModel *streamStatsModel;
// Get selected ports
model->portListFromIndex(selectedColumns, portList);
if (portList.size()) {
QDockWidget *dock = new QDockWidget(mainWindow);
streamStatsModel = new StreamStatsModel(dock);
dock->setWidget(new StreamStatsWindow(streamStatsModel, dock));
dock->setWindowTitle(dock->widget()->windowTitle());
dock->setObjectName("streamStatsDock");
dock->setAttribute(Qt::WA_DeleteOnClose);
QDockWidget *statsDock = mainWindow->findChild<QDockWidget*>(
"statsDock");
mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dock);
mainWindow->tabifyDockWidget(statsDock, dock);
dock->show();
dock->raise();
}
// Get stream stats for selected ports, portgroup by portgroup
for (int i = 0; i < portList.size(); i++)
{
PortGroup &pg = pgl->portGroupByIndex(portList.at(i).portGroupId);
if (pg.getStreamStats(&portList[i].portList)) {
connect(&pg,SIGNAL(streamStatsReceived(
quint32, const OstProto::StreamStatsList*)),
streamStatsModel, SLOT(appendStreamStatsList(
quint32, const OstProto::StreamStatsList*)));
}
}
}
void PortStatsWindow::on_tbFilter_clicked()
{
bool ok;
QList<uint> currentColumns, newColumns;
PortStatsFilterDialog dialog;
QAbstractItemModel *mdl = tvPortStats->model();
// create the input list for the filter dialog -
// list of logical-indexes ordered by their current visual indexes
for(int vi = 0; vi < mdl->columnCount(); vi++) {
int li = tvPortStats->horizontalHeader()->logicalIndex(vi);
if (!tvPortStats->isColumnHidden(li)) {
currentColumns.append(li);
}
}
// return list from the filter dialog -
// list of logical-indexes ordered by their new visual indexes
newColumns = dialog.getItemList(&ok, mdl, Qt::Horizontal, currentColumns);
if (ok)
{
QHeaderView *hv = tvPortStats->horizontalHeader();
// hide/show sections first ...
for(int li = 0; li < mdl->columnCount(); li++)
tvPortStats->setColumnHidden(li, !newColumns.contains(li));
// ... then for the 'shown' columns, set the visual index
for(int vi = 0; vi < newColumns.size(); vi++)
hv->moveSection(hv->visualIndex(newColumns.at(vi)), vi);
}
}