diff --git a/tools/cabana/binaryview.cc b/tools/cabana/binaryview.cc index 875bd034ec..ba50b101fc 100644 --- a/tools/cabana/binaryview.cc +++ b/tools/cabana/binaryview.cc @@ -11,7 +11,7 @@ // BinaryView -const int CELL_HEIGHT = 30; +const int CELL_HEIGHT = 26; BinaryView::BinaryView(QWidget *parent) : QTableView(parent) { model = new BinaryViewModel(this); @@ -105,15 +105,9 @@ void BinaryView::leaveEvent(QEvent *event) { } void BinaryView::setMessage(const QString &message_id) { - msg_id = message_id; model->setMessage(message_id); clearSelection(); updateState(); - updateGeometry(); -} - -void BinaryView::updateState() { - model->updateState(); } const Signal *BinaryView::getResizingSignal() const { @@ -176,6 +170,9 @@ void BinaryViewModel::setMessage(const QString &message_id) { items[idx].sigs.push_back(&dbc_msg->sigs[i]); } } + } else { + row_count = can->lastMessage(msg_id).dat.size(); + items.resize(row_count * column_count); } endResetModel(); diff --git a/tools/cabana/binaryview.h b/tools/cabana/binaryview.h index 0f58e9ed20..a907a673bf 100644 --- a/tools/cabana/binaryview.h +++ b/tools/cabana/binaryview.h @@ -57,10 +57,10 @@ class BinaryView : public QTableView { public: BinaryView(QWidget *parent = nullptr); void setMessage(const QString &message_id); - void updateState(); void highlight(const Signal *sig); - const Signal *hoveredSignal() const { return hovered_sig; } QSet getOverlappingSignals() const; + inline const Signal *hoveredSignal() const { return hovered_sig; } + inline void updateState() { model->updateState(); } signals: void signalHovered(const Signal *sig); @@ -75,7 +75,6 @@ private: void leaveEvent(QEvent *event) override; const Signal *getResizingSignal() const; - QString msg_id; QModelIndex anchor_index; BinaryViewModel *model; BinaryItemDelegate *delegate; diff --git a/tools/cabana/detailwidget.cc b/tools/cabana/detailwidget.cc index 9bbc442154..f3e3438229 100644 --- a/tools/cabana/detailwidget.cc +++ b/tools/cabana/detailwidget.cc @@ -31,7 +31,6 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart QFrame *title_frame = new QFrame(this); QVBoxLayout *frame_layout = new QVBoxLayout(title_frame); title_frame->setFrameShape(QFrame::StyledPanel); - title_frame->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); // message title QHBoxLayout *title_layout = new QHBoxLayout(); @@ -80,7 +79,6 @@ DetailWidget::DetailWidget(ChartsWidget *charts, QWidget *parent) : charts(chart // signals signals_container = new QWidget(this); signals_container->setLayout(new QVBoxLayout); - signals_container->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); container_layout->addWidget(signals_container); // history log @@ -147,32 +145,35 @@ void DetailWidget::setMessage(const QString &message_id) { void DetailWidget::dbcMsgChanged(int show_form_idx) { if (msg_id.isEmpty()) return; - warning_widget->hide(); + setUpdatesEnabled(false); QStringList warnings; + for (auto f : signal_list) f->hide(); - clearLayout(signals_container->layout()); - QString msg_name = tr("untitled"); - if (auto msg = dbc()->msg(msg_id)) { + const Msg *msg = dbc()->msg(msg_id); + if (msg) { for (int i = 0; i < msg->sigs.size(); ++i) { - auto form = new SignalEdit(i, msg_id, &(msg->sigs[i])); - form->setChartOpened(charts->isChartOpened(msg_id, &(msg->sigs[i]))); - signals_container->layout()->addWidget(form); - QObject::connect(form, &SignalEdit::showFormClicked, this, &DetailWidget::showForm); - QObject::connect(form, &SignalEdit::remove, this, &DetailWidget::removeSignal); - QObject::connect(form, &SignalEdit::save, this, &DetailWidget::saveSignal); - QObject::connect(form, &SignalEdit::highlight, binary_view, &BinaryView::highlight); - QObject::connect(binary_view, &BinaryView::signalHovered, form, &SignalEdit::signalHovered); - QObject::connect(form, &SignalEdit::showChart, [this, sig = &msg->sigs[i]](bool show) { charts->showChart(msg_id, sig, show); }); - if (i == show_form_idx) { - QTimer::singleShot(0, [=]() { emit form->showFormClicked(); }); + SignalEdit *form = i < signal_list.size() ? signal_list[i] : nullptr; + if (!form) { + form = new SignalEdit(i); + QObject::connect(form, &SignalEdit::showFormClicked, this, &DetailWidget::showForm); + QObject::connect(form, &SignalEdit::remove, this, &DetailWidget::removeSignal); + QObject::connect(form, &SignalEdit::save, this, &DetailWidget::saveSignal); + QObject::connect(form, &SignalEdit::highlight, binary_view, &BinaryView::highlight); + QObject::connect(binary_view, &BinaryView::signalHovered, form, &SignalEdit::signalHovered); + QObject::connect(form, &SignalEdit::showChart, charts, &ChartsWidget::showChart); + signals_container->layout()->addWidget(form); + signal_list.push_back(form); } + form->setSignal(msg_id, &(msg->sigs[i]), i == show_form_idx); + form->setChartOpened(charts->isChartOpened(msg_id, &(msg->sigs[i]))); + form->show(); } - msg_name = msg->name.c_str(); if (msg->size != can->lastMessage(msg_id).dat.size()) warnings.push_back(tr("Message size (%1) is incorrect.").arg(msg->size)); } + edit_btn->setVisible(true); - name_label->setText(msg_name); + name_label->setText(msg ? msg->name.c_str() : "untitled"); binary_view->setMessage(msg_id); history_log->setMessage(msg_id); @@ -183,10 +184,9 @@ void DetailWidget::dbcMsgChanged(int show_form_idx) { warnings.push_back(tr("%1 has overlapping bits.").arg(s->name.c_str())); } - if (!warnings.isEmpty()) { - warning_label->setText(warnings.join('\n')); - warning_widget->show(); - } + warning_label->setText(warnings.join('\n')); + warning_widget->setVisible(!warnings.isEmpty()); + setUpdatesEnabled(true); } void DetailWidget::updateState() { @@ -199,18 +199,15 @@ void DetailWidget::updateState() { void DetailWidget::showForm() { SignalEdit *sender = qobject_cast(QObject::sender()); - for (auto f : signals_container->findChildren()) { + setUpdatesEnabled(false); + for (auto f : signal_list) f->setFormVisible(f == sender && !f->isFormVisible()); - if (f == sender) - QTimer::singleShot(0, [=]() { scroll->ensureWidgetVisible(f); }); - } + QTimer::singleShot(1, [this]() { setUpdatesEnabled(true); }); } void DetailWidget::updateChartState(const QString &id, const Signal *sig, bool opened) { - if (id == msg_id) { - for (auto f : signals_container->findChildren()) - if (f->sig == sig) f->setChartOpened(opened); - } + for (auto f : signal_list) + if (f->msg_id == id && f->sig == sig) f->setChartOpened(opened); } void DetailWidget::editMsg() { @@ -265,7 +262,7 @@ void DetailWidget::saveSignal(const Signal *sig, const Signal &new_sig) { dbc()->updateSignal(msg_id, sig->name.c_str(), new_sig); // update binary view and history log - dbcMsgChanged(); + updateState(); } void DetailWidget::removeSignal(const Signal *sig) { diff --git a/tools/cabana/detailwidget.h b/tools/cabana/detailwidget.h index d8784f3f14..ce3468e472 100644 --- a/tools/cabana/detailwidget.h +++ b/tools/cabana/detailwidget.h @@ -50,4 +50,5 @@ private: BinaryView *binary_view; QScrollArea *scroll; ChartsWidget *charts; + QList signal_list; }; diff --git a/tools/cabana/signaledit.cc b/tools/cabana/signaledit.cc index ef0a85eba3..ee91887d0a 100644 --- a/tools/cabana/signaledit.cc +++ b/tools/cabana/signaledit.cc @@ -13,40 +13,37 @@ // SignalForm -SignalForm::SignalForm(const Signal &sig, QWidget *parent) : QWidget(parent) { +SignalForm::SignalForm(QWidget *parent) : QWidget(parent) { QFormLayout *form_layout = new QFormLayout(this); + form_layout->setContentsMargins(0, 0, 0, 0); - name = new QLineEdit(sig.name.c_str()); + name = new QLineEdit(); form_layout->addRow(tr("Name"), name); size = new QSpinBox(); size->setMinimum(1); - size->setValue(sig.size); form_layout->addRow(tr("Size"), size); endianness = new QComboBox(); endianness->addItems({"Little", "Big"}); - endianness->setCurrentIndex(sig.is_little_endian ? 0 : 1); form_layout->addRow(tr("Endianness"), endianness); - form_layout->addRow(tr("lsb"), new QLabel(QString::number(sig.lsb))); - form_layout->addRow(tr("msb"), new QLabel(QString::number(sig.msb))); + ; + form_layout->addRow(tr("lsb"), lsb = new QLabel()); + form_layout->addRow(tr("msb"), msb = new QLabel()); sign = new QComboBox(); sign->addItems({"Signed", "Unsigned"}); - sign->setCurrentIndex(sig.is_signed ? 0 : 1); form_layout->addRow(tr("sign"), sign); auto double_validator = new QDoubleValidator(this); factor = new QLineEdit(); factor->setValidator(double_validator); - factor->setText(QString::number(sig.factor)); form_layout->addRow(tr("Factor"), factor); offset = new QLineEdit(); offset->setValidator(double_validator); - offset->setText(QString::number(sig.offset)); form_layout->addRow(tr("Offset"), offset); // TODO: parse the following parameters in opendbc @@ -66,18 +63,15 @@ SignalForm::SignalForm(const Signal &sig, QWidget *parent) : QWidget(parent) { // SignalEdit -SignalEdit::SignalEdit(int index, const QString &msg_id, const Signal *sig, QWidget *parent) : msg_id(msg_id), sig(sig), form_idx(index), QWidget(parent) { +SignalEdit::SignalEdit(int index, QWidget *parent) : form_idx(index), QWidget(parent) { QVBoxLayout *main_layout = new QVBoxLayout(this); main_layout->setContentsMargins(0, 0, 0, 0); // title bar QHBoxLayout *title_layout = new QHBoxLayout(); - icon = new QLabel(">"); - icon->setStyleSheet("font-weight:bold"); + icon = new QLabel(); title_layout->addWidget(icon); title = new ElidedLabel(this); - title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); - title->setText(QString("%1. %2").arg(index + 1).arg(sig->name.c_str())); title->setStyleSheet(QString("font-weight:bold; color:%1").arg(getColor(index))); title_layout->addWidget(title, 1); @@ -96,9 +90,6 @@ SignalEdit::SignalEdit(int index, const QString &msg_id, const Signal *sig, QWid // signal form form_container = new QWidget(this); QVBoxLayout *v_layout = new QVBoxLayout(form_container); - form = new SignalForm(*sig, this); - v_layout->addWidget(form); - QHBoxLayout *h = new QHBoxLayout(); QPushButton *remove_btn = new QPushButton(tr("Remove Signal")); h->addWidget(remove_btn); @@ -106,8 +97,6 @@ SignalEdit::SignalEdit(int index, const QString &msg_id, const Signal *sig, QWid QPushButton *save_btn = new QPushButton(tr("Save")); h->addWidget(save_btn); v_layout->addLayout(h); - - form_container->setVisible(false); main_layout->addWidget(form_container); // bottom line @@ -119,11 +108,19 @@ SignalEdit::SignalEdit(int index, const QString &msg_id, const Signal *sig, QWid QObject::connect(remove_btn, &QPushButton::clicked, [this]() { emit remove(this->sig); }); 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(!chart_opened); }); - QObject::connect(seek_btn, &QPushButton::clicked, [this, msg_id]() { - SignalFindDlg dlg(msg_id, this->sig, this); + 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); +} + +void SignalEdit::setSignal(const QString &message_id, const Signal *signal, bool show_form) { + msg_id = message_id; + sig = signal; + title->setText(QString("%1. %2").arg(form_idx + 1).arg(sig->name.c_str())); + setFormVisible(show_form); } void SignalEdit::saveSignal() { @@ -152,6 +149,20 @@ void SignalEdit::setChartOpened(bool opened) { } void SignalEdit::setFormVisible(bool visible) { + if (visible) { + if (!form) { + form = new SignalForm(this); + ((QVBoxLayout *)form_container->layout())->insertWidget(0, form); + } + form->name->setText(sig->name.c_str()); + form->size->setValue(sig->size); + form->endianness->setCurrentIndex(sig->is_little_endian ? 0 : 1); + form->sign->setCurrentIndex(sig->is_signed ? 0 : 1); + form->factor->setText(QString::number(sig->factor)); + form->offset->setText(QString::number(sig->offset)); + form->msb->setText(QString::number(sig->msb)); + form->lsb->setText(QString::number(sig->lsb)); + } form_container->setVisible(visible); icon->setText(visible ? "▼" : ">"); } diff --git a/tools/cabana/signaledit.h b/tools/cabana/signaledit.h index e3d38d5b25..dce9d27479 100644 --- a/tools/cabana/signaledit.h +++ b/tools/cabana/signaledit.h @@ -14,9 +14,10 @@ class SignalForm : public QWidget { public: - SignalForm(const Signal &sig, QWidget *parent); + SignalForm(QWidget *parent); QLineEdit *name, *unit, *comment, *val_desc, *offset, *factor, *min_val, *max_val; + QLabel *lsb, *msb; QSpinBox *size; QComboBox *sign, *endianness; }; @@ -25,16 +26,18 @@ class SignalEdit : public QWidget { Q_OBJECT public: - SignalEdit(int index, const QString &msg_id, const Signal *sig, QWidget *parent = nullptr); + SignalEdit(int index, QWidget *parent = nullptr); + void setSignal(const QString &msg_id, const Signal *sig, bool show_form); void setChartOpened(bool opened); void setFormVisible(bool show); void signalHovered(const Signal *sig); inline bool isFormVisible() const { return form_container->isVisible(); } const Signal *sig = nullptr; + QString msg_id; signals: void highlight(const Signal *sig); - void showChart(bool show); + void showChart(const QString &name, const Signal *sig, bool show); void showFormClicked(); void remove(const Signal *sig); void save(const Signal *sig, const Signal &new_sig); @@ -44,12 +47,11 @@ protected: void leaveEvent(QEvent *event) override; void saveSignal(); - SignalForm *form; + SignalForm *form = nullptr; ElidedLabel *title; QWidget *form_container; QLabel *icon; int form_idx = 0; - QString msg_id; bool chart_opened = false; QPushButton *plot_btn; };