@ -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 ) ;