/* ==================================================================== * 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 "TextLineNrWidget.h" #include "PainterSetup.h" #include "TextPositionCalculator.h" #include "ScrollPositionCalculator.h" #include "ColorId.h" #include "sublib/Line.h" #include "sublib/TextModel.h" #include "sublib/ColorStorage.h" #include "sublib/NullTextModel.h" // sys #include #include #include static int dashLinePad = 1; static int borderPad = 3; static NullTextModel NullText; TextLineNrWidget::TextLineNrWidget( QWidget *parent, unsigned long flags, const char *name ) : QWidget( parent, name ), _flags(flags), _ypos(0) { _lnColumns = 3; _lnLeftPad = borderPad; _lnRightPad = borderPad; setSizePolicy( QSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding) ); setBackgroundMode( Qt::NoBackground ); setModel(&NullText); } TextLineNrWidget::~TextLineNrWidget() { } void TextLineNrWidget::setModel( TextModel* model ) { _model = model; sc::Size lines = _model->getLineCnt(); char buf[16] = ""; _lnColumns = sprintf( buf, "%u", lines ); updateGeometry(); } void TextLineNrWidget::setFlags( unsigned long flags ) { _flags = flags; } void TextLineNrWidget::paintEvent( QPaintEvent *e ) { QRect pr = e->rect(); // Qt/X11 does crash when pr is null // todo: why is pr null? if( pr.isNull() ) return; PainterSetup ps(this,pr); QPainter& pp = ps.getPainter(); pp.setPen( ColorStorage::getColor(ColorLineNrFg) ); pp.setBackgroundColor( ColorStorage::getColor(ColorLineNrBg) ); QFontMetrics m(font()); TextPositionCalculator tpc( m, pr, 0, _ypos ); int topLine = tpc.getTopLine(); int botLine = tpc.getBottomLine(); int lnDefWidth = sizeHint().width(); // calc the first line number we have to draw // TODO // we could optimize this if we would remember the first visible line // and then count from there.... int clnr = 0; int lineNr = clnr; for( int y = -_ypos; y < tpc.getLineY(topLine); y += m.height(), clnr++ ) { Line line = _model->getLine( clnr ); if( ! line.isEmpty() ) { lineNr++; } } for( int curLine = topLine; curLine <= botLine; curLine++ ) { // clear line background pp.eraseRect( 0, tpc.getLineY(curLine), lnDefWidth, tpc.getFontHeight() ); Line line = _model->getLine( curLine ); if( ! line.isEmpty() ) { // draw right aligned line number char lnBuf[32]; int lnLength = sprintf( lnBuf, "%d", ++lineNr ); int lnWidth = m.width( lnBuf, lnLength ); int textX = 0; if( _flags & Right ) { textX = lnDefWidth-lnWidth-_lnRightPad + 1; } if( _flags & Left ) { textX = lnDefWidth-lnWidth-_lnRightPad-dashLinePad; } pp.drawText( textX, tpc.getTextY(curLine), lnBuf, lnLength ); } } int dashX = 0; if( _flags & Right ) { dashX = 0; } if( _flags & Left ) { dashX = lnDefWidth - 1; } // draw dash line pp.setPen( ColorStorage::getColor(ColorDashBg) ); pp.drawLine( dashX, pr.y(), dashX, pr.y()+pr.height() ); pp.setPen( ColorStorage::getColor(ColorDashFg) ); for( int d = pr.y()+(_ypos + pr.y())%2; d < pr.y()+pr.height(); d+=2 ) { pp.drawPoint( dashX, d ); } } void TextLineNrWidget::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 ); } QSize TextLineNrWidget::sizeHint() const { QFontMetrics m(font()); sc::Size width = m.width('x') * _lnColumns + _lnLeftPad + _lnRightPad + dashLinePad; sc::Size height = m.height() * _model->getLineCnt(); return QSize( (int)width, (int)height ); }