]> sigrok.org Git - pulseview.git/blobdiff - pv/views/trace/decodetrace.cpp
DecoderOutput: Add basic view skeleton
[pulseview.git] / pv / views / trace / decodetrace.cpp
index 8ff00cd296ecb005a99dcbcc69219ee5023c67de..c7796efcf8618784fd463d9d5840b265ee77fe78 100644 (file)
@@ -31,6 +31,7 @@ extern "C" {
 
 #include <QAction>
 #include <QApplication>
+#include <QClipboard>
 #include <QComboBox>
 #include <QFileDialog>
 #include <QFormLayout>
@@ -101,6 +102,11 @@ DecodeTrace::DecodeTrace(pv::Session &session,
 {
        decode_signal_ = dynamic_pointer_cast<data::DecodeSignal>(base_);
 
+       GlobalSettings settings;
+       always_show_all_rows_ = settings.value(GlobalSettings::Key_Dec_AlwaysShowAllRows).toBool();
+
+       GlobalSettings::add_change_handler(this);
+
        // Determine shortest string we want to see displayed in full
        QFontMetrics m(QApplication::font());
        min_useful_label_width_ = m.width("XX"); // e.g. two hex characters
@@ -136,6 +142,11 @@ DecodeTrace::DecodeTrace(pv::Session &session,
        delayed_trace_updater_.setInterval(1000 / MaxTraceUpdateRate);
 }
 
+DecodeTrace::~DecodeTrace()
+{
+       GlobalSettings::remove_change_handler(this);
+}
+
 bool DecodeTrace::enabled() const
 {
        return true;
@@ -181,7 +192,7 @@ void DecodeTrace::paint_mid(QPainter &p, ViewItemPaintParams &pp)
        sample_range.second = min((int64_t)sample_range.second,
                decode_signal_->get_decoded_sample_count(current_segment_, false));
 
-       const vector<Row> rows = decode_signal_->visible_rows();
+       const vector<Row> rows = decode_signal_->get_rows(!always_show_all_rows_);
 
        visible_rows_.clear();
        for (const Row& row : rows) {
@@ -199,7 +210,7 @@ void DecodeTrace::paint_mid(QPainter &p, ViewItemPaintParams &pp)
                vector<Annotation> annotations;
                decode_signal_->get_annotation_subset(annotations, row,
                        current_segment_, sample_range.first, sample_range.second);
-               if (!annotations.empty()) {
+               if (always_show_all_rows_ || !annotations.empty()) {
                        draw_annotations(annotations, p, annotation_height, pp, y,
                                get_row_color(row.index()), row_title_width);
                        y += row_height_;
@@ -277,6 +288,8 @@ void DecodeTrace::update_stack_button()
                        connect(decoder_menu, SIGNAL(decoder_selected(srd_decoder*)),
                                this, SLOT(on_stack_decoder(srd_decoder*)));
 
+                       decoder_menu->setStyleSheet("QMenu { menu-scrollable: 1; }");
+
                        stack_button_->setMenu(decoder_menu);
                        stack_button_->show();
                        return;
@@ -370,9 +383,12 @@ QMenu* DecodeTrace::create_view_context_menu(QWidget *parent, QPoint &click_pos)
                selected_row_ = nullptr;
        }
 
+       const View *const view = owner_->view();
+       assert(view);
+       QPoint pos = view->viewport()->mapFrom(parent, click_pos);
+
        // Default sample range is "from here"
-       const pair<uint64_t, uint64_t> sample_range =
-               get_view_sample_range(click_pos.x(), click_pos.x() + 1);
+       const pair<uint64_t, uint64_t> sample_range = get_view_sample_range(pos.x(), pos.x() + 1);
        selected_sample_range_ = make_pair(sample_range.first, numeric_limits<uint64_t>::max());
 
        if (decode_signal_->is_paused()) {
@@ -391,6 +407,13 @@ QMenu* DecodeTrace::create_view_context_menu(QWidget *parent, QPoint &click_pos)
                menu->addAction(pause);
        }
 
+       QAction *const copy_annotation_to_clipboard =
+               new QAction(tr("Copy annotation text to clipboard"), this);
+       copy_annotation_to_clipboard->setIcon(QIcon::fromTheme("edit-paste",
+               QIcon(":/icons/edit-paste.svg")));
+       connect(copy_annotation_to_clipboard, SIGNAL(triggered()), this, SLOT(on_copy_annotation_to_clipboard()));
+       menu->addAction(copy_annotation_to_clipboard);
+
        menu->addSeparator();
 
        QAction *const export_all_rows =
@@ -439,9 +462,6 @@ QMenu* DecodeTrace::create_view_context_menu(QWidget *parent, QPoint &click_pos)
        connect(export_row_with_cursor, SIGNAL(triggered()), this, SLOT(on_export_row_with_cursor()));
        menu->addAction(export_row_with_cursor);
 
-       const View *view = owner_->view();
-       assert(view);
-
        if (!view->cursors()->enabled()) {
                export_all_rows_with_cursor->setEnabled(false);
                export_row_with_cursor->setEnabled(false);
@@ -853,8 +873,6 @@ void DecodeTrace::hover_point_changed(const QPoint &hp)
 
        QString ann = get_annotation_at_point(hp);
 
-       assert(view);
-
        if (!row_height_ || ann.isEmpty()) {
                QToolTip::hideText();
                return;
@@ -1061,6 +1079,15 @@ void DecodeTrace::export_annotations(vector<Annotation> *annotations) const
        msg.exec();
 }
 
+void DecodeTrace::on_setting_changed(const QString &key, const QVariant &value)
+{
+       if (key == GlobalSettings::Key_Dec_AlwaysShowAllRows) {
+               visible_rows_.clear();
+               max_visible_rows_ = 0;
+               always_show_all_rows_ = value.toBool();
+       }
+}
+
 void DecodeTrace::on_new_annotations()
 {
        if (!delayed_trace_updater_.isActive())
@@ -1175,6 +1202,30 @@ void DecodeTrace::on_show_hide_decoder(int index)
                owner_->row_item_appearance_changed(false, true);
 }
 
+void DecodeTrace::on_copy_annotation_to_clipboard()
+{
+       using namespace pv::data::decode;
+
+       if (!selected_row_)
+               return;
+
+       vector<Annotation> *annotations = new vector<Annotation>();
+
+       decode_signal_->get_annotation_subset(*annotations, *selected_row_,
+               current_segment_, selected_sample_range_.first, selected_sample_range_.first);
+
+       if (annotations->empty())
+               return;
+
+       QClipboard *clipboard = QGuiApplication::clipboard();
+       clipboard->setText(annotations->front().annotations().front(), QClipboard::Clipboard);
+
+       if (clipboard->supportsSelection())
+               clipboard->setText(annotations->front().annotations().front(), QClipboard::Selection);
+
+       delete annotations;
+}
+
 void DecodeTrace::on_export_row()
 {
        selected_sample_range_ = make_pair(0, numeric_limits<uint64_t>::max());