* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <QApplication>
#include <QDebug>
#include <QString>
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
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) {
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);
}
}
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_)
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();
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()
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;
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();
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_;
};
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)),
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)