# include "tools/cabana/chart/signalselector.h"
# include <QCompleter>
# include <QDialogButtonBox>
# include <QGridLayout>
# include <QLabel>
# include <QLineEdit>
# include <QPushButton>
# include <QVBoxLayout>
# include "tools/cabana/streams/abstractstream.h"
SignalSelector : : SignalSelector ( QString title , QWidget * parent ) : QDialog ( parent ) {
setWindowTitle ( title ) ;
QGridLayout * main_layout = new QGridLayout ( this ) ;
// left column
main_layout - > addWidget ( new QLabel ( tr ( " Available Signals " ) ) , 0 , 0 ) ;
main_layout - > addWidget ( msgs_combo = new QComboBox ( this ) , 1 , 0 ) ;
msgs_combo - > setEditable ( true ) ;
msgs_combo - > lineEdit ( ) - > setPlaceholderText ( tr ( " Select a msg... " ) ) ;
msgs_combo - > setInsertPolicy ( QComboBox : : NoInsert ) ;
msgs_combo - > completer ( ) - > setCompletionMode ( QCompleter : : PopupCompletion ) ;
msgs_combo - > completer ( ) - > setFilterMode ( Qt : : MatchContains ) ;
main_layout - > addWidget ( available_list = new QListWidget ( this ) , 2 , 0 ) ;
// buttons
QVBoxLayout * btn_layout = new QVBoxLayout ( ) ;
QPushButton * add_btn = new QPushButton ( utils : : icon ( " chevron-right " ) , " " , this ) ;
add_btn - > setEnabled ( false ) ;
QPushButton * remove_btn = new QPushButton ( utils : : icon ( " chevron-left " ) , " " , this ) ;
remove_btn - > setEnabled ( false ) ;
btn_layout - > addStretch ( 0 ) ;
btn_layout - > addWidget ( add_btn ) ;
btn_layout - > addWidget ( remove_btn ) ;
btn_layout - > addStretch ( 0 ) ;
main_layout - > addLayout ( btn_layout , 0 , 1 , 3 , 1 ) ;
// right column
main_layout - > addWidget ( new QLabel ( tr ( " Selected Signals " ) ) , 0 , 2 ) ;
main_layout - > addWidget ( selected_list = new QListWidget ( this ) , 1 , 2 , 2 , 1 ) ;
auto buttonBox = new QDialogButtonBox ( QDialogButtonBox : : Ok | QDialogButtonBox : : Cancel ) ;
main_layout - > addWidget ( buttonBox , 3 , 2 ) ;
for ( auto it = can - > last_msgs . cbegin ( ) ; it ! = can - > last_msgs . cend ( ) ; + + it ) {
if ( auto m = dbc ( ) - > msg ( it . key ( ) ) ) {
msgs_combo - > addItem ( QString ( " %1 (%2) " ) . arg ( m - > name ) . arg ( it . key ( ) . toString ( ) ) , QVariant : : fromValue ( it . key ( ) ) ) ;
}
}
msgs_combo - > model ( ) - > sort ( 0 ) ;
msgs_combo - > setCurrentIndex ( - 1 ) ;
QObject : : connect ( msgs_combo , qOverload < int > ( & QComboBox : : currentIndexChanged ) , this , & SignalSelector : : updateAvailableList ) ;
QObject : : connect ( available_list , & QListWidget : : currentRowChanged , [ = ] ( int row ) { add_btn - > setEnabled ( row ! = - 1 ) ; } ) ;
QObject : : connect ( selected_list , & QListWidget : : currentRowChanged , [ = ] ( int row ) { remove_btn - > setEnabled ( row ! = - 1 ) ; } ) ;
QObject : : connect ( available_list , & QListWidget : : itemDoubleClicked , this , & SignalSelector : : add ) ;
QObject : : connect ( selected_list , & QListWidget : : itemDoubleClicked , this , & SignalSelector : : remove ) ;
QObject : : connect ( add_btn , & QPushButton : : clicked , [ this ] ( ) { if ( auto item = available_list - > currentItem ( ) ) add ( item ) ; } ) ;
QObject : : connect ( remove_btn , & QPushButton : : clicked , [ this ] ( ) { if ( auto item = selected_list - > currentItem ( ) ) remove ( item ) ; } ) ;
QObject : : connect ( buttonBox , & QDialogButtonBox : : accepted , this , & QDialog : : accept ) ;
QObject : : connect ( buttonBox , & QDialogButtonBox : : rejected , this , & QDialog : : reject ) ;
}
void SignalSelector : : add ( QListWidgetItem * item ) {
auto it = ( ListItem * ) item ;
addItemToList ( selected_list , it - > msg_id , it - > sig , true ) ;
delete item ;
}
void SignalSelector : : remove ( QListWidgetItem * item ) {
auto it = ( ListItem * ) item ;
if ( it - > msg_id = = msgs_combo - > currentData ( ) . value < MessageId > ( ) ) {
addItemToList ( available_list , it - > msg_id , it - > sig ) ;
}
delete item ;
}
void SignalSelector : : updateAvailableList ( int index ) {
if ( index = = - 1 ) return ;
available_list - > clear ( ) ;
MessageId msg_id = msgs_combo - > itemData ( index ) . value < MessageId > ( ) ;
auto selected_items = seletedItems ( ) ;
for ( auto s : dbc ( ) - > msg ( msg_id ) - > getSignals ( ) ) {
bool is_selected = std : : any_of ( selected_items . begin ( ) , selected_items . end ( ) , [ = , sig = s ] ( auto it ) { return it - > msg_id = = msg_id & & it - > sig = = sig ; } ) ;
if ( ! is_selected ) {
addItemToList ( available_list , msg_id , s ) ;
}
}
}
void SignalSelector : : addItemToList ( QListWidget * parent , const MessageId id , const cabana : : Signal * sig , bool show_msg_name ) {
QString text = QString ( " <span style= \" color:%0; \" >■ </span> %1 " ) . arg ( sig - > color . name ( ) , sig - > name ) ;
if ( show_msg_name ) text + = QString ( " <font color= \" gray \" >%0 %1</font> " ) . arg ( msgName ( id ) , id . toString ( ) ) ;
QLabel * label = new QLabel ( text ) ;
label - > setContentsMargins ( 5 , 0 , 5 , 0 ) ;
auto new_item = new ListItem ( id , sig , parent ) ;
new_item - > setSizeHint ( label - > sizeHint ( ) ) ;
parent - > setItemWidget ( new_item , label ) ;
}
QList < SignalSelector : : ListItem * > SignalSelector : : seletedItems ( ) {
QList < SignalSelector : : ListItem * > ret ;
for ( int i = 0 ; i < selected_list - > count ( ) ; + + i ) ret . push_back ( ( ListItem * ) selected_list - > item ( i ) ) ;
return ret ;
}