using std::vector;
using pv::data::decode::Annotation;
+using pv::data::decode::AnnotationClass;
using pv::data::decode::Row;
using pv::data::decode::DecodeChannel;
using pv::data::DecodeSignal;
this, SLOT(on_show_hide_decoder(int)));
connect(&row_show_hide_mapper_, SIGNAL(mapped(int)),
this, SLOT(on_show_hide_row(int)));
+ connect(&class_show_hide_mapper_, SIGNAL(mapped(QWidget*)),
+ this, SLOT(on_show_hide_class(QWidget*)));
connect(&delayed_trace_updater_, SIGNAL(timeout()),
this, SLOT(on_delayed_trace_update()));
{
GlobalSettings::remove_change_handler(this);
- for (RowData& r : rows_) {
+ for (DecodeTraceRow& r : rows_) {
for (QCheckBox* cb : r.selectors)
delete cb;
return make_pair(-default_row_height_, default_row_height_);
unsigned int height = 0;
- for (const RowData& r : rows_)
+ for (const DecodeTraceRow& r : rows_)
if (r.currently_visible)
height += r.height;
sample_range.second = min((int64_t)sample_range.second,
decode_signal_->get_decoded_sample_count(current_segment_, false));
- for (RowData& r : rows_)
- r.currently_visible = false;
visible_rows_ = 0;
int y = get_visual_y();
- for (RowData& r : rows_) {
+ for (DecodeTraceRow& r : rows_) {
// If the row is hidden, we don't want to fetch annotations
- if ((!r.decode_row.decoder()->shown()) || (!r.decode_row.visible())) {
+ assert(r.decode_row);
+ assert(r.decode_row->decoder());
+ if ((!r.decode_row->decoder()->shown()) || (!r.decode_row->visible())) {
r.currently_visible = false;
continue;
}
// Show row if there are visible annotations or when user wants to see
// all rows that have annotations somewhere and this one is one of them
- size_t ann_count = decode_signal_->get_annotation_count(r.decode_row, current_segment_);
- r.currently_visible = !annotations.empty() || (always_show_all_rows_ && (ann_count > 0));
+ r.currently_visible = !annotations.empty();
+ if (!r.currently_visible) {
+ size_t ann_count = decode_signal_->get_annotation_count(r.decode_row, current_segment_);
+ r.currently_visible = always_show_all_rows_ && (ann_count > 0);
+ }
if (r.currently_visible) {
draw_annotations(annotations, p, annotation_height_, pp, y,
- get_row_color(r.decode_row.index()), r.title_width);
+ get_row_color(r.decode_row->index()), r.title_width);
y += r.height;
visible_rows_++;
}
{
unsigned int y = get_visual_y();
- for (const RowData& r : rows_) {
+ for (const DecodeTraceRow& r : rows_) {
if (!r.currently_visible)
continue;
const QRect text_rect(pp.left() + ArrowSize * 2, y - r.height / 2,
pp.right() - pp.left(), r.height);
- const QString h(r.decode_row.title());
+ const QString h(r.decode_row->title());
const int f = Qt::AlignLeft | Qt::AlignVCenter |
Qt::TextDontClip;
// Only show decoders in the menu that can be stacked onto the last one in the stack
if (!stack.empty()) {
- const srd_decoder* d = stack.back()->decoder();
+ const srd_decoder* d = stack.back()->get_srd_decoder();
if (d->outputs) {
pv::widgets::DecoderMenu *const decoder_menu =
}
selected_row_ = nullptr;
- const RowData* r = get_row_at_point(click_pos);
+ const DecodeTraceRow* r = get_row_at_point(click_pos);
if (r)
- selected_row_ = &(r->decode_row);
+ selected_row_ = r->decode_row;
const View *const view = owner_->view();
assert(view);
assert(owner_);
- RowData* hover_row = get_row_at_point(hp);
+ DecodeTraceRow* hover_row = get_row_at_point(hp);
// Row expansion marker handling
- for (RowData& r : rows_)
+ for (DecodeTraceRow& r : rows_)
r.expand_marker_highlighted = false;
if (hover_row) {
void DecodeTrace::mouse_left_press_event(const QMouseEvent* event)
{
// Handle row expansion marker
- for (RowData& r : rows_) {
+ for (DecodeTraceRow& r : rows_) {
if (!r.expand_marker_highlighted)
continue;
return color;
}
-unsigned int DecodeTrace::get_row_y(const RowData* row) const
+unsigned int DecodeTrace::get_row_y(const DecodeTraceRow* row) const
{
assert(row);
unsigned int y = get_visual_y();
- for (const RowData& r : rows_) {
+ for (const DecodeTraceRow& r : rows_) {
if (!r.currently_visible)
continue;
return y;
}
-RowData* DecodeTrace::get_row_at_point(const QPoint &point)
+DecodeTraceRow* DecodeTrace::get_row_at_point(const QPoint &point)
{
int y = get_visual_y() - (default_row_height_ / 2);
- for (RowData& r : rows_) {
+ for (DecodeTraceRow& r : rows_) {
if (!r.currently_visible)
continue;
const pair<uint64_t, uint64_t> sample_range =
get_view_sample_range(point.x(), point.x() + 1);
- const RowData* r = get_row_at_point(point);
+ const DecodeTraceRow* r = get_row_at_point(point);
if (!r)
return QString();
GlobalSettings settings;
assert(dec);
- const srd_decoder *const decoder = dec->decoder();
+ const srd_decoder *const decoder = dec->get_srd_decoder();
assert(decoder);
const bool decoder_deletable = index > 0;
const QString sample_range = QString("%1-%2") \
.arg(QString::number(ann.start_sample()), QString::number(ann.end_sample()));
- const QString class_name = quote + ann.row()->class_name() + quote;
+ const QString row_name = quote + ann.row()->description() + quote;
QString all_ann_text;
for (const QString &s : ann.annotations())
out_text = out_text.replace("%s", sample_range);
out_text = out_text.replace("%d",
quote + QString::fromUtf8(ann.row()->decoder()->name()) + quote);
- out_text = out_text.replace("%c", class_name);
+ out_text = out_text.replace("%r", row_name);
out_text = out_text.replace("%1", first_ann_text);
out_text = out_text.replace("%a", all_ann_text);
out_stream << out_text << '\n';
msg.exec();
}
-void DecodeTrace::update_rows()
+void DecodeTrace::initialize_row_widgets(DecodeTraceRow* r, unsigned int row_id)
{
- lock_guard<mutex> lock(row_modification_mutex_);
-
QFontMetrics m(QApplication::font());
QPalette header_palette = owner_->view()->palette();
QColor(0, 0, 0, ExpansionAreaAlpha));
}
- for (RowData& r : rows_)
+ const int w = m.boundingRect(r->decode_row->title()).width() + RowTitleMargin;
+ r->title_width = w;
+
+ r->container->resize(owner_->view()->viewport()->width() - r->container->pos().x(),
+ r->expanded_height - 2 * default_row_height_);
+ r->container->setVisible(false);
+
+ QVBoxLayout* vlayout = new QVBoxLayout();
+ r->container->setLayout(vlayout);
+
+ // Add header container with checkbox for this row
+ vlayout->addWidget(r->header_container);
+ vlayout->setContentsMargins(0, 0, 0, 0);
+ vlayout->setSpacing(0);
+ r->header_container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ r->header_container->setMinimumSize(0, default_row_height_);
+ r->header_container->setLayout(new QVBoxLayout());
+ r->header_container->layout()->setContentsMargins(10, 2, 0, 2);
+
+ r->header_container->setAutoFillBackground(true);
+ r->header_container->setPalette(header_palette);
+
+ QCheckBox* cb = new QCheckBox();
+ r->header_container->layout()->addWidget(cb);
+ cb->setText(tr("Show this row"));
+ cb->setChecked(r->decode_row->visible());
+
+ row_show_hide_mapper_.setMapping(cb, row_id);
+ connect(cb, SIGNAL(stateChanged(int)),
+ &row_show_hide_mapper_, SLOT(map()));
+
+ // Add selector container
+ vlayout->addWidget(r->selector_container);
+ r->selector_container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ r->selector_container->setMinimumSize(0, 3 * default_row_height_); // FIXME
+ r->selector_container->setLayout(new QHBoxLayout());
+
+ r->selector_container->setAutoFillBackground(true);
+ r->selector_container->setPalette(selector_palette);
+
+ // Add all classes that can be toggled
+ vector<AnnotationClass*> ann_classes = r->decode_row->ann_classes();
+
+ for (const AnnotationClass* ann_class : ann_classes) {
+ cb = new QCheckBox();
+ cb->setText(tr(ann_class->description));
+ cb->setChecked(ann_class->visible);
+
+ r->selector_container->layout()->addWidget(cb);
+
+ cb->setProperty("ann_class_ptr", QVariant::fromValue((void*)ann_class));
+ class_show_hide_mapper_.setMapping(cb, cb);
+ connect(cb, SIGNAL(stateChanged(int)),
+ &class_show_hide_mapper_, SLOT(map()));
+ }
+}
+
+void DecodeTrace::update_rows()
+{
+ lock_guard<mutex> lock(row_modification_mutex_);
+
+ for (DecodeTraceRow& r : rows_)
r.exists = false;
unsigned int row_id = 0;
- for (const Row& decode_row : decode_signal_->get_rows()) {
+ for (Row* decode_row : decode_signal_->get_rows()) {
// Find row in our list
auto r_it = find_if(rows_.begin(), rows_.end(),
- [&](RowData& r){ return r.decode_row == decode_row; });
+ [&](DecodeTraceRow& r){ return r.decode_row == decode_row; });
- RowData* r = nullptr;
+ DecodeTraceRow* r = nullptr;
if (r_it == rows_.end()) {
// Row doesn't exist yet, create and append it
- RowData nr;
+ DecodeTraceRow nr;
nr.decode_row = decode_row;
nr.height = default_row_height_;
nr.expanded_height = default_row_height_;
rows_.push_back(nr);
r = &rows_.back();
+ initialize_row_widgets(r, row_id);
} else
r = &(*r_it);
r->exists = true;
-
- const int w = m.boundingRect(r->decode_row.title()).width() + RowTitleMargin;
- r->title_width = w;
-
- r->container->resize(owner_->view()->viewport()->width() - r->container->pos().x(),
- r->expanded_height - 2 * default_row_height_);
- r->container->setVisible(false);
-
- QVBoxLayout* vlayout = new QVBoxLayout();
- r->container->setLayout(vlayout);
-
- // Add header container with checkbox for this row
- vlayout->addWidget(r->header_container);
- vlayout->setContentsMargins(0, 0, 0, 0);
- vlayout->setSpacing(0);
- r->header_container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- r->header_container->setMinimumSize(0, default_row_height_);
- r->header_container->setLayout(new QVBoxLayout());
- r->header_container->layout()->setContentsMargins(10, 2, 0, 2);
-
- r->header_container->setAutoFillBackground(true);
- r->header_container->setPalette(header_palette);
-
- QCheckBox* cb = new QCheckBox();
- r->header_container->layout()->addWidget(cb);
- cb->setText(tr("Show this row"));
- cb->setChecked(r->decode_row.visible());
-
- row_show_hide_mapper_.setMapping(cb, row_id);
- connect(cb, SIGNAL(stateChanged(int)),
- &row_show_hide_mapper_, SLOT(map()));
-
- // Add selector container
- vlayout->addWidget(r->selector_container);
- r->selector_container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- r->selector_container->setMinimumSize(0, 3 * default_row_height_); // FIXME
- r->selector_container->setLayout(new QVBoxLayout());
-
- r->selector_container->setAutoFillBackground(true);
- r->selector_container->setPalette(selector_palette);
-
-
- // Add all classes that can be toggled
-
row_id++;
}
} while (any_exists);
}
-void DecodeTrace::set_row_expanded(RowData* r)
+void DecodeTrace::set_row_expanded(DecodeTraceRow* r)
{
r->height = r->expanded_height;
r->expanding = false;
r->container->resize(owner_->view()->viewport()->width() - r->container->pos().x(),
r->height - 2 * default_row_height_);
+
+ max_visible_rows_ = 0;
}
-void DecodeTrace::set_row_collapsed(RowData* r)
+void DecodeTrace::set_row_collapsed(DecodeTraceRow* r)
{
r->height = default_row_height_;
r->collapsing = false;
r->container->resize(owner_->view()->viewport()->width() - r->container->pos().x(),
r->height - 2 * default_row_height_);
+
+ max_visible_rows_ = 0;
}
void DecodeTrace::update_expanded_rows()
{
- for (RowData& r : rows_) {
+ for (DecodeTraceRow& r : rows_) {
r.container->move(2 * ArrowSize,
get_row_y(&r) + default_row_height_);
owner_->row_item_appearance_changed(false, true);
}
-void DecodeTrace::on_show_hide_row(int index)
+void DecodeTrace::on_show_hide_row(int row_id)
{
- if (index >= (int)rows_.size())
+ if (row_id >= (int)rows_.size())
return;
- set_row_collapsed(&rows_[index]);
- rows_[index].decode_row.set_visible(!rows_[index].decode_row.visible());
+ set_row_collapsed(&rows_[row_id]);
+ rows_[row_id].decode_row->set_visible(!rows_[row_id].decode_row->visible());
// Force re-calculation of the trace height, see paint_mid()
max_visible_rows_ = 0;
owner_->row_item_appearance_changed(false, true);
}
+void DecodeTrace::on_show_hide_class(QWidget* sender)
+{
+ void* ann_class_ptr = sender->property("ann_class_ptr").value<void*>();
+ assert(ann_class_ptr);
+
+ AnnotationClass* ann_class = (AnnotationClass*)ann_class_ptr;
+ ann_class->visible = !ann_class->visible;
+
+ owner_->row_item_appearance_changed(false, true);
+}
+
void DecodeTrace::on_copy_annotation_to_clipboard()
{
using namespace pv::data::decode;
vector<Annotation> *annotations = new vector<Annotation>();
- decode_signal_->get_annotation_subset(*annotations, *selected_row_,
+ decode_signal_->get_annotation_subset(*annotations, selected_row_,
current_segment_, selected_sample_range_.first, selected_sample_range_.first);
if (annotations->empty())
vector<Annotation> *annotations = new vector<Annotation>();
- decode_signal_->get_annotation_subset(*annotations, *selected_row_,
+ decode_signal_->get_annotation_subset(*annotations, selected_row_,
current_segment_, selected_sample_range_.first, selected_sample_range_.second);
if (annotations->empty())
{
bool animation_finished = true;
- for (RowData& r : rows_) {
+ for (DecodeTraceRow& r : rows_) {
if (!(r.expanding || r.collapsing))
continue;