Replace Port Stats Link/Tx/Capture state text with icons
* All 3 icons are combined into a single row instead of 3 separate rows * Tooltip to clarify meaning of icons * Qt Model-View displays icon left-aligned, so use a custom delegate to center-align it * Add a icon for "Transmit On" * Edit icons for "Start/Stop Capture"
This commit is contained in:
parent
48721cece4
commit
496e044bdd
40
client/icononlydelegate.h
Normal file
40
client/icononlydelegate.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright (C) 2018 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 _ICON_ONLY_DELEGATE
|
||||
#define _ICON_ONLY_DELEGATE
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
class IconOnlyDelegate : public QStyledItemDelegate
|
||||
{
|
||||
using QStyledItemDelegate::QStyledItemDelegate;
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
opt.decorationPosition = QStyleOptionViewItem::Top;
|
||||
opt.features.setFlag(QStyleOptionViewItem::HasDisplay, false);
|
||||
QStyledItemDelegate::paint(painter, opt, index);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 514 B |
Binary file not shown.
Before Width: | Height: | Size: 417 B After Width: | Height: | Size: 435 B |
BIN
client/icons/transmit_on.png
Normal file
BIN
client/icons/transmit_on.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 749 B |
@ -1,48 +1,49 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>icons/about.png</file>
|
||||
<file>icons/add.png</file>
|
||||
<file>icons/arrow_down.png</file>
|
||||
<file>icons/arrow_left.png</file>
|
||||
<file>icons/arrow_right.png</file>
|
||||
<file>icons/arrow_up.png</file>
|
||||
<file>icons/bullet_error.png</file>
|
||||
<file>icons/bullet_green.png</file>
|
||||
<file>icons/bullet_orange.png</file>
|
||||
<file>icons/bullet_red.png</file>
|
||||
<file>icons/bullet_white.png</file>
|
||||
<file>icons/bullet_yellow.png</file>
|
||||
<file>icons/control_play.png</file>
|
||||
<file>icons/control_stop.png</file>
|
||||
<file>icons/deco_exclusive.png</file>
|
||||
<file>icons/delete.png</file>
|
||||
<file>icons/devicegroup_add.png</file>
|
||||
<file>icons/devicegroup_delete.png</file>
|
||||
<file>icons/devicegroup_edit.png</file>
|
||||
<file>icons/exit.png</file>
|
||||
<file>icons/gaps.png</file>
|
||||
<file>icons/help.png</file>
|
||||
<file>icons/logo.png</file>
|
||||
<file>icons/magnifier.png</file>
|
||||
<file>icons/name.png</file>
|
||||
<file>icons/neighbor_clear.png</file>
|
||||
<file>icons/neighbor_resolve.png</file>
|
||||
<file>icons/portgroup_add.png</file>
|
||||
<file>icons/portgroup_connect.png</file>
|
||||
<file>icons/portgroup_delete.png</file>
|
||||
<file>icons/portgroup_disconnect.png</file>
|
||||
<file>icons/portstats_clear.png</file>
|
||||
<file>icons/portstats_clear_all.png</file>
|
||||
<file>icons/portstats_filter.png</file>
|
||||
<file>icons/preferences.png</file>
|
||||
<file>icons/qt.png</file>
|
||||
<file>icons/refresh.png</file>
|
||||
<file>icons/sound_mute.png</file>
|
||||
<file>icons/sound_none.png</file>
|
||||
<file>icons/stream_add.png</file>
|
||||
<file>icons/stream_delete.png</file>
|
||||
<file>icons/stream_duplicate.png</file>
|
||||
<file>icons/stream_edit.png</file>
|
||||
<file>icons/stream_stats.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/">
|
||||
<file>icons/transmit_on.png</file>
|
||||
<file>icons/about.png</file>
|
||||
<file>icons/add.png</file>
|
||||
<file>icons/arrow_down.png</file>
|
||||
<file>icons/arrow_left.png</file>
|
||||
<file>icons/arrow_right.png</file>
|
||||
<file>icons/arrow_up.png</file>
|
||||
<file>icons/bullet_error.png</file>
|
||||
<file>icons/bullet_green.png</file>
|
||||
<file>icons/bullet_orange.png</file>
|
||||
<file>icons/bullet_red.png</file>
|
||||
<file>icons/bullet_white.png</file>
|
||||
<file>icons/bullet_yellow.png</file>
|
||||
<file>icons/control_play.png</file>
|
||||
<file>icons/control_stop.png</file>
|
||||
<file>icons/deco_exclusive.png</file>
|
||||
<file>icons/delete.png</file>
|
||||
<file>icons/devicegroup_add.png</file>
|
||||
<file>icons/devicegroup_delete.png</file>
|
||||
<file>icons/devicegroup_edit.png</file>
|
||||
<file>icons/exit.png</file>
|
||||
<file>icons/gaps.png</file>
|
||||
<file>icons/help.png</file>
|
||||
<file>icons/logo.png</file>
|
||||
<file>icons/magnifier.png</file>
|
||||
<file>icons/name.png</file>
|
||||
<file>icons/neighbor_clear.png</file>
|
||||
<file>icons/neighbor_resolve.png</file>
|
||||
<file>icons/portgroup_add.png</file>
|
||||
<file>icons/portgroup_connect.png</file>
|
||||
<file>icons/portgroup_delete.png</file>
|
||||
<file>icons/portgroup_disconnect.png</file>
|
||||
<file>icons/portstats_clear.png</file>
|
||||
<file>icons/portstats_clear_all.png</file>
|
||||
<file>icons/portstats_filter.png</file>
|
||||
<file>icons/preferences.png</file>
|
||||
<file>icons/qt.png</file>
|
||||
<file>icons/refresh.png</file>
|
||||
<file>icons/sound_mute.png</file>
|
||||
<file>icons/sound_none.png</file>
|
||||
<file>icons/stream_add.png</file>
|
||||
<file>icons/stream_delete.png</file>
|
||||
<file>icons/stream_duplicate.png</file>
|
||||
<file>icons/stream_edit.png</file>
|
||||
<file>icons/stream_stats.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -20,6 +20,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#include "portstatsmodel.h"
|
||||
#include "portgrouplist.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPixmapCache>
|
||||
#include <QTimer>
|
||||
|
||||
enum {
|
||||
@ -94,15 +96,12 @@ void PortStatsModel::getDomainIndexes(const QModelIndex &index,
|
||||
|
||||
QVariant PortStatsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
uint pgidx, pidx;
|
||||
int row;
|
||||
|
||||
// Check for a valid index
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
// Check for row/column limits
|
||||
row = index.row();
|
||||
int row = index.row();
|
||||
if (row >= e_STAT_MAX)
|
||||
return QVariant();
|
||||
|
||||
@ -112,15 +111,22 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const
|
||||
if (index.column() >= (numPorts.last()))
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::TextAlignmentRole)
|
||||
{
|
||||
if (row >= e_STATISTICS_START && row <= e_STATISTICS_END)
|
||||
return Qt::AlignRight; // right-align numbers
|
||||
else
|
||||
return Qt::AlignHCenter; // center-align everything else
|
||||
}
|
||||
|
||||
uint pgidx, pidx;
|
||||
getDomainIndexes(index, pgidx, pidx);
|
||||
|
||||
OstProto::PortStats stats = pgl->mPortGroups.at(pgidx)
|
||||
->mPorts[pidx]->getStats();
|
||||
// Check role
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
OstProto::PortStats stats;
|
||||
|
||||
stats = pgl->mPortGroups.at(pgidx)->mPorts[pidx]->getStats();
|
||||
|
||||
switch(row)
|
||||
{
|
||||
// Info
|
||||
@ -128,14 +134,8 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const
|
||||
return pgl->mPortGroups.at(pgidx)->mPorts[pidx]->userName();
|
||||
|
||||
// States
|
||||
case e_LINK_STATE:
|
||||
return LinkStateName.at(stats.state().link_state());
|
||||
|
||||
case e_TRANSMIT_STATE:
|
||||
return BoolStateName.at(stats.state().is_transmit_on());
|
||||
|
||||
case e_CAPTURE_STATE:
|
||||
return BoolStateName.at(stats.state().is_capture_on());
|
||||
case e_COMBO_STATE:
|
||||
return QVariant();
|
||||
|
||||
// Statistics
|
||||
case e_STAT_FRAMES_RCVD:
|
||||
@ -201,12 +201,26 @@ QVariant PortStatsModel::data(const QModelIndex &index, int role) const
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (role == Qt::TextAlignmentRole)
|
||||
else if (role == Qt::DecorationRole)
|
||||
{
|
||||
if (row >= e_STATISTICS_START && row <= e_STATISTICS_END)
|
||||
return Qt::AlignRight; // right-align numbers
|
||||
if (row == e_COMBO_STATE)
|
||||
return statusIcons(
|
||||
stats.state().link_state(),
|
||||
stats.state().is_transmit_on(),
|
||||
stats.state().is_capture_on());
|
||||
else
|
||||
return Qt::AlignHCenter; // center-align everything else
|
||||
return QVariant();
|
||||
}
|
||||
else if (role == Qt::ToolTipRole)
|
||||
{
|
||||
if (row == e_COMBO_STATE)
|
||||
return QString("Transmit:<b><i>%1</i></b> Link:<b><i>%2</i></b> "
|
||||
"Capture:<b><i>%3</i></b>")
|
||||
.arg(BoolStateName.at(stats.state().is_transmit_on()))
|
||||
.arg(LinkStateName.at(stats.state().link_state()))
|
||||
.arg(BoolStateName.at(stats.state().is_capture_on()));
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
else
|
||||
return QVariant();
|
||||
@ -351,3 +365,49 @@ void PortStatsModel::when_portGroup_stats_update(quint32 /*portGroupId*/)
|
||||
|
||||
emit dataChanged(topLeft, bottomRight);
|
||||
}
|
||||
|
||||
QPixmap PortStatsModel::statusIcons(
|
||||
int linkState, bool transmit, bool capture) const
|
||||
{
|
||||
QPixmap pixmap;
|
||||
QString key = QString("$ost:statusList:%1:%2:%3")
|
||||
.arg(linkState).arg(transmit).arg(capture);
|
||||
|
||||
if (QPixmapCache::find(key, pixmap))
|
||||
return pixmap;
|
||||
|
||||
static int sz = QPixmap(":/icons/transmit_on.png").width();
|
||||
|
||||
// Assume all icons are of same size and are square
|
||||
QPixmap blank(sz, sz);
|
||||
blank.fill(Qt::transparent);
|
||||
|
||||
pixmap = QPixmap(sz*3, sz);
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
QPainter painter(&pixmap);
|
||||
|
||||
painter.drawPixmap(0, 0,
|
||||
transmit ? QPixmap(":/icons/transmit_on.png") : blank);
|
||||
|
||||
switch (linkState) {
|
||||
case OstProto::LinkStateUp:
|
||||
painter.drawPixmap(sz, 0, QPixmap(":/icons/bullet_green.png"));
|
||||
break;
|
||||
case OstProto::LinkStateDown:
|
||||
painter.drawPixmap(sz, 0, QPixmap(":/icons/bullet_red.png"));
|
||||
break;
|
||||
case OstProto::LinkStateUnknown:
|
||||
painter.drawPixmap(sz, 0, QPixmap(":/icons/bullet_white.png"));
|
||||
break;
|
||||
default:
|
||||
painter.drawPixmap(sz, 0, blank);
|
||||
}
|
||||
|
||||
painter.drawPixmap(sz*2, 0,
|
||||
capture ? QPixmap(":/icons/sound_none.png") : blank);
|
||||
|
||||
|
||||
QPixmapCache::insert(key, pixmap);
|
||||
return pixmap;
|
||||
}
|
||||
|
@ -36,11 +36,9 @@ typedef enum {
|
||||
// State
|
||||
e_STATE_START,
|
||||
|
||||
e_LINK_STATE = e_STATE_START,
|
||||
e_TRANSMIT_STATE,
|
||||
e_CAPTURE_STATE,
|
||||
e_COMBO_STATE = e_STATE_START,
|
||||
|
||||
e_STATE_END = e_CAPTURE_STATE,
|
||||
e_STATE_END = e_COMBO_STATE,
|
||||
|
||||
// Statistics
|
||||
e_STATISTICS_START,
|
||||
@ -77,9 +75,7 @@ typedef enum {
|
||||
static QStringList PortStatName = (QStringList()
|
||||
<< "User"
|
||||
|
||||
<< "Link State"
|
||||
<< "Transmit State"
|
||||
<< "Capture State"
|
||||
<< "Status"
|
||||
|
||||
<< "Frames Received"
|
||||
<< "Frames Sent"
|
||||
@ -160,6 +156,7 @@ class PortStatsModel : public QAbstractTableModel
|
||||
|
||||
void getDomainIndexes(const QModelIndex &index,
|
||||
uint &portGroupIdx, uint &portIdx) const;
|
||||
QPixmap statusIcons(int linkState, bool transmit, bool capture) const;
|
||||
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,7 @@ 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"
|
||||
@ -53,6 +54,24 @@ PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
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(
|
||||
@ -65,6 +84,7 @@ PortStatsWindow::PortStatsWindow(PortGroupList *pgl, QWidget *parent)
|
||||
PortStatsWindow::~PortStatsWindow()
|
||||
{
|
||||
delete proxyStatsModel;
|
||||
delete statusDelegate;
|
||||
}
|
||||
|
||||
/* ------------- SLOTS (public) -------------- */
|
||||
|
@ -27,6 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#include "portstatsmodel.h"
|
||||
|
||||
class QSortFilterProxyModel;
|
||||
class QStyledItemDelegate;
|
||||
|
||||
class PortStatsWindow : public QWidget, public Ui::PortStatsWindow
|
||||
{
|
||||
@ -63,6 +64,7 @@ private:
|
||||
PortGroupList *pgl;
|
||||
PortStatsModel *model;
|
||||
QSortFilterProxyModel *proxyStatsModel;
|
||||
QStyledItemDelegate *statusDelegate;
|
||||
QModelIndexList selectedColumns;
|
||||
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user