summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/frame_data.h8
-rw-r--r--ui/qt/main_window.cpp2
-rw-r--r--ui/qt/packet_list.cpp27
-rw-r--r--ui/qt/packet_list_model.cpp103
-rw-r--r--ui/qt/packet_list_model.h8
-rw-r--r--ui/qt/packet_list_record.cpp8
-rw-r--r--ui/qt/packet_list_record.h8
-rw-r--r--ui/qt/related_packet_delegate.cpp2
-rw-r--r--ui/ui_util.h2
9 files changed, 144 insertions, 24 deletions
diff --git a/epan/frame_data.h b/epan/frame_data.h
index 996f4e1321..bf8842e640 100644
--- a/epan/frame_data.h
+++ b/epan/frame_data.h
@@ -23,6 +23,10 @@
#ifndef __FRAME_DATA_H__
#define __FRAME_DATA_H__
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
#include <epan/tvbuff.h>
#include <wsutil/nstime.h>
#include "ws_symbol_export.h"
@@ -119,6 +123,10 @@ WS_DLL_PUBLIC void frame_data_set_after_dissect(frame_data *fdata,
/** @} */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
#endif /* __FRAME_DATA__ */
/*
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index 3aa5a31ddc..677bf88403 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -1578,7 +1578,7 @@ void MainWindow::setMenusForCaptureInProgress(bool capture_in_progress) {
main_ui_->actionSummary->setEnabled(capture_in_progress);
- qDebug() << "FIX: packet list heading menu sensitivity";
+ // XXX Fix packet list heading menu sensitivity
// set_menu_sensitivity(ui_manager_packet_list_heading, "/PacketListHeadingPopup/SortAscending",
// !capture_in_progress);
// set_menu_sensitivity(ui_manager_packet_list_heading, "/PacketListHeadingPopup/SortDescending",
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index bb593ad0ed..e2adc1f3bc 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -47,12 +47,17 @@
#include "frame_tvbuff.h"
-#include <QTreeWidget>
-#include <QTabWidget>
-#include <QTextEdit>
-#include <QScrollBar>
#include <QContextMenuEvent>
+#include <QHeaderView>
#include <QMessageBox>
+#include <QScrollBar>
+#include <QTabWidget>
+#include <QTextEdit>
+#include <QTreeWidget>
+
+// To do:
+// - Heading context menus
+// - Catch column reordering and rebuild the column list accoringly.
// If we ever add the ability to open multiple capture files we might be
// able to use something like QMap<capture_file *, PacketList *> to match
@@ -231,15 +236,16 @@ PacketList::PacketList(QWidget *parent) :
{
QMenu *submenu, *subsubmenu;
- setItemsExpandable(FALSE);
- setRootIsDecorated(FALSE);
- setSortingEnabled(TRUE);
- setUniformRowHeights(TRUE);
+ setItemsExpandable(false);
+ setRootIsDecorated(false);
+ setSortingEnabled(true);
+ setUniformRowHeights(true);
setAccessibleName("Packet list");
setItemDelegateForColumn(0, &related_packet_delegate_);
packet_list_model_ = new PacketListModel(this, cap_file_);
setModel(packet_list_model_);
+ sortByColumn(-1, Qt::AscendingOrder);
// XXX We might want to reimplement setParent() and fill in the context
// menu there.
@@ -387,6 +393,7 @@ PacketList::PacketList(QWidget *parent) :
g_assert(gbl_cur_packet_list == NULL);
gbl_cur_packet_list = this;
+ connect(packet_list_model_, SIGNAL(goToPacket(int)), this, SLOT(goToPacket(int)));
connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(updateAll()));
}
@@ -615,7 +622,7 @@ void PacketList::clear() {
/* XXX is this correct in all cases?
* Reset the sort column, use packetlist as model in case the list is frozen.
*/
- sortByColumn(0, Qt::AscendingOrder);
+ sortByColumn(-1, Qt::AscendingOrder);
setColumnVisibility();
}
@@ -718,7 +725,7 @@ QString &PacketList::getFilterFromRowAndColumn()
QString PacketList::packetComment()
{
int row = currentIndex().row();
- frame_data *fdata;
+ const frame_data *fdata;
char *pkt_comment;
if (!cap_file_ || !packet_list_model_) return NULL;
diff --git a/ui/qt/packet_list_model.cpp b/ui/qt/packet_list_model.cpp
index 0de133d440..78f57f550e 100644
--- a/ui/qt/packet_list_model.cpp
+++ b/ui/qt/packet_list_model.cpp
@@ -76,7 +76,7 @@ int PacketListModel::packetNumberToRow(int packet_num) const
guint PacketListModel::recreateVisibleRows()
{
- int pos = visible_rows_.count() + 1;
+ int pos = visible_rows_.count();
PacketListRecord *record;
beginResetModel();
@@ -135,6 +135,103 @@ void PacketListModel::setMonospaceFont(const QFont &mono_font)
recreateVisibleRows();
}
+// The Qt MVC documentation suggests using QSortFilterProxyModel for sorting
+// and filtering. That seems like overkill but it might be something we want
+// to do in the future.
+
+int PacketListModel::sort_column_;
+int PacketListModel::text_sort_column_;
+Qt::SortOrder PacketListModel::sort_order_;
+capture_file *PacketListModel::sort_cap_file_;
+
+void PacketListModel::sort(int column, Qt::SortOrder order)
+{
+ if (!cap_file_ || visible_rows_.length() < 1) {
+ return;
+ }
+
+ sort_column_ = column;
+ text_sort_column_ = PacketListRecord::textColumn(column);
+ sort_order_ = order;
+ sort_cap_file_ = cap_file_;
+
+ beginResetModel();
+ qSort(visible_rows_.begin(), visible_rows_.end(), recordLessThan);
+ for (int i = 0; i < visible_rows_.count(); i++) {
+ number_to_row_[visible_rows_[i]->frameData()->num] = i;
+ }
+ endResetModel();
+
+ if (cap_file_->current_frame) {
+ emit goToPacket(cap_file_->current_frame->num);
+ }
+}
+
+bool PacketListModel::recordLessThan(PacketListRecord *r1, PacketListRecord *r2)
+{
+ int cmp_val = 0;
+
+ // Wherein we try to cram the logic of packet_list_compare_records,
+ // _packet_list_compare_records, and packet_list_compare_custom from
+ // gtk/packet_list_store.c into one function
+
+ if (sort_column_ < 0) {
+ // No column.
+ cmp_val = frame_data_compare(sort_cap_file_->epan, r1->frameData(), r2->frameData(), COL_NUMBER);
+ } else if (text_sort_column_ < 0) {
+ // Column comes directly from frame data
+ cmp_val = frame_data_compare(sort_cap_file_->epan, r1->frameData(), r2->frameData(), sort_cap_file_->cinfo.col_fmt[sort_column_]);
+ } else {
+ if (r1->columnString(sort_cap_file_, sort_column_).toByteArray().data() == r2->columnString(sort_cap_file_, sort_column_).toByteArray().data()) {
+ cmp_val = 0;
+ } else if (sort_cap_file_->cinfo.col_fmt[sort_column_] == COL_CUSTOM) {
+ header_field_info *hfi;
+
+ // Column comes from custom data
+ hfi = proto_registrar_get_byname(sort_cap_file_->cinfo.col_custom_field[sort_column_]);
+
+ if (hfi == NULL) {
+ cmp_val = frame_data_compare(sort_cap_file_->epan, r1->frameData(), r2->frameData(), COL_NUMBER);
+ } else if ((hfi->strings == NULL) &&
+ (((IS_FT_INT(hfi->type) || IS_FT_UINT(hfi->type)) &&
+ ((hfi->display == BASE_DEC) || (hfi->display == BASE_DEC_HEX) ||
+ (hfi->display == BASE_OCT))) ||
+ (hfi->type == FT_DOUBLE) || (hfi->type == FT_FLOAT) ||
+ (hfi->type == FT_BOOLEAN) || (hfi->type == FT_FRAMENUM) ||
+ (hfi->type == FT_RELATIVE_TIME)))
+ {
+ /* Attempt to convert to numbers */
+ bool ok_r1, ok_r2;
+ double num_r1 = r1->columnString(sort_cap_file_, sort_column_).toDouble(&ok_r1);
+ double num_r2 = r2->columnString(sort_cap_file_, sort_column_).toDouble(&ok_r2);
+
+ if (!ok_r1 && !ok_r2) {
+ cmp_val = 0;
+ } else if (!ok_r1 || num_r1 < num_r2) {
+ cmp_val = -1;
+ } else if (!ok_r2 || num_r1 > num_r2) {
+ cmp_val = 1;
+ }
+ } else {
+ cmp_val = strcmp(r1->columnString(sort_cap_file_, sort_column_).toByteArray().data(), r2->columnString(sort_cap_file_, sort_column_).toByteArray().data());
+ }
+ } else {
+ cmp_val = strcmp(r1->columnString(sort_cap_file_, sort_column_).toByteArray().data(), r2->columnString(sort_cap_file_, sort_column_).toByteArray().data());
+ }
+
+ if (cmp_val == 0) {
+ // Last resort. Compare column numbers.
+ cmp_val = frame_data_compare(sort_cap_file_->epan, r1->frameData(), r2->frameData(), COL_NUMBER);
+ }
+ }
+
+ if (sort_order_ == Qt::AscendingOrder) {
+ return cmp_val < 0;
+ } else {
+ return cmp_val > 0;
+ }
+}
+
int PacketListModel::rowCount(const QModelIndex &parent) const
{
if (parent.column() >= prefs.num_cols)
@@ -158,7 +255,7 @@ QVariant PacketListModel::data(const QModelIndex &index, int role) const
PacketListRecord *record = static_cast<PacketListRecord*>(index.internalPointer());
if (!record)
return QVariant();
- frame_data *fdata = record->frameData();
+ const frame_data *fdata = record->frameData();
if (!fdata)
return QVariant();
@@ -242,7 +339,7 @@ QVariant PacketListModel::headerData(int section, Qt::Orientation orientation,
gint PacketListModel::appendPacket(frame_data *fdata)
{
PacketListRecord *record = new PacketListRecord(fdata);
- gint pos = visible_rows_.count() + 1;
+ gint pos = visible_rows_.count();
physical_rows_ << record;
diff --git a/ui/qt/packet_list_model.h b/ui/qt/packet_list_model.h
index 3775f1958a..9c22be5daa 100644
--- a/ui/qt/packet_list_model.h
+++ b/ui/qt/packet_list_model.h
@@ -65,9 +65,11 @@ public:
int columnTextSize(const char *str);
signals:
+ void goToPacket(int);
public slots:
void setMonospaceFont(const QFont &mono_font);
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
private:
capture_file *cap_file_;
@@ -78,6 +80,12 @@ private:
QMap<int, int> number_to_row_;
int header_height_;
+
+ static int sort_column_;
+ static int text_sort_column_;
+ static Qt::SortOrder sort_order_;
+ static capture_file *sort_cap_file_;
+ static bool recordLessThan(PacketListRecord *r1, PacketListRecord *r2);
};
#endif // PACKET_LIST_MODEL_H
diff --git a/ui/qt/packet_list_record.cpp b/ui/qt/packet_list_record.cpp
index 296693b59b..1799ddfc78 100644
--- a/ui/qt/packet_list_record.cpp
+++ b/ui/qt/packet_list_record.cpp
@@ -33,7 +33,7 @@
#include <QStringList>
-QMap<int, int> cinfo_column_;
+QMap<int, int> PacketListRecord::cinfo_column_;
PacketListRecord::PacketListRecord(frame_data *frameData) :
fdata_(frameData),
@@ -42,7 +42,7 @@ PacketListRecord::PacketListRecord(frame_data *frameData) :
{
}
-QVariant PacketListRecord::columnString(capture_file *cap_file, int column)
+const QVariant PacketListRecord::columnString(capture_file *cap_file, int column)
{
// packet_list_store.c:packet_list_get_value
g_assert(fdata_);
@@ -58,10 +58,6 @@ QVariant PacketListRecord::columnString(capture_file *cap_file, int column)
return col_text_.value(column, QByteArray());
}
-frame_data *PacketListRecord::frameData() {
- return fdata_;
-}
-
void PacketListRecord::resetColumns(column_info *cinfo)
{
if (!cinfo) {
diff --git a/ui/qt/packet_list_record.h b/ui/qt/packet_list_record.h
index 18fd3d90ba..a116e62633 100644
--- a/ui/qt/packet_list_record.h
+++ b/ui/qt/packet_list_record.h
@@ -40,8 +40,10 @@ class PacketListRecord
public:
PacketListRecord(frame_data *frameData);
// Return the string value for a column. Data is cached if possible.
- QVariant columnString(capture_file *cap_file, int column);
- frame_data *frameData();
+ const QVariant columnString(capture_file *cap_file, int column);
+ frame_data *frameData() const { return fdata_; }
+ // packet_list->col_to_text in gtk/packet_list_store.c
+ static int textColumn(int column) { return cinfo_column_.value(column, -1); }
int columnTextSize(const char *str);
static void resetColumns(column_info *cinfo);
@@ -52,6 +54,8 @@ private:
QList<QByteArray> col_text_;
frame_data *fdata_;
+ static QMap<int, int> cinfo_column_;
+
/** Has this record been columnized? */
// gboolean columnized_;
diff --git a/ui/qt/related_packet_delegate.cpp b/ui/qt/related_packet_delegate.cpp
index 11fb34caac..c7964d2e8f 100644
--- a/ui/qt/related_packet_delegate.cpp
+++ b/ui/qt/related_packet_delegate.cpp
@@ -38,7 +38,7 @@ void RelatedPacketDelegate::paint(QPainter *painter, const QStyleOptionViewItem
optv4.decorationSize.setWidth(en_w);
QStyledItemDelegate::paint(painter, optv4, index);
- frame_data *fd;
+ const frame_data *fd;
PacketListRecord *record = static_cast<PacketListRecord*>(index.internalPointer());
if (!record || (fd = record->frameData()) == NULL) {
return;
diff --git a/ui/ui_util.h b/ui/ui_util.h
index af6335e95d..7ebd59bd3d 100644
--- a/ui/ui_util.h
+++ b/ui/ui_util.h
@@ -67,7 +67,7 @@ void packet_list_thaw(void);
void packet_list_next(void);
void packet_list_prev(void);
guint packet_list_append(column_info *cinfo, frame_data *fdata);
-frame_data * packet_list_get_row_data(gint row);
+frame_data *packet_list_get_row_data(gint row);
void packet_list_set_selected_row(gint row);
void packet_list_enable_color(gboolean enable);
void packet_list_queue_draw(void);