summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2016-05-19 11:21:02 +0900
committerAnders Broman <a.broman58@gmail.com>2016-05-25 06:36:25 +0000
commit6952c1342a7c4ff1828e0bc1a36cfcfd394ee923 (patch)
tree433370041cf427f46d6a4d4c56d95726e93ec686 /ui
parentbf628988b655895ef429fa835e77c5fdca9a901b (diff)
downloadwireshark-6952c1342a7c4ff1828e0bc1a36cfcfd394ee923.tar.gz
Qt: Add Time and Comment labels to the sequence diagram.
Add "Time" and "Comment" labels to the sequence diagram similar to the GTK+ UI. Draw a border around the diagram as well. Widen the default spacing and set it to a simple em-width multiple. Fix our port number alignment. Copy over the sequence diagram colors from the GTK+ UI and add them to ColorUtils. Color sequences according to their respective conversation numbers. To do: - Add zoom. Ping-Bug: 12419 Change-Id: I3f9b4ffbfcc34aae1c38e303cd36ff207be247b1 Reviewed-on: https://code.wireshark.org/review/15554 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/qt/color_utils.cpp70
-rw-r--r--ui/qt/color_utils.h8
-rw-r--r--ui/qt/sequence_diagram.cpp69
-rw-r--r--ui/qt/sequence_dialog.cpp81
-rw-r--r--ui/qt/sequence_dialog.h4
5 files changed, 157 insertions, 75 deletions
diff --git a/ui/qt/color_utils.cpp b/ui/qt/color_utils.cpp
index 204aa59f80..cb1bdb7ac6 100644
--- a/ui/qt/color_utils.cpp
+++ b/ui/qt/color_utils.cpp
@@ -31,24 +31,6 @@ const QColor ColorUtils::expert_color_error = QColor ( 0xff, 0x5c, 0x5c );
const QColor ColorUtils::expert_color_foreground = QColor ( 0x00, 0x00, 0x00 ); /* Black */
const QColor ColorUtils::hidden_proto_item = QColor ( 0x44, 0x44, 0x44 ); /* Gray */
-// Available colors
-// XXX - Add custom
-const QList<QRgb> ColorUtils::graph_colors_ = QList<QRgb>()
- << tango_aluminium_6 // Bar outline (use black instead)?
- << tango_sky_blue_5
- << tango_butter_6
- << tango_chameleon_5
- << tango_scarlet_red_5
- << tango_plum_5
- << tango_orange_6
- << tango_aluminium_3
- << tango_sky_blue_3
- << tango_butter_3
- << tango_chameleon_3
- << tango_scarlet_red_3
- << tango_plum_3
- << tango_orange_3;
-
ColorUtils::ColorUtils(QObject *parent) :
QObject(parent)
{
@@ -109,6 +91,58 @@ QRgb ColorUtils::alphaBlend(const QBrush &brush1, const QBrush &brush2, qreal al
return alphaBlend(brush1.color(), brush2.color(), alpha);
}
+QList<QRgb> ColorUtils::graph_colors_;
+const QList<QRgb> ColorUtils::graphColors()
+{
+ if (graph_colors_.isEmpty()) {
+ // Available graph colors
+ // XXX - Add custom
+ graph_colors_ = QList<QRgb>()
+ << tango_aluminium_6 // Bar outline (use black instead)?
+ << tango_sky_blue_5
+ << tango_butter_6
+ << tango_chameleon_5
+ << tango_scarlet_red_5
+ << tango_plum_5
+ << tango_orange_6
+ << tango_aluminium_3
+ << tango_sky_blue_3
+ << tango_butter_3
+ << tango_chameleon_3
+ << tango_scarlet_red_3
+ << tango_plum_3
+ << tango_orange_3;
+ }
+ return graph_colors_;
+}
+
+QRgb ColorUtils::graphColor(int item)
+{
+ if (graph_colors_.isEmpty()) graphColors(); // Init list.
+ return graph_colors_[item % graph_colors_.size()];
+}
+
+QList<QRgb> ColorUtils::sequence_colors_;
+QRgb ColorUtils::sequenceColor(int item)
+{
+ if (sequence_colors_.isEmpty()) {
+ // Available sequence colors. Copied from gtk/graph_analysis.c.
+ // XXX - Add custom?
+ sequence_colors_ = QList<QRgb>()
+ << qRgb(144, 238, 144)
+ << qRgb(255, 160, 123)
+ << qRgb(255, 182, 193)
+ << qRgb(250, 250, 210)
+ << qRgb(255, 255, 52)
+ << qRgb(103, 205, 170)
+ << qRgb(224, 255, 255)
+ << qRgb(176, 196, 222)
+ << qRgb(135, 206, 254)
+ << qRgb(211, 211, 211);
+ }
+ return sequence_colors_[item % sequence_colors_.size()];
+}
+
/*
* Editor modelines
*
diff --git a/ui/qt/color_utils.h b/ui/qt/color_utils.h
index e9b1806363..3dceadf474 100644
--- a/ui/qt/color_utils.h
+++ b/ui/qt/color_utils.h
@@ -53,15 +53,17 @@ public:
static const QColor expert_color_foreground; /* black */
static const QColor hidden_proto_item; /* gray */
- static const QList<QRgb> graphColors() { return graph_colors_; }
- static QRgb graphColor(int item) { return graph_colors_[item % graph_colors_.size()]; }
+ static const QList<QRgb> graphColors();
+ static QRgb graphColor(int item);
+ static QRgb sequenceColor(int item);
signals:
public slots:
private:
- static const QList<QRgb> graph_colors_;
+ static QList<QRgb> graph_colors_;
+ static QList<QRgb> sequence_colors_;
};
void color_filter_qt_add_cb(color_filter_t *colorf, gpointer user_data);
diff --git a/ui/qt/sequence_diagram.cpp b/ui/qt/sequence_diagram.cpp
index 1beab92659..fa1ace2d54 100644
--- a/ui/qt/sequence_diagram.cpp
+++ b/ui/qt/sequence_diagram.cpp
@@ -25,6 +25,7 @@
#include "ui/tap-sequence-analysis.h"
+#include "color_utils.h"
#include "qt_ui_utils.h"
#include <QFont>
@@ -187,7 +188,7 @@ void SequenceDiagram::draw(QCPPainter *painter)
QPen fg_pen;
qreal alpha = 0.50;
- // Lifelines (node lines)
+ // Lifelines (node lines). Will likely be overdrawn below.
painter->save();
painter->setOpacity(alpha);
fg_pen = mainPen();
@@ -208,35 +209,40 @@ void SequenceDiagram::draw(QCPPainter *painter)
double cur_key = it.key();
seq_analysis_item_t *sai = it.value().value;
QPen fg_pen(mainPen());
+ QColor bg_color;
if (sai->frame_number == selected_packet_) {
- // Highlighted background
- painter->save();
- QRect bg_rect(
- QPoint(coordsToPixels(cur_key - 0.5, value_axis_->range().lower).toPoint()),
- QPoint(coordsToPixels(cur_key + 0.5, value_axis_->range().upper).toPoint()));
QPalette sel_pal;
- painter->fillRect(bg_rect, sel_pal.brush(QPalette::Highlight));
fg_pen.setColor(sel_pal.color(QPalette::HighlightedText));
+ bg_color = sel_pal.color(QPalette::Highlight);
+ } else {
+ fg_pen.setColor(Qt::black);
+ bg_color = ColorUtils::sequenceColor(sai->conv_num);
+ }
- // Highlighted lifelines
- painter->save();
- QPen hl_pen = fg_pen;
- hl_pen.setStyle(Qt::DashLine);
- painter->setPen(hl_pen);
- painter->setOpacity(alpha);
- for (int ll_x = value_axis_->range().lower; ll_x < value_axis_->range().upper; ll_x++) {
- // Only draw where we have arrows.
- if (ll_x < 0 || ll_x >= value_axis_->tickVector().size()) continue;
- QPoint ll_start(coordsToPixels(cur_key - 0.5, ll_x).toPoint());
- QPoint ll_end(coordsToPixels(cur_key + 0.5, ll_x).toPoint());
- hl_pen.setDashOffset(bg_rect.top() - ll_start.x());
- painter->drawLine(ll_start, ll_end);
- }
- painter->restore();
-
- painter->restore();
+ // Highlighted background
+// painter->save();
+ QRect bg_rect(
+ QPoint(coordsToPixels(cur_key - 0.5, value_axis_->range().lower).toPoint()),
+ QPoint(coordsToPixels(cur_key + 0.5, value_axis_->range().upper).toPoint()));
+ painter->fillRect(bg_rect, bg_color);
+// painter->restore();
+
+ // Highlighted lifelines
+ painter->save();
+ QPen hl_pen = fg_pen;
+ hl_pen.setStyle(Qt::DashLine);
+ painter->setPen(hl_pen);
+ painter->setOpacity(alpha);
+ for (int ll_x = value_axis_->range().lower; ll_x < value_axis_->range().upper; ll_x++) {
+ // Only draw where we have arrows.
+ if (ll_x < 0 || ll_x >= value_axis_->tickVector().size()) continue;
+ QPoint ll_start(coordsToPixels(cur_key - 0.5, ll_x).toPoint());
+ QPoint ll_end(coordsToPixels(cur_key + 0.5, ll_x).toPoint());
+ hl_pen.setDashOffset(bg_rect.top() - ll_start.x());
+ painter->drawLine(ll_start, ll_end);
}
+ painter->restore();
if (cur_key < key_axis_->range().lower || cur_key > key_axis_->range().upper) {
continue;
@@ -283,14 +289,17 @@ void SequenceDiagram::draw(QCPPainter *painter)
painter->drawText(text_pt, arrow_label);
if (sai->port_src && sai->port_dst) {
- QString port_num = QString::number(sai->port_src);
- text_pt = QPoint(arrow_start.x() - en_w - (cfm.width(port_num) * dir_mul),
+ int left_x = dir_mul > 0 ? arrow_start.x() : arrow_end.x();
+ int right_x = dir_mul > 0 ? arrow_end.x() : arrow_start.x();
+ QString port_left = QString::number(dir_mul > 0 ? sai->port_src : sai->port_dst);
+ QString port_right = QString::number(dir_mul > 0 ? sai->port_dst : sai->port_src);
+
+ text_pt = QPoint(left_x - en_w - cfm.width(port_left),
arrow_start.y() + (en_w / 2));
- painter->drawText(text_pt, port_num);
+ painter->drawText(text_pt, port_left);
- port_num = QString::number(sai->port_dst);
- text_pt.setX(arrow_end.x() - en_w + (cfm.width(port_num) * dir_mul));
- painter->drawText(text_pt, port_num);
+ text_pt.setX(right_x + en_w);
+ painter->drawText(text_pt, port_right);
}
painter->restore();
}
diff --git a/ui/qt/sequence_dialog.cpp b/ui/qt/sequence_dialog.cpp
index f2776fca19..4bd5d9d548 100644
--- a/ui/qt/sequence_dialog.cpp
+++ b/ui/qt/sequence_dialog.cpp
@@ -27,6 +27,7 @@
#include "wsutil/nstime.h"
#include "wsutil/utf8_entities.h"
+#include "color_utils.h"
#include "progress_frame.h"
#include "sequence_diagram.h"
#include "wireshark_application.h"
@@ -37,6 +38,9 @@
#include <QPoint>
// To do:
+// - Add zoom controls.
+// - Limit dragging to valid ranges.
+// - Handle trackpad and mouse wheel scrolling.
// - Add UTF8 to text dump
// - Save to XMI? http://www.umlgraph.org/
// - Time: abs vs delta
@@ -46,8 +50,6 @@
// - Change line_style to seq_type (i.e. draw ACKs dashed)
// - Create WSGraph subclasses with common behavior.
// - Help button and text
-// - Diagram shrinks when you click on it on retina displays.
-// - Add zoom controls.
SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *info) :
WiresharkDialog(parent, cf),
@@ -55,7 +57,7 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
info_(info),
num_items_(0),
packet_num_(0),
- node_label_w_(20)
+ sequence_w_(1)
{
ui->setupUi(this);
loadGeometry(parent.width(), parent.height() * 4 / 5);
@@ -80,9 +82,32 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
sp->xAxis->setPadding(0);
sp->xAxis->setLabelPadding(0);
sp->xAxis->setTickLabelPadding(0);
+
+ QPen base_pen(ColorUtils::alphaBlend(palette().text(), palette().base(), 0.25));
+ base_pen.setWidthF(0.5);
+ sp->xAxis2->setBasePen(base_pen);
+ sp->yAxis->setBasePen(base_pen);
+ sp->yAxis2->setBasePen(base_pen);
+
sp->xAxis2->setVisible(true);
sp->yAxis2->setVisible(true);
+ key_text_ = new QCPItemText(sp);
+ key_text_->setText(tr("Time"));
+ sp->addItem(key_text_);
+
+ key_text_->setPositionAlignment(Qt::AlignRight | Qt::AlignBottom);
+ key_text_->position->setType(QCPItemPosition::ptAbsolute);
+ key_text_->setClipToAxisRect(false);
+
+ comment_text_ = new QCPItemText(sp);
+ comment_text_->setText(tr("Comment"));
+ sp->addItem(comment_text_);
+
+ comment_text_->setPositionAlignment(Qt::AlignLeft | Qt::AlignBottom);
+ comment_text_->position->setType(QCPItemPosition::ptAbsolute);
+ comment_text_->setClipToAxisRect(false);
+
one_em_ = QFontMetrics(sp->yAxis->labelFont()).height();
ui->horizontalScrollBar->setSingleStep(100 / one_em_);
ui->verticalScrollBar->setSingleStep(100 / one_em_);
@@ -134,8 +159,6 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
connect(this, SIGNAL(goToPacket(int)), seq_diagram_, SLOT(setSelectedPacket(int)));
disconnect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
-
- QTimer::singleShot(0, this, SLOT(fillDiagram()));
}
SequenceDialog::~SequenceDialog()
@@ -151,7 +174,7 @@ void SequenceDialog::updateWidgets()
void SequenceDialog::showEvent(QShowEvent *)
{
- resetAxes();
+ QTimer::singleShot(0, this, SLOT(fillDiagram()));
}
void SequenceDialog::resizeEvent(QResizeEvent *)
@@ -350,18 +373,8 @@ void SequenceDialog::fillDiagram()
seq_diagram_->setData(info_->sainfo());
}
- QFontMetrics vfm = QFontMetrics(sp->xAxis2->labelFont());
- char* addr_str;
- node_label_w_ = 0;
- for (guint i = 0; i < info_->sainfo()->num_nodes; i++) {
- addr_str = address_to_display(NULL, &(info_->sainfo()->nodes[i]));
- int label_w = vfm.width(addr_str);
- if (node_label_w_ < label_w) {
- node_label_w_ = label_w;
- }
- wmem_free(NULL, addr_str);
- }
- node_label_w_ = (node_label_w_ * 3 / 4) + one_em_;
+ QFontMetrics fm = QFontMetrics(sp->xAxis2->labelFont());
+ sequence_w_ = fm.height() * 15 ; // Arbitrary
mouseMoved(NULL);
resetAxes();
@@ -394,6 +407,7 @@ void SequenceDialog::resetAxes(bool keep_lower)
if (!info_->sainfo()) return;
QCustomPlot *sp = ui->sequencePlot;
+
// Allow space for labels on the top and port numbers on the left.
double top_pos = -1.0, left_pos = -0.5;
if (keep_lower) {
@@ -401,21 +415,42 @@ void SequenceDialog::resetAxes(bool keep_lower)
left_pos = sp->xAxis2->range().lower;
}
- double range_ratio = sp->xAxis2->axisRect()->width() / node_label_w_;
- sp->xAxis2->setRange(left_pos, range_ratio + left_pos);
+ double range_span = sp->viewport().width() / sequence_w_;
+ sp->xAxis2->setRange(left_pos, range_span + left_pos);
- range_ratio = sp->yAxis->axisRect()->height() / (one_em_ * 1.5);
- sp->yAxis->setRange(top_pos, range_ratio + top_pos);
+ range_span = sp->axisRect()->height() / (one_em_ * 1.5);
+ sp->yAxis->setRange(top_pos, range_span + top_pos);
double rmin = sp->xAxis2->range().size() / 2;
ui->horizontalScrollBar->setRange((rmin - 0.5) * 100, (info_->sainfo()->num_nodes - 0.5 - rmin) * 100);
xAxisChanged(sp->xAxis2->range());
+ ui->horizontalScrollBar->setValue(ui->horizontalScrollBar->minimum()); // Shouldn't be needed.
rmin = (sp->yAxis->range().size() / 2);
ui->verticalScrollBar->setRange((rmin - 1.0) * 100, (num_items_ - 0.5 - rmin) * 100);
yAxisChanged(sp->yAxis->range());
- sp->replot();
+ // It would be exceedingly handy if we could do one or both of the
+ // following:
+ // - Position an axis label above its axis inline with the tick labels.
+ // - Anchor a QCPItemText to one of the corners of a QCPAxis.
+ // Neither of those appear to be possible, so we first call replot in
+ // order to lay out our X axes, place our labels, the call replot again.
+ sp->replot(QCustomPlot::rpQueued);
+
+ QRect axis_rect = sp->axisRect()->rect();
+ key_text_->position->setCoords(axis_rect.left()
+ - sp->yAxis->padding()
+ - sp->yAxis->tickLabelPadding()
+ - sp->yAxis->offset(),
+ axis_rect.top());
+ comment_text_->position->setCoords(axis_rect.right()
+ + sp->yAxis2->padding()
+ + sp->yAxis2->tickLabelPadding()
+ + sp->yAxis2->offset(),
+ axis_rect.top());
+
+ sp->replot(QCustomPlot::rpHint);
}
void SequenceDialog::on_resetButton_clicked()
diff --git a/ui/qt/sequence_dialog.h b/ui/qt/sequence_dialog.h
index 59505583c6..e091b583b0 100644
--- a/ui/qt/sequence_dialog.h
+++ b/ui/qt/sequence_dialog.h
@@ -108,8 +108,10 @@ private:
int num_items_;
guint32 packet_num_;
double one_em_;
- int node_label_w_;
+ int sequence_w_;
QMenu ctx_menu_;
+ QCPItemText *key_text_;
+ QCPItemText *comment_text_;
void panAxes(int x_pixels, int y_pixels);
void resetAxes(bool keep_lower = false);