|
|
|
@ -61,22 +61,33 @@ MainWindow::MainWindow() : QMainWindow() { |
|
|
|
|
QObject::connect(charts_widget, &ChartsWidget::dock, this, &MainWindow::dockCharts); |
|
|
|
|
QObject::connect(can, &AbstractStream::streamStarted, this, &MainWindow::loadDBCFromFingerprint); |
|
|
|
|
QObject::connect(dbc(), &DBCManager::DBCFileChanged, this, &MainWindow::DBCFileChanged); |
|
|
|
|
QObject::connect(detail_widget->undo_stack, &QUndoStack::indexChanged, [this](int index) { |
|
|
|
|
setWindowTitle(tr("%1%2 - Cabana").arg(index > 0 ? "* " : "").arg(dbc()->name())); |
|
|
|
|
}); |
|
|
|
|
QObject::connect(detail_widget->undo_stack, &QUndoStack::cleanChanged, [this](bool clean) { setWindowModified(!clean); }); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::createActions() { |
|
|
|
|
QMenu *file_menu = menuBar()->addMenu(tr("&File")); |
|
|
|
|
file_menu->addAction(tr("Open DBC File..."), this, &MainWindow::loadDBCFromFile)->setShortcuts(QKeySequence::Open); |
|
|
|
|
file_menu->addAction(tr("New DBC File"), this, &MainWindow::newFile)->setShortcuts(QKeySequence::New); |
|
|
|
|
file_menu->addAction(tr("Open DBC File..."), this, &MainWindow::openFile)->setShortcuts(QKeySequence::Open); |
|
|
|
|
file_menu->addAction(tr("Load DBC From Clipboard"), this, &MainWindow::loadDBCFromClipboard); |
|
|
|
|
open_recent_menu = file_menu->addMenu(tr("Open &Recent")); |
|
|
|
|
for (int i = 0; i < MAX_RECENT_FILES; ++i) { |
|
|
|
|
recent_files_acts[i] = new QAction(this); |
|
|
|
|
recent_files_acts[i]->setVisible(false); |
|
|
|
|
QObject::connect(recent_files_acts[i], &QAction::triggered, this, &MainWindow::openRecentFile); |
|
|
|
|
open_recent_menu->addAction(recent_files_acts[i]); |
|
|
|
|
} |
|
|
|
|
updateRecentFileActions(); |
|
|
|
|
|
|
|
|
|
file_menu->addSeparator(); |
|
|
|
|
file_menu->addAction(tr("Save DBC..."), this, &MainWindow::saveDBCToFile)->setShortcuts(QKeySequence::Save); |
|
|
|
|
file_menu->addAction(tr("Save DBC As..."), this, &MainWindow::saveAsDBCToFile)->setShortcuts(QKeySequence::SaveAs); |
|
|
|
|
file_menu->addAction(tr("Save DBC..."), this, &MainWindow::save)->setShortcuts(QKeySequence::Save); |
|
|
|
|
file_menu->addAction(tr("Save DBC As..."), this, &MainWindow::saveAs)->setShortcuts(QKeySequence::SaveAs); |
|
|
|
|
file_menu->addAction(tr("Copy DBC To Clipboard"), this, &MainWindow::saveDBCToClipboard); |
|
|
|
|
file_menu->addSeparator(); |
|
|
|
|
file_menu->addAction(tr("Settings..."), this, &MainWindow::setOption)->setShortcuts(QKeySequence::Preferences); |
|
|
|
|
|
|
|
|
|
file_menu->addSeparator(); |
|
|
|
|
file_menu->addAction(tr("E&xit"), qApp, &QApplication::closeAllWindows)->setShortcuts(QKeySequence::Quit); |
|
|
|
|
|
|
|
|
|
QMenu *edit_menu = menuBar()->addMenu(tr("&Edit")); |
|
|
|
|
auto undo_act = detail_widget->undo_stack->createUndoAction(this, tr("&Undo")); |
|
|
|
|
undo_act->setShortcuts(QKeySequence::Undo); |
|
|
|
@ -181,34 +192,57 @@ void MainWindow::DBCFileChanged() { |
|
|
|
|
detail_widget->undo_stack->clear(); |
|
|
|
|
int index = dbc_combo->findText(QFileInfo(dbc()->name()).baseName()); |
|
|
|
|
dbc_combo->setCurrentIndex(index); |
|
|
|
|
setWindowTitle(tr("%1 - Cabana").arg(dbc()->name())); |
|
|
|
|
setWindowFilePath(QString("%1").arg(dbc()->name())); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::loadDBCFromName(const QString &name) { |
|
|
|
|
if (name != dbc()->name()) { |
|
|
|
|
dbc()->open(name); |
|
|
|
|
void MainWindow::newFile() { |
|
|
|
|
remindSaveChanges(); |
|
|
|
|
dbc()->open("untitled.dbc", ""); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::openFile() { |
|
|
|
|
remindSaveChanges(); |
|
|
|
|
QString fn = QFileDialog::getOpenFileName(this, tr("Open File"), settings.last_dir, "DBC (*.dbc)"); |
|
|
|
|
if (!fn.isEmpty()) { |
|
|
|
|
loadFile(fn); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::loadDBCFromFile() { |
|
|
|
|
file_name = QFileDialog::getOpenFileName(this, tr("Open File"), settings.last_dir, "DBC (*.dbc)"); |
|
|
|
|
if (!file_name.isEmpty()) { |
|
|
|
|
settings.last_dir = QFileInfo(file_name).absolutePath(); |
|
|
|
|
QFile file(file_name); |
|
|
|
|
void MainWindow::loadFile(const QString &fn) { |
|
|
|
|
if (!fn.isEmpty()) { |
|
|
|
|
QFile file(fn); |
|
|
|
|
if (file.open(QIODevice::ReadOnly)) { |
|
|
|
|
auto dbc_name = QFileInfo(file_name).baseName(); |
|
|
|
|
auto dbc_name = QFileInfo(fn).baseName(); |
|
|
|
|
dbc()->open(dbc_name, file.readAll()); |
|
|
|
|
setCurrentFile(fn); |
|
|
|
|
statusBar()->showMessage(tr("DBC File %1 loaded").arg(fn), 2000); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::openRecentFile() { |
|
|
|
|
if (auto action = qobject_cast<QAction *>(sender())) { |
|
|
|
|
remindSaveChanges(); |
|
|
|
|
loadFile(action->data().toString()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::loadDBCFromName(const QString &name) { |
|
|
|
|
if (name != dbc()->name()) { |
|
|
|
|
remindSaveChanges(); |
|
|
|
|
dbc()->open(name); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::loadDBCFromClipboard() { |
|
|
|
|
remindSaveChanges(); |
|
|
|
|
QString dbc_str = QGuiApplication::clipboard()->text(); |
|
|
|
|
dbc()->open("From Clipboard", dbc_str); |
|
|
|
|
dbc()->open("from_clipboard.dbc", dbc_str); |
|
|
|
|
QMessageBox::information(this, tr("Load From Clipboard"), tr("DBC Successfully Loaded!")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::loadDBCFromFingerprint() { |
|
|
|
|
remindSaveChanges(); |
|
|
|
|
auto fingerprint = can->carFingerprint(); |
|
|
|
|
video_dock->setWindowTitle(tr("ROUTE: %1 FINGERPINT: %2").arg(can->routeName()).arg(fingerprint.isEmpty() ? tr("Unknown Car") : fingerprint)); |
|
|
|
|
if (!fingerprint.isEmpty()) { |
|
|
|
@ -218,25 +252,31 @@ void MainWindow::loadDBCFromFingerprint() { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
dbc()->open("New_DBC", ""); |
|
|
|
|
newFile(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::saveDBCToFile() { |
|
|
|
|
if (file_name.isEmpty()) { |
|
|
|
|
saveAsDBCToFile(); |
|
|
|
|
void MainWindow::save() { |
|
|
|
|
if (current_file.isEmpty()) { |
|
|
|
|
saveAs(); |
|
|
|
|
} else { |
|
|
|
|
settings.last_dir = QFileInfo(file_name).absolutePath(); |
|
|
|
|
QFile file(file_name); |
|
|
|
|
if (file.open(QIODevice::WriteOnly)) { |
|
|
|
|
file.write(dbc()->generateDBC().toUtf8()); |
|
|
|
|
} |
|
|
|
|
saveFile(current_file); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::saveAsDBCToFile() { |
|
|
|
|
file_name = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::cleanPath(settings.last_dir + "/untitled.dbc"), tr("DBC (*.dbc)")); |
|
|
|
|
if (!file_name.isEmpty()) { |
|
|
|
|
saveDBCToFile(); |
|
|
|
|
void MainWindow::saveFile(const QString &fn) { |
|
|
|
|
QFile file(fn); |
|
|
|
|
if (file.open(QIODevice::WriteOnly)) { |
|
|
|
|
file.write(dbc()->generateDBC().toUtf8()); |
|
|
|
|
detail_widget->undo_stack->setClean(); |
|
|
|
|
setCurrentFile(fn); |
|
|
|
|
statusBar()->showMessage(tr("File saved"), 2000); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::saveAs() { |
|
|
|
|
QString fn = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::cleanPath(settings.last_dir + "/untitled.dbc"), tr("DBC (*.dbc)")); |
|
|
|
|
if (!fn.isEmpty()) { |
|
|
|
|
saveFile(fn); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -245,6 +285,49 @@ void MainWindow::saveDBCToClipboard() { |
|
|
|
|
QMessageBox::information(this, tr("Copy To Clipboard"), tr("DBC Successfully copied!")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::setCurrentFile(const QString &fn) { |
|
|
|
|
current_file = fn; |
|
|
|
|
setWindowFilePath(QString("%1").arg(fn)); |
|
|
|
|
settings.recent_files.removeAll(fn); |
|
|
|
|
settings.recent_files.prepend(fn); |
|
|
|
|
while (settings.recent_files.size() > MAX_RECENT_FILES) { |
|
|
|
|
settings.recent_files.removeLast(); |
|
|
|
|
} |
|
|
|
|
settings.last_dir = QFileInfo(fn).absolutePath(); |
|
|
|
|
updateRecentFileActions(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::updateRecentFileActions() { |
|
|
|
|
int num_recent_files = std::min<int>(settings.recent_files.size(), MAX_RECENT_FILES); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < num_recent_files; ++i) { |
|
|
|
|
QString text = tr("&%1 %2").arg(i + 1).arg(QFileInfo(settings.recent_files[i]).fileName()); |
|
|
|
|
recent_files_acts[i]->setText(text); |
|
|
|
|
recent_files_acts[i]->setData(settings.recent_files[i]); |
|
|
|
|
recent_files_acts[i]->setVisible(true); |
|
|
|
|
} |
|
|
|
|
for (int i = num_recent_files; i < MAX_RECENT_FILES; ++i) { |
|
|
|
|
recent_files_acts[i]->setVisible(false); |
|
|
|
|
} |
|
|
|
|
open_recent_menu->setEnabled(num_recent_files > 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::remindSaveChanges() { |
|
|
|
|
bool discard_changes = false; |
|
|
|
|
while (!detail_widget->undo_stack->isClean() && !discard_changes) { |
|
|
|
|
int ret = (QMessageBox::question(this, tr("Unsaved Changes"), |
|
|
|
|
tr("You have unsaved changes. Press ok to save them, cancel to discard."), |
|
|
|
|
QMessageBox::Ok | QMessageBox::Cancel)); |
|
|
|
|
if (ret == QMessageBox::Ok) { |
|
|
|
|
save(); |
|
|
|
|
} else { |
|
|
|
|
discard_changes = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
detail_widget->undo_stack->clear(); |
|
|
|
|
current_file = ""; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::updateDownloadProgress(uint64_t cur, uint64_t total, bool success) { |
|
|
|
|
if (success && cur < total) { |
|
|
|
|
progress_bar->setValue((cur / (double)total) * 100); |
|
|
|
@ -264,7 +347,7 @@ void MainWindow::dockCharts(bool dock) { |
|
|
|
|
} else if (!dock && !floating_window) { |
|
|
|
|
floating_window = new QWidget(this); |
|
|
|
|
floating_window->setWindowFlags(Qt::Window); |
|
|
|
|
floating_window->setWindowTitle("Charts - Cabana"); |
|
|
|
|
floating_window->setWindowTitle("Charts"); |
|
|
|
|
floating_window->setLayout(new QVBoxLayout()); |
|
|
|
|
floating_window->layout()->addWidget(charts_widget); |
|
|
|
|
floating_window->installEventFilter(charts_widget); |
|
|
|
@ -273,15 +356,7 @@ void MainWindow::dockCharts(bool dock) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MainWindow::closeEvent(QCloseEvent *event) { |
|
|
|
|
if (detail_widget->undo_stack->index() > 0) { |
|
|
|
|
auto ret = QMessageBox::question(this, tr("Unsaved Changes"), |
|
|
|
|
tr("Are you sure you want to exit without saving?\nAny unsaved changes will be lost."), |
|
|
|
|
QMessageBox::Yes | QMessageBox::No); |
|
|
|
|
if (ret == QMessageBox::No) { |
|
|
|
|
event->ignore(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
remindSaveChanges(); |
|
|
|
|
|
|
|
|
|
main_win = nullptr; |
|
|
|
|
if (floating_window) |
|
|
|
|