diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 728b1876f6..dfcff45185 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -676,6 +676,8 @@ void MainWindow::captureFileReadFinished() { main_ui_->statusBar->setFileName(capture_file_); + packet_list_->captureFileReadFinished(); + emit setDissectedCaptureFile(capture_file_.capFile()); } diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp index 4e5bd43b72..cabdbbbf81 100644 --- a/ui/qt/packet_list.cpp +++ b/ui/qt/packet_list.cpp @@ -374,6 +374,7 @@ PacketList::PacketList(QWidget *parent) : g_assert(gbl_cur_packet_list == NULL); gbl_cur_packet_list = this; + connect(packet_list_model_, SIGNAL(rowHeightsVary()), this, SLOT(rowHeightsVary())); connect(packet_list_model_, SIGNAL(goToPacket(int)), this, SLOT(goToPacket(int))); connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(redrawVisiblePackets())); @@ -728,6 +729,13 @@ void PacketList::setAutoScroll(bool enabled) } } +// Called when we finish reading, reloading, rescanning, and retapping +// packets. +void PacketList::captureFileReadFinished() +{ + packet_list_model_->flushVisibleRows(); +} + void PacketList::freeze() { setUpdatesEnabled(false); @@ -765,6 +773,7 @@ void PacketList::clear() { create_near_overlay_ = true; create_far_overlay_ = true; + setUniformRowHeights(true); setColumnVisibility(); } @@ -1226,6 +1235,14 @@ void PacketList::sectionMoved(int, int, int) wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); } +void PacketList::rowHeightsVary() +{ + // This impairs performance considerably for large numbers of packets. + // We should probably move a bunch of the code in ::data to + // RelatedPacketDelegate and make it the delegate for everything. + setUniformRowHeights(false); +} + void PacketList::copySummary() { if (!currentIndex().isValid()) return; diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h index 3ffc5f88af..207601e4c9 100644 --- a/ui/qt/packet_list.h +++ b/ui/qt/packet_list.h @@ -74,6 +74,7 @@ public: void recolorPackets(); void setAutoScroll(bool enabled = true); void setCaptureInProgress(bool in_progress = false) { capture_in_progress_ = in_progress; tail_at_end_ = in_progress; } + void captureFileReadFinished(); protected: void showEvent(QShowEvent *); @@ -158,6 +159,7 @@ private slots: void columnVisibilityTriggered(); void sectionResized(int col, int, int new_width); void sectionMoved(int, int, int); + void rowHeightsVary(); void copySummary(); void vScrollBarActionTriggered(int); void drawFarOverlay(); diff --git a/ui/qt/packet_list_model.cpp b/ui/qt/packet_list_model.cpp index 404dda58ab..70cc7f3f4e 100644 --- a/ui/qt/packet_list_model.cpp +++ b/ui/qt/packet_list_model.cpp @@ -46,7 +46,7 @@ PacketListModel::PacketListModel(QObject *parent, capture_file *cf) : QAbstractItemModel(parent), - size_hint_enabled_(true), + uniform_row_heights_(true), row_height_(-1), line_spacing_(0) { @@ -88,7 +88,6 @@ int PacketListModel::packetNumberToRow(int packet_num) const guint PacketListModel::recreateVisibleRows() { int pos = visible_rows_.count(); - PacketListRecord *record; beginResetModel(); visible_rows_.clear(); @@ -96,7 +95,7 @@ guint PacketListModel::recreateVisibleRows() endResetModel(); beginInsertRows(QModelIndex(), pos, pos); - foreach (record, physical_rows_) { + foreach (PacketListRecord *record, physical_rows_) { if (record->frameData()->flags.passed_dfilter || record->frameData()->flags.ref_time) { visible_rows_ << record; number_to_row_[record->frameData()->num] = visible_rows_.count() - 1; @@ -114,6 +113,7 @@ void PacketListModel::clear() { number_to_row_.clear(); PacketListRecord::clearStringPool(); endResetModel(); + uniform_row_heights_ = true; } void PacketListModel::resetColumns() @@ -389,8 +389,13 @@ bool PacketListModel::recordLessThan(PacketListRecord *r1, PacketListRecord *r2) } } +// ::data is const so we have to make changes here. void PacketListModel::emitItemHeightChanged(const QModelIndex &ih_index) { + if (uniform_row_heights_) { + uniform_row_heights_ = false; + emit rowHeightsVary(); + } emit dataChanged(ih_index, ih_index); } @@ -475,20 +480,16 @@ QVariant PacketListModel::data(const QModelIndex &d_index, int role) const // Assume each line count is 1. If the line count changes, emit // itemHeightChanged which triggers another redraw (including a // fetch of SizeHintRole and DisplayRole) in the next event loop. - if (column == 0 && record->lineCountChanged()) + if (column == 0 && record->lineCountChanged()) { emit itemHeightChanged(d_index); + } return column_string; } case Qt::SizeHintRole: { - if (size_hint_enabled_) { - // We assume that inter-line spacing is 0. - QSize size = QSize(-1, row_height_ + ((record->lineCount() - 1) * line_spacing_)); - return size; - } else { - // Used by PacketList::sizeHintForColumn - return QVariant(); - } + // We assume that inter-line spacing is 0. + QSize size = QSize(-1, row_height_ + ((record->lineCount() - 1) * line_spacing_)); + return size; } default: return QVariant(); @@ -514,21 +515,42 @@ QVariant PacketListModel::headerData(int section, Qt::Orientation orientation, return QVariant(); } +void PacketListModel::flushVisibleRows() +{ + gint pos = visible_rows_.count(); + + if (new_visible_rows_.count() > 0) { + beginInsertRows(QModelIndex(), pos, pos + new_visible_rows_.count()); + foreach (PacketListRecord *record, new_visible_rows_) { + frame_data *fdata = record->frameData(); + + visible_rows_ << record; + number_to_row_[fdata->num] = visible_rows_.count() - 1; + } + endInsertRows(); + new_visible_rows_.clear(); + } +} + +// XXX Pass in cinfo from packet_list_append so that we can fill in +// line counts? gint PacketListModel::appendPacket(frame_data *fdata) { PacketListRecord *record = new PacketListRecord(fdata); - gint pos = visible_rows_.count(); + gint pos = -1; physical_rows_ << record; if (fdata->flags.passed_dfilter || fdata->flags.ref_time) { - beginInsertRows(QModelIndex(), pos, pos); - visible_rows_ << record; - number_to_row_[fdata->num] = visible_rows_.count() - 1; - endInsertRows(); - } else { - pos = -1; + new_visible_rows_ << record; + if (new_visible_rows_.count() < 2) { + // This is the first queued packet. Schedule an insertion for + // the next UI update. + QTimer::singleShot(0, this, SLOT(flushVisibleRows())); + } + pos = visible_rows_.count() + new_visible_rows_.count() - 1; } + return pos; } diff --git a/ui/qt/packet_list_model.h b/ui/qt/packet_list_model.h index 4471ebf3a9..8a41712555 100644 --- a/ui/qt/packet_list_model.h +++ b/ui/qt/packet_list_model.h @@ -69,11 +69,12 @@ public: void setDisplayedFrameIgnore(gboolean set); void toggleFrameRefTime(const QModelIndex &rt_index); void unsetAllFrameRefTime(); - void setSizeHintEnabled(bool enable) { size_hint_enabled_ = enable; } + void setSizeHintEnabled(bool enable) { uniform_row_heights_ = enable; } signals: void goToPacket(int); void itemHeightChanged(const QModelIndex &ih_index) const; + void rowHeightsVary(); void pushBusyStatus(const QString &status); void popBusyStatus(); @@ -84,16 +85,18 @@ signals: public slots: void setMonospaceFont(const QFont &mono_font, int row_height); void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); + void flushVisibleRows(); private: capture_file *cap_file_; QFont mono_font_; QList col_names_; - QVector visible_rows_; QVector physical_rows_; + QVector visible_rows_; + QVector new_visible_rows_; QMap number_to_row_; - bool size_hint_enabled_; + bool uniform_row_heights_; int row_height_; int line_spacing_;