@ -11,11 +11,6 @@
# include "tools/cabana/commands.h"
# include "tools/cabana/commands.h"
static QString msg_node_from_id ( const MessageId & id ) {
auto msg = dbc ( ) - > msg ( id ) ;
return msg ? msg - > transmitter : QString ( ) ;
}
MessagesWidget : : MessagesWidget ( QWidget * parent ) : menu ( new QMenu ( this ) ) , QWidget ( parent ) {
MessagesWidget : : MessagesWidget ( QWidget * parent ) : menu ( new QMenu ( this ) ) , QWidget ( parent ) {
QVBoxLayout * main_layout = new QVBoxLayout ( this ) ;
QVBoxLayout * main_layout = new QVBoxLayout ( this ) ;
main_layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
main_layout - > setContentsMargins ( 0 , 0 , 0 , 0 ) ;
@ -23,12 +18,10 @@ MessagesWidget::MessagesWidget(QWidget *parent) : menu(new QMenu(this)), QWidget
// toolbar
// toolbar
main_layout - > addWidget ( createToolBar ( ) ) ;
main_layout - > addWidget ( createToolBar ( ) ) ;
// message table
// message table
view = new MessageView ( this ) ;
main_layout - > addWidget ( view = new MessageView ( this ) ) ;
model = new MessageListModel ( this ) ;
view - > setItemDelegate ( delegate = new MessageBytesDelegate ( view , settings . multiple_lines_hex ) ) ;
header = new MessageViewHeader ( this ) ;
view - > setModel ( model = new MessageListModel ( this ) ) ;
view - > setItemDelegate ( delegate = new MessageBytesDelegate ( view , settings . multiple_lines_bytes ) ) ;
view - > setHeader ( header = new MessageViewHeader ( this ) ) ;
view - > setHeader ( header ) ;
view - > setModel ( model ) ;
view - > setSortingEnabled ( true ) ;
view - > setSortingEnabled ( true ) ;
view - > sortByColumn ( MessageListModel : : Column : : NAME , Qt : : AscendingOrder ) ;
view - > sortByColumn ( MessageListModel : : Column : : NAME , Qt : : AscendingOrder ) ;
view - > setAllColumnsShowFocus ( true ) ;
view - > setAllColumnsShowFocus ( true ) ;
@ -36,6 +29,7 @@ MessagesWidget::MessagesWidget(QWidget *parent) : menu(new QMenu(this)), QWidget
view - > setItemsExpandable ( false ) ;
view - > setItemsExpandable ( false ) ;
view - > setIndentation ( 0 ) ;
view - > setIndentation ( 0 ) ;
view - > setRootIsDecorated ( false ) ;
view - > setRootIsDecorated ( false ) ;
view - > setUniformRowHeights ( ! settings . multiple_lines_hex ) ;
// Must be called before setting any header parameters to avoid overriding
// Must be called before setting any header parameters to avoid overriding
restoreHeaderState ( settings . message_header_state ) ;
restoreHeaderState ( settings . message_header_state ) ;
@ -44,15 +38,14 @@ MessagesWidget::MessagesWidget(QWidget *parent) : menu(new QMenu(this)), QWidget
header - > setStretchLastSection ( true ) ;
header - > setStretchLastSection ( true ) ;
header - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
header - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
main_layout - > addWidget ( view ) ;
// suppress
// suppress
QHBoxLayout * suppress_layout = new QHBoxLayout ( ) ;
QHBoxLayout * suppress_layout = new QHBoxLayout ( ) ;
suppress_add = new QPushButton ( " Suppress Highlighted " ) ;
suppress_layout - > addWidget ( suppress_add = new QPushButton ( " Suppress Highlighted " ) ) ;
suppress_clear = new QPushButton ( ) ;
suppress_layout - > addWidget ( suppress_clear = new QPushButton ( ) ) ;
suppress_layout - > addWidget ( suppress_add ) ;
suppress_clear - > setToolTip ( tr ( " Clear suppressed " ) ) ;
suppress_layout - > addWidget ( suppress_clear ) ;
suppress_layout - > addStretch ( 1 ) ;
QCheckBox * suppress_defined_signals = new QCheckBox ( tr ( " Suppress Defined Signals " ) , this ) ;
QCheckBox * suppress_defined_signals = new QCheckBox ( tr ( " Suppress Signals " ) , this ) ;
suppress_defined_signals - > setToolTip ( tr ( " Suppress defined signals " ) ) ;
suppress_defined_signals - > setChecked ( settings . suppress_defined_signals ) ;
suppress_defined_signals - > setChecked ( settings . suppress_defined_signals ) ;
suppress_layout - > addWidget ( suppress_defined_signals ) ;
suppress_layout - > addWidget ( suppress_defined_signals ) ;
main_layout - > addLayout ( suppress_layout ) ;
main_layout - > addLayout ( suppress_layout ) ;
@ -62,10 +55,7 @@ MessagesWidget::MessagesWidget(QWidget *parent) : menu(new QMenu(this)), QWidget
QObject : : connect ( header , & MessageViewHeader : : filtersUpdated , model , & MessageListModel : : setFilterStrings ) ;
QObject : : connect ( header , & MessageViewHeader : : filtersUpdated , model , & MessageListModel : : setFilterStrings ) ;
QObject : : connect ( header , & MessageViewHeader : : customContextMenuRequested , this , & MessagesWidget : : headerContextMenuEvent ) ;
QObject : : connect ( header , & MessageViewHeader : : customContextMenuRequested , this , & MessagesWidget : : headerContextMenuEvent ) ;
QObject : : connect ( view - > horizontalScrollBar ( ) , & QScrollBar : : valueChanged , header , & MessageViewHeader : : updateHeaderPositions ) ;
QObject : : connect ( view - > horizontalScrollBar ( ) , & QScrollBar : : valueChanged , header , & MessageViewHeader : : updateHeaderPositions ) ;
QObject : : connect ( suppress_defined_signals , & QCheckBox : : stateChanged , [ = ] ( int state ) {
QObject : : connect ( suppress_defined_signals , & QCheckBox : : stateChanged , can , & AbstractStream : : suppressDefinedSignals ) ;
settings . suppress_defined_signals = ( state = = Qt : : Checked ) ;
emit settings . changed ( ) ;
} ) ;
QObject : : connect ( can , & AbstractStream : : msgsReceived , model , & MessageListModel : : msgsReceived ) ;
QObject : : connect ( can , & AbstractStream : : msgsReceived , model , & MessageListModel : : msgsReceived ) ;
QObject : : connect ( dbc ( ) , & DBCManager : : DBCFileChanged , this , & MessagesWidget : : dbcModified ) ;
QObject : : connect ( dbc ( ) , & DBCManager : : DBCFileChanged , this , & MessagesWidget : : dbcModified ) ;
QObject : : connect ( UndoStack : : instance ( ) , & QUndoStack : : indexChanged , this , & MessagesWidget : : dbcModified ) ;
QObject : : connect ( UndoStack : : instance ( ) , & QUndoStack : : indexChanged , this , & MessagesWidget : : dbcModified ) ;
@ -76,24 +66,17 @@ MessagesWidget::MessagesWidget(QWidget *parent) : menu(new QMenu(this)), QWidget
view - > updateBytesSectionSize ( ) ;
view - > updateBytesSectionSize ( ) ;
} ) ;
} ) ;
QObject : : connect ( view - > selectionModel ( ) , & QItemSelectionModel : : currentChanged , [ = ] ( const QModelIndex & current , const QModelIndex & previous ) {
QObject : : connect ( view - > selectionModel ( ) , & QItemSelectionModel : : currentChanged , [ = ] ( const QModelIndex & current , const QModelIndex & previous ) {
if ( current . isValid ( ) & & current . row ( ) < model - > msgs . size ( ) ) {
if ( current . isValid ( ) & & current . row ( ) < model - > items_ . size ( ) ) {
auto & id = model - > msgs [ current . row ( ) ] ;
const auto & id = model - > items_ [ current . row ( ) ] . id ;
if ( ! current_msg_id | | id ! = * current_msg_id ) {
if ( ! current_msg_id | | id ! = * current_msg_id ) {
current_msg_id = id ;
current_msg_id = id ;
emit msgSelectionChanged ( * current_msg_id ) ;
emit msgSelectionChanged ( * current_msg_id ) ;
}
}
}
}
} ) ;
} ) ;
QObject : : connect ( suppress_add , & QPushButton : : clicked , [ = ] ( ) {
QObject : : connect ( suppress_add , & QPushButton : : clicked , this , & MessagesWidget : : suppressHighlighted ) ;
model - > suppress ( ) ;
QObject : : connect ( suppress_clear , & QPushButton : : clicked , this , & MessagesWidget : : suppressHighlighted ) ;
updateSuppressedButtons ( ) ;
suppressHighlighted ( ) ;
} ) ;
QObject : : connect ( suppress_clear , & QPushButton : : clicked , [ = ] ( ) {
model - > clearSuppress ( ) ;
updateSuppressedButtons ( ) ;
} ) ;
updateSuppressedButtons ( ) ;
setWhatsThis ( tr ( R " (
setWhatsThis ( tr ( R " (
< b > Message View < / b > < br / >
< b > Message View < / b > < br / >
@ -126,19 +109,22 @@ void MessagesWidget::dbcModified() {
}
}
void MessagesWidget : : selectMessage ( const MessageId & msg_id ) {
void MessagesWidget : : selectMessage ( const MessageId & msg_id ) {
auto it = std : : find ( model - > msgs . cbegin ( ) , model - > msgs . cend ( ) , msg_id ) ;
auto it = std : : find_if ( model - > items_ . cbegin ( ) , model - > items_ . cend ( ) ,
if ( it ! = model - > msgs . cend ( ) ) {
[ & msg_id ] ( auto & item ) { return item . id = = msg_id ; } ) ;
view - > setCurrentIndex ( model - > index ( std : : distance ( model - > msgs . cbegin ( ) , it ) , 0 ) ) ;
if ( it ! = model - > items_ . cend ( ) ) {
view - > setCurrentIndex ( model - > index ( std : : distance ( model - > items_ . cbegin ( ) , it ) , 0 ) ) ;
}
}
}
}
void MessagesWidget : : updateSuppressedButtons ( ) {
void MessagesWidget : : suppressHighlighted ( ) {
if ( model - > suppressed_bytes . empty ( ) ) {
if ( sender ( ) = = suppress_add ) {
suppress_clear - > setEnabled ( false ) ;
size_t n = can - > suppressHighlighted ( ) ;
suppress_clear - > setText ( " Clear Suppressed " ) ;
suppress_clear - > setText ( tr ( " Clear (%1) " ) . arg ( n ) ) ;
} else {
suppress_clear - > setEnabled ( true ) ;
suppress_clear - > setEnabled ( true ) ;
suppress_clear - > setText ( QString ( " Clear Suppressed (%1) " ) . arg ( model - > suppressed_bytes . size ( ) ) ) ;
} else {
can - > clearSuppressed ( ) ;
suppress_clear - > setText ( tr ( " Clear " ) ) ;
suppress_clear - > setEnabled ( false ) ;
}
}
}
}
@ -160,12 +146,13 @@ void MessagesWidget::menuAboutToShow() {
menu - > addSeparator ( ) ;
menu - > addSeparator ( ) ;
auto action = menu - > addAction ( tr ( " Mutlti-Line bytes " ) , this , & MessagesWidget : : setMultiLineBytes ) ;
auto action = menu - > addAction ( tr ( " Mutlti-Line bytes " ) , this , & MessagesWidget : : setMultiLineBytes ) ;
action - > setCheckable ( true ) ;
action - > setCheckable ( true ) ;
action - > setChecked ( settings . multiple_lines_bytes ) ;
action - > setChecked ( settings . multiple_lines_hex ) ;
}
}
void MessagesWidget : : setMultiLineBytes ( bool multi ) {
void MessagesWidget : : setMultiLineBytes ( bool multi ) {
settings . multiple_lines_bytes = multi ;
settings . multiple_lines_hex = multi ;
delegate - > setMultipleLines ( multi ) ;
delegate - > setMultipleLines ( multi ) ;
view - > setUniformRowHeights ( ! multi ) ;
view - > updateBytesSectionSize ( ) ;
view - > updateBytesSectionSize ( ) ;
view - > doItemsLayout ( ) ;
view - > doItemsLayout ( ) ;
}
}
@ -188,7 +175,7 @@ QVariant MessageListModel::headerData(int section, Qt::Orientation orientation,
}
}
QVariant MessageListModel : : data ( const QModelIndex & index , int role ) const {
QVariant MessageListModel : : data ( const QModelIndex & index , int role ) const {
if ( ! index . isValid ( ) | | index . row ( ) > = msgs . size ( ) ) return { } ;
if ( ! index . isValid ( ) | | index . row ( ) > = items_ . size ( ) ) return { } ;
auto getFreq = [ ] ( const CanData & d ) {
auto getFreq = [ ] ( const CanData & d ) {
if ( d . freq > 0 & & ( can - > currentSec ( ) - d . ts - 1.0 / settings . fps ) < ( 5.0 / d . freq ) ) {
if ( d . freq > 0 & & ( can - > currentSec ( ) - d . ts - 1.0 / settings . fps ) < ( 5.0 / d . freq ) ) {
@ -198,33 +185,24 @@ QVariant MessageListModel::data(const QModelIndex &index, int role) const {
}
}
} ;
} ;
const auto & id = msgs [ index . row ( ) ] ;
const auto & item = items_ [ index . row ( ) ] ;
auto & can_data = can - > lastMessage ( id ) ;
if ( role = = Qt : : DisplayRole ) {
if ( role = = Qt : : DisplayRole ) {
switch ( index . column ( ) ) {
switch ( index . column ( ) ) {
case Column : : NAME : return msgName ( id ) ;
case Column : : NAME : return item . name ;
case Column : : SOURCE : return id . source ! = INVALID_SOURCE ? QString : : number ( id . source ) : " N/A " ;
case Column : : SOURCE : return item . i d . source ! = INVALID_SOURCE ? QString : : number ( item . id . source ) : " N/A " ;
case Column : : ADDRESS : return QString : : number ( id . address , 16 ) ;
case Column : : ADDRESS : return QString : : number ( item . i d . address , 16 ) ;
case Column : : NODE : return msg_node_from_id ( id ) ;
case Column : : NODE : return item . node ;
case Column : : FREQ : return id . source ! = INVALID_SOURCE ? getFreq ( can_ data) : " N/A " ;
case Column : : FREQ : return item . i d . source ! = INVALID_SOURCE ? getFreq ( * item . data ) : " N/A " ;
case Column : : COUNT : return id . source ! = INVALID_SOURCE ? QString : : number ( can_data . count ) : " N/A " ;
case Column : : COUNT : return item . i d . source ! = INVALID_SOURCE ? QString : : number ( item . data - > count ) : " N/A " ;
case Column : : DATA : return id . source ! = INVALID_SOURCE ? toHex ( can_data . dat ) : " N/A " ;
case Column : : DATA : return item . i d . source ! = INVALID_SOURCE ? " " : " N/A " ;
}
}
} else if ( role = = ColorsRole ) {
} else if ( role = = ColorsRole ) {
QVector < QColor > colors = can_data . colors ;
return QVariant : : fromValue ( ( void * ) ( & item . data - > colors ) ) ;
if ( ! suppressed_bytes . empty ( ) ) {
} else if ( role = = BytesRole & & index . column ( ) = = Column : : DATA & & item . id . source ! = INVALID_SOURCE ) {
for ( int i = 0 ; i < colors . size ( ) ; i + + ) {
return QVariant : : fromValue ( ( void * ) ( & item . data - > dat ) ) ;
if ( suppressed_bytes . contains ( { id , i } ) ) {
colors [ i ] = QColor ( 255 , 255 , 255 , 0 ) ;
}
}
}
return QVariant : : fromValue ( colors ) ;
} else if ( role = = BytesRole & & index . column ( ) = = Column : : DATA & & id . source ! = INVALID_SOURCE ) {
return can_data . dat ;
} else if ( role = = Qt : : ToolTipRole & & index . column ( ) = = Column : : NAME ) {
} else if ( role = = Qt : : ToolTipRole & & index . column ( ) = = Column : : NAME ) {
auto msg = dbc ( ) - > msg ( id ) ;
auto msg = dbc ( ) - > msg ( item . id ) ;
auto tooltip = msg ? msg - > name : UNTITLED ;
auto tooltip = item . name ;
if ( msg & & ! msg - > comment . isEmpty ( ) ) tooltip + = " <br /><span style= \" color:gray; \" > " + msg - > comment + " </span> " ;
if ( msg & & ! msg - > comment . isEmpty ( ) ) tooltip + = " <br /><span style= \" color:gray; \" > " + msg - > comment + " </span> " ;
return tooltip ;
return tooltip ;
}
}
@ -232,31 +210,31 @@ QVariant MessageListModel::data(const QModelIndex &index, int role) const {
}
}
void MessageListModel : : setFilterStrings ( const QMap < int , QString > & filters ) {
void MessageListModel : : setFilterStrings ( const QMap < int , QString > & filters ) {
filter_str = filters ;
filters_ = filters ;
filterAndSort ( ) ;
filterAndSort ( ) ;
}
}
void MessageListModel : : dbcModified ( ) {
void MessageListModel : : dbcModified ( ) {
dbc_address . clear ( ) ;
dbc_messages_ . clear ( ) ;
for ( const auto & [ _ , m ] : dbc ( ) - > getMessages ( - 1 ) ) {
for ( const auto & [ _ , m ] : dbc ( ) - > getMessages ( - 1 ) ) {
dbc_address . insert ( m . address ) ;
dbc_messages_ . insert ( MessageId { . source = INVALID_SOURCE , . address = m . address } ) ;
}
}
filterAndSort ( ) ;
filterAndSort ( true ) ;
}
}
void MessageListModel : : sortMessage s ( std : : vector < MessageId > & new_msg s ) {
void MessageListModel : : sortItem s ( std : : vector < MessageListModel : : Item > & item s ) {
auto do_sort = [ order = sort_order ] ( std : : vector < MessageId > & m , auto proj ) {
auto do_sort = [ order = sort_order ] ( std : : vector < MessageListModel : : Item > & m , auto proj ) {
std : : sort ( m . begin ( ) , m . end ( ) , [ order , proj = std : : move ( proj ) ] ( auto & l , auto & r ) {
std : : stable_s ort ( m . begin ( ) , m . end ( ) , [ order , proj = std : : move ( proj ) ] ( auto & l , auto & r ) {
return order = = Qt : : AscendingOrder ? proj ( l ) < proj ( r ) : proj ( l ) > proj ( r ) ;
return order = = Qt : : AscendingOrder ? proj ( l ) < proj ( r ) : proj ( l ) > proj ( r ) ;
} ) ;
} ) ;
} ;
} ;
switch ( sort_column ) {
switch ( sort_column ) {
case Column : : NAME : do_sort ( new_msg s, [ ] ( auto & id ) { return std : : make_pair ( msgName ( id ) , id ) ; } ) ; break ;
case Column : : NAME : do_sort ( item s, [ ] ( auto & item ) { return std : : tie ( item . name , item . id ) ; } ) ; break ;
case Column : : SOURCE : do_sort ( new_msg s, [ ] ( auto & id ) { return std : : tie ( id . source , id ) ; } ) ; break ;
case Column : : SOURCE : do_sort ( item s, [ ] ( auto & item ) { return std : : tie ( item . i d . source , item . id ) ; } ) ; break ;
case Column : : ADDRESS : do_sort ( new_msg s, [ ] ( auto & id ) { return std : : tie ( id . address , id ) ; } ) ; break ;
case Column : : ADDRESS : do_sort ( item s, [ ] ( auto & item ) { return std : : tie ( item . i d . address , item . id ) ; } ) ; break ;
case Column : : NODE : do_sort ( new_msg s, [ ] ( auto & id ) { return std : : make_pair ( msg_node_from_id ( id ) , id ) ; } ) ; break ;
case Column : : NODE : do_sort ( item s, [ ] ( auto & item ) { return std : : tie ( item . node , item . id ) ; } ) ; break ;
case Column : : FREQ : do_sort ( new_msg s, [ ] ( auto & id ) { return std : : tie ( can - > lastMessage ( id ) . freq , id ) ; } ) ; break ;
case Column : : FREQ : do_sort ( item s, [ ] ( auto & item ) { return std : : tie ( item . data - > freq , item . id ) ; } ) ; break ;
case Column : : COUNT : do_sort ( new_msg s, [ ] ( auto & id ) { return std : : tie ( can - > lastMessage ( id ) . count , id ) ; } ) ; break ;
case Column : : COUNT : do_sort ( item s, [ ] ( auto & item ) { return std : : tie ( item . data - > count , item . id ) ; } ) ; break ;
}
}
}
}
@ -275,83 +253,85 @@ static bool parseRange(const QString &filter, uint32_t value, int base = 10) {
return ok & & value > = min & & value < = max ;
return ok & & value > = min & & value < = max ;
}
}
bool MessageListModel : : matchMessage ( const MessageId & id , const CanData & data , const QMap < int , QString > & filters ) {
bool MessageListModel : : match ( const MessageListModel : : Item & item ) {
if ( filters_ . isEmpty ( ) )
return true ;
bool match = true ;
bool match = true ;
for ( auto it = filters . cbegin ( ) ; it ! = filters . cend ( ) & & match ; + + it ) {
for ( auto it = filters_ . cbegin ( ) ; it ! = filters_ . cend ( ) & & match ; + + it ) {
const QString & txt = it . value ( ) ;
const QString & txt = it . value ( ) ;
QRegularExpression re ( txt , QRegularExpression : : CaseInsensitiveOption | QRegularExpression : : DotMatchesEverythingOption ) ;
switch ( it . key ( ) ) {
switch ( it . key ( ) ) {
case Column : : NAME : {
case Column : : NAME : {
const auto msg = dbc ( ) - > msg ( id ) ;
match = item . name . contains ( txt , Qt : : CaseInsensitive ) ;
match = re . match ( msg ? msg - > name : UNTITLED ) . hasMatch ( ) ;
if ( ! match ) {
match = match | | ( msg & & std : : any_of ( msg - > sigs . cbegin ( ) , msg - > sigs . cend ( ) ,
const auto m = dbc ( ) - > msg ( item . id ) ;
[ & re ] ( const auto & s ) { return re . match ( s - > name ) . hasMatch ( ) ; } ) ) ;
match = m & & std : : any_of ( m - > sigs . cbegin ( ) , m - > sigs . cend ( ) ,
[ & txt ] ( const auto & s ) { return s - > name . contains ( txt , Qt : : CaseInsensitive ) ; } ) ;
}
break ;
break ;
}
}
case Column : : SOURCE :
case Column : : SOURCE :
match = parseRange ( txt , id . source ) ;
match = parseRange ( txt , item . i d . source ) ;
break ;
break ;
case Column : : ADDRESS : {
case Column : : ADDRESS :
match = re . match ( QString : : number ( id . address , 16 ) ) . hasMatch ( ) ;
match = QString : : number ( item . id . address , 16 ) . contains ( txt , Qt : : CaseInsensitive ) ;
match = match | | parseRange ( txt , id . address , 16 ) ;
match = match | | parseRange ( txt , item . i d . address , 16 ) ;
break ;
break ;
}
case Column : : NODE :
case Column : : NODE :
match = re . match ( msg_node_from_id ( id ) ) . hasMatch ( ) ;
match = item . node . contains ( txt , Qt : : CaseInsensitive ) ;
break ;
break ;
case Column : : FREQ :
case Column : : FREQ :
// TODO: Hide stale messages?
// TODO: Hide stale messages?
match = parseRange ( txt , data . freq ) ;
match = parseRange ( txt , item . data - > freq ) ;
break ;
break ;
case Column : : COUNT :
case Column : : COUNT :
match = parseRange ( txt , data . count ) ;
match = parseRange ( txt , item . data - > count ) ;
break ;
break ;
case Column : : DATA : {
case Column : : DATA :
match = QString ( data . dat . toHex ( ) ) . contains ( txt , Qt : : CaseInsensitive ) ;
match = utils : : toHex ( item . data - > dat ) . contains ( txt , Qt : : CaseInsensitive ) ;
match = match | | re . match ( QString ( data . dat . toHex ( ) ) ) . hasMatch ( ) ;
match = match | | re . match ( QString ( data . dat . toHex ( ' ' ) ) ) . hasMatch ( ) ;
break ;
break ;
}
}
}
}
}
return match ;
return match ;
}
}
void MessageListModel : : filterAndSort ( ) {
void MessageListModel : : filterAndSort ( bool force_reset ) {
std : : vector < MessageId > new_msgs ;
// merge CAN and DBC messages
new_msgs . reserve ( can - > last_msgs . size ( ) + dbc_address . size ( ) ) ;
std : : vector < MessageId > all_messages ;
all_messages . reserve ( can - > lastMessages ( ) . size ( ) + dbc_messages_ . size ( ) ) ;
auto address = dbc_address ;
auto dbc_msgs = dbc_messages_ ;
for ( auto it = can - > last_msgs . cbegin ( ) ; it ! = can - > last_msgs . cend ( ) ; + + it ) {
for ( const auto & [ id , m ] : can - > lastMessages ( ) ) {
if ( filter_str . isEmpty ( ) | | matchMessage ( it . key ( ) , it . value ( ) , filter_str ) ) {
all_messages . push_back ( id ) ;
new_msgs . push_back ( it . key ( ) ) ;
dbc_msgs . erase ( MessageId { . source = INVALID_SOURCE , . address = id . address } ) ;
}
address . remove ( it . key ( ) . address ) ;
}
}
std : : copy ( dbc_msgs . begin ( ) , dbc_msgs . end ( ) , std : : back_inserter ( all_messages ) ) ;
// merge all DBC messages
// filter and sort
for ( auto & addr : address ) {
std : : vector < Item > items ;
MessageId id { . source = INVALID_SOURCE , . address = addr } ;
for ( const auto & id : all_messages ) {
if ( filter_str . isEmpty ( ) | | matchMessage ( id , { } , filter_str ) ) {
auto msg = dbc ( ) - > msg ( id ) ;
new_msgs . push_back ( id ) ;
Item item = { . id = id ,
}
. name = msg ? msg - > name : UNTITLED ,
. node = msg ? msg - > transmitter : QString ( ) ,
. data = & can - > lastMessage ( id ) } ;
if ( match ( item ) )
items . emplace_back ( item ) ;
}
}
sortItems ( items ) ;
sortMessages ( new_msgs ) ;
if ( force_reset | | items_ ! = items ) {
if ( msgs ! = new_msgs ) {
beginResetModel ( ) ;
beginResetModel ( ) ;
msgs = std : : move ( new_msg s) ;
items_ = std : : move ( items ) ;
endResetModel ( ) ;
endResetModel ( ) ;
}
}
}
}
void MessageListModel : : msgsReceived ( const QHash < MessageId , CanData > * new_msgs , bool has_new_ids ) {
void MessageListModel : : msgsReceived ( const std : : set < MessageId > * new_msgs , bool has_new_ids ) {
if ( has_new_ids | | filter_str . contains ( Column : : FREQ ) | | filter_str . contains ( Column : : COUNT ) | | filter_str . contains ( Column : : DATA ) ) {
if ( has_new_ids | | filters_ . contains ( Column : : FREQ ) | | filters_ . contains ( Column : : COUNT ) | | filters_ . contains ( Column : : DATA ) ) {
filterAndSort ( ) ;
filterAndSort ( ) ;
}
}
for ( int i = 0 ; i < msgs . size ( ) ; + + i ) {
for ( int i = 0 ; i < items_ . size ( ) ; + + i ) {
if ( new_msgs - > contains ( msgs [ i ] ) ) {
if ( ! new_msgs | | new_msgs - > count ( items_ [ i ] . id ) ) {
for ( int col = Column : : FREQ ; col < columnCount ( ) ; + + col )
for ( int col = Column : : FREQ ; col < columnCount ( ) ; + + col )
emit dataChanged ( index ( i , col ) , index ( i , col ) , { Qt : : DisplayRole } ) ;
emit dataChanged ( index ( i , col ) , index ( i , col ) , { Qt : : DisplayRole } ) ;
}
}
@ -359,31 +339,13 @@ void MessageListModel::msgsReceived(const QHash<MessageId, CanData> *new_msgs, b
}
}
void MessageListModel : : sort ( int column , Qt : : SortOrder order ) {
void MessageListModel : : sort ( int column , Qt : : SortOrder order ) {
if ( column ! = columnCount ( ) - 1 ) {
if ( column ! = Column : : DATA ) {
sort_column = column ;
sort_column = column ;
sort_order = order ;
sort_order = order ;
filterAndSort ( ) ;
filterAndSort ( ) ;
}
}
}
}
void MessageListModel : : suppress ( ) {
const double cur_ts = can - > currentSec ( ) ;
for ( auto & id : msgs ) {
auto & can_data = can - > lastMessage ( id ) ;
for ( int i = 0 ; i < can_data . dat . size ( ) ; i + + ) {
const double dt = cur_ts - can_data . last_change_t [ i ] ;
if ( dt < 2.0 ) {
suppressed_bytes . insert ( { id , i } ) ;
}
}
}
}
void MessageListModel : : clearSuppress ( ) {
suppressed_bytes . clear ( ) ;
}
// MessageView
// MessageView
void MessageView : : drawRow ( QPainter * painter , const QStyleOptionViewItem & option , const QModelIndex & index ) const {
void MessageView : : drawRow ( QPainter * painter , const QStyleOptionViewItem & option , const QModelIndex & index ) const {
@ -414,14 +376,11 @@ void MessageView::updateBytesSectionSize() {
auto delegate = ( ( MessageBytesDelegate * ) itemDelegate ( ) ) ;
auto delegate = ( ( MessageBytesDelegate * ) itemDelegate ( ) ) ;
int max_bytes = 8 ;
int max_bytes = 8 ;
if ( ! delegate - > multipleLines ( ) ) {
if ( ! delegate - > multipleLines ( ) ) {
for ( auto it = can - > last_msgs . constBegin ( ) ; it ! = can - > last_msgs . constEnd ( ) ; + + it ) {
for ( const auto & [ _ , m ] : can - > lastMessages ( ) ) {
max_bytes = std : : max ( max_bytes , it . value ( ) . dat . size ( ) ) ;
max_bytes = std : : max < int > ( max_bytes , m . dat . size ( ) ) ;
}
}
}
}
int width = delegate - > widthForBytes ( max_bytes ) ;
header ( ) - > resizeSection ( MessageListModel : : Column : : DATA , delegate - > sizeForBytes ( max_bytes ) . width ( ) ) ;
if ( header ( ) - > sectionSize ( MessageListModel : : Column : : DATA ) ! = width ) {
header ( ) - > resizeSection ( MessageListModel : : Column : : DATA , width ) ;
}
}
}
// MessageViewHeader
// MessageViewHeader
@ -446,8 +405,7 @@ void MessageViewHeader::updateHeaderPositions() {
for ( int i = 0 ; i < count ( ) ; i + + ) {
for ( int i = 0 ; i < count ( ) ; i + + ) {
if ( editors [ i ] ) {
if ( editors [ i ] ) {
int h = editors [ i ] - > sizeHint ( ) . height ( ) ;
int h = editors [ i ] - > sizeHint ( ) . height ( ) ;
editors [ i ] - > move ( sectionViewportPosition ( i ) , sz . height ( ) ) ;
editors [ i ] - > setGeometry ( sectionViewportPosition ( i ) , sz . height ( ) , sectionSize ( i ) , h ) ;
editors [ i ] - > resize ( sectionSize ( i ) , h ) ;
editors [ i ] - > setHidden ( isSectionHidden ( i ) ) ;
editors [ i ] - > setHidden ( isSectionHidden ( i ) ) ;
}
}
}
}