# include  "tools/cabana/messageswidget.h" 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <limits> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QCheckBox> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QHBoxLayout> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QPainter> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QPushButton> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QScrollBar> 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <QVBoxLayout> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								# 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 )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QVBoxLayout  * main_layout  =  new  QVBoxLayout ( this ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  main_layout - > setContentsMargins ( 0 ,  0 ,  0 ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  main_layout - > setSpacing ( 0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // toolbar
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  main_layout - > addWidget ( createToolBar ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // message table
   
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  view  =  new  MessageView ( this ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  model  =  new  MessageListModel ( this ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  header  =  new  MessageViewHeader ( this ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  view - > setItemDelegate ( delegate  =  new  MessageBytesDelegate ( view ,  settings . multiple_lines_bytes ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  view - > setHeader ( header ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  view - > setModel ( model ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view - > setSortingEnabled ( true ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  view - > sortByColumn ( MessageListModel : : Column : : NAME ,  Qt : : AscendingOrder ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  view - > setAllColumnsShowFocus ( true ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view - > setEditTriggers ( QAbstractItemView : : NoEditTriggers ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  view - > setItemsExpandable ( false ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view - > setIndentation ( 0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view - > setRootIsDecorated ( false ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // Must be called before setting any header parameters to avoid overriding
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  restoreHeaderState ( settings . message_header_state ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  header - > setSectionsMovable ( true ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  header - > setSectionResizeMode ( MessageListModel : : Column : : DATA ,  QHeaderView : : Fixed ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  header - > setStretchLastSection ( true ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  header - > setContextMenuPolicy ( Qt : : CustomContextMenu ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  main_layout - > addWidget ( view ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // suppress
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QHBoxLayout  * suppress_layout  =  new  QHBoxLayout ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  suppress_add  =  new  QPushButton ( " Suppress Highlighted " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  suppress_clear  =  new  QPushButton ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  suppress_layout - > addWidget ( suppress_add ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  suppress_layout - > addWidget ( suppress_clear ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QCheckBox  * suppress_defined_signals  =  new  QCheckBox ( tr ( " Suppress Defined Signals " ) ,  this ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  suppress_defined_signals - > setChecked ( settings . suppress_defined_signals ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  suppress_layout - > addWidget ( suppress_defined_signals ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  main_layout - > addLayout ( suppress_layout ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // signals/slots
   
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( menu ,  & QMenu : : aboutToShow ,  this ,  & MessagesWidget : : menuAboutToShow ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( header ,  & MessageViewHeader : : filtersUpdated ,  model ,  & MessageListModel : : setFilterStrings ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( header ,  & MessageViewHeader : : customContextMenuRequested ,  this ,  & MessagesWidget : : headerContextMenuEvent ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( view - > horizontalScrollBar ( ) ,  & QScrollBar : : valueChanged ,  header ,  & MessageViewHeader : : updateHeaderPositions ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( suppress_defined_signals ,  & QCheckBox : : stateChanged ,  [ = ] ( int  state )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    settings . suppress_defined_signals  =  ( state  = =  Qt : : Checked ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    emit  settings . changed ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( can ,  & AbstractStream : : msgsReceived ,  model ,  & MessageListModel : : msgsReceived ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( dbc ( ) ,  & DBCManager : : DBCFileChanged ,  this ,  & MessagesWidget : : dbcModified ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( UndoStack : : instance ( ) ,  & QUndoStack : : indexChanged ,  this ,  & MessagesWidget : : dbcModified ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( model ,  & MessageListModel : : modelReset ,  [ this ] ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( current_msg_id )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      selectMessage ( * current_msg_id ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    view - > updateBytesSectionSize ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( view - > selectionModel ( ) ,  & QItemSelectionModel : : currentChanged ,  [ = ] ( const  QModelIndex  & current ,  const  QModelIndex  & previous )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( current . isValid ( )  & &  current . row ( )  <  model - > msgs . size ( ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      auto  & id  =  model - > msgs [ current . row ( ) ] ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! current_msg_id  | |  id  ! =  * current_msg_id )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        current_msg_id  =  id ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        emit  msgSelectionChanged ( * current_msg_id ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( suppress_add ,  & QPushButton : : clicked ,  [ = ] ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    model - > suppress ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    updateSuppressedButtons ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QObject : : connect ( suppress_clear ,  & QPushButton : : clicked ,  [ = ] ( )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    model - > clearSuppress ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    updateSuppressedButtons ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  updateSuppressedButtons ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  setWhatsThis ( tr ( R " ( 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    < b > Message  View < / b > < br / > 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    < ! - -  TODO :  add  descprition  here  - - > 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    < span  style = " color:gray " > Byte  color < / span > < br  / > 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    < span  style = " color:gray; " > ■  < / span >  constant  changing < br  / > 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    < span  style = " color:blue; " > ■  < / span >  increasing < br  / > 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    < span  style = " color:red; " > ■  < / span >  decreasing 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ) " )); 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								QToolBar  * MessagesWidget : : createToolBar ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QToolBar  * toolbar  =  new  QToolBar ( this ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  toolbar - > setIconSize ( { 12 ,  12 } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  toolbar - > addWidget ( num_msg_label  =  new  QLabel ( this ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  num_msg_label - > setSizePolicy ( QSizePolicy : : Expanding ,  QSizePolicy : : Preferred ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  views_btn  =  toolbar - > addAction ( utils : : icon ( " three-dots " ) ,  tr ( " View... " ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  views_btn - > setMenu ( menu ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  view_button  =  qobject_cast < QToolButton  * > ( toolbar - > widgetForAction ( views_btn ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view_button - > setPopupMode ( QToolButton : : InstantPopup ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view_button - > setToolButtonStyle ( Qt : : ToolButtonIconOnly ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view_button - > setStyleSheet ( " QToolButton::menu-indicator { image: none; } " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  toolbar ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessagesWidget : : dbcModified ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  num_msg_label - > setText ( tr ( " %1 Messages, %2 Signals " ) . arg ( dbc ( ) - > msgCount ( ) ) . arg ( dbc ( ) - > signalCount ( ) ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  model - > dbcModified ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessagesWidget : : selectMessage ( const  MessageId  & msg_id )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  auto  it  =  std : : find ( model - > msgs . cbegin ( ) ,  model - > msgs . cend ( ) ,  msg_id ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( it  ! =  model - > msgs . cend ( ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    view - > setCurrentIndex ( model - > index ( std : : distance ( model - > msgs . cbegin ( ) ,  it ) ,  0 ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessagesWidget : : updateSuppressedButtons ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( model - > suppressed_bytes . empty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    suppress_clear - > setEnabled ( false ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    suppress_clear - > setText ( " Clear Suppressed " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }  else  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    suppress_clear - > setEnabled ( true ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    suppress_clear - > setText ( QString ( " Clear Suppressed (%1) " ) . arg ( model - > suppressed_bytes . size ( ) ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessagesWidget : : headerContextMenuEvent ( const  QPoint  & pos )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  menu - > exec ( header - > mapToGlobal ( pos ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessagesWidget : : menuAboutToShow ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  menu - > clear ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( int  i  =  0 ;  i  <  header - > count ( ) ;  + + i )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    int  logical_index  =  header - > logicalIndex ( i ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  action  =  menu - > addAction ( model - > headerData ( logical_index ,  Qt : : Horizontal ) . toString ( ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                  [ = ] ( bool  checked )  {  header - > setSectionHidden ( logical_index ,  ! checked ) ;  } ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    action - > setCheckable ( true ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    action - > setChecked ( ! header - > isSectionHidden ( logical_index ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // Can't hide the name column
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    action - > setEnabled ( logical_index  >  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  menu - > addSeparator ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  action  =  menu - > addAction ( tr ( " Mutlti-Line bytes " ) ,  this ,  & MessagesWidget : : setMultiLineBytes ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  action - > setCheckable ( true ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  action - > setChecked ( settings . multiple_lines_bytes ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessagesWidget : : setMultiLineBytes ( bool  multi )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  settings . multiple_lines_bytes  =  multi ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  delegate - > setMultipleLines ( multi ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view - > updateBytesSectionSize ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  view - > doItemsLayout ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								// MessageListModel
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								QVariant  MessageListModel : : headerData ( int  section ,  Qt : : Orientation  orientation ,  int  role )  const  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( orientation  = =  Qt : : Horizontal  & &  role  = =  Qt : : DisplayRole )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( section )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : NAME :  return  tr ( " Name " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : SOURCE :  return  tr ( " Bus " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : ADDRESS :  return  tr ( " ID " ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : NODE :  return  tr ( " Node " ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : FREQ :  return  tr ( " Freq " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : COUNT :  return  tr ( " Count " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : DATA :  return  tr ( " Bytes " ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  { } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								QVariant  MessageListModel : : data ( const  QModelIndex  & index ,  int  role )  const  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( ! index . isValid ( )  | |  index . row ( )  > =  msgs . size ( ) )  return  { } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  auto  getFreq  =  [ ] ( const  CanData  & d )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( d . freq  >  0  & &  ( can - > currentSec ( )  -  d . ts  -  1.0  /  settings . fps )  <  ( 5.0  /  d . freq ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  d . freq  > =  0.95  ?  QString : : number ( std : : nearbyint ( d . freq ) )  :  QString : : number ( d . freq ,  ' f ' ,  2 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    }  else  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      return  QStringLiteral ( " -- " ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  const  auto  & id  =  msgs [ index . row ( ) ] ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  & can_data  =  can - > lastMessage ( id ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( role  = =  Qt : : DisplayRole )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( index . column ( ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : NAME :  return  msgName ( id ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : SOURCE :  return  id . source  ! =  INVALID_SOURCE  ?  QString : : number ( id . source )  :  " N/A " ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : ADDRESS :  return  QString : : number ( id . address ,  16 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : NODE :  return  msg_node_from_id ( id ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : FREQ :  return  id . source  ! =  INVALID_SOURCE  ?  getFreq ( can_data )  :  " N/A " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : COUNT :  return  id . source  ! =  INVALID_SOURCE  ?  QString : : number ( can_data . count )  :  " N/A " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : DATA :  return  id . source  ! =  INVALID_SOURCE  ?  toHex ( can_data . dat )  :  " N/A " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  }  else  if  ( role  = =  ColorsRole )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QVector < QColor >  colors  =  can_data . colors ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! suppressed_bytes . empty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  ( int  i  =  0 ;  i  <  colors . size ( ) ;  i + + )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        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 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  msg  =  dbc ( ) - > msg ( id ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  tooltip  =  msg  ?  msg - > name  :  UNTITLED ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( msg  & &  ! msg - > comment . isEmpty ( ) )  tooltip  + =  " <br /><span style= \" color:gray; \" > "  +  msg - > comment  +  " </span> " ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  tooltip ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  { } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessageListModel : : setFilterStrings ( const  QMap < int ,  QString >  & filters )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  filter_str  =  filters ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  filterAndSort ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessageListModel : : dbcModified ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  dbc_address . clear ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for  ( const  auto  & [ _ ,  m ]  :  dbc ( ) - > getMessages ( - 1 ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    dbc_address . insert ( m . address ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  filterAndSort ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessageListModel : : sortMessages ( std : : vector < MessageId >  & new_msgs )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  auto  do_sort  =  [ order  =  sort_order ] ( std : : vector < MessageId >  & m ,  auto  proj )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    std : : sort ( 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 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  switch  ( sort_column )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Column : : NAME :  do_sort ( new_msgs ,  [ ] ( auto  & id )  {  return  std : : make_pair ( msgName ( id ) ,  id ) ;  } ) ;  break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Column : : SOURCE :  do_sort ( new_msgs ,  [ ] ( auto  & id )  {  return  std : : tie ( id . source ,  id ) ;  } ) ;  break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Column : : ADDRESS :  do_sort ( new_msgs ,  [ ] ( auto  & id )  {  return  std : : tie ( id . address ,  id ) ; } ) ;  break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Column : : NODE :  do_sort ( new_msgs ,  [ ] ( auto  & id )  {  return  std : : make_pair ( msg_node_from_id ( id ) ,  id ) ; } ) ;  break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Column : : FREQ :  do_sort ( new_msgs ,  [ ] ( auto  & id )  {  return  std : : tie ( can - > lastMessage ( id ) . freq ,  id ) ;  } ) ;  break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  Column : : COUNT :  do_sort ( new_msgs ,  [ ] ( auto  & id )  {  return  std : : tie ( can - > lastMessage ( id ) . count ,  id ) ;  } ) ;  break ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  parseRange ( const  QString  & filter ,  uint32_t  value ,  int  base  =  10 )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // Parse out filter string into a range (e.g. "1" -> {1, 1}, "1-3" -> {1, 3}, "1-" -> {1, inf})
   
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  unsigned  int  min  =  std : : numeric_limits < unsigned  int > : : min ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unsigned  int  max  =  std : : numeric_limits < unsigned  int > : : max ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  auto  s  =  filter . split ( ' - ' ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  bool  ok  =  s . size ( )  > =  1  & &  s . size ( )  < =  2 ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( ok  & &  ! s [ 0 ] . isEmpty ( ) )  min  =  s [ 0 ] . toUInt ( & ok ,  base ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( ok  & &  s . size ( )  = =  1 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    max  =  min ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }  else  if  ( ok  & &  s . size ( )  = =  2  & &  ! s [ 1 ] . isEmpty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    max  =  s [ 1 ] . toUInt ( & ok ,  base ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  ok  & &  value  > =  min  & &  value  < =  max ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  MessageListModel : : matchMessage ( const  MessageId  & id ,  const  CanData  & data ,  const  QMap < int ,  QString >  & filters )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  bool  match  =  true ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for  ( auto  it  =  filters . cbegin ( ) ;  it  ! =  filters . cend ( )  & &  match ;  + + it )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    const  QString  & txt  =  it . value ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    QRegularExpression  re ( txt ,  QRegularExpression : : CaseInsensitiveOption  |  QRegularExpression : : DotMatchesEverythingOption ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( it . key ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : NAME :  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        const  auto  msg  =  dbc ( ) - > msg ( id ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        match  =  re . match ( msg  ?  msg - > name  :  UNTITLED ) . hasMatch ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        match  =  match  | |  ( msg  & &  std : : any_of ( msg - > sigs . cbegin ( ) ,  msg - > sigs . cend ( ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                             [ & re ] ( const  auto  & s )  {  return  re . match ( s - > name ) . hasMatch ( ) ;  } ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : SOURCE : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        match  =  parseRange ( txt ,  id . source ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : ADDRESS :  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        match  =  re . match ( QString : : number ( id . address ,  16 ) ) . hasMatch ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        match  =  match  | |  parseRange ( txt ,  id . address ,  16 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : NODE : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        match  =  re . match ( msg_node_from_id ( id ) ) . hasMatch ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : FREQ : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        // TODO: Hide stale messages?
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        match  =  parseRange ( txt ,  data . freq ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      case  Column : : COUNT : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        match  =  parseRange ( txt ,  data . count ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      case  Column : : DATA :  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        match  =  QString ( data . dat . toHex ( ) ) . contains ( txt ,  Qt : : CaseInsensitive ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        match  =  match  | |  re . match ( QString ( data . dat . toHex ( ) ) ) . hasMatch ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        match  =  match  | |  re . match ( QString ( data . dat . toHex ( '   ' ) ) ) . hasMatch ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        break ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  match ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessageListModel : : filterAndSort ( )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  std : : vector < MessageId >  new_msgs ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  new_msgs . reserve ( can - > last_msgs . size ( )  +  dbc_address . size ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  address  =  dbc_address ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( auto  it  =  can - > last_msgs . cbegin ( ) ;  it  ! =  can - > last_msgs . cend ( ) ;  + + it )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( filter_str . isEmpty ( )  | |  matchMessage ( it . key ( ) ,  it . value ( ) ,  filter_str ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      new_msgs . push_back ( it . key ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    address . remove ( it . key ( ) . address ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // merge all DBC messages
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( auto  & addr  :  address )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MessageId  id { . source  =  INVALID_SOURCE ,  . address  =  addr } ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( filter_str . isEmpty ( )  | |  matchMessage ( id ,  { } ,  filter_str ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      new_msgs . push_back ( id ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  sortMessages ( new_msgs ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( msgs  ! =  new_msgs )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    beginResetModel ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    msgs  =  std : : move ( new_msgs ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    endResetModel ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  MessageListModel : : msgsReceived ( const  QHash < MessageId ,  CanData >  * 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 ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    filterAndSort ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for  ( int  i  =  0 ;  i  <  msgs . size ( ) ;  + + i )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( new_msgs - > contains ( msgs [ i ] ) )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      for  ( int  col  =  Column : : FREQ ;  col  <  columnCount ( ) ;  + + col ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        emit  dataChanged ( index ( i ,  col ) ,  index ( i ,  col ) ,  { Qt : : DisplayRole } ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessageListModel : : sort ( int  column ,  Qt : : SortOrder  order )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( column  ! =  columnCount ( )  -  1 )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sort_column  =  column ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    sort_order  =  order ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    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
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessageView : : drawRow ( QPainter  * painter ,  const  QStyleOptionViewItem  & option ,  const  QModelIndex  & index )  const  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QTreeView : : drawRow ( painter ,  option ,  index ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  int  gridHint  =  style ( ) - > styleHint ( QStyle : : SH_Table_GridLineColor ,  & option ,  this ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  const  QColor  gridColor  =  QColor : : fromRgba ( static_cast < QRgb > ( gridHint ) ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QPen  old_pen  =  painter - > pen ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  painter - > setPen ( gridColor ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  painter - > drawLine ( option . rect . left ( ) ,  option . rect . bottom ( ) ,  option . rect . right ( ) ,  option . rect . bottom ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  y  =  option . rect . y ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  painter - > translate ( visualRect ( model ( ) - > index ( 0 ,  0 ) ) . x ( )  -  indentation ( )  -  .5 ,  - .5 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( int  i  =  0 ;  i  <  header ( ) - > count ( ) ;  + + i )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    painter - > translate ( header ( ) - > sectionSize ( header ( ) - > logicalIndex ( i ) ) ,  0 ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    painter - > drawLine ( 0 ,  y ,  0 ,  y  +  option . rect . height ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  painter - > setPen ( old_pen ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  painter - > resetTransform ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessageView : : dataChanged ( const  QModelIndex  & topLeft ,  const  QModelIndex  & bottomRight ,  const  QVector < int >  & roles )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  // Bypass the slow call to QTreeView::dataChanged.
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // QTreeView::dataChanged will invalidate the height cache and that's what we don't need in MessageView.
   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QAbstractItemView : : dataChanged ( topLeft ,  bottomRight ,  roles ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessageView : : updateBytesSectionSize ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  auto  delegate  =  ( ( MessageBytesDelegate  * ) itemDelegate ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  max_bytes  =  8 ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( ! delegate - > multipleLines ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto  it  =  can - > last_msgs . constBegin ( ) ;  it  ! =  can - > last_msgs . constEnd ( ) ;  + + it )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      max_bytes  =  std : : max ( max_bytes ,  it . value ( ) . dat . size ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  int  width  =  delegate - > widthForBytes ( max_bytes ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( header ( ) - > sectionSize ( MessageListModel : : Column : : DATA )  ! =  width )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    header ( ) - > resizeSection ( MessageListModel : : Column : : DATA ,  width ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								// MessageViewHeader
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								MessageViewHeader : : MessageViewHeader ( QWidget  * parent )  :  QHeaderView ( Qt : : Horizontal ,  parent )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QObject : : connect ( this ,  & QHeaderView : : sectionResized ,  this ,  & MessageViewHeader : : updateHeaderPositions ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QObject : : connect ( this ,  & QHeaderView : : sectionMoved ,  this ,  & MessageViewHeader : : updateHeaderPositions ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessageViewHeader : : updateFilters ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QMap < int ,  QString >  filters ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( int  i  =  0 ;  i  <  count ( ) ;  i + + )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( editors [ i ]  & &  ! editors [ i ] - > text ( ) . isEmpty ( ) )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      filters [ i ]  =  editors [ i ] - > text ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  emit  filtersUpdated ( filters ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessageViewHeader : : updateHeaderPositions ( )  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QSize  sz  =  QHeaderView : : sizeHint ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  for  ( int  i  =  0 ;  i  <  count ( ) ;  i + + )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( editors [ i ] )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      int  h  =  editors [ i ] - > sizeHint ( ) . height ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      editors [ i ] - > move ( sectionViewportPosition ( i ) ,  sz . height ( ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      editors [ i ] - > resize ( sectionSize ( i ) ,  h ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      editors [ i ] - > setHidden ( isSectionHidden ( i ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  MessageViewHeader : : updateGeometries ( )  { 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for  ( int  i  =  0 ;  i  <  count ( ) ;  i + + )  { 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! editors [ i ] )  { 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      QString  column_name  =  model ( ) - > headerData ( i ,  Qt : : Horizontal ,  Qt : : DisplayRole ) . toString ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      editors [ i ]  =  new  QLineEdit ( this ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      editors [ i ] - > setClearButtonEnabled ( true ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      editors [ i ] - > setPlaceholderText ( tr ( " Filter %1 " ) . arg ( column_name ) ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      QObject : : connect ( editors [ i ] ,  & QLineEdit : : textChanged ,  this ,  & MessageViewHeader : : updateFilters ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  } 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  setViewportMargins ( 0 ,  0 ,  0 ,  editors [ 0 ]  ?  editors [ 0 ] - > sizeHint ( ) . height ( )  :  0 ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  QHeaderView : : updateGeometries ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  updateHeaderPositions ( ) ; 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								QSize  MessageViewHeader : : sizeHint ( )  const  { 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  QSize  sz  =  QHeaderView : : sizeHint ( ) ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  return  editors [ 0 ]  ?  QSize ( sz . width ( ) ,  sz . height ( )  +  editors [ 0 ] - > height ( )  +  1 )  :  sz ; 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								}