diff options
author | Roland Knall <roland.knall@br-automation.com> | 2017-10-30 13:58:28 +0100 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2017-11-08 20:20:31 +0000 |
commit | 8a6ea0e454dddcc1d9c14ad1e02a43a53a4ef667 (patch) | |
tree | 1afd59377e5e62f8f0b057cfb406f077823872e4 /ui/qt | |
parent | 87431fef2836c8d77ea694844cd5dff0e8b801f8 (diff) |
Qt: Further cleanup ByteView
This further separates ByteView and the rest of the system.
Using FieldInformation and DataPrinter, this is the final cleanup
of the ByteViewTab
Change-Id: If41521167527cf5664c2564cdd0d45fea0f3f612
Reviewed-on: https://code.wireshark.org/review/22783
Petri-Dish: Roland Knall <rknall@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'ui/qt')
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(); |