2016-10-01 06:54:57 +00:00
/* interface_frame.cpp
* Display of interfaces , including their respective data , and the
* capability to filter interfaces by type
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 1998 Gerald Combs
*
2018-04-30 07:47:58 +00:00
* SPDX - License - Identifier : GPL - 2.0 - or - later
*/
2016-10-01 06:54:57 +00:00
# include "config.h"
# include <ui_interface_frame.h>
2017-04-25 20:43:32 +00:00
# include "caputils/capture_ifinfo.h"
2018-12-12 00:26:51 +00:00
2020-01-09 20:47:45 +00:00
# ifdef Q_OS_WIN
# include "caputils/capture-wpcap.h"
# endif
2016-10-01 06:54:57 +00:00
# include "ui/qt/interface_frame.h"
2018-12-12 00:26:51 +00:00
# include <ui/qt/wireshark_application.h>
2016-10-01 06:54:57 +00:00
2018-12-12 00:26:51 +00:00
# include <ui/qt/models/interface_tree_model.h>
2017-07-25 14:47:16 +00:00
# include <ui/qt/models/sparkline_delegate.h>
2018-12-12 00:26:51 +00:00
# include <ui/qt/utils/tango_colors.h>
2016-10-01 06:54:57 +00:00
# include "extcap.h"
2018-12-12 00:26:51 +00:00
# include <wsutil/utf8_entities.h>
2016-10-01 06:54:57 +00:00
# include <QFrame>
# include <QPushButton>
# include <QHBoxLayout>
# include <QLabel>
# include <QItemSelection>
2018-01-12 20:16:11 +00:00
# include <epan/prefs.h>
2016-10-01 06:54:57 +00:00
# define BTN_IFTYPE_PROPERTY "ifType"
# ifdef HAVE_LIBPCAP
const int stat_update_interval_ = 1000 ; // ms
# endif
InterfaceFrame : : InterfaceFrame ( QWidget * parent )
2017-11-23 12:34:19 +00:00
: QFrame ( parent ) ,
2016-10-01 06:54:57 +00:00
ui ( new Ui : : InterfaceFrame )
2018-12-12 00:26:51 +00:00
, proxy_model_ ( Q_NULLPTR )
, source_model_ ( Q_NULLPTR )
, info_model_ ( this )
2016-10-01 06:54:57 +00:00
# ifdef HAVE_LIBPCAP
, stat_timer_ ( NULL )
# endif // HAVE_LIBPCAP
{
ui - > setupUi ( this ) ;
setStyleSheet ( QString (
" QFrame { "
" border: 0; "
" } "
" QTreeView { "
" border: 0; "
" } "
2018-12-12 00:26:51 +00:00
" QLabel { "
" border-radius: 0.5em; "
" padding: 0.33em; "
" margin-bottom: 0.25em; "
// We might want to transition this to normal colors this after a timeout.
" color: #%1; "
" background-color: #%2; "
" } "
)
. arg ( ws_css_warn_text , 6 , 16 , QChar ( ' 0 ' ) )
. arg ( ws_css_warn_background , 6 , 16 , QChar ( ' 0 ' ) ) ) ;
ui - > warningLabel - > hide ( ) ;
2016-10-01 06:54:57 +00:00
# ifdef Q_OS_MAC
ui - > interfaceTree - > setAttribute ( Qt : : WA_MacShowFocusRect , false ) ;
# endif
/* TODO: There must be a better way to do this */
2016-10-17 09:57:00 +00:00
ifTypeDescription . insert ( IF_WIRED , tr ( " Wired " ) ) ;
2016-10-01 06:54:57 +00:00
ifTypeDescription . insert ( IF_AIRPCAP , tr ( " AirPCAP " ) ) ;
ifTypeDescription . insert ( IF_PIPE , tr ( " Pipe " ) ) ;
ifTypeDescription . insert ( IF_STDIN , tr ( " STDIN " ) ) ;
ifTypeDescription . insert ( IF_BLUETOOTH , tr ( " Bluetooth " ) ) ;
ifTypeDescription . insert ( IF_WIRELESS , tr ( " Wireless " ) ) ;
ifTypeDescription . insert ( IF_DIALUP , tr ( " Dial-Up " ) ) ;
ifTypeDescription . insert ( IF_USB , tr ( " USB " ) ) ;
ifTypeDescription . insert ( IF_EXTCAP , tr ( " External Capture " ) ) ;
ifTypeDescription . insert ( IF_VIRTUAL , tr ( " Virtual " ) ) ;
2016-10-03 14:31:36 +00:00
QList < InterfaceTreeColumns > columns ;
columns . append ( IFTREE_COL_EXTCAP ) ;
2018-08-12 01:55:01 +00:00
columns . append ( IFTREE_COL_DISPLAY_NAME ) ;
2016-10-03 14:31:36 +00:00
columns . append ( IFTREE_COL_STATS ) ;
2018-12-12 00:26:51 +00:00
proxy_model_ . setColumns ( columns ) ;
proxy_model_ . setStoreOnChange ( true ) ;
proxy_model_ . setSourceModel ( & source_model_ ) ;
2018-01-12 12:15:58 +00:00
2018-12-12 00:26:51 +00:00
info_model_ . setSourceModel ( & proxy_model_ ) ;
info_model_ . setColumn ( columns . indexOf ( IFTREE_COL_STATS ) ) ;
2016-10-01 06:54:57 +00:00
2018-12-12 00:26:51 +00:00
ui - > interfaceTree - > setModel ( & info_model_ ) ;
ui - > interfaceTree - > setItemDelegateForColumn ( proxy_model_ . mapSourceToColumn ( IFTREE_COL_STATS ) , new SparkLineDelegate ( this ) ) ;
2016-10-01 06:54:57 +00:00
2019-07-30 07:48:56 +00:00
ui - > interfaceTree - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
connect ( ui - > interfaceTree , SIGNAL ( customContextMenuRequested ( QPoint ) ) , this , SLOT ( showContextMenu ( QPoint ) ) ) ;
2016-10-01 06:54:57 +00:00
connect ( wsApp , SIGNAL ( appInitialized ( ) ) , this , SLOT ( interfaceListChanged ( ) ) ) ;
connect ( wsApp , SIGNAL ( localInterfaceListChanged ( ) ) , this , SLOT ( interfaceListChanged ( ) ) ) ;
connect ( ui - > interfaceTree - > selectionModel ( ) , SIGNAL ( selectionChanged ( const QItemSelection & , const QItemSelection & ) ) ,
this , SLOT ( interfaceTreeSelectionChanged ( const QItemSelection & , const QItemSelection & ) ) ) ;
}
InterfaceFrame : : ~ InterfaceFrame ( )
{
delete ui ;
}
2016-10-17 09:57:00 +00:00
QMenu * InterfaceFrame : : getSelectionMenu ( )
{
2017-04-19 21:11:43 +00:00
QMenu * contextMenu = new QMenu ( this ) ;
2018-12-12 00:26:51 +00:00
QList < int > typesDisplayed = proxy_model_ . typesDisplayed ( ) ;
2016-10-17 09:57:00 +00:00
2016-10-18 20:28:28 +00:00
QMap < int , QString > : : const_iterator it = ifTypeDescription . constBegin ( ) ;
2019-11-17 19:02:20 +00:00
while ( it ! = ifTypeDescription . constEnd ( ) )
2016-10-17 09:57:00 +00:00
{
2016-10-18 20:28:28 +00:00
int ifType = it . key ( ) ;
2019-11-17 19:02:20 +00:00
if ( typesDisplayed . contains ( ifType ) )
2016-10-18 20:28:28 +00:00
{
QAction * endp_action = new QAction ( it . value ( ) , this ) ;
2018-01-15 07:53:55 +00:00
endp_action - > setData ( QVariant : : fromValue ( ifType ) ) ;
2016-10-18 20:28:28 +00:00
endp_action - > setCheckable ( true ) ;
2018-12-12 00:26:51 +00:00
endp_action - > setChecked ( proxy_model_ . isInterfaceTypeShown ( ifType ) ) ;
2016-10-18 20:28:28 +00:00
connect ( endp_action , SIGNAL ( triggered ( ) ) , this , SLOT ( triggeredIfTypeButton ( ) ) ) ;
contextMenu - > addAction ( endp_action ) ;
}
+ + it ;
2016-10-17 09:57:00 +00:00
}
2016-12-27 09:14:32 +00:00
# ifdef HAVE_PCAP_REMOTE
2019-11-17 19:02:20 +00:00
if ( proxy_model_ . remoteInterfacesExist ( ) )
2016-12-27 09:14:32 +00:00
{
QAction * toggleRemoteAction = new QAction ( tr ( " Remote interfaces " ) , this ) ;
toggleRemoteAction - > setCheckable ( true ) ;
2018-12-12 00:26:51 +00:00
toggleRemoteAction - > setChecked ( ! proxy_model_ . remoteDisplay ( ) ) ;
2016-12-27 09:14:32 +00:00
connect ( toggleRemoteAction , SIGNAL ( triggered ( ) ) , this , SLOT ( toggleRemoteInterfaces ( ) ) ) ;
contextMenu - > addAction ( toggleRemoteAction ) ;
}
# endif
2017-03-13 10:10:08 +00:00
#if 0
// Disabled until bug 13354 is fixed
2016-10-20 07:34:49 +00:00
contextMenu - > addSeparator ( ) ;
QAction * toggleHideAction = new QAction ( tr ( " Show hidden interfaces " ) , this ) ;
toggleHideAction - > setCheckable ( true ) ;
2018-12-12 00:26:51 +00:00
toggleHideAction - > setChecked ( ! proxy_model_ - > filterHidden ( ) ) ;
2016-10-20 07:34:49 +00:00
connect ( toggleHideAction , SIGNAL ( triggered ( ) ) , this , SLOT ( toggleHiddenInterfaces ( ) ) ) ;
contextMenu - > addAction ( toggleHideAction ) ;
2017-03-13 10:10:08 +00:00
# endif
2016-10-20 07:34:49 +00:00
2016-10-17 09:57:00 +00:00
return contextMenu ;
}
int InterfaceFrame : : interfacesHidden ( )
{
2018-12-12 00:26:51 +00:00
return proxy_model_ . interfacesHidden ( ) ;
2016-10-17 09:57:00 +00:00
}
int InterfaceFrame : : interfacesPresent ( )
{
2018-12-12 00:26:51 +00:00
return source_model_ . rowCount ( ) - proxy_model_ . interfacesHidden ( ) ;
2016-10-17 09:57:00 +00:00
}
2017-07-16 21:26:51 +00:00
void InterfaceFrame : : ensureSelectedInterface ( )
2017-07-14 21:38:59 +00:00
{
2017-07-16 21:26:51 +00:00
# ifdef HAVE_LIBPCAP
if ( interfacesPresent ( ) < 1 ) return ;
2018-12-12 00:26:51 +00:00
if ( source_model_ . selectedDevices ( ) . count ( ) < 1 ) {
QModelIndex first_idx = info_model_ . mapFromSource ( proxy_model_ . index ( 0 , 0 ) ) ;
2017-07-16 21:26:51 +00:00
ui - > interfaceTree - > setCurrentIndex ( first_idx ) ;
}
2017-07-14 21:38:59 +00:00
ui - > interfaceTree - > setFocus ( ) ;
2017-07-16 21:26:51 +00:00
# endif
2017-07-14 21:38:59 +00:00
}
2016-10-01 06:54:57 +00:00
void InterfaceFrame : : hideEvent ( QHideEvent * ) {
# ifdef HAVE_LIBPCAP
if ( stat_timer_ )
stat_timer_ - > stop ( ) ;
2018-12-12 00:26:51 +00:00
source_model_ . stopStatistic ( ) ;
2016-10-01 06:54:57 +00:00
# endif // HAVE_LIBPCAP
}
void InterfaceFrame : : showEvent ( QShowEvent * ) {
2016-10-13 07:11:50 +00:00
2016-10-01 06:54:57 +00:00
# ifdef HAVE_LIBPCAP
if ( stat_timer_ )
stat_timer_ - > start ( stat_update_interval_ ) ;
# endif // HAVE_LIBPCAP
}
void InterfaceFrame : : actionButton_toggled ( bool checked )
{
QVariant ifType = sender ( ) - > property ( BTN_IFTYPE_PROPERTY ) ;
2019-11-17 19:02:20 +00:00
if ( ifType . isValid ( ) )
2016-10-01 06:54:57 +00:00
{
2018-12-12 00:26:51 +00:00
proxy_model_ . setInterfaceTypeVisible ( ifType . toInt ( ) , checked ) ;
2016-10-01 06:54:57 +00:00
}
2016-10-13 07:11:50 +00:00
resetInterfaceTreeDisplay ( ) ;
2016-10-01 06:54:57 +00:00
}
2016-10-17 09:57:00 +00:00
void InterfaceFrame : : triggeredIfTypeButton ( )
2016-10-01 06:54:57 +00:00
{
2016-10-17 09:57:00 +00:00
QAction * sender = qobject_cast < QAction * > ( QObject : : sender ( ) ) ;
2019-11-17 19:02:20 +00:00
if ( sender )
2016-10-01 06:54:57 +00:00
{
2016-10-17 09:57:00 +00:00
int ifType = sender - > data ( ) . value < int > ( ) ;
2018-12-12 00:26:51 +00:00
proxy_model_ . toggleTypeVisibility ( ifType ) ;
2016-10-01 06:54:57 +00:00
2016-10-17 09:57:00 +00:00
resetInterfaceTreeDisplay ( ) ;
emit typeSelectionChanged ( ) ;
}
2016-10-01 06:54:57 +00:00
}
void InterfaceFrame : : interfaceListChanged ( )
2016-10-13 07:11:50 +00:00
{
2018-12-12 00:26:51 +00:00
info_model_ . clearInfos ( ) ;
2019-11-17 19:02:20 +00:00
if ( prefs . capture_no_extcap )
2018-12-12 00:26:51 +00:00
info_model_ . appendInfo ( tr ( " External capture interfaces disabled. " ) ) ;
2018-01-12 12:15:58 +00:00
2016-10-13 07:11:50 +00:00
resetInterfaceTreeDisplay ( ) ;
2017-03-10 13:37:18 +00:00
// Ensure that device selection is consistent with the displayed selection.
updateSelectedInterfaces ( ) ;
2016-10-17 09:57:00 +00:00
# ifdef HAVE_LIBPCAP
if ( ! stat_timer_ ) {
updateStatistics ( ) ;
stat_timer_ = new QTimer ( this ) ;
connect ( stat_timer_ , SIGNAL ( timeout ( ) ) , this , SLOT ( updateStatistics ( ) ) ) ;
stat_timer_ - > start ( stat_update_interval_ ) ;
}
# endif
2016-10-13 07:11:50 +00:00
}
2016-10-20 07:34:49 +00:00
void InterfaceFrame : : toggleHiddenInterfaces ( )
{
2018-12-12 00:26:51 +00:00
proxy_model_ . toggleFilterHidden ( ) ;
2016-10-20 07:34:49 +00:00
emit typeSelectionChanged ( ) ;
}
2016-12-27 09:14:32 +00:00
# ifdef HAVE_PCAP_REMOTE
void InterfaceFrame : : toggleRemoteInterfaces ( )
{
2018-12-12 00:26:51 +00:00
proxy_model_ . toggleRemoteDisplay ( ) ;
2016-12-27 09:14:32 +00:00
emit typeSelectionChanged ( ) ;
}
# endif
2016-10-13 07:11:50 +00:00
void InterfaceFrame : : resetInterfaceTreeDisplay ( )
2016-10-01 06:54:57 +00:00
{
2018-12-12 00:26:51 +00:00
ui - > warningLabel - > setText ( tr ( " No interfaces found " ) ) ;
ui - > warningLabel - > hide ( ) ;
2020-01-09 20:47:45 +00:00
if ( ! haveCapturePermissions ( ) )
{
# if defined(Q_OS_WIN)
ui - > warningLabel - > setText ( tr ( " <p>Local interfaces are unavailable because no capture driver is installed.</p> "
" <p>You can fix this by installing <a href= \" https://nmap.org/npcap/ \" >Npcap</a> or <a href= \" https://www.winpcap.org/install/default.htm \" >WinPcap</a>.</p> " ) ) ;
ui - > warningLabel - > show ( ) ;
return ;
# elif defined(Q_OS_MAC)
QString install_chmodbpf_path = wsApp - > applicationDirPath ( ) + " /../Resources/Extras/Install ChmodBPF.pkg " ;
ui - > warningLabel - > setText ( tr ( " <p>Local interfaces are unavailable due to insufficient permissions.</p> "
" <p>You can fix this by <a href= \" file://%1 \" >installing ChmodBPF</a>.</p> " )
. arg ( install_chmodbpf_path ) ) ;
ui - > warningLabel - > show ( ) ;
return ;
# endif
}
2019-11-17 19:02:20 +00:00
if ( proxy_model_ . rowCount ( ) = = 0 )
2016-10-01 06:54:57 +00:00
{
2018-12-12 00:26:51 +00:00
ui - > interfaceTree - > hide ( ) ;
ui - > warningLabel - > setText ( proxy_model_ . interfaceError ( ) ) ;
2019-11-17 19:02:20 +00:00
if ( prefs . capture_no_interface_load ) {
2018-12-12 00:26:51 +00:00
ui - > warningLabel - > setText ( tr ( " Interfaces not loaded (due to preference). Go to Capture " UTF8_RIGHTWARDS_ARROW " Refresh Interfaces to load. " ) ) ;
}
ui - > warningLabel - > show ( ) ;
2016-10-01 06:54:57 +00:00
}
else
{
2018-12-12 00:26:51 +00:00
ui - > interfaceTree - > show ( ) ;
ui - > warningLabel - > hide ( ) ;
ui - > interfaceTree - > resizeColumnToContents ( proxy_model_ . mapSourceToColumn ( IFTREE_COL_EXTCAP ) ) ;
ui - > interfaceTree - > resizeColumnToContents ( proxy_model_ . mapSourceToColumn ( IFTREE_COL_DISPLAY_NAME ) ) ;
ui - > interfaceTree - > resizeColumnToContents ( proxy_model_ . mapSourceToColumn ( IFTREE_COL_STATS ) ) ;
2016-10-01 06:54:57 +00:00
}
}
2018-12-12 00:26:51 +00:00
bool InterfaceFrame : : haveCapturePermissions ( ) const
{
2020-01-09 20:47:45 +00:00
# if defined(Q_OS_WIN)
return has_wpcap ;
# elif defined(Q_OS_MAC)
2018-12-12 00:26:51 +00:00
QFileInfo bpf0_fi = QFileInfo ( " /dev/bpf0 " ) ;
return bpf0_fi . isReadable ( ) & & bpf0_fi . isWritable ( ) ;
# else
return true ;
# endif
}
2016-10-01 06:54:57 +00:00
void InterfaceFrame : : updateSelectedInterfaces ( )
{
2019-11-17 19:02:20 +00:00
if ( source_model_ . rowCount ( ) = = 0 )
2016-10-01 06:54:57 +00:00
return ;
2016-10-02 14:47:04 +00:00
# ifdef HAVE_LIBPCAP
2018-12-12 00:26:51 +00:00
QItemSelection sourceSelection = source_model_ . selectedDevices ( ) ;
QItemSelection mySelection = info_model_ . mapSelectionFromSource ( proxy_model_ . mapSelectionFromSource ( sourceSelection ) ) ;
2016-10-01 06:54:57 +00:00
ui - > interfaceTree - > selectionModel ( ) - > clearSelection ( ) ;
2019-11-17 19:02:20 +00:00
ui - > interfaceTree - > selectionModel ( ) - > select ( mySelection , QItemSelectionModel : : SelectCurrent ) ;
2016-10-02 14:47:04 +00:00
# endif
2016-10-01 06:54:57 +00:00
}
void InterfaceFrame : : interfaceTreeSelectionChanged ( const QItemSelection & selected , const QItemSelection & deselected )
{
if ( selected . count ( ) = = 0 & & deselected . count ( ) = = 0 )
return ;
2019-11-17 19:02:20 +00:00
if ( source_model_ . rowCount ( ) = = 0 )
2016-10-01 06:54:57 +00:00
return ;
2016-10-03 14:31:36 +00:00
# ifdef HAVE_LIBPCAP
2016-10-01 06:54:57 +00:00
/* Take all selected interfaces, not just the newly ones */
QItemSelection allSelected = ui - > interfaceTree - > selectionModel ( ) - > selection ( ) ;
2018-12-12 00:26:51 +00:00
QItemSelection sourceSelection = proxy_model_ . mapSelectionToSource ( info_model_ . mapSelectionToSource ( allSelected ) ) ;
2016-10-01 06:54:57 +00:00
2019-11-17 19:02:20 +00:00
if ( source_model_ . updateSelectedDevices ( sourceSelection ) )
2016-10-01 06:54:57 +00:00
emit itemSelectionChanged ( ) ;
2016-10-02 14:47:04 +00:00
# endif
2016-10-01 06:54:57 +00:00
}
void InterfaceFrame : : on_interfaceTree_doubleClicked ( const QModelIndex & index )
{
2018-12-12 00:26:51 +00:00
QModelIndex realIndex = proxy_model_ . mapToSource ( info_model_ . mapToSource ( index ) ) ;
2016-10-01 06:54:57 +00:00
2019-11-17 19:02:20 +00:00
if ( ! realIndex . isValid ( ) )
2016-10-01 06:54:57 +00:00
return ;
2018-01-06 20:39:26 +00:00
# ifdef HAVE_LIBPCAP
2016-10-01 06:54:57 +00:00
2018-12-12 00:26:51 +00:00
QString device_name = source_model_ . getColumnContent ( realIndex . row ( ) , IFTREE_COL_NAME ) . toString ( ) ;
QString extcap_string = source_model_ . getColumnContent ( realIndex . row ( ) , IFTREE_COL_EXTCAP_PATH ) . toString ( ) ;
2016-10-01 06:54:57 +00:00
/* We trust the string here. If this interface is really extcap, the string is
* being checked immediatly before the dialog is being generated */
2019-11-17 19:02:20 +00:00
if ( extcap_string . length ( ) > 0 )
2016-10-01 06:54:57 +00:00
{
/* this checks if configuration is required and not yet provided or saved via prefs */
2019-11-17 19:02:20 +00:00
if ( extcap_has_configuration ( ( const char * ) ( device_name . toStdString ( ) . c_str ( ) ) , TRUE ) )
2016-10-01 06:54:57 +00:00
{
emit showExtcapOptions ( device_name ) ;
return ;
}
}
# endif
emit startCapture ( ) ;
}
2018-01-06 20:39:26 +00:00
# ifdef HAVE_LIBPCAP
2016-10-01 06:54:57 +00:00
void InterfaceFrame : : on_interfaceTree_clicked ( const QModelIndex & index )
{
2019-11-17 19:02:20 +00:00
if ( index . column ( ) = = 0 )
2016-10-01 06:54:57 +00:00
{
2018-12-12 00:26:51 +00:00
QModelIndex realIndex = proxy_model_ . mapToSource ( info_model_ . mapToSource ( index ) ) ;
2016-10-01 06:54:57 +00:00
2019-11-17 19:02:20 +00:00
if ( ! realIndex . isValid ( ) )
2016-10-01 06:54:57 +00:00
return ;
2018-12-12 00:26:51 +00:00
QString device_name = source_model_ . getColumnContent ( realIndex . row ( ) , IFTREE_COL_NAME ) . toString ( ) ;
QString extcap_string = source_model_ . getColumnContent ( realIndex . row ( ) , IFTREE_COL_EXTCAP_PATH ) . toString ( ) ;
2016-10-01 06:54:57 +00:00
/* We trust the string here. If this interface is really extcap, the string is
* being checked immediatly before the dialog is being generated */
2019-11-17 19:02:20 +00:00
if ( extcap_string . length ( ) > 0 )
2016-10-01 06:54:57 +00:00
{
/* this checks if configuration is required and not yet provided or saved via prefs */
2019-11-17 19:02:20 +00:00
if ( extcap_has_configuration ( ( const char * ) ( device_name . toStdString ( ) . c_str ( ) ) , FALSE ) )
2016-10-01 06:54:57 +00:00
{
emit showExtcapOptions ( device_name ) ;
return ;
}
}
}
}
# endif
void InterfaceFrame : : updateStatistics ( void )
{
2019-11-17 19:02:20 +00:00
if ( source_model_ . rowCount ( ) = = 0 )
2016-10-01 06:54:57 +00:00
return ;
# ifdef HAVE_LIBPCAP
2019-11-17 19:02:20 +00:00
for ( int idx = 0 ; idx < proxy_model_ . rowCount ( ) ; idx + + )
2016-10-01 06:54:57 +00:00
{
2018-12-12 00:26:51 +00:00
QModelIndex selectIndex = info_model_ . mapFromSource ( proxy_model_ . mapFromSource ( source_model_ . index ( idx , 0 ) ) ) ;
2016-10-01 06:54:57 +00:00
/* Proxy model has not masked out the interface */
2019-11-17 19:02:20 +00:00
if ( selectIndex . isValid ( ) )
2018-12-12 00:26:51 +00:00
source_model_ . updateStatistic ( idx ) ;
2016-10-01 06:54:57 +00:00
}
# endif
}
/* Proxy Method so we do not need to expose the source model */
void InterfaceFrame : : getPoints ( int idx , PointList * pts )
{
2018-12-12 00:26:51 +00:00
source_model_ . getPoints ( idx , pts ) ;
2016-10-01 06:54:57 +00:00
}
2018-10-01 20:09:33 +00:00
void InterfaceFrame : : showRunOnFile ( void )
{
2018-12-12 00:26:51 +00:00
ui - > warningLabel - > setText ( " Interfaces not loaded on startup (run on capture file). Go to Capture -> Refresh Interfaces to load. " ) ;
2018-10-01 20:09:33 +00:00
}
2019-07-30 07:48:56 +00:00
void InterfaceFrame : : showContextMenu ( QPoint pos )
{
QMenu ctx_menu ;
ctx_menu . addAction ( tr ( " Start capture " ) , this , SIGNAL ( startCapture ( ) ) ) ;
ctx_menu . exec ( ui - > interfaceTree - > mapToGlobal ( pos ) ) ;
}
2016-10-01 06:54:57 +00:00
/*
* Editor modelines
*
* Local Variables :
* c - basic - offset : 4
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* ex : set shiftwidth = 4 tabstop = 8 expandtab :
* : indentSize = 4 : tabSize = 8 : noTabs = true :
*/