diff options
author | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2013-11-25 14:15:49 +0000 |
---|---|---|
committer | Alexis La Goutte <alexis.lagoutte@gmail.com> | 2013-11-25 14:15:49 +0000 |
commit | 43b1f476952e5de0f75e051377e6d6288979de2e (patch) | |
tree | 343e9bb36ad1de0333a7f4d60eb5be1540c9e508 | |
parent | 402fed459fb3f03c3f6fd2a0fd6649b935904c13 (diff) |
From Thomas ERSFELD (GSoC13) : Add Capture interface dialog window
* Reuse sparkline from welcome
* Split settings in tab (!= GTK)
* No all feature work (Work In Progress...)
* ...
Comments (and review) are welcome !
svn path=/trunk/; revision=53563
-rw-r--r-- | ui/qt/CMakeLists.txt | 3 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 2 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 4 | ||||
-rw-r--r-- | ui/qt/QtShark.pro | 3 | ||||
-rw-r--r-- | ui/qt/capture_interfaces_dialog.cpp | 400 | ||||
-rw-r--r-- | ui/qt/capture_interfaces_dialog.h | 115 | ||||
-rw-r--r-- | ui/qt/capture_interfaces_dialog.ui | 686 | ||||
-rw-r--r-- | ui/qt/interface_tree.cpp | 29 | ||||
-rw-r--r-- | ui/qt/interface_tree.h | 7 | ||||
-rw-r--r-- | ui/qt/main_welcome.cpp | 5 | ||||
-rw-r--r-- | ui/qt/main_welcome.h | 2 | ||||
-rw-r--r-- | ui/qt/main_window.cpp | 6 | ||||
-rw-r--r-- | ui/qt/main_window.h | 4 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 43 | ||||
-rw-r--r-- | ui/qt/preferences_dialog.cpp | 111 | ||||
-rw-r--r-- | ui/qt/preferences_dialog.h | 1 |
16 files changed, 1361 insertions, 60 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index 587600bc22..7a3686fe34 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -33,6 +33,7 @@ set(WIRESHARK_QT_HEADERS capture_filter_syntax_worker.h capture_info_dialog.h capture_interface_dialog.h + capture_interfaces_dialog.h capture_preferences_frame.h color_dialog.h color_utils.h @@ -99,6 +100,7 @@ set(WIRESHARK_QT_SRC capture_filter_syntax_worker.cpp capture_info_dialog.cpp capture_interface_dialog.cpp + capture_interfaces_dialog.cpp color_dialog.cpp color_utils.cpp capture_preferences_frame.cpp @@ -168,6 +170,7 @@ set(DIRTY_FILES set(WIRESHARK_QT_UI capture_preferences_frame.ui + capture_interfaces_dialog.ui column_preferences_frame.ui decode_as_dialog.ui export_object_dialog.ui diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index 855dea6074..64e7d13bd5 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -124,6 +124,8 @@ ui_%.h: %.ui #moc_%.cpp: %.h # $(MOC) $< -o $@ +capture_interfaces_dialog.cpp capture_interfaces_dialog.h: ui_capture_interfaces_dialog.h + capture_preferences_frame.cpp capture_preferences_frame.h: ui_capture_preferences_frame.h column_preferences_frame.cpp column_preferences_frame.h: ui_column_preferences_frame.h diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common index 62c5aa5f0a..340f2feba6 100644 --- a/ui/qt/Makefile.common +++ b/ui/qt/Makefile.common @@ -31,6 +31,7 @@ GENERATED_HEADER_FILES = # Generated header files that we don't want in the distribution. NODIST_GENERATED_HEADER_FILES = \ + ui_capture_interfaces_dialog.h \ ui_capture_preferences_frame.h \ ui_column_preferences_frame.h \ ui_decode_as_dialog.h \ @@ -103,6 +104,7 @@ MOC_HDRS = \ capture_filter_syntax_worker.h \ capture_info_dialog.h \ capture_interface_dialog.h \ + capture_interfaces_dialog.h \ color_dialog.h \ color_utils.h \ capture_preferences_frame.h \ @@ -159,6 +161,7 @@ MOC_HDRS = \ # .ui files. # UI_FILES = \ + capture_interfaces_dialog.ui \ capture_preferences_frame.ui \ column_preferences_frame.ui \ decode_as_dialog.ui \ @@ -246,6 +249,7 @@ WIRESHARK_QT_SRC = \ capture_filter_syntax_worker.cpp \ capture_info_dialog.cpp \ capture_interface_dialog.cpp \ + capture_interfaces_dialog.cpp \ color_dialog.cpp \ color_utils.cpp \ capture_preferences_frame.cpp \ diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro index a0ee15cc95..a726f38b62 100644 --- a/ui/qt/QtShark.pro +++ b/ui/qt/QtShark.pro @@ -222,6 +222,7 @@ HEADERS_WS_C = \ FORMS += \ capture_preferences_frame.ui \ + capture_interfaces_dialog.ui \ column_preferences_frame.ui \ decode_as_dialog.ui \ export_object_dialog.ui \ @@ -252,6 +253,7 @@ FORMS += \ HEADERS += $$HEADERS_WS_C \ accordion_frame.h \ + capture_interfaces_dialog.h \ capture_preferences_frame.h \ column_preferences_frame.h \ decode_as_dialog.h \ @@ -546,6 +548,7 @@ SOURCES += \ capture_filter_syntax_worker.cpp \ capture_info_dialog.cpp \ capture_interface_dialog.cpp \ + capture_interfaces_dialog.cpp \ capture_preferences_frame.cpp \ color_dialog.cpp \ color_utils.cpp \ diff --git a/ui/qt/capture_interfaces_dialog.cpp b/ui/qt/capture_interfaces_dialog.cpp new file mode 100644 index 0000000000..4305dc9b73 --- /dev/null +++ b/ui/qt/capture_interfaces_dialog.cpp @@ -0,0 +1,400 @@ +/* capture_interfaces_dialog.cpp + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + +#include "capture_interfaces_dialog.h" +#include "ui_capture_interfaces_dialog.h" + +#include "config.h" + +#include <glib.h> + +#include <QSpacerItem> +#include <QTimer> + +#include "../capture_globals.h" + +#include "capture_ui_utils.h" +#include "ui/ui_util.h" +#include "ui/capture_globals.h" +#include "ui/iface_lists.h" +#include "ui/utf8_entities.h" + +#include <cstdio> +#include <epan/prefs.h> +#include <epan/prefs-int.h> + +#include "sparkline_delegate.h" + +const int stat_update_interval_ = 1000; // ms + +CaptureInterfacesDialog::CaptureInterfacesDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::CaptureInterfacesDialog) +{ + ui->setupUi(this); + + stat_timer_ = NULL; + stat_cache_ = NULL; + + connect(ui->tbInterfaces,SIGNAL(itemPressed(QTableWidgetItem *)),this,SLOT(tableItemPressed(QTableWidgetItem *))); + connect(ui->tbInterfaces,SIGNAL(itemClicked(QTableWidgetItem *)),this,SLOT(tableItemClicked(QTableWidgetItem *))); +} + +void CaptureInterfacesDialog::tableItemClicked(QTableWidgetItem * item) +{ + Q_UNUSED(item) + + interface_t device; + global_capture_opts.num_selected = 0; + + for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) + { + bool checked = (ui->tbInterfaces->item(row, 0)->checkState() == Qt::Checked) ? true : false; + QString interface_name = ui->tbInterfaces->item(row, 1)->text(); + + device = g_array_index(global_capture_opts.all_ifaces, interface_t, row); + + if (checked == true) + { + device.selected = TRUE; + global_capture_opts.num_selected++; + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, row); + g_array_insert_val(global_capture_opts.all_ifaces, row, device); + } + else + { + device.selected = FALSE; + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, row); + g_array_insert_val(global_capture_opts.all_ifaces, row, device); + } + + } +} + +CaptureInterfacesDialog::~CaptureInterfacesDialog() +{ + delete ui; +} + +void CaptureInterfacesDialog::SetTab(int index) +{ + ui->tabWidget->setCurrentIndex(index); +} + +void CaptureInterfacesDialog::on_capturePromModeCheckBox_toggled(bool checked) +{ + prefs.capture_prom_mode = checked; +} + +void CaptureInterfacesDialog::on_cbStopCaptureAuto_toggled(bool checked) +{ + global_capture_opts.has_file_duration = checked; +} + +void CaptureInterfacesDialog::on_cbNewFileAuto_toggled(bool checked) +{ + global_capture_opts.multi_files_on = checked; +} + +void CaptureInterfacesDialog::on_cbUpdatePacketsRT_toggled(bool checked) +{ + global_capture_opts.real_time_mode = checked; +} + +void CaptureInterfacesDialog::on_cbAutoScroll_toggled(bool checked) +{ + Q_UNUSED(checked) + //global_capture_opts.has_file_duration = checked; +} + +void CaptureInterfacesDialog::on_cbExtraCaptureInfo_toggled(bool checked) +{ + global_capture_opts.show_info = checked; +} + +void CaptureInterfacesDialog::on_cbResolveMacAddresses_toggled(bool checked) +{ + gbl_resolv_flags.mac_name = checked; +} + +void CaptureInterfacesDialog::on_cbResolveNetworkNames_toggled(bool checked) +{ + gbl_resolv_flags.network_name = checked; +} + +void CaptureInterfacesDialog::on_cbResolveTransportNames_toggled(bool checked) +{ + gbl_resolv_flags.transport_name = checked; +} + +void CaptureInterfacesDialog::on_bStart_clicked() +{ + qDebug("Starting capture"); + + emit startCapture(); + + this->close(); +} + +void CaptureInterfacesDialog::on_bStop_clicked() +{ + qDebug("Stop capture"); + + emit stopCapture(); +} + +void CaptureInterfacesDialog::UpdateInterfaces() +{ + ui->cbPcap->setCurrentIndex(!prefs.capture_pcap_ng); + ui->capturePromModeCheckBox->setChecked(prefs.capture_prom_mode); + + ui->cbStopCaptureAuto->setChecked(global_capture_opts.has_file_duration); + ui->cbNewFileAuto->setChecked(global_capture_opts.multi_files_on); + + ui->cbUpdatePacketsRT->setChecked(global_capture_opts.real_time_mode); + ui->cbAutoScroll->setChecked(true); + ui->cbExtraCaptureInfo->setChecked(global_capture_opts.show_info); + + ui->cbResolveMacAddresses->setChecked(gbl_resolv_flags.mac_name); + ui->cbResolveNetworkNames->setChecked(gbl_resolv_flags.network_name); + ui->cbResolveTransportNames->setChecked(gbl_resolv_flags.transport_name); + + ui->tbInterfaces->setRowCount(0); + + + GList *if_list; + int err; + gchar *err_str = NULL; + GList *list; + char *snaplen_string, *linkname; + //guint i; + link_row *linkr = NULL; + //interface_t device; + #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + gint buffer; + #endif + gint snaplen; + gboolean hassnap, pmode; + + if_list = capture_interface_list(&err, &err_str,main_window_update); + if_list = g_list_sort(if_list, if_list_comparator_alph); + + // XXX Do we need to check for this? capture_interface_list returns an error if the length is 0. + if (g_list_length(if_list) > 0) { + interface_t device; + //setDisabled(false); + + for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) { + QList<int> *points; + + device = g_array_index(global_capture_opts.all_ifaces, interface_t, i); + + /* Continue if capture device is hidden */ + if (device.hidden) { + continue; + } + + QString output; + + ui->tbInterfaces->setRowCount(ui->tbInterfaces->rowCount() + 1); + + QTableWidgetItem *cbSelected = new QTableWidgetItem(); + cbSelected->setCheckState(device.selected ? Qt::Checked : Qt::Unchecked); + ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, CAPTURE, cbSelected); + + // traffic lines + ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate()); + points = new QList<int>(); + QTableWidgetItem *ti = new QTableWidgetItem(); + ti->setData(Qt::UserRole, qVariantFromValue(points)); + ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, TRAFFIC, ti); + + output = QString(device.display_name); + ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, INTERFACE, new QTableWidgetItem(output)); + + linkname = NULL; + if(capture_dev_user_linktype_find(device.name) != -1) { + device.active_dlt = capture_dev_user_linktype_find(device.name); + } + for (list = device.links; list != NULL; list = g_list_next(list)) { + linkr = (link_row*)(list->data); + if (linkr->dlt == device.active_dlt) { + linkname = g_strdup(linkr->name); + break; + } + } + + if (!linkname) + linkname = g_strdup("unknown"); + pmode = capture_dev_user_pmode_find(device.name); + if (pmode != -1) { + device.pmode = pmode; + } + hassnap = capture_dev_user_hassnap_find(device.name); + snaplen = capture_dev_user_snaplen_find(device.name); + if(snaplen != -1 && hassnap != -1) { + /* Default snap lenght set in preferences */ + device.snaplen = snaplen; + device.has_snaplen = hassnap; + } else { + /* No preferences set yet, use default values */ + device.snaplen = WTAP_MAX_PACKET_SIZE; + device.has_snaplen = FALSE; + } + + if (device.has_snaplen) { + snaplen_string = g_strdup_printf("%d", device.snaplen); + } else { + snaplen_string = g_strdup("default"); + } + + #if defined(_WIN32) || defined(HAVE_PCAP_CREATE) + if (capture_dev_user_buffersize_find(device.name) != -1) { + buffer = capture_dev_user_buffersize_find(device.name); + device.buffer = buffer; + } else { + device.buffer = DEFAULT_CAPTURE_BUFFER_SIZE; + } + #endif + + output = QString(linkname); + ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, LINK, new QTableWidgetItem(output)); + + output = QString(device.pmode ? "true" : "false"); + ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, PMODE, new QTableWidgetItem(output)); + + output = QString(snaplen_string); + ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, SNAPLEN, new QTableWidgetItem(output)); + + output = QString().sprintf("%d", device.buffer); + ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, BUFFER, new QTableWidgetItem(output)); + + output = QString(device.monitor_mode_enabled ? "true" : "false"); + ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, MONITOR, new QTableWidgetItem(output)); + + if (strstr(prefs.capture_device, device.name) != NULL) { + device.selected = TRUE; + global_capture_opts.num_selected++; + global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i); + g_array_insert_val(global_capture_opts.all_ifaces, i, device); + } + if (device.selected) { + ui->tbInterfaces->item(ui->tbInterfaces->rowCount()-1, 0)->setSelected(true); + } + } + } + free_interface_list(if_list); + resizeEvent(NULL); + + if (!stat_timer_) { + updateStatistics(); + stat_timer_ = new QTimer(this); + connect(stat_timer_, SIGNAL(timeout()), this, SLOT(updateStatistics())); + stat_timer_->start(stat_update_interval_); + } +} + +void CaptureInterfacesDialog::updateStatistics(void) { + //guint diff; + QList<int> *points = NULL; + + + if (!stat_cache_) { + // Start gathering statistics using dumpcap + // We crash (on OS X at least) if we try to do this from ::showEvent. + stat_cache_ = capture_stat_start(&global_capture_opts); + } + if (!stat_cache_) return; + + + for (int row = 0; row < ui->tbInterfaces->rowCount(); row++) + { + //bool checked = (ui->tbInterfaces->item(row, 0)->checkState() == Qt::Checked) ? true : false; + + //points = new QList<int>(); + +// for (if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) { +// device = g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx); +// QString device_name = ui->tbInterfaces->item(row, INTERFACE)->text(); +// if (device_name.compare(device.name) || device.hidden || device.type == IF_PIPE) +// continue; + + //diff = 0; +// if (capture_stats(stat_cache_, device.name, &stats)) { +// if ((int)(stats.ps_recv - device.last_packets) >= 0) { +// diff = stats.ps_recv - device.last_packets; +// } +// device.last_packets = stats.ps_recv; +// } + + points = ui->tbInterfaces->item(row, TRAFFIC)->data(Qt::UserRole).value<QList<int> *>(); + emit getPoints(row, points); + //ui->tbInterfaces->item + + //ui->tbInterfaces->setItemDelegateForColumn(TRAFFIC, new SparkLineDelegate()); + //points = new QList<int>(); + //QTableWidgetItem *ti = new QTableWidgetItem(); + //ti->setData(Qt::UserRole, qVariantFromValue(points)); + + QTableWidgetItem *ti = ui->tbInterfaces->item(ui->tbInterfaces->rowCount()-1, TRAFFIC); + ti->setData(Qt::UserRole, qVariantFromValue(points)); + //ui->tbInterfaces->setItem(ui->tbInterfaces->rowCount()-1, TRAFFIC, ti); + + //points->append(diff); + ui->tbInterfaces->viewport()->update(); +// global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, if_idx); +// g_array_insert_val(global_capture_opts.all_ifaces, if_idx, device); + + } +} + + +void CaptureInterfacesDialog::on_tbInterfaces_hideEvent(QHideEvent *evt) { + Q_UNUSED(evt); + + if (stat_timer_) stat_timer_->stop(); + if (stat_cache_) { + capture_stat_stop(stat_cache_); + stat_cache_ = NULL; + } +} + +void CaptureInterfacesDialog::on_tbInterfaces_showEvent(QShowEvent *evt) { + Q_UNUSED(evt); + + if (stat_timer_) stat_timer_->start(stat_update_interval_); +} + +/* + * 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/capture_interfaces_dialog.h b/ui/qt/capture_interfaces_dialog.h new file mode 100644 index 0000000000..a70cfd7e2e --- /dev/null +++ b/ui/qt/capture_interfaces_dialog.h @@ -0,0 +1,115 @@ +/* capture_interfaces_dialog.h + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + +#ifndef CAPTURE_INTERFACES_DIALOG_H +#define CAPTURE_INTERFACES_DIALOG_H + +#include <QDialog> +#include <QTableWidget> + +#include "interface_tree.h" +#include "preferences_dialog.h" + +/* + * Symbolic names for column indices. + */ +enum +{ + CAPTURE = 0, + INTERFACE, + TRAFFIC, + LINK, + PMODE, + SNAPLEN, +#if defined(HAVE_PCAP_CREATE) + BUFFER, + MONITOR, +#elif defined(_WIN32) && !defined(HAVE_PCAP_CREATE) + BUFFER, +#endif + FILTER, + NUM_COLUMNS +}; + + +namespace Ui { +class CaptureInterfacesDialog; +} + +class CaptureInterfacesDialog : public QDialog +{ + Q_OBJECT + +public: + explicit CaptureInterfacesDialog(QWidget *parent = 0); + ~CaptureInterfacesDialog(); + + void SetTab(int index); + void UpdateInterfaces(); + //void updateStatistics(void); + +private slots: + void on_capturePromModeCheckBox_toggled(bool checked); + void on_cbStopCaptureAuto_toggled(bool checked); + void on_cbUpdatePacketsRT_toggled(bool checked); + void on_cbAutoScroll_toggled(bool checked); + void on_cbNewFileAuto_toggled(bool checked); + void on_cbExtraCaptureInfo_toggled(bool checked); + void on_cbResolveMacAddresses_toggled(bool checked); + void on_cbResolveNetworkNames_toggled(bool checked); + void on_cbResolveTransportNames_toggled(bool checked); + void on_bStart_clicked(); + void on_bStop_clicked(); + void tableItemClicked(QTableWidgetItem * item); + void updateStatistics(void); + void on_tbInterfaces_hideEvent(QHideEvent *evt); + void on_tbInterfaces_showEvent(QShowEvent *evt); + +signals: + void startCapture(); + void stopCapture(); + void getPoints(int row, PointList *pts); + +private: + Ui::CaptureInterfacesDialog *ui; + Qt::CheckState m_pressedItemState; + + if_stat_cache_t *stat_cache_; + QTimer *stat_timer_; +}; + +#endif // CAPTURE_INTERFACES_DIALOG_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/capture_interfaces_dialog.ui b/ui/qt/capture_interfaces_dialog.ui new file mode 100644 index 0000000000..317f0e0522 --- /dev/null +++ b/ui/qt/capture_interfaces_dialog.ui @@ -0,0 +1,686 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CaptureInterfacesDialog</class> + <widget class="QDialog" name="CaptureInterfacesDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>636</width> + <height>403</height> + </rect> + </property> + <property name="windowTitle"> + <string>Wireshark: Capture interfaces</string> + </property> + <widget class="QTabWidget" name="tabWidget"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>641</width> + <height>351</height> + </rect> + </property> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>Input</string> + </attribute> + <widget class="QPushButton" name="bClose_2"> + <property name="geometry"> + <rect> + <x>510</x> + <y>250</y> + <width>91</width> + <height>23</height> + </rect> + </property> + <property name="text"> + <string>Add pipe...</string> + </property> + </widget> + <widget class="QCheckBox" name="capturePromModeCheckBox"> + <property name="geometry"> + <rect> + <x>20</x> + <y>244</y> + <width>363</width> + <height>20</height> + </rect> + </property> + <property name="toolTip"> + <string><html><head/><body><p>You probably want to enable this. Usually a network card will only capture the traffic sent to its own network address. If you want to capture all traffic that the network card can &quot;see&quot;, mark this option. See the FAQ for some more details of capturing packets from a switched network.</p></body></html></string> + </property> + <property name="text"> + <string>Capture packets in promiscuous mode</string> + </property> + </widget> + <widget class="QCheckBox" name="captureShowInfoCheckBox"> + <property name="geometry"> + <rect> + <x>20</x> + <y>280</y> + <width>363</width> + <height>20</height> + </rect> + </property> + <property name="toolTip"> + <string><html><head/><body><p>Show the capture summary dialog while capturing.</p></body></html></string> + </property> + <property name="text"> + <string>Show the capture summary dialog while capturing</string> + </property> + </widget> + <widget class="QTableWidget" name="tbInterfaces"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>611</width> + <height>221</height> + </rect> + </property> + <property name="editTriggers"> + <set>QAbstractItemView::NoEditTriggers</set> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <property name="rowCount"> + <number>0</number> + </property> + <property name="columnCount"> + <number>9</number> + </property> + <column> + <property name="text"> + <string>Capture</string> + </property> + </column> + <column> + <property name="text"> + <string>Interface</string> + </property> + </column> + <column> + <property name="text"> + <string>Traffic</string> + </property> + </column> + <column> + <property name="text"> + <string>Link-layer header</string> + </property> + </column> + <column> + <property name="text"> + <string>Prom. mode</string> + </property> + </column> + <column> + <property name="text"> + <string>Snaplen [B]</string> + </property> + </column> + <column> + <property name="text"> + <string>Buffer [MB]</string> + </property> + </column> + <column> + <property name="text"> + <string>Mon. Mode</string> + </property> + </column> + <column> + <property name="text"> + <string>Capture Filter</string> + </property> + </column> + </widget> + </widget> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>Output</string> + </attribute> + <widget class="QCheckBox" name="checkBox"> + <property name="geometry"> + <rect> + <x>40</x> + <y>50</y> + <width>231</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string>Capture direcly to file</string> + </property> + </widget> + <widget class="QCheckBox" name="cbNewFileAuto"> + <property name="geometry"> + <rect> + <x>40</x> + <y>110</y> + <width>341</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string>Create a new file automatically after...</string> + </property> + </widget> + <widget class="QCheckBox" name="checkBox_3"> + <property name="geometry"> + <rect> + <x>61</x> + <y>143</y> + <width>271</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string> packets</string> + </property> + </widget> + <widget class="QSpinBox" name="spinBox"> + <property name="geometry"> + <rect> + <x>85</x> + <y>141</y> + <width>121</width> + <height>25</height> + </rect> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::PlusMinus</enum> + </property> + <property name="maximum"> + <number>1000</number> + </property> + </widget> + <widget class="QCheckBox" name="checkBox_4"> + <property name="geometry"> + <rect> + <x>60</x> + <y>170</y> + <width>21</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string/> + </property> + </widget> + <widget class="QCheckBox" name="checkBox_5"> + <property name="geometry"> + <rect> + <x>60</x> + <y>200</y> + <width>51</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string/> + </property> + </widget> + <widget class="QCheckBox" name="checkBox_6"> + <property name="geometry"> + <rect> + <x>40</x> + <y>230</y> + <width>131</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string>Reuse old files</string> + </property> + </widget> + <widget class="QWidget" name="layoutWidget"> + <property name="geometry"> + <rect> + <x>50</x> + <y>70</y> + <width>311</width> + <height>29</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>File:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item> + <widget class="QPushButton" name="pushButton"> + <property name="text"> + <string>Browse...</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="layoutWidget"> + <property name="geometry"> + <rect> + <x>40</x> + <y>10</y> + <width>199</width> + <height>29</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Output format</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="cbPcap"> + <item> + <property name="text"> + <string>PCAP-NG</string> + </property> + </item> + <item> + <property name="text"> + <string>PCAP</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="layoutWidget"> + <property name="geometry"> + <rect> + <x>84</x> + <y>198</y> + <width>251</width> + <height>29</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QSpinBox" name="spinBox_3"> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::PlusMinus</enum> + </property> + <property name="maximum"> + <number>1000</number> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBox_3"> + <item> + <property name="text"> + <string>seconds</string> + </property> + </item> + <item> + <property name="text"> + <string>minutes</string> + </property> + </item> + <item> + <property name="text"> + <string>hours</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="layoutWidget"> + <property name="geometry"> + <rect> + <x>84</x> + <y>168</y> + <width>251</width> + <height>29</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QSpinBox" name="spinBox_2"> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::PlusMinus</enum> + </property> + <property name="maximum"> + <number>1000</number> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBox_2"> + <item> + <property name="text"> + <string>Megabytes</string> + </property> + </item> + <item> + <property name="text"> + <string>Kilobytes</string> + </property> + </item> + <item> + <property name="text"> + <string>Bytes</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + <zorder>layoutWidget</zorder> + <zorder>layoutWidget</zorder> + <zorder>layoutWidget</zorder> + <zorder>layoutWidget</zorder> + <zorder>checkBox_3</zorder> + <zorder>checkBox</zorder> + <zorder>cbNewFileAuto</zorder> + <zorder>spinBox</zorder> + <zorder>checkBox_4</zorder> + <zorder>checkBox_5</zorder> + <zorder>checkBox_6</zorder> + </widget> + <widget class="QWidget" name="tab_3"> + <attribute name="title"> + <string>Options</string> + </attribute> + <widget class="QCheckBox" name="cbStopCaptureAuto"> + <property name="geometry"> + <rect> + <x>10</x> + <y>170</y> + <width>261</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string>Stop capture automatically after...</string> + </property> + </widget> + <widget class="QSpinBox" name="spinBox_7"> + <property name="geometry"> + <rect> + <x>54</x> + <y>198</y> + <width>121</width> + <height>25</height> + </rect> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::PlusMinus</enum> + </property> + <property name="maximum"> + <number>1000</number> + </property> + </widget> + <widget class="QCheckBox" name="checkBox_14"> + <property name="geometry"> + <rect> + <x>29</x> + <y>227</y> + <width>21</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string/> + </property> + </widget> + <widget class="QWidget" name="layoutWidget_6"> + <property name="geometry"> + <rect> + <x>53</x> + <y>255</y> + <width>251</width> + <height>29</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_11"> + <item> + <widget class="QSpinBox" name="spinBox_8"> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::PlusMinus</enum> + </property> + <property name="maximum"> + <number>1000</number> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBox_7"> + <item> + <property name="text"> + <string>seconds</string> + </property> + </item> + <item> + <property name="text"> + <string>minutes</string> + </property> + </item> + <item> + <property name="text"> + <string>hours</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + <widget class="QCheckBox" name="checkBox_15"> + <property name="geometry"> + <rect> + <x>29</x> + <y>257</y> + <width>51</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string/> + </property> + </widget> + <widget class="QWidget" name="layoutWidget_7"> + <property name="geometry"> + <rect> + <x>53</x> + <y>225</y> + <width>251</width> + <height>29</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_12"> + <item> + <widget class="QSpinBox" name="spinBox_9"> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::PlusMinus</enum> + </property> + <property name="maximum"> + <number>1000</number> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="comboBox_8"> + <item> + <property name="text"> + <string>Megabytes</string> + </property> + </item> + <item> + <property name="text"> + <string>Kilobytes</string> + </property> + </item> + <item> + <property name="text"> + <string>Bytes</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + <widget class="QCheckBox" name="checkBox_16"> + <property name="geometry"> + <rect> + <x>30</x> + <y>200</y> + <width>271</width> + <height>21</height> + </rect> + </property> + <property name="text"> + <string> packets</string> + </property> + </widget> + <widget class="QGroupBox" name="groupBox"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>601</width> + <height>111</height> + </rect> + </property> + <property name="title"> + <string>Display Options</string> + </property> + <widget class="QWidget" name="layoutWidget"> + <property name="geometry"> + <rect> + <x>10</x> + <y>20</y> + <width>298</width> + <height>80</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QCheckBox" name="cbUpdatePacketsRT"> + <property name="text"> + <string>Update list of packets in real-time</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="cbAutoScroll"> + <property name="text"> + <string>Automatically scroll during live capture</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="cbExtraCaptureInfo"> + <property name="text"> + <string>Show extra capture information dialog</string> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QGroupBox" name="groupBox_2"> + <property name="geometry"> + <rect> + <x>320</x> + <y>0</y> + <width>601</width> + <height>111</height> + </rect> + </property> + <property name="title"> + <string>Name Resolution</string> + </property> + <widget class="QWidget" name="layoutWidget_9"> + <property name="geometry"> + <rect> + <x>10</x> + <y>20</y> + <width>211</width> + <height>80</height> + </rect> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QCheckBox" name="cbResolveMacAddresses"> + <property name="text"> + <string>Resolve MAC Addresses</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="cbResolveNetworkNames"> + <property name="text"> + <string>Resolve network names</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="cbResolveTransportNames"> + <property name="text"> + <string>Resolve transport names</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </widget> + </widget> + </widget> + <widget class="QWidget" name="layoutWidget"> + <property name="geometry"> + <rect> + <x>10</x> + <y>360</y> + <width>360</width> + <height>29</height> + </rect> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="bStart"> + <property name="text"> + <string>Start</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="bStop"> + <property name="text"> + <string>Stop</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="bClose"> + <property name="text"> + <string>Close</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + <resources/> + <connections/> +</ui> diff --git a/ui/qt/interface_tree.cpp b/ui/qt/interface_tree.cpp index 70d8b8d764..795800bcf7 100644 --- a/ui/qt/interface_tree.cpp +++ b/ui/qt/interface_tree.cpp @@ -49,6 +49,8 @@ InterfaceTree::InterfaceTree(QWidget *parent) : { QTreeWidgetItem *ti; + qRegisterMetaType< PointList >( "PointList" ); + header()->setVisible(false); setRootIsDecorated(false); setUniformRowHeights(true); @@ -200,6 +202,33 @@ void InterfaceTree::getInterfaceList() #endif // HAVE_LIBPCAP } +void InterfaceTree::getPoints(int row, PointList *pts) +{ + QTreeWidgetItemIterator iter(this); + qDebug("iter;..!"); + + for (int i = 0; (*iter); i++) + { + if (row == i) + { + qDebug("found! row:%d", row); + QString device_name = (*iter)->data(0, Qt::UserRole).value<QString>(); + QList<int> *punkt = (*iter)->data(1, Qt::UserRole).value<QList<int> *>(); + for (int j = 0; j < punkt->length(); j++) + { + pts->append(punkt->at(j)); + } + //pts = new QList<int>(*punkt); + //pts->operator =(punkt); + //pts = punkt; + //pts->append(150); + qDebug("done"); + return; + } + iter++; + } +} + void InterfaceTree::updateStatistics(void) { #ifdef HAVE_LIBPCAP interface_t device; diff --git a/ui/qt/interface_tree.h b/ui/qt/interface_tree.h index 4fb7a14d6a..6ccbc1ac54 100644 --- a/ui/qt/interface_tree.h +++ b/ui/qt/interface_tree.h @@ -37,6 +37,8 @@ #include <QTreeWidget> +typedef QList<int> PointList; + class InterfaceTree : public QTreeWidget { Q_OBJECT @@ -62,6 +64,8 @@ public slots: // add_interface_to_list // change_interface_selection // change_interface_selection_for_all + //void getPoints(int row, QList<int> *pts); + void getPoints(int row, PointList *pts); private slots: void getInterfaceList(); @@ -69,6 +73,9 @@ private slots: void updateSelectedInterfaces(); }; + +//Q_DECLARE_METATYPE(QList<int>) + #endif // INTERFACE_TREE_H /* diff --git a/ui/qt/main_welcome.cpp b/ui/qt/main_welcome.cpp index 8020a30ba3..57f4f60fc9 100644 --- a/ui/qt/main_welcome.cpp +++ b/ui/qt/main_welcome.cpp @@ -167,6 +167,11 @@ MainWelcome::MainWelcome(QWidget *parent) : splash_overlay_ = new SplashOverlay(this); } +InterfaceTree *MainWelcome::getInterfaceTree() +{ + return welcome_ui_->interfaceTree; +} + void MainWelcome::destroySplashOverlay() { #if !defined(Q_OS_MAC) || QT_VERSION > QT_VERSION_CHECK(5, 0, 0) diff --git a/ui/qt/main_welcome.h b/ui/qt/main_welcome.h index 4e0851ee08..adb182df0d 100644 --- a/ui/qt/main_welcome.h +++ b/ui/qt/main_welcome.h @@ -29,6 +29,7 @@ #include <QTreeWidgetItem> #include "splash_overlay.h" +#include "interface_tree.h" namespace Ui { class MainWelcome; @@ -39,6 +40,7 @@ class MainWelcome : public QFrame Q_OBJECT public: explicit MainWelcome(QWidget *parent = 0); + InterfaceTree *getInterfaceTree(); protected: void resizeEvent(QResizeEvent *event); diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp index d3c827406d..97d3990971 100644 --- a/ui/qt/main_window.cpp +++ b/ui/qt/main_window.cpp @@ -119,6 +119,9 @@ MainWindow::MainWindow(QWidget *parent) : connect(&summary_dialog_, SIGNAL(captureCommentChanged()), this, SLOT(updateForUnsavedChanges())); + connect(&capture_interfaces_dialog_, SIGNAL(startCapture()), this, SLOT(startCapture())); + connect(&capture_interfaces_dialog_, SIGNAL(stopCapture()), this, SLOT(stopCapture())); + const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit()); connect(df_edit, SIGNAL(pushFilterSyntaxStatus(QString&)), main_ui_->statusBar, SLOT(pushFilterStatus(QString&))); connect(df_edit, SIGNAL(popFilterSyntaxStatus()), main_ui_->statusBar, SLOT(popFilterStatus())); @@ -293,6 +296,9 @@ MainWindow::MainWindow(QWidget *parent) : connect(main_ui_->welcomePage, SIGNAL(captureFilterSyntaxChanged(bool)), this, SLOT(captureFilterSyntaxChanged(bool))); + connect(&capture_interfaces_dialog_, SIGNAL(getPoints(int,PointList*)), + this->main_welcome_->getInterfaceTree(), SLOT(getPoints(int,PointList*))); + main_ui_->mainStack->setCurrentWidget(main_welcome_); } diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index a296680a4d..f30de3a509 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -58,6 +58,7 @@ #include "capture_file_dialog.h" #include "summary_dialog.h" #include "follow_stream_dialog.h" +#include "capture_interfaces_dialog.h" class QAction; @@ -116,6 +117,7 @@ private: bool capture_stopping_; bool capture_filter_valid_; + CaptureInterfacesDialog capture_interfaces_dialog_; // Pipe input gint pipe_source_; @@ -321,6 +323,8 @@ private slots: void on_actionStatisticsTcpStreamRoundTripTime_triggered(); void on_actionStatisticsTcpStreamWindowScaling_triggered(); + void on_actionCaptureInterfaces_triggered(); + void openStatisticsTreeDialog(const gchar *abbr); void on_actionStatisticsANCP_triggered(); void on_actionStatisticsBACappInstanceId_triggered(); diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 551c0499bd..77c90fdc49 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -2013,11 +2013,6 @@ void MainWindow::on_goToLineEdit_returnPressed() on_goToGo_clicked(); } -void MainWindow::on_actionCaptureOptions_triggered() -{ - qDebug() << "Capture options"; -} - void MainWindow::on_actionStartCapture_triggered() { //#ifdef HAVE_AIRPCAP @@ -2082,6 +2077,44 @@ void MainWindow::on_actionSummary_triggered() summary_dialog_.activateWindow(); } +void MainWindow::on_actionCaptureInterfaces_triggered() +{ + capture_interfaces_dialog_.SetTab(0); + capture_interfaces_dialog_.UpdateInterfaces(); + + if (capture_interfaces_dialog_.isMinimized() == true) + { + capture_interfaces_dialog_.showNormal(); + } + else + { + capture_interfaces_dialog_.show(); + } + + capture_interfaces_dialog_.raise(); + capture_interfaces_dialog_.activateWindow(); +} + +void MainWindow::on_actionCaptureOptions_triggered() +{ + capture_interfaces_dialog_.SetTab(2); + capture_interfaces_dialog_.UpdateInterfaces(); + + if (capture_interfaces_dialog_.isMinimized() == true) + { + capture_interfaces_dialog_.showNormal(); + } + else + { + capture_interfaces_dialog_.show(); + } + + capture_interfaces_dialog_.raise(); + capture_interfaces_dialog_.activateWindow(); +} + + + /* * Editor modelines * diff --git a/ui/qt/preferences_dialog.cpp b/ui/qt/preferences_dialog.cpp index b4317e0fb2..f23d1d3093 100644 --- a/ui/qt/preferences_dialog.cpp +++ b/ui/qt/preferences_dialog.cpp @@ -64,6 +64,62 @@ pref_t *prefFromPrefPtr(void *pref_ptr) return pref_ptr_to_pref_[pref_ptr]; } +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); + + 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 (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue; + + const char *type_name = prefs_pref_type_name(pref); + if (!type_name) continue; + + pref_stash(pref, NULL); + + QTreeWidgetItem *item = new QTreeWidgetItem(); + QString full_name = QString(module->name ? module->name : module->parent->name) + "." + pref->name; + QString type_desc = gchar_free_to_qstring(prefs_pref_type_description(pref)); + QString default_value = gchar_free_to_qstring(prefs_pref_to_str(pref, pref_stashed)); + + item->setData(0, Qt::UserRole, qVariantFromValue(pref)); + item->setText(0, full_name); + item->setToolTip(0, QString("<span>%1</span>").arg(pref->description)); + item->setToolTip(1, QObject::tr("Has this preference been changed?")); + item->setText(2, type_name); + item->setToolTip(2, QString("<span>%1</span>").arg(type_desc)); + item->setToolTip(3, QString("<span>%1</span>").arg( + default_value.isEmpty() ? default_value : QObject::tr("Default value is empty"))); + tl_children << item; + + // .uat is a void * so it wins the "useful key value" prize. + if (pref->varp.uat) { + pref_ptr_to_pref_[pref->varp.uat] = 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; +} + + extern "C" { // Callbacks prefs routines @@ -153,61 +209,6 @@ module_prefs_show(module_t *module, gpointer ti_ptr) } 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); - - 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 (pref->type == PREF_OBSOLETE || pref->type == PREF_STATIC_TEXT) continue; - - const char *type_name = prefs_pref_type_name(pref); - if (!type_name) continue; - - pref_stash(pref, NULL); - - QTreeWidgetItem *item = new QTreeWidgetItem(); - QString full_name = QString(module->name ? module->name : module->parent->name) + "." + pref->name; - QString type_desc = gchar_free_to_qstring(prefs_pref_type_description(pref)); - QString default_value = gchar_free_to_qstring(prefs_pref_to_str(pref, pref_stashed)); - - item->setData(0, Qt::UserRole, qVariantFromValue(pref)); - item->setText(0, full_name); - item->setToolTip(0, QString("<span>%1</span>").arg(pref->description)); - item->setToolTip(1, QObject::tr("Has this preference been changed?")); - item->setText(2, type_name); - item->setToolTip(2, QString("<span>%1</span>").arg(type_desc)); - item->setToolTip(3, QString("<span>%1</span>").arg( - default_value.isEmpty() ? default_value : QObject::tr("Default value is empty"))); - tl_children << item; - - // .uat is a void * so it wins the "useful key value" prize. - if (pref->varp.uat) { - pref_ptr_to_pref_[pref->varp.uat] = 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 module_prefs_unstash(module_t *module, gpointer data) { gboolean *must_redissect_p = (gboolean *)data; diff --git a/ui/qt/preferences_dialog.h b/ui/qt/preferences_dialog.h index 827ea893eb..fe4db669b7 100644 --- a/ui/qt/preferences_dialog.h +++ b/ui/qt/preferences_dialog.h @@ -37,6 +37,7 @@ #include <QComboBox> extern pref_t *prefFromPrefPtr(void *pref_ptr); +extern guint fill_advanced_prefs(module_t *module, gpointer root_ptr); namespace Ui { class PreferencesDialog; |