#include <QAction>
#include <QApplication>
+#include <QClipboard>
#include <QComboBox>
#include <QFileDialog>
#include <QFormLayout>
paint_hover_marker(p);
}
+void DecodeTrace::update_stack_button()
+{
+ const vector< shared_ptr<data::decode::Decoder> > &stack = decode_signal_->decoder_stack();
+
+ // 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();
+
+ if (d->outputs) {
+ pv::widgets::DecoderMenu *const decoder_menu =
+ new pv::widgets::DecoderMenu(stack_button_, (const char*)(d->outputs->data));
+ connect(decoder_menu, SIGNAL(decoder_selected(srd_decoder*)),
+ this, SLOT(on_stack_decoder(srd_decoder*)));
+
+ stack_button_->setMenu(decoder_menu);
+ stack_button_->show();
+ return;
+ }
+ }
+
+ // No decoders available for stacking
+ stack_button_->setMenu(nullptr);
+ stack_button_->hide();
+}
+
void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
{
using pv::data::decode::Decoder;
}
// Add stacking button
- pv::widgets::DecoderMenu *const decoder_menu =
- new pv::widgets::DecoderMenu(parent);
- connect(decoder_menu, SIGNAL(decoder_selected(srd_decoder*)),
- this, SLOT(on_stack_decoder(srd_decoder*)));
-
- QPushButton *const stack_button =
- new QPushButton(tr("Stack Decoder"), parent);
- stack_button->setMenu(decoder_menu);
- stack_button->setToolTip(tr("Stack a higher-level decoder on top of this one"));
+ stack_button_ = new QPushButton(tr("Stack Decoder"), parent);
+ stack_button_->setToolTip(tr("Stack a higher-level decoder on top of this one"));
+ update_stack_button();
QHBoxLayout *stack_button_box = new QHBoxLayout;
- stack_button_box->addWidget(stack_button, 0, Qt::AlignRight);
+ stack_button_box->addWidget(stack_button_, 0, Qt::AlignRight);
form->addRow(stack_button_box);
}
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()) {
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.png")));
+ 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 =
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);
QString ann = get_annotation_at_point(hp);
- assert(view);
-
if (!row_height_ || ann.isEmpty()) {
QToolTip::hideText();
return;
}
QMessageBox msg(owner_->view());
- msg.setText(tr("Error"));
- msg.setInformativeText(tr("File %1 could not be written to.").arg(file_name));
+ msg.setText(tr("Error") + "\n\n" + tr("File %1 could not be written to.").arg(file_name));
msg.setStandardButtons(QMessageBox::Ok);
msg.setIcon(QMessageBox::Warning);
msg.exec();
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());
+
+ delete annotations;
+}
+
void DecodeTrace::on_export_row()
{
selected_sample_range_ = make_pair(0, numeric_limits<uint64_t>::max());