Cabana: add menu bar to main window (#26419)

* add menu bar

* show DBC name in title

* cleanup
old-commit-hash: fc872271ae
taco
Dean Lee 2 years ago committed by GitHub
parent 7dcbc23732
commit ca2faafdb9
  1. 1
      tools/cabana/chartswidget.cc
  2. 197
      tools/cabana/mainwin.cc
  3. 36
      tools/cabana/mainwin.h

@ -14,6 +14,7 @@
ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) { ChartsWidget::ChartsWidget(QWidget *parent) : QWidget(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(this); QVBoxLayout *main_layout = new QVBoxLayout(this);
main_layout->setContentsMargins(0, 0, 0, 0);
// toolbar // toolbar
QToolBar *toolbar = new QToolBar(tr("Charts"), this); QToolBar *toolbar = new QToolBar(tr("Charts"), this);

@ -1,14 +1,17 @@
#include "tools/cabana/mainwin.h" #include "tools/cabana/mainwin.h"
#include <QApplication> #include <QApplication>
#include <QClipboard>
#include <QCompleter> #include <QCompleter>
#include <QDialogButtonBox>
#include <QFile> #include <QFile>
#include <QFileDialog> #include <QFileDialog>
#include <QFileInfo> #include <QFileInfo>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPushButton> #include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
#include <QScreen> #include <QScreen>
#include <QToolBar>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "tools/replay/util.h" #include "tools/replay/util.h"
@ -18,15 +21,13 @@ void qLogMessageHandler(QtMsgType type, const QMessageLogContext &context, const
if (main_win) emit main_win->showMessage(msg, 0); if (main_win) emit main_win->showMessage(msg, 0);
} }
MainWindow::MainWindow() : QWidget() { MainWindow::MainWindow() : QMainWindow() {
QVBoxLayout *main_layout = new QVBoxLayout(this); setWindowTitle("Cabana");
main_layout->setContentsMargins(11, 11, 11, 5); QWidget *central_widget = new QWidget(this);
QHBoxLayout *main_layout = new QHBoxLayout(central_widget);
main_layout->setContentsMargins(11, 11, 11, 0);
main_layout->setSpacing(0); main_layout->setSpacing(0);
QHBoxLayout *h_layout = new QHBoxLayout();
h_layout->setContentsMargins(0, 0, 0, 0);
main_layout->addLayout(h_layout);
splitter = new QSplitter(Qt::Horizontal, this); splitter = new QSplitter(Qt::Horizontal, this);
splitter->setHandleWidth(11); splitter->setHandleWidth(11);
@ -34,7 +35,6 @@ MainWindow::MainWindow() : QWidget() {
QWidget *messages_container = new QWidget(this); QWidget *messages_container = new QWidget(this);
QVBoxLayout *messages_layout = new QVBoxLayout(messages_container); QVBoxLayout *messages_layout = new QVBoxLayout(messages_container);
messages_layout->setContentsMargins(0, 0, 0, 0); messages_layout->setContentsMargins(0, 0, 0, 0);
QHBoxLayout *dbc_file_layout = new QHBoxLayout();
dbc_combo = new QComboBox(this); dbc_combo = new QComboBox(this);
auto dbc_names = dbc()->allDBCNames(); auto dbc_names = dbc()->allDBCNames();
for (const auto &name : dbc_names) { for (const auto &name : dbc_names) {
@ -42,21 +42,9 @@ MainWindow::MainWindow() : QWidget() {
} }
dbc_combo->model()->sort(0); dbc_combo->model()->sort(0);
dbc_combo->setEditable(true); dbc_combo->setEditable(true);
dbc_combo->setCurrentText(QString());
dbc_combo->setInsertPolicy(QComboBox::NoInsert); dbc_combo->setInsertPolicy(QComboBox::NoInsert);
dbc_combo->completer()->setCompletionMode(QCompleter::PopupCompletion); dbc_combo->completer()->setCompletionMode(QCompleter::PopupCompletion);
QFont font; messages_layout->addWidget(dbc_combo);
font.setBold(true);
dbc_combo->lineEdit()->setFont(font);
dbc_file_layout->addWidget(dbc_combo);
QPushButton *load_from_paste = new QPushButton(tr("Load from paste"), this);
dbc_file_layout->addWidget(load_from_paste);
dbc_file_layout->addStretch();
QPushButton *save_btn = new QPushButton(tr("Save DBC"), this);
dbc_file_layout->addWidget(save_btn);
messages_layout->addLayout(dbc_file_layout);
messages_widget = new MessagesWidget(this); messages_widget = new MessagesWidget(this);
messages_layout->addWidget(messages_widget); messages_layout->addWidget(messages_widget);
@ -65,8 +53,7 @@ MainWindow::MainWindow() : QWidget() {
charts_widget = new ChartsWidget(this); charts_widget = new ChartsWidget(this);
detail_widget = new DetailWidget(charts_widget, this); detail_widget = new DetailWidget(charts_widget, this);
splitter->addWidget(detail_widget); splitter->addWidget(detail_widget);
main_layout->addWidget(splitter);
h_layout->addWidget(splitter);
// right widgets // right widgets
QWidget *right_container = new QWidget(this); QWidget *right_container = new QWidget(this);
@ -74,35 +61,21 @@ MainWindow::MainWindow() : QWidget() {
r_layout = new QVBoxLayout(right_container); r_layout = new QVBoxLayout(right_container);
r_layout->setContentsMargins(11, 0, 0, 0); r_layout->setContentsMargins(11, 0, 0, 0);
QHBoxLayout *right_hlayout = new QHBoxLayout(); QHBoxLayout *right_hlayout = new QHBoxLayout();
QLabel *fingerprint_label = new QLabel(this); fingerprint_label = new QLabel(this);
right_hlayout->addWidget(fingerprint_label); right_hlayout->addWidget(fingerprint_label, 0, Qt::AlignLeft);
// TODO: click to select another route. // TODO: click to select another route.
right_hlayout->addWidget(new QLabel(can->route())); right_hlayout->addWidget(new QLabel(can->route()), 0, Qt::AlignRight);
QPushButton *settings_btn = new QPushButton("Settings");
right_hlayout->addWidget(settings_btn, 0, Qt::AlignRight);
r_layout->addLayout(right_hlayout); r_layout->addLayout(right_hlayout);
video_widget = new VideoWidget(this); video_widget = new VideoWidget(this);
r_layout->addWidget(video_widget, 0, Qt::AlignTop); r_layout->addWidget(video_widget, 0, Qt::AlignTop);
r_layout->addWidget(charts_widget); r_layout->addWidget(charts_widget);
main_layout->addWidget(right_container);
h_layout->addWidget(right_container); setCentralWidget(central_widget);
createActions();
// status bar createStatusBar();
status_bar = new QStatusBar(this);
status_bar->setFixedHeight(20);
status_bar->setContentsMargins(0, 0, 0, 0);
status_bar->setSizeGripEnabled(true);
progress_bar = new QProgressBar();
progress_bar->setRange(0, 100);
progress_bar->setTextVisible(true);
progress_bar->setFixedSize({230, 16});
progress_bar->setVisible(false);
status_bar->addPermanentWidget(progress_bar);
main_layout->addWidget(status_bar);
qRegisterMetaType<uint64_t>("uint64_t"); qRegisterMetaType<uint64_t>("uint64_t");
qRegisterMetaType<ReplyMsgType>("ReplyMsgType"); qRegisterMetaType<ReplyMsgType>("ReplyMsgType");
@ -122,35 +95,65 @@ MainWindow::MainWindow() : QWidget() {
} }
QObject::connect(dbc_combo, SIGNAL(activated(const QString &)), SLOT(loadDBCFromName(const QString &))); QObject::connect(dbc_combo, SIGNAL(activated(const QString &)), SLOT(loadDBCFromName(const QString &)));
QObject::connect(load_from_paste, &QPushButton::clicked, this, &MainWindow::loadDBCFromPaste); QObject::connect(this, &MainWindow::showMessage, statusBar(), &QStatusBar::showMessage);
QObject::connect(save_btn, &QPushButton::clicked, this, &MainWindow::saveDBC);
QObject::connect(this, &MainWindow::showMessage, status_bar, &QStatusBar::showMessage);
QObject::connect(this, &MainWindow::updateProgressBar, this, &MainWindow::updateDownloadProgress); QObject::connect(this, &MainWindow::updateProgressBar, this, &MainWindow::updateDownloadProgress);
QObject::connect(messages_widget, &MessagesWidget::msgSelectionChanged, detail_widget, &DetailWidget::setMessage); QObject::connect(messages_widget, &MessagesWidget::msgSelectionChanged, detail_widget, &DetailWidget::setMessage);
QObject::connect(charts_widget, &ChartsWidget::dock, this, &MainWindow::dockCharts); QObject::connect(charts_widget, &ChartsWidget::dock, this, &MainWindow::dockCharts);
QObject::connect(charts_widget, &ChartsWidget::rangeChanged, video_widget, &VideoWidget::rangeChanged); QObject::connect(charts_widget, &ChartsWidget::rangeChanged, video_widget, &VideoWidget::rangeChanged);
QObject::connect(settings_btn, &QPushButton::clicked, this, &MainWindow::setOption);
QObject::connect(can, &CANMessages::streamStarted, this, &MainWindow::loadDBCFromFingerprint); QObject::connect(can, &CANMessages::streamStarted, this, &MainWindow::loadDBCFromFingerprint);
QObject::connect(can, &CANMessages::streamStarted, [=]() { fingerprint_label->setText(can->carFingerprint() ); }); QObject::connect(dbc(), &DBCManager::DBCFileChanged, [this]() {
dbc_combo->setCurrentText(QFileInfo(dbc()->name()).baseName());
setWindowTitle(tr("%1 - Cabana").arg(dbc()->name()));
});
}
void MainWindow::createActions() {
QMenu *file_menu = menuBar()->addMenu(tr("&File"));
file_menu->addAction(tr("Open DBC File..."), this, &MainWindow::loadDBCFromFile);
file_menu->addAction(tr("Load DBC From Clipboard"), this, &MainWindow::loadDBCFromClipboard);
file_menu->addSeparator();
file_menu->addAction(tr("Save DBC As..."), this, &MainWindow::saveDBCToFile);
file_menu->addAction(tr("Copy DBC To Clipboard"), this, &MainWindow::saveDBCToClipboard);
file_menu->addSeparator();
file_menu->addAction(tr("Settings..."), this, &MainWindow::setOption);
QMenu *help_menu = menuBar()->addMenu(tr("&Help"));
help_menu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
}
void MainWindow::createStatusBar() {
progress_bar = new QProgressBar();
progress_bar->setRange(0, 100);
progress_bar->setTextVisible(true);
progress_bar->setFixedSize({230, 16});
progress_bar->setVisible(false);
statusBar()->addPermanentWidget(progress_bar);
} }
void MainWindow::loadDBCFromName(const QString &name) { void MainWindow::loadDBCFromName(const QString &name) {
if (name != dbc()->name()) { if (name != dbc()->name())
dbc()->open(name); dbc()->open(name);
dbc_combo->setCurrentText(name);
}
} }
void MainWindow::loadDBCFromPaste() { void MainWindow::loadDBCFromFile() {
LoadDBCDialog dlg(this); QString file_name = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::homePath(), "DBC (*.dbc)");
if (dlg.exec()) { if (!file_name.isEmpty()) {
dbc()->open("from paste", dlg.dbc_edit->toPlainText()); QFile file(file_name);
dbc_combo->setCurrentText("loaded from paste"); if (file.open(QIODevice::ReadOnly)) {
auto dbc_name = QFileInfo(file_name).baseName();
dbc()->open(dbc_name, file.readAll());
}
} }
} }
void MainWindow::loadDBCFromClipboard() {
QString dbc_str = QGuiApplication::clipboard()->text();
dbc()->open("From Clipboard", dbc_str);
QMessageBox::information(this, tr("Load From Clipboard"), tr("DBC Successfully Loaded!"));
}
void MainWindow::loadDBCFromFingerprint() { void MainWindow::loadDBCFromFingerprint() {
auto fingerprint = can->carFingerprint(); auto fingerprint = can->carFingerprint();
fingerprint_label->setText(fingerprint);
if (!fingerprint.isEmpty() && dbc()->name().isEmpty()) { if (!fingerprint.isEmpty() && dbc()->name().isEmpty()) {
auto dbc_name = fingerprint_to_dbc[fingerprint]; auto dbc_name = fingerprint_to_dbc[fingerprint];
if (dbc_name != QJsonValue::Undefined) { if (dbc_name != QJsonValue::Undefined) {
@ -159,14 +162,23 @@ void MainWindow::loadDBCFromFingerprint() {
} }
} }
void MainWindow::saveDBC() { void MainWindow::saveDBCToFile() {
SaveDBCDialog dlg(this); QString file_name = QFileDialog::getSaveFileName(this, tr("Save File"),
dlg.dbc_edit->setText(dbc()->generateDBC()); QDir::homePath() + "/untitled.dbc", tr("DBC (*.dbc)"));
dlg.exec(); if (!file_name.isEmpty()) {
QFile file(file_name);
if (file.open(QIODevice::WriteOnly))
file.write(dbc()->generateDBC().toUtf8());
}
}
void MainWindow::saveDBCToClipboard() {
QGuiApplication::clipboard()->setText(dbc()->generateDBC());
QMessageBox::information(this, tr("Copy To Clipboard"), tr("DBC Successfully copied!"));
} }
void MainWindow::updateDownloadProgress(uint64_t cur, uint64_t total, bool success) { void MainWindow::updateDownloadProgress(uint64_t cur, uint64_t total, bool success) {
if (success && cur < total) { if (success && cur < total) {
progress_bar->setValue((cur / (double)total) * 100); progress_bar->setValue((cur / (double)total) * 100);
progress_bar->setFormat(tr("Downloading %p% (%1)").arg(formattedDataSize(total).c_str())); progress_bar->setFormat(tr("Downloading %p% (%1)").arg(formattedDataSize(total).c_str()));
progress_bar->show(); progress_bar->show();
@ -202,60 +214,3 @@ void MainWindow::setOption() {
SettingsDlg dlg(this); SettingsDlg dlg(this);
dlg.exec(); dlg.exec();
} }
// LoadDBCDialog
LoadDBCDialog::LoadDBCDialog(QWidget *parent) : QDialog(parent) {
QVBoxLayout *main_layout = new QVBoxLayout(this);
dbc_edit = new QTextEdit(this);
dbc_edit->setAcceptRichText(false);
dbc_edit->setPlaceholderText(tr("paste DBC file here"));
main_layout->addWidget(dbc_edit);
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
main_layout->addWidget(buttonBox);
setMinimumSize({640, 480});
QObject::connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
QObject::connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
}
// SaveDBCDialog
SaveDBCDialog::SaveDBCDialog(QWidget *parent) : QDialog(parent) {
setWindowTitle(tr("Save DBC"));
QVBoxLayout *main_layout = new QVBoxLayout(this);
dbc_edit = new QTextEdit(this);
dbc_edit->setAcceptRichText(false);
main_layout->addWidget(dbc_edit);
QPushButton *copy_to_clipboard = new QPushButton(tr("Copy To Clipboard"), this);
QPushButton *save_as = new QPushButton(tr("Save As"), this);
QHBoxLayout *btn_layout = new QHBoxLayout();
btn_layout->addStretch();
btn_layout->addWidget(copy_to_clipboard);
btn_layout->addWidget(save_as);
main_layout->addLayout(btn_layout);
setMinimumSize({640, 480});
QObject::connect(copy_to_clipboard, &QPushButton::clicked, this, &SaveDBCDialog::copytoClipboard);
QObject::connect(save_as, &QPushButton::clicked, this, &SaveDBCDialog::saveAs);
}
void SaveDBCDialog::copytoClipboard() {
dbc_edit->selectAll();
dbc_edit->copy();
QDialog::accept();
}
void SaveDBCDialog::saveAs() {
QString file_name = QFileDialog::getSaveFileName(this, tr("Save File"),
QDir::homePath() + "/untitled.dbc", tr("DBC (*.dbc)"));
if (!file_name.isEmpty()) {
QFile file(file_name);
if (file.open(QIODevice::WriteOnly)) {
file.write(dbc_edit->toPlainText().toUtf8());
}
QDialog::accept();
}
}

@ -1,37 +1,40 @@
#pragma once #pragma once
#include <QComboBox> #include <QComboBox>
#include <QDialog>
#include <QJsonDocument> #include <QJsonDocument>
#include <QMainWindow>
#include <QProgressBar> #include <QProgressBar>
#include <QSplitter> #include <QSplitter>
#include <QStatusBar> #include <QStatusBar>
#include <QTextEdit>
#include "tools/cabana/chartswidget.h" #include "tools/cabana/chartswidget.h"
#include "tools/cabana/detailwidget.h" #include "tools/cabana/detailwidget.h"
#include "tools/cabana/messageswidget.h" #include "tools/cabana/messageswidget.h"
#include "tools/cabana/videowidget.h" #include "tools/cabana/videowidget.h"
class MainWindow : public QWidget { class MainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
public: public:
MainWindow(); MainWindow();
void dockCharts(bool dock); void dockCharts(bool dock);
void showStatusMessage(const QString &msg, int timeout = 0) { status_bar->showMessage(msg, timeout); } void showStatusMessage(const QString &msg, int timeout = 0) { statusBar()->showMessage(msg, timeout); }
public slots: public slots:
void loadDBCFromName(const QString &name); void loadDBCFromName(const QString &name);
void loadDBCFromFingerprint(); void loadDBCFromFingerprint();
void loadDBCFromPaste(); void loadDBCFromFile();
void saveDBC(); void loadDBCFromClipboard();
void saveDBCToFile();
void saveDBCToClipboard();
signals: signals:
void showMessage(const QString &msg, int timeout); void showMessage(const QString &msg, int timeout);
void updateProgressBar(uint64_t cur, uint64_t total, bool success); void updateProgressBar(uint64_t cur, uint64_t total, bool success);
protected: protected:
void createActions();
void createStatusBar();
void closeEvent(QCloseEvent *event) override; void closeEvent(QCloseEvent *event) override;
void updateDownloadProgress(uint64_t cur, uint64_t total, bool success); void updateDownloadProgress(uint64_t cur, uint64_t total, bool success);
void setOption(); void setOption();
@ -44,26 +47,7 @@ protected:
QWidget *floating_window = nullptr; QWidget *floating_window = nullptr;
QVBoxLayout *r_layout; QVBoxLayout *r_layout;
QProgressBar *progress_bar; QProgressBar *progress_bar;
QStatusBar *status_bar; QLabel *fingerprint_label;
QJsonDocument fingerprint_to_dbc; QJsonDocument fingerprint_to_dbc;
QComboBox *dbc_combo; QComboBox *dbc_combo;
}; };
class LoadDBCDialog : public QDialog {
Q_OBJECT
public:
LoadDBCDialog(QWidget *parent);
QTextEdit *dbc_edit;
};
class SaveDBCDialog : public QDialog {
Q_OBJECT
public:
SaveDBCDialog(QWidget *parent);
void copytoClipboard();
void saveAs();
QTextEdit *dbc_edit;
};

Loading…
Cancel
Save