|
|
|
@ -3,8 +3,12 @@ |
|
|
|
|
#include <QDialogButtonBox> |
|
|
|
|
#include <QFormLayout> |
|
|
|
|
#include <QHBoxLayout> |
|
|
|
|
#include <QRadioButton> |
|
|
|
|
#include <QScrollArea> |
|
|
|
|
#include <QVBoxLayout> |
|
|
|
|
|
|
|
|
|
#include "selfdrive/ui/qt/util.h" |
|
|
|
|
|
|
|
|
|
// SignalForm
|
|
|
|
|
|
|
|
|
|
SignalForm::SignalForm(const Signal &sig, QWidget *parent) : start_bit(sig.start_bit), QWidget(parent) { |
|
|
|
@ -93,6 +97,12 @@ SignalEdit::SignalEdit(int index, const QString &msg_id, const Signal &sig, QWid |
|
|
|
|
title->setStyleSheet(QString("font-weight:bold; color:%1").arg(getColor(index))); |
|
|
|
|
title_layout->addWidget(title, 1); |
|
|
|
|
|
|
|
|
|
QPushButton *seek_btn = new QPushButton("⌕"); |
|
|
|
|
seek_btn->setStyleSheet("font-weight:bold;font-size:20px"); |
|
|
|
|
seek_btn->setToolTip(tr("Find signal values")); |
|
|
|
|
seek_btn->setFixedSize(20, 20); |
|
|
|
|
title_layout->addWidget(seek_btn); |
|
|
|
|
|
|
|
|
|
QPushButton *plot_btn = new QPushButton("📈"); |
|
|
|
|
plot_btn->setToolTip(tr("Show Plot")); |
|
|
|
|
plot_btn->setFixedSize(20, 20); |
|
|
|
@ -124,13 +134,17 @@ SignalEdit::SignalEdit(int index, const QString &msg_id, const Signal &sig, QWid |
|
|
|
|
main_layout->addWidget(hline); |
|
|
|
|
|
|
|
|
|
QObject::connect(remove_btn, &QPushButton::clicked, this, &SignalEdit::remove); |
|
|
|
|
QObject::connect(title, &ElidedLabel::clicked, this, &SignalEdit::showFormClicked); |
|
|
|
|
QObject::connect(save_btn, &QPushButton::clicked, [=]() { |
|
|
|
|
QString new_name = form->getSignal().name.c_str(); |
|
|
|
|
title->setText(QString("%1. %2").arg(index + 1).arg(new_name)); |
|
|
|
|
emit save(); |
|
|
|
|
sig_name = new_name; |
|
|
|
|
}); |
|
|
|
|
QObject::connect(title, &ElidedLabel::clicked, this, &SignalEdit::showFormClicked); |
|
|
|
|
QObject::connect(seek_btn, &QPushButton::clicked, [this, msg_id, s = &sig]() { |
|
|
|
|
SignalFindDlg dlg(msg_id, s, this); |
|
|
|
|
dlg.exec(); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SignalEdit::setFormVisible(bool visible) { |
|
|
|
@ -159,3 +173,66 @@ AddSignalDialog::AddSignalDialog(const QString &id, int start_bit, int size, QWi |
|
|
|
|
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); |
|
|
|
|
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
SignalFindDlg::SignalFindDlg(const QString &id, const Signal *signal, QWidget *parent) : QDialog(parent) { |
|
|
|
|
setWindowTitle(tr("Find signal values")); |
|
|
|
|
QVBoxLayout *main_layout = new QVBoxLayout(this); |
|
|
|
|
|
|
|
|
|
QHBoxLayout *h = new QHBoxLayout(); |
|
|
|
|
h->addWidget(new QLabel(signal->name.c_str())); |
|
|
|
|
QComboBox *comp_box = new QComboBox(); |
|
|
|
|
comp_box->addItems({">", "=", "<"}); |
|
|
|
|
h->addWidget(comp_box); |
|
|
|
|
QLineEdit *value_edit = new QLineEdit("0", this); |
|
|
|
|
value_edit->setValidator( new QDoubleValidator(-500000, 500000, 6, this) ); |
|
|
|
|
h->addWidget(value_edit, 1); |
|
|
|
|
QPushButton *search_btn = new QPushButton(tr("Find"), this); |
|
|
|
|
h->addWidget(search_btn); |
|
|
|
|
main_layout->addLayout(h); |
|
|
|
|
|
|
|
|
|
QWidget *container = new QWidget(this); |
|
|
|
|
QVBoxLayout *signals_layout = new QVBoxLayout(container); |
|
|
|
|
QScrollArea *scroll = new QScrollArea(this); |
|
|
|
|
scroll->setWidget(container); |
|
|
|
|
scroll->setWidgetResizable(true); |
|
|
|
|
scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); |
|
|
|
|
main_layout->addWidget(scroll); |
|
|
|
|
|
|
|
|
|
QObject::connect(search_btn, &QPushButton::clicked, [=]() { |
|
|
|
|
clearLayout(signals_layout); |
|
|
|
|
|
|
|
|
|
CANMessages::FindFlags comp = CANMessages::EQ; |
|
|
|
|
if (comp_box->currentIndex() == 0) { |
|
|
|
|
comp = CANMessages::GT; |
|
|
|
|
} else if (comp_box->currentIndex() == 2) { |
|
|
|
|
comp = CANMessages::LT; |
|
|
|
|
} |
|
|
|
|
double value = value_edit->text().toDouble(); |
|
|
|
|
|
|
|
|
|
const int limit_results = 50; |
|
|
|
|
auto values = can->findSignalValues(id, signal, value, comp, limit_results); |
|
|
|
|
for (auto &v : values) { |
|
|
|
|
QHBoxLayout *item_layout = new QHBoxLayout(); |
|
|
|
|
item_layout->addWidget(new QLabel(QString::number(v.x(), 'f', 2))); |
|
|
|
|
item_layout->addWidget(new QLabel(QString::number(v.y()))); |
|
|
|
|
item_layout->addStretch(1); |
|
|
|
|
|
|
|
|
|
QPushButton *goto_btn = new QPushButton(tr("Goto"), this); |
|
|
|
|
QObject::connect(goto_btn, &QPushButton::clicked, [sec = v.x()]() { can->seekTo(sec); }); |
|
|
|
|
item_layout->addWidget(goto_btn); |
|
|
|
|
signals_layout->addLayout(item_layout); |
|
|
|
|
} |
|
|
|
|
if (values.size() == limit_results) { |
|
|
|
|
QFrame *hline = new QFrame(); |
|
|
|
|
hline->setFrameShape(QFrame::HLine); |
|
|
|
|
hline->setFrameShadow(QFrame::Sunken); |
|
|
|
|
signals_layout->addWidget(hline); |
|
|
|
|
QLabel *info = new QLabel(tr("Only display the first %1 results").arg(limit_results)); |
|
|
|
|
info->setAlignment(Qt::AlignCenter); |
|
|
|
|
signals_layout->addWidget(info); |
|
|
|
|
} |
|
|
|
|
if (values.size() * 30 > container->height()) { |
|
|
|
|
scroll->setFixedHeight(std::min(values.size() * 30, 300)); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|