]> sigrok.org Git - pulseview.git/commitdiff
Implement MetadataObjMousePos and use it in the TabularDecView
authorSoeren Apel <redacted>
Thu, 30 Apr 2020 23:11:57 +0000 (01:11 +0200)
committerUwe Hermann <redacted>
Sun, 3 May 2020 15:20:55 +0000 (17:20 +0200)
pv/metadata_obj.cpp
pv/metadata_obj.hpp
pv/views/tabular_decoder/model.cpp
pv/views/tabular_decoder/view.cpp
pv/views/tabular_decoder/view.hpp
pv/views/trace/view.cpp

index b6e77461c0f706d1984cbdf97aff123242dbd8ff..3788dbc75907427dd69458b87475cc54f5274be6 100644 (file)
@@ -25,7 +25,8 @@ namespace pv {
 const char* MetadataObjectNames[MetadataObjectTypeCount] = {
        "main_view_range",
        "selection",
-       "time_marker"
+       "time_marker",
+       "mouse_pos"
 };
 
 const char* MetadataValueNames[MetadataValueTypeCount] = {
index fef77795173d0707531ac41fade8a41582439eeb..6837fef2b2879cbc8918722816db30a206ad5ef0 100644 (file)
@@ -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
 };
 
index c8692efb17d7125003b8989a2311b3b275a00b3d..938e6add3a6236a6e5cd3ef29fec26ed7029ebe7 100644 (file)
@@ -17,6 +17,7 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <QApplication>
 #include <QDebug>
 #include <QString>
 
@@ -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<const Annotation*>(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_)
index b4bb93de3086f88ce501787ea8c3996d5dfe84ed..3f1c3939c946c7bef1d69ba484e1ae6329208df6 100644 (file)
@@ -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()
index 7d25f700e3089376a12c64fecaed89672f7aa782..891c227cd8e6a6446af7b32aab7f1279483383f4 100644 (file)
@@ -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_;
 };
 
index 0a51a96fb5398a590997e558a9fc7427c9e3679b..69599b1bb1bd28a8ad767e474e56be3b7a9640a6 100644 (file)
@@ -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<TraceTreeItem>& 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<int64_t>();
+
+               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)