From: Soeren Apel Date: Thu, 30 Apr 2020 23:11:57 +0000 (+0200) Subject: Implement MetadataObjMousePos and use it in the TabularDecView X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=1c5211005b1c7682bf4597bfb20cf8b1937d792d;p=pulseview.git Implement MetadataObjMousePos and use it in the TabularDecView --- diff --git a/pv/metadata_obj.cpp b/pv/metadata_obj.cpp index b6e77461..3788dbc7 100644 --- a/pv/metadata_obj.cpp +++ b/pv/metadata_obj.cpp @@ -25,7 +25,8 @@ namespace pv { const char* MetadataObjectNames[MetadataObjectTypeCount] = { "main_view_range", "selection", - "time_marker" + "time_marker", + "mouse_pos" }; const char* MetadataValueNames[MetadataValueTypeCount] = { diff --git a/pv/metadata_obj.hpp b/pv/metadata_obj.hpp index fef77795..6837fef2 100644 --- a/pv/metadata_obj.hpp +++ b/pv/metadata_obj.hpp @@ -39,6 +39,8 @@ enum MetadataObjectType { MetadataObjMainViewRange, MetadataObjSelection, MetadataObjTimeMarker, + // --- Types below will not be saved/restored --- + MetadataObjMousePos, MetadataObjectTypeCount // Indicates how many metadata object types there are, must always be last }; diff --git a/pv/views/tabular_decoder/model.cpp b/pv/views/tabular_decoder/model.cpp index c8692efb..938e6add 100644 --- a/pv/views/tabular_decoder/model.cpp +++ b/pv/views/tabular_decoder/model.cpp @@ -17,6 +17,7 @@ * along with this program; if not, see . */ +#include #include #include @@ -47,6 +48,7 @@ AnnotationCollectionModel::AnnotationCollectionModel(QObject* parent) : prev_last_row_(0), start_index_(0), end_index_(0), + had_highlight_before_(false), hide_hidden_(false) { // TBD Maybe use empty columns as indentation levels to indicate stacked decoders @@ -58,6 +60,16 @@ AnnotationCollectionModel::AnnotationCollectionModel(QObject* parent) : header_data_.emplace_back(tr("Value")); // Column #5 } +int AnnotationCollectionModel::get_hierarchy_level(const Annotation* ann) const +{ + int level = 0; + + const unsigned int ann_stack_level = ann->row_data()->row()->decoder()->get_stack_level(); + level = (signal_->decoder_stack().size() - 1 - ann_stack_level); + + return level; +} + QVariant AnnotationCollectionModel::data_from_ann(const Annotation* ann, int index) const { switch (index) { @@ -91,18 +103,40 @@ QVariant AnnotationCollectionModel::data(const QModelIndex& index, int role) con if ((role == Qt::DisplayRole) || (role == Qt::ToolTipRole)) return data_from_ann(ann, index.column()); - if (role == Qt::BackgroundRole) { - int level = 0; + if (role == Qt::ForegroundRole) { + if (index.column() >= get_hierarchy_level(ann)) { + // Invert the text color if this cell is highlighted + const bool must_highlight = (highlight_sample_num_ > 0) && + ((int64_t)ann->start_sample() <= highlight_sample_num_) && + ((int64_t)ann->end_sample() >= highlight_sample_num_); + + if (must_highlight) { + if (GlobalSettings::current_theme_is_dark()) + return QApplication::palette().brush(QPalette::Window); + else + return QApplication::palette().brush(QPalette::WindowText); + } + } - const unsigned int ann_stack_level = ann->row_data()->row()->decoder()->get_stack_level(); - level = (signal_->decoder_stack().size() - 1 - ann_stack_level); + return QApplication::palette().brush(QPalette::WindowText); + } + if (role == Qt::BackgroundRole) { // Only use custom cell background color if column index reached the hierarchy level - if (index.column() >= level) { - if (GlobalSettings::current_theme_is_dark()) - return QBrush(ann->dark_color()); + if (index.column() >= get_hierarchy_level(ann)) { + + QColor color; + const bool must_highlight = (highlight_sample_num_ > 0) && + ((int64_t)ann->start_sample() <= highlight_sample_num_) && + ((int64_t)ann->end_sample() >= highlight_sample_num_); + + if (must_highlight) + color = ann->color(); else - return QBrush(ann->bright_color()); + color = GlobalSettings::current_theme_is_dark() ? + ann->dark_color() : ann->bright_color(); + + return QBrush(color); } } @@ -328,6 +362,43 @@ void AnnotationCollectionModel::update_annotations_without_hidden() all_annotations_without_hidden_.resize(count); } +void AnnotationCollectionModel::update_highlighted_rows(QModelIndex first, + QModelIndex last, int64_t sample_num) +{ + bool has_highlight = false; + + highlight_sample_num_ = sample_num; + + if (!dataset_ || dataset_->empty()) + return; + + if (sample_num >= 0) { + last = last.sibling(last.row() + 1, 0); + + // Check if there are any annotations visible in the table view that + // we would need to highlight - only then do we do so + QModelIndex index = first; + do { + const Annotation* ann = + static_cast(index.internalPointer()); + assert(ann); + + if (((int64_t)ann->start_sample() <= sample_num) && + ((int64_t)ann->end_sample() >= sample_num)) { + has_highlight = true; + break; + } + + index = index.sibling(index.row() + 1, 0); + } while (index != last); + } + + if (has_highlight || had_highlight_before_) + dataChanged(first, last); + + had_highlight_before_ = has_highlight; +} + void AnnotationCollectionModel::on_annotation_visibility_changed() { if (!hide_hidden_) diff --git a/pv/views/tabular_decoder/view.cpp b/pv/views/tabular_decoder/view.cpp index b4bb93de..3f1c3939 100644 --- a/pv/views/tabular_decoder/view.cpp +++ b/pv/views/tabular_decoder/view.cpp @@ -157,7 +157,7 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) : table_view_->setModel(model_); table_view_->setSelectionBehavior(QAbstractItemView::SelectRows); table_view_->setSelectionMode(QAbstractItemView::ContiguousSelection); - table_view_->setSortingEnabled(true); + table_view_->setSortingEnabled(false); table_view_->sortByColumn(0, Qt::AscendingOrder); const int font_height = QFontMetrics(QApplication::font()).height(); @@ -586,6 +586,14 @@ void View::on_metadata_object_changed(MetadataObject* obj, model_->set_sample_range(max((int64_t)0, start_sample), max((int64_t)0, end_sample)); } + + if (obj->type() == MetadataObjMousePos) { + QModelIndex first_visual_idx = table_view_->indexAt(table_view_->rect().topLeft()); + QModelIndex last_visual_idx = table_view_->indexAt(table_view_->rect().bottomLeft()); + + model_->update_highlighted_rows(first_visual_idx, last_visual_idx, + obj->value(MetadataValueStartSample).toLongLong()); + } } void View::perform_delayed_view_update() diff --git a/pv/views/tabular_decoder/view.hpp b/pv/views/tabular_decoder/view.hpp index 7d25f700..891c227c 100644 --- a/pv/views/tabular_decoder/view.hpp +++ b/pv/views/tabular_decoder/view.hpp @@ -63,6 +63,7 @@ class AnnotationCollectionModel : public QAbstractTableModel public: AnnotationCollectionModel(QObject* parent = nullptr); + int get_hierarchy_level(const Annotation* ann) const; QVariant data_from_ann(const Annotation* ann, int index) const; QVariant data(const QModelIndex& index, int role) const override; Qt::ItemFlags flags(const QModelIndex& index) const override; @@ -82,6 +83,8 @@ public: void set_hide_hidden(bool hide_hidden); void update_annotations_without_hidden(); + void update_highlighted_rows(QModelIndex first, QModelIndex last, + int64_t sample_num); private Q_SLOTS: void on_annotation_visibility_changed(); @@ -95,6 +98,8 @@ private: uint32_t prev_segment_; uint64_t prev_last_row_; uint64_t start_sample_, end_sample_, start_index_, end_index_; + int64_t highlight_sample_num_; + bool had_highlight_before_; bool hide_hidden_; }; diff --git a/pv/views/trace/view.cpp b/pv/views/trace/view.cpp index 0a51a96f..69599b1b 100644 --- a/pv/views/trace/view.cpp +++ b/pv/views/trace/view.cpp @@ -184,9 +184,10 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) : GlobalSettings::add_change_handler(this); // Set up metadata objects and event handlers - if (is_main_view) + if (is_main_view) { session_.metadata_obj_manager()->create_object(MetadataObjMainViewRange); - + session_.metadata_obj_manager()->create_object(MetadataObjMousePos); + } // Set up UI event handlers connect(scrollarea_->horizontalScrollBar(), SIGNAL(valueChanged(int)), @@ -1572,8 +1573,19 @@ void View::update_hover_point() for (const shared_ptr& r : trace_tree_items) r->hover_point_changed(hover_point_); - // Notify any other listeners + // Notify this view's listeners hover_point_changed(hover_widget_, hover_point_); + + // Hover point is -1 when invalid and 0 for the header + if (hover_point_.x() > 0) { + // Notify global listeners + pv::util::Timestamp mouse_time = offset_ + hover_point_.x() * scale_; + int64_t sample_num = (mouse_time * session_.get_samplerate()).convert_to(); + + MetadataObject* md_obj = + session_.metadata_obj_manager()->find_object_by_type(MetadataObjMousePos); + md_obj->set_value(MetadataValueStartSample, QVariant((qlonglong)sample_num)); + } } void View::row_item_appearance_changed(bool label, bool content)