forked from osmocom/wireshark
Qt: Hide columns for traffic tree
Allow columns to be hidden for the traffic tree dialogs Conversations and Endpoints and store the information profile specific
This commit is contained in:
parent
f75f577579
commit
2b4878d452
|
@ -40,6 +40,7 @@ wsbuglink:17779[]
|
|||
- The dialog elements have been moved to make it easier to handle for new users.
|
||||
- Selection of tap elements is done via list
|
||||
- All configurations and options are done via a left side button row
|
||||
- Columns for the Conversations and Endpoint dialogs can be hidden by context menu
|
||||
|
||||
* The PCRE2 library (https://www.pcre.org/) is now a required dependency to build Wireshark.
|
||||
|
||||
|
@ -77,6 +78,8 @@ The following features are new (or have been significantly updated) since versio
|
|||
* The Windows installers now ship with Qt 6.2.3.
|
||||
They previously shipped with Qt 6.2.4.
|
||||
|
||||
* The Conversation and Endpoint dialogs have been reworked extensively
|
||||
|
||||
The following features are new (or have been significantly updated) since version 3.6.0:
|
||||
|
||||
* The Windows installers now ship with Npcap 1.60.
|
||||
|
|
|
@ -95,7 +95,7 @@ ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf) :
|
|||
{
|
||||
trafficList()->setProtocolInfo(table_name_, &(recent.conversation_tabs));
|
||||
|
||||
trafficTab()->setProtocolInfo(table_name_, trafficList()->protocols(), trafficList()->selectedProtocols(), &createModel);
|
||||
trafficTab()->setProtocolInfo(table_name_, trafficList(), &(recent.conversation_tabs_columns), &createModel);
|
||||
trafficTab()->setDelegate(CONV_COLUMN_START, &createDelegate);
|
||||
trafficTab()->setDelegate(CONV_COLUMN_DURATION, &createDelegate);
|
||||
trafficTab()->setFilter(cf.displayFilter());
|
||||
|
|
|
@ -69,7 +69,7 @@ EndpointDialog::EndpointDialog(QWidget &parent, CaptureFile &cf) :
|
|||
{
|
||||
trafficList()->setProtocolInfo(table_name_, &(recent.endpoint_tabs));
|
||||
|
||||
trafficTab()->setProtocolInfo(table_name_, trafficList()->protocols(), trafficList()->selectedProtocols(), &createModel);
|
||||
trafficTab()->setProtocolInfo(table_name_, trafficList(), &(recent.endpoint_tabs_columns), &createModel);
|
||||
trafficTab()->setFilter(cf.displayFilter());
|
||||
displayFilterCheckBox()->setChecked(cf.displayFilter().length() > 0);
|
||||
connect(trafficTab(), &TrafficTab::filterAction, this, &EndpointDialog::filterAction);
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <ui/qt/utils/variant_pointer.h>
|
||||
#include <ui/qt/widgets/traffic_tab.h>
|
||||
#include <ui/qt/widgets/traffic_tree.h>
|
||||
#include <ui/qt/widgets/traffic_types_list.h>
|
||||
#include <ui/qt/widgets/detachable_tabwidget.h>
|
||||
|
||||
#include <QStringList>
|
||||
|
@ -176,6 +177,24 @@ bool TrafficDataFilterProxy::lessThan(const QModelIndex &source_left, const QMod
|
|||
return QSortFilterProxyModel::lessThan(source_left, source_right);
|
||||
}
|
||||
|
||||
bool TrafficDataFilterProxy::filterAcceptsColumn(int source_column, const QModelIndex &) const
|
||||
{
|
||||
return (!hideColumns_.contains(source_column));
|
||||
}
|
||||
|
||||
void TrafficDataFilterProxy::setColumnVisibility(int column, bool visible)
|
||||
{
|
||||
hideColumns_.removeAll(column);
|
||||
if (!visible)
|
||||
hideColumns_.append(column);
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
bool TrafficDataFilterProxy::columnVisible(int column) const
|
||||
{
|
||||
return ! hideColumns_.contains(column);
|
||||
}
|
||||
|
||||
|
||||
TrafficTab::TrafficTab(QWidget * parent) :
|
||||
DetachableTabWidget(parent)
|
||||
|
@ -189,14 +208,17 @@ TrafficTab::TrafficTab(QWidget * parent) :
|
|||
TrafficTab::~TrafficTab()
|
||||
{}
|
||||
|
||||
void TrafficTab::setProtocolInfo(QString tableName, QList<int> allProtocols, QList<int> openTabs, ATapModelCallback createModel)
|
||||
void TrafficTab::setProtocolInfo(QString tableName, TrafficTypesList * trafficList, GList ** recentColumnList, ATapModelCallback createModel)
|
||||
{
|
||||
setTabBasename(tableName);
|
||||
_allProtocols = allProtocols;
|
||||
|
||||
_allProtocols = trafficList->protocols();
|
||||
if (createModel)
|
||||
_createModel = createModel;
|
||||
|
||||
setOpenTabs(openTabs);
|
||||
_recentColumnList = recentColumnList;
|
||||
|
||||
setOpenTabs(trafficList->selectedProtocols());
|
||||
}
|
||||
|
||||
void TrafficTab::setDelegate(int column, ATapCreateDelegate createDelegate)
|
||||
|
@ -228,7 +250,7 @@ void TrafficTab::setDelegate(int column, ATapCreateDelegate createDelegate)
|
|||
|
||||
QTreeView * TrafficTab::createTree(int protoId)
|
||||
{
|
||||
TrafficTree * tree = new TrafficTree(tabBasename(), this);
|
||||
TrafficTree * tree = new TrafficTree(tabBasename(), _recentColumnList, this);
|
||||
|
||||
if (_createModel) {
|
||||
ATapDataModel * model = _createModel(protoId, "");
|
||||
|
@ -253,6 +275,8 @@ QTreeView * TrafficTab::createTree(int protoId)
|
|||
tree->setSelectionModel(ism);
|
||||
connect(ism, &QItemSelectionModel::currentChanged, this, &TrafficTab::doCurrentIndexChange);
|
||||
|
||||
tree->applyRecentColumns();
|
||||
|
||||
tree->sortByColumn(0, Qt::AscendingOrder);
|
||||
|
||||
connect(proxyModel, &TrafficDataFilterProxy::modelReset, this, [tree]() {
|
||||
|
@ -262,6 +286,13 @@ QTreeView * TrafficTab::createTree(int protoId)
|
|||
}
|
||||
});
|
||||
connect(proxyModel, &TrafficDataFilterProxy::modelReset, this, &TrafficTab::modelReset);
|
||||
|
||||
/* If the columns for the tree have changed, contact the tab. By also having the tab
|
||||
* columns changed signal connecting back to the tree, it will propagate to all trees
|
||||
* registered with this tab. Attention, this heavily relies on the fact, that all
|
||||
* tree data models are identical */
|
||||
connect(tree, &TrafficTree::columnsHaveChanged, this, &TrafficTab::columnsHaveChanged);
|
||||
connect(this, &TrafficTab::columnsHaveChanged, tree, &TrafficTree::columnsChanged);
|
||||
}
|
||||
|
||||
return tree;
|
||||
|
|
|
@ -12,9 +12,12 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <ui/qt/models/atap_data_model.h>
|
||||
#include <ui/qt/filter_action.h>
|
||||
#include <ui/qt/widgets/detachable_tabwidget.h>
|
||||
#include <ui/qt/widgets/traffic_types_list.h>
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QTreeView>
|
||||
|
@ -67,10 +70,17 @@ class TrafficDataFilterProxy : public QSortFilterProxyModel
|
|||
public:
|
||||
TrafficDataFilterProxy(QObject *parent = nullptr);
|
||||
|
||||
void setColumnVisibility(int column, bool visible);
|
||||
bool columnVisible(int column) const;
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
|
||||
virtual bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const;
|
||||
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
|
||||
|
||||
private:
|
||||
QList<int> hideColumns_;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -97,13 +107,13 @@ public:
|
|||
* without having to removing the predefined object during setup of the UI.
|
||||
*
|
||||
* @param tableName The name for the table. Used for the protocol selection button
|
||||
* @param allProtocols a list of all possible protocols. It's order will set the tab oder
|
||||
* @param openTabs a list of protocol ids to open at start of dialog
|
||||
* @param trafficList an element of traffictypeslist, which handles all profile selections
|
||||
* @param recentColumnList a list of columns to be displayed for this traffic type
|
||||
* @param createModel A callback, which will create the correct model for the trees
|
||||
*
|
||||
* @see ATapModelCallback
|
||||
*/
|
||||
void setProtocolInfo(QString tableName, QList<int> allProtocols, QList<int> openTabs, ATapModelCallback createModel);
|
||||
void setProtocolInfo(QString tableName, TrafficTypesList * trafficList, GList ** recentColumnList, ATapModelCallback createModel);
|
||||
|
||||
/**
|
||||
* @brief Set the Delegate object for a specific column
|
||||
|
@ -219,6 +229,7 @@ signals:
|
|||
void retapRequired();
|
||||
void disablingTaps();
|
||||
void tabsChanged(QList<int> protocols);
|
||||
void columnsHaveChanged(QList<int> columns);
|
||||
|
||||
protected slots:
|
||||
|
||||
|
@ -230,6 +241,7 @@ private:
|
|||
QMap<int, int> _tabs;
|
||||
ATapModelCallback _createModel;
|
||||
QMap<int, ATapCreateDelegate> _createDelegates;
|
||||
GList ** _recentColumnList;
|
||||
|
||||
bool _disableTaps;
|
||||
bool _nameResolution;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <ui/qt/filter_action.h>
|
||||
#include <ui/qt/models/atap_data_model.h>
|
||||
#include <ui/qt/utils/variant_pointer.h>
|
||||
#include <ui/qt/widgets/traffic_tab.h>
|
||||
#include <ui/qt/widgets/traffic_tree.h>
|
||||
|
||||
#include <QStringList>
|
||||
|
@ -39,20 +40,120 @@
|
|||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QHeaderView>
|
||||
|
||||
TrafficTree::TrafficTree(QString baseName, QWidget *parent) :
|
||||
TrafficTreeHeaderView::TrafficTreeHeaderView(GList ** recentColumnList, QWidget * parent):
|
||||
QHeaderView(Qt::Horizontal, parent)
|
||||
{
|
||||
_recentColumnList = recentColumnList;
|
||||
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
connect(this, &QHeaderView::customContextMenuRequested, this, &TrafficTreeHeaderView::headerContextMenu);
|
||||
}
|
||||
|
||||
TrafficTreeHeaderView::~TrafficTreeHeaderView()
|
||||
{}
|
||||
|
||||
void TrafficTreeHeaderView::headerContextMenu(const QPoint &pos)
|
||||
{
|
||||
TrafficTree * tree = qobject_cast<TrafficTree *>(parent());
|
||||
if (!tree)
|
||||
return;
|
||||
|
||||
TrafficDataFilterProxy * proxy = qobject_cast<TrafficDataFilterProxy *>(tree->model());
|
||||
if (sender() != this || ! proxy)
|
||||
return;
|
||||
|
||||
QMenu ctxMenu;
|
||||
|
||||
for (int col = 0; col < tree->dataModel()->columnCount(); col++)
|
||||
{
|
||||
QString name = tree->dataModel()->headerData(col).toString();
|
||||
QAction * action = new QAction(name);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(proxy->columnVisible(col));
|
||||
action->setProperty("col_nr", col);
|
||||
ctxMenu.addAction(action);
|
||||
|
||||
connect(action, &QAction::triggered, this, &TrafficTreeHeaderView::columnTriggered);
|
||||
}
|
||||
|
||||
ctxMenu.exec(mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void TrafficTreeHeaderView::applyRecent()
|
||||
{
|
||||
TrafficTree * tree = qobject_cast<TrafficTree *>(parent());
|
||||
if (!tree)
|
||||
return;
|
||||
|
||||
QList<int> columns;
|
||||
for (GList * endTab = *_recentColumnList; endTab; endTab = endTab->next) {
|
||||
QString colStr = QString((const char *)endTab->data);
|
||||
bool ok = false;
|
||||
int col = colStr.toInt(&ok);
|
||||
if (ok)
|
||||
columns << col;
|
||||
}
|
||||
|
||||
if (columns.count() > 0) {
|
||||
TrafficDataFilterProxy * proxy = qobject_cast<TrafficDataFilterProxy *>(tree->model());
|
||||
for (int col = 0; col < tree->dataModel()->columnCount(); col++) {
|
||||
proxy->setColumnVisibility(col, columns.contains(col));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TrafficTreeHeaderView::columnTriggered(bool checked)
|
||||
{
|
||||
TrafficTree * tree = qobject_cast<TrafficTree *>(parent());
|
||||
if (!tree)
|
||||
return;
|
||||
|
||||
TrafficDataFilterProxy * proxy = qobject_cast<TrafficDataFilterProxy *>(tree->model());
|
||||
QAction * entry = qobject_cast<QAction *>(sender());
|
||||
if (! proxy || ! entry || ! entry->property("col_nr").isValid())
|
||||
return;
|
||||
|
||||
int col = entry->property("col_nr").toInt();
|
||||
proxy->setColumnVisibility(col, checked);
|
||||
|
||||
prefs_clear_string_list(*_recentColumnList);
|
||||
*_recentColumnList = NULL;
|
||||
|
||||
QList<int> visible;
|
||||
|
||||
for (int col = 0; col < tree->dataModel()->columnCount(); col++) {
|
||||
if (proxy->columnVisible(col)) {
|
||||
visible << col;
|
||||
gchar *nr = qstring_strdup(QString::number(col));
|
||||
*_recentColumnList = g_list_append(*_recentColumnList, nr);
|
||||
}
|
||||
}
|
||||
|
||||
emit columnsHaveChanged(visible);
|
||||
}
|
||||
|
||||
|
||||
TrafficTree::TrafficTree(QString baseName, GList ** recentColumnList, QWidget *parent) :
|
||||
QTreeView(parent)
|
||||
{
|
||||
_tapEnabled = true;
|
||||
_saveRaw = true;
|
||||
_baseName = baseName;
|
||||
_exportRole = ATapDataModel::UNFORMATTED_DISPLAYDATA;
|
||||
_header = nullptr;
|
||||
|
||||
setAlternatingRowColors(true);
|
||||
setRootIsDecorated(false);
|
||||
setSortingEnabled(true);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
|
||||
_header = new TrafficTreeHeaderView(recentColumnList);
|
||||
setHeader(_header);
|
||||
|
||||
connect(_header, &TrafficTreeHeaderView::columnsHaveChanged, this, &TrafficTree::columnsHaveChanged);
|
||||
connect(this, &QTreeView::customContextMenuRequested, this, &TrafficTree::customContextMenu);
|
||||
}
|
||||
|
||||
|
@ -277,3 +378,22 @@ void TrafficTree::disableTap()
|
|||
return;
|
||||
model->disableTap();
|
||||
}
|
||||
|
||||
void TrafficTree::applyRecentColumns()
|
||||
{
|
||||
if (_header)
|
||||
_header->applyRecent();
|
||||
}
|
||||
|
||||
void TrafficTree::columnsChanged(QList<int> columns)
|
||||
{
|
||||
TrafficDataFilterProxy * proxy = qobject_cast<TrafficDataFilterProxy *>(model());
|
||||
if (!proxy)
|
||||
return;
|
||||
|
||||
for (int col = 0; col < dataModel()->columnCount(); col++) {
|
||||
proxy->setColumnVisibility(col, columns.contains(col));
|
||||
}
|
||||
|
||||
resizeAction();
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <ui/recent.h>
|
||||
|
||||
#include <ui/qt/models/atap_data_model.h>
|
||||
|
@ -19,6 +21,29 @@
|
|||
|
||||
#include <QTreeView>
|
||||
#include <QMenu>
|
||||
#include <QHeaderView>
|
||||
|
||||
class TrafficTreeHeaderView : public QHeaderView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrafficTreeHeaderView(GList ** recentColumnList, QWidget * parent = nullptr);
|
||||
~TrafficTreeHeaderView();
|
||||
|
||||
void applyRecent();
|
||||
|
||||
signals:
|
||||
void columnsHaveChanged(QList<int> visible);
|
||||
|
||||
private:
|
||||
GList ** _recentColumnList;
|
||||
|
||||
private slots:
|
||||
void headerContextMenu(const QPoint &pos);
|
||||
void columnTriggered(bool checked = false);
|
||||
|
||||
};
|
||||
|
||||
|
||||
class TrafficTree : public QTreeView
|
||||
{
|
||||
|
@ -35,7 +60,7 @@ public:
|
|||
CLIPBOARD_JSON /* export as JSON */
|
||||
} eTrafficTreeClipboard;
|
||||
|
||||
TrafficTree(QString baseName, QWidget *parent = nullptr);
|
||||
TrafficTree(QString baseName, GList ** recentColumnList, QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Create a menu containing clipboard copy entries for this tab
|
||||
|
@ -48,12 +73,16 @@ public:
|
|||
*/
|
||||
QMenu * createCopyMenu(QWidget * parent = nullptr);
|
||||
|
||||
void applyRecentColumns();
|
||||
|
||||
signals:
|
||||
void filterAction(QString filter, FilterAction::Action action, FilterAction::ActionType type);
|
||||
void columnsHaveChanged(QList<int> columns);
|
||||
|
||||
public slots:
|
||||
void tapListenerEnabled(bool enable);
|
||||
void disableTap();
|
||||
void columnsChanged(QList<int> columns);
|
||||
|
||||
private:
|
||||
bool _tapEnabled;
|
||||
|
@ -61,18 +90,21 @@ private:
|
|||
bool _saveRaw;
|
||||
QString _baseName;
|
||||
|
||||
TrafficTreeHeaderView * _header;
|
||||
|
||||
ATapDataModel * dataModel();
|
||||
|
||||
QMenu * createActionSubMenu(FilterAction::Action cur_action, QModelIndex idx, bool isConversation);
|
||||
void copyToClipboard(eTrafficTreeClipboard type);
|
||||
|
||||
friend class TrafficTreeHeaderView;
|
||||
|
||||
private slots:
|
||||
void customContextMenu(const QPoint &pos);
|
||||
void useFilterAction();
|
||||
void clipboardAction();
|
||||
void resizeAction();
|
||||
void toggleSaveRawAction();
|
||||
|
||||
};
|
||||
|
||||
#endif // TRAFFIC_TREE_H
|
||||
|
|
20
ui/recent.c
20
ui/recent.c
|
@ -60,7 +60,9 @@
|
|||
#define RECENT_LAST_USED_PROFILE "gui.last_used_profile"
|
||||
#define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir"
|
||||
#define RECENT_GUI_CONVERSATION_TABS "gui.conversation_tabs"
|
||||
#define RECENT_GUI_CONVERSATION_TABS_COLUMNS "gui.conversation_tabs_columns"
|
||||
#define RECENT_GUI_ENDPOINT_TABS "gui.endpoint_tabs"
|
||||
#define RECENT_GUI_ENDPOINT_TABS_COLUMNS "gui.endpoint_tabs_columns"
|
||||
#define RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES "gui.rlc_pdus_from_mac_frames"
|
||||
#define RECENT_GUI_CUSTOM_COLORS "gui.custom_colors"
|
||||
#define RECENT_GUI_TOOLBAR_SHOW "gui.additional_toolbar_show"
|
||||
|
@ -918,12 +920,24 @@ write_profile_recent(void)
|
|||
fprintf(rf, RECENT_GUI_CONVERSATION_TABS ": %s\n", string_list);
|
||||
g_free(string_list);
|
||||
|
||||
fprintf(rf, "\n# Conversation dialog tabs columns.\n");
|
||||
fprintf(rf, "# List of conversation columns numbers.\n");
|
||||
string_list = join_string_list(recent.conversation_tabs_columns);
|
||||
fprintf(rf, RECENT_GUI_CONVERSATION_TABS_COLUMNS ": %s\n", string_list);
|
||||
g_free(string_list);
|
||||
|
||||
fprintf(rf, "\n# Open endpoint dialog tabs.\n");
|
||||
fprintf(rf, "# List of endpoint names, e.g. \"TCP\", \"IPv6\".\n");
|
||||
string_list = join_string_list(recent.endpoint_tabs);
|
||||
fprintf(rf, RECENT_GUI_ENDPOINT_TABS ": %s\n", string_list);
|
||||
g_free(string_list);
|
||||
|
||||
fprintf(rf, "\n# Endpoint dialog tabs columns.\n");
|
||||
fprintf(rf, "# List of endpoint columns numbers.\n");
|
||||
string_list = join_string_list(recent.endpoint_tabs_columns);
|
||||
fprintf(rf, RECENT_GUI_ENDPOINT_TABS_COLUMNS ": %s\n", string_list);
|
||||
g_free(string_list);
|
||||
|
||||
write_recent_boolean(rf, "For RLC stats, whether to use RLC PDUs found inside MAC frames",
|
||||
RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES,
|
||||
recent.gui_rlc_use_pdus_from_mac);
|
||||
|
@ -1122,8 +1136,12 @@ read_set_recent_pair_static(gchar *key, const gchar *value,
|
|||
recent.has_gui_geometry_main_lower_pane = TRUE;
|
||||
} else if (strcmp(key, RECENT_GUI_CONVERSATION_TABS) == 0) {
|
||||
recent.conversation_tabs = prefs_get_string_list(value);
|
||||
} else if (strcmp(key, RECENT_GUI_CONVERSATION_TABS_COLUMNS) == 0) {
|
||||
recent.conversation_tabs_columns = prefs_get_string_list(value);
|
||||
} else if (strcmp(key, RECENT_GUI_ENDPOINT_TABS) == 0) {
|
||||
recent.endpoint_tabs = prefs_get_string_list(value);
|
||||
} else if (strcmp(key, RECENT_GUI_ENDPOINT_TABS_COLUMNS) == 0) {
|
||||
recent.endpoint_tabs_columns = prefs_get_string_list(value);
|
||||
} else if (strcmp(key, RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES) == 0) {
|
||||
parse_recent_boolean(value, &recent.gui_rlc_use_pdus_from_mac);
|
||||
} else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) {
|
||||
|
@ -1611,6 +1629,8 @@ recent_cleanup(void)
|
|||
g_list_free_full(recent.gui_additional_toolbars, g_free);
|
||||
g_list_free_full(recent.interface_toolbars, g_free);
|
||||
prefs_clear_string_list(recent.conversation_tabs);
|
||||
prefs_clear_string_list(recent.conversation_tabs_columns);
|
||||
prefs_clear_string_list(recent.endpoint_tabs);
|
||||
prefs_clear_string_list(recent.endpoint_tabs_columns);
|
||||
prefs_clear_string_list(recent.custom_colors);
|
||||
}
|
||||
|
|
|
@ -128,7 +128,9 @@ typedef struct recent_settings_tag {
|
|||
gboolean sys_warn_if_no_capture;
|
||||
GList *col_width_list; /* column widths */
|
||||
GList *conversation_tabs; /* enabled conversation dialog tabs */
|
||||
GList *conversation_tabs_columns; /* save the columns for conversation dialogs */
|
||||
GList *endpoint_tabs; /* enabled endpoint dialog tabs */
|
||||
GList *endpoint_tabs_columns; /* save the columns for endpoint dialogs */
|
||||
gchar *gui_fileopen_remembered_dir; /* folder of last capture loaded in File Open dialog */
|
||||
gboolean gui_rlc_use_pdus_from_mac;
|
||||
GList *custom_colors;
|
||||
|
|
Loading…
Reference in New Issue