|
|
@ -1,12 +1,11 @@ |
|
|
|
#include "tools/cabana/signaledit.h" |
|
|
|
#include "tools/cabana/signaledit.h" |
|
|
|
|
|
|
|
|
|
|
|
#include <QDialogButtonBox> |
|
|
|
|
|
|
|
#include <QDoubleValidator> |
|
|
|
#include <QDoubleValidator> |
|
|
|
#include <QFormLayout> |
|
|
|
#include <QFormLayout> |
|
|
|
#include <QHBoxLayout> |
|
|
|
#include <QHBoxLayout> |
|
|
|
#include <QMessageBox> |
|
|
|
|
|
|
|
#include <QRadioButton> |
|
|
|
|
|
|
|
#include <QScrollArea> |
|
|
|
#include <QScrollArea> |
|
|
|
|
|
|
|
#include <QTimer> |
|
|
|
|
|
|
|
#include <QToolBar> |
|
|
|
#include <QVBoxLayout> |
|
|
|
#include <QVBoxLayout> |
|
|
|
|
|
|
|
|
|
|
|
#include "selfdrive/ui/qt/util.h" |
|
|
|
#include "selfdrive/ui/qt/util.h" |
|
|
@ -15,7 +14,6 @@ |
|
|
|
|
|
|
|
|
|
|
|
SignalForm::SignalForm(QWidget *parent) : QWidget(parent) { |
|
|
|
SignalForm::SignalForm(QWidget *parent) : QWidget(parent) { |
|
|
|
QFormLayout *form_layout = new QFormLayout(this); |
|
|
|
QFormLayout *form_layout = new QFormLayout(this); |
|
|
|
form_layout->setContentsMargins(0, 0, 0, 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
name = new QLineEdit(); |
|
|
|
name = new QLineEdit(); |
|
|
|
form_layout->addRow(tr("Name"), name); |
|
|
|
form_layout->addRow(tr("Name"), name); |
|
|
@ -58,6 +56,13 @@ SignalForm::SignalForm(QWidget *parent) : QWidget(parent) { |
|
|
|
form_layout->addRow(tr("Maximum value"), max_val); |
|
|
|
form_layout->addRow(tr("Maximum value"), max_val); |
|
|
|
val_desc = new QLineEdit(); |
|
|
|
val_desc = new QLineEdit(); |
|
|
|
form_layout->addRow(tr("Value descriptions"), val_desc); |
|
|
|
form_layout->addRow(tr("Value descriptions"), val_desc); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(name, &QLineEdit::textEdited, this, &SignalForm::changed); |
|
|
|
|
|
|
|
QObject::connect(factor, &QLineEdit::textEdited, this, &SignalForm::changed); |
|
|
|
|
|
|
|
QObject::connect(offset, &QLineEdit::textEdited, this, &SignalForm::changed); |
|
|
|
|
|
|
|
QObject::connect(sign, SIGNAL(activated(int)), SIGNAL(changed())); |
|
|
|
|
|
|
|
QObject::connect(endianness, SIGNAL(activated(int)), SIGNAL(changed())); |
|
|
|
|
|
|
|
QObject::connect(size, SIGNAL(valueChanged(int)), SIGNAL(changed())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SignalEdit
|
|
|
|
// SignalEdit
|
|
|
@ -67,36 +72,25 @@ SignalEdit::SignalEdit(int index, QWidget *parent) : form_idx(index), QWidget(pa |
|
|
|
main_layout->setContentsMargins(0, 0, 0, 0); |
|
|
|
main_layout->setContentsMargins(0, 0, 0, 0); |
|
|
|
|
|
|
|
|
|
|
|
// title bar
|
|
|
|
// title bar
|
|
|
|
QHBoxLayout *title_layout = new QHBoxLayout(); |
|
|
|
auto toolbar = new QToolBar(this); |
|
|
|
|
|
|
|
toolbar->setStyleSheet("QToolButton {width:15px;height:15px;font-size:15px}"); |
|
|
|
icon = new QLabel(); |
|
|
|
icon = new QLabel(); |
|
|
|
title_layout->addWidget(icon); |
|
|
|
toolbar->addWidget(icon); |
|
|
|
title = new ElidedLabel(this); |
|
|
|
title = new ElidedLabel(this); |
|
|
|
|
|
|
|
title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); |
|
|
|
title->setStyleSheet(QString("font-weight:bold; color:%1").arg(getColor(index))); |
|
|
|
title->setStyleSheet(QString("font-weight:bold; color:%1").arg(getColor(index))); |
|
|
|
title_layout->addWidget(title, 1); |
|
|
|
toolbar->addWidget(title); |
|
|
|
|
|
|
|
plot_btn = toolbar->addAction("", [this]() { emit showChart(msg_id, sig, !chart_opened); }); |
|
|
|
QPushButton *seek_btn = new QPushButton("⌕"); |
|
|
|
auto seek_btn = toolbar->addAction(QIcon::fromTheme("edit-find"), "", [this]() { SignalFindDlg(msg_id, sig, this).exec(); }); |
|
|
|
seek_btn->setStyleSheet("QPushButton{font-weight:bold;font-size:18px}"); |
|
|
|
|
|
|
|
seek_btn->setToolTip(tr("Find signal values")); |
|
|
|
seek_btn->setToolTip(tr("Find signal values")); |
|
|
|
seek_btn->setFixedSize(25, 25); |
|
|
|
auto remove_btn = toolbar->addAction("x", [this]() { emit remove(sig); }); |
|
|
|
title_layout->addWidget(seek_btn); |
|
|
|
remove_btn->setToolTip(tr("Remove signal")); |
|
|
|
|
|
|
|
main_layout->addWidget(toolbar); |
|
|
|
plot_btn = new QPushButton(this); |
|
|
|
|
|
|
|
plot_btn->setStyleSheet("QPushButton {font-size:18px}"); |
|
|
|
|
|
|
|
plot_btn->setFixedSize(25, 25); |
|
|
|
|
|
|
|
title_layout->addWidget(plot_btn); |
|
|
|
|
|
|
|
main_layout->addLayout(title_layout); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// signal form
|
|
|
|
// signal form
|
|
|
|
form_container = new QWidget(this); |
|
|
|
form = new SignalForm(this); |
|
|
|
QVBoxLayout *v_layout = new QVBoxLayout(form_container); |
|
|
|
form->setVisible(false); |
|
|
|
QHBoxLayout *h = new QHBoxLayout(); |
|
|
|
main_layout->addWidget(form); |
|
|
|
QPushButton *remove_btn = new QPushButton(tr("Remove Signal")); |
|
|
|
|
|
|
|
h->addWidget(remove_btn); |
|
|
|
|
|
|
|
h->addStretch(); |
|
|
|
|
|
|
|
QPushButton *save_btn = new QPushButton(tr("Save")); |
|
|
|
|
|
|
|
h->addWidget(save_btn); |
|
|
|
|
|
|
|
v_layout->addLayout(h); |
|
|
|
|
|
|
|
main_layout->addWidget(form_container); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// bottom line
|
|
|
|
// bottom line
|
|
|
|
QFrame *hline = new QFrame(); |
|
|
|
QFrame *hline = new QFrame(); |
|
|
@ -104,25 +98,22 @@ SignalEdit::SignalEdit(int index, QWidget *parent) : form_idx(index), QWidget(pa |
|
|
|
hline->setFrameShadow(QFrame::Sunken); |
|
|
|
hline->setFrameShadow(QFrame::Sunken); |
|
|
|
main_layout->addWidget(hline); |
|
|
|
main_layout->addWidget(hline); |
|
|
|
|
|
|
|
|
|
|
|
QObject::connect(remove_btn, &QPushButton::clicked, [this]() { emit remove(this->sig); }); |
|
|
|
QObject::connect(form, &SignalForm::changed, this, &SignalEdit::saveSignal); |
|
|
|
QObject::connect(title, &ElidedLabel::clicked, this, &SignalEdit::showFormClicked); |
|
|
|
QObject::connect(title, &ElidedLabel::clicked, this, &SignalEdit::showFormClicked); |
|
|
|
QObject::connect(save_btn, &QPushButton::clicked, this, &SignalEdit::saveSignal); |
|
|
|
|
|
|
|
QObject::connect(plot_btn, &QPushButton::clicked, [this]() { emit showChart(msg_id, sig, !chart_opened); }); |
|
|
|
|
|
|
|
QObject::connect(seek_btn, &QPushButton::clicked, [this]() { |
|
|
|
|
|
|
|
SignalFindDlg dlg(msg_id, sig, this); |
|
|
|
|
|
|
|
dlg.exec(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); |
|
|
|
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SignalEdit::setSignal(const QString &message_id, const Signal *signal, bool show_form) { |
|
|
|
void SignalEdit::setSignal(const QString &message_id, const Signal *signal) { |
|
|
|
msg_id = message_id; |
|
|
|
|
|
|
|
sig = signal; |
|
|
|
sig = signal; |
|
|
|
|
|
|
|
updateForm(msg_id == message_id && form->isVisible()); |
|
|
|
|
|
|
|
msg_id = message_id; |
|
|
|
title->setText(QString("%1. %2").arg(form_idx + 1).arg(sig->name.c_str())); |
|
|
|
title->setText(QString("%1. %2").arg(form_idx + 1).arg(sig->name.c_str())); |
|
|
|
setFormVisible(show_form); |
|
|
|
show(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SignalEdit::saveSignal() { |
|
|
|
void SignalEdit::saveSignal() { |
|
|
|
|
|
|
|
if (!sig || !form->changed_by_user) return; |
|
|
|
|
|
|
|
|
|
|
|
Signal s = *sig; |
|
|
|
Signal s = *sig; |
|
|
|
s.name = form->name->text().toStdString(); |
|
|
|
s.name = form->name->text().toStdString(); |
|
|
|
s.size = form->size->text().toInt(); |
|
|
|
s.size = form->size->text().toInt(); |
|
|
@ -148,33 +139,38 @@ void SignalEdit::saveSignal() { |
|
|
|
s.lsb = bigEndianStartBitsIndex(bigEndianBitIndex(s.start_bit) + s.size - 1); |
|
|
|
s.lsb = bigEndianStartBitsIndex(bigEndianBitIndex(s.start_bit) + s.size - 1); |
|
|
|
s.msb = s.start_bit; |
|
|
|
s.msb = s.start_bit; |
|
|
|
} |
|
|
|
} |
|
|
|
title->setText(QString("%1. %2").arg(form_idx + 1).arg(form->name->text())); |
|
|
|
if (s != *sig) |
|
|
|
emit save(this->sig, s); |
|
|
|
emit save(this->sig, s); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SignalEdit::setChartOpened(bool opened) { |
|
|
|
void SignalEdit::setChartOpened(bool opened) { |
|
|
|
plot_btn->setText(opened ? "☒" : "📈"); |
|
|
|
plot_btn->setText(opened ? "☒" : "📈"); |
|
|
|
plot_btn->setToolTip(opened ? tr("Close Plot") :tr("Show Plot")); |
|
|
|
plot_btn->setToolTip(opened ? tr("Close Plot") : tr("Show Plot")); |
|
|
|
chart_opened = opened; |
|
|
|
chart_opened = opened; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SignalEdit::setFormVisible(bool visible) { |
|
|
|
void SignalEdit::updateForm(bool visible) { |
|
|
|
if (visible) { |
|
|
|
if (visible && sig) { |
|
|
|
if (!form) { |
|
|
|
form->changed_by_user = false; |
|
|
|
form = new SignalForm(this); |
|
|
|
|
|
|
|
((QVBoxLayout *)form_container->layout())->insertWidget(0, form); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
form->name->setText(sig->name.c_str()); |
|
|
|
form->name->setText(sig->name.c_str()); |
|
|
|
form->size->setValue(sig->size); |
|
|
|
|
|
|
|
form->endianness->setCurrentIndex(sig->is_little_endian ? 0 : 1); |
|
|
|
form->endianness->setCurrentIndex(sig->is_little_endian ? 0 : 1); |
|
|
|
form->sign->setCurrentIndex(sig->is_signed ? 0 : 1); |
|
|
|
form->sign->setCurrentIndex(sig->is_signed ? 0 : 1); |
|
|
|
form->factor->setText(QString::number(sig->factor)); |
|
|
|
form->factor->setText(QString::number(sig->factor)); |
|
|
|
form->offset->setText(QString::number(sig->offset)); |
|
|
|
form->offset->setText(QString::number(sig->offset)); |
|
|
|
form->msb->setText(QString::number(sig->msb)); |
|
|
|
form->msb->setText(QString::number(sig->msb)); |
|
|
|
form->lsb->setText(QString::number(sig->lsb)); |
|
|
|
form->lsb->setText(QString::number(sig->lsb)); |
|
|
|
|
|
|
|
form->size->setValue(sig->size); |
|
|
|
|
|
|
|
form->changed_by_user = true; |
|
|
|
} |
|
|
|
} |
|
|
|
form_container->setVisible(visible); |
|
|
|
form->setVisible(visible); |
|
|
|
icon->setText(visible ? "▼" : ">"); |
|
|
|
icon->setText(visible ? "▼ " : "> "); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SignalEdit::showFormClicked() { |
|
|
|
|
|
|
|
parentWidget()->setUpdatesEnabled(false); |
|
|
|
|
|
|
|
for (auto &edit : parentWidget()->findChildren<SignalEdit*>()) |
|
|
|
|
|
|
|
edit->updateForm(edit == this && !form->isVisible()); |
|
|
|
|
|
|
|
QTimer::singleShot(1, [this]() { parentWidget()->setUpdatesEnabled(true); }); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SignalEdit::signalHovered(const Signal *s) { |
|
|
|
void SignalEdit::signalHovered(const Signal *s) { |
|
|
@ -182,6 +178,13 @@ void SignalEdit::signalHovered(const Signal *s) { |
|
|
|
title->setStyleSheet(QString("font-weight:bold; color:%1").arg(color.name())); |
|
|
|
title->setStyleSheet(QString("font-weight:bold; color:%1").arg(color.name())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SignalEdit::hideEvent(QHideEvent *event) { |
|
|
|
|
|
|
|
msg_id = ""; |
|
|
|
|
|
|
|
sig = nullptr; |
|
|
|
|
|
|
|
updateForm(false); |
|
|
|
|
|
|
|
QWidget::hideEvent(event); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void SignalEdit::enterEvent(QEvent *event) { |
|
|
|
void SignalEdit::enterEvent(QEvent *event) { |
|
|
|
emit highlight(sig); |
|
|
|
emit highlight(sig); |
|
|
|
QWidget::enterEvent(event); |
|
|
|
QWidget::enterEvent(event); |
|
|
@ -204,7 +207,7 @@ SignalFindDlg::SignalFindDlg(const QString &id, const Signal *signal, QWidget *p |
|
|
|
comp_box->addItems({">", "=", "<"}); |
|
|
|
comp_box->addItems({">", "=", "<"}); |
|
|
|
h->addWidget(comp_box); |
|
|
|
h->addWidget(comp_box); |
|
|
|
QLineEdit *value_edit = new QLineEdit("0", this); |
|
|
|
QLineEdit *value_edit = new QLineEdit("0", this); |
|
|
|
value_edit->setValidator( new QDoubleValidator(-500000, 500000, 6, this) ); |
|
|
|
value_edit->setValidator(new QDoubleValidator(-500000, 500000, 6, this)); |
|
|
|
h->addWidget(value_edit, 1); |
|
|
|
h->addWidget(value_edit, 1); |
|
|
|
QPushButton *search_btn = new QPushButton(tr("Find"), this); |
|
|
|
QPushButton *search_btn = new QPushButton(tr("Find"), this); |
|
|
|
h->addWidget(search_btn); |
|
|
|
h->addWidget(search_btn); |
|
|
|