]> sigrok.org Git - pulseview.git/blobdiff - pv/views/trace/trace.cpp
Session: Fix issue #67 by improving error handling
[pulseview.git] / pv / views / trace / trace.cpp
index 5c854aed17e2aa3db35f4b668ec6d5ad4b09662d..4535a13efcb31f6e504d77963179e550c891349f 100644 (file)
@@ -49,19 +49,22 @@ const int Trace::LabelHitPadding = 2;
 
 const QColor Trace::BrightGrayBGColor = QColor(0, 0, 0, 10 * 255 / 100);
 const QColor Trace::DarkGrayBGColor = QColor(0, 0, 0, 15 * 255 / 100);
+const QColor Trace::ErrorBgColor = QColor(0xEF, 0x29, 0x29);
 
-Trace::Trace(shared_ptr<data::SignalBase> channel) :
-       base_(channel),
+Trace::Trace(shared_ptr<data::SignalBase> signal) :
+       base_(signal),
        axis_pen_(AxisPen),
        segment_display_mode_(ShowLastSegmentOnly),  // Will be overwritten by View
        current_segment_(0),
        popup_(nullptr),
        popup_form_(nullptr)
 {
-       connect(channel.get(), SIGNAL(name_changed(const QString&)),
+       connect(signal.get(), SIGNAL(name_changed(const QString&)),
                this, SLOT(on_name_changed(const QString&)));
-       connect(channel.get(), SIGNAL(color_changed(const QColor&)),
+       connect(signal.get(), SIGNAL(color_changed(const QColor&)),
                this, SLOT(on_color_changed(const QColor&)));
+       connect(signal.get(), SIGNAL(error_message_changed(const QString&)),
+               this, SLOT(on_error_message_changed(const QString&)));
 
        GlobalSettings::add_change_handler(this);
 
@@ -175,6 +178,26 @@ void Trace::paint_label(QPainter &p, const QRect &rect, bool hover)
                Qt::AlignCenter | Qt::AlignVCenter, base_->name());
 }
 
+void Trace::paint_error(QPainter &p, const ViewItemPaintParams &pp)
+{
+       const QString message = base_->get_error_message();
+
+       const int y = get_visual_y();
+
+       p.setPen(ErrorBgColor.darker());
+       p.setBrush(ErrorBgColor);
+
+       const QRectF bounding_rect = QRectF(pp.left(), INT_MIN / 2 + y, pp.right(), INT_MAX);
+
+       const QRectF text_rect = p.boundingRect(bounding_rect, Qt::AlignCenter, message);
+       const qreal r = text_rect.height() / 4;
+
+       p.drawRoundedRect(text_rect.adjusted(-r, -r, r, r), r, r, Qt::AbsoluteSize);
+
+       p.setPen(Qt::black);
+       p.drawText(text_rect, message);
+}
+
 QMenu* Trace::create_header_context_menu(QWidget *parent)
 {
        QMenu *const menu = ViewItem::create_header_context_menu(parent);
@@ -292,12 +315,13 @@ void Trace::paint_back(QPainter &p, ViewItemPaintParams &pp)
 
 void Trace::paint_axis(QPainter &p, ViewItemPaintParams &pp, int y)
 {
+       bool was_antialiased = p.testRenderHint(QPainter::Antialiasing);
        p.setRenderHint(QPainter::Antialiasing, false);
 
        p.setPen(axis_pen_);
        p.drawLine(QPointF(pp.left(), y), QPointF(pp.right(), y));
 
-       p.setRenderHint(QPainter::Antialiasing, true);
+       p.setRenderHint(QPainter::Antialiasing, was_antialiased);
 }
 
 void Trace::add_color_option(QWidget *parent, QFormLayout *form)
@@ -328,10 +352,11 @@ void Trace::paint_hover_marker(QPainter &p)
 
        const pair<int, int> extents = v_extents();
 
+       bool was_antialiased = p.testRenderHint(QPainter::Antialiasing);
        p.setRenderHint(QPainter::Antialiasing, false);
        p.drawLine(x, get_visual_y() + extents.first,
                x, get_visual_y() + extents.second);
-       p.setRenderHint(QPainter::Antialiasing, true);
+       p.setRenderHint(QPainter::Antialiasing, was_antialiased);
 }
 
 void Trace::create_popup_form()
@@ -344,13 +369,28 @@ void Trace::create_popup_form()
        // handled, leaving the parent popup_ time to handle the change.
        if (popup_form_) {
                QWidget *suicidal = new QWidget();
-               suicidal->setLayout(popup_form_);
+               suicidal->setLayout(popup_->layout());
                suicidal->deleteLater();
        }
 
        // Repopulate the popup
-       popup_form_ = new QFormLayout(popup_);
-       popup_->setLayout(popup_form_);
+       widgets::QWidthAdjustingScrollArea* scrollarea = new widgets::QWidthAdjustingScrollArea();
+       QWidget* scrollarea_content = new QWidget(scrollarea);
+
+       scrollarea->setWidget(scrollarea_content);
+       scrollarea->setWidgetResizable(true);
+       scrollarea->setContentsMargins(0, 0, 0, 0);
+       scrollarea->setFrameShape(QFrame::NoFrame);
+       scrollarea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+       scrollarea_content->setContentsMargins(0, 0, 0, 0);
+
+       popup_->setLayout(new QVBoxLayout());
+       popup_->layout()->addWidget(scrollarea);
+       popup_->layout()->setContentsMargins(0, 0, 0, 0);
+
+       popup_form_ = new QFormLayout(scrollarea_content);
+       popup_form_->setSizeConstraint(QLayout::SetMinAndMaxSize);
+
        populate_popup_form(popup_, popup_form_);
 }
 
@@ -385,6 +425,14 @@ void Trace::on_color_changed(const QColor &color)
                owner_->row_item_appearance_changed(true, true);
 }
 
+void Trace::on_error_message_changed(const QString &msg)
+{
+       (void)msg;
+
+       if (owner_)
+               owner_->row_item_appearance_changed(false, true);
+}
+
 void Trace::on_popup_closed()
 {
        popup_ = nullptr;
@@ -394,7 +442,8 @@ void Trace::on_popup_closed()
 void Trace::on_nameedit_changed(const QString &name)
 {
        /* This event handler notifies SignalBase that the name changed */
-       base_->set_name(name);
+       if (!name.isEmpty())
+               base_->set_name(name);
 }
 
 void Trace::on_coloredit_changed(const QColor &color)
@@ -411,7 +460,7 @@ void Trace::on_create_marker_here() const
        const Ruler *ruler = view->ruler();
        QPoint p = ruler->mapFrom(view, QPoint(context_menu_x_pos_, 0));
 
-       view->add_flag(ruler->get_time_from_x_pos(p.x()));
+       view->add_flag(ruler->get_absolute_time_from_x_pos(p.x()));
 }
 
 } // namespace trace