aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2017-12-29 11:23:07 -0500
committerRoland Knall <rknall@gmail.com>2018-01-04 21:20:59 +0000
commitd239da264c5d0ca2ecfd609ae3eccced939a4c46 (patch)
treeaa5b490fa2d9c1b4b6899a411bbcca03ccc0659d /ui
parenta79b7986cddf40a8ade57638916951323fff581e (diff)
Convert preference dialog to use more models.
Convert Advanced view and Modules view to use a single base model, loading the preferences once and then filter and display what they need with QSortFilterProxyModel derived classes. Convert the PreferencePane "types" to just strings. This allows a more straightforward relationship between the "special" modules that need custom widgets for preference manipulation and it also removes dependency on preferences_dialog.h for many files. Change-Id: I091deb3061564aa4d1564e9ca1c792715961b083 Reviewed-on: https://code.wireshark.org/review/25134 Reviewed-by: Michael Mann <mmann78@netscape.net> Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/qt/CMakeLists.txt6
-rw-r--r--ui/qt/Makefile.am6
-rw-r--r--ui/qt/capture_interfaces_dialog.h2
-rw-r--r--ui/qt/capture_preferences_frame.cpp1
-rw-r--r--ui/qt/capture_preferences_frame.h4
-rw-r--r--ui/qt/filter_expression_frame.cpp17
-rw-r--r--ui/qt/filter_expression_frame.h17
-rw-r--r--ui/qt/font_color_preferences_frame.cpp16
-rw-r--r--ui/qt/font_color_preferences_frame.h4
-rw-r--r--ui/qt/layout_preferences_frame.cpp17
-rw-r--r--ui/qt/layout_preferences_frame.h2
-rw-r--r--ui/qt/main_window.cpp12
-rw-r--r--ui/qt/main_window.h5
-rw-r--r--ui/qt/main_window_preferences_frame.cpp15
-rw-r--r--ui/qt/main_window_preferences_frame.h16
-rw-r--r--ui/qt/main_window_slots.cpp22
-rw-r--r--ui/qt/models/pref_delegate.cpp270
-rw-r--r--ui/qt/models/pref_delegate.h54
-rw-r--r--ui/qt/models/pref_models.cpp768
-rw-r--r--ui/qt/models/pref_models.h173
-rw-r--r--ui/qt/packet_list.cpp3
-rw-r--r--ui/qt/packet_list.h17
-rw-r--r--ui/qt/preferences_dialog.cpp819
-rw-r--r--ui/qt/preferences_dialog.h65
-rw-r--r--ui/qt/preferences_dialog.ui78
-rw-r--r--ui/qt/widgets/display_filter_edit.cpp18
-rw-r--r--ui/qt/widgets/display_filter_edit.h17
-rw-r--r--ui/qt/widgets/pref_module_view.cpp117
-rw-r--r--ui/qt/widgets/pref_module_view.h48
29 files changed, 1576 insertions, 1033 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 609971922b..1b3ee4a829 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -44,6 +44,7 @@ set(WIRESHARK_WIDGET_HEADERS
widgets/interface_toolbar_lineedit.h
widgets/label_stack.h
widgets/overlay_scroll_bar.h
+ widgets/pref_module_view.h
widgets/qcustomplot.h
widgets/stock_icon_tool_button.h
widgets/syntax_line_edit.h
@@ -84,6 +85,8 @@ set(WIRESHARK_MODEL_HEADERS
models/packet_list_record.h
models/path_chooser_delegate.h
models/percent_bar_delegate.h
+ models/pref_delegate.h
+ models/pref_models.h
models/proto_tree_model.h
models/related_packet_delegate.h
models/sparkline_delegate.h
@@ -267,6 +270,7 @@ set(WIRESHARK_WIDGET_SRCS
widgets/interface_toolbar_lineedit.cpp
widgets/label_stack.cpp
widgets/overlay_scroll_bar.cpp
+ widgets/pref_module_view.cpp
widgets/qcustomplot.cpp
widgets/stock_icon_tool_button.cpp
widgets/syntax_line_edit.cpp
@@ -304,6 +308,8 @@ set(WIRESHARK_MODEL_SRCS
models/packet_list_record.cpp
models/path_chooser_delegate.cpp
models/percent_bar_delegate.cpp
+ models/pref_delegate.cpp
+ models/pref_models.cpp
models/proto_tree_model.cpp
models/related_packet_delegate.cpp
models/sparkline_delegate.cpp
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index 6c467895c4..bed07d6a61 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -174,6 +174,7 @@ MOC_WIDGET_HDRS = \
widgets/interface_toolbar_lineedit.h \
widgets/label_stack.h \
widgets/overlay_scroll_bar.h \
+ widgets/pref_module_view.h \
widgets/syntax_line_edit.h \
widgets/stock_icon_tool_button.h \
widgets/tabnav_tree_view.h \
@@ -213,6 +214,8 @@ MOC_MODELS_HDRS = \
models/packet_list_record.h \
models/path_chooser_delegate.h \
models/percent_bar_delegate.h \
+ models/pref_delegate.h \
+ models/pref_models.h \
models/proto_tree_model.h \
models/related_packet_delegate.h \
models/sparkline_delegate.h \
@@ -511,6 +514,7 @@ WIRESHARK_QT_WIDGET_SRC = \
widgets/interface_toolbar_lineedit.cpp \
widgets/label_stack.cpp \
widgets/overlay_scroll_bar.cpp \
+ widgets/pref_module_view.cpp \
widgets/stock_icon_tool_button.cpp \
widgets/syntax_line_edit.cpp \
widgets/tabnav_tree_view.cpp \
@@ -546,6 +550,8 @@ WIRESHARK_QT_MODELS_SRCS = \
models/packet_list_record.cpp \
models/path_chooser_delegate.cpp \
models/percent_bar_delegate.cpp \
+ models/pref_delegate.cpp \
+ models/pref_models.cpp \
models/proto_tree_model.cpp \
models/related_packet_delegate.cpp \
models/sparkline_delegate.cpp \
diff --git a/ui/qt/capture_interfaces_dialog.h b/ui/qt/capture_interfaces_dialog.h
index 22843b6443..70ff71947d 100644
--- a/ui/qt/capture_interfaces_dialog.h
+++ b/ui/qt/capture_interfaces_dialog.h
@@ -35,8 +35,6 @@
typedef struct if_stat_cache_s if_stat_cache_t;
-#include "preferences_dialog.h"
-
namespace Ui {
class CaptureInterfacesDialog;
}
diff --git a/ui/qt/capture_preferences_frame.cpp b/ui/qt/capture_preferences_frame.cpp
index 3791edb7a7..2a7baf9c5d 100644
--- a/ui/qt/capture_preferences_frame.cpp
+++ b/ui/qt/capture_preferences_frame.cpp
@@ -28,6 +28,7 @@
#endif
#include "capture_preferences_frame.h"
+#include <ui/qt/models/pref_models.h>
#include <ui_capture_preferences_frame.h>
#include "wireshark_application.h"
diff --git a/ui/qt/capture_preferences_frame.h b/ui/qt/capture_preferences_frame.h
index 8410291207..1932396a9a 100644
--- a/ui/qt/capture_preferences_frame.h
+++ b/ui/qt/capture_preferences_frame.h
@@ -22,10 +22,10 @@
#ifndef CAPTURE_PREFERENCES_FRAME_H
#define CAPTURE_PREFERENCES_FRAME_H
-#include "preferences_dialog.h"
-
#include <QFrame>
+#include <epan/prefs.h>
+
namespace Ui {
class CapturePreferencesFrame;
}
diff --git a/ui/qt/filter_expression_frame.cpp b/ui/qt/filter_expression_frame.cpp
index 322c750f0f..c82d4ec943 100644
--- a/ui/qt/filter_expression_frame.cpp
+++ b/ui/qt/filter_expression_frame.cpp
@@ -4,19 +4,7 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include "filter_expression_frame.h"
@@ -27,6 +15,7 @@
#include <ui/preference_utils.h>
#include <ui/qt/models/uat_model.h>
+#include <ui/qt/models/pref_models.h>
#include <QPushButton>
#include <QKeyEvent>
@@ -115,7 +104,7 @@ void FilterExpressionFrame::updateWidgets()
void FilterExpressionFrame::on_filterExpressionPreferencesPushButton_clicked()
{
on_buttonBox_rejected();
- emit showPreferencesDialog(PreferencesDialog::ppFilterExpressions);
+ emit showPreferencesDialog(PrefsModel::FILTER_BUTTONS_PREFERENCE_TREE_NAME);
}
void FilterExpressionFrame::on_labelLineEdit_textChanged(const QString)
diff --git a/ui/qt/filter_expression_frame.h b/ui/qt/filter_expression_frame.h
index 8394537a59..dc2013301c 100644
--- a/ui/qt/filter_expression_frame.h
+++ b/ui/qt/filter_expression_frame.h
@@ -4,26 +4,13 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef FILTER_EXPRESSION_FRAME_H
#define FILTER_EXPRESSION_FRAME_H
#include "accordion_frame.h"
-#include "preferences_dialog.h"
namespace Ui {
class FilterExpressionFrame;
@@ -41,7 +28,7 @@ public:
void editExpression(int exprIdx);
signals:
- void showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane);
+ void showPreferencesDialog(QString pane_name);
void filterExpressionsChanged();
void pushFilterSyntaxStatus(const QString&);
diff --git a/ui/qt/font_color_preferences_frame.cpp b/ui/qt/font_color_preferences_frame.cpp
index e3b7ea866c..908d3b25fc 100644
--- a/ui/qt/font_color_preferences_frame.cpp
+++ b/ui/qt/font_color_preferences_frame.cpp
@@ -4,24 +4,14 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
+#include <config.h>
#include <ui/qt/utils/qt_ui_utils.h>
#include "font_color_preferences_frame.h"
+#include <ui/qt/models/pref_models.h>
#include <ui_font_color_preferences_frame.h>
#include <ui/qt/utils/color_utils.h>
#include "wireshark_application.h"
diff --git a/ui/qt/font_color_preferences_frame.h b/ui/qt/font_color_preferences_frame.h
index 9255472c95..10d44f9611 100644
--- a/ui/qt/font_color_preferences_frame.h
+++ b/ui/qt/font_color_preferences_frame.h
@@ -22,11 +22,11 @@
#ifndef FONT_COLOR_PREFERENCES_FRAME_H
#define FONT_COLOR_PREFERENCES_FRAME_H
-#include "preferences_dialog.h"
-
#include <QFrame>
#include <QFont>
+#include <epan/prefs.h>
+
namespace Ui {
class FontColorPreferencesFrame;
}
diff --git a/ui/qt/layout_preferences_frame.cpp b/ui/qt/layout_preferences_frame.cpp
index 0ac1571ca4..f003eccb1e 100644
--- a/ui/qt/layout_preferences_frame.cpp
+++ b/ui/qt/layout_preferences_frame.cpp
@@ -4,21 +4,11 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
+#include <config.h>
+
#include "layout_preferences_frame.h"
#include <ui_layout_preferences_frame.h>
@@ -28,6 +18,7 @@
#include <QDebug>
#include <epan/prefs-int.h>
+#include <ui/qt/models/pref_models.h>
LayoutPreferencesFrame::LayoutPreferencesFrame(QWidget *parent) :
QFrame(parent),
diff --git a/ui/qt/layout_preferences_frame.h b/ui/qt/layout_preferences_frame.h
index c0dacbe76c..85bb8c0c14 100644
--- a/ui/qt/layout_preferences_frame.h
+++ b/ui/qt/layout_preferences_frame.h
@@ -22,7 +22,7 @@
#ifndef LAYOUT_PREFERENCES_FRAME_H
#define LAYOUT_PREFERENCES_FRAME_H
-#include "preferences_dialog.h"
+#include <epan/prefs.h>
#include <QFrame>
#include <QAbstractButton>
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index ce51e4863a..6bd39de22a 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -372,8 +372,8 @@ MainWindow::MainWindow(QWidget *parent) :
connect(df_edit, SIGNAL(pushFilterSyntaxWarning(const QString&)),
main_ui_->statusBar, SLOT(pushTemporaryStatus(const QString&)));
connect(df_edit, SIGNAL(filterPackets(QString,bool)), this, SLOT(filterPackets(QString,bool)));
- connect(df_edit, SIGNAL(showPreferencesDialog(PreferencesDialog::PreferencesPane)),
- this, SLOT(showPreferencesDialog(PreferencesDialog::PreferencesPane)));
+ connect(df_edit, SIGNAL(showPreferencesDialog(QString)),
+ this, SLOT(showPreferencesDialog(QString)));
connect(wsApp, SIGNAL(preferencesChanged()), df_edit, SLOT(checkFilter()));
funnel_statistics_ = new FunnelStatistics(this, capture_file_);
@@ -572,8 +572,8 @@ MainWindow::MainWindow(QWidget *parent) :
this, SLOT(showPreferencesDialog(QString)));
connect(main_ui_->preferenceEditorFrame, SIGNAL(showProtocolPreferences(QString)),
this, SLOT(showPreferencesDialog(QString)));
- connect(main_ui_->filterExpressionFrame, SIGNAL(showPreferencesDialog(PreferencesDialog::PreferencesPane)),
- this, SLOT(showPreferencesDialog(PreferencesDialog::PreferencesPane)));
+ connect(main_ui_->filterExpressionFrame, SIGNAL(showPreferencesDialog(QString)),
+ this, SLOT(showPreferencesDialog(QString)));
connect(main_ui_->filterExpressionFrame, SIGNAL(filterExpressionsChanged()),
this, SLOT(filterExpressionsChanged()));
@@ -622,8 +622,8 @@ MainWindow::MainWindow(QWidget *parent) :
this, SIGNAL(frameSelected(int)));
connect(packet_list_, SIGNAL(packetDissectionChanged()),
this, SLOT(redissectPackets()));
- connect(packet_list_, SIGNAL(showColumnPreferences(PreferencesDialog::PreferencesPane)),
- this, SLOT(showPreferencesDialog(PreferencesDialog::PreferencesPane)));
+ connect(packet_list_, SIGNAL(showColumnPreferences(QString)),
+ this, SLOT(showPreferencesDialog(QString)));
connect(packet_list_, SIGNAL(showProtocolPreferences(QString)),
this, SLOT(showPreferencesDialog(QString)));
connect(packet_list_, SIGNAL(editProtocolPreference(preference*,pref_module*)),
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index d3a01e0bd7..7bb2255545 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -46,7 +46,7 @@
#include <ui/qt/widgets/display_filter_combo.h>
#include "filter_action.h"
#include "follow_stream_dialog.h"
-#include "preferences_dialog.h"
+#include <ui/qt/models/pref_models.h>
class AccordionFrame;
class ByteViewTab;
@@ -452,8 +452,7 @@ private slots:
void on_actionEditPacketComment_triggered();
void on_actionDeleteAllPacketComments_triggered();
void on_actionEditConfigurationProfiles_triggered();
- void showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane = PreferencesDialog::ppAppearance);
- void showPreferencesDialog(QString module_name);
+ void showPreferencesDialog(QString pane_name);
void on_actionEditPreferences_triggered();
void showHideMainWidgets(QAction *action);
diff --git a/ui/qt/main_window_preferences_frame.cpp b/ui/qt/main_window_preferences_frame.cpp
index 3bd0eac6ef..182c13d151 100644
--- a/ui/qt/main_window_preferences_frame.cpp
+++ b/ui/qt/main_window_preferences_frame.cpp
@@ -4,19 +4,7 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include "wireshark_application.h"
@@ -27,6 +15,7 @@
#include "ui/language.h"
#include <epan/prefs-int.h>
+#include <ui/qt/models/pref_models.h>
#include <wsutil/filesystem.h>
#include <QFileDialog>
diff --git a/ui/qt/main_window_preferences_frame.h b/ui/qt/main_window_preferences_frame.h
index 4ee39023d7..230bc5c6c0 100644
--- a/ui/qt/main_window_preferences_frame.h
+++ b/ui/qt/main_window_preferences_frame.h
@@ -4,25 +4,13 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef MAIN_WINDOW_PREFERENCES_FRAME_H
#define MAIN_WINDOW_PREFERENCES_FRAME_H
-#include "preferences_dialog.h"
+#include <epan/prefs.h>
#include <QFrame>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 9fd932af26..c3e4775474 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -2332,27 +2332,13 @@ void MainWindow::on_actionEditConfigurationProfiles_triggered()
cp_dialog.exec();
}
-void MainWindow::showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane)
+void MainWindow::showPreferencesDialog(QString pane_name)
{
PreferencesDialog pref_dialog(this);
saveWindowGeometry(); // Save in case the layout panes are rearranged
- pref_dialog.setPane(start_pane);
- pref_dialog.exec();
-
- // Emitting PacketDissectionChanged directly from a QDialog can cause
- // problems on macOS.
- wsApp->flushAppSignals();
-}
-
-void MainWindow::showPreferencesDialog(QString module_name)
-{
- PreferencesDialog pref_dialog(this);
-
- saveWindowGeometry(); // Save in case the layout panes are rearranged
-
- pref_dialog.setPane(module_name);
+ pref_dialog.setPane(pane_name);
pref_dialog.exec();
// Emitting PacketDissectionChanged directly from a QDialog can cause
@@ -2362,7 +2348,7 @@ void MainWindow::showPreferencesDialog(QString module_name)
void MainWindow::on_actionEditPreferences_triggered()
{
- showPreferencesDialog();
+ showPreferencesDialog(PrefsModel::APPEARANCE_PREFERENCE_TREE_NAME);
}
// View Menu
@@ -4059,7 +4045,7 @@ void MainWindow::filterToolbarCustomMenuHandler(const QPoint& pos)
void MainWindow::filterToolbarShowPreferences()
{
- emit showPreferencesDialog(PreferencesDialog::ppFilterExpressions);
+ emit showPreferencesDialog(PrefsModel::FILTER_BUTTONS_PREFERENCE_TREE_NAME);
}
int MainWindow::uatRowIndexForFilterExpression(QString label, QString expression)
diff --git a/ui/qt/models/pref_delegate.cpp b/ui/qt/models/pref_delegate.cpp
new file mode 100644
index 0000000000..8a4b83a68f
--- /dev/null
+++ b/ui/qt/models/pref_delegate.cpp
@@ -0,0 +1,270 @@
+/* pref_delegate.cpp
+ * Delegates for editing prefereneces.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <ui/qt/models/pref_delegate.h>
+#include <epan/prefs-int.h>
+
+#include <QComboBox>
+#include <QFileDialog>
+#include <QLineEdit>
+#include <QColorDialog>
+
+#include "uat_dialog.h"
+#include "wireshark_application.h"
+
+#include <ui/qt/widgets/editor_file_dialog.h>
+
+RangeSyntaxLineEdit::RangeSyntaxLineEdit(QWidget *parent)
+ : SyntaxLineEdit(parent),
+ maxRange_(0xFFFFFFFF)
+{
+ connect(this, SIGNAL(textChanged(QString)), this, SLOT(checkRange(QString)));
+}
+
+void RangeSyntaxLineEdit::checkRange(QString range)
+{
+ if (range.isEmpty()) {
+ setSyntaxState(SyntaxLineEdit::Empty);
+ return;
+ }
+
+ range_t *newrange;
+ convert_ret_t ret = range_convert_str(NULL, &newrange, range.toUtf8().constData(), maxRange_);
+
+ if (ret == CVT_NO_ERROR) {
+ setSyntaxState(SyntaxLineEdit::Valid);
+ wmem_free(NULL, newrange);
+ } else {
+ setSyntaxState(SyntaxLineEdit::Invalid);
+ }
+}
+
+
+
+
+AdvancedPrefDelegate::AdvancedPrefDelegate(QObject *parent) : QStyledItemDelegate(parent)
+{
+}
+
+PrefsItem* AdvancedPrefDelegate::indexToPref(const QModelIndex &index) const
+{
+ const QVariant v = index.model()->data(index, Qt::UserRole);
+ return VariantPointer<PrefsItem>::asPtr(v);
+}
+
+QWidget *AdvancedPrefDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
+{
+ PrefsItem* pref;
+ QString filename;
+
+ switch(index.column())
+ {
+ case AdvancedPrefsModel::colName:
+ case AdvancedPrefsModel::colStatus:
+ case AdvancedPrefsModel::colType:
+ //If user clicks on any of these columns, reset preference back to default
+ //There is no need to launch an editor
+ ((QAbstractItemModel*)index.model())->setData(index, QVariant(), Qt::EditRole);
+ break;
+ case AdvancedPrefsModel::colValue:
+ pref = indexToPref(index);
+ switch(pref->getPrefType())
+ {
+ case PREF_DECODE_AS_UINT:
+ case PREF_UINT:
+ {
+ QLineEdit* editor = new QLineEdit(parent);
+#if 0
+ //XXX - Do we want some help handling formatting the number?
+ editor->setInputMask("0000000009;");
+#endif
+ return editor;
+ }
+ case PREF_BOOL:
+ //Setting any non-NULL value will invert boolean value
+ ((QAbstractItemModel*)index.model())->setData(index, QString("BOOL"), Qt::EditRole);
+ break;
+ case PREF_ENUM:
+ {
+ QComboBox* editor = new QComboBox(parent);
+ return editor;
+ }
+ case PREF_STRING:
+ {
+ //Separated from UINT in case formatting needs to be applied to UINT
+ QLineEdit* editor = new QLineEdit(parent);
+ return editor;
+ }
+ case PREF_DECODE_AS_RANGE:
+ case PREF_RANGE:
+ {
+ RangeSyntaxLineEdit *editor = new RangeSyntaxLineEdit(parent);
+ return editor;
+ }
+ case PREF_UAT:
+ {
+ if (pref->getPrefGUIType() == GUI_ALL || pref->getPrefGUIType() == GUI_QT) {
+ UatDialog uat_dlg(parent, prefs_get_uat_value(pref->getPref()));
+ uat_dlg.exec();
+ }
+ }
+ break;
+ case PREF_SAVE_FILENAME:
+ filename = QFileDialog::getSaveFileName(parent, wsApp->windowTitleString(prefs_get_title(pref->getPref())),
+ index.model()->data(index, Qt::DisplayRole).toString());
+ if (!filename.isEmpty()) {
+ ((QAbstractItemModel*)index.model())->setData(index, QDir::toNativeSeparators(filename), Qt::EditRole);
+ }
+ break;
+ case PREF_OPEN_FILENAME:
+ filename = QFileDialog::getOpenFileName(parent, wsApp->windowTitleString(prefs_get_title(pref->getPref())),
+ index.model()->data(index, Qt::DisplayRole).toString());
+ if (!filename.isEmpty()) {
+ ((QAbstractItemModel*)index.model())->setData(index, QDir::toNativeSeparators(filename), Qt::EditRole);
+ }
+ break;
+ case PREF_DIRNAME:
+ filename = QFileDialog::getExistingDirectory(parent, wsApp->windowTitleString(prefs_get_title(pref->getPref())),
+ index.model()->data(index, Qt::DisplayRole).toString());
+ if (!filename.isEmpty()) {
+ ((QAbstractItemModel*)index.model())->setData(index, QDir::toNativeSeparators(filename), Qt::EditRole);
+ }
+ break;
+ case PREF_COLOR:
+ {
+ QColorDialog color_dlg;
+ color_t color = *prefs_get_color_value(pref->getPref(), pref_stashed);
+
+ color_dlg.setCurrentColor(QColor(
+ color.red >> 8,
+ color.green >> 8,
+ color.blue >> 8
+ ));
+ if (color_dlg.exec() == QDialog::Accepted) {
+ ((QAbstractItemModel*)index.model())->setData(index, color_dlg.currentColor().name(), Qt::EditRole);
+ }
+ break;
+ }
+
+ }
+ break;
+ }
+
+ return 0;
+}
+
+void AdvancedPrefDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
+{
+ PrefsItem* pref = indexToPref(index);
+
+ switch(pref->getPrefType())
+ {
+ case PREF_DECODE_AS_UINT:
+ case PREF_UINT:
+ {
+ QLineEdit* line = static_cast<QLineEdit*>(editor);
+ line->setText(index.model()->data(index, Qt::DisplayRole).toString());
+ }
+ break;
+ case PREF_ENUM:
+ {
+ QComboBox* combo = static_cast<QComboBox*>(editor);
+ const enum_val_t *ev;
+ PrefsItem* pref = VariantPointer<PrefsItem>::asPtr(index.model()->data(index, Qt::UserRole));
+ for (ev = prefs_get_enumvals(pref->getPref()); ev && ev->description; ev++) {
+ combo->addItem(ev->description, QVariant(ev->value));
+ if (prefs_get_enum_value(pref->getPref(), pref_stashed) == ev->value)
+ combo->setCurrentIndex(combo->count() - 1);
+ }
+ }
+ break;
+ case PREF_STRING:
+ {
+ QLineEdit* line = static_cast<QLineEdit*>(editor);
+ line->setText(index.model()->data(index, Qt::DisplayRole).toString());
+ }
+ break;
+ case PREF_DECODE_AS_RANGE:
+ case PREF_RANGE:
+ {
+ RangeSyntaxLineEdit* syntax = static_cast<RangeSyntaxLineEdit*>(editor);
+ syntax->setText(index.model()->data(index, Qt::DisplayRole).toString());
+ }
+ break;
+ case PREF_UAT:
+ case PREF_SAVE_FILENAME:
+ case PREF_OPEN_FILENAME:
+ case PREF_DIRNAME:
+ case PREF_COLOR:
+ //Handled by the dialogs created
+ break;
+ default:
+ //Ensure any new preference types are handled
+ Q_ASSERT(FALSE);
+ break;
+ }
+}
+
+void AdvancedPrefDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+ PrefsItem* pref = indexToPref(index);
+ switch(pref->getPrefType())
+ {
+ case PREF_DECODE_AS_UINT:
+ case PREF_UINT:
+ case PREF_STRING:
+ {
+ QLineEdit* line = static_cast<QLineEdit*>(editor);
+ model->setData(index, line->text(), Qt::EditRole);
+ break;
+ }
+ case PREF_ENUM:
+ {
+ QComboBox* combo = static_cast<QComboBox*>(editor);
+ model->setData(index, combo->itemData(combo->currentIndex()), Qt::EditRole);
+ }
+ break;
+ case PREF_DECODE_AS_RANGE:
+ case PREF_RANGE:
+ {
+ RangeSyntaxLineEdit* syntax = static_cast<RangeSyntaxLineEdit*>(editor);
+ model->setData(index, syntax->text(), Qt::EditRole);
+ break;
+ }
+ case PREF_UAT:
+ //do nothing because UAT values aren't shown in table
+ break;
+ case PREF_SAVE_FILENAME:
+ case PREF_OPEN_FILENAME:
+ case PREF_DIRNAME:
+ case PREF_COLOR:
+ //do nothing, dialog signals will update table
+ pref = NULL;
+ break;
+ default:
+ //Ensure any new preference types are handled
+ Q_ASSERT(FALSE);
+ break;
+ }
+}
+
+/* * 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:
+ */
diff --git a/ui/qt/models/pref_delegate.h b/ui/qt/models/pref_delegate.h
new file mode 100644
index 0000000000..1f693e6ade
--- /dev/null
+++ b/ui/qt/models/pref_delegate.h
@@ -0,0 +1,54 @@
+/* pref_delegate.h
+ * Delegates for editing prefereneces.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef PREF_DELEGATE_H
+#define PREF_DELEGATE_H
+
+#include <config.h>
+
+#include <ui/qt/models/pref_models.h>
+#include <ui/qt/widgets/syntax_line_edit.h>
+
+#include <QStyledItemDelegate>
+#include <QModelIndex>
+
+class AdvancedPrefDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ AdvancedPrefDelegate(QObject *parent = 0);
+
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const;
+ void setEditorData(QWidget *editor, const QModelIndex &index) const;
+ void setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const;
+
+private:
+ PrefsItem* indexToPref(const QModelIndex &index) const;
+};
+
+//Utility class for range preferences
+class RangeSyntaxLineEdit : public SyntaxLineEdit
+{
+ Q_OBJECT
+public:
+ explicit RangeSyntaxLineEdit(QWidget *parent = 0);
+ void setMaxRange(unsigned int max) {maxRange_ = max;}
+
+public slots:
+ void checkRange(QString range);
+
+private:
+ unsigned int maxRange_;
+};
+
+#endif // PREF_DELEGATE_H
diff --git a/ui/qt/models/pref_models.cpp b/ui/qt/models/pref_models.cpp
new file mode 100644
index 0000000000..5c37035ab4
--- /dev/null
+++ b/ui/qt/models/pref_models.cpp
@@ -0,0 +1,768 @@
+/* pref_models.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <ui/qt/models/pref_models.h>
+#include <ui/qt/utils/qt_ui_utils.h>
+#include <epan/prefs-int.h>
+
+#ifdef HAVE_LIBPCAP
+#ifdef _WIN32
+#include "caputils/capture-wpcap.h"
+#endif /* _WIN32 */
+#endif /* HAVE_LIBPCAP */
+
+#include <QFont>
+#include <QColor>
+
+// XXX Should we move this to ui/preference_utils?
+static GHashTable * pref_ptr_to_pref_ = NULL;
+pref_t *prefFromPrefPtr(void *pref_ptr)
+{
+ return (pref_t *)g_hash_table_lookup(pref_ptr_to_pref_, (gpointer) pref_ptr);
+}
+
+static void prefInsertPrefPtr(void * pref_ptr, pref_t * pref)
+{
+ if ( ! pref_ptr_to_pref_ )
+ pref_ptr_to_pref_ = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
+
+ gpointer key = (gpointer) pref_ptr;
+ gpointer val = (gpointer) pref;
+
+ /* Already existing entries will be ignored */
+ if ( (pref = (pref_t *)g_hash_table_lookup(pref_ptr_to_pref_, key) ) == NULL )
+ g_hash_table_insert(pref_ptr_to_pref_, key, val);
+}
+
+PrefsItem::PrefsItem(module_t *module, pref_t *pref, PrefsItem* parent)
+ : ModelHelperTreeItem<PrefsItem>(parent),
+ pref_(pref),
+ module_(module),
+ changed_(false)
+{
+ name_ = QString(module->name ? module->name : module->parent->name);
+ if (pref_ != NULL) {
+ name_ += QString(".%1").arg(prefs_get_name(pref_));
+ }
+}
+
+PrefsItem::PrefsItem(QString name, PrefsItem* parent)
+ : ModelHelperTreeItem<PrefsItem>(parent),
+ pref_(NULL),
+ module_(NULL),
+ name_(name),
+ changed_(false)
+{
+
+}
+
+PrefsItem::~PrefsItem()
+{
+}
+
+int PrefsItem::getPrefType() const
+{
+ if (pref_ == NULL)
+ return 0;
+
+ return prefs_get_type(pref_);
+}
+
+int PrefsItem::getPrefGUIType() const
+{
+ if (pref_ == NULL)
+ return GUI_ALL;
+
+ return prefs_get_gui_type(pref_);
+}
+
+bool PrefsItem::isPrefDefault() const
+{
+ if (pref_ == NULL)
+ return true;
+
+ if (changed_ == false)
+ return prefs_pref_is_default(pref_) ? true : false;
+
+ return false;
+}
+
+QString PrefsItem::getPrefTypeName() const
+{
+ if (pref_ == NULL)
+ return "";
+
+ return QString(prefs_pref_type_name(pref_));
+}
+
+QString PrefsItem::getModuleName() const
+{
+ if (module_ == NULL)
+ return name_;
+
+ return QString(module_->name);
+}
+
+
+void PrefsItem::setChanged(bool changed)
+{
+ changed_ = changed;
+}
+
+
+const char* PrefsModel::ADVANCED_PREFERENCE_TREE_NAME = "Advanced";
+const char* PrefsModel::APPEARANCE_PREFERENCE_TREE_NAME = "Appearance";
+const char* PrefsModel::LAYOUT_PREFERENCE_TREE_NAME = "Layout";
+const char* PrefsModel::COLUMNS_PREFERENCE_TREE_NAME = "Columns";
+const char* PrefsModel::FONT_AND_COLORS_PREFERENCE_TREE_NAME = "Font and Colors";
+const char* PrefsModel::CAPTURE_PREFERENCE_TREE_NAME = "Capture";
+const char* PrefsModel::EXPERT_PREFERENCE_TREE_NAME = "Expert";
+const char* PrefsModel::FILTER_BUTTONS_PREFERENCE_TREE_NAME = "Filter Buttons";
+
+
+PrefsModel::PrefsModel(QObject *parent) :
+ QAbstractItemModel(parent),
+ root_(new PrefsItem(QString("ROOT"), NULL))
+{
+ populate();
+}
+
+PrefsModel::~PrefsModel()
+{
+ delete root_;
+}
+
+int PrefsModel::rowCount(const QModelIndex &parent) const
+{
+ PrefsItem *parent_item;
+ if (parent.column() > 0)
+ return 0;
+
+ if (!parent.isValid())
+ parent_item = root_;
+ else
+ parent_item = static_cast<PrefsItem*>(parent.internalPointer());
+
+ if (parent_item == NULL)
+ return 0;
+
+ return parent_item->childCount();
+}
+
+int PrefsModel::columnCount(const QModelIndex&) const
+{
+ return colLast;
+}
+
+
+QModelIndex PrefsModel::parent(const QModelIndex& index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ PrefsItem* item = static_cast<PrefsItem*>(index.internalPointer());
+ if (item != NULL) {
+ PrefsItem* parent_item = item->parentItem();
+ if (parent_item != NULL) {
+ if (parent_item == root_)
+ return QModelIndex();
+
+ return createIndex(parent_item->row(), 0, parent_item);
+ }
+ }
+
+ return QModelIndex();
+}
+
+QModelIndex PrefsModel::index(int row, int column, const QModelIndex& parent) const
+{
+ if (!hasIndex(row, column, parent))
+ return QModelIndex();
+
+ PrefsItem *parent_item, *child_item;
+
+ if (!parent.isValid())
+ parent_item = root_;
+ else
+ parent_item = static_cast<PrefsItem*>(parent.internalPointer());
+
+ Q_ASSERT(parent_item);
+
+ child_item = parent_item->child(row);
+ if (child_item) {
+ return createIndex(row, column, child_item);
+ }
+
+ return QModelIndex();
+}
+
+QVariant PrefsModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::UserRole))
+ return QVariant();
+
+ PrefsItem* item = static_cast<PrefsItem*>(index.internalPointer());
+ if (item == NULL)
+ return QVariant();
+
+ if (role == Qt::UserRole)
+ return VariantPointer<PrefsItem>::asQVariant(item);
+
+ switch ((enum PrefsModelColumn)index.column()) {
+ case colName:
+ return item->getName();
+
+ case colStatus:
+ if ((item->getPrefType() == PREF_UAT && (item->getPrefGUIType() == GUI_ALL || item->getPrefGUIType() == GUI_QT)) || item->getPrefType() == PREF_CUSTOM)
+ return QObject::tr("Unknown");
+
+ if (item->isPrefDefault())
+ return QObject::tr("Default");
+
+ return QObject::tr("Changed");
+ case colType:
+ return item->getPrefTypeName();
+ case colValue:
+ if (item->getPref() == NULL)
+ return QVariant();
+
+ return QString(gchar_free_to_qstring(prefs_pref_to_str(item->getPref(), pref_stashed)).remove(QRegExp("\n\t")));
+ default:
+ break;
+ }
+
+ return QVariant();
+}
+
+static guint
+fill_prefs(module_t *module, gpointer root_ptr)
+{
+ PrefsItem* root_item = static_cast<PrefsItem*>(root_ptr);
+
+ if ((module == NULL) || (root_item == NULL))
+ return 1;
+
+ if (module->numprefs < 1 && !prefs_module_has_submodules(module))
+ return 0;
+
+ PrefsItem* module_item = new PrefsItem(module, NULL, root_item);
+ root_item->appendChild(module_item);
+
+ for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) {
+ pref_t *pref = (pref_t *) pref_l->data;
+
+ if (prefs_get_type(pref) == PREF_OBSOLETE || prefs_get_type(pref) == PREF_STATIC_TEXT)
+ continue;
+
+ const char *type_name = prefs_pref_type_name(pref);
+ if (!type_name)
+ continue;
+
+ pref_stash(pref, NULL);
+
+ PrefsItem* item = new PrefsItem(module, pref, module_item);
+ module_item->appendChild(item);
+
+ // .uat is a void * so it wins the "useful key value" prize.
+ if (prefs_get_uat_value(pref)) {
+ prefInsertPrefPtr( prefs_get_uat_value(pref), pref);
+ }
+ }
+
+ if(prefs_module_has_submodules(module))
+ return prefs_modules_foreach_submodules(module, fill_prefs, module_item);
+
+ return 0;
+}
+
+void PrefsModel::populate()
+{
+ // Printing prefs don't apply here.
+ module_t *print_module = prefs_find_module("print");
+ if (print_module)
+ print_module->use_gui = FALSE;
+
+ //Since "expert" is really a pseudo protocol, it shouldn't be
+ //categorized with other "real" protocols when it comes to
+ //preferences. Since it's just a UAT, don't bury it in
+ //with the other protocols
+ module_t *expert_module = prefs_find_module("_ws.expert");
+ if (expert_module)
+ expert_module->use_gui = FALSE;
+
+ prefs_modules_foreach_submodules(NULL, fill_prefs, (gpointer)root_);
+
+ //Add the "specially handled" preferences
+ PrefsItem *appearance_item, *appearance_subitem, *special_item;
+
+ appearance_item = new PrefsItem(APPEARANCE_PREFERENCE_TREE_NAME, root_);
+ root_->appendChild(appearance_item);
+
+ appearance_subitem = new PrefsItem(LAYOUT_PREFERENCE_TREE_NAME, appearance_item);
+ appearance_item->appendChild(appearance_subitem);
+ appearance_subitem = new PrefsItem(COLUMNS_PREFERENCE_TREE_NAME, appearance_item);
+ appearance_item->appendChild(appearance_subitem);
+ appearance_subitem = new PrefsItem(FONT_AND_COLORS_PREFERENCE_TREE_NAME, appearance_item);
+ appearance_item->appendChild(appearance_subitem);
+
+ special_item = new PrefsItem(CAPTURE_PREFERENCE_TREE_NAME, root_);
+ root_->appendChild(special_item);
+ special_item = new PrefsItem(EXPERT_PREFERENCE_TREE_NAME, root_);
+ root_->appendChild(special_item);
+ special_item = new PrefsItem(FILTER_BUTTONS_PREFERENCE_TREE_NAME, root_);
+ root_->appendChild(special_item);
+ special_item = new PrefsItem(ADVANCED_PREFERENCE_TREE_NAME, root_);
+ root_->appendChild(special_item);
+}
+
+
+
+
+
+AdvancedPrefsModel::AdvancedPrefsModel(QObject * parent)
+: QSortFilterProxyModel(parent),
+filter_()
+{
+}
+
+QVariant AdvancedPrefsModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+
+ switch (section) {
+ case colName:
+ return tr("Name");
+ case colStatus:
+ return tr("Status");
+ case colType:
+ return tr("Type");
+ case colValue:
+ return tr("Value");
+ default:
+ break;
+ }
+ }
+ return QVariant();
+}
+
+QVariant AdvancedPrefsModel::data(const QModelIndex &dataindex, int role) const
+{
+ if (!dataindex.isValid())
+ return QVariant();
+
+ QModelIndex modelIndex = mapToSource(dataindex);
+
+ PrefsItem* item = static_cast<PrefsItem*>(modelIndex.internalPointer());
+ if (item == NULL)
+ return QVariant();
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch ((AdvancedPrefsModelColumn)dataindex.column())
+ {
+ case colName:
+ if (item->getPref() == NULL)
+ return item->getModule()->title;
+
+ return sourceModel()->data(sourceModel()->index(modelIndex.row(), PrefsModel::colName, modelIndex.parent()), role);
+ case colStatus:
+ if (item->getPref() == NULL)
+ return QVariant();
+
+ return sourceModel()->data(sourceModel()->index(modelIndex.row(), PrefsModel::colStatus, modelIndex.parent()), role);
+ case colType:
+ if (item->getPref() == NULL)
+ return QVariant();
+
+ return sourceModel()->data(sourceModel()->index(modelIndex.row(), PrefsModel::colType, modelIndex.parent()), role);
+ case colValue:
+ if (item->getPref() == NULL)
+ return QVariant();
+
+ return sourceModel()->data(sourceModel()->index(modelIndex.row(), PrefsModel::colValue, modelIndex.parent()), role);
+ default:
+ break;
+ }
+ break;
+ case Qt::ToolTipRole:
+ switch ((AdvancedPrefsModelColumn)dataindex.column())
+ {
+ case colName:
+ if (item->getPref() == NULL)
+ return QString("<span>%1</span>").arg(item->getModule()->description);
+
+ return QString("<span>%1</span>").arg(prefs_get_description(item->getPref()));
+ case colStatus:
+ if (item->getPref() == NULL)
+ return QVariant();
+
+ return QObject::tr("Has this preference been changed?");
+ case colType:
+ if (item->getPref() == NULL) {
+ return QVariant();
+ } else {
+ QString type_desc = gchar_free_to_qstring(prefs_pref_type_description(item->getPref()));
+ return QString("<span>%1</span>").arg(type_desc);
+ }
+ break;
+ case colValue:
+ if (item->getPref() == NULL) {
+ return QVariant();
+ } else {
+ QString default_value = gchar_free_to_qstring(prefs_pref_to_str(item->getPref(), pref_stashed));
+ return QString("<span>%1</span>").arg(
+ default_value.isEmpty() ? default_value : QObject::tr("Default value is empty"));
+ }
+ default:
+ break;
+ }
+ break;
+ case Qt::FontRole:
+ if (item->getPref() == NULL)
+ return QVariant();
+
+ if (!item->isPrefDefault() &&
+ /* UATs and custom preferences are "unknown", that shouldn't mean that they are always bolded */
+ item->getPrefType() != PREF_UAT && item->getPrefType() != PREF_CUSTOM) {
+ QFont font;
+ font.setBold(true);
+ return font;
+ }
+ break;
+ case Qt::UserRole:
+ return sourceModel()->data(modelIndex, role);
+ default:
+ break;
+ }
+
+ return QVariant();
+}
+
+bool AdvancedPrefsModel::setData(const QModelIndex &dataindex, const QVariant &value, int role)
+{
+ if ((!dataindex.isValid()) || (role != Qt::EditRole))
+ return false;
+
+ QModelIndex modelIndex = mapToSource(dataindex);
+
+ PrefsItem* item = static_cast<PrefsItem*>(modelIndex.internalPointer());
+ if (item == NULL)
+ return false;
+
+ if (value.isNull()) {
+ //reset preference to default
+ reset_stashed_pref(item->getPref());
+ item->setChanged(false);
+ } else {
+ item->setChanged(true);
+ switch (item->getPrefType())
+ {
+ case PREF_DECODE_AS_UINT:
+ case PREF_UINT:
+ {
+ bool ok;
+ guint new_val = value.toString().toUInt(&ok, prefs_get_uint_base(item->getPref()));
+
+ if (ok)
+ prefs_set_uint_value(item->getPref(), new_val, pref_stashed);
+ }
+ break;
+ case PREF_BOOL:
+ prefs_invert_bool_value(item->getPref(), pref_stashed);
+ break;
+ case PREF_ENUM:
+ prefs_set_enum_value(item->getPref(), value.toInt(), pref_stashed);
+ break;
+ case PREF_STRING:
+ prefs_set_string_value(item->getPref(), value.toString().toStdString().c_str(), pref_stashed);
+ break;
+ case PREF_DECODE_AS_RANGE:
+ case PREF_RANGE:
+ prefs_set_stashed_range_value(item->getPref(), value.toString().toUtf8().constData());
+ break;
+ case PREF_SAVE_FILENAME:
+ case PREF_OPEN_FILENAME:
+ case PREF_DIRNAME:
+ prefs_set_string_value(item->getPref(), value.toString().toStdString().c_str(), pref_stashed);
+ break;
+ case PREF_COLOR:
+ {
+ QColor qc(value.toString());
+ color_t color;
+
+ color.red = qc.red() << 8 | qc.red();
+ color.green = qc.green() << 8 | qc.green();
+ color.blue = qc.blue() << 8 | qc.blue();
+
+ prefs_set_color_value(item->getPref(), color, pref_stashed);
+ break;
+ }
+ }
+ }
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ QVector<int> roles;
+ roles << role;
+#endif
+
+ // The status field may change as well as the value, so mark them for update
+ emit dataChanged(index(dataindex.row(), AdvancedPrefsModel::colStatus),
+ index(dataindex.row(), AdvancedPrefsModel::colValue)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ , roles
+#endif
+ );
+
+ return true;
+}
+
+Qt::ItemFlags AdvancedPrefsModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+
+ QModelIndex modelIndex = mapToSource(index);
+
+ PrefsItem* item = static_cast<PrefsItem*>(modelIndex.internalPointer());
+ if (item == NULL)
+ return 0;
+
+ Qt::ItemFlags flags = QAbstractItemModel::flags(index);
+ if (item->getPref() == NULL) {
+ /* Base modules aren't changable */
+ flags &= ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
+ } else {
+ flags |= Qt::ItemIsEditable;
+ }
+
+ return flags;
+}
+
+
+int AdvancedPrefsModel::columnCount(const QModelIndex&) const
+{
+ return colLast;
+}
+
+void AdvancedPrefsModel::setFirstColumnSpanned(QTreeView* tree, const QModelIndex& mIndex)
+{
+ int childCount, row;
+ PrefsItem* item;
+ if (mIndex.isValid()) {
+ item = VariantPointer<PrefsItem>::asPtr(data(mIndex, Qt::UserRole));
+ if (item != NULL) {
+ childCount = item->childCount();
+ if (childCount > 0) {
+ tree->setFirstColumnSpanned(mIndex.row(), mIndex.parent(), true);
+ for (row = 0; row < childCount; row++) {
+ setFirstColumnSpanned(tree, mIndex.child(row, 0));
+ }
+ }
+ }
+ } else {
+ for (row = 0; row < rowCount(); row++) {
+ setFirstColumnSpanned(tree, index(row, 0));
+ }
+ }
+}
+
+bool AdvancedPrefsModel::filterAcceptItem(PrefsItem& item) const
+{
+ if (filter_.isEmpty())
+ return true;
+
+ QString name, tooltip;
+ if (item.getPref() == NULL) {
+ name = item.getModule()->title;
+ tooltip = item.getModule()->description;
+ } else {
+ name = QString(item.getModule()->name ? item.getModule()->name : item.getModule()->parent->name);
+ name += QString(".%1").arg(prefs_get_name(item.getPref()));
+ tooltip = prefs_get_description(item.getPref());
+ }
+
+ if (name.contains(filter_, Qt::CaseInsensitive) || tooltip.contains(filter_, Qt::CaseInsensitive))
+ return true;
+
+ PrefsItem *child_item;
+ for (int child_row = 0; child_row < item.childCount(); child_row++)
+ {
+ child_item = item.child(child_row);
+ if ((child_item != NULL) && (filterAcceptItem(*child_item)))
+ return true;
+ }
+
+ return false;
+}
+
+bool AdvancedPrefsModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QModelIndex nameIdx = sourceModel()->index(sourceRow, PrefsModel::colName, sourceParent);
+ PrefsItem* item = static_cast<PrefsItem*>(nameIdx.internalPointer());
+ if (item == NULL)
+ return true;
+
+ //filter out the "special" preferences
+ if ((item->getModule() == NULL) && (item->getPref() == NULL))
+ return false;
+
+ if (filterAcceptItem(*item))
+ return true;
+
+ return false;
+}
+
+void AdvancedPrefsModel::setFilter(const QString& filter)
+{
+ filter_ = filter;
+ invalidateFilter();
+}
+
+
+
+
+
+ModulePrefsModel::ModulePrefsModel(QObject* parent)
+ : QSortFilterProxyModel(parent)
+ , advancedPrefName_(PrefsModel::ADVANCED_PREFERENCE_TREE_NAME)
+{
+}
+
+QVariant ModulePrefsModel::data(const QModelIndex &dataindex, int role) const
+{
+ if (!dataindex.isValid())
+ return QVariant();
+
+ QModelIndex modelIndex = mapToSource(dataindex);
+
+ PrefsItem* item = static_cast<PrefsItem*>(modelIndex.internalPointer());
+ if (item == NULL)
+ return QVariant();
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ switch ((ModulePrefsModelColumn)dataindex.column())
+ {
+ case colName:
+ if (item->getPref() == NULL) {
+ if (item->getModule() == NULL) {
+ return item->getName();
+ }
+
+ return item->getModule()->title;
+ }
+
+ return sourceModel()->data(sourceModel()->index(modelIndex.row(), PrefsModel::colName, modelIndex.parent()), role);
+ default:
+ break;
+ }
+ break;
+ case Qt::UserRole:
+ return sourceModel()->data(modelIndex, role);
+ case ModuleName:
+ return item->getModuleName();
+ default:
+ break;
+ }
+
+ return QVariant();
+}
+Qt::ItemFlags ModulePrefsModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return 0;
+
+ bool disable_capture = true;
+#ifdef HAVE_LIBPCAP
+#ifdef _WIN32
+ /* Is WPcap loaded? */
+ if (has_wpcap) {
+#endif /* _WIN32 */
+ disable_capture = false;
+#ifdef _WIN32
+ }
+#endif /* _WIN32 */
+#endif /* HAVE_LIBPCAP */
+
+ Qt::ItemFlags flags = QAbstractItemModel::flags(index);
+ if (disable_capture) {
+ QModelIndex modelIndex = mapToSource(index);
+
+ PrefsItem* item = static_cast<PrefsItem*>(modelIndex.internalPointer());
+ if (item == NULL)
+ return flags;
+
+ if (item->getName().compare(PrefsModel::CAPTURE_PREFERENCE_TREE_NAME) == 0) {
+ flags &= (~Qt::ItemIsEnabled);
+ }
+ }
+
+ return flags;
+}
+
+int ModulePrefsModel::columnCount(const QModelIndex&) const
+{
+ return colLast;
+}
+
+bool ModulePrefsModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
+{
+ //Force "Advanced" preferences to be at bottom of model
+ if (source_left.isValid() && !source_left.parent().isValid() &&
+ source_right.isValid() && !source_right.parent().isValid()) {
+ PrefsItem* left_item = static_cast<PrefsItem*>(source_left.internalPointer());
+ PrefsItem* right_item = static_cast<PrefsItem*>(source_right.internalPointer());
+ if ((left_item != NULL) && (left_item->getName().compare(advancedPrefName_) == 0)) {
+ return false;
+ }
+ if ((right_item != NULL) && (right_item->getName().compare(advancedPrefName_) == 0)) {
+ return true;
+ }
+ }
+
+
+ return QSortFilterProxyModel::lessThan(source_left, source_right);
+}
+
+bool ModulePrefsModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+{
+ QModelIndex nameIdx = sourceModel()->index(sourceRow, PrefsModel::colName, sourceParent);
+ PrefsItem* item = static_cast<PrefsItem*>(nameIdx.internalPointer());
+ if (item == NULL)
+ return true;
+
+ if (item->getPref() != NULL)
+ return false;
+
+ if (item->getModule() != NULL) {
+ if (!item->getModule()->use_gui) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+
+/*
+ * 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:
+ */
diff --git a/ui/qt/models/pref_models.h b/ui/qt/models/pref_models.h
new file mode 100644
index 0000000000..4914e61133
--- /dev/null
+++ b/ui/qt/models/pref_models.h
@@ -0,0 +1,173 @@
+/* pref_models.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef PREF_MODELS_H
+#define PREF_MODELS_H
+
+#include <config.h>
+
+#include <ui/qt/models/tree_model_helpers.h>
+
+#include <epan/prefs.h>
+
+#include <QSortFilterProxyModel>
+#include <QTreeView>
+
+class PrefsItem : public ModelHelperTreeItem<PrefsItem>
+{
+public:
+ PrefsItem(module_t *module, pref_t *pref, PrefsItem* parent);
+ PrefsItem(QString name, PrefsItem* parent);
+ virtual ~PrefsItem();
+
+ QString getName() const {return name_;}
+ pref_t* getPref() const {return pref_;}
+ int getPrefType() const;
+ int getPrefGUIType() const;
+ bool isPrefDefault() const;
+ QString getPrefTypeName() const;
+ module_t* getModule() const {return module_;}
+ QString getModuleName() const;
+ void setChanged(bool changed = true);
+
+private:
+ pref_t *pref_;
+ module_t *module_;
+ QString name_;
+ //set to true if changed during module manipulation
+ //Used to determine proper "default" for comparison
+ bool changed_;
+};
+
+
+class PrefsModel : public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+ explicit PrefsModel(QObject * parent = Q_NULLPTR);
+ virtual ~PrefsModel();
+
+ //Names of special preferences handled by the GUI
+ //Names used as keys to determine correct pan displayed
+ static const char* ADVANCED_PREFERENCE_TREE_NAME;
+ static const char* APPEARANCE_PREFERENCE_TREE_NAME;
+ static const char* LAYOUT_PREFERENCE_TREE_NAME;
+ static const char* COLUMNS_PREFERENCE_TREE_NAME;
+ static const char* FONT_AND_COLORS_PREFERENCE_TREE_NAME;
+ static const char* CAPTURE_PREFERENCE_TREE_NAME;
+ static const char* EXPERT_PREFERENCE_TREE_NAME;
+ static const char* FILTER_BUTTONS_PREFERENCE_TREE_NAME;
+
+ enum PrefsModelColumn {
+ colName = 0,
+ colStatus,
+ colType,
+ colValue,
+ colLast
+ };
+
+ QModelIndex index(int row, int column,
+ const QModelIndex & = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &) const;
+ QVariant data(const QModelIndex &index, int role) const;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+private:
+ void populate();
+
+ PrefsItem* root_;
+};
+
+class AdvancedPrefsModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+
+ explicit AdvancedPrefsModel(QObject * parent = Q_NULLPTR);
+
+ enum AdvancedPrefsModelColumn {
+ colName = 0,
+ colStatus,
+ colType,
+ colValue,
+ colLast
+ };
+
+ virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+
+ void setFilter(const QString& filter);
+
+ QVariant headerData(int section, Qt::Orientation orientation,
+ int role = Qt::DisplayRole) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ //Keep the internals of model hidden from tree
+ void setFirstColumnSpanned(QTreeView* tree, const QModelIndex &index = QModelIndex());
+
+protected:
+ bool filterAcceptItem(PrefsItem& item) const;
+
+private:
+
+ QString filter_;
+};
+
+class ModulePrefsModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+
+ explicit ModulePrefsModel(QObject * parent = Q_NULLPTR);
+
+ enum ModulePrefsModelColumn {
+ colName = 0,
+ colLast
+ };
+
+ enum ModulePrefsRoles {
+ ModuleName = Qt::UserRole + 1
+ };
+
+ QVariant data(const QModelIndex &index, int role) const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+ virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+
+protected:
+ bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
+
+private:
+ //cache of the translated "Advanced" preference name
+ QString advancedPrefName_;
+};
+
+extern pref_t *prefFromPrefPtr(void *pref_ptr);
+
+#endif // PREF_MODELS_H
+
+/*
+ * 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:
+ */
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index 16e545e96d..891ff4585a 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -47,6 +47,7 @@
#include <ui/qt/utils/data_printer.h>
#include <ui/qt/utils/frame_information.h>
#include <ui/qt/utils/variant_pointer.h>
+#include <ui/qt/models/pref_models.h>
#include <QAction>
#include <QActionGroup>
@@ -1362,7 +1363,7 @@ void PacketList::headerMenuTriggered()
recent_set_column_xalign(header_ctx_column_, checked ? COLUMN_XALIGN_RIGHT : COLUMN_XALIGN_DEFAULT);
break;
case caColumnPreferences:
- emit showColumnPreferences(PreferencesDialog::ppColumn);
+ emit showColumnPreferences(PrefsModel::COLUMNS_PREFERENCE_TREE_NAME);
break;
case caEditColumn:
emit editColumn(header_ctx_column_);
diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h
index 2ee97fe338..6d2eed23cc 100644
--- a/ui/qt/packet_list.h
+++ b/ui/qt/packet_list.h
@@ -4,19 +4,7 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef PACKET_LIST_H
@@ -24,7 +12,6 @@
#include "byte_view_tab.h"
#include <ui/qt/models/packet_list_model.h>
-#include "preferences_dialog.h"
#include "proto_tree.h"
#include "protocol_preferences_menu.h"
#include <ui/qt/models/related_packet_delegate.h>
@@ -150,7 +137,7 @@ private:
signals:
void packetDissectionChanged();
- void showColumnPreferences(PreferencesDialog::PreferencesPane start_pane);
+ void showColumnPreferences(QString pane_name);
void editColumn(int column);
void packetListScrolled(bool at_end);
void showProtocolPreferences(const QString module_name);
diff --git a/ui/qt/preferences_dialog.cpp b/ui/qt/preferences_dialog.cpp
index 3592ca2e68..c2ef0a799a 100644
--- a/ui/qt/preferences_dialog.cpp
+++ b/ui/qt/preferences_dialog.cpp
@@ -4,19 +4,7 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include "preferences_dialog.h"
@@ -24,12 +12,6 @@
#include "module_preferences_scroll_area.h"
-#ifdef HAVE_LIBPCAP
-#ifdef _WIN32
-#include "caputils/capture-wpcap.h"
-#endif /* _WIN32 */
-#endif /* HAVE_LIBPCAP */
-
#include <epan/prefs-int.h>
#include <epan/decode_as.h>
#include <ui/language.h>
@@ -38,300 +20,12 @@
#include <ui/recent.h>
#include <main_window.h>
-#include <ui/qt/widgets/syntax_line_edit.h>
-#include <ui/qt/utils/qt_ui_utils.h>
-#include "uat_dialog.h"
#include "wireshark_application.h"
-#include <ui/qt/utils/variant_pointer.h>
-
-#include <QColorDialog>
-#include <QComboBox>
-#include <QFileDialog>
-#include <QFrame>
-#include <QHBoxLayout>
-#include <QKeyEvent>
-#include <QLineEdit>
-#include <QMessageBox>
-#include <QSpacerItem>
-#include <QTreeWidgetItemIterator>
-
-// XXX Should we move this to ui/preference_utils?
-static GHashTable * pref_ptr_to_pref_ = NULL;
-pref_t *prefFromPrefPtr(void *pref_ptr)
-{
- return (pref_t *)g_hash_table_lookup(pref_ptr_to_pref_, (gpointer) pref_ptr);
-}
-
-static void prefInsertPrefPtr(void * pref_ptr, pref_t * pref)
-{
- if ( ! pref_ptr_to_pref_ )
- pref_ptr_to_pref_ = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
-
- gpointer key = (gpointer) pref_ptr;
- gpointer val = (gpointer) pref;
-
- /* Already existing entries will be ignored */
- if ( (pref = (pref_t *)g_hash_table_lookup(pref_ptr_to_pref_, key) ) == NULL )
- g_hash_table_insert(pref_ptr_to_pref_, key, val);
-}
-
-enum {
- module_type_ = 1000,
- advanced_type_
-};
-
-enum {
- adv_name_col_,
- adv_status_col_,
- adv_type_col_,
- adv_value_col_
-};
-
-enum {
- stacked_role_ = Qt::UserRole + 1, // pd_ui_->stackedWidget
- module_name_role_, // QString
- mpsa_role_ // QWidget *
-};
-
-class AdvancedPrefTreeWidgetItem : public QTreeWidgetItem
-{
-public:
- AdvancedPrefTreeWidgetItem(pref_t *pref, module_t *module) :
- QTreeWidgetItem (advanced_type_),
- pref_(pref),
- module_(module)
- {}
- pref_t *pref() { return pref_; }
- void updatePref() { emitDataChanged(); }
-
- virtual QVariant data(int column, int role) const {
- bool is_default = prefs_pref_is_default(pref_);
- switch (role) {
- case Qt::DisplayRole:
- switch (column) {
- case adv_name_col_:
- {
- QString full_name = QString(module_->name ? module_->name : module_->parent->name);
- full_name += QString(".%1").arg(prefs_get_name(pref_));
- return full_name;
- }
- case adv_status_col_:
- if ((prefs_get_type(pref_) == PREF_UAT && (prefs_get_gui_type(pref_) == GUI_ALL || prefs_get_gui_type(pref_) == GUI_QT))|| prefs_get_type(pref_) == PREF_CUSTOM) {
- return QObject::tr("Unknown");
- } else if (is_default) {
- return QObject::tr("Default");
- } else {
- return QObject::tr("Changed");
- }
- case adv_type_col_:
- return QString(prefs_pref_type_name(pref_));
- case adv_value_col_:
- {
- QString cur_value = gchar_free_to_qstring(prefs_pref_to_str(pref_, pref_stashed)).remove(QRegExp("\n\t"));
- return cur_value;
- }
- default:
- break;
- }
- break;
- case Qt::ToolTipRole:
- switch (column) {
- case adv_name_col_:
- return QString("<span>%1</span>").arg(prefs_get_description(pref_));
- case adv_status_col_:
- return QObject::tr("Has this preference been changed?");
- case adv_type_col_:
- {
- QString type_desc = gchar_free_to_qstring(prefs_pref_type_description(pref_));
- return QString("<span>%1</span>").arg(type_desc);
- }
- case adv_value_col_:
- {
- QString default_value = gchar_free_to_qstring(prefs_pref_to_str(pref_, pref_stashed));
- return QString("<span>%1</span>").arg(
- default_value.isEmpty() ? default_value : QObject::tr("Default value is empty"));
- }
- default:
- break;
- }
- break;
- case Qt::FontRole:
- if (!is_default && treeWidget()) {
- QFont font = treeWidget()->font();
- font.setBold(true);
- return font;
- }
- break;
- default:
- break;
- }
- return QTreeWidgetItem::data(column, role);
- }
-
-private:
- pref_t *pref_;
- module_t *module_;
-};
-
-class ModulePrefTreeWidgetItem : public QTreeWidgetItem
-{
-public:
- ModulePrefTreeWidgetItem(QTreeWidgetItem *parent, module_t *module) :
- QTreeWidgetItem (parent, module_type_),
- module_(module),
- mpsa_(0)
- {}
- void ensureModulePreferencesScrollArea(QStackedWidget *sw) {
- /*
- * We create pages for interior nodes even if they don't have
- * preferences, so that we at least have something to show
- * if the user clicks on them, even if it's empty.
- */
-
- /* Scrolled window */
- if (!mpsa_) {
- mpsa_ = new ModulePreferencesScrollArea(module_);
- if (sw->indexOf(mpsa_) < 0) sw->addWidget(mpsa_);
- }
- }
-
- virtual QVariant data(int column, int role) const {
- if (column == 0) {
- switch (role) {
- case Qt::DisplayRole:
- return QString(module_->title);
- case module_name_role_:
- return QString (module_->name);
- case mpsa_role_:
- return qVariantFromValue(mpsa_);
- default:
- break;
- }
- }
- return QTreeWidgetItem::data(column, role);
- }
-
-private:
- module_t *module_;
- QWidget *mpsa_;
-};
-
extern "C" {
// Callbacks prefs routines
static guint
-fill_advanced_prefs(module_t *module, gpointer root_ptr)
-{
- QTreeWidgetItem *root_item = static_cast<QTreeWidgetItem *>(root_ptr);
-
- if (!module || !root_item) return 1;
-
- if (module->numprefs < 1 && !prefs_module_has_submodules(module)) return 0;
-
- QString module_title = module->title;
-
- QTreeWidgetItem *tl_item = new QTreeWidgetItem(root_item);
- tl_item->setText(0, module_title);
- tl_item->setToolTip(0, QString("<span>%1</span>").arg(module->description));
- tl_item->setFirstColumnSpanned(true);
- Qt::ItemFlags item_flags = tl_item->flags();
- item_flags &= ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
- tl_item->setFlags(item_flags);
-
-
- QList<QTreeWidgetItem *>tl_children;
- for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = g_list_next(pref_l)) {
- pref_t *pref = (pref_t *) pref_l->data;
-
- if (prefs_get_type(pref) == PREF_OBSOLETE || prefs_get_type(pref) == PREF_STATIC_TEXT) continue;
-
- const char *type_name = prefs_pref_type_name(pref);
- if (!type_name) continue;
-
- pref_stash(pref, NULL);
-
- AdvancedPrefTreeWidgetItem *item = new AdvancedPrefTreeWidgetItem(pref, module);
- tl_children << item;
-
- // .uat is a void * so it wins the "useful key value" prize.
- if (prefs_get_uat_value(pref)) {
- prefInsertPrefPtr( prefs_get_uat_value(pref), pref);
- }
- }
- tl_item->addChildren(tl_children);
-
- if(prefs_module_has_submodules(module))
- return prefs_modules_foreach_submodules(module, fill_advanced_prefs, tl_item);
-
- return 0;
-}
-
-static guint
-pref_exists(pref_t *, gpointer)
-{
- return 1;
-}
-
-static guint
-fill_module_prefs(module_t *module, gpointer ti_ptr)
-{
- QTreeWidgetItem *item = static_cast<QTreeWidgetItem *>(ti_ptr);
-
- if (!item) return 0;
-
- QStackedWidget *stacked_widget = VariantPointer<QStackedWidget>::asPtr(item->data(0, stacked_role_));
-
- if (!stacked_widget) return 0;
-
- if (!module->use_gui) {
- /* This module uses its own GUI interface to modify its
- * preferences, so ignore it
- */
- return 0;
- }
-
- /*
- * Is this module an interior node, with modules underneath it?
- */
- if (!prefs_module_has_submodules(module)) {
- /*
- * No.
- * Does it have any preferences (other than possibly obsolete ones)?
- */
- if (prefs_pref_foreach(module, pref_exists, NULL) == 0) {
- /*
- * No. Don't put the module into the preferences window,
- * as there's nothing to show.
- *
- * XXX - we should do the same for interior ndes; if the module
- * has no non-obsolete preferences *and* nothing under it has
- * non-obsolete preferences, don't put it into the window.
- */
- return 0;
- }
- }
-
- /*
- * Add this module to the tree.
- */
- ModulePrefTreeWidgetItem *new_mpti = new ModulePrefTreeWidgetItem(item, module);
- new_mpti->setData(0, stacked_role_, item->data(0, stacked_role_));
-
- /*
- * Is this an interior node?
- */
- if (prefs_module_has_submodules(module)) {
- /*
- * Yes. Walk the subtree and attach stuff to it.
- */
- prefs_modules_foreach_submodules(module, fill_module_prefs, (gpointer) new_mpti);
- }
-
- return 0;
-}
-
-static guint
module_prefs_unstash(module_t *module, gpointer data)
{
gboolean *must_redissect_p = (gboolean *)data;
@@ -381,89 +75,58 @@ module_prefs_clean_stash(module_t *module, gpointer)
} // extern "C"
// Preference tree items
-const int appearance_item_ = 0;
-const int capture_item_ = 1;
+const int APPEARANCE_ITEM = 0;
+
+//placeholder key to keep dynamically loaded preferences
+static const char* MODULES_NAME = "Modules";
PreferencesDialog::PreferencesDialog(QWidget *parent) :
GeometryStateDialog(parent),
pd_ui_(new Ui::PreferencesDialog),
- cur_pref_type_(0),
- cur_line_edit_(NULL),
- cur_combo_box_(NULL),
- saved_combo_idx_(0)
+ model_(this),
+ advancedPrefsModel_(this),
+ advancedPrefsDelegate_(this),
+ modulePrefsModel_(this)
{
- QTreeWidgetItem tmp_item; // Adding pre-populated top-level items is much faster
- prefs_modules_foreach_submodules(NULL, fill_advanced_prefs, (gpointer) &tmp_item);
+ advancedPrefsModel_.setSourceModel(&model_);
+ modulePrefsModel_.setSourceModel(&model_);
// Some classes depend on pref_ptr_to_pref_ so this MUST be called after
- // fill_advanced_prefs.
+ // model_.populate().
pd_ui_->setupUi(this);
loadGeometry();
setWindowTitle(wsApp->windowTitleString(tr("Preferences")));
- pd_ui_->advancedTree->invisibleRootItem()->addChildren(tmp_item.takeChildren());
+
+ pd_ui_->advancedView->setModel(&advancedPrefsModel_);
+ pd_ui_->advancedView->setItemDelegate(&advancedPrefsDelegate_);
+ advancedPrefsModel_.setFirstColumnSpanned(pd_ui_->advancedView);
+
+ pd_ui_->prefsView->setModel(&modulePrefsModel_);
pd_ui_->splitter->setStretchFactor(0, 1);
pd_ui_->splitter->setStretchFactor(1, 5);
+ pd_ui_->prefsView->sortByColumn(ModulePrefsModel::colName, Qt::AscendingOrder);
- pd_ui_->prefsTree->invisibleRootItem()->child(appearance_item_)->setExpanded(true);
+ //Set the Appearance leaf to expanded
+ pd_ui_->prefsView->setExpanded(modulePrefsModel_.index(APPEARANCE_ITEM, 0), true);
- bool disable_capture = true;
-#ifdef HAVE_LIBPCAP
-#ifdef _WIN32
- /* Is WPcap loaded? */
- if (has_wpcap) {
-#endif /* _WIN32 */
- disable_capture = false;
-#ifdef _WIN32
- }
-#endif /* _WIN32 */
-#endif /* HAVE_LIBPCAP */
- pd_ui_->prefsTree->invisibleRootItem()->child(capture_item_)->setDisabled(disable_capture);
-
- // PreferencesPane, prefsTree, and stackedWidget must all correspond to each other.
- // This may not be the best way to go about enforcing that.
- QTreeWidgetItem *item = pd_ui_->prefsTree->topLevelItem(0);
- item->setSelected(true);
- pd_ui_->stackedWidget->setCurrentIndex(0);
- for (int i = 0; i < pd_ui_->stackedWidget->count() && item; i++) {
- item->setData(0, mpsa_role_, qVariantFromValue(pd_ui_->stackedWidget->widget(i)));
- item = pd_ui_->prefsTree->itemBelow(item);
- }
- item = pd_ui_->prefsTree->topLevelItem(0);
- prefs_pane_to_item_[ppAppearance] = item;
- prefs_pane_to_item_[ppLayout] = item->child(0);
- prefs_pane_to_item_[ppColumn] = item->child(1);
- prefs_pane_to_item_[ppFontAndColor] = item->child(2);
- prefs_pane_to_item_[ppCapture] = pd_ui_->prefsTree->topLevelItem(1);
- prefs_pane_to_item_[ppExpert] = pd_ui_->prefsTree->topLevelItem(2);
- prefs_pane_to_item_[ppFilterExpressions] = pd_ui_->prefsTree->topLevelItem(3);
- pd_ui_->filterExpressonsFrame->setUat(uat_get_table_by_name("Display expressions"));
-
- // Printing prefs don't apply here.
- module_t *print_module = prefs_find_module("print");
- if (print_module)
- print_module->use_gui = FALSE;
+ // PreferencesPane, prefsView, and stackedWidget must all correspond to each other.
+ prefs_pane_to_item_[PrefsModel::APPEARANCE_PREFERENCE_TREE_NAME] = pd_ui_->appearanceFrame;
+ prefs_pane_to_item_[PrefsModel::LAYOUT_PREFERENCE_TREE_NAME] = pd_ui_->layoutFrame;
+ prefs_pane_to_item_[PrefsModel::COLUMNS_PREFERENCE_TREE_NAME] = pd_ui_->columnFrame;
+ prefs_pane_to_item_[PrefsModel::FONT_AND_COLORS_PREFERENCE_TREE_NAME] = pd_ui_->fontandcolorFrame;
+ prefs_pane_to_item_[PrefsModel::CAPTURE_PREFERENCE_TREE_NAME] = pd_ui_->captureFrame;
+ prefs_pane_to_item_[PrefsModel::EXPERT_PREFERENCE_TREE_NAME] = pd_ui_->expertFrame;
+ prefs_pane_to_item_[PrefsModel::FILTER_BUTTONS_PREFERENCE_TREE_NAME] = pd_ui_->filterExpressonsFrame;
+ prefs_pane_to_item_[PrefsModel::ADVANCED_PREFERENCE_TREE_NAME] = pd_ui_->advancedFrame;
+ prefs_pane_to_item_[MODULES_NAME] = NULL;
- //Since "expert" is really a pseudo protocol, it shouldn't be
- //categorized with other "real" protocols when it comes to
- //preferences. Since it's just a UAT, don't bury it in
- //with the other protocols
+ pd_ui_->filterExpressonsFrame->setUat(uat_get_table_by_name("Display expressions"));
pd_ui_->expertFrame->setUat(uat_get_table_by_name("Expert Info Severity Level Configuration"));
- module_t *expert_module = prefs_find_module("_ws.expert");
- if (expert_module)
- expert_module->use_gui = FALSE;
-
- // We called takeChildren above so this shouldn't be necessary.
- while (tmp_item.childCount() > 0) {
- tmp_item.removeChild(tmp_item.child(0));
- }
- tmp_item.setData(0, stacked_role_, VariantPointer<QStackedWidget>::asQVariant(pd_ui_->stackedWidget));
- prefs_modules_foreach_submodules(NULL, fill_module_prefs, (gpointer) &tmp_item);
- pd_ui_->prefsTree->invisibleRootItem()->insertChildren(
- pd_ui_->prefsTree->invisibleRootItem()->childCount() - 1, tmp_item.takeChildren());
+ connect(pd_ui_->prefsView, SIGNAL(goToPane(QString)), this, SLOT(selectPane(QString)));
}
PreferencesDialog::~PreferencesDialog()
@@ -472,418 +135,68 @@ PreferencesDialog::~PreferencesDialog()
prefs_modules_foreach_submodules(NULL, module_prefs_clean_stash, NULL);
}
-void PreferencesDialog::setPane(PreferencesDialog::PreferencesPane start_pane)
+void PreferencesDialog::setPane(const QString pane_name)
{
- if (prefs_pane_to_item_.contains(start_pane)) {
- pd_ui_->prefsTree->setCurrentItem(prefs_pane_to_item_[start_pane]);
- }
-}
-
-// Only valid for ModulePrefTreeWidgetItems.
-void PreferencesDialog::setPane(const QString module_name)
-{
- QTreeWidgetItemIterator pref_it(pd_ui_->prefsTree);
- while (*pref_it) {
- if ((*pref_it)->type() == module_type_) {
- ModulePrefTreeWidgetItem *mp_ti = dynamic_cast<ModulePrefTreeWidgetItem *>(*pref_it);
- // Ensure that the module's scroll area exists and that it's in the
- // widget stack.
- if (mp_ti) {
- QString mpsa_name = (*pref_it)->data(0, module_name_role_).toString();
- if (mpsa_name == module_name) {
- mp_ti->ensureModulePreferencesScrollArea(pd_ui_->stackedWidget);
- QWidget *mpsa = (*pref_it)->data(0, mpsa_role_).value<QWidget *>();
- if (mpsa) {
- pd_ui_->prefsTree->setCurrentItem((*pref_it));
- break;
- }
- }
- }
- }
- ++pref_it;
- }
+ pd_ui_->prefsView->setPane(pane_name);
}
void PreferencesDialog::showEvent(QShowEvent *)
{
QStyleOption style_opt;
- int new_prefs_tree_width = pd_ui_->prefsTree->style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &style_opt).left();
+ int new_prefs_tree_width = pd_ui_->prefsView->style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &style_opt).left();
QList<int> sizes = pd_ui_->splitter->sizes();
#ifdef Q_OS_WIN
new_prefs_tree_width *= 2;
#endif
- pd_ui_->prefsTree->resizeColumnToContents(0);
- new_prefs_tree_width += pd_ui_->prefsTree->columnWidth(0);
- pd_ui_->prefsTree->setMinimumWidth(new_prefs_tree_width);
+ pd_ui_->prefsView->resizeColumnToContents(ModulePrefsModel::colName);
+ new_prefs_tree_width += pd_ui_->prefsView->columnWidth(ModulePrefsModel::colName);
+ pd_ui_->prefsView->setMinimumWidth(new_prefs_tree_width);
+
sizes[1] += sizes[0] - new_prefs_tree_width;
sizes[0] = new_prefs_tree_width;
pd_ui_->splitter->setSizes(sizes);
pd_ui_->splitter->setStretchFactor(0, 1);
- pd_ui_->advancedTree->expandAll();
- pd_ui_->advancedTree->setSortingEnabled(true);
- pd_ui_->advancedTree->sortByColumn(0, Qt::AscendingOrder);
+ pd_ui_->advancedView->expandAll();
+ pd_ui_->advancedView->setSortingEnabled(true);
+ pd_ui_->advancedView->sortByColumn(AdvancedPrefsModel::colName, Qt::AscendingOrder);
int one_em = fontMetrics().height();
- pd_ui_->advancedTree->setColumnWidth(adv_name_col_, one_em * 12); // Don't let long items widen things too much
- pd_ui_->advancedTree->resizeColumnToContents(adv_status_col_);
- pd_ui_->advancedTree->resizeColumnToContents(adv_type_col_);
- pd_ui_->advancedTree->setColumnWidth(adv_value_col_, one_em * 30);
-}
-
-void PreferencesDialog::keyPressEvent(QKeyEvent *evt)
-{
- if (cur_line_edit_ && cur_line_edit_->hasFocus()) {
- switch (evt->key()) {
- case Qt::Key_Escape:
- cur_line_edit_->setText(saved_string_pref_);
- /* Fall Through */
- case Qt::Key_Enter:
- case Qt::Key_Return:
- switch (cur_pref_type_) {
- case PREF_UINT:
- uintPrefEditingFinished();
- break;
- case PREF_STRING:
- stringPrefEditingFinished();
- break;
- case PREF_RANGE:
- rangePrefEditingFinished();
- break;
- default:
- break;
- }
-
- delete cur_line_edit_;
- return;
- default:
- break;
- }
- } else if (cur_combo_box_ && cur_combo_box_->hasFocus()) {
- switch (evt->key()) {
- case Qt::Key_Escape:
- cur_combo_box_->setCurrentIndex(saved_combo_idx_);
- /* Fall Through */
- case Qt::Key_Enter:
- case Qt::Key_Return:
- // XXX The combo box eats enter and return
- enumPrefCurrentIndexChanged(cur_combo_box_->currentIndex());
- delete cur_combo_box_;
- return;
- default:
- break;
- }
- }
- QDialog::keyPressEvent(evt);
-}
-
-void PreferencesDialog::on_prefsTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *)
-{
- if (!current) return;
- QWidget *new_item = NULL;
-
- // "current" might be a QTreeWidgetItem from our .ui file, e.g. "Columns"
- // or a ModulePrefTreeWidgetItem created by fill_module_prefs, e.g. a
- // protocol preference. If it's the latter, ensure that the module's
- // scroll area exists and that it's in the widget stack.
- if (current->type() == module_type_) {
- ModulePrefTreeWidgetItem *mp_ti = dynamic_cast<ModulePrefTreeWidgetItem *>(current);
- if (mp_ti) mp_ti->ensureModulePreferencesScrollArea(pd_ui_->stackedWidget);
- }
-
- new_item = current->data(0, mpsa_role_).value<QWidget *>();
- g_assert(new_item != NULL);
- pd_ui_->stackedWidget->setCurrentWidget(new_item);
-}
-
-void PreferencesDialog::on_advancedSearchLineEdit_textEdited(const QString &search_re)
-{
- QTreeWidgetItemIterator branch_it(pd_ui_->advancedTree);
- QRegExp regex(search_re, Qt::CaseInsensitive);
-
- // Hide or show everything
- while (*branch_it) {
- (*branch_it)->setHidden(!search_re.isEmpty());
- ++branch_it;
- }
- if (search_re.isEmpty()) return;
-
- // Hide or show each item, showing its parents if needed
- QTreeWidgetItemIterator pref_it(pd_ui_->advancedTree);
- while (*pref_it) {
- bool hidden = true;
-
- if ((*pref_it)->type() == advanced_type_) {
-
- if ((*pref_it)->text(0).contains(regex) ||
- (*pref_it)->toolTip(0).contains(regex)) {
- hidden = false;
- }
-
- (*pref_it)->setHidden(hidden);
- if (!hidden) {
- QTreeWidgetItem *parent = (*pref_it)->parent();
- while (parent) {
- parent->setHidden(false);
- parent = parent->parent();
- }
- }
- }
- ++pref_it;
- }
+ pd_ui_->advancedView->setColumnWidth(AdvancedPrefsModel::colName, one_em * 12); // Don't let long items widen things too much
+ pd_ui_->advancedView->resizeColumnToContents(AdvancedPrefsModel::colStatus);
+ pd_ui_->advancedView->resizeColumnToContents(AdvancedPrefsModel::colType);
+ pd_ui_->advancedView->setColumnWidth(AdvancedPrefsModel::colValue, one_em * 30);
}
-void PreferencesDialog::on_advancedTree_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *previous)
+void PreferencesDialog::selectPane(QString pane)
{
- if (previous && pd_ui_->advancedTree->itemWidget(previous, 3)) {
- pd_ui_->advancedTree->removeItemWidget(previous, 3);
- }
-}
-
-void PreferencesDialog::on_advancedTree_itemActivated(QTreeWidgetItem *item, int column)
-{
- AdvancedPrefTreeWidgetItem *adv_ti;
- pref_t *pref = NULL;
-
- if (item->type() == advanced_type_) {
- adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(item);
- if (adv_ti) pref = adv_ti->pref();
- }
-
- if (!pref || cur_line_edit_ || cur_combo_box_) return;
-
- if (column < 3) { // Reset to default
- reset_stashed_pref(pref);
- adv_ti->updatePref();
+ if (prefs_pane_to_item_.contains(pane)) {
+ pd_ui_->stackedWidget->setCurrentWidget(prefs_pane_to_item_[pane]);
} else {
- QWidget *editor = NULL;
-
- switch (prefs_get_type(pref)) {
- case PREF_DECODE_AS_UINT:
- case PREF_UINT:
- {
- char* tmpstr = prefs_pref_to_str(pref, pref_stashed);
- cur_line_edit_ = new QLineEdit();
-// cur_line_edit_->setInputMask("0000000009;");
- saved_string_pref_ = tmpstr;
- g_free(tmpstr);
- connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(uintPrefEditingFinished()));
- editor = cur_line_edit_;
- break;
- }
- case PREF_BOOL:
- prefs_invert_bool_value(pref, pref_stashed);
- adv_ti->updatePref();
- break;
- case PREF_ENUM:
- {
- cur_combo_box_ = new QComboBox();
- const enum_val_t *ev;
- for (ev = prefs_get_enumvals(pref); ev && ev->description; ev++) {
- cur_combo_box_->addItem(ev->description, QVariant(ev->value));
- if (prefs_get_enum_value(pref, pref_stashed) == ev->value)
- cur_combo_box_->setCurrentIndex(cur_combo_box_->count() - 1);
- }
- saved_combo_idx_ = cur_combo_box_->currentIndex();
- connect(cur_combo_box_, SIGNAL(currentIndexChanged(int)), this, SLOT(enumPrefCurrentIndexChanged(int)));
- editor = cur_combo_box_;
- break;
- }
- case PREF_STRING:
- {
- cur_line_edit_ = new QLineEdit();
- saved_string_pref_ = prefs_get_string_value(pref, pref_stashed);
- connect(cur_line_edit_, SIGNAL(editingFinished()), this, SLOT(stringPrefEditingFinished()));
- editor = cur_line_edit_;
- break;
- }
- case PREF_SAVE_FILENAME:
- case PREF_OPEN_FILENAME:
- case PREF_DIRNAME:
- {
- QString filename;
-
- if (prefs_get_type(pref) == PREF_SAVE_FILENAME) {
- filename = QFileDialog::getSaveFileName(this, wsApp->windowTitleString(prefs_get_title(pref)),
- prefs_get_string_value(pref, pref_stashed));
-
- } else if (prefs_get_type(pref) == PREF_OPEN_FILENAME) {
- filename = QFileDialog::getOpenFileName(this, wsApp->windowTitleString(prefs_get_title(pref)),
- prefs_get_string_value(pref, pref_stashed));
-
- } else {
- filename = QFileDialog::getExistingDirectory(this, wsApp->windowTitleString(prefs_get_title(pref)),
- prefs_get_string_value(pref, pref_stashed));
+ //If not found in prefs_pane_to_item_, it must be an individual module
+ module_t* module = prefs_find_module(pane.toStdString().c_str());
+ if (module != NULL) {
+ QWidget* moduleWindow = prefs_pane_to_item_[MODULES_NAME];
+ if (moduleWindow != NULL) {
+ pd_ui_->stackedWidget->removeWidget(moduleWindow);
+ delete moduleWindow;
}
- if (!filename.isEmpty()) {
- prefs_set_string_value(pref, QDir::toNativeSeparators(filename).toStdString().c_str(), pref_stashed);
- adv_ti->updatePref();
- }
- break;
- }
- case PREF_DECODE_AS_RANGE:
- case PREF_RANGE:
- {
- SyntaxLineEdit *syntax_edit = new SyntaxLineEdit();
- char *cur_val = prefs_pref_to_str(pref, pref_stashed);
- saved_string_pref_ = gchar_free_to_qstring(cur_val);
- connect(syntax_edit, SIGNAL(textChanged(QString)),
- this, SLOT(rangePrefTextChanged(QString)));
- connect(syntax_edit, SIGNAL(editingFinished()), this, SLOT(rangePrefEditingFinished()));
- editor = cur_line_edit_ = syntax_edit;
- break;
- }
- case PREF_COLOR:
- {
- QColorDialog color_dlg;
- color_t color = *prefs_get_color_value(pref, pref_stashed);
-
- color_dlg.setCurrentColor(QColor(
- color.red >> 8,
- color.green >> 8,
- color.blue >> 8
- ));
- if (color_dlg.exec() == QDialog::Accepted) {
- QColor cc = color_dlg.currentColor();
- color.red = cc.red() << 8 | cc.red();
- color.green = cc.green() << 8 | cc.green();
- color.blue = cc.blue() << 8 | cc.blue();
- prefs_set_color_value(pref, color, pref_stashed);
- adv_ti->updatePref();
- }
- break;
- }
- case PREF_UAT:
- {
- if (prefs_get_gui_type(pref) == GUI_ALL || prefs_get_gui_type(pref) == GUI_QT) {
- UatDialog uat_dlg(this, prefs_get_uat_value(pref));
- uat_dlg.exec();
- }
- break;
- }
- default:
- break;
- }
- cur_pref_type_ = prefs_get_type(pref);
- if (cur_line_edit_) {
- cur_line_edit_->setText(saved_string_pref_);
- cur_line_edit_->selectAll();
- connect(cur_line_edit_, SIGNAL(destroyed()), this, SLOT(lineEditPrefDestroyed()));
- }
- if (cur_combo_box_) {
- connect(cur_combo_box_, SIGNAL(destroyed()), this, SLOT(enumPrefDestroyed()));
- }
- if (editor) {
- QFrame *edit_frame = new QFrame();
- QHBoxLayout *hb = new QHBoxLayout();
- QSpacerItem *spacer = new QSpacerItem(5, 10);
-
- hb->addWidget(editor, 0);
- hb->addSpacerItem(spacer);
- hb->setStretch(1, 1);
- hb->setContentsMargins(0, 0, 0, 0);
-
- edit_frame->setLineWidth(0);
- edit_frame->setFrameStyle(QFrame::NoFrame);
- // The documentation suggests setting autoFillbackground. That looks silly
- // so we clear the item text instead.
- item->setText(3, "");
- edit_frame->setLayout(hb);
- pd_ui_->advancedTree->setItemWidget(item, 3, edit_frame);
- editor->setFocus();
+ moduleWindow = new ModulePreferencesScrollArea(module);
+ prefs_pane_to_item_[MODULES_NAME] = moduleWindow;
+ pd_ui_->stackedWidget->addWidget(moduleWindow);
+ pd_ui_->stackedWidget->setCurrentWidget(moduleWindow);
}
}
}
-void PreferencesDialog::lineEditPrefDestroyed()
-{
- cur_line_edit_ = NULL;
-}
-
-void PreferencesDialog::enumPrefDestroyed()
-{
- cur_combo_box_ = NULL;
-}
-
-void PreferencesDialog::uintPrefEditingFinished()
-{
- AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
- if (!cur_line_edit_ || !adv_ti) return;
-
- pref_t *pref = adv_ti->pref();
- if (!pref) return;
-
- bool ok;
- guint new_val = cur_line_edit_->text().toUInt(&ok, prefs_get_uint_base(pref));
-
- if (ok) prefs_set_uint_value(pref, new_val, pref_stashed);
- pd_ui_->advancedTree->removeItemWidget(adv_ti, 3);
- adv_ti->updatePref();
-}
-
-void PreferencesDialog::enumPrefCurrentIndexChanged(int index)
-{
- AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
- if (!cur_combo_box_ || !adv_ti || index < 0) return;
-
- pref_t *pref = adv_ti->pref();
- if (!pref) return;
-
- prefs_set_uint_value(pref, cur_combo_box_->itemData(index).toInt(), pref_stashed);
- adv_ti->updatePref();
-}
-
-void PreferencesDialog::stringPrefEditingFinished()
-{
- AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
- if (!cur_line_edit_ || !adv_ti) return;
-
- pref_t *pref = adv_ti->pref();
- if (!pref) return;
-
- prefs_set_string_value(pref, cur_line_edit_->text().toStdString().c_str(), pref_stashed);
- pd_ui_->advancedTree->removeItemWidget(adv_ti, 3);
- adv_ti->updatePref();
-}
-
-void PreferencesDialog::rangePrefTextChanged(const QString &text)
-{
- SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(cur_line_edit_);
- AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
- if (!syntax_edit || !adv_ti) return;
-
- pref_t *pref = adv_ti->pref();
- if (!pref) return;
-
- if (text.isEmpty()) {
- syntax_edit->setSyntaxState(SyntaxLineEdit::Empty);
- } else {
- range_t *newrange;
- convert_ret_t ret = range_convert_str(NULL, &newrange, text.toUtf8().constData(), prefs_get_max_value(pref));
-
- if (ret == CVT_NO_ERROR) {
- syntax_edit->setSyntaxState(SyntaxLineEdit::Valid);
- } else {
- syntax_edit->setSyntaxState(SyntaxLineEdit::Invalid);
- }
- wmem_free(NULL, newrange);
- }
-}
-
-void PreferencesDialog::rangePrefEditingFinished()
+void PreferencesDialog::on_advancedSearchLineEdit_textEdited(const QString &search_re)
{
- SyntaxLineEdit *syntax_edit = qobject_cast<SyntaxLineEdit *>(QObject::sender());
- AdvancedPrefTreeWidgetItem *adv_ti = dynamic_cast<AdvancedPrefTreeWidgetItem *>(pd_ui_->advancedTree->currentItem());
- if (!syntax_edit || !adv_ti) return;
-
- pref_t *pref = adv_ti->pref();
- if (!pref) return;
-
- prefs_set_stashed_range_value(pref, syntax_edit->text().toUtf8().constData());
- pd_ui_->advancedTree->removeItemWidget(adv_ti, 3);
- adv_ti->updatePref();
+ advancedPrefsModel_.setFilter(search_re);
+ /* If items are filtered out, then filtered back in, the tree remains colapsed
+ Force an expansion */
+ pd_ui_->advancedView->expandAll();
}
void PreferencesDialog::on_buttonBox_accepted()
diff --git a/ui/qt/preferences_dialog.h b/ui/qt/preferences_dialog.h
index b841f783fd..e78116f27e 100644
--- a/ui/qt/preferences_dialog.h
+++ b/ui/qt/preferences_dialog.h
@@ -4,19 +4,7 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef PREFERENCES_DIALOG_H
@@ -24,19 +12,15 @@
#include <config.h>
-#include <glib.h>
-
#include <epan/prefs.h>
-#include "wireshark_application.h"
+#include <ui/qt/models/pref_models.h>
+#include <ui/qt/models/pref_delegate.h>
#include "geometry_state_dialog.h"
-#include <QTreeWidgetItem>
class QComboBox;
-extern pref_t *prefFromPrefPtr(void *pref_ptr);
-
namespace Ui {
class PreferencesDialog;
}
@@ -46,50 +30,27 @@ class PreferencesDialog : public GeometryStateDialog
Q_OBJECT
public:
- // This, prefsTree, and stackedWidget must all correspond to each other.
- enum PreferencesPane {
- ppAppearance,
- ppLayout,
- ppColumn,
- ppFontAndColor,
- ppCapture,
- ppExpert,
- ppFilterExpressions
- };
-
explicit PreferencesDialog(QWidget *parent = 0);
~PreferencesDialog();
- void setPane(PreferencesPane start_pane);
- void setPane(const QString module_name);
+
+ void setPane(const QString pane_name);
protected:
void showEvent(QShowEvent *evt);
- void keyPressEvent(QKeyEvent *evt);
private:
- void updateItem(QTreeWidgetItem &item);
-
Ui::PreferencesDialog *pd_ui_;
- QHash<PreferencesDialog::PreferencesPane, QTreeWidgetItem *>prefs_pane_to_item_;
- int cur_pref_type_;
- QLineEdit *cur_line_edit_;
- QString saved_string_pref_;
- QComboBox *cur_combo_box_;
- int saved_combo_idx_;
+
+ QHash<QString, QWidget*> prefs_pane_to_item_;
+
+ PrefsModel model_;
+ AdvancedPrefsModel advancedPrefsModel_;
+ AdvancedPrefDelegate advancedPrefsDelegate_;
+ ModulePrefsModel modulePrefsModel_;
private slots:
- void on_prefsTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
+ void selectPane(QString pane);
void on_advancedSearchLineEdit_textEdited(const QString &search_re);
- void lineEditPrefDestroyed();
- void enumPrefDestroyed();
- void uintPrefEditingFinished();
- void enumPrefCurrentIndexChanged(int index);
- void stringPrefEditingFinished();
- void rangePrefTextChanged(const QString & text);
- void rangePrefEditingFinished();
-
- void on_advancedTree_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
- void on_advancedTree_itemActivated(QTreeWidgetItem *item, int column);
void on_buttonBox_accepted();
void on_buttonBox_rejected();
diff --git a/ui/qt/preferences_dialog.ui b/ui/qt/preferences_dialog.ui
index 621076fe53..662590e2d6 100644
--- a/ui/qt/preferences_dialog.ui
+++ b/ui/qt/preferences_dialog.ui
@@ -16,7 +16,7 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <widget class="QTreeWidget" name="prefsTree">
+ <widget class="PrefModuleTreeView" name="prefsView">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
@@ -29,51 +29,9 @@
<property name="headerHidden">
<bool>true</bool>
</property>
- <column>
- <property name="text">
- <string notr="true">1</string>
- </property>
- </column>
- <item>
- <property name="text">
- <string>Appearance</string>
- </property>
- <item>
- <property name="text">
- <string>Layout</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Columns</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Font and Colors</string>
- </property>
- </item>
- </item>
- <item>
- <property name="text">
- <string>Capture</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Expert</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Filter Buttons</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Advanced</string>
- </property>
- </item>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
</widget>
<widget class="QStackedWidget" name="stackedWidget">
<property name="sizePolicy">
@@ -122,33 +80,13 @@
</layout>
</item>
<item>
- <widget class="QTreeWidget" name="advancedTree">
+ <widget class="QTreeView" name="advancedView">
<property name="indentation">
<number>0</number>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
- <column>
- <property name="text">
- <string>Name</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Status</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Type</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Value</string>
- </property>
- </column>
</widget>
</item>
</layout>
@@ -205,6 +143,12 @@
<header>uat_frame.h</header>
<container>1</container>
</customwidget>
+ <customwidget>
+ <class>PrefModuleTreeView</class>
+ <extends>QTreeView</extends>
+ <header>widgets/pref_module_view.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections>
diff --git a/ui/qt/widgets/display_filter_edit.cpp b/ui/qt/widgets/display_filter_edit.cpp
index 97cdbe96e6..46f832d8dc 100644
--- a/ui/qt/widgets/display_filter_edit.cpp
+++ b/ui/qt/widgets/display_filter_edit.cpp
@@ -4,19 +4,7 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#include "config.h"
@@ -34,6 +22,8 @@
#include <ui/qt/widgets/stock_icon_tool_button.h>
#include <ui/qt/widgets/syntax_line_edit.h>
#include <ui/qt/utils/wireshark_mime_data.h>
+#include <ui/qt/models/pref_models.h>
+#include "wireshark_application.h"
#include <QAction>
#include <QAbstractItemView>
@@ -519,7 +509,7 @@ void DisplayFilterEdit::showFilters()
void DisplayFilterEdit::showExpressionPrefs()
{
- emit showPreferencesDialog(PreferencesDialog::ppFilterExpressions);
+ emit showPreferencesDialog(PrefsModel::FILTER_BUTTONS_PREFERENCE_TREE_NAME);
}
void DisplayFilterEdit::applyOrPrepareFilter()
diff --git a/ui/qt/widgets/display_filter_edit.h b/ui/qt/widgets/display_filter_edit.h
index 84c6307fd4..447d969671 100644
--- a/ui/qt/widgets/display_filter_edit.h
+++ b/ui/qt/widgets/display_filter_edit.h
@@ -4,19 +4,7 @@
* 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.
+ * SPDX-License-Identifier: GPL-2.0+
*/
#ifndef DISPLAYFILTEREDIT_H
@@ -24,7 +12,6 @@
#include <QDrag>
-#include <ui/qt/preferences_dialog.h>
#include <ui/qt/widgets/syntax_line_edit.h>
class QEvent;
@@ -87,7 +74,7 @@ signals:
void popFilterSyntaxStatus();
void pushFilterSyntaxWarning(const QString&);
void filterPackets(QString new_filter, bool force);
- void showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane);
+ void showPreferencesDialog(QString pane_name);
};
#endif // DISPLAYFILTEREDIT_H
diff --git a/ui/qt/widgets/pref_module_view.cpp b/ui/qt/widgets/pref_module_view.cpp
new file mode 100644
index 0000000000..388839260d
--- /dev/null
+++ b/ui/qt/widgets/pref_module_view.cpp
@@ -0,0 +1,117 @@
+/* pref_module_view.cpp
+ * Tree view of preference module data.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "pref_module_view.h"
+#include <ui/qt/models/pref_models.h>
+
+#include <QHeaderView>
+
+PrefModuleTreeView::PrefModuleTreeView(QWidget *parent) : QTreeView(parent),
+ appearanceName_(PrefsModel::APPEARANCE_PREFERENCE_TREE_NAME)
+{
+}
+
+void PrefModuleTreeView::setPane(const QString pane_name)
+{
+ QModelIndex newIndex, modelIndex, appearanceIndex, protocolIndex, statIndex;
+ QString modelTreeName;
+ int row;
+
+ //look for the pane name in the main tree before trying children
+ for (row = 0; row < model()->rowCount(); row++)
+ {
+ modelIndex = model()->index(row, ModulePrefsModel::colName);
+ modelTreeName = model()->data(modelIndex, Qt::DisplayRole).toString();
+
+ if (modelTreeName.compare(appearanceName_) == 0) {
+ appearanceIndex = modelIndex;
+ } else if (modelTreeName.compare("Protocols") == 0) {
+ protocolIndex = modelIndex;
+ } else if (modelTreeName.compare("Statistics") == 0) {
+ statIndex = modelIndex;
+ }
+
+ if (modelTreeName.compare(pane_name) == 0) {
+ newIndex = modelIndex;
+ break;
+ }
+ }
+
+ //Look through appearance children
+ if (!newIndex.isValid()) {
+ for (row = 0; row < model()->rowCount(appearanceIndex); row++)
+ {
+ modelIndex = model()->index(row, ModulePrefsModel::colName, appearanceIndex);
+ modelTreeName = model()->data(modelIndex, Qt::DisplayRole).toString();
+
+ if (modelTreeName.compare(pane_name) == 0) {
+ newIndex = modelIndex;
+ break;
+ }
+ }
+ }
+
+ //Look through protocol children
+ if (!newIndex.isValid()) {
+ for (row = 0; row < model()->rowCount(protocolIndex); row++)
+ {
+ modelIndex = model()->index(row, ModulePrefsModel::colName, protocolIndex);
+ PrefsItem* proto_pref = VariantPointer<PrefsItem>::asPtr(model()->data(modelIndex, Qt::UserRole));
+ if (proto_pref != NULL) {
+ if (pane_name.compare(proto_pref->getModuleName()) == 0) {
+ newIndex = modelIndex;
+ break;
+ }
+ }
+ }
+ }
+
+ //Look through stat children
+ if (!newIndex.isValid()) {
+ for (row = 0; row < model()->rowCount(protocolIndex); row++)
+ {
+ modelIndex = model()->index(row, ModulePrefsModel::colName, protocolIndex);
+ PrefsItem* stat_pref = VariantPointer<PrefsItem>::asPtr(model()->data(modelIndex, Qt::UserRole));
+ if (stat_pref != NULL) {
+ if (pane_name.compare(stat_pref->getModuleName()) == 0) {
+ newIndex = modelIndex;
+ break;
+ }
+ }
+ }
+ }
+
+ setCurrentIndex(newIndex);
+}
+
+
+void PrefModuleTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ if (current.isValid())
+ {
+ QString pane_name = model()->data(current, ModulePrefsModel::ModuleName).toString();
+
+ emit goToPane(pane_name);
+ }
+
+ QTreeView::currentChanged(current, previous);
+}
+
+/* * 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:
+ */
diff --git a/ui/qt/widgets/pref_module_view.h b/ui/qt/widgets/pref_module_view.h
new file mode 100644
index 0000000000..8a1b871bfc
--- /dev/null
+++ b/ui/qt/widgets/pref_module_view.h
@@ -0,0 +1,48 @@
+/* pref_module_view.h
+ * Tree view of preference module data.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef PREFERENCE_MODULE_VIEW_H
+#define PREFERENCE_MODULE_VIEW_H
+
+#include <config.h>
+#include <QTreeView>
+
+class PrefModuleTreeView : public QTreeView
+{
+ Q_OBJECT
+public:
+ PrefModuleTreeView(QWidget *parent = 0);
+
+ void setPane(const QString pane_name);
+
+signals:
+ void goToPane(QString pane);
+
+protected slots:
+ void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+private:
+ //cache the translation of the module names we check frequently
+ QString appearanceName_;
+};
+#endif // PREFERENCE_MODULE_VIEW_H
+
+/*
+ * 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:
+ */