forked from osmocom/wireshark
Qt: Improve UIX for sparklines
Sparklines should display to the user, which interfaces are active and ready for capture. Additionally it should be easy to find active interfaces, without filtering first. This change reorders the interface list, in order to sort active interfaces on top, as well as hide information if no packet has been received on that interface, to ensure that the user can find active interfaces faster, making it easier to capture on systems where the interfaces have very generic names. The interface context menu has been amended to allow interfaces to be hidden/unhidden from the main interface list as well
This commit is contained in:
parent
49ec7da90e
commit
1278af07c3
|
@ -109,6 +109,9 @@ They previously shipped with Npcap 1.55.
|
|||
|
||||
* ZigBee ZCL Messaging: rename zbee_zcl_se.msg.msg_ctrl.depreciated to zbee_zcl_se.msg.msg_ctrl.deprecated
|
||||
|
||||
* The interface list on the welcome page sorts active interfaces first and only displays the sparkline for active interfaces.
|
||||
Additionally, the interfaces can now be hidden/unhidden via the context menu in the interface list
|
||||
|
||||
=== Removed Features and Support
|
||||
|
||||
* CMake: The options starting with DISABLE_something were renamed ENABLE_something for consistency.
|
||||
|
|
|
@ -793,7 +793,8 @@ void CaptureOptionsDialog::updateInterfaces()
|
|||
|
||||
ti->setText(col_interface_, device->display_name);
|
||||
ti->setData(col_interface_, Qt::UserRole, QString(device->name));
|
||||
ti->setData(col_traffic_, Qt::UserRole, QVariant::fromValue(ti->points));
|
||||
if (device->if_info.type != IF_EXTCAP)
|
||||
ti->setData(col_traffic_, Qt::UserRole, QVariant::fromValue(ti->points));
|
||||
|
||||
if (device->no_addresses > 0) {
|
||||
QString addr_str = tr("%1: %2").arg(device->no_addresses > 1 ? tr("Addresses") : tr("Address")).arg(device->addresses);
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "extcap.h"
|
||||
|
||||
#include <ui/recent.h>
|
||||
#include "capture_opts.h"
|
||||
#include "ui/capture_globals.h"
|
||||
#include <wsutil/utf8_entities.h>
|
||||
|
||||
#include <QDesktopServices>
|
||||
|
@ -100,6 +102,7 @@ InterfaceFrame::InterfaceFrame(QWidget * parent)
|
|||
info_model_.setColumn(static_cast<int>(columns.indexOf(IFTREE_COL_STATS)));
|
||||
|
||||
ui->interfaceTree->setModel(&info_model_);
|
||||
ui->interfaceTree->setSortingEnabled(true);
|
||||
|
||||
ui->interfaceTree->setItemDelegateForColumn(proxy_model_.mapSourceToColumn(IFTREE_COL_STATS), new SparkLineDelegate(this));
|
||||
|
||||
|
@ -247,6 +250,7 @@ void InterfaceFrame::interfaceListChanged()
|
|||
|
||||
void InterfaceFrame::toggleHiddenInterfaces()
|
||||
{
|
||||
source_model_.interfaceListChanged();
|
||||
proxy_model_.toggleFilterHidden();
|
||||
|
||||
emit typeSelectionChanged();
|
||||
|
@ -475,7 +479,6 @@ void InterfaceFrame::updateStatistics(void)
|
|||
if (selectIndex.isValid())
|
||||
source_model_.updateStatistic(idx);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -509,6 +512,21 @@ void InterfaceFrame::showContextMenu(QPoint pos)
|
|||
|
||||
startCapture(ifaces);
|
||||
});
|
||||
|
||||
ctx_menu.addSeparator();
|
||||
|
||||
QModelIndex actIndex = ui->interfaceTree->indexAt(pos);
|
||||
QModelIndex realIndex = proxy_model_.mapToSource(info_model_.mapToSource(actIndex));
|
||||
bool isHidden = realIndex.sibling(realIndex.row(), IFTREE_COL_HIDDEN).data(Qt::UserRole).toBool();
|
||||
QAction * hideAction = ctx_menu.addAction(tr("Hide Interface"), this, [=] () {
|
||||
/* Attention! Only realIndex.row is a 1:1 correlation to all_ifaces */
|
||||
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, realIndex.row());
|
||||
device->hidden = ! device->hidden;
|
||||
mainApp->emitAppSignal(MainApplication::LocalInterfacesChanged);
|
||||
});
|
||||
hideAction->setCheckable(true);
|
||||
hideAction->setChecked(isHidden);
|
||||
|
||||
ctx_menu.exec(ui->interfaceTree->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
|
|
|
@ -369,3 +369,15 @@ QString InterfaceSortFilterModel::interfaceError()
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InterfaceSortFilterModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||
{
|
||||
bool leftActive = source_left.sibling(source_left.row(), InterfaceTreeColumns::IFTREE_COL_ACTIVE).data(Qt::UserRole).toBool();
|
||||
bool rightActive = source_right.sibling(source_right.row(), InterfaceTreeColumns::IFTREE_COL_ACTIVE).data(Qt::UserRole).toBool();
|
||||
|
||||
if (rightActive && ! leftActive)
|
||||
return true;
|
||||
|
||||
return QSortFilterProxyModel::lessThan(source_left, source_right);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
protected:
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const;
|
||||
bool filterAcceptsColumn(int source_column, const QModelIndex & source_parent) const;
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
|
||||
|
||||
private:
|
||||
bool _filterHidden;
|
||||
|
|
|
@ -227,9 +227,14 @@ QVariant InterfaceTreeModel::data(const QModelIndex &index, int role) const
|
|||
{
|
||||
if (col == IFTREE_COL_STATS)
|
||||
{
|
||||
if (points.contains(device->name))
|
||||
if ((active.contains(device->name) && active[device->name]) && points.contains(device->name))
|
||||
return QVariant::fromValue(points[device->name]);
|
||||
}
|
||||
else if (col == IFTREE_COL_ACTIVE)
|
||||
{
|
||||
if (active.contains(device->name))
|
||||
return QVariant::fromValue(active[device->name]);
|
||||
}
|
||||
else if (col == IFTREE_COL_HIDDEN)
|
||||
{
|
||||
return QVariant::fromValue((bool)device->hidden);
|
||||
|
@ -354,6 +359,7 @@ void InterfaceTreeModel::interfaceListChanged()
|
|||
emit beginResetModel();
|
||||
|
||||
points.clear();
|
||||
active.clear();
|
||||
|
||||
emit endResetModel();
|
||||
}
|
||||
|
@ -439,9 +445,13 @@ void InterfaceTreeModel::updateStatistic(unsigned int idx)
|
|||
|
||||
struct pcap_stat stats;
|
||||
unsigned diff = 0;
|
||||
bool isActive = false;
|
||||
|
||||
if (capture_stats(stat_cache_, device->name, &stats))
|
||||
{
|
||||
if ( (int) stats.ps_recv > 0 )
|
||||
isActive = true;
|
||||
|
||||
if ((int)(stats.ps_recv - device->last_packets) >= 0)
|
||||
{
|
||||
diff = stats.ps_recv - device->last_packets;
|
||||
|
@ -451,7 +461,16 @@ void InterfaceTreeModel::updateStatistic(unsigned int idx)
|
|||
}
|
||||
|
||||
points[device->name].append(diff);
|
||||
|
||||
if (active[device->name] != isActive)
|
||||
{
|
||||
emit beginResetModel();
|
||||
active[device->name] = isActive;
|
||||
emit endResetModel();
|
||||
}
|
||||
|
||||
emit dataChanged(index(idx, IFTREE_COL_STATS), index(idx, IFTREE_COL_STATS));
|
||||
|
||||
#else
|
||||
Q_UNUSED(idx)
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,7 @@ enum InterfaceTreeColumns
|
|||
IFTREE_COL_PROMISCUOUSMODE,
|
||||
IFTREE_COL_TYPE,
|
||||
IFTREE_COL_STATS,
|
||||
IFTREE_COL_ACTIVE,
|
||||
IFTREE_COL_SNAPLEN,
|
||||
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
|
||||
IFTREE_COL_BUFFERLEN,
|
||||
|
@ -85,13 +86,12 @@ public:
|
|||
|
||||
public slots:
|
||||
void getPoints(int idx, PointList *pts);
|
||||
|
||||
protected slots:
|
||||
void interfaceListChanged();
|
||||
|
||||
private:
|
||||
QVariant toolTipForInterface(int idx) const;
|
||||
QMap<QString, PointList> points;
|
||||
QMap<QString, bool> active;
|
||||
|
||||
#ifdef HAVE_LIBPCAP
|
||||
if_stat_cache_t *stat_cache_;
|
||||
|
|
Loading…
Reference in New Issue