diff --git a/tools/cabana/dbc/dbcfile.cc b/tools/cabana/dbc/dbcfile.cc index 8b4f98508c..c4025725ac 100644 --- a/tools/cabana/dbc/dbcfile.cc +++ b/tools/cabana/dbc/dbcfile.cc @@ -186,6 +186,19 @@ QStringList DBCFile::signalNames() const { return ret; } +int DBCFile::signalCount(const MessageId &id) const { + if (msgs.count(id.address) == 0) return 0; + return msgs.at(id.address).sigs.size(); +} + +int DBCFile::signalCount() const { + int total = 0; + for (auto const& [_, msg] : msgs) { + total += msg.sigs.size(); + } + return total; +} + int DBCFile::msgCount() const { return msgs.size(); } @@ -194,6 +207,10 @@ QString DBCFile::name() const { return name_; } +bool DBCFile::isEmpty() const { + return (signalCount() == 0) && name().isEmpty(); +} + void DBCFile::parseExtraInfo(const QString &content) { static QRegularExpression bo_regexp(R"(^BO_ (\w+) (\w+) *: (\w+) (\w+))"); static QRegularExpression sg_regexp(R"(^SG_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))"); diff --git a/tools/cabana/dbc/dbcfile.h b/tools/cabana/dbc/dbcfile.h index 082ee773b1..96fbe6a9f1 100644 --- a/tools/cabana/dbc/dbcfile.h +++ b/tools/cabana/dbc/dbcfile.h @@ -43,8 +43,11 @@ public: const cabana::Msg *msg(uint32_t address) const; const cabana::Msg* msg(const QString &name); QStringList signalNames() const; + int signalCount(const MessageId &id) const; + int signalCount() const; int msgCount() const; QString name() const; + bool isEmpty() const; QString filename; diff --git a/tools/cabana/dbc/dbcmanager.cc b/tools/cabana/dbc/dbcmanager.cc index 24803a303f..123d783986 100644 --- a/tools/cabana/dbc/dbcmanager.cc +++ b/tools/cabana/dbc/dbcmanager.cc @@ -180,6 +180,26 @@ QStringList DBCManager::signalNames() const { return ret; } +int DBCManager::signalCount(const MessageId &id) const { + auto sources_dbc_file = findDBCFile(id); + if (!sources_dbc_file) { + return 0; + } + + auto [_, dbc_file] = *sources_dbc_file; + return dbc_file->signalCount(id); +} + +int DBCManager::signalCount() const { + int ret = 0; + + for (auto &[_, dbc_file] : dbc_files) { + ret += dbc_file->signalCount(); + } + + return ret; +} + int DBCManager::msgCount() const { int ret = 0; @@ -194,6 +214,16 @@ int DBCManager::dbcCount() const { return dbc_files.size(); } +int DBCManager::nonEmptyDBCCount() const { + int cnt = 0; + for (auto &[_, dbc_file] : dbc_files) { + if (!dbc_file->isEmpty()) { + cnt++; + } + } + return cnt; +} + void DBCManager::updateSources(const SourceSet &s) { sources = s; } diff --git a/tools/cabana/dbc/dbcmanager.h b/tools/cabana/dbc/dbcmanager.h index f9af96516c..60d8a072ec 100644 --- a/tools/cabana/dbc/dbcmanager.h +++ b/tools/cabana/dbc/dbcmanager.h @@ -38,8 +38,11 @@ public: const cabana::Msg* msg(uint8_t source, const QString &name); QStringList signalNames() const; + int signalCount(const MessageId &id) const; + int signalCount() const; int msgCount() const; int dbcCount() const; + int nonEmptyDBCCount() const; std::optional> findDBCFile(const uint8_t source) const; std::optional> findDBCFile(const MessageId &id) const; diff --git a/tools/cabana/mainwin.cc b/tools/cabana/mainwin.cc index c979a20f16..5b6d436dca 100644 --- a/tools/cabana/mainwin.cc +++ b/tools/cabana/mainwin.cc @@ -232,6 +232,7 @@ void MainWindow::undoStackIndexChanged(int index) { prev_undostack_index = index; prev_undostack_count = count; autoSave(); + updateLoadSaveMenus(); } void MainWindow::undoStackCleanChanged(bool clean) { @@ -411,7 +412,7 @@ void MainWindow::saveFile() { if (!dbc_file->filename.isEmpty()) { dbc_file->save(); updateRecentFiles(dbc_file->filename); - } else { + } else if (!dbc_file->isEmpty()) { QString fn = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::cleanPath(settings.last_dir + "/untitled.dbc"), tr("DBC (*.dbc)")); if (!fn.isEmpty()) { dbc_file->saveAs(fn); @@ -426,22 +427,22 @@ void MainWindow::saveFile() { void MainWindow::saveAs() { // Assume only one file is open - assert(dbc()->dbcCount() > 0); - auto &[_, dbc_file] = dbc()->dbc_files.first(); - - QString fn = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::cleanPath(settings.last_dir + "/untitled.dbc"), tr("DBC (*.dbc)")); - if (!fn.isEmpty()) { - dbc_file->saveAs(fn); + for (auto &[s, dbc_file] : dbc()->dbc_files) { + if (dbc_file->isEmpty()) continue; + QString fn = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::cleanPath(settings.last_dir + "/untitled.dbc"), tr("DBC (*.dbc)")); + if (!fn.isEmpty()) { + dbc_file->saveAs(fn); + } } } void MainWindow::saveDBCToClipboard() { // Assume only one file is open - assert(dbc()->dbcCount() > 0); - - auto &[_, dbc_file] = dbc()->dbc_files.first(); - QGuiApplication::clipboard()->setText(dbc_file->generateDBC()); - QMessageBox::information(this, tr("Copy To Clipboard"), tr("DBC Successfully copied!")); + for (auto &[s, dbc_file] : dbc()->dbc_files) { + if (dbc_file->isEmpty()) continue; + QGuiApplication::clipboard()->setText(dbc_file->generateDBC()); + QMessageBox::information(this, tr("Copy To Clipboard"), tr("DBC Successfully copied!")); + } } void MainWindow::updateSources(const SourceSet &s) { @@ -450,17 +451,20 @@ void MainWindow::updateSources(const SourceSet &s) { } void MainWindow::updateLoadSaveMenus() { - if (dbc()->dbcCount() > 1) { + int cnt = dbc()->nonEmptyDBCCount(); + save_dbc->setEnabled(cnt > 0); + + if (cnt > 1) { save_dbc->setText(tr("Save %1 DBCs...").arg(dbc()->dbcCount())); } else { save_dbc->setText(tr("Save DBC...")); } // TODO: Support save as for multiple files - save_dbc_as->setEnabled(dbc()->dbcCount() == 1); + save_dbc_as->setEnabled(cnt == 1); // TODO: Support clipboard for multiple files - copy_dbc_to_clipboard->setEnabled(dbc()->dbcCount() == 1); + copy_dbc_to_clipboard->setEnabled(cnt == 1); QList sources_sorted = sources.toList();