aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/qt/CMakeLists.txt10
-rw-r--r--ui/qt/Makefile.am10
-rw-r--r--ui/qt/byte_view_tab.cpp352
-rw-r--r--ui/qt/byte_view_tab.h44
-rw-r--r--ui/qt/main_status_bar.cpp56
-rw-r--r--ui/qt/main_status_bar.h3
-rw-r--r--ui/qt/main_window.cpp54
-rw-r--r--ui/qt/main_window.h17
-rw-r--r--ui/qt/main_window_slots.cpp96
-rw-r--r--ui/qt/packet_dialog.cpp70
-rw-r--r--ui/qt/packet_dialog.h10
-rw-r--r--ui/qt/packet_list.cpp25
-rw-r--r--ui/qt/packet_list.h7
-rw-r--r--ui/qt/proto_tree.cpp63
-rw-r--r--ui/qt/proto_tree.h8
-rw-r--r--ui/qt/utils/data_printer.cpp182
-rw-r--r--ui/qt/utils/data_printer.h85
-rw-r--r--ui/qt/utils/field_information.cpp175
-rw-r--r--ui/qt/utils/field_information.h91
-rw-r--r--ui/qt/utils/frame_information.cpp117
-rw-r--r--ui/qt/utils/frame_information.h80
-rw-r--r--ui/qt/widgets/byte_view_text.cpp (renamed from ui/qt/byte_view_text.cpp)0
-rw-r--r--ui/qt/widgets/byte_view_text.h (renamed from ui/qt/byte_view_text.h)0
-rw-r--r--ui/qt/wireshark_application.cpp14
-rw-r--r--ui/qt/wireshark_application.h4
25 files changed, 1113 insertions, 460 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index d6a0045ddf..b3bdbc4703 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -24,6 +24,7 @@ ADD_CUSTOM_CMAKE_INCLUDE()
set(WIRESHARK_WIDGET_HEADERS
widgets/additional_toolbar.h
widgets/apply_line_edit.h
+ widgets/byte_view_text.h
widgets/capture_filter_combo.h
widgets/capture_filter_edit.h
widgets/clickable_label.h
@@ -48,6 +49,9 @@ set(WIRESHARK_WIDGET_HEADERS
set(WIRESHARK_UTILS_HEADERS
utils/color_utils.h
+ utils/field_information.h
+ utils/frame_information.h
+ utils/data_printer.h
utils/stock_icon.h
utils/qt_ui_utils.h
utils/tango_colors.h
@@ -87,7 +91,6 @@ set(WIRESHARK_QT_HEADERS
bluetooth_hci_summary_dialog.h
accordion_frame.h
byte_view_tab.h
- byte_view_text.h
capture_file.h
capture_file_dialog.h
capture_file_properties_dialog.h
@@ -226,6 +229,7 @@ file(GLOB EXTRA_QT_HEADERS
set(WIRESHARK_WIDGET_SRCS
widgets/additional_toolbar.cpp
widgets/apply_line_edit.cpp
+ widgets/byte_view_text.cpp
widgets/capture_filter_combo.cpp
widgets/capture_filter_edit.cpp
widgets/clickable_label.cpp
@@ -250,6 +254,9 @@ set(WIRESHARK_WIDGET_SRCS
set(WIRESHARK_UTILS_SRCS
utils/color_utils.cpp
+ utils/field_information.cpp
+ utils/frame_information.cpp
+ utils/data_printer.cpp
utils/stock_icon.cpp
utils/wireshark_mime_data.cpp
utils/qt_ui_utils.cpp
@@ -285,7 +292,6 @@ set(WIRESHARK_QT_SRC
bluetooth_devices_dialog.cpp
bluetooth_hci_summary_dialog.cpp
byte_view_tab.cpp
- byte_view_text.cpp
capture_file.cpp
capture_file_dialog.cpp
capture_file_properties_dialog.cpp
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index 735c849a55..eca7868386 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -154,6 +154,7 @@ GENERATOR_FILES =
MOC_WIDGET_HDRS = \
widgets/additional_toolbar.h \
widgets/apply_line_edit.h \
+ widgets/byte_view_text.h \
widgets/capture_filter_combo.h \
widgets/capture_filter_edit.h \
widgets/clickable_label.h \
@@ -178,6 +179,9 @@ MOC_WIDGET_HDRS = \
# Files that are utility classes with multi-purpose, but no widgets
MOC_UTILS_HDRS = \
utils/color_utils.h \
+ utils/field_information.h \
+ utils/frame_information.h \
+ utils/data_printer.h \
utils/stock_icon.h \
utils/qt_ui_utils.h \
utils/wireshark_mime_data.h \
@@ -216,7 +220,6 @@ MOC_HDRS = \
bluetooth_devices_dialog.h \
bluetooth_hci_summary_dialog.h \
byte_view_tab.h \
- byte_view_text.h \
capture_file.h \
capture_file_dialog.h \
capture_file_properties_dialog.h \
@@ -470,6 +473,7 @@ QM_FILES = $(TS_FILES:.ts=.qm)
WIRESHARK_QT_WIDGET_SRC = \
widgets/additional_toolbar.cpp \
widgets/apply_line_edit.cpp \
+ widgets/byte_view_text.cpp \
widgets/capture_filter_combo.cpp \
widgets/capture_filter_edit.cpp \
widgets/clickable_label.cpp \
@@ -493,6 +497,9 @@ WIRESHARK_QT_WIDGET_SRC = \
WIRESHARK_QT_UTILS_SRC = \
utils/color_utils.cpp \
+ utils/field_information.cpp \
+ utils/frame_information.cpp \
+ utils/data_printer.cpp \
utils/stock_icon.cpp \
utils/wireshark_mime_data.cpp \
utils/qt_ui_utils.cpp
@@ -525,7 +532,6 @@ WIRESHARK_QT_SRC = \
bluetooth_devices_dialog.cpp \
bluetooth_hci_summary_dialog.cpp \
byte_view_tab.cpp \
- byte_view_text.cpp \
capture_file.cpp \
capture_file_dialog.cpp \
capture_file_properties_dialog.cpp \
diff --git a/ui/qt/byte_view_tab.cpp b/ui/qt/byte_view_tab.cpp
index 5fea573bed..9b9c08cdcc 100644
--- a/ui/qt/byte_view_tab.cpp
+++ b/ui/qt/byte_view_tab.cpp
@@ -29,9 +29,12 @@
#include "cfile.h"
#include "epan/epan_dissect.h"
+#include "epan/tvbuff-int.h"
+
+#include <wireshark_application.h>
#include <ui/qt/utils/variant_pointer.h>
-#include <ui/qt/byte_view_text.h>
+#include <ui/qt/widgets/byte_view_text.h>
#define tvb_data_property "tvb_data_property"
@@ -41,12 +44,27 @@
ByteViewTab::ByteViewTab(QWidget *parent) :
QTabWidget(parent),
- cap_file_(0)
+ cap_file_(0),
+ curSelected(0)
{
setAccessibleName(tr("Packet bytes"));
setTabPosition(QTabWidget::South);
setDocumentMode(true);
- addTab();
+
+ connect(wsApp, SIGNAL(appInitialized()), this, SLOT(connectToMainWindow()));
+}
+
+void ByteViewTab::connectToMainWindow()
+{
+ connect(this, SIGNAL(fieldSelected(FieldInformation *)),
+ wsApp->mainWindow(), SIGNAL(fieldSelected(FieldInformation *)));
+ connect(this, SIGNAL(fieldHighlight(FieldInformation *)),
+ wsApp->mainWindow(), SIGNAL(fieldHighlight(FieldInformation *)));
+
+ /* Connect change of packet selection */
+ connect(wsApp->mainWindow(), SIGNAL(packetSelectionChanged()), this, SLOT(packetSelectionChanged()));
+ connect(wsApp->mainWindow(), SIGNAL(setCaptureFile(capture_file*)), this, SLOT(setCaptureFile(capture_file*)));
+ connect(wsApp->mainWindow(), SIGNAL(fieldSelected(FieldInformation *)), this, SLOT(selectedFieldChanged(FieldInformation *)));
}
void ByteViewTab::addTab(const char *name, tvbuff_t *tvb) {
@@ -64,16 +82,17 @@ void ByteViewTab::addTab(const char *name, tvbuff_t *tvb) {
ByteViewText * byte_view_text = new ByteViewText(data, encoding, this);
byte_view_text->setAccessibleName(name);
- byte_view_text->setMonospaceFont(mono_font_);
+ byte_view_text->setMonospaceFont(wsApp->monospaceFont());
byte_view_text->setProperty(tvb_data_property, VariantPointer<tvbuff_t>::asQVariant(tvb));
- connect(this, SIGNAL(monospaceFontChanged(QFont)), byte_view_text, SLOT(setMonospaceFont(QFont)));
+ connect(wsApp, SIGNAL(zoomMonospaceFont(QFont)), byte_view_text, SLOT(setMonospaceFont(QFont)));
connect(byte_view_text, SIGNAL(byteHovered(int)), this, SLOT(byteViewTextHovered(int)));
connect(byte_view_text, SIGNAL(byteSelected(int)), this, SLOT(byteViewTextMarked(int)));
int idx = QTabWidget::addTab(byte_view_text, name);
+ byte_view_text->setProperty("tab_index", qVariantFromValue(idx));
QTabWidget::setTabToolTip(idx, name);
}
@@ -99,221 +118,89 @@ void ByteViewTab::packetSelectionChanged()
void ByteViewTab::byteViewTextHovered(int idx)
{
- if ( idx < 0 )
+ if ( idx >= 0 && cap_file_ && cap_file_->edt )
{
- emit tvbOffsetHovered((tvbuff_t *)0, idx);
- return;
- }
+ tvbuff_t * tvb = VariantPointer<tvbuff_t>::asPtr(sender()->property(tvb_data_property));
+ proto_tree * tree = cap_file_->edt->tree;
- tvbuff_t * tvb = VariantPointer<tvbuff_t>::asPtr(sender()->property(tvb_data_property));
-
- emit tvbOffsetHovered(tvb, idx);
-}
-
-void ByteViewTab::byteViewTextMarked(int idx)
-{
- if ( idx < 0 )
- {
- emit tvbOffsetMarked((tvbuff_t *)0, idx);
- return;
- }
-
- tvbuff_t * tvb = VariantPointer<tvbuff_t>::asPtr(sender()->property(tvb_data_property));
-
- emit tvbOffsetMarked(tvb, idx);
-}
-
-// XXX How many hex dump routines do we have?
-const int byte_line_length_ = 16; // Print out data for 16 bytes on one line
-void ByteViewTab::copyHexTextDump(QByteArray data, bool append_text)
-{
- QString clipboard_text;
- /* Write hex data for a line, then ascii data, then concatenate and add to buffer */
- QString hex_str, char_str;
- int i;
- bool end_of_line = true; /* Initial state is end of line */
- int byte_line_part_length;
-
- i = 0;
- while (i < data.count()) {
- if(end_of_line) {
- hex_str += QString("%1 ").arg(i, 4, 16, QChar('0')); /* Offset - note that we _append_ here */
- }
-
- hex_str += QString(" %1").arg(data[i], 2, 16, QChar('0'));
- if(append_text) {
- char_str += QString("%1").arg(g_ascii_isprint(data[i]) ? QChar(data[i]) : '.');
- }
-
- /* Look ahead to see if this is the end of the data */
- byte_line_part_length = (++i) % byte_line_length_;
- if(i >= data.count()){
- /* End of data - need to fill in spaces in hex string and then do "end of line".
- *
- */
- if (append_text) {
- int fill_len = byte_line_part_length == 0 ?
- 0 : byte_line_length_ - byte_line_part_length;
- /* Add three spaces for each missing byte */
- hex_str += QString(fill_len * 3, ' ');
- }
- end_of_line = true;
- } else {
- end_of_line = (byte_line_part_length == 0);
- }
-
- if (end_of_line){
- /* End of line */
- clipboard_text += hex_str;
- if(append_text) {
- /* Two spaces between hex and text */
- clipboard_text += " ";
- clipboard_text += char_str;
+ if ( tvb && tree )
+ {
+ field_info * fi = proto_find_field_from_offset(tree, idx, tvb);
+ if ( fi )
+ {
+ emit fieldHighlight(new FieldInformation(fi, this));
+ return;
}
- /* Setup ready for next line */
- hex_str = "\n";
- char_str.clear();
}
}
- if (!clipboard_text.isEmpty()) {
- qApp->clipboard()->setText(clipboard_text);
- }
+ emit fieldHighlight((FieldInformation *)0);
}
-void ByteViewTab::copyPrintableText(QByteArray data)
+void ByteViewTab::byteViewTextMarked(int idx)
{
- QString clipboard_text;
-
- for (int i = 0; i < data.count(); i++)
+ if ( idx >= 0 && cap_file_ && cap_file_->edt )
{
- if ( QChar(data[i]).toLatin1() != 0 )
- clipboard_text += QChar(data[i]);
- }
-
- if (!clipboard_text.isEmpty()) {
- qApp->clipboard()->setText(clipboard_text);
- }
-}
-
-void ByteViewTab::copyHexStream(QByteArray data)
-{
- if (!data.isEmpty()) {
- qApp->clipboard()->setText(data.toHex().toUpper());
- }
-}
-void ByteViewTab::copyBinary(QByteArray data)
-{
- if (!data.isEmpty()) {
- QMimeData *mime_data = new QMimeData;
- // gtk/gui_utils.c:copy_binary_to_clipboard says:
- /* XXX - this is not understood by most applications,
- * but can be pasted into the better hex editors - is
- * there something better that we can do?
- */
- // As of 2015-07-30, pasting into Frhed works on Windows. Pasting into
- // Hex Editor Neo and HxD does not.
- mime_data->setData("application/octet-stream", data);
- qApp->clipboard()->setMimeData(mime_data);
- }
-}
+ tvbuff_t * tvb = VariantPointer<tvbuff_t>::asPtr(sender()->property(tvb_data_property));
+ proto_tree * tree = cap_file_->edt->tree;
-void ByteViewTab::copyEscapedString(QByteArray data)
-{
- QString clipboard_text;
-
- // Beginning quote
- clipboard_text += QString("\"");
-
- for (int i = 0; i < data.count(); i++)
- {
- // Terminate this line if it has reached 16 bytes,
- // unless it is also the very last byte in the data,
- // as the termination after this for loop will take
- // care of that.
- if (i % 16 == 0 && i != 0 && i != data.count() - 1) {
- clipboard_text += QString("\" \\\n\"");
+ if ( tvb && tree )
+ {
+ field_info * fi = proto_find_field_from_offset(tree, idx, tvb);
+ if ( fi )
+ {
+ emit fieldSelected(new FieldInformation(fi, this));
+ return;
+ }
}
- clipboard_text += QString("\\x%1").arg(data[i], 2, 16, QChar('0'));
}
- // End quote
- clipboard_text += QString("\"\n");
- if (!clipboard_text.isEmpty()) {
- qApp->clipboard()->setText(clipboard_text);
- }
+ emit fieldSelected((FieldInformation *)0);
}
ByteViewText * ByteViewTab::findByteViewTextForTvb(tvbuff_t * search_tvb, int * idx)
{
- int cnt = 0;
- ByteViewText * item = 0;
+ ByteViewText * item = 0;
if ( ! search_tvb )
return item;
- item = qobject_cast<ByteViewText*>(widget(cnt));
+ bool found = false;
+
+ QList<ByteViewText *> allBVTs = findChildren<ByteViewText *>();
+ unsigned int length = search_tvb->length;
+ for (int i = 0; i < allBVTs.size() && ! found; ++i)
+ {
+ ByteViewText * bvt = allBVTs.at(i);
+ tvbuff_t * stored = VariantPointer<tvbuff_t>::asPtr(bvt->property(tvb_data_property));
+ if ( stored == search_tvb )
+ {
+ found = true;
+ }
+ else
+ {
+ if ( stored->length >= length && tvb_memeql(search_tvb, 0, stored->real_data, length ) == 0 )
+ {
+ /* In packetDialog we do not match, because we came from different data sources.
+ * Assuming the capture files match, this should be a sufficient enough difference */
+ found = true;
+ }
+ }
- while ( item ) {
- if ( ! item->property(tvb_data_property).isNull() )
+ if ( found )
{
- tvbuff_t * stored = VariantPointer<tvbuff_t>::asPtr(item->property(tvb_data_property));
- if ( stored && stored == search_tvb )
+ int wdgIdx = bvt->property("tab_index").toInt();
+ if ( idx )
{
- if ( idx )
- *idx = cnt;
- break;
+ *idx = wdgIdx;
}
+ item = (ByteViewText *)widget(wdgIdx);
}
- item = qobject_cast<ByteViewText*>(widget(++cnt));
}
return item;
}
-void ByteViewTab::copyData(ByteViewTab::copyDataType copy_type, field_info *fi)
-{
- ByteViewText *byte_view_text = 0;
-
- if ( fi )
- byte_view_text = findByteViewTextForTvb(fi->ds_tvb);
-
- if (!byte_view_text) return;
-
- QByteArray data = byte_view_text->viewData();
-
- if ( data.isEmpty() == 0 )
- return;
-
- if ( fi && fi->start >= 0 && fi->length > 0 && fi->length <= data.count() )
- data = data.right(fi->length);
-
- if ( data.isEmpty() ) return;
-
- switch (copy_type) {
- case copyDataHexTextDump:
- copyHexTextDump(data, true);
- break;
- case copyDataHexDump:
- copyHexTextDump(data, false);
- break;
- case copyDataPrintableText:
- copyPrintableText(data);
- break;
- case copyDataHexStream:
- copyHexStream(data);
- break;
- case copyDataBinary:
- copyBinary(data);
- break;
- case copyDataEscapedString:
- copyEscapedString(data);
- break;
- default:
- break;
- }
-}
-
void ByteViewTab::tabInserted(int index) {
setTabsVisible();
QTabWidget::tabInserted(index);
@@ -331,85 +218,47 @@ void ByteViewTab::setTabsVisible() {
tabBar()->hide();
}
-void ByteViewTab::protoTreeItemChanged(QTreeWidgetItem *current) {
- if (current && cap_file_) {
+void ByteViewTab::selectedFrameChanged(int frameNum)
+{
+ Q_UNUSED(frameNum);
+}
+
+void ByteViewTab::selectedFieldChanged(FieldInformation *selected) {
+
+ ByteViewText * byte_view_text = 0;
+
+ if (selected) {
field_info *fi;
- fi = VariantPointer<field_info>::asPtr(current->data(0, Qt::UserRole));
+ fi = selected->fieldInfo();
- ByteViewText *byte_view_text = 0;
int idx = 0;
-
if ( fi )
byte_view_text = findByteViewTextForTvb(fi->ds_tvb, &idx);
- if (byte_view_text) {
- QTreeWidgetItem *parent = current->parent();
- field_info *parent_fi = NULL;
- int f_start = -1, f_end = -1, f_len = -1;
- int fa_start = -1, fa_end = -1, fa_len = -1;
- int p_start = -1, p_end = -1, p_len = -1;
- guint len = tvb_captured_length(fi->ds_tvb);
-
- // Find and highlight the protocol bytes
- while (parent && parent->parent()) {
- parent = parent->parent();
- }
- if (parent) {
- parent_fi = VariantPointer<field_info>::asPtr(parent->data(0, Qt::UserRole));
- }
- if (parent_fi && parent_fi->ds_tvb == fi->ds_tvb) {
- p_start = parent_fi->start;
- p_len = parent_fi->length;
- }
+ if (byte_view_text)
+ {
+ int f_start = -1, f_end = -1;
if (cap_file_->search_in_progress && (cap_file_->hex || (cap_file_->string && cap_file_->packet_data))) {
// In the hex view, only highlight the target bytes or string. The entire
// field can then be displayed by clicking on any of the bytes in the field.
f_start = cap_file_->search_pos - cap_file_->search_len + 1;
- f_len = cap_file_->search_len;
+ f_end = f_start + cap_file_->search_len;
} else {
- f_start = fi->start;
- f_len = fi->length;
- }
-
- /* bmask = finfo->hfinfo->bitmask << hfinfo_bitshift(finfo->hfinfo); */ /* (value & mask) >> shift */
- fa_start = fi->appendix_start;
- fa_len = fi->appendix_length;
-
- if (p_start >= 0 && p_len > 0 && (guint)p_start < len) {
- p_end = p_start + p_len;
- }
- if (f_start >= 0 && f_len > 0 && (guint)f_start < len) {
- f_end = f_start + f_len;
- }
- if (fa_start >= 0 && fa_len > 0 && (guint)fa_start < len) {
- fa_end = fa_start + fa_len;
- }
-
- if (f_end == -1 && fa_end != -1) {
- f_start = fa_start;
- f_end = fa_end;
- fa_start = fa_end = -1;
+ f_start = selected->position().start;
+ f_end = selected->position().end;
}
- /* don't exceed the end of available data */
- if (p_end != -1 && (guint)p_end > len) p_end = len;
- if (f_end != -1 && (guint)f_end > len) f_end = len;
- if (fa_end != -1 && (guint)fa_end > len) fa_end = len;
-
- // Protocol
- byte_view_text->markProtocol(p_start, p_end);
+ setCurrentIndex(idx);
- // Field bytes
byte_view_text->markField(f_start, f_end);
-
- // Appendix (trailer) bytes
- byte_view_text->markAppendix(fa_start, fa_end);
-
- setCurrentIndex(idx);
+ byte_view_text->markProtocol(selected->parentField()->position().start, selected->parentField()->position().end);
+ byte_view_text->markAppendix(selected->appendix().start, selected->appendix().end);
}
}
+
+ curSelected = selected;
}
void ByteViewTab::setCaptureFile(capture_file *cf)
@@ -417,13 +266,6 @@ void ByteViewTab::setCaptureFile(capture_file *cf)
cap_file_ = cf;
}
-void ByteViewTab::setMonospaceFont(const QFont &mono_font)
-{
- mono_font_ = mono_font;
- emit monospaceFontChanged(mono_font_);
- update();
-}
-
/*
* Editor modelines
*
diff --git a/ui/qt/byte_view_tab.h b/ui/qt/byte_view_tab.h
index 202409ef2a..b1b8708211 100644
--- a/ui/qt/byte_view_tab.h
+++ b/ui/qt/byte_view_tab.h
@@ -28,69 +28,55 @@
#include <epan/proto.h>
#include <epan/tvbuff.h>
+#include <ui/qt/utils/field_information.h>
+
#include "cfile.h"
#include <QTabWidget>
-#include <QTreeWidget>
-#include <QTreeWidgetItem>
-#include <ui/qt/byte_view_text.h>
+
+#include <ui/qt/widgets/byte_view_text.h>
class ByteViewTab : public QTabWidget
{
Q_OBJECT
-public:
- enum copyDataType {
- copyDataHexTextDump,
- copyDataHexDump,
- copyDataPrintableText,
- copyDataHexStream,
- copyDataBinary,
- copyDataEscapedString
- };
+public:
explicit ByteViewTab(QWidget *parent = 0);
- void copyData(copyDataType copy_type, field_info *fi = NULL);
-
public slots:
/* Set the capture file */
void setCaptureFile(capture_file *cf);
/* Creates the tabs and data, depends on an dissection which has already run */
void packetSelectionChanged();
- void protoTreeItemChanged(QTreeWidgetItem *current);
- void setMonospaceFont(const QFont &mono_font);
+ void selectedFrameChanged(int);
+ void selectedFieldChanged(FieldInformation *);
signals:
- void monospaceFontChanged(const QFont &mono_font);
- void byteFieldHovered(const QString &);
-
- void tvbOffsetHovered(tvbuff_t *, int);
- void tvbOffsetMarked(tvbuff_t *, int);
+ void fieldSelected(FieldInformation *);
+ void fieldHighlight(FieldInformation *);
private:
capture_file *cap_file_;
- QFont mono_font_;
+
+ FieldInformation * curSelected;
void setTabsVisible();
- void copyHexTextDump(QByteArray data, bool append_text);
- void copyPrintableText(QByteArray data);
- void copyHexStream(QByteArray data);
- void copyBinary(QByteArray data);
- void copyEscapedString(QByteArray data);
ByteViewText * findByteViewTextForTvb(tvbuff_t * search, int * idx = 0);
void addTab(const char *name = "", tvbuff_t *tvb = NULL);
protected:
- void tabInserted(int index);
- void tabRemoved(int index);
+ void tabInserted(int);
+ void tabRemoved(int);
private slots:
void byteViewTextHovered(int);
void byteViewTextMarked(int);
+
+ void connectToMainWindow();
};
#endif // BYTE_VIEW_TAB_H
diff --git a/ui/qt/main_status_bar.cpp b/ui/qt/main_status_bar.cpp
index 7c1e29ba05..2e3bad3377 100644
--- a/ui/qt/main_status_bar.cpp
+++ b/ui/qt/main_status_bar.cpp
@@ -289,6 +289,40 @@ void MainStatusBar::setCaptureFile(capture_file *cf)
comment_button_->setEnabled(cap_file_ != NULL);
}
+void MainStatusBar::selectedFieldChanged(FieldInformation * finfo)
+{
+ QString item_info;
+
+ if ( ! finfo )
+ return;
+
+ FieldInformation::HeaderInfo hInfo = finfo->headerInfo();
+
+ if ( hInfo.isValid )
+ {
+ if ( hInfo.description.length() > 0 ) {
+ item_info.append(hInfo.description);
+ } else {
+ item_info.append(hInfo.name);
+ }
+ }
+
+ if (!item_info.isEmpty()) {
+ int finfo_length;
+ if ( hInfo.isValid )
+ item_info.append(" (" + hInfo.abbreviation + ")");
+
+ finfo_length = finfo->position().length + finfo->appendix().length;
+ if (finfo_length == 1) {
+ item_info.append(tr(", 1 byte"));
+ } else if (finfo_length > 1) {
+ item_info.append(QString(tr(", %1 bytes")).arg(finfo_length));
+ }
+ }
+
+ pushFieldStatus(item_info);
+}
+
void MainStatusBar::pushTemporaryStatus(const QString &message) {
info_status_.pushText(message, STATUS_CTX_TEMPORARY);
}
@@ -320,6 +354,28 @@ void MainStatusBar::popFieldStatus() {
info_status_.popText(STATUS_CTX_FIELD);
}
+void MainStatusBar::highlightedFieldChanged(FieldInformation * finfo)
+{
+ QString hint;
+
+ if ( finfo )
+ {
+ FieldInformation::Position pos = finfo->position();
+ QString field_str;
+
+ if (pos.length < 2) {
+ hint = QString(tr("Byte %1")).arg(pos.start);
+ } else {
+ hint = QString(tr("Bytes %1-%2")).arg(pos.start).arg(pos.start + pos.length - 1);
+ }
+ hint += QString(": %1 (%2)")
+ .arg(finfo->headerInfo().name)
+ .arg(finfo->headerInfo().abbreviation);
+ }
+
+ pushByteStatus(hint);
+}
+
void MainStatusBar::pushByteStatus(const QString &message)
{
if (message.isEmpty()) {
diff --git a/ui/qt/main_status_bar.h b/ui/qt/main_status_bar.h
index 5f454f88a9..00d98db3e4 100644
--- a/ui/qt/main_status_bar.h
+++ b/ui/qt/main_status_bar.h
@@ -28,6 +28,7 @@
#include "capchild/capture_session.h"
+#include <ui/qt/utils/field_information.h>
#include <ui/qt/widgets/label_stack.h>
#include "progress_frame.h"
#include "wireshark_application.h"
@@ -79,6 +80,8 @@ signals:
public slots:
void setCaptureFile(capture_file *cf);
+ void selectedFieldChanged(FieldInformation *);
+ void highlightedFieldChanged(FieldInformation *);
void pushTemporaryStatus(const QString &message);
void popTemporaryStatus();
void pushFileStatus(const QString &message, const QString &messagetip = QString());
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index 9e06490ed9..3ed70e3f35 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -495,27 +495,33 @@ MainWindow::MainWindow(QWidget *parent) :
packet_list_ = new PacketList(&master_split_);
main_ui_->wirelessTimelineWidget->setPacketList(packet_list_);
+ connect(packet_list_, SIGNAL(fieldSelected(FieldInformation *)),
+ this, SIGNAL(fieldSelected(FieldInformation *)));
connect(packet_list_, SIGNAL(packetSelectionChanged()),
- main_ui_->wirelessTimelineWidget, SLOT(packetSelectionChanged()));
+ this, SIGNAL(packetSelectionChanged()));
connect(packet_list_->packetListModel(), SIGNAL(bgColorizationProgress(int,int)),
main_ui_->wirelessTimelineWidget, SLOT(bgColorizationProgress(int,int)));
- connect(packet_list_, SIGNAL(packetSelectionChanged()),
- main_ui_->statusBar, SLOT(packetSelectionChanged()));
proto_tree_ = new ProtoTree(&master_split_);
proto_tree_->installEventFilter(this);
- byte_view_tab_ = new ByteViewTab(&master_split_);
-
packet_list_->setProtoTree(proto_tree_);
- packet_list_->setByteViewTab(byte_view_tab_);
packet_list_->installEventFilter(this);
- connect(packet_list_, SIGNAL(packetSelectionChanged()),
- byte_view_tab_, SLOT(packetSelectionChanged()));
-
main_welcome_ = main_ui_->welcomePage;
+ connect(proto_tree_, SIGNAL(fieldSelected(FieldInformation *)),
+ this, SIGNAL(fieldSelected(FieldInformation *)));
+ connect(this, SIGNAL(fieldSelected(FieldInformation *)),
+ proto_tree_, SLOT(selectedFieldChanged(FieldInformation *)));
+ connect(this, SIGNAL(fieldHighlight(FieldInformation *)),
+ main_ui_->statusBar, SLOT(highlightedFieldChanged(FieldInformation *)));
+ connect(this, SIGNAL(fieldSelected(FieldInformation *)),
+ main_ui_->statusBar, SLOT(selectedFieldChanged(FieldInformation *)));
+
+
+ createByteViewDialog();
+
// Packet list and proto tree must exist before these are called.
setMenusForSelectedPacket();
setMenusForSelectedTreeRow();
@@ -648,6 +654,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(main_ui_->filterExpressionFrame, SIGNAL(filterExpressionsChanged()),
this, SLOT(filterExpressionsChanged()));
+ /* Connect change of capture file */
connect(this, SIGNAL(setCaptureFile(capture_file*)),
main_ui_->searchFrame, SLOT(setCaptureFile(capture_file*)));
connect(this, SIGNAL(setCaptureFile(capture_file*)),
@@ -656,15 +663,15 @@ MainWindow::MainWindow(QWidget *parent) :
packet_list_, SLOT(setCaptureFile(capture_file*)));
connect(this, SIGNAL(setCaptureFile(capture_file*)),
proto_tree_, SLOT(setCaptureFile(capture_file*)));
- connect(this, SIGNAL(setCaptureFile(capture_file*)),
- byte_view_tab_, SLOT(setCaptureFile(capture_file*)));
+ connect(this, SIGNAL(packetSelectionChanged()),
+ main_ui_->wirelessTimelineWidget, SLOT(packetSelectionChanged()));
+ connect(this, SIGNAL(packetSelectionChanged()),
+ main_ui_->statusBar, SLOT(packetSelectionChanged()));
- connect(this, SIGNAL(monospaceFontChanged(QFont)),
+ connect(wsApp, SIGNAL(zoomMonospaceFont(QFont)),
packet_list_, SLOT(setMonospaceFont(QFont)));
- connect(this, SIGNAL(monospaceFontChanged(QFont)),
+ connect(wsApp, SIGNAL(zoomMonospaceFont(QFont)),
proto_tree_, SLOT(setMonospaceFont(QFont)));
- connect(this, SIGNAL(monospaceFontChanged(QFont)),
- byte_view_tab_, SLOT(setMonospaceFont(QFont)));
connect(main_ui_->actionGoNextPacket, SIGNAL(triggered()),
packet_list_, SLOT(goNextPacket()));
@@ -714,10 +721,12 @@ MainWindow::MainWindow(QWidget *parent) :
connect(packet_list_->packetListModel(), SIGNAL(popProgressStatus()),
main_ui_->statusBar, SLOT(popProgressStatus()));
- connect(proto_tree_, SIGNAL(protoItemSelected(const QString&)),
- main_ui_->statusBar, SLOT(pushFieldStatus(const QString&)));
- connect(proto_tree_, SIGNAL(protoItemSelected(field_info *)),
- this, SLOT(setMenusForSelectedTreeRow(field_info *)));
+ connect(proto_tree_, SIGNAL(fieldSelected(FieldInformation *)),
+ this, SIGNAL(fieldSelected(FieldInformation *)));
+ connect(this, SIGNAL(fieldSelected(FieldInformation *)),
+ main_ui_->statusBar, SLOT(selectedFieldChanged(FieldInformation *)));
+ connect(this, SIGNAL(fieldSelected(FieldInformation *)),
+ this, SLOT(setMenusForSelectedTreeRow(FieldInformation *)));
connect(proto_tree_, SIGNAL(openPacketInNewWindow(bool)),
this, SLOT(openPacketDialog(bool)));
connect(proto_tree_, SIGNAL(showProtocolPreferences(QString)),
@@ -725,9 +734,6 @@ MainWindow::MainWindow(QWidget *parent) :
connect(proto_tree_, SIGNAL(editProtocolPreference(preference*,pref_module*)),
main_ui_->preferenceEditorFrame, SLOT(editPreference(preference*,pref_module*)));
- connect(byte_view_tab_, SIGNAL(tvbOffsetHovered(tvbuff_t *, int)),
- this, SLOT(setTvbOffsetHovered(tvbuff_t *, int)));
-
connect(main_ui_->statusBar, SIGNAL(showExpertInfo()),
this, SLOT(on_actionAnalyzeExpertInfo_triggered()));
@@ -2880,6 +2886,10 @@ void MainWindow::setMwFileName(QString fileName)
return;
}
+void MainWindow::createByteViewDialog()
+{
+ byte_view_tab_ = new ByteViewTab(&master_split_);
+}
/*
* Editor modelines
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 1f92b00a13..efae934015 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -54,6 +54,7 @@
#include "capture_file.h"
#include "capture_file_dialog.h"
#include "capture_file_properties_dialog.h"
+#include <ui/qt/utils/field_information.h>
#include <ui/qt/widgets/display_filter_combo.h>
#include "filter_action.h"
#include "follow_stream_dialog.h"
@@ -157,13 +158,13 @@ private:
CaptureFile capture_file_;
QFont mono_font_;
WirelessFrame *wireless_frame_;
- // XXX - packet_list_, proto_tree_, and byte_view_tab_ should
+ // XXX - packet_list_ and proto_tree_ should
// probably be full-on values instead of pointers.
PacketList *packet_list_;
ProtoTree *proto_tree_;
+ ByteViewTab * byte_view_tab_;
QWidget *previous_focus_;
FileSetDialog *file_set_dialog_;
- ByteViewTab *byte_view_tab_;
QWidget empty_pane_;
QActionGroup *show_hide_actions_;
QActionGroup *time_display_actions_;
@@ -255,17 +256,23 @@ private:
void goToConversationFrame(bool go_next);
void colorizeWithFilter(QByteArray filter, int color_number = -1);
+ void createByteViewDialog();
+
signals:
void setCaptureFile(capture_file *cf);
void setDissectedCaptureFile(capture_file *cf);
void displayFilterSuccess(bool success);
- void monospaceFontChanged(const QFont &mono_font);
void closePacketDialogs();
void reloadFields();
void packetInfoChanged(struct _packet_info *pinfo);
void fieldFilterChanged(const QByteArray field_filter);
void filterAction(QString filter, FilterAction::Action action, FilterAction::ActionType type);
+ void fieldSelected(FieldInformation *);
+ void fieldHighlight(FieldInformation *);
+
+ void packetSelectionChanged();
+
public slots:
// in main_window_slots.cpp
/**
@@ -344,7 +351,7 @@ private slots:
void updateRecentCaptures();
void recentActionTriggered();
void setMenusForSelectedPacket();
- void setMenusForSelectedTreeRow(field_info *fi = NULL);
+ void setMenusForSelectedTreeRow(FieldInformation *fi = NULL);
void interfaceSelectionChanged();
void captureFilterSyntaxChanged(bool valid);
void redissectPackets();
@@ -396,8 +403,6 @@ private slots:
void openTapParameterDialog(const QString cfg_str, const QString arg, void *userdata);
void openTapParameterDialog();
- void setTvbOffsetHovered(tvbuff_t * tvb, int idx);
-
#ifdef HAVE_SOFTWARE_UPDATE
void softwareUpdateRequested();
#endif
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index ee25e61e58..77a60b4582 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -1383,7 +1383,7 @@ void MainWindow::setMenusForSelectedPacket()
main_ui_->actionTelephonyLteRlcGraph->setEnabled(is_lte_rlc);
}
-void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
+void MainWindow::setMenusForSelectedTreeRow(FieldInformation *finfo) {
bool can_match_selected = false;
bool is_framenum = false;
@@ -1394,6 +1394,10 @@ void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
QByteArray field_filter;
int field_id = -1;
+ field_info * fi = 0;
+ if ( finfo )
+ fi = finfo->fieldInfo();
+
if (capture_file_.capFile()) {
capture_file_.capFile()->finfo_selected = fi;
@@ -1782,35 +1786,6 @@ void MainWindow::openTapParameterDialog()
openTapParameterDialog(cfg_str, NULL, NULL);
}
-void MainWindow::setTvbOffsetHovered(tvbuff_t * tvb, int idx)
-{
- QString field_str("");
-
- if ( tvb && capture_file_.capFile() && capture_file_.capFile()->edt )
- {
- proto_tree * tree = capture_file_.capFile()->edt->tree;
- if ( tree )
- {
- field_info * fi = proto_find_field_from_offset(tree, idx, tvb);
-
- if (fi) {
- if (fi->length < 2) {
- field_str = QString(tr("Byte %1"))
- .arg(fi->start);
- } else {
- field_str = QString(tr("Bytes %1-%2"))
- .arg(fi->start)
- .arg(fi->start + fi->length - 1);
- }
- field_str += QString(": %1 (%2)")
- .arg(fi->hfinfo->name)
- .arg(fi->hfinfo->abbrev);
- }
- }
- }
- main_ui_->statusBar->pushByteStatus(field_str);
-}
-
#ifdef HAVE_SOFTWARE_UPDATE
void MainWindow::softwareUpdateRequested() {
// We could call testCaptureFileClose here, but that would give us yet
@@ -2482,14 +2457,7 @@ void MainWindow::on_actionViewNameResolutionTransport_triggered()
void MainWindow::zoomText()
{
- // Scale by 10%, rounding to nearest half point, minimum 1 point.
- // XXX Small sizes repeat. It might just be easier to create a map of multipliers.
- mono_font_ = QFont(wsApp->monospaceFont());
- qreal zoom_size = wsApp->monospaceFont().pointSize() * 2 * qPow(qreal(1.1), recent.gui_zoom_level);
- zoom_size = qRound(zoom_size) / qreal(2.0);
- zoom_size = qMax(zoom_size, qreal(1.0));
- mono_font_.setPointSizeF(zoom_size);
- emit monospaceFontChanged(mono_font_);
+ wsApp->zoomTextFont(recent.gui_zoom_level);
}
void MainWindow::on_actionViewZoomIn_triggered()
@@ -2655,11 +2623,9 @@ void MainWindow::openPacketDialog(bool from_reference)
if (fdata) {
PacketDialog *packet_dialog = new PacketDialog(*this, capture_file_, fdata);
- connect(this, SIGNAL(monospaceFontChanged(QFont)),
- packet_dialog, SIGNAL(monospaceFontChanged(QFont)));
connect(this, SIGNAL(closePacketDialogs()),
packet_dialog, SLOT(close()));
- zoomText(); // Emits monospaceFontChanged
+ zoomText(); // Emits wsApp->zoomMonospaceFont(QFont)
packet_dialog->show();
}
@@ -3899,9 +3865,13 @@ void MainWindow::on_actionContextCopyBytesHexTextDump_triggered()
QAction *ca = qobject_cast<QAction*>(sender());
if (!ca) return;
- field_info *fi = VariantPointer<field_info>::asPtr(ca->data());
+ IDataPrintable * fieldInfo =
+ VariantPointer<IDataPrintable>::asPtr(ca->property("idataprintable_"));
+ if ( ! fieldInfo )
+ return;
- byte_view_tab_->copyData(ByteViewTab::copyDataHexTextDump, fi);
+ DataPrinter printer;
+ printer.toClipboard(DataPrinter::DP_HexDump, fieldInfo);
}
void MainWindow::on_actionContextCopyBytesHexDump_triggered()
@@ -3909,9 +3879,13 @@ void MainWindow::on_actionContextCopyBytesHexDump_triggered()
QAction *ca = qobject_cast<QAction*>(sender());
if (!ca) return;
- field_info *fi = VariantPointer<field_info>::asPtr(ca->data());
+ IDataPrintable * fieldInfo =
+ VariantPointer<IDataPrintable>::asPtr(ca->property("idataprintable_"));
+ if ( ! fieldInfo )
+ return;
- byte_view_tab_->copyData(ByteViewTab::copyDataHexDump, fi);
+ DataPrinter printer;
+ printer.toClipboard(DataPrinter::DP_HexOnly, fieldInfo);
}
void MainWindow::on_actionContextCopyBytesPrintableText_triggered()
@@ -3919,9 +3893,13 @@ void MainWindow::on_actionContextCopyBytesPrintableText_triggered()
QAction *ca = qobject_cast<QAction*>(sender());
if (!ca) return;
- field_info *fi = VariantPointer<field_info>::asPtr(ca->data());
+ IDataPrintable * fieldInfo =
+ VariantPointer<IDataPrintable>::asPtr(ca->property("idataprintable_"));
+ if ( ! fieldInfo )
+ return;
- byte_view_tab_->copyData(ByteViewTab::copyDataPrintableText, fi);
+ DataPrinter printer;
+ printer.toClipboard(DataPrinter::DP_PrintableText, fieldInfo);
}
void MainWindow::on_actionContextCopyBytesHexStream_triggered()
@@ -3929,9 +3907,13 @@ void MainWindow::on_actionContextCopyBytesHexStream_triggered()
QAction *ca = qobject_cast<QAction*>(sender());
if (!ca) return;
- field_info *fi = VariantPointer<field_info>::asPtr(ca->data());
+ IDataPrintable * fieldInfo =
+ VariantPointer<IDataPrintable>::asPtr(ca->property("idataprintable_"));
+ if ( ! fieldInfo )
+ return;
- byte_view_tab_->copyData(ByteViewTab::copyDataHexStream, fi);
+ DataPrinter printer;
+ printer.toClipboard(DataPrinter::DP_HexStream, fieldInfo);
}
void MainWindow::on_actionContextCopyBytesBinary_triggered()
@@ -3939,9 +3921,13 @@ void MainWindow::on_actionContextCopyBytesBinary_triggered()
QAction *ca = qobject_cast<QAction*>(sender());
if (!ca) return;
- field_info *fi = VariantPointer<field_info>::asPtr(ca->data());
+ IDataPrintable * fieldInfo =
+ VariantPointer<IDataPrintable>::asPtr(ca->property("idataprintable_"));
+ if ( ! fieldInfo )
+ return;
- byte_view_tab_->copyData(ByteViewTab::copyDataBinary, fi);
+ DataPrinter printer;
+ printer.toClipboard(DataPrinter::DP_Binary, fieldInfo);
}
void MainWindow::on_actionContextCopyBytesEscapedString_triggered()
@@ -3949,9 +3935,13 @@ void MainWindow::on_actionContextCopyBytesEscapedString_triggered()
QAction *ca = qobject_cast<QAction*>(sender());
if (!ca) return;
- field_info *fi = VariantPointer<field_info>::asPtr(ca->data());
+ IDataPrintable * fieldInfo =
+ VariantPointer<IDataPrintable>::asPtr(ca->property("idataprintable_"));
+ if ( ! fieldInfo )
+ return;
- byte_view_tab_->copyData(ByteViewTab::copyDataEscapedString, fi);
+ DataPrinter printer;
+ printer.toClipboard(DataPrinter::DP_EscapedString, fieldInfo);
}
void MainWindow::on_actionContextWikiProtocolPage_triggered()
diff --git a/ui/qt/packet_dialog.cpp b/ui/qt/packet_dialog.cpp
index 7849a3d5f9..afd5224228 100644
--- a/ui/qt/packet_dialog.cpp
+++ b/ui/qt/packet_dialog.cpp
@@ -35,6 +35,7 @@
#include "proto_tree.h"
#include "wireshark_application.h"
+#include <ui/qt/utils/field_information.h>
#include <QTreeWidgetItemIterator>
// To do:
@@ -86,17 +87,17 @@ PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata)
ui->hintLabel->setText(col_info_);
- connect(this, SIGNAL(monospaceFontChanged(QFont)),
+ connect(wsApp, SIGNAL(zoomMonospaceFont(QFont)),
proto_tree_, SLOT(setMonospaceFont(QFont)));
- connect(this, SIGNAL(monospaceFontChanged(QFont)),
- byte_view_tab_, SLOT(setMonospaceFont(QFont)));
-
- connect(proto_tree_, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
- byte_view_tab_, SLOT(protoTreeItemChanged(QTreeWidgetItem*)));
- connect(byte_view_tab_, SIGNAL(byteFieldHovered(const QString&)),
- this, SLOT(setHintText(const QString&)));
- connect(byte_view_tab_, SIGNAL(tvbOffsetHovered(tvbuff_t *, int)),
- this, SLOT(setTvbOffsetHovered(tvbuff_t *, int)));
+
+ connect(byte_view_tab_, SIGNAL(fieldSelected(FieldInformation *)),
+ proto_tree_, SLOT(selectedFieldChanged(FieldInformation *)));
+ connect(proto_tree_, SIGNAL(fieldSelected(FieldInformation *)),
+ byte_view_tab_, SLOT(selectedFieldChanged(FieldInformation *)));
+
+ connect(byte_view_tab_, SIGNAL(fieldHighlight(FieldInformation *)),
+ this, SLOT(setHintText(FieldInformation *)));
+
}
PacketDialog::~PacketDialog()
@@ -115,39 +116,30 @@ void PacketDialog::captureFileClosing()
WiresharkDialog::captureFileClosing();
}
-void PacketDialog::setTvbOffsetHovered(tvbuff_t * tvb, int idx)
+void PacketDialog::on_buttonBox_helpRequested()
{
- QString field_str("");
-
- if ( tvb && cap_file_.capFile() && cap_file_.capFile()->edt )
- {
- proto_tree * tree = cap_file_.capFile()->edt->tree;
- if ( tree )
- {
- field_info * fi = proto_find_field_from_offset(tree, idx, tvb);
-
- if (fi) {
- if (fi->length < 2) {
- field_str = QString(tr("Byte %1"))
- .arg(fi->start);
- } else {
- field_str = QString(tr("Bytes %1-%2"))
- .arg(fi->start)
- .arg(fi->start + fi->length - 1);
- }
- field_str += QString(": %1 (%2)")
- .arg(fi->hfinfo->name)
- .arg(fi->hfinfo->abbrev);
- }
- }
- }
-
- ui->hintLabel->setText(field_str);
+ wsApp->helpTopicAction(HELP_NEW_PACKET_DIALOG);
}
-void PacketDialog::on_buttonBox_helpRequested()
+void PacketDialog::setHintText(FieldInformation * finfo)
{
- wsApp->helpTopicAction(HELP_NEW_PACKET_DIALOG);
+ QString hint;
+
+ if ( finfo )
+ {
+ FieldInformation::Position pos = finfo->position();
+ QString field_str;
+
+ if (pos.length < 2) {
+ hint = QString(tr("Byte %1")).arg(pos.start);
+ } else {
+ hint = QString(tr("Bytes %1-%2")).arg(pos.start).arg(pos.start + pos.length - 1);
+ }
+ hint += QString(": %1 (%2)")
+ .arg(finfo->headerInfo().name)
+ .arg(finfo->headerInfo().abbreviation);
+ }
+ ui->hintLabel->setText(hint);
}
/*
diff --git a/ui/qt/packet_dialog.h b/ui/qt/packet_dialog.h
index 429519c85b..f5b5f76b96 100644
--- a/ui/qt/packet_dialog.h
+++ b/ui/qt/packet_dialog.h
@@ -27,6 +27,8 @@
#include "epan/epan_dissect.h"
#include "wiretap/wtap.h"
+#include <ui/qt/utils/field_information.h>
+
class ByteViewTab;
class ProtoTree;
@@ -42,14 +44,12 @@ public:
explicit PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata);
~PacketDialog();
-signals:
- void monospaceFontChanged(QFont);
-
private slots:
- void captureFileClosing();
- void setTvbOffsetHovered(tvbuff_t * tvb, int idx);
void on_buttonBox_helpRequested();
+ void captureFileClosing();
+ void setHintText(FieldInformation *);
+
private:
Ui::PacketDialog *ui;
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index 2e904a0fdb..2c6a26d780 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -19,7 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "packet_list.h"
+#include <ui/qt/packet_list.h>
#include "config.h"
@@ -56,6 +56,9 @@
#include "proto_tree.h"
#include <ui/qt/utils/qt_ui_utils.h>
#include "wireshark_application.h"
+#include <ui/qt/utils/data_printer.h>
+#include <ui/qt/utils/frame_information.h>
+#include <ui/qt/utils/variant_pointer.h>
#include <QAction>
#include <QActionGroup>
@@ -235,7 +238,6 @@ enum copy_summary_type {
PacketList::PacketList(QWidget *parent) :
QTreeView(parent),
proto_tree_(NULL),
- byte_view_tab_(NULL),
cap_file_(NULL),
decode_as_(NULL),
ctx_column_(-1),
@@ -473,13 +475,6 @@ void PacketList::setProtoTree (ProtoTree *proto_tree) {
&related_packet_delegate_, SLOT(addRelatedFrame(int,ft_framenum_type_t)));
}
-void PacketList::setByteViewTab (ByteViewTab *byte_view_tab) {
- byte_view_tab_ = byte_view_tab;
-
- connect(proto_tree_, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
- byte_view_tab_, SLOT(protoTreeItemChanged(QTreeWidgetItem*)));
-}
-
PacketListModel *PacketList::packetListModel() const {
return packet_list_model_;
}
@@ -543,7 +538,7 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
}
if (fi && proto_tree_) {
- proto_tree_->selectField(fi);
+ emit fieldSelected(new FieldInformation(fi, this));
}
} else if (!cap_file_->search_in_progress && proto_tree_) {
proto_tree_->restoreSelectedField();
@@ -575,7 +570,17 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
}
proto_prefs_menu_.setModule(module_name);
+ QModelIndex ctxIndex = indexAt(event->pos());
+ FrameInformation * frameData =
+ new FrameInformation(new CaptureFile(this, cap_file_), packet_list_model_->getRowFdata(ctxIndex.row()));
+
foreach (QAction *action, copy_actions_) {
+ if ( frameData->isValid() )
+ {
+ action->setProperty("idataprintable_",
+ VariantPointer<IDataPrintable>::asQVariant((IDataPrintable*)frameData));
+ }
+
action->setData(QVariant());
}
diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h
index 2aa92d99c5..5b69f9ec8e 100644
--- a/ui/qt/packet_list.h
+++ b/ui/qt/packet_list.h
@@ -28,6 +28,7 @@
#include "proto_tree.h"
#include "protocol_preferences_menu.h"
#include <ui/qt/models/related_packet_delegate.h>
+#include <ui/qt/utils/field_information.h>
#include <QMenu>
#include <QTime>
@@ -60,7 +61,7 @@ public:
QMenu *conversationMenu() { return &conv_menu_; }
QMenu *colorizeMenu() { return &colorize_menu_; }
void setProtoTree(ProtoTree *proto_tree);
- void setByteViewTab(ByteViewTab *byteViewTab);
+
/** Disable and clear the packet list.
*
* Disable packet list widget updates, clear the detail and byte views,
@@ -105,7 +106,6 @@ protected slots:
private:
PacketListModel *packet_list_model_;
ProtoTree *proto_tree_;
- ByteViewTab *byte_view_tab_;
capture_file *cap_file_;
QMenu ctx_menu_;
QMenu conv_menu_;
@@ -157,6 +157,9 @@ signals:
void showProtocolPreferences(const QString module_name);
void editProtocolPreference(struct preference *pref, struct pref_module *module);
+ void selectedFrameChanged(int);
+ void fieldSelected(FieldInformation *);
+
public slots:
void setCaptureFile(capture_file *cf);
void setMonospaceFont(const QFont &mono_font);
diff --git a/ui/qt/proto_tree.cpp b/ui/qt/proto_tree.cpp
index 5afe0e33d3..06938e3e0a 100644
--- a/ui/qt/proto_tree.cpp
+++ b/ui/qt/proto_tree.cpp
@@ -317,6 +317,7 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
conv_menu_.addAction(action);
}
+ FieldInformation * finfo = 0;
field_info *fi = NULL;
const char *module_name = NULL;
if (selectedItems().count() > 0) {
@@ -328,17 +329,19 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
module_name = proto_registrar_get_abbrev(fi->hfinfo->parent);
}
}
+ finfo = new FieldInformation(fi, this);
}
proto_prefs_menu_.setModule(module_name);
foreach (QAction *action, copy_actions_) {
- action->setData(VariantPointer<field_info>::asQVariant(fi));
+ action->setProperty("idataprintable_",
+ VariantPointer<IDataPrintable>::asQVariant((IDataPrintable *)finfo));
}
decode_as_->setData(qVariantFromValue(true));
// Set menu sensitivity and action data.
- emit protoItemSelected(fi);
+ emit fieldSelected(finfo);
ctx_menu_.exec(event->globalPos());
decode_as_->setData(QVariant());
}
@@ -429,29 +432,21 @@ void ProtoTree::updateSelectionStatus(QTreeWidgetItem* item)
fi = VariantPointer<field_info>::asPtr(item->data(0, Qt::UserRole));
if (!fi || !fi->hfinfo) return;
- if (fi->hfinfo->blurb != NULL && fi->hfinfo->blurb[0] != '\0') {
- item_info.append(QString().fromUtf8(fi->hfinfo->blurb));
- } else {
- item_info.append(QString().fromUtf8(fi->hfinfo->name));
- }
-
- if (!item_info.isEmpty()) {
- int finfo_length;
- item_info.append(" (" + QString().fromUtf8(fi->hfinfo->abbrev) + ")");
+ FieldInformation * finfo = new FieldInformation(fi, this);
- finfo_length = fi->length + fi->appendix_length;
- if (finfo_length == 1) {
- item_info.append(tr(", 1 byte"));
- } else if (finfo_length > 1) {
- item_info.append(QString(tr(", %1 bytes")).arg(finfo_length));
- }
+ // Find and highlight the protocol bytes
+ QTreeWidgetItem * parent = item->parent();
+ while (parent && parent->parent()) {
+ parent = parent->parent();
+ }
+ if (parent) {
+ finfo->setParentField(VariantPointer<field_info>::asPtr(parent->data(0, Qt::UserRole)));
+ }
+ if ( finfo->isValid() )
+ {
saveSelectedField(item);
-
- emit protoItemSelected("");
- emit protoItemSelected(NULL);
- emit protoItemSelected(item_info);
- emit protoItemSelected(fi);
+ emit fieldSelected(finfo);
} // else the GTK+ version pushes an empty string as described below.
/*
* Don't show anything if the field name is zero-length;
@@ -473,8 +468,7 @@ void ProtoTree::updateSelectionStatus(QTreeWidgetItem* item)
*/
} else {
- emit protoItemSelected("");
- emit protoItemSelected(NULL);
+ emit fieldSelected(NULL);
}
}
@@ -598,16 +592,21 @@ void ProtoTree::itemDoubleClick(QTreeWidgetItem *item, int) {
}
}
-void ProtoTree::selectField(field_info *fi)
+void ProtoTree::selectedFieldChanged(FieldInformation * finfo)
{
- QTreeWidgetItemIterator iter(this);
- while (*iter) {
- if (fi == VariantPointer<field_info>::asPtr((*iter)->data(0, Qt::UserRole))) {
- setCurrentItem(*iter);
- scrollToItem(*iter);
- break;
+ if ( finfo )
+ {
+ field_info * fi = finfo->fieldInfo();
+
+ QTreeWidgetItemIterator iter(this);
+ while (*iter) {
+ if (fi == VariantPointer<field_info>::asPtr((*iter)->data(0, Qt::UserRole))) {
+ setCurrentItem(*iter);
+ scrollToItem(*iter);
+ break;
+ }
+ ++iter;
}
- ++iter;
}
}
diff --git a/ui/qt/proto_tree.h b/ui/qt/proto_tree.h
index cf9c85369a..248d38f28f 100644
--- a/ui/qt/proto_tree.h
+++ b/ui/qt/proto_tree.h
@@ -30,6 +30,7 @@
#include "protocol_preferences_menu.h"
+#include <ui/qt/utils/field_information.h>
#include <QTreeWidget>
#include <QMenu>
@@ -42,7 +43,6 @@ public:
void fillProtocolTree(proto_tree *protocol_tree);
void emitRelatedFrame(int related_frame, ft_framenum_type_t framenum_type = FT_FRAMENUM_NONE);
void goToField(int hf_id);
- void selectField(field_info *fi);
void closeContextMenu();
void clear();
void saveSelectedField(QTreeWidgetItem *);
@@ -71,8 +71,8 @@ private:
capture_file *cap_file_;
signals:
- void protoItemSelected(const QString &);
- void protoItemSelected(field_info *);
+ void fieldSelected(FieldInformation *);
+
void openPacketInNewWindow(bool);
void goToPacket(int);
void relatedFrame(int, ft_framenum_type_t);
@@ -92,6 +92,8 @@ public slots:
void collapseAll();
void itemDoubleClick(QTreeWidgetItem *item, int column);
+ void selectedFieldChanged(FieldInformation *);
+
private slots:
void updateContentWidth();
};
diff --git a/ui/qt/utils/data_printer.cpp b/ui/qt/utils/data_printer.cpp
new file mode 100644
index 0000000000..fbb8a3c797
--- /dev/null
+++ b/ui/qt/utils/data_printer.cpp
@@ -0,0 +1,182 @@
+/* data_printer.cpp
+ *
+ * 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 <ui/qt/utils/data_printer.h>
+
+#include <stdint.h>
+
+#include <QApplication>
+#include <QClipboard>
+#include <QString>
+#include <QMimeData>
+
+DataPrinter::DataPrinter(QObject * parent)
+: QObject(parent),
+ byteLineLength_(16)
+{}
+
+void DataPrinter::toClipboard(DataPrinter::DumpType type, IDataPrintable * printable)
+{
+ QByteArray printData = printable->printableData();
+
+ QString clipboard_text;
+
+ switch(type)
+ {
+ case DP_PrintableText:
+ for (int i = 0; i < printData.length(); i++) {
+ if (QChar::isSpace(printData[i]) || QChar::isLetter(printData[i])) {
+ clipboard_text += QChar(printData[i]);
+ }
+ }
+ break;
+ case DP_HexStream:
+ for (int i = 0; i < printData.length(); i++)
+ clipboard_text += QString("%1").arg(printData[i], 2, 16, QChar('0'));
+ break;
+ case DP_EscapedString:
+ // Beginning quote
+ clipboard_text += QString("\"");
+
+ for (int i = 0; i < printData.length(); i++) {
+ // Terminate this line if it has reached 16 bytes,
+ // unless it is also the very last byte in the data,
+ // as the termination after this for loop will take
+ // care of that.
+ if (i % 16 == 0 && i != 0 && i != printData.length() - 1) {
+ clipboard_text += QString("\" \\\n\"");
+ }
+ clipboard_text += QString("\\x%1").arg(printData[i], 2, 16, QChar('0'));
+ }
+ // End quote
+ clipboard_text += QString("\"\n");
+ break;
+ case DP_Binary:
+ binaryDump(printData);
+ break;
+ case DP_HexDump:
+ clipboard_text = hexTextDump(printData, true);
+ break;
+ case DP_HexOnly:
+ clipboard_text = hexTextDump(printData, false);
+ break;
+ default:
+ break;
+ }
+
+ if (!clipboard_text.isEmpty()) {
+ qApp->clipboard()->setText(clipboard_text);
+ }
+}
+
+void DataPrinter::binaryDump(QByteArray printData)
+{
+ if (!printData.isEmpty()) {
+ QMimeData *mime_data = new QMimeData;
+ // gtk/gui_utils.c:copy_binary_to_clipboard says:
+ /* XXX - this is not understood by most applications,
+ * but can be pasted into the better hex editors - is
+ * there something better that we can do?
+ */
+ // As of 2015-07-30, pasting into Frhed works on Windows. Pasting into
+ // Hex Editor Neo and HxD does not.
+ mime_data->setData("application/octet-stream", printData);
+ qApp->clipboard()->setMimeData(mime_data);
+ }
+}
+
+void DataPrinter::setByteLineLength(int bll)
+{
+ byteLineLength_ = bll;
+}
+
+int DataPrinter::byteLineLength() const
+{
+ return byteLineLength_;
+}
+
+QString DataPrinter::hexTextDump(QByteArray printData, bool showText)
+{
+ QString clipboard_text;
+
+ QString byteStr;
+ QString dataStr;
+
+ int cnt = 0;
+ while ( cnt < printData.length() )
+ {
+ byteStr += QString(" %1").arg((uint8_t) printData[cnt], 2, 16, QChar('0'));
+ if ( showText )
+ {
+ char ch = '.';
+ if ( QChar::isPrint(printData[cnt]) )
+ ch = (char) printData[cnt];
+ dataStr += QChar( ch );
+ }
+ cnt++;
+ }
+
+ int lines = printData.length() / byteLineLength_;
+ if ( printData.length() % byteLineLength_ > 0 )
+ lines++;
+
+ for ( cnt = 0; cnt < lines; cnt++ )
+ {
+ int offset = cnt * 0x10;
+
+ clipboard_text += QString("%1 ").arg(offset, 4, 16, QChar('0'));
+ clipboard_text += byteStr.mid(offset * 3, byteLineLength_ * 3);
+
+ if ( showText )
+ {
+ /* separation bytes for byte and text */
+ clipboard_text += QString(3, ' ');
+
+ /* separation bytes last line */
+ if ( cnt == ( lines - 1 ) )
+ {
+ int remSpace = byteLineLength_ - dataStr.mid(offset, byteLineLength_).length();
+ clipboard_text += QString(remSpace * 3, ' ');
+ }
+
+ /* text representation */
+ clipboard_text += dataStr.mid(offset, byteLineLength_);
+ }
+
+ clipboard_text += "\n";
+ }
+
+ return clipboard_text;
+}
+
+
+/*
+ * 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/utils/data_printer.h b/ui/qt/utils/data_printer.h
new file mode 100644
index 0000000000..923c15169b
--- /dev/null
+++ b/ui/qt/utils/data_printer.h
@@ -0,0 +1,85 @@
+/* data_printer.h
+ *
+ * Used by ByteView and others, to create data dumps in printable
+ * form
+ *
+ * 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 DATA_PRINTER_H
+#define DATA_PRINTER_H
+
+#include <config.h>
+
+#include <QObject>
+
+
+class IDataPrintable
+{
+public:
+ virtual ~IDataPrintable() {}
+
+ virtual QByteArray printableData() = 0;
+};
+
+class DataPrinter : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DataPrinter(QObject *parent = 0);
+
+ enum DumpType {
+ DP_HexDump,
+ DP_HexOnly,
+ DP_HexStream,
+ DP_PrintableText,
+ DP_EscapedString,
+ DP_Binary
+ };
+
+ void toClipboard(DataPrinter::DumpType type, IDataPrintable * printable);
+
+ void setByteLineLength(int);
+ int byteLineLength() const;
+
+private:
+ QString hexTextDump(QByteArray printData, bool append_text);
+ void binaryDump(QByteArray printData);
+
+ int byteLineLength_;
+};
+
+#define IDataPrintable_iid "org.wireshark.Qt.UI.IDataPrintable"
+
+Q_DECLARE_INTERFACE(IDataPrintable, IDataPrintable_iid)
+
+#endif // DATA_PRINTER_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/utils/field_information.cpp b/ui/qt/utils/field_information.cpp
new file mode 100644
index 0000000000..77997eab84
--- /dev/null
+++ b/ui/qt/utils/field_information.cpp
@@ -0,0 +1,175 @@
+/* field_information.cpp
+ *
+ * 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 <stdint.h>
+
+#include <ui/qt/utils/field_information.h>
+
+FieldInformation::FieldInformation(field_info * fi, QObject * parent)
+:QObject(parent)
+{
+ fi_ = fi;
+ parent_fi_ = 0;
+}
+
+bool FieldInformation::isValid()
+{
+ bool ret = false;
+
+ if ( fi_ )
+ {
+ if (fi_->hfinfo->blurb != 0 && fi_->hfinfo->blurb[0] != '\0') {
+ ret = true;
+ } else {
+ ret = ((QString().fromUtf8(fi_->hfinfo->name)).length() > 0 );
+ }
+ }
+
+ return ret;
+}
+
+void FieldInformation::setParentField(field_info * par_fi)
+{
+ parent_fi_ = par_fi;
+}
+
+field_info * FieldInformation::fieldInfo() const
+{
+ return fi_;
+}
+
+FieldInformation::HeaderInfo FieldInformation::headerInfo() const
+{
+ HeaderInfo header;
+ header.isValid = false;
+
+ if ( fi_ && fi_->hfinfo )
+ {
+ header.isValid = true;
+ header.name = QString().fromUtf8(fi_->hfinfo->name);
+ header.description = QString().fromUtf8(fi_->hfinfo->blurb);
+ header.abbreviation = QString().fromUtf8(fi_->hfinfo->abbrev);
+ }
+
+ return header;
+}
+
+FieldInformation * FieldInformation::parentField() const
+{
+ return new FieldInformation(parent_fi_);
+}
+
+bool FieldInformation::tvbContains(FieldInformation *child)
+{
+ if ( fi_ && child && fi_->ds_tvb == child->fieldInfo()->ds_tvb )
+ return true;
+
+ return false;
+}
+
+FieldInformation::Position FieldInformation::position() const
+{
+ Position pos = {-1, -1, -1};
+ if ( fi_ )
+ {
+ guint len = tvb_captured_length(fi_->ds_tvb);
+
+ pos.start = fi_->start;
+ pos.length = fi_->length;
+
+ if (pos.start >= 0 && pos.length > 0 && (guint)pos.start < len)
+ {
+ pos.end = pos.start + pos.length;
+ }
+ else
+ {
+ if ( fi_->appendix_start >= 0 && fi_->appendix_length > 0 && (guint)fi_->appendix_start < len )
+ {
+ pos.start = fi_->appendix_start;
+ pos.end = fi_->appendix_start + fi_->appendix_length;
+ }
+ }
+
+ if (pos.end != -1 && (guint)pos.end > len)
+ pos.end = len;
+ }
+
+ return pos;
+}
+
+FieldInformation::Position FieldInformation::appendix() const
+{
+ Position pos = {-1, -1, -1};
+ if ( fi_ )
+ {
+ guint len = tvb_captured_length(fi_->ds_tvb);
+
+ pos.start = fi_->appendix_start;
+ pos.length = fi_->appendix_length;
+
+ if (pos.start >= 0 && pos.length > 0 && (guint)pos.start < len)
+ pos.end = pos.start + pos.length;
+
+ /* sanity check with total field length */
+ if ( position().end == -1 )
+ {
+ pos.start = -1;
+ pos.end = -1;
+ }
+
+ if (pos.end != -1 && (guint)pos.end > len)
+ pos.end = len;
+ }
+
+ return pos;
+}
+#include <QDebug>
+QByteArray FieldInformation::printableData()
+{
+ QByteArray data;
+
+ if ( fi_ && fi_->ds_tvb )
+ {
+ FieldInformation::Position pos = position();
+ int rem_length = tvb_captured_length_remaining(fi_->ds_tvb, pos.start);
+
+ int length = pos.length;
+ if ( length > rem_length )
+ length = rem_length;
+qDebug() << "Bin hier";
+ uint8_t * dataSet = (uint8_t *)tvb_memdup(wmem_file_scope(), fi_->ds_tvb, pos.start, length );
+ data = QByteArray::fromRawData((char *)dataSet, length);
+ }
+
+ return data;
+}
+/*
+ * 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/utils/field_information.h b/ui/qt/utils/field_information.h
new file mode 100644
index 0000000000..71f49b5a47
--- /dev/null
+++ b/ui/qt/utils/field_information.h
@@ -0,0 +1,91 @@
+/* field_information.h
+ *
+ * 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 FIELD_INFORMATION_H_
+#define FIELD_INFORMATION_H_
+
+#include <config.h>
+
+#include <epan/proto.h>
+
+#include <ui/qt/utils/data_printer.h>
+
+#include <QObject>
+
+class FieldInformation : public QObject, public IDataPrintable
+{
+ Q_OBJECT
+ Q_INTERFACES(IDataPrintable)
+
+public:
+
+ struct HeaderInfo
+ {
+ QString name;
+ QString description;
+ QString abbreviation;
+ bool isValid;
+ };
+
+ struct Position
+ {
+ int start;
+ int end;
+ int length;
+ };
+
+ explicit FieldInformation(field_info * fi, QObject * parent = Q_NULLPTR);
+
+ bool isValid();
+
+ field_info * fieldInfo() const;
+
+ HeaderInfo headerInfo() const;
+ Position position() const;
+ Position appendix() const;
+
+ void setParentField(field_info * fi);
+ FieldInformation * parentField() const;
+ bool tvbContains(FieldInformation *);
+
+ QByteArray printableData();
+
+private:
+
+ field_info * fi_;
+ field_info * parent_fi_;
+};
+
+
+#endif // FIELD_INFORMATION_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/utils/frame_information.cpp b/ui/qt/utils/frame_information.cpp
new file mode 100644
index 0000000000..0b4116d2bc
--- /dev/null
+++ b/ui/qt/utils/frame_information.cpp
@@ -0,0 +1,117 @@
+/* frame_information.cpp
+ *
+ * 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 <epan/epan_dissect.h>
+#include "epan/epan.h"
+#include "epan/column.h"
+#include "epan/ftypes/ftypes.h"
+
+#include "wiretap/wtap.h"
+
+#include "cfile.h"
+#include "file.h"
+#include <ui/qt/capture_file.h>
+
+#include "frame_tvbuff.h"
+
+#include <stdint.h>
+
+#include <ui/qt/utils/frame_information.h>
+
+FrameInformation::FrameInformation(CaptureFile * capfile, frame_data * fi, QObject * parent)
+:QObject(parent),
+ fi_(fi),
+ cap_file_(capfile),
+ packet_data_(0)
+{
+ loadFrameTree();
+}
+
+void FrameInformation::loadFrameTree()
+{
+ if ( ! fi_ || ! cap_file_ )
+ return;
+
+ if (!cf_read_record(cap_file_->capFile(), fi_))
+ return;
+
+ struct wtap_pkthdr phdr_ = cap_file_->capFile()->phdr;
+ packet_data_ = (guint8 *) g_memdup(ws_buffer_start_ptr(&(cap_file_->capFile()->buf)), fi_->cap_len);
+
+ /* proto tree, visible. We need a proto tree if there's custom columns */
+ epan_dissect_init(&edt_, cap_file_->capFile()->epan, TRUE, TRUE);
+ col_custom_prime_edt(&edt_, &(cap_file_->capFile()->cinfo));
+
+ epan_dissect_run(&edt_, cap_file_->capFile()->cd_t, &phdr_,
+ frame_tvbuff_new(fi_, packet_data_),
+ fi_, &(cap_file_->capFile()->cinfo));
+ epan_dissect_fill_in_columns(&edt_, TRUE, TRUE);
+}
+
+FrameInformation::~FrameInformation()
+{
+ epan_dissect_cleanup(&edt_);
+ delete(packet_data_);
+}
+
+bool FrameInformation::isValid()
+{
+ bool ret = false;
+
+ if ( fi_ && cap_file_ && edt_.tvb )
+ {
+ ret = true;
+ }
+
+ return ret;
+}
+
+frame_data * FrameInformation::frameData() const
+{
+ return fi_;
+}
+
+QByteArray FrameInformation::printableData()
+{
+ QByteArray data;
+
+ if ( fi_ )
+ {
+ int rem_length = tvb_captured_length(edt_.tvb);
+
+ uint8_t * dataSet = (uint8_t *)tvb_memdup(wmem_file_scope(), edt_.tvb, 0, rem_length );
+ data = QByteArray::fromRawData((char *)dataSet, rem_length);
+ }
+
+ return data;
+}
+/*
+ * 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/utils/frame_information.h b/ui/qt/utils/frame_information.h
new file mode 100644
index 0000000000..1a3a8fda3f
--- /dev/null
+++ b/ui/qt/utils/frame_information.h
@@ -0,0 +1,80 @@
+/* frame_information.h
+ *
+ * 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 FRAME_INFORMATION_H_
+#define FRAME_INFORMATION_H_
+
+#include <config.h>
+
+#include <epan/proto.h>
+#include <epan/epan_dissect.h>
+#include "epan/epan.h"
+#include "epan/column.h"
+#include "epan/ftypes/ftypes.h"
+
+#include <ui/qt/capture_file.h>
+
+#include <ui/qt/utils/data_printer.h>
+
+#include <QObject>
+
+class FrameInformation : public QObject, public IDataPrintable
+{
+ Q_OBJECT
+ Q_INTERFACES(IDataPrintable)
+
+public:
+
+ explicit FrameInformation(CaptureFile * cfile, frame_data * fi, QObject * parent = Q_NULLPTR);
+ virtual ~FrameInformation();
+
+ bool isValid();
+
+ frame_data * frameData() const;
+
+ QByteArray printableData();
+
+private:
+
+ frame_data * fi_;
+ CaptureFile * cap_file_;
+ guint8 *packet_data_;
+ epan_dissect_t edt_;
+
+ void loadFrameTree();
+
+};
+
+
+#endif // FRAME_INFORMATION_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/byte_view_text.cpp b/ui/qt/widgets/byte_view_text.cpp
index 95575140ed..95575140ed 100644
--- a/ui/qt/byte_view_text.cpp
+++ b/ui/qt/widgets/byte_view_text.cpp
diff --git a/ui/qt/byte_view_text.h b/ui/qt/widgets/byte_view_text.h
index f5a7430f94..f5a7430f94 100644
--- a/ui/qt/byte_view_text.h
+++ b/ui/qt/widgets/byte_view_text.h
diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp
index 0c67b8ec86..a99ca47c59 100644
--- a/ui/qt/wireshark_application.cpp
+++ b/ui/qt/wireshark_application.cpp
@@ -96,6 +96,7 @@
#include <QThread>
#include <QUrl>
#include <QColorDialog>
+#include <qmath.h>
#ifdef _MSC_VER
#pragma warning(pop)
@@ -1263,6 +1264,19 @@ void WiresharkApplication::doTriggerMenuItem(MainMenuItem menuItem)
}
}
+void WiresharkApplication::zoomTextFont(int zoomLevel)
+{
+ // Scale by 10%, rounding to nearest half point, minimum 1 point.
+ // XXX Small sizes repeat. It might just be easier to create a map of multipliers.
+ QFont zoomed_font_ = mono_font_;
+ qreal zoom_size = mono_font_.pointSize() * 2 * qPow(qreal(1.1), zoomLevel);
+ zoom_size = qRound(zoom_size) / qreal(2.0);
+ zoom_size = qMax(zoom_size, qreal(1.0));
+ zoomed_font_.setPointSizeF(zoom_size);
+
+ emit zoomMonospaceFont(zoomed_font_);
+}
+
#ifdef HAVE_SOFTWARE_UPDATE
bool WiresharkApplication::softwareUpdateCanShutdown() {
software_update_ok_ = true;
diff --git a/ui/qt/wireshark_application.h b/ui/qt/wireshark_application.h
index 1754f83aa0..3d2677ca33 100644
--- a/ui/qt/wireshark_application.h
+++ b/ui/qt/wireshark_application.h
@@ -138,6 +138,8 @@ public:
void doTriggerMenuItem(MainMenuItem menuItem);
+ void zoomTextFont(int zoomLevel);
+
private:
bool initialized_;
bool is_reloading_lua_;
@@ -200,6 +202,8 @@ signals:
/* Signals activation and stop of a capture. The value provides the number of active captures */
void captureActive(int);
+ void zoomMonospaceFont(const QFont & font);
+
public slots:
void clearRecentCaptures();
void captureFileReadStarted();