@ -92,8 +92,7 @@ void MainWindow::createActions() {
file_menu - > addAction ( tr ( " New DBC File " ) , this , & MainWindow : : newFile ) - > setShortcuts ( QKeySequence : : New ) ;
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 ( " Open DBC File... " ) , this , & MainWindow : : openFile ) - > setShortcuts ( QKeySequence : : Open ) ;
open_dbc_for_source = file_menu - > addMenu ( tr ( " Open &DBC File for Bus " ) ) ;
manage_dbcs_menu = file_menu - > addMenu ( tr ( " Manage &DBC Files " ) ) ;
open_dbc_for_source - > setEnabled ( false ) ;
open_recent_menu = file_menu - > addMenu ( tr ( " Open &Recent " ) ) ;
open_recent_menu = file_menu - > addMenu ( tr ( " Open &Recent " ) ) ;
for ( int i = 0 ; i < MAX_RECENT_FILES ; + + i ) {
for ( int i = 0 ; i < MAX_RECENT_FILES ; + + i ) {
@ -113,7 +112,7 @@ void MainWindow::createActions() {
load_opendbc_menu - > addAction ( QString : : fromStdString ( name ) , this , & MainWindow : : openOpendbcFile ) ;
load_opendbc_menu - > addAction ( QString : : fromStdString ( name ) , this , & MainWindow : : openOpendbcFile ) ;
}
}
file_menu - > addAction ( tr ( " Load DBC From Clipboard " ) , this , & MainWindow : : loadDBCFromClipboard ) ;
file_menu - > addAction ( tr ( " Load DBC From Clipboard " ) , [ = ] ( ) { loadFromClipboard ( ) ; } ) ;
file_menu - > addSeparator ( ) ;
file_menu - > addSeparator ( ) ;
save_dbc = file_menu - > addAction ( tr ( " Save DBC... " ) , this , & MainWindow : : save ) ;
save_dbc = file_menu - > addAction ( tr ( " Save DBC... " ) , this , & MainWindow : : save ) ;
@ -122,7 +121,7 @@ void MainWindow::createActions() {
save_dbc_as = file_menu - > addAction ( tr ( " Save DBC As... " ) , this , & MainWindow : : saveAs ) ;
save_dbc_as = file_menu - > addAction ( tr ( " Save DBC As... " ) , this , & MainWindow : : saveAs ) ;
save_dbc_as - > setShortcuts ( QKeySequence : : SaveAs ) ;
save_dbc_as - > setShortcuts ( QKeySequence : : SaveAs ) ;
copy_dbc_to_clipboard = file_menu - > addAction ( tr ( " Copy DBC To Clipboard " ) , this , & MainWindow : : saveDBC ToClipboard ) ;
copy_dbc_to_clipboard = file_menu - > addAction ( tr ( " Copy DBC To Clipboard " ) , this , & MainWindow : : saveToClipboard ) ;
file_menu - > addSeparator ( ) ;
file_menu - > addSeparator ( ) ;
file_menu - > addAction ( tr ( " Settings... " ) , this , & MainWindow : : setOption ) - > setShortcuts ( QKeySequence : : Preferences ) ;
file_menu - > addAction ( tr ( " Settings... " ) , this , & MainWindow : : setOption ) - > setShortcuts ( QKeySequence : : Preferences ) ;
@ -275,18 +274,20 @@ void MainWindow::openFile() {
}
}
}
}
void MainWindow : : openFileForSource ( ) {
void MainWindow : : openFileForSource ( SourceSet s ) {
if ( auto action = qobject_cast < QAction * > ( sender ( ) ) ) {
QString fn = QFileDialog : : getOpenFileName ( this , tr ( " Open File " ) , settings . last_dir , " DBC (*.dbc) " ) ;
uint8_t source = action - > data ( ) . value < uint8_t > ( ) ;
if ( ! fn . isEmpty ( ) ) {
assert ( source < 64 ) ;
loadFile ( fn , s , false ) ;
QString fn = QFileDialog : : getOpenFileName ( this , tr ( " Open File " ) , settings . last_dir , " DBC (*.dbc) " ) ;
if ( ! fn . isEmpty ( ) ) {
loadFile ( fn , { source , uint8_t ( source + 128 ) , uint8_t ( source + 192 ) } , false ) ;
}
}
}
}
}
void MainWindow : : newFileForSource ( SourceSet s ) {
remindSaveChanges ( ) ;
dbc ( ) - > close ( s ) ;
dbc ( ) - > open ( s , " " , " " ) ;
}
void MainWindow : : loadFile ( const QString & fn , SourceSet s , bool close_all ) {
void MainWindow : : loadFile ( const QString & fn , SourceSet s , bool close_all ) {
if ( ! fn . isEmpty ( ) ) {
if ( ! fn . isEmpty ( ) ) {
QString dbc_fn = fn ;
QString dbc_fn = fn ;
@ -307,6 +308,7 @@ void MainWindow::loadFile(const QString &fn, SourceSet s, bool close_all) {
dbc ( ) - > closeAll ( ) ;
dbc ( ) - > closeAll ( ) ;
}
}
dbc ( ) - > close ( s ) ;
bool ret = dbc ( ) - > open ( s , dbc_fn , & error ) ;
bool ret = dbc ( ) - > open ( s , dbc_fn , & error ) ;
if ( ret ) {
if ( ret ) {
updateRecentFiles ( fn ) ;
updateRecentFiles ( fn ) ;
@ -346,13 +348,17 @@ void MainWindow::loadDBCFromOpendbc(const QString &name) {
updateLoadSaveMenus ( ) ;
updateLoadSaveMenus ( ) ;
}
}
void MainWindow : : loadDBC FromClipboard ( ) {
void MainWindow : : loadFromClipboard ( SourceSet s , bool close_all ) {
remindSaveChanges ( ) ;
remindSaveChanges ( ) ;
QString dbc_str = QGuiApplication : : clipboard ( ) - > text ( ) ;
QString dbc_str = QGuiApplication : : clipboard ( ) - > text ( ) ;
QString error ;
QString error ;
dbc ( ) - > closeAll ( ) ;
if ( close_all ) {
bool ret = dbc ( ) - > open ( SOURCE_ALL , " " , dbc_str , & error ) ;
dbc ( ) - > closeAll ( ) ;
}
dbc ( ) - > close ( s ) ;
bool ret = dbc ( ) - > open ( s , " " , dbc_str , & error ) ;
if ( ret & & dbc ( ) - > msgCount ( ) > 0 ) {
if ( ret & & dbc ( ) - > msgCount ( ) > 0 ) {
QMessageBox : : information ( this , tr ( " Load From Clipboard " ) , tr ( " DBC Successfully Loaded! " ) ) ;
QMessageBox : : information ( this , tr ( " Load From Clipboard " ) , tr ( " DBC Successfully Loaded! " ) ) ;
} else {
} else {
@ -388,9 +394,22 @@ void MainWindow::loadDBCFromFingerprint() {
}
}
void MainWindow : : save ( ) {
void MainWindow : : save ( ) {
saveFile ( ) ;
// Save all open DBC files
for ( auto & [ s , dbc_file ] : dbc ( ) - > dbc_files ) {
if ( dbc_file - > isEmpty ( ) ) continue ;
saveFile ( dbc_file ) ;
}
}
void MainWindow : : saveAs ( ) {
// Save as all open DBC files. Should not be called with more than 1 file open
for ( auto & [ s , dbc_file ] : dbc ( ) - > dbc_files ) {
if ( dbc_file - > isEmpty ( ) ) continue ;
saveFileAs ( dbc_file ) ;
}
}
}
void MainWindow : : autoSave ( ) {
void MainWindow : : autoSave ( ) {
if ( ! UndoStack : : instance ( ) - > isClean ( ) ) {
if ( ! UndoStack : : instance ( ) - > isClean ( ) ) {
for ( auto & [ _ , dbc_file ] : dbc ( ) - > dbc_files ) {
for ( auto & [ _ , dbc_file ] : dbc ( ) - > dbc_files ) {
@ -407,46 +426,86 @@ void MainWindow::cleanupAutoSaveFile() {
}
}
}
}
void MainWindow : : saveFile ( ) {
void MainWindow : : closeFile ( DBCFile * dbc_file ) {
// Save all open DBC files
assert ( dbc_file ! = nullptr ) ;
for ( auto & [ s , dbc_file ] : dbc ( ) - > dbc_files ) {
remindSaveChanges ( ) ;
if ( ! dbc_file - > filename . isEmpty ( ) ) {
dbc_file - > save ( ) ;
dbc ( ) - > close ( dbc_file ) ;
updateRecentFiles ( dbc_file - > filename ) ;
} else if ( ! dbc_file - > isEmpty ( ) ) {
// Ensure we always have at least one file open
QString fn = QFileDialog : : getSaveFileName ( this , tr ( " Save File " ) , QDir : : cleanPath ( settings . last_dir + " /untitled.dbc " ) , tr ( " DBC (*.dbc) " ) ) ;
if ( dbc ( ) - > dbcCount ( ) = = 0 ) {
if ( ! fn . isEmpty ( ) ) {
newFile ( ) ;
dbc_file - > saveAs ( fn ) ;
}
updateRecentFiles ( fn ) ;
}
}
void MainWindow : : saveFile ( DBCFile * dbc_file ) {
assert ( dbc_file ! = nullptr ) ;
SourceSet s ;
for ( auto & [ s_ , dbc_file_ ] : dbc ( ) - > dbc_files ) {
if ( dbc_file_ = = dbc_file ) {
s = s_ ;
break ;
}
}
if ( ! dbc_file - > filename . isEmpty ( ) ) {
dbc_file - > save ( ) ;
updateRecentFiles ( dbc_file - > filename ) ;
} else if ( ! dbc_file - > isEmpty ( ) ) {
QString fn = QFileDialog : : getSaveFileName ( this , tr ( " Save File (bus: %1) " ) . arg ( toString ( s ) ) , QDir : : cleanPath ( settings . last_dir + " /untitled.dbc " ) , tr ( " DBC (*.dbc) " ) ) ;
if ( ! fn . isEmpty ( ) ) {
dbc_file - > saveAs ( fn ) ;
updateRecentFiles ( fn ) ;
}
}
}
}
UndoStack : : instance ( ) - > setClean ( ) ;
UndoStack : : instance ( ) - > setClean ( ) ;
statusBar ( ) - > showMessage ( tr ( " File saved " ) , 2000 ) ;
statusBar ( ) - > showMessage ( tr ( " File saved " ) , 2000 ) ;
updateLoadSaveMenus ( ) ;
}
}
void MainWindow : : saveAs ( ) {
void MainWindow : : saveFile As ( DBCFile * dbc_file ) {
// Assume only one file is open
assert ( dbc_file ! = nullptr ) ;
for ( auto & [ s , dbc_file ] : dbc ( ) - > dbc_files ) {
if ( dbc_file - > isEmpty ( ) ) continue ;
SourceSet s ;
QString fn = QFileDialog : : getSaveFileName ( this , tr ( " Save File " ) , QDir : : cleanPath ( settings . last_dir + " /untitled.dbc " ) , tr ( " DBC (*.dbc) " ) ) ;
for ( auto & [ s_ , dbc_file_ ] : dbc ( ) - > dbc_files ) {
if ( ! fn . isEmpty ( ) ) {
if ( dbc_file_ = = dbc_file ) {
dbc_file - > saveAs ( fn ) ;
s = s_ ;
updateRecentFiles ( fn ) ;
break ;
}
}
}
}
QString fn = QFileDialog : : getSaveFileName ( this , tr ( " Save File (bus: %1) " ) . arg ( toString ( s ) ) , QDir : : cleanPath ( settings . last_dir + " /untitled.dbc " ) , tr ( " DBC (*.dbc) " ) ) ;
if ( ! fn . isEmpty ( ) ) {
dbc_file - > saveAs ( fn ) ;
updateRecentFiles ( fn ) ;
updateLoadSaveMenus ( ) ;
}
}
}
void MainWindow : : saveDBCToClipboard ( ) {
void MainWindow : : removeBusFromFile ( DBCFile * dbc_file , uint8_t source ) {
// Assume only one file is open
assert ( dbc_file ! = nullptr ) ;
SourceSet ss = { source , uint8_t ( source + 128 ) , uint8_t ( source + 192 ) } ;
dbc ( ) - > removeSourcesFromFile ( dbc_file , ss ) ;
updateLoadSaveMenus ( ) ;
}
void MainWindow : : saveToClipboard ( ) {
// Copy all open DBC files to clipboard. Should not be called with more than 1 file open
for ( auto & [ s , dbc_file ] : dbc ( ) - > dbc_files ) {
for ( auto & [ s , dbc_file ] : dbc ( ) - > dbc_files ) {
if ( dbc_file - > isEmpty ( ) ) continue ;
if ( dbc_file - > isEmpty ( ) ) continue ;
QGuiApplication : : clipboard ( ) - > setText ( dbc_file - > generateDBC ( ) ) ;
saveFileToClipboard ( dbc_file ) ;
QMessageBox : : information ( this , tr ( " Copy To Clipboard " ) , tr ( " DBC Successfully copied! " ) ) ;
}
}
}
}
void MainWindow : : saveFileToClipboard ( DBCFile * dbc_file ) {
assert ( dbc_file ! = nullptr ) ;
QGuiApplication : : clipboard ( ) - > setText ( dbc_file - > generateDBC ( ) ) ;
QMessageBox : : information ( this , tr ( " Copy To Clipboard " ) , tr ( " DBC Successfully copied! " ) ) ;
}
void MainWindow : : updateSources ( const SourceSet & s ) {
void MainWindow : : updateSources ( const SourceSet & s ) {
sources = s ;
sources = s ;
updateLoadSaveMenus ( ) ;
updateLoadSaveMenus ( ) ;
@ -462,7 +521,6 @@ void MainWindow::updateLoadSaveMenus() {
save_dbc - > setText ( tr ( " Save DBC... " ) ) ;
save_dbc - > setText ( tr ( " Save DBC... " ) ) ;
}
}
// TODO: Support save as for multiple files
save_dbc_as - > setEnabled ( cnt = = 1 ) ;
save_dbc_as - > setEnabled ( cnt = = 1 ) ;
// TODO: Support clipboard for multiple files
// TODO: Support clipboard for multiple files
@ -472,35 +530,92 @@ void MainWindow::updateLoadSaveMenus() {
QList < uint8_t > sources_sorted = sources . toList ( ) ;
QList < uint8_t > sources_sorted = sources . toList ( ) ;
std : : sort ( sources_sorted . begin ( ) , sources_sorted . end ( ) ) ;
std : : sort ( sources_sorted . begin ( ) , sources_sorted . end ( ) ) ;
open_dbc_for_source - > setEnabled ( sources . size ( ) > 0 ) ;
manage_dbcs_menu - > clear ( ) ;
open_dbc_for_source - > clear ( ) ;
std : : map < QString , QStringList > dbc_files ;
for ( uint8_t source : sources_sorted ) {
for ( uint8_t source : sources_sorted ) {
if ( source > = 64 ) continue ; // Sent and blocked buses are handled implicitly
if ( source > = 64 ) continue ; // Sent and blocked buses are handled implicitly
QAction * action = new QAction ( this ) ;
SourceSet ss = { source , uint8_t ( source + 128 ) , uint8_t ( source + 192 ) } ;
auto d = dbc ( ) - > findDBCFile ( source ) ;
QString name = tr ( " no DBC " ) ;
QMenu * bus_menu = new QMenu ( this ) ;
if ( d ) {
if ( ! d - > second - > name ( ) . isEmpty ( ) ) {
// New
name = tr ( " %1 " ) . arg ( d - > second - > name ( ) ) ;
QAction * new_action = new QAction ( this ) ;
} else {
new_action - > setText ( tr ( " New DBC File... " ) ) ;
name = " untitled " ;
QObject : : connect ( new_action , & QAction : : triggered , [ = ] ( ) { newFileForSource ( ss ) ; } ) ;
bus_menu - > addAction ( new_action ) ;
// Open
QAction * open_action = new QAction ( this ) ;
open_action - > setText ( tr ( " Open DBC File... " ) ) ;
QObject : : connect ( open_action , & QAction : : triggered , [ = ] ( ) { openFileForSource ( ss ) ; } ) ;
bus_menu - > addAction ( open_action ) ;
// Open
QAction * load_clipboard_action = new QAction ( this ) ;
load_clipboard_action - > setText ( tr ( " Load DBC From Clipboard... " ) ) ;
QObject : : connect ( load_clipboard_action , & QAction : : triggered , [ = ] ( ) { loadFromClipboard ( ss , false ) ; } ) ;
bus_menu - > addAction ( load_clipboard_action ) ;
// Show sub-menu for each dbc for this source.
QStringList bus_menu_fns ;
for ( auto it : dbc ( ) - > dbc_files ) {
auto & [ src , dbc_file ] = it ;
if ( ! src . contains ( source ) & & ( src ! = SOURCE_ALL ) ) {
continue ;
}
}
dbc_files [ d - > second - > filename ] . push_back ( QString : : number ( source ) ) ;
QString fn = dbc_file - > filename . isEmpty ( ) ? " untitled " : QFileInfo ( dbc_file - > filename ) . baseName ( ) ;
// QMenu *manage_menu = bus_menu;
bus_menu - > addSeparator ( ) ;
QAction * fn_action = new QAction ( this ) ;
fn_action - > setText ( fn + " ( " + toString ( src ) + " ) " ) ;
fn_action - > setEnabled ( false ) ;
bus_menu - > addAction ( fn_action ) ;
// Save
QAction * save_action = new QAction ( this ) ;
save_action - > setText ( tr ( " Save... " ) ) ;
bus_menu - > addAction ( save_action ) ;
QObject : : connect ( save_action , & QAction : : triggered , [ = ] ( ) { saveFile ( it . second ) ; } ) ;
// Save as
QAction * save_as_action = new QAction ( this ) ;
save_as_action - > setText ( tr ( " Save As... " ) ) ;
bus_menu - > addAction ( save_as_action ) ;
QObject : : connect ( save_as_action , & QAction : : triggered , [ = ] ( ) { saveFileAs ( it . second ) ; } ) ;
// Copy to clipboard
QAction * save_clipboard_action = new QAction ( this ) ;
save_clipboard_action - > setText ( tr ( " Copy to Clipboard... " ) ) ;
bus_menu - > addAction ( save_clipboard_action ) ;
QObject : : connect ( save_clipboard_action , & QAction : : triggered , [ = ] ( ) { saveFileToClipboard ( it . second ) ; } ) ;
// Remove from this bus
QAction * remove_action = new QAction ( this ) ;
remove_action - > setText ( tr ( " Remove from this bus... " ) ) ;
bus_menu - > addAction ( remove_action ) ;
QObject : : connect ( remove_action , & QAction : : triggered , [ = ] ( ) { removeBusFromFile ( it . second , source ) ; } ) ;
// Close/Remove from all buses
QAction * close_action = new QAction ( this ) ;
close_action - > setText ( tr ( " Remove from all buses... " ) ) ;
bus_menu - > addAction ( close_action ) ;
QObject : : connect ( close_action , & QAction : : triggered , [ = ] ( ) { closeFile ( it . second ) ; } ) ;
bus_menu_fns < < fn ;
}
}
action - > setText ( tr ( " Bus %1 (current: %2) " ) . arg ( source ) . arg ( name ) ) ;
action - > setData ( source ) ;
QObject : : connect ( action , & QAction : : triggered , this , & MainWindow : : openFileForSource ) ;
manage_dbcs_menu - > addMenu ( bus_menu ) ;
open_dbc_for_source - > addAction ( action ) ;
QString bus_menu_title = bus_menu_fns . size ( ) ? bus_menu_fns . join ( " , " ) : " No DBCs loaded " ;
bus_menu - > setTitle ( tr ( " Bus %1 (%2) " ) . arg ( source ) . arg ( bus_menu_title ) ) ;
}
}
QStringList title ;
QStringList title ;
for ( auto & [ filename , src ] : dbc_files ) {
for ( auto & [ src , dbc_file ] : dbc ( ) - > dbc_files ) {
QString bus = dbc_files . size ( ) = = 1 ? " all " : src . join ( " , " ) ;
QString fn = dbc_file - > filename . isEmpty ( ) ? " untitled " : QFileInfo ( dbc_file - > filename ) . baseName ( ) ;
title . push_back ( " [ " + bus + " ] " + QFileInfo ( filename ) . baseName ( ) ) ;
title . push_back ( tr ( " (%1) %2 " ) . arg ( toString ( src ) ) . arg ( fn ) ) ;
}
}
setWindowFilePath ( title . join ( " | " ) ) ;
setWindowFilePath ( title . join ( " | " ) ) ;
}
}