2016-10-01 06:54:57 +00:00
|
|
|
/* interface_sort_filter_model.cpp
|
|
|
|
* Proxy model for the display of interface data for the interface tree
|
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
|
|
|
* This program 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 2
|
|
|
|
* 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, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2017-07-25 14:47:16 +00:00
|
|
|
#include <ui/qt/models/interface_tree_model.h>
|
|
|
|
#include <ui/qt/models/interface_tree_cache_model.h>
|
|
|
|
#include <ui/qt/models/interface_sort_filter_model.h>
|
2016-10-01 06:54:57 +00:00
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
#include <epan/prefs.h>
|
|
|
|
#include <ui/preference_utils.h>
|
2017-07-25 14:15:18 +00:00
|
|
|
#include <ui/qt/utils/qt_ui_utils.h>
|
2016-10-01 06:54:57 +00:00
|
|
|
|
|
|
|
#include "wireshark_application.h"
|
|
|
|
|
|
|
|
#include <QAbstractItemModel>
|
|
|
|
|
|
|
|
InterfaceSortFilterModel::InterfaceSortFilterModel(QObject *parent) :
|
|
|
|
QSortFilterProxyModel(parent)
|
2016-10-25 12:27:56 +00:00
|
|
|
{
|
|
|
|
resetAllFilter();
|
|
|
|
}
|
|
|
|
|
|
|
|
void InterfaceSortFilterModel::resetAllFilter()
|
2016-10-01 06:54:57 +00:00
|
|
|
{
|
|
|
|
_filterHidden = true;
|
2016-10-06 15:04:45 +00:00
|
|
|
_filterTypes = true;
|
|
|
|
_invertTypeFilter = false;
|
2016-10-26 08:03:50 +00:00
|
|
|
_storeOnChange = false;
|
2016-12-27 09:14:32 +00:00
|
|
|
#ifdef HAVE_PCAP_REMOTE
|
|
|
|
_remoteDisplay = true;
|
|
|
|
#endif
|
2016-10-01 06:54:57 +00:00
|
|
|
|
2016-10-03 14:31:36 +00:00
|
|
|
/* Adding all columns, to have a default setting */
|
|
|
|
for ( int col = 0; col < IFTREE_COL_MAX; col++ )
|
|
|
|
_columns.append((InterfaceTreeColumns)col);
|
2016-10-25 12:27:56 +00:00
|
|
|
|
|
|
|
invalidateFilter();
|
|
|
|
invalidate();
|
2016-10-26 08:03:50 +00:00
|
|
|
}
|
2016-10-03 14:31:36 +00:00
|
|
|
|
2016-10-26 08:03:50 +00:00
|
|
|
void InterfaceSortFilterModel::setStoreOnChange(bool storeOnChange)
|
|
|
|
{
|
|
|
|
_storeOnChange = storeOnChange;
|
|
|
|
if ( storeOnChange )
|
|
|
|
{
|
|
|
|
connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(resetPreferenceData()));
|
|
|
|
resetPreferenceData();
|
|
|
|
}
|
2016-10-01 06:54:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InterfaceSortFilterModel::setFilterHidden(bool filter)
|
|
|
|
{
|
|
|
|
_filterHidden = filter;
|
|
|
|
|
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
|
2016-12-27 09:14:32 +00:00
|
|
|
#ifdef HAVE_PCAP_REMOTE
|
|
|
|
void InterfaceSortFilterModel::setRemoteDisplay(bool remoteDisplay)
|
|
|
|
{
|
|
|
|
_remoteDisplay = remoteDisplay;
|
|
|
|
|
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InterfaceSortFilterModel::remoteDisplay()
|
|
|
|
{
|
|
|
|
return _remoteDisplay;
|
|
|
|
}
|
|
|
|
|
|
|
|
void InterfaceSortFilterModel::toggleRemoteDisplay()
|
|
|
|
{
|
|
|
|
_remoteDisplay = ! _remoteDisplay;
|
|
|
|
|
|
|
|
if ( _storeOnChange )
|
|
|
|
{
|
|
|
|
prefs.gui_interfaces_remote_display = ! _remoteDisplay;
|
|
|
|
|
|
|
|
prefs_main_write();
|
|
|
|
}
|
|
|
|
|
|
|
|
invalidateFilter();
|
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InterfaceSortFilterModel::remoteInterfacesExist()
|
|
|
|
{
|
|
|
|
bool exist = false;
|
|
|
|
|
|
|
|
if ( sourceModel()->rowCount() == 0 )
|
|
|
|
return exist;
|
|
|
|
|
|
|
|
for (int idx = 0; idx < sourceModel()->rowCount() && ! exist; idx++)
|
|
|
|
exist = ((InterfaceTreeModel *)sourceModel())->isRemote(idx);
|
|
|
|
|
|
|
|
return exist;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-10-06 15:04:45 +00:00
|
|
|
void InterfaceSortFilterModel::setFilterByType(bool filter, bool invert)
|
|
|
|
{
|
|
|
|
_filterTypes = filter;
|
|
|
|
_invertTypeFilter = invert;
|
|
|
|
|
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
|
2016-10-01 06:54:57 +00:00
|
|
|
void InterfaceSortFilterModel::resetPreferenceData()
|
|
|
|
{
|
|
|
|
displayHiddenTypes.clear();
|
|
|
|
QString stored_prefs(prefs.gui_interfaces_hide_types);
|
|
|
|
if ( stored_prefs.length() > 0 )
|
|
|
|
{
|
|
|
|
QStringList ifTypesStored = stored_prefs.split(',');
|
2016-10-18 20:28:28 +00:00
|
|
|
QStringList::const_iterator it = ifTypesStored.constBegin();
|
|
|
|
while(it != ifTypesStored.constEnd())
|
2016-10-01 06:54:57 +00:00
|
|
|
{
|
2016-10-18 20:28:28 +00:00
|
|
|
int i_val = (*it).toInt();
|
2016-10-01 06:54:57 +00:00
|
|
|
if ( ! displayHiddenTypes.contains(i_val) )
|
|
|
|
displayHiddenTypes.append(i_val);
|
2016-10-18 20:28:28 +00:00
|
|
|
++it;
|
2016-10-01 06:54:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-13 10:10:08 +00:00
|
|
|
#if 0
|
|
|
|
// Disabled until bug 13354 is fixed
|
2016-10-20 07:34:49 +00:00
|
|
|
_filterHidden = ! prefs.gui_interfaces_show_hidden;
|
2017-03-13 10:10:08 +00:00
|
|
|
#endif
|
2016-12-27 09:14:32 +00:00
|
|
|
#ifdef HAVE_PCAP_REMOTE
|
|
|
|
_remoteDisplay = prefs.gui_interfaces_remote_display;
|
|
|
|
#endif
|
2016-10-20 07:34:49 +00:00
|
|
|
|
2016-10-01 06:54:57 +00:00
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InterfaceSortFilterModel::filterHidden() const
|
|
|
|
{
|
|
|
|
return _filterHidden;
|
|
|
|
}
|
|
|
|
|
2016-10-20 07:34:49 +00:00
|
|
|
void InterfaceSortFilterModel::toggleFilterHidden()
|
|
|
|
{
|
|
|
|
_filterHidden = ! _filterHidden;
|
|
|
|
|
2016-10-26 08:03:50 +00:00
|
|
|
if ( _storeOnChange )
|
|
|
|
{
|
|
|
|
prefs.gui_interfaces_show_hidden = ! _filterHidden;
|
2016-10-20 07:34:49 +00:00
|
|
|
|
2016-10-26 08:03:50 +00:00
|
|
|
prefs_main_write();
|
|
|
|
}
|
2016-10-20 07:34:49 +00:00
|
|
|
|
|
|
|
invalidateFilter();
|
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
|
2016-10-06 15:04:45 +00:00
|
|
|
bool InterfaceSortFilterModel::filterByType() const
|
|
|
|
{
|
|
|
|
return _filterTypes;
|
|
|
|
}
|
|
|
|
|
2016-10-01 06:54:57 +00:00
|
|
|
int InterfaceSortFilterModel::interfacesHidden()
|
|
|
|
{
|
2016-10-02 14:47:04 +00:00
|
|
|
#ifdef HAVE_LIBPCAP
|
2016-10-01 06:54:57 +00:00
|
|
|
if ( ! global_capture_opts.all_ifaces )
|
|
|
|
return 0;
|
2016-10-02 14:47:04 +00:00
|
|
|
#endif
|
2016-10-01 06:54:57 +00:00
|
|
|
|
|
|
|
return sourceModel()->rowCount() - rowCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
QList<int> InterfaceSortFilterModel::typesDisplayed()
|
|
|
|
{
|
|
|
|
QList<int> shownTypes;
|
2016-10-03 14:31:36 +00:00
|
|
|
|
|
|
|
if ( sourceModel()->rowCount() == 0 )
|
2016-10-01 06:54:57 +00:00
|
|
|
return shownTypes;
|
|
|
|
|
2016-10-03 14:31:36 +00:00
|
|
|
for (int idx = 0; idx < sourceModel()->rowCount(); idx++)
|
2016-10-01 06:54:57 +00:00
|
|
|
{
|
2016-10-03 14:31:36 +00:00
|
|
|
int type = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
|
|
|
|
bool hidden = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN).toBool();
|
|
|
|
|
|
|
|
if ( ! hidden )
|
2016-10-01 06:54:57 +00:00
|
|
|
{
|
2016-10-03 14:31:36 +00:00
|
|
|
if ( ! shownTypes.contains(type) )
|
|
|
|
shownTypes.append(type);
|
2016-10-01 06:54:57 +00:00
|
|
|
}
|
|
|
|
}
|
2016-10-03 14:31:36 +00:00
|
|
|
|
2016-10-01 06:54:57 +00:00
|
|
|
return shownTypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
void InterfaceSortFilterModel::setInterfaceTypeVisible(int ifType, bool visible)
|
|
|
|
{
|
|
|
|
if ( visible && displayHiddenTypes.contains(ifType) )
|
|
|
|
displayHiddenTypes.removeAll(ifType);
|
|
|
|
else if ( ! visible && ! displayHiddenTypes.contains(ifType) )
|
|
|
|
displayHiddenTypes.append(ifType);
|
|
|
|
else
|
|
|
|
/* Nothing should have changed */
|
|
|
|
return;
|
|
|
|
|
2016-10-26 08:03:50 +00:00
|
|
|
if ( _storeOnChange )
|
2016-10-01 06:54:57 +00:00
|
|
|
{
|
2016-10-26 08:03:50 +00:00
|
|
|
QString new_pref;
|
|
|
|
QList<int>::const_iterator it = displayHiddenTypes.constBegin();
|
|
|
|
while( it != displayHiddenTypes.constEnd() )
|
|
|
|
{
|
|
|
|
new_pref.append(QString("%1,").arg(*it));
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
if (new_pref.length() > 0)
|
|
|
|
new_pref = new_pref.left(new_pref.length() - 1);
|
2016-10-01 06:54:57 +00:00
|
|
|
|
2016-10-26 08:03:50 +00:00
|
|
|
prefs.gui_interfaces_hide_types = qstring_strdup(new_pref);
|
2016-10-01 06:54:57 +00:00
|
|
|
|
2016-10-26 08:03:50 +00:00
|
|
|
prefs_main_write();
|
|
|
|
}
|
2016-10-01 06:54:57 +00:00
|
|
|
|
2016-10-13 07:11:50 +00:00
|
|
|
invalidateFilter();
|
2016-10-01 06:54:57 +00:00
|
|
|
invalidate();
|
|
|
|
}
|
|
|
|
|
2016-10-17 09:57:00 +00:00
|
|
|
void InterfaceSortFilterModel::toggleTypeVisibility(int ifType)
|
|
|
|
{
|
|
|
|
bool checked = isInterfaceTypeShown(ifType);
|
|
|
|
|
|
|
|
setInterfaceTypeVisible(ifType, checked ? false : true);
|
|
|
|
}
|
|
|
|
|
2016-10-01 06:54:57 +00:00
|
|
|
bool InterfaceSortFilterModel::isInterfaceTypeShown(int ifType) const
|
|
|
|
{
|
2016-10-06 15:04:45 +00:00
|
|
|
bool result = false;
|
2016-10-01 06:54:57 +00:00
|
|
|
|
2016-10-06 15:04:45 +00:00
|
|
|
if ( displayHiddenTypes.size() == 0 )
|
|
|
|
result = true;
|
|
|
|
else if ( ! displayHiddenTypes.contains(ifType) )
|
|
|
|
result = true;
|
|
|
|
|
|
|
|
return ( ( _invertTypeFilter && ! result ) || ( ! _invertTypeFilter && result ) );
|
2016-10-01 06:54:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool InterfaceSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
|
|
|
|
{
|
|
|
|
QModelIndex realIndex = sourceModel()->index(sourceRow, 0, sourceParent);
|
2016-10-02 14:47:04 +00:00
|
|
|
|
|
|
|
if ( ! realIndex.isValid() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBPCAP
|
2016-10-01 06:54:57 +00:00
|
|
|
int idx = realIndex.row();
|
|
|
|
|
|
|
|
/* No data loaded, we do not display anything */
|
2016-10-03 14:31:36 +00:00
|
|
|
if ( sourceModel()->rowCount() == 0 )
|
2016-10-01 06:54:57 +00:00
|
|
|
return false;
|
|
|
|
|
2016-10-25 12:27:56 +00:00
|
|
|
int type = -1;
|
|
|
|
bool hidden = false;
|
|
|
|
|
|
|
|
if (dynamic_cast<InterfaceTreeCacheModel*>(sourceModel()) != 0)
|
|
|
|
{
|
|
|
|
type = ((InterfaceTreeCacheModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
|
|
|
|
hidden = ((InterfaceTreeCacheModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
|
|
|
|
}
|
|
|
|
else if (dynamic_cast<InterfaceTreeModel*>(sourceModel()) != 0)
|
|
|
|
{
|
|
|
|
type = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
|
|
|
|
hidden = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
2016-10-01 06:54:57 +00:00
|
|
|
|
2016-10-03 14:31:36 +00:00
|
|
|
if ( hidden && _filterHidden )
|
2016-10-01 06:54:57 +00:00
|
|
|
return false;
|
|
|
|
|
2016-10-06 15:04:45 +00:00
|
|
|
if ( _filterTypes && ! isInterfaceTypeShown(type) )
|
2016-12-27 09:14:32 +00:00
|
|
|
{
|
|
|
|
#ifdef HAVE_PCAP_REMOTE
|
|
|
|
/* Remote interfaces have the if type IF_WIRED, therefore would be filtered, if not explicitly checked here */
|
2016-12-29 09:20:01 +00:00
|
|
|
if ( type != IF_WIRED || ! ((InterfaceTreeModel *)sourceModel())->isRemote(idx) )
|
2016-12-27 09:14:32 +00:00
|
|
|
#endif
|
2016-10-01 06:54:57 +00:00
|
|
|
return false;
|
2016-12-27 09:14:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_PCAP_REMOTE
|
2016-12-29 09:20:01 +00:00
|
|
|
if ( ((InterfaceTreeModel *)sourceModel())->isRemote(idx) )
|
|
|
|
{
|
|
|
|
if ( ! _remoteDisplay )
|
|
|
|
return false;
|
|
|
|
}
|
2016-12-27 09:14:32 +00:00
|
|
|
#endif
|
|
|
|
|
2016-10-02 14:47:04 +00:00
|
|
|
#endif
|
2016-10-01 06:54:57 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-10-03 14:31:36 +00:00
|
|
|
bool InterfaceSortFilterModel::filterAcceptsColumn(int sourceColumn, const QModelIndex & sourceParent) const
|
|
|
|
{
|
|
|
|
QModelIndex realIndex = sourceModel()->index(0, sourceColumn, sourceParent);
|
|
|
|
|
|
|
|
if ( ! realIndex.isValid() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ( ! _columns.contains((InterfaceTreeColumns)sourceColumn) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void InterfaceSortFilterModel::setColumns(QList<InterfaceTreeColumns> columns)
|
|
|
|
{
|
|
|
|
_columns.clear();
|
|
|
|
_columns.append(columns);
|
|
|
|
}
|
|
|
|
|
|
|
|
int InterfaceSortFilterModel::mapSourceToColumn(InterfaceTreeColumns mdlIndex)
|
|
|
|
{
|
|
|
|
if ( ! _columns.contains(mdlIndex) )
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return _columns.indexOf(mdlIndex, 0);
|
|
|
|
}
|
|
|
|
|
2016-10-06 15:04:45 +00:00
|
|
|
QModelIndex InterfaceSortFilterModel::mapToSource(const QModelIndex &proxyIndex) const
|
|
|
|
{
|
|
|
|
if ( ! proxyIndex.isValid() )
|
|
|
|
return QModelIndex();
|
|
|
|
|
2016-10-22 17:53:00 +00:00
|
|
|
if ( ! sourceModel() )
|
|
|
|
return QModelIndex();
|
|
|
|
|
2016-10-06 15:04:45 +00:00
|
|
|
QModelIndex baseIndex = QSortFilterProxyModel::mapToSource(proxyIndex);
|
|
|
|
QModelIndex newIndex = sourceModel()->index(baseIndex.row(), _columns.at(proxyIndex.column()));
|
|
|
|
|
|
|
|
return newIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndex InterfaceSortFilterModel::mapFromSource(const QModelIndex &sourceIndex) const
|
|
|
|
{
|
|
|
|
if ( ! sourceIndex.isValid() )
|
|
|
|
return QModelIndex();
|
|
|
|
else if ( ! _columns.contains( (InterfaceTreeColumns) sourceIndex.column() ) )
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
QModelIndex newIndex = QSortFilterProxyModel::mapFromSource(sourceIndex);
|
|
|
|
|
|
|
|
return index(newIndex.row(), _columns.indexOf((InterfaceTreeColumns) sourceIndex.column()));
|
|
|
|
}
|
|
|
|
|
2016-10-13 07:11:50 +00:00
|
|
|
QString InterfaceSortFilterModel::interfaceError()
|
|
|
|
{
|
|
|
|
QString result;
|
|
|
|
|
|
|
|
InterfaceTreeModel * sourceModel = dynamic_cast<InterfaceTreeModel *>(this->sourceModel());
|
|
|
|
if ( sourceModel != NULL )
|
|
|
|
result = sourceModel->interfaceError();
|
|
|
|
|
|
|
|
if ( result.size() == 0 && rowCount() == 0 )
|
|
|
|
result = QString(tr("No interfaces to be displayed. %1 interfaces filtered.")).arg(interfacesHidden());
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
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:
|
|
|
|
*/
|