/* ==================================================================== * Copyright (c) 2003-2006, Martin Hauner * http://subcommander.tigris.org * * Subcommander is licensed as described in the file doc/COPYING, which * you should have received as part of this distribution. * ==================================================================== */ // sc #include "TextGlueWidget.h" #include "sublib/Line.h" #include "sublib/TextModel.h" #include "sublib/NullTextModel.h" #include "PainterSetup.h" #include "DiffInfoModel.h" #include "TextPositionCalculator.h" #include "ScrollPositionCalculator.h" #include "Conflict.h" // sys #include #include #include "util/max.h" // qt //#include //#include #include #include "ConflictMarkerWidget.h" static const int dashLinePad = 1; QColor TextGlueWidget::_bgDash(255,255,255); QColor TextGlueWidget::_fgDash(150,150,150); QColor TextGlueWidget::_bg(255,255,255); QColor TextGlueWidget::_fg(230,230,230); QColor TextGlueWidget::_fgMerge(160,170,195); static NullTextModel nullModel; TextGlueWidget::TextGlueWidget( QWidget *parent, const char *name ) : QWidget( parent, name ), _model(0), _left(&nullModel), _right(&nullModel), _lines(0), _flags(0), _ypos(0) { _lnColumns = 3; _lnLeftPad = 3; _lnRightPad = 3; setSizePolicy( QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding) ); setBackgroundMode( Qt::NoBackground ); } TextGlueWidget::~TextGlueWidget() { } void TextGlueWidget::setModel( DiffInfoModel* model ) { _model = model; } void TextGlueWidget::setModel( TextModel* left, TextModel* right ) { _left = left; _right = right; updateGeometry(); update(); } QColor TextGlueWidget::getColor( DiffInfo& di, bool left ) { if( di.getDiffNumber() == _currDiff ) { switch( di.getMergeType() ) { case msModified: { if( left ) { return _fgMerge; } return QColor(0,0,0); } case msLatest: { if( ! left ) { return _fgMerge; } return QColor(0,0,0); } //case msNotMerged: //case msOriginal: default: { return QColor(0,0,0); } } } return _fg; } void TextGlueWidget::paintEvent( QPaintEvent *e ) { QRect pr = e->rect(); PainterSetup ps(this,pr); QPainter& pp = ps.getPainter(); //pp.setPen(_fg); // grey... pp.setBackgroundColor(_bg); QFontMetrics m(font()); TextPositionCalculator tpc( m, pr, 0, _ypos ); int topLine = tpc.getTopLine(); int botLine = tpc.getBottomLine(); int lnDefWidth = sizeHint().width(); for( int curLine = topLine; curLine <= botLine; curLine++ ) { // clear line background pp.eraseRect( 0, tpc.getLineY(curLine), lnDefWidth, m.height() ); if( ! _model ) { continue; } // the block stuff below doesn't like an invalid line but we need // the clear line above.. sc::Size maxLine = std::max(_left->getLineCnt(),_right->getLineCnt()); if( (sc::Size)curLine >= maxLine ) { continue; } Line lline = _left->getLine(curLine); DiffInfo& linfo = _model->getInfo( lline.getBlockNr() ); const BlockInfo& lb = linfo.getBlockInfo(); QColor lcolor = getColor( linfo, true ); Line rline = _right->getLine(curLine); DiffInfo& rinfo = _model->getInfo( rline.getBlockNr() ); const BlockInfo& rb = rinfo.getBlockInfo(); QColor rcolor = getColor( rinfo, false ); if( lb.getStart() == curLine && (lline.isDifference() || rline.isDifference()) ) { if( linfo.getDiffNumber() == _currDiff || rinfo.getDiffNumber() == _currDiff ) { pp.setPen(QColor(0,0,0)); } else { pp.setPen(_fg); } // draw text centered char lnBuf[32]; int lnLength = sprintf( lnBuf, "%d", linfo.getDiffNumber() ); int lnWidth = m.width( lnBuf, lnLength ); pp.drawText( (lnDefWidth/2)-(lnWidth/2), tpc.getTextY(curLine), lnBuf, lnLength ); } if( lline.isDifference() ) { pp.setPen( lcolor ); if( lb.getStart() == curLine ) { pp.drawRect( 2, tpc.getLineY(curLine), 2, 2 ); } pp.drawRect( 4, tpc.getLineY(curLine), 2, m.height() ); } if( rline.isDifference() ) { pp.setPen( rcolor ); if( rb.getStart() == curLine ) { pp.drawRect( lnDefWidth-4, tpc.getLineY(curLine), 2, 2 ); } pp.drawRect( lnDefWidth-6, tpc.getLineY(curLine), 2, m.height() ); } } // left dash line pp.setPen( _bgDash ); pp.drawLine( 0, pr.y(), 0, pr.y()+pr.height() ); pp.setPen( _fgDash ); for( int d = pr.y()+(_ypos + pr.y())%2; d < pr.y()+pr.height(); d+=2 ) { pp.drawPoint( 0, d ); } // right dash line pp.setPen( _bgDash ); pp.drawLine( lnDefWidth-dashLinePad, pr.y(), lnDefWidth-dashLinePad, pr.y()+pr.height() ); pp.setPen( _fgDash ); for( int d = pr.y()+(_ypos + pr.y())%2; d < pr.y()+pr.height(); d+=2 ) { pp.drawPoint( lnDefWidth-dashLinePad, d ); } } void TextGlueWidget::setScrollPosY( int ypos ) { ScrollPositionCalculator spc; int oy = _ypos; int ny = spc.calcPos( oy, ypos, height(), sizeHint().height() ); if( oy == ny ) { return; } _ypos = ny; super::scroll( 0, oy - _ypos ); } void TextGlueWidget::setLineCnt( sc::Size l ) { _lines = l; } void TextGlueWidget::setActiveDiff( int num ) { _currDiff = num; update(); } QSize TextGlueWidget::sizeHint() const { QFontMetrics m(font()); sc::Size width = m.width('x')*_lnColumns + _lnLeftPad + _lnRightPad + 2*dashLinePad; sc::Size height = m.height() *_lines; return QSize( (int)width, (int)height ); } #if 0 int TextGlueWidget::width() const { return super::width(); } int TextGlueWidget::height() const { return super::height(); } #endif #if 0 DiffInfos infos = _model->getInfos(); DiffInfo info; for( DiffInfos::iterator it = infos.begin(); it != infos.end(); it++ ) { const DiffInfo& info = (*it); if( info.getBlockInfo().getStart() < topLine ) { info = } } for( DiffInfos::iterator it = infos.begin(); it != infos.end(); it++ ) { const DiffInfo& info = (*it); if( info.getType() != ctCommon ) { } } #endif