frame_data *PacketListModel::getRowFdata(int row) { if (row < 0 || row >= visible_rows_.count()) return NULL; PacketListRecord *record = visible_rows_[row]; if (!record) return NULL; return record->frameData(); }
guint PacketListModel::recreateVisibleRows() { int pos = visible_rows_.count() + 1; PacketListRecord *record; beginResetModel(); visible_rows_.clear(); number_to_row_.clear(); endResetModel(); beginInsertRows(QModelIndex(), pos, pos); foreach (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; } } endInsertRows(); return visible_rows_.count(); }
QVariant PacketListModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); PacketListRecord *record = static_cast<PacketListRecord*>(index.internalPointer()); if (!record) return QVariant(); const frame_data *fdata = record->frameData(); if (!fdata) return QVariant(); switch (role) { case Qt::FontRole: return mono_font_; case Qt::TextAlignmentRole: switch(recent_get_column_xalign(index.column())) { case COLUMN_XALIGN_RIGHT: return Qt::AlignRight; break; case COLUMN_XALIGN_CENTER: return Qt::AlignCenter; break; case COLUMN_XALIGN_LEFT: return Qt::AlignLeft; break; case COLUMN_XALIGN_DEFAULT: default: if (right_justify_column(index.column(), cap_file_)) { return Qt::AlignRight; } break; } return Qt::AlignLeft; case Qt::BackgroundRole: const color_t *color; if (fdata->flags.ignored) { color = &prefs.gui_ignored_bg; } else if (fdata->flags.marked) { color = &prefs.gui_marked_bg; } else if (fdata->color_filter && recent.packet_list_colorize) { const color_filter_t *color_filter = (const color_filter_t *) fdata->color_filter; color = &color_filter->bg_color; } else { return QVariant(); } return QColor(color->red >> 8, color->green >> 8, color->blue >> 8); case Qt::ForegroundRole: if (fdata->flags.ignored) { color = &prefs.gui_ignored_fg; } else if (fdata->flags.marked) { color = &prefs.gui_marked_fg; } else if (fdata->color_filter && recent.packet_list_colorize) { const color_filter_t *color_filter = (const color_filter_t *) fdata->color_filter; color = &color_filter->fg_color; } else { return QVariant(); } return QColor(color->red >> 8, color->green >> 8, color->blue >> 8); case Qt::DisplayRole: { int column = index.column(); QVariant column_string = record->columnString(cap_file_, column); // We don't know an item's sizeHint until we fetch its text here. // 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()) emit itemHeightChanged(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(); } } default: return QVariant(); } return QVariant(); }
QVariant PacketListModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); PacketListRecord *record = static_cast<PacketListRecord*>(index.internalPointer()); if (!record) return QVariant(); frame_data *fdata = record->frameData(); if (!fdata) return QVariant(); switch (role) { case Qt::FontRole: return wsApp->monospaceFont(); case Qt::TextAlignmentRole: switch(recent_get_column_xalign(index.column())) { case COLUMN_XALIGN_RIGHT: return Qt::AlignRight; break; case COLUMN_XALIGN_CENTER: return Qt::AlignCenter; break; case COLUMN_XALIGN_LEFT: return Qt::AlignLeft; break; case COLUMN_XALIGN_DEFAULT: default: if (right_justify_column(index.column(), cap_file_)) { return Qt::AlignRight; } break; } return Qt::AlignLeft; case Qt::BackgroundRole: const color_t *color; if (fdata->flags.ignored) { color = &prefs.gui_ignored_bg; } else if (fdata->flags.marked) { color = &prefs.gui_marked_bg; } else if (fdata->color_filter) { const color_filter_t *color_filter = (const color_filter_t *) fdata->color_filter; color = &color_filter->bg_color; } else { return QVariant(); } // g_log(NULL, G_LOG_LEVEL_DEBUG, "i: %d m: %d cf: %p bg: %d %d %d", fdata->flags.ignored, fdata->flags.marked, fdata->color_filter, color->red, color->green, color->blue); return QColor(color->red >> 8, color->green >> 8, color->blue >> 8); case Qt::ForegroundRole: if (fdata->flags.ignored) { color = &prefs.gui_ignored_fg; } else if (fdata->flags.marked) { color = &prefs.gui_marked_fg; } else if (fdata->color_filter) { const color_filter_t *color_filter = (const color_filter_t *) fdata->color_filter; color = &color_filter->fg_color; } else { return QVariant(); } return QColor(color->red >> 8, color->green >> 8, color->blue >> 8); case Qt::DisplayRole: { int column = index.column(); // g_log(NULL, G_LOG_LEVEL_DEBUG, "showing col %d", col_num); return record->columnString(cap_file_, column); } default: return QVariant(); } return QVariant(); }
void RelatedPacketDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) QStyleOptionViewItemV4 option_vi = option; #else QStyleOptionViewItem option_vi = option; #endif QStyledItemDelegate::initStyleOption(&option_vi, index); int em_w = option_vi.fontMetrics.height(); int en_w = (em_w + 1) / 2; int line_w = (option_vi.fontMetrics.lineWidth()); #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) option_vi.features |= QStyleOptionViewItemV4::HasDecoration; #else option_vi.features |= QStyleOptionViewItem::HasDecoration; #endif option_vi.decorationSize.setHeight(1); option_vi.decorationSize.setWidth(em_w); QStyledItemDelegate::paint(painter, option_vi, index); guint32 setup_frame = 0, last_frame = 0; if (conv_) { setup_frame = (int) conv_->setup_frame; last_frame = (int) conv_->last_frame; } const frame_data *fd; PacketListRecord *record = static_cast<PacketListRecord*>(index.internalPointer()); if (!record || (fd = record->frameData()) == NULL) { return; } painter->save(); if (QApplication::style()->objectName().contains("vista")) { // QWindowsVistaStyle::drawControl does this internally. Unfortunately there // doesn't appear to be a more general way to do this. option_vi.palette.setColor(QPalette::All, QPalette::HighlightedText, option_vi.palette.color(QPalette::Active, QPalette::Text)); } QPalette::ColorGroup cg = option_vi.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; QColor fg; if (cg == QPalette::Normal && !(option_vi.state & QStyle::State_Active)) cg = QPalette::Inactive; if (option_vi.state & QStyle::State_Selected) { fg = option_vi.palette.color(cg, QPalette::HighlightedText); } else { fg = option_vi.palette.color(cg, QPalette::Text); } fg = ColorUtils::alphaBlend(fg, option_vi.palette.color(cg, QPalette::Base), 0.5); QPen line_pen(fg); line_pen.setWidth(line_w); line_pen.setJoinStyle(Qt::RoundJoin); painter->setPen(line_pen); painter->translate(option_vi.rect.x(), option_vi.rect.y()); painter->translate(en_w + 0.5, 0.5); painter->setRenderHint(QPainter::Antialiasing, true); int height = option_vi.rect.height(); // Uncomment to make the boundary visible. // painter->save(); // painter->setPen(Qt::darkRed); // painter->drawRect(QRectF(0.5, 0.5, en_w - 1, height - 1)); // painter->restore(); // The current decorations are based on what looked good and were easy // to code. // It might be useful to have a JACKPOT_MODE define that shows each // decoration in sequence in order to make it easier to create // screenshots for the User's Guide. // Vertical line. Lower and upper half for the start and end of the // conversation respectively, solid for conversation member, dashed // for other packets in the start-end range. if (setup_frame > 0 && last_frame > 0 && setup_frame != last_frame) { if (fd->num == setup_frame) { QPoint start_line[] = { QPoint(en_w - 1, height / 2), QPoint(0, height / 2), QPoint(0, height) }; painter->drawPolyline(start_line, 3); } else if (fd->num > setup_frame && fd->num < last_frame) { painter->save(); if (conv_ != record->conversation()) { QPen other_pen(line_pen); other_pen.setStyle(Qt::DashLine); painter->setPen(other_pen); } painter->drawLine(0, 0, 0, height); painter->restore(); } else if (fd->num == last_frame) { QPoint end_line[] = { QPoint(en_w - 1, height / 2), QPoint(0, height / 2), QPoint(0, 0) }; painter->drawPolyline(end_line, 3); } } // Related packet indicator. Rightward arrow for requests, leftward // arrow for responses, circle for others. // XXX These are comically oversized when we have multi-line rows. if (related_frames_.contains(fd->num)) { painter->setBrush(fg); switch (related_frames_[fd->num]) { // Request and response arrows are moved forward one pixel in order to // maximize white space between the heads and the conversation line. case FT_FRAMENUM_REQUEST: { int hh = height / 2; QPoint tail(2 - en_w, hh); QPoint head(en_w, hh); drawArrow(painter, tail, head, hh / 2); break; } case FT_FRAMENUM_RESPONSE: { int hh = height / 2; QPoint tail(en_w - 1, hh); QPoint head(1 - en_w, hh); drawArrow(painter, tail, head, hh / 2); break; } case FT_FRAMENUM_ACK: { QRect bbox (2 - en_w, height / 3, em_w - 2, height / 2); drawCheckMark(painter, bbox); break; } case FT_FRAMENUM_DUP_ACK: { QRect bbox (2 - en_w, (height / 3) - (line_w * 2), em_w - 2, height / 2); drawCheckMark(painter, bbox); bbox.moveTop(bbox.top() + (line_w * 3)); drawCheckMark(painter, bbox); break; } case FT_FRAMENUM_NONE: default: painter->drawEllipse(QPointF(0.0, option_vi.rect.height() / 2), 2, 2); } } painter->restore(); }
void RelatedPacketDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { int en_w = option.fontMetrics.height() / 2; QStyleOptionViewItemV4 optv4 = option; QStyledItemDelegate::initStyleOption(&optv4, index); optv4.features |= QStyleOptionViewItemV4::HasDecoration; optv4.decorationSize.setHeight(1); optv4.decorationSize.setWidth(en_w); QStyledItemDelegate::paint(painter, optv4, index); const frame_data *fd; PacketListRecord *record = static_cast<PacketListRecord*>(index.internalPointer()); if (!record || (fd = record->frameData()) == NULL) { return; } painter->save(); if (QApplication::style()->objectName().contains("vista")) { // QWindowsVistaStyle::drawControl does this internally. Unfortunately there // doesn't appear to be a more general way to do this. optv4.palette.setColor(QPalette::All, QPalette::HighlightedText, optv4.palette.color(QPalette::Active, QPalette::Text)); } QPalette::ColorGroup cg = optv4.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; QColor fg; if (cg == QPalette::Normal && !(optv4.state & QStyle::State_Active)) cg = QPalette::Inactive; if (optv4.state & QStyle::State_Selected) { fg = optv4.palette.color(cg, QPalette::HighlightedText); } else { fg = optv4.palette.color(cg, QPalette::Text); } qreal alpha = 0.20; // Arbitrary. Should arguably be a preference. // We draw in the same place more than once so we first draw on a // QImage at 100% opacity then draw that on our packet list item. QImage overlay = QImage(en_w * 2, optv4.rect.height(), QImage::Format_ARGB32_Premultiplied); QPainter op(&overlay); overlay.fill(Qt::transparent); op.setPen(fg); op.translate(en_w + 0.5, 0.5); op.setRenderHint(QPainter::Antialiasing, true); // The current decorations are based on what looked good and were easy // to code. W might want to improve them by drawing small dots or tick // marks for frames in the same conversation XOR draw a gap for unrelated // frames. if (first_frame_ > 0 && last_frame_ > 0 && first_frame_ != last_frame_) { int height = optv4.rect.height(); if ((int) fd->num == first_frame_) { op.drawLine(0, height / 2, 0, height); op.drawLine(1, height / 2, en_w, height / 2); } else if ((int) fd->num > first_frame_ && (int) fd->num < last_frame_) { op.drawLine(0, 0, 0, height); } else if ((int) fd->num == last_frame_) { op.drawLine(0, 0, 0, height / 2); op.drawLine(1, height / 2, en_w, height / 2); } } if (related_frames_.contains(fd->num)) { op.setBrush(fg); op.drawEllipse(QPointF(0.0, optv4.rect.height() / 2), 2, 2); } painter->setOpacity(alpha); painter->drawImage(optv4.rect.x(), optv4.rect.y(), overlay); painter->restore(); }