@ -13,21 +13,23 @@ 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					const  int  CELL_HEIGHT  =  30 ; const  int  CELL_HEIGHT  =  30 ;  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  std : : pair < int ,  int >  getSignalRange ( const  Signal  * s )  {  
			
		
	
		
		
			
				
					
					  int  from  =  s - > is_little_endian  ?  s - > start_bit  :  bigEndianBitIndex ( s - > start_bit ) ;   
			
		
	
		
		
			
				
					
					  int  to  =  from  +  s - > size  -  1 ;   
			
		
	
		
		
			
				
					
					  return  { from ,  to } ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					BinaryView : : BinaryView ( QWidget  * parent )  :  QTableView ( parent )  { BinaryView : : BinaryView ( QWidget  * parent )  :  QTableView ( parent )  {  
			
		
	
		
		
			
				
					
					  model  =  new  BinaryViewModel ( this ) ;    model  =  new  BinaryViewModel ( this ) ;   
			
		
	
		
		
			
				
					
					  setModel ( model ) ;    setModel ( model ) ;   
			
		
	
		
		
			
				
					
					  setItemDelegate ( new  BinaryItemDelegate ( this ) ) ;    delegate  =  new  BinaryItemDelegate ( this ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  setItemDelegate ( delegate ) ;   
			
		
	
		
		
			
				
					
					  horizontalHeader ( ) - > setSectionResizeMode ( QHeaderView : : Stretch ) ;    horizontalHeader ( ) - > setSectionResizeMode ( QHeaderView : : Stretch ) ;   
			
		
	
		
		
			
				
					
					  horizontalHeader ( ) - > hide ( ) ;    horizontalHeader ( ) - > hide ( ) ;   
			
		
	
		
		
			
				
					
					  verticalHeader ( ) - > setSectionResizeMode ( QHeaderView : : Stretch ) ;    verticalHeader ( ) - > setSectionResizeMode ( QHeaderView : : Stretch ) ;   
			
		
	
		
		
			
				
					
					  setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;    setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;   
			
		
	
		
		
			
				
					
					  setMouseTracking ( true ) ;    setMouseTracking ( true ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  // replace selection model
   
			
		
	
		
		
			
				
					
					  auto  old_model  =  selectionModel ( ) ;   
			
		
	
		
		
			
				
					
					  setSelectionModel ( new  BinarySelectionModel ( model ) ) ;   
			
		
	
		
		
			
				
					
					  delete  old_model ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  QObject : : connect ( model ,  & QAbstractItemModel : : modelReset ,  [ this ] ( )  {    QObject : : connect ( model ,  & QAbstractItemModel : : modelReset ,  [ this ] ( )  {   
			
		
	
		
		
			
				
					
					    setFixedHeight ( ( CELL_HEIGHT  +  1 )  *  std : : min ( model - > rowCount ( ) ,  8 )  +  2 ) ;      setFixedHeight ( ( CELL_HEIGHT  +  1 )  *  std : : min ( model - > rowCount ( ) ,  8 )  +  2 ) ;   
			
		
	
		
		
			
				
					
					  } ) ;    } ) ;   
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -41,12 +43,42 @@ void BinaryView::highlight(const Signal *sig) { 
			
		
	
		
		
			
				
					
					  }    }   
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  BinaryView : : setSelection ( const  QRect  & rect ,  QItemSelectionModel : : SelectionFlags  flags )  {  
			
		
	
		
		
			
				
					
					  QModelIndex  tl  =  indexAt ( { qMin ( rect . left ( ) ,  rect . right ( ) ) ,  qMin ( rect . top ( ) ,  rect . bottom ( ) ) } ) ;   
			
		
	
		
		
			
				
					
					  QModelIndex  br  =  indexAt ( { qMax ( rect . left ( ) ,  rect . right ( ) ) ,  qMax ( rect . top ( ) ,  rect . bottom ( ) ) } ) ;   
			
		
	
		
		
			
				
					
					  if  ( ! tl . isValid ( )  | |  ! br . isValid ( ) )   
			
		
	
		
		
			
				
					
					    return ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  if  ( tl  <  anchor_index )  {   
			
		
	
		
		
			
				
					
					    br  =  anchor_index ;   
			
		
	
		
		
			
				
					
					  }  else  if  ( anchor_index  <  br )  {   
			
		
	
		
		
			
				
					
					    tl  =  anchor_index ;   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					  QItemSelection  selection ;   
			
		
	
		
		
			
				
					
					  for  ( int  row  =  tl . row ( ) ;  row  < =  br . row ( ) ;  + + row )  {   
			
		
	
		
		
			
				
					
					    int  left_col  =  ( row  = =  tl . row ( ) )  ?  tl . column ( )  :  0 ;   
			
		
	
		
		
			
				
					
					    int  right_col  =  ( row  = =  br . row ( ) )  ?  br . column ( )  :  7 ;   
			
		
	
		
		
			
				
					
					    selection . merge ( { model - > index ( row ,  left_col ) ,  model - > index ( row ,  right_col ) } ,  flags ) ;   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					  selectionModel ( ) - > select ( selection ,  flags ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  BinaryView : : mousePressEvent ( QMouseEvent  * event )  {  
			
		
	
		
		
			
				
					
					  delegate - > setSelectionColor ( style ( ) - > standardPalette ( ) . color ( QPalette : : Active ,  QPalette : : Highlight ) ) ;   
			
		
	
		
		
			
				
					
					  anchor_index  =  indexAt ( event - > pos ( ) ) ;   
			
		
	
		
		
			
				
					
					  if  ( getResizingSignal ( )  ! =  nullptr )  {   
			
		
	
		
		
			
				
					
					    auto  item  =  ( const  BinaryViewModel : : Item  * ) anchor_index . internalPointer ( ) ;   
			
		
	
		
		
			
				
					
					    delegate - > setSelectionColor ( item - > bg_color ) ;   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					  QTableView : : mousePressEvent ( event ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  BinaryView : : mouseMoveEvent ( QMouseEvent  * event )  { void  BinaryView : : mouseMoveEvent ( QMouseEvent  * event )  {  
			
		
	
		
		
			
				
					
					  if  ( auto  index  =  indexAt ( event - > pos ( ) ) ;  index . isValid ( ) )  {    if  ( auto  index  =  indexAt ( event - > pos ( ) ) ;  index . isValid ( ) )  {   
			
		
	
		
		
			
				
					
					    auto  item  =  ( BinaryViewModel : : Item  * ) index . internalPointer ( ) ;      auto  item  =  ( BinaryViewModel : : Item  * ) index . internalPointer ( ) ;   
			
		
	
		
		
			
				
					
					    highlight ( item - > sig ) ;      highlight ( item - > sig ) ;   
			
		
	
		
		
			
				
					
					    if  ( item - > sig )      item - > sig  ?  QToolTip : : showText ( event - > globalPos ( ) ,  item - > sig - > name . c_str ( ) ,  this ,  rect ( )  )   
			
				
				
			
		
	
		
		
			
				
					
					      QToolTip : : showText ( event - > globalPos ( ) ,  item - > sig - > name . c_str ( ) ,  this ,  rect ( ) ) ;                :  QToolTip : : hideText (  ) ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					  }    }   
			
		
	
		
		
			
				
					
					  QTableView : : mouseMoveEvent ( event ) ;    QTableView : : mouseMoveEvent ( event ) ;   
			
		
	
		
		
			
				
					
					} }  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -55,10 +87,21 @@ void BinaryView::mouseReleaseEvent(QMouseEvent *event) { 
			
		
	
		
		
			
				
					
					  QTableView : : mouseReleaseEvent ( event ) ;    QTableView : : mouseReleaseEvent ( event ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  if  ( auto  indexes  =  selectedIndexes ( ) ;  ! indexes . isEmpty ( ) )  {    if  ( auto  indexes  =  selectedIndexes ( ) ;  ! indexes . isEmpty ( ) )  {   
			
		
	
		
		
			
				
					
					    int  start_bit  =  indexes . first ( ) . row ( )  *  8  +  indexes . first ( ) . column ( ) ;      int  from  =  indexes . first ( ) . row ( )  *  8  +  indexes . first ( ) . column ( ) ;   
			
				
				
			
		
	
		
		
			
				
					
					    int  size  =  indexes . back ( ) . row ( )  *  8  +  indexes . back ( ) . column ( )  -  start_bit  +  1 ;      int  to  =  indexes . back ( ) . row ( )  *  8  +  indexes . back ( ) . column ( ) ;   
			
				
				
			
		
	
		
		
			
				
					
					    emit  cellsSelected ( start_bit ,  size ) ;      if  ( auto  sig  =  getResizingSignal ( ) )  {   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					      auto  [ sig_from ,  sig_to ]  =  getSignalRange ( sig ) ;   
			
		
	
		
		
			
				
					
					      if  ( from  > =  sig_from  & &  to  < =  sig_to )  {   // reduce size
   
			
		
	
		
		
			
				
					
					        emit ( from  = =  sig_from  ?  resizeSignal ( sig ,  to ,  sig_to )  :  resizeSignal ( sig ,  sig_from ,  from ) ) ;   
			
		
	
		
		
			
				
					
					      }  else  {   // increase size
   
			
		
	
		
		
			
				
					
					        emit  resizeSignal ( sig ,  std : : min ( from ,  sig_from ) ,  std : : max ( to ,  sig_to ) ) ;   
			
		
	
		
		
			
				
					
					      }   
			
		
	
		
		
			
				
					
					    }  else  {   
			
		
	
		
		
			
				
					
					      emit  addSignal ( from ,  to ) ;   
			
		
	
		
		
			
				
					
					    }      }   
			
		
	
		
		
			
				
					
					    clearSelection ( ) ;   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					  anchor_index  =  QModelIndex ( ) ;   
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  BinaryView : : leaveEvent ( QEvent  * event )  { void  BinaryView : : leaveEvent ( QEvent  * event )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -78,6 +121,19 @@ void BinaryView::updateState() { 
			
		
	
		
		
			
				
					
					  model - > updateState ( ) ;    model - > updateState ( ) ;   
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					const  Signal  * BinaryView : : getResizingSignal ( )  const  {  
			
		
	
		
		
			
				
					
					  if  ( anchor_index . isValid ( ) )  {   
			
		
	
		
		
			
				
					
					    auto  item  =  ( const  BinaryViewModel : : Item  * ) anchor_index . internalPointer ( ) ;   
			
		
	
		
		
			
				
					
					    if  ( item  & &  item - > sig )  {   
			
		
	
		
		
			
				
					
					      int  archor_pos  =  anchor_index . row ( )  *  8  +  anchor_index . column ( ) ;   
			
		
	
		
		
			
				
					
					      auto  [ sig_from ,  sig_to ]  =  getSignalRange ( item - > sig ) ;   
			
		
	
		
		
			
				
					
					      if  ( archor_pos  = =  sig_from  | |  archor_pos  = =  sig_to )   
			
		
	
		
		
			
				
					
					        return  item - > sig ;   
			
		
	
		
		
			
				
					
					    }   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					  return  nullptr ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// BinaryViewModel
 // BinaryViewModel
  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  BinaryViewModel : : setMessage ( const  QString  & message_id )  { void  BinaryViewModel : : setMessage ( const  QString  & message_id )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -93,8 +149,7 @@ void BinaryViewModel::setMessage(const QString &message_id) { 
			
		
	
		
		
			
				
					
					    items . resize ( row_count  *  column_count ) ;      items . resize ( row_count  *  column_count ) ;   
			
		
	
		
		
			
				
					
					    for  ( int  i  =  0 ;  i  <  dbc_msg - > sigs . size ( ) ;  + + i )  {      for  ( int  i  =  0 ;  i  <  dbc_msg - > sigs . size ( ) ;  + + i )  {   
			
		
	
		
		
			
				
					
					      const  auto  & sig  =  dbc_msg - > sigs [ i ] ;        const  auto  & sig  =  dbc_msg - > sigs [ i ] ;   
			
		
	
		
		
			
				
					
					      const  int  start  =  sig . is_little_endian  ?  sig . start_bit  :  bigEndianBitIndex ( sig . start_bit ) ;        auto  [ start ,  end ]  =  getSignalRange ( & sig ) ;   
			
				
				
			
		
	
		
		
			
				
					
					      const  int  end  =  start  +  sig . size  -  1 ;   
			
		
	
		
		
	
		
		
			
				
					
					      for  ( int  j  =  start ;  j  < =  end ;  + + j )  {        for  ( int  j  =  start ;  j  < =  end ;  + + j )  {   
			
		
	
		
		
			
				
					
					        int  idx  =  column_count  *  ( j  /  8 )  +  j  %  8 ;          int  idx  =  column_count  *  ( j  /  8 )  +  j  %  8 ;   
			
		
	
		
		
			
				
					
					        if  ( idx  > =  items . size ( ) )  {          if  ( idx  > =  items . size ( ) )  {   
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -165,21 +220,6 @@ QVariant BinaryViewModel::headerData(int section, Qt::Orientation orientation, i 
			
		
	
		
		
			
				
					
					  return  { } ;    return  { } ;   
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// BinarySelectionModel
  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					void  BinarySelectionModel : : select ( const  QItemSelection  & selection ,  QItemSelectionModel : : SelectionFlags  command )  {  
			
		
	
		
		
			
				
					
					  QItemSelection  new_selection  =  selection ;   
			
		
	
		
		
			
				
					
					  if  ( auto  indexes  =  selection . indexes ( ) ;  ! indexes . isEmpty ( ) )  {   
			
		
	
		
		
			
				
					
					    auto  [ begin_idx ,  end_idx ]  =  ( QModelIndex [ ] ) { indexes . first ( ) ,  indexes . back ( ) } ;   
			
		
	
		
		
			
				
					
					    for  ( int  row  =  begin_idx . row ( ) ;  row  < =  end_idx . row ( ) ;  + + row )  {   
			
		
	
		
		
			
				
					
					      int  left_col  =  ( row  = =  begin_idx . row ( ) )  ?  begin_idx . column ( )  :  0 ;   
			
		
	
		
		
			
				
					
					      int  right_col  =  ( row  = =  end_idx . row ( ) )  ?  end_idx . column ( )  :  7 ;   
			
		
	
		
		
			
				
					
					      new_selection . merge ( { model ( ) - > index ( row ,  left_col ) ,  model ( ) - > index ( row ,  right_col ) } ,  command ) ;   
			
		
	
		
		
			
				
					
					    }   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					  QItemSelectionModel : : select ( new_selection ,  command ) ;   
			
		
	
		
		
			
				
					
					}  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// BinaryItemDelegate
 // BinaryItemDelegate
  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					BinaryItemDelegate : : BinaryItemDelegate ( QObject  * parent )  :  QStyledItemDelegate ( parent )  { BinaryItemDelegate : : BinaryItemDelegate ( QObject  * parent )  :  QStyledItemDelegate ( parent )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -187,7 +227,7 @@ BinaryItemDelegate::BinaryItemDelegate(QObject *parent) : QStyledItemDelegate(pa 
			
		
	
		
		
			
				
					
					  small_font . setPointSize ( 6 ) ;    small_font . setPointSize ( 6 ) ;   
			
		
	
		
		
			
				
					
					  hex_font  =  QFontDatabase : : systemFont ( QFontDatabase : : FixedFont ) ;    hex_font  =  QFontDatabase : : systemFont ( QFontDatabase : : FixedFont ) ;   
			
		
	
		
		
			
				
					
					  hex_font . setBold ( true ) ;    hex_font . setBold ( true ) ;   
			
		
	
		
		
			
				
					
					  highlight _color=  QApplication : : style ( ) - > standardPalette ( ) . color ( QPalette : : Active ,  QPalette : : Highlight ) ;    selection _color=  QApplication : : style ( ) - > standardPalette ( ) . color ( QPalette : : Active ,  QPalette : : Highlight ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					QSize  BinaryItemDelegate : : sizeHint ( const  QStyleOptionViewItem  & option ,  const  QModelIndex  & index )  const  { QSize  BinaryItemDelegate : : sizeHint ( const  QStyleOptionViewItem  & option ,  const  QModelIndex  & index )  const  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -204,7 +244,7 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op 
			
		
	
		
		
			
				
					
					  // background
    // background
   
			
		
	
		
		
			
				
					
					  QColor  bg_color  =  hover  ?  hoverColor ( item - > bg_color )  :  item - > bg_color ;    QColor  bg_color  =  hover  ?  hoverColor ( item - > bg_color )  :  item - > bg_color ;   
			
		
	
		
		
			
				
					
					  if  ( option . state  &  QStyle : : State_Selected )  {    if  ( option . state  &  QStyle : : State_Selected )  {   
			
		
	
		
		
			
				
					
					    bg_color  =  highlight _color;      bg_color  =  selection _color;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  }    }   
			
		
	
		
		
			
				
					
					  painter - > fillRect ( option . rect ,  bg_color ) ;    painter - > fillRect ( option . rect ,  bg_color ) ;