+void DecodeTrace::delete_pressed()
+{
+ on_delete();
+}
+
+void DecodeTrace::hover_point_changed(const QPoint &hp)
+{
+ Trace::hover_point_changed(hp);
+
+ assert(owner_);
+
+ RowData* hover_row = get_row_at_point(hp);
+
+ // Row expansion marker handling
+ for (RowData& r : rows_)
+ r.expand_marker_highlighted = false;
+
+ if (hover_row) {
+ int row_y = get_row_y(hover_row);
+ if ((hp.x() > 0) && (hp.x() < 2 * ArrowSize) &&
+ (hp.y() > (int)(row_y - ArrowSize)) && (hp.y() < (int)(row_y + ArrowSize)))
+ hover_row->expand_marker_highlighted = true;
+ }
+
+ // Tooltip handling
+ if (hp.x() > 0) {
+ QString ann = get_annotation_at_point(hp);
+
+ if (!ann.isEmpty()) {
+ QFontMetrics m(QToolTip::font());
+ const QRect text_size = m.boundingRect(QRect(), 0, ann);
+
+ // This is OS-specific and unfortunately we can't query it, so
+ // use an approximation to at least try to minimize the error.
+ const int padding = default_row_height_ + 8;
+
+ // Make sure the tool tip doesn't overlap with the mouse cursor.
+ // If it did, the tool tip would constantly hide and re-appear.
+ // We also push it up by one row so that it appears above the
+ // decode trace, not below.
+ QPoint p = hp;
+ p.setX(hp.x() - (text_size.width() / 2) - padding);
+
+ p.setY(get_row_y(hover_row) - default_row_height_ -
+ text_size.height() - padding);
+
+ const View *const view = owner_->view();
+ assert(view);
+ QToolTip::showText(view->viewport()->mapToGlobal(p), ann);
+
+ } else
+ QToolTip::hideText();
+
+ } else
+ QToolTip::hideText();
+}
+
+void DecodeTrace::mouse_left_press_event(const QMouseEvent* event)
+{
+ // Handle row expansion marker
+ for (RowData& r : rows_) {
+ if (!r.expand_marker_highlighted)
+ continue;
+
+ unsigned int y = get_row_y(&r);
+ if ((event->x() > 0) && (event->x() <= (int)(ArrowSize + 3)) &&
+ (event->y() > (int)(y - (default_row_height_ / 2))) &&
+ (event->y() <= (int)(y + (default_row_height_ / 2)))) {
+
+ if (r.expanded) {
+ r.collapsing = true;
+ r.expanded = false;
+ r.anim_shape = ArrowSize;
+ } else {
+ r.expanding = true;
+ r.anim_shape = 0;
+ r.container->setVisible(true);
+ }
+
+ r.animation_step = 0;
+ r.anim_height = r.height;
+
+ r.container->move(2 * ArrowSize,
+ get_row_y(&r) + default_row_height_);
+
+ animation_timer_.start();
+ }
+ }
+}
+