annotate kdiff3/src/difftextwindow.cpp @ 66:efe33e938730

0.9.86
author joachim99
date Thu, 16 Sep 2004 02:40:08 +0000
parents 8af4bb9d9a5a
children d7cafcda8c99
rev   line source
joachim99@8 1 /***************************************************************************
joachim99@8 2 difftextwindow.cpp - description
joachim99@8 3 -------------------
joachim99@8 4 begin : Mon Apr 8 2002
joachim99@58 5 copyright : (C) 2002-2004 by Joachim Eibl
joachim99@8 6 email : joachim.eibl@gmx.de
joachim99@8 7 ***************************************************************************/
joachim99@8 8
joachim99@8 9 /***************************************************************************
joachim99@8 10 * *
joachim99@8 11 * This program is free software; you can redistribute it and/or modify *
joachim99@8 12 * it under the terms of the GNU General Public License as published by *
joachim99@8 13 * the Free Software Foundation; either version 2 of the License, or *
joachim99@8 14 * (at your option) any later version. *
joachim99@8 15 * *
joachim99@8 16 ***************************************************************************/
joachim99@8 17
joachim99@8 18 #include <iostream>
joachim99@8 19 #include "diff.h"
joachim99@8 20 #include "merger.h"
joachim99@8 21 #include <qpainter.h>
joachim99@8 22 #include <assert.h>
joachim99@8 23 #include <qpixmap.h>
joachim99@8 24 #include <qstatusbar.h>
joachim99@8 25 #include <qapplication.h>
joachim99@8 26 #include <qtooltip.h>
joachim99@8 27 #include <qfont.h>
joachim99@66 28 #include <qstringlist.h>
joachim99@8 29 #include <optiondialog.h>
joachim99@8 30 #include <math.h>
joachim99@8 31 #include <qdragobject.h>
joachim99@51 32 #include <klocale.h>
joachim99@8 33
joachim99@53 34 #undef leftInfoWidth
joachim99@8 35 #define leftInfoWidth (4+m_lineNumberWidth) // Nr of information columns on left side
joachim99@8 36
joachim99@8 37
joachim99@8 38 DiffTextWindow::DiffTextWindow(
joachim99@8 39 QWidget* pParent,
joachim99@8 40 QStatusBar* pStatusBar,
joachim99@8 41 OptionDialog* pOptionDialog
joachim99@8 42 )
joachim99@8 43 : QWidget(pParent, 0, WRepaintNoErase)
joachim99@8 44 {
joachim99@8 45 setFocusPolicy( QWidget::ClickFocus );
joachim99@8 46 setAcceptDrops( true );
joachim99@8 47
joachim99@8 48 m_pOptionDialog = pOptionDialog;
joachim99@8 49 init( 0, 0, 0, 0, 0, false );
joachim99@8 50
joachim99@8 51 setBackgroundMode( PaletteBase );
joachim99@8 52 setMinimumSize(QSize(20,20));
joachim99@8 53
joachim99@8 54 m_pStatusBar = pStatusBar;
joachim99@8 55 m_bPaintingAllowed = true;
joachim99@66 56 m_bWordWrap = false;
joachim99@27 57
joachim99@27 58 setFont(m_pOptionDialog->m_font);
joachim99@8 59 }
joachim99@8 60
joachim99@8 61
joachim99@8 62 void DiffTextWindow::init(
joachim99@8 63 const QString& filename,
joachim99@58 64 const LineData* pLineData,
joachim99@8 65 int size,
joachim99@8 66 const Diff3LineVector* pDiff3LineVector,
joachim99@8 67 int winIdx,
joachim99@8 68 bool bTriple
joachim99@8 69 )
joachim99@8 70 {
joachim99@8 71 m_filename = filename;
joachim99@8 72 m_pLineData = pLineData;
joachim99@8 73 m_size = size;
joachim99@8 74 m_pDiff3LineVector = pDiff3LineVector;
joachim99@66 75 m_diff3WrapLineVector.clear();
joachim99@8 76 m_winIdx = winIdx;
joachim99@8 77
joachim99@8 78 m_firstLine = 0;
joachim99@8 79 m_oldFirstLine = -1;
joachim99@8 80 m_firstColumn = 0;
joachim99@8 81 m_oldFirstColumn = -1;
joachim99@8 82 m_bTriple = bTriple;
joachim99@8 83 m_scrollDeltaX=0;
joachim99@8 84 m_scrollDeltaY=0;
joachim99@8 85 m_bMyUpdate = false;
joachim99@8 86 m_fastSelectorLine1 = 0;
joachim99@8 87 m_fastSelectorNofLines = 0;
joachim99@8 88 m_lineNumberWidth = 0;
joachim99@8 89 selection.reset();
joachim99@8 90 selection.oldFirstLine = -1; // reset is not enough here.
joachim99@8 91 selection.oldLastLine = -1;
joachim99@8 92 selection.lastLine = -1;
joachim99@8 93
joachim99@8 94 QToolTip::remove(this);
joachim99@8 95 QToolTip::add( this, QRect( 0,0, 1024, fontMetrics().height() ), m_filename );
joachim99@8 96 update();
joachim99@8 97 }
joachim99@8 98
joachim99@8 99 void DiffTextWindow::setPaintingAllowed( bool bAllowPainting )
joachim99@8 100 {
joachim99@8 101 if (m_bPaintingAllowed != bAllowPainting)
joachim99@8 102 {
joachim99@8 103 m_bPaintingAllowed = bAllowPainting;
joachim99@8 104 if ( m_bPaintingAllowed ) update();
joachim99@8 105 }
joachim99@8 106 }
joachim99@8 107
joachim99@8 108 void DiffTextWindow::dragEnterEvent( QDragEnterEvent* e )
joachim99@8 109 {
joachim99@8 110 e->accept( QUriDrag::canDecode(e) || QTextDrag::canDecode(e) );
joachim99@8 111 // Note that the corresponding drop is handled in KDiff3App::eventFilter().
joachim99@8 112 }
joachim99@8 113
joachim99@8 114 void DiffTextWindow::setFirstLine(int firstLine)
joachim99@8 115 {
joachim99@66 116 int fontHeight = fontMetrics().height();
joachim99@66 117 int topLineYOffset = fontHeight + 3;
joachim99@66 118
joachim99@66 119 int newFirstLine = max2(0,firstLine);
joachim99@66 120
joachim99@66 121 int deltaY = fontHeight * ( m_firstLine - newFirstLine );
joachim99@66 122
joachim99@66 123 m_firstLine = newFirstLine;
joachim99@66 124
joachim99@66 125 if ( m_scrollDeltaY > 0 )
joachim99@66 126 {
joachim99@66 127 update( 0, height()-fontHeight*3, width(), fontHeight*3 );
joachim99@66 128 }
joachim99@66 129 else if ( m_scrollDeltaY<0 )
joachim99@66 130 {
joachim99@66 131 update( 0, 0, width(), topLineYOffset+fontHeight*2 );
joachim99@66 132 }
joachim99@66 133 else
joachim99@66 134 {
joachim99@66 135 update( 0, 0, width(), topLineYOffset );
joachim99@66 136 }
joachim99@66 137
joachim99@66 138 QRect r( 0, topLineYOffset, width(), height()-topLineYOffset );
joachim99@66 139 QWidget::scroll( 0, deltaY, r );
joachim99@8 140 }
joachim99@8 141
joachim99@8 142 void DiffTextWindow::setFirstColumn(int firstCol)
joachim99@8 143 {
joachim99@66 144 int fontHeight = fontMetrics().height();
joachim99@66 145 int fontWidth = fontMetrics().width('W');
joachim99@66 146 int topLineYOffset = fontHeight + 3;
joachim99@66 147 int xOffset = leftInfoWidth * fontWidth;
joachim99@66 148
joachim99@66 149 int newFirstColumn = max2(0,firstCol);
joachim99@66 150
joachim99@66 151 int deltaX = fontWidth * ( m_firstColumn - newFirstColumn );
joachim99@66 152
joachim99@66 153 m_firstColumn = newFirstColumn;
joachim99@66 154
joachim99@66 155 QRect r( xOffset, topLineYOffset, width()-xOffset, height()-topLineYOffset );
joachim99@66 156
joachim99@66 157 QWidget::scroll( deltaX, 0, r );
joachim99@8 158 }
joachim99@8 159
joachim99@8 160 int DiffTextWindow::getNofColumns()
joachim99@8 161 {
joachim99@66 162 if (m_bWordWrap)
joachim99@8 163 {
joachim99@66 164 return getNofVisibleColumns();
joachim99@8 165 }
joachim99@66 166 else
joachim99@66 167 {
joachim99@66 168 int nofColumns = 0;
joachim99@66 169 for( int i = 0; i< m_size; ++i )
joachim99@66 170 {
joachim99@66 171 if ( m_pLineData[i].width() > nofColumns )
joachim99@66 172 nofColumns = m_pLineData[i].width();
joachim99@66 173 }
joachim99@66 174 return nofColumns;
joachim99@66 175 }
joachim99@8 176 }
joachim99@8 177
joachim99@8 178 int DiffTextWindow::getNofLines()
joachim99@8 179 {
joachim99@66 180 return m_bWordWrap ? m_diff3WrapLineVector.size() :
joachim99@66 181 m_pDiff3LineVector->size();
joachim99@66 182 }
joachim99@66 183
joachim99@66 184
joachim99@66 185 int DiffTextWindow::convertLineToDiff3LineIdx( int line )
joachim99@66 186 {
joachim99@66 187 if ( m_bWordWrap && m_diff3WrapLineVector.size()>0 )
joachim99@66 188 return m_diff3WrapLineVector[ min2( line, (int)m_diff3WrapLineVector.size()-1 ) ].diff3LineIndex;
joachim99@66 189 else
joachim99@66 190 return line;
joachim99@66 191 }
joachim99@66 192
joachim99@66 193 int DiffTextWindow::convertDiff3LineIdxToLine( int d3lIdx )
joachim99@66 194 {
joachim99@66 195 if ( m_bWordWrap && m_pDiff3LineVector!=0 && m_pDiff3LineVector->size()>0 )
joachim99@66 196 return (*m_pDiff3LineVector)[ min2( d3lIdx, (int)m_pDiff3LineVector->size()-1 ) ]->sumLinesNeededForDisplay;
joachim99@66 197 else
joachim99@66 198 return d3lIdx;
joachim99@8 199 }
joachim99@8 200
joachim99@8 201 /** Returns a line number where the linerange [line, line+nofLines] can
joachim99@8 202 be displayed best. If it fits into the currently visible range then
joachim99@8 203 the returned value is the current firstLine.
joachim99@8 204 */
joachim99@8 205 int getBestFirstLine( int line, int nofLines, int firstLine, int visibleLines )
joachim99@8 206 {
joachim99@8 207 int newFirstLine = firstLine;
joachim99@8 208 if ( line < firstLine || line + nofLines + 2 > firstLine + visibleLines )
joachim99@8 209 {
joachim99@8 210 if ( nofLines > visibleLines || nofLines <= ( 2*visibleLines / 3 - 1) )
joachim99@8 211 newFirstLine = line - visibleLines/3;
joachim99@8 212 else
joachim99@8 213 newFirstLine = line - (visibleLines - nofLines);
joachim99@8 214 }
joachim99@8 215
joachim99@8 216 return newFirstLine;
joachim99@8 217 }
joachim99@8 218
joachim99@8 219
joachim99@8 220 void DiffTextWindow::setFastSelectorRange( int line1, int nofLines )
joachim99@66 221 {
joachim99@8 222 m_fastSelectorLine1 = line1;
joachim99@8 223 m_fastSelectorNofLines = nofLines;
joachim99@8 224 if ( isVisible() )
joachim99@8 225 {
joachim99@66 226 int newFirstLine = getBestFirstLine(
joachim99@66 227 convertDiff3LineIdxToLine(m_fastSelectorLine1),
joachim99@66 228 convertDiff3LineIdxToLine(m_fastSelectorLine1+m_fastSelectorNofLines)-convertDiff3LineIdxToLine(m_fastSelectorLine1),
joachim99@66 229 m_firstLine,
joachim99@66 230 getNofVisibleLines()
joachim99@66 231 );
joachim99@8 232 if ( newFirstLine != m_firstLine )
joachim99@8 233 {
joachim99@8 234 scroll( 0, newFirstLine - m_firstLine );
joachim99@8 235 }
joachim99@8 236
joachim99@8 237 update();
joachim99@8 238 }
joachim99@8 239 }
joachim99@8 240
joachim99@8 241
joachim99@66 242 void DiffTextWindow::showStatusLine(int line )
joachim99@8 243 {
joachim99@66 244 int d3lIdx = convertLineToDiff3LineIdx( line );
joachim99@8 245 int l=0;
joachim99@66 246 const Diff3Line* pD3l = (*m_pDiff3LineVector)[d3lIdx];
joachim99@66 247 if(d3lIdx >= 0 && d3lIdx<(int)m_pDiff3LineVector->size() && pD3l != 0 )
joachim99@8 248 {
joachim99@66 249 if ( m_winIdx==1 ) l = pD3l->lineA;
joachim99@66 250 else if ( m_winIdx==2 ) l = pD3l->lineB;
joachim99@66 251 else if ( m_winIdx==3 ) l = pD3l->lineC;
joachim99@8 252 else assert(false);
joachim99@8 253
joachim99@8 254 QString s;
joachim99@8 255 if ( l!=-1 )
joachim99@66 256 s.sprintf("File %s: Line %d", m_filename.ascii(), l+1 );
joachim99@8 257 else
joachim99@66 258 s.sprintf("File %s: Line not available", m_filename.ascii() );
joachim99@66 259 if (m_pStatusBar!=0) m_pStatusBar->message(s);
joachim99@8 260 }
joachim99@8 261 }
joachim99@8 262
joachim99@66 263 void DiffTextWindow::focusInEvent(QFocusEvent* e)
joachim99@66 264 {
joachim99@66 265 emit gotFocus();
joachim99@66 266 QWidget::focusInEvent(e);
joachim99@66 267 }
joachim99@8 268
joachim99@8 269 void DiffTextWindow::mousePressEvent ( QMouseEvent* e )
joachim99@8 270 {
joachim99@8 271 if ( e->button() == LeftButton )
joachim99@8 272 {
joachim99@8 273 int line;
joachim99@8 274 int pos;
joachim99@8 275 convertToLinePos( e->x(), e->y(), line, pos );
joachim99@8 276 if ( pos < m_firstColumn )
joachim99@8 277 {
joachim99@66 278 emit setFastSelectorLine( convertLineToDiff3LineIdx(line) );
joachim99@8 279 selection.firstLine = -1; // Disable current selection
joachim99@8 280 }
joachim99@8 281 else
joachim99@8 282 { // Selection
joachim99@8 283 resetSelection();
joachim99@8 284 selection.start( line, pos );
joachim99@8 285 selection.end( line, pos );
joachim99@8 286
joachim99@66 287 showStatusLine( line );
joachim99@8 288 }
joachim99@8 289 }
joachim99@8 290 }
joachim99@8 291
joachim99@8 292 bool isCTokenChar( char c )
joachim99@8 293 {
joachim99@8 294 return (c=='_') ||
joachim99@8 295 ( c>='A' && c<='Z' ) || ( c>='a' && c<='z' ) ||
joachim99@8 296 (c>='0' && c<='9');
joachim99@8 297 }
joachim99@8 298
joachim99@8 299 /// Calculate where a token starts and ends, given the x-position on screen.
joachim99@8 300 void calcTokenPos( const char* p, int size, int posOnScreen, int& pos1, int& pos2 )
joachim99@8 301 {
joachim99@8 302 // Cursor conversions that consider g_tabSize
joachim99@8 303 int pos = convertToPosInText( p, size, max2( 0, posOnScreen ) );
joachim99@8 304 if ( pos>=size )
joachim99@8 305 {
joachim99@8 306 pos1=size;
joachim99@8 307 pos2=size;
joachim99@8 308 return;
joachim99@8 309 }
joachim99@8 310
joachim99@8 311 pos1 = pos;
joachim99@8 312 pos2 = pos+1;
joachim99@8 313
joachim99@8 314 if( isCTokenChar( p[pos1] ) )
joachim99@8 315 {
joachim99@8 316 while( pos1>=0 && isCTokenChar( p[pos1] ) )
joachim99@8 317 --pos1;
joachim99@8 318 ++pos1;
joachim99@8 319
joachim99@8 320 while( pos2<size && isCTokenChar( p[pos2] ) )
joachim99@8 321 ++pos2;
joachim99@8 322 }
joachim99@8 323 }
joachim99@8 324
joachim99@8 325 void DiffTextWindow::mouseDoubleClickEvent( QMouseEvent* e )
joachim99@8 326 {
joachim99@8 327 if ( e->button() == LeftButton )
joachim99@8 328 {
joachim99@8 329 int line;
joachim99@8 330 int pos;
joachim99@8 331 convertToLinePos( e->x(), e->y(), line, pos );
joachim99@8 332
joachim99@8 333 // Get the string data of the current line
joachim99@66 334 QCString s;
joachim99@66 335 if ( m_bWordWrap )
joachim99@66 336 {
joachim99@66 337 const Diff3WrapLine& d = m_diff3WrapLineVector[line];
joachim99@66 338 s = getString( d.diff3LineIndex ).mid( d.wrapLineOffset, d.wrapLineLength );
joachim99@66 339 }
joachim99@66 340 else
joachim99@66 341 {
joachim99@66 342 s = getString( line );
joachim99@66 343 }
joachim99@66 344
joachim99@8 345 if ( ! s.isEmpty() )
joachim99@8 346 {
joachim99@8 347 int pos1, pos2;
joachim99@8 348 calcTokenPos( s, s.length(), pos, pos1, pos2 );
joachim99@8 349
joachim99@8 350 resetSelection();
joachim99@8 351 selection.start( line, convertToPosOnScreen( s, pos1 ) );
joachim99@8 352 selection.end( line, convertToPosOnScreen( s, pos2 ) );
joachim99@8 353 update();
joachim99@8 354 // emit selectionEnd() happens in the mouseReleaseEvent.
joachim99@66 355 showStatusLine( line );
joachim99@8 356 }
joachim99@8 357 }
joachim99@8 358 }
joachim99@8 359
joachim99@8 360 void DiffTextWindow::mouseReleaseEvent ( QMouseEvent * /*e*/ )
joachim99@8 361 {
joachim99@8 362 //if ( e->button() == LeftButton )
joachim99@8 363 {
joachim99@8 364 killTimers();
joachim99@8 365 if (selection.firstLine != -1 )
joachim99@8 366 {
joachim99@8 367 emit selectionEnd();
joachim99@8 368 }
joachim99@8 369 }
joachim99@8 370 m_scrollDeltaX=0;
joachim99@8 371 m_scrollDeltaY=0;
joachim99@8 372 }
joachim99@8 373
joachim99@8 374 void DiffTextWindow::mouseMoveEvent ( QMouseEvent * e )
joachim99@8 375 {
joachim99@8 376 int line;
joachim99@8 377 int pos;
joachim99@8 378 convertToLinePos( e->x(), e->y(), line, pos );
joachim99@8 379 if (selection.firstLine != -1 )
joachim99@8 380 {
joachim99@8 381 selection.end( line, pos );
joachim99@8 382
joachim99@66 383 showStatusLine( line );
joachim99@8 384
joachim99@8 385 // Scroll because mouse moved out of the window
joachim99@8 386 const QFontMetrics& fm = fontMetrics();
joachim99@8 387 int fontHeight = fm.height();
joachim99@8 388 int fontWidth = fm.width('W');
joachim99@8 389 int topLineYOffset = fontHeight + 3;
joachim99@8 390 int deltaX=0;
joachim99@8 391 int deltaY=0;
joachim99@8 392 if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1;
joachim99@8 393 if ( e->x() > width() ) deltaX=+1;
joachim99@8 394 if ( e->y() < topLineYOffset ) deltaY=-1;
joachim99@8 395 if ( e->y() > height() ) deltaY=+1;
joachim99@66 396 if ( deltaX != 0 && m_scrollDeltaX!=deltaX || deltaY!= 0 && m_scrollDeltaY!=deltaY )
joachim99@8 397 {
joachim99@66 398 m_scrollDeltaX = deltaX;
joachim99@66 399 m_scrollDeltaY = deltaY;
joachim99@8 400 emit scroll( deltaX, deltaY );
joachim99@66 401 startTimer(50);
joachim99@66 402 }
joachim99@66 403 else
joachim99@66 404 {
joachim99@66 405 m_scrollDeltaX = deltaX;
joachim99@66 406 m_scrollDeltaY = deltaY;
joachim99@66 407 myUpdate(0);
joachim99@8 408 }
joachim99@8 409 }
joachim99@8 410 }
joachim99@8 411
joachim99@8 412
joachim99@8 413 void DiffTextWindow::myUpdate(int afterMilliSecs)
joachim99@8 414 {
joachim99@8 415 killTimers();
joachim99@8 416 m_bMyUpdate = true;
joachim99@8 417 startTimer( afterMilliSecs );
joachim99@8 418 }
joachim99@8 419
joachim99@8 420 void DiffTextWindow::timerEvent(QTimerEvent*)
joachim99@8 421 {
joachim99@8 422 killTimers();
joachim99@8 423
joachim99@8 424 if ( m_bMyUpdate )
joachim99@8 425 {
joachim99@8 426 paintEvent( 0 );
joachim99@8 427 m_bMyUpdate = false;
joachim99@8 428 }
joachim99@8 429
joachim99@8 430 if ( m_scrollDeltaX != 0 || m_scrollDeltaY != 0 )
joachim99@8 431 {
joachim99@8 432 selection.end( selection.lastLine + m_scrollDeltaY, selection.lastPos + m_scrollDeltaX );
joachim99@8 433 emit scroll( m_scrollDeltaX, m_scrollDeltaY );
joachim99@8 434 killTimers();
joachim99@8 435 startTimer(50);
joachim99@8 436 }
joachim99@8 437 }
joachim99@8 438
joachim99@8 439 void DiffTextWindow::resetSelection()
joachim99@8 440 {
joachim99@8 441 selection.reset();
joachim99@8 442 update();
joachim99@8 443 }
joachim99@8 444
joachim99@8 445 void DiffTextWindow::convertToLinePos( int x, int y, int& line, int& pos )
joachim99@8 446 {
joachim99@8 447 const QFontMetrics& fm = fontMetrics();
joachim99@8 448 int fontHeight = fm.height();
joachim99@8 449 int fontWidth = fm.width('W');
joachim99@8 450 int xOffset = (leftInfoWidth-m_firstColumn)*fontWidth;
joachim99@8 451
joachim99@8 452 int topLineYOffset = fontHeight + 3;
joachim99@8 453
joachim99@8 454 int yOffset = topLineYOffset - m_firstLine * fontHeight;
joachim99@8 455
joachim99@8 456 line = ( y - yOffset ) / fontHeight;
joachim99@8 457 pos = ( x - xOffset ) / fontWidth;
joachim99@8 458 }
joachim99@8 459
joachim99@8 460 int Selection::firstPosInLine(int l)
joachim99@8 461 {
joachim99@8 462 assert( firstLine != -1 );
joachim99@8 463
joachim99@8 464 int l1 = firstLine;
joachim99@8 465 int l2 = lastLine;
joachim99@8 466 int p1 = firstPos;
joachim99@8 467 int p2 = lastPos;
joachim99@8 468 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
joachim99@8 469 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
joachim99@8 470
joachim99@8 471 if ( l==l1 )
joachim99@8 472 return p1;
joachim99@8 473 return 0;
joachim99@8 474 }
joachim99@8 475
joachim99@8 476 int Selection::lastPosInLine(int l)
joachim99@8 477 {
joachim99@8 478 assert( firstLine != -1 );
joachim99@8 479
joachim99@8 480 int l1 = firstLine;
joachim99@8 481 int l2 = lastLine;
joachim99@8 482 int p1 = firstPos;
joachim99@8 483 int p2 = lastPos;
joachim99@8 484
joachim99@8 485 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
joachim99@8 486 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
joachim99@8 487
joachim99@8 488 if ( l==l2 )
joachim99@8 489 return p2;
joachim99@8 490 return INT_MAX;
joachim99@8 491 }
joachim99@8 492
joachim99@8 493 bool Selection::within( int l, int p )
joachim99@8 494 {
joachim99@8 495 if ( firstLine == -1 ) return false;
joachim99@8 496 int l1 = firstLine;
joachim99@8 497 int l2 = lastLine;
joachim99@8 498 int p1 = firstPos;
joachim99@8 499 int p2 = lastPos;
joachim99@8 500 if ( l1>l2 ){ std::swap(l1,l2); std::swap(p1,p2); }
joachim99@8 501 if ( l1==l2 && p1>p2 ){ std::swap(p1,p2); }
joachim99@8 502 if( l1 <= l && l <= l2 )
joachim99@8 503 {
joachim99@8 504 if ( l1==l2 )
joachim99@8 505 return p>=p1 && p<p2;
joachim99@8 506 if ( l==l1 )
joachim99@8 507 return p>=p1;
joachim99@8 508 if ( l==l2 )
joachim99@8 509 return p<p2;
joachim99@8 510 return true;
joachim99@8 511 }
joachim99@8 512 return false;
joachim99@8 513 }
joachim99@8 514
joachim99@8 515 bool Selection::lineWithin( int l )
joachim99@8 516 {
joachim99@8 517 if ( firstLine == -1 ) return false;
joachim99@8 518 int l1 = firstLine;
joachim99@8 519 int l2 = lastLine;
joachim99@8 520
joachim99@8 521 if ( l1>l2 ){ std::swap(l1,l2); }
joachim99@8 522
joachim99@8 523 return ( l1 <= l && l <= l2 );
joachim99@8 524 }
joachim99@8 525
joachim99@8 526 void DiffTextWindow::writeLine(
joachim99@8 527 QPainter& p,
joachim99@8 528 const LineData* pld,
joachim99@8 529 const DiffList* pLineDiff1,
joachim99@8 530 const DiffList* pLineDiff2,
joachim99@8 531 int line,
joachim99@8 532 int whatChanged,
joachim99@8 533 int whatChanged2,
joachim99@66 534 int srcLineNr,
joachim99@66 535 int wrapLineOffset,
joachim99@66 536 int wrapLineLength,
joachim99@66 537 bool bWrapLine
joachim99@8 538 )
joachim99@8 539 {
joachim99@8 540 QFont normalFont = font();
joachim99@8 541 QFont diffFont = normalFont;
joachim99@8 542 diffFont.setItalic( m_pOptionDialog->m_bItalicForDeltas );
joachim99@8 543 const QFontMetrics& fm = fontMetrics();
joachim99@8 544 int fontHeight = fm.height();
joachim99@8 545 int fontAscent = fm.ascent();
joachim99@8 546 int fontDescent = fm.descent();
joachim99@8 547 int fontWidth = fm.width('W');
joachim99@8 548 int topLineYOffset = fontHeight + 3;
joachim99@8 549
joachim99@8 550 int xOffset = (leftInfoWidth - m_firstColumn)*fontWidth;
joachim99@8 551 int yOffset = (line-m_firstLine) * fontHeight + topLineYOffset;
joachim99@8 552
joachim99@8 553 QRect lineRect( 0, yOffset, width(), fontHeight );
joachim99@8 554 if ( ! m_invalidRect.intersects( lineRect ) )
joachim99@8 555 return;
joachim99@8 556
joachim99@66 557 int fastSelectorLine1 = convertDiff3LineIdxToLine(m_fastSelectorLine1);
joachim99@66 558 int fastSelectorLine2 = convertDiff3LineIdxToLine(m_fastSelectorLine1+m_fastSelectorNofLines)-1;
joachim99@66 559
joachim99@66 560 bool bFastSelectionRange = (line>=fastSelectorLine1 && line<= fastSelectorLine2 );
joachim99@8 561 QColor bgColor = m_pOptionDialog->m_bgColor;
joachim99@8 562 QColor diffBgColor = m_pOptionDialog->m_diffBgColor;
joachim99@8 563
joachim99@8 564 if ( bFastSelectionRange )
joachim99@8 565 {
joachim99@8 566 bgColor = m_pOptionDialog->m_currentRangeBgColor;
joachim99@8 567 diffBgColor = m_pOptionDialog->m_currentRangeDiffBgColor;
joachim99@8 568 }
joachim99@8 569
joachim99@8 570 // QRect winRect = rect(); //p.window();
joachim99@8 571 if ( yOffset+fontHeight<0 || height() + fontHeight < yOffset )
joachim99@8 572 return;
joachim99@8 573
joachim99@8 574 int changed = whatChanged;
joachim99@8 575 if ( pLineDiff1 != 0 ) changed |= 1;
joachim99@8 576 if ( pLineDiff2 != 0 ) changed |= 2;
joachim99@8 577
joachim99@8 578 QColor c = m_pOptionDialog->m_fgColor;
joachim99@8 579 if ( changed == 2 ) {
joachim99@8 580 c = m_cDiff2;
joachim99@8 581 } else if ( changed == 1 ) {
joachim99@8 582 c = m_cDiff1;
joachim99@8 583 } else if ( changed == 3 ) {
joachim99@8 584 c = m_cDiffBoth;
joachim99@8 585 }
joachim99@8 586
joachim99@8 587 p.fillRect( leftInfoWidth*fontWidth, yOffset, width(), fontHeight, bgColor );
joachim99@51 588
joachim99@8 589 if (pld!=0)
joachim99@8 590 {
joachim99@8 591 // First calculate the "changed" information for each character.
joachim99@8 592 int i=0;
joachim99@8 593 std::vector<UINT8> charChanged( pld->size );
joachim99@8 594 if ( pLineDiff1!=0 || pLineDiff2 != 0 )
joachim99@8 595 {
joachim99@8 596 Merger merger( pLineDiff1, pLineDiff2 );
joachim99@8 597 while( ! merger.isEndReached() && i<pld->size )
joachim99@8 598 {
joachim99@8 599 if ( i < pld->size )
joachim99@8 600 {
joachim99@8 601 charChanged[i] = merger.whatChanged();
joachim99@8 602 ++i;
joachim99@8 603 }
joachim99@8 604 merger.next();
joachim99@8 605 }
joachim99@8 606 }
joachim99@8 607
joachim99@8 608 QCString s=" ";
joachim99@8 609 // Convert tabs
joachim99@8 610 int outPos = 0;
joachim99@66 611
joachim99@66 612 int lineLength = m_bWordWrap ? wrapLineOffset+wrapLineLength : pld->size;
joachim99@66 613 for( i=wrapLineOffset; i<lineLength; ++i )
joachim99@8 614 {
joachim99@8 615 int spaces = 1;
joachim99@8 616
joachim99@8 617 if ( pld->pLine[i]=='\t' )
joachim99@8 618 {
joachim99@8 619 spaces = tabber( outPos, g_tabSize );
joachim99@8 620 s[0] = ' ';
joachim99@8 621 }
joachim99@8 622 else
joachim99@8 623 {
joachim99@8 624 s[0] = pld->pLine[i];
joachim99@8 625 }
joachim99@8 626
joachim99@8 627 QColor c = m_pOptionDialog->m_fgColor;
joachim99@8 628 int cchanged = charChanged[i] | whatChanged;
joachim99@8 629
joachim99@8 630 if ( cchanged == 2 ) {
joachim99@8 631 c = m_cDiff2;
joachim99@8 632 } else if ( cchanged == 1 ) {
joachim99@8 633 c = m_cDiff1;
joachim99@8 634 } else if ( cchanged == 3 ) {
joachim99@8 635 c = m_cDiffBoth;
joachim99@8 636 }
joachim99@8 637
joachim99@51 638 if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 && !m_pOptionDialog->m_bShowWhiteSpace )
joachim99@51 639 {
joachim99@51 640 // The user doesn't want to see highlighted white space.
joachim99@51 641 c = m_pOptionDialog->m_fgColor;
joachim99@51 642 }
joachim99@51 643
joachim99@8 644 QRect outRect( xOffset + fontWidth*outPos, yOffset, fontWidth*spaces, fontHeight );
joachim99@8 645 if ( m_invalidRect.intersects( outRect ) )
joachim99@8 646 {
joachim99@8 647 if( !selection.within( line, outPos ) )
joachim99@8 648 {
joachim99@51 649
joachim99@8 650 if( c!=m_pOptionDialog->m_fgColor )
joachim99@8 651 {
joachim99@8 652 QColor lightc = diffBgColor;
joachim99@8 653 p.fillRect( xOffset + fontWidth*outPos, yOffset,
joachim99@8 654 fontWidth*spaces, fontHeight, lightc );
joachim99@8 655 p.setFont(diffFont);
joachim99@8 656 }
joachim99@8 657
joachim99@8 658 p.setPen( c );
joachim99@8 659 if ( s[0]==' ' && c!=m_pOptionDialog->m_fgColor && charChanged[i]!=0 )
joachim99@8 660 {
joachim99@51 661 if ( m_pOptionDialog->m_bShowWhiteSpaceCharacters && m_pOptionDialog->m_bShowWhiteSpace)
joachim99@8 662 {
joachim99@8 663 p.fillRect( xOffset + fontWidth*outPos, yOffset+fontAscent,
joachim99@8 664 fontWidth*spaces-1, fontDescent+1, c );
joachim99@8 665 }
joachim99@8 666 }
joachim99@8 667 else
joachim99@8 668 {
joachim99@51 669 p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, decodeString(s,m_pOptionDialog) );
joachim99@8 670 }
joachim99@8 671 p.setFont(normalFont);
joachim99@8 672 }
joachim99@8 673 else
joachim99@8 674 {
joachim99@8 675 p.fillRect( xOffset + fontWidth*outPos, yOffset,
joachim99@8 676 fontWidth*(spaces), fontHeight, colorGroup().highlight() );
joachim99@8 677
joachim99@8 678 p.setPen( colorGroup().highlightedText() );
joachim99@51 679 p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, decodeString(s,m_pOptionDialog) );
joachim99@8 680
joachim99@8 681 selection.bSelectionContainsData = true;
joachim99@8 682 }
joachim99@8 683 }
joachim99@8 684
joachim99@8 685 outPos += spaces;
joachim99@8 686 }
joachim99@8 687
joachim99@8 688 if( selection.lineWithin( line ) && selection.lineWithin( line+1 ) )
joachim99@8 689 {
joachim99@8 690 p.fillRect( xOffset + fontWidth*outPos, yOffset,
joachim99@8 691 width(), fontHeight, colorGroup().highlight() );
joachim99@8 692 }
joachim99@8 693 }
joachim99@8 694
joachim99@8 695 p.fillRect( 0, yOffset, leftInfoWidth*fontWidth, fontHeight, m_pOptionDialog->m_bgColor );
joachim99@8 696
joachim99@8 697 xOffset = (m_lineNumberWidth+2)*fontWidth;
joachim99@8 698 int xLeft = m_lineNumberWidth*fontWidth;
joachim99@8 699 p.setPen( m_pOptionDialog->m_fgColor );
joachim99@8 700 if ( pld!=0 )
joachim99@8 701 {
joachim99@66 702 if ( m_pOptionDialog->m_bShowLineNumbers && !bWrapLine )
joachim99@8 703 {
joachim99@8 704 QString num;
joachim99@8 705 num.sprintf( "%0*d", m_lineNumberWidth, srcLineNr);
joachim99@8 706 p.drawText( 0, yOffset + fontAscent, num );
joachim99@8 707 //p.drawLine( xLeft -1, yOffset, xLeft -1, yOffset+fontHeight-1 );
joachim99@8 708 }
joachim99@66 709 if ( !bWrapLine || wrapLineLength>0 )
joachim99@66 710 {
joachim99@66 711 p.setPen( QPen( m_pOptionDialog->m_fgColor, 0, bWrapLine ? DotLine : SolidLine) );
joachim99@66 712 p.drawLine( xOffset +1, yOffset, xOffset +1, yOffset+fontHeight-1 );
joachim99@66 713 p.setPen( QPen( m_pOptionDialog->m_fgColor, 0, SolidLine) );
joachim99@66 714 }
joachim99@8 715 }
joachim99@8 716 if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 )//&& whatChanged==0 )
joachim99@8 717 {
joachim99@51 718 if ( m_pOptionDialog->m_bShowWhiteSpace )
joachim99@51 719 {
joachim99@51 720 p.setBrushOrigin(0,0);
joachim99@51 721 p.fillRect( xLeft, yOffset, fontWidth*2-1, fontHeight, QBrush(c,Dense5Pattern) );
joachim99@51 722 }
joachim99@8 723 }
joachim99@8 724 else
joachim99@8 725 {
joachim99@8 726 p.fillRect( xLeft, yOffset, fontWidth*2-1, fontHeight, c==m_pOptionDialog->m_fgColor ? bgColor : c );
joachim99@8 727 }
joachim99@8 728
joachim99@8 729 if ( bFastSelectionRange )
joachim99@8 730 {
joachim99@8 731 p.fillRect( xOffset + fontWidth-1, yOffset, 3, fontHeight, m_pOptionDialog->m_fgColor );
joachim99@8 732 }
joachim99@8 733 }
joachim99@8 734
joachim99@8 735 void DiffTextWindow::paintEvent( QPaintEvent* e )
joachim99@8 736 {
joachim99@66 737 if ( m_pDiff3LineVector==0 || ! m_bPaintingAllowed ||
joachim99@66 738 ( m_diff3WrapLineVector.empty() && m_bWordWrap ) )
joachim99@66 739 return;
joachim99@8 740
joachim99@8 741 m_lineNumberWidth = m_pOptionDialog->m_bShowLineNumbers ? (int)log10((double)m_size)+1 : 0;
joachim99@8 742
joachim99@8 743 if (e!=0)
joachim99@8 744 {
joachim99@8 745 m_invalidRect |= e->rect();
joachim99@8 746 }
joachim99@8 747
joachim99@8 748 if ( m_winIdx==1 )
joachim99@8 749 {
joachim99@8 750 m_cThis = m_pOptionDialog->m_colorA;
joachim99@8 751 m_cDiff1 = m_pOptionDialog->m_colorB;
joachim99@8 752 m_cDiff2 = m_pOptionDialog->m_colorC;
joachim99@8 753 }
joachim99@8 754 if ( m_winIdx==2 )
joachim99@8 755 {
joachim99@8 756 m_cThis = m_pOptionDialog->m_colorB;
joachim99@8 757 m_cDiff1 = m_pOptionDialog->m_colorC;
joachim99@8 758 m_cDiff2 = m_pOptionDialog->m_colorA;
joachim99@8 759 }
joachim99@8 760 if ( m_winIdx==3 )
joachim99@8 761 {
joachim99@8 762 m_cThis = m_pOptionDialog->m_colorC;
joachim99@8 763 m_cDiff1 = m_pOptionDialog->m_colorA;
joachim99@8 764 m_cDiff2 = m_pOptionDialog->m_colorB;
joachim99@8 765 }
joachim99@8 766 m_cDiffBoth = m_pOptionDialog->m_colorForConflict; // Conflict color
joachim99@8 767
joachim99@8 768 bool bOldSelectionContainsData = selection.bSelectionContainsData;
joachim99@8 769 selection.bSelectionContainsData = false;
joachim99@8 770
joachim99@8 771 int fontHeight = fontMetrics().height();
joachim99@8 772 int fontAscent = fontMetrics().ascent();
joachim99@8 773 // int fontDescent = fontMetrics().descent();
joachim99@8 774
joachim99@8 775 int topLineYOffset = fontHeight + 3;
joachim99@8 776
joachim99@8 777 if ( selection.oldLastLine != -1 )
joachim99@8 778 {
joachim99@8 779 int lastLine;
joachim99@8 780 int firstLine;
joachim99@8 781 if ( selection.oldFirstLine != -1 )
joachim99@8 782 {
joachim99@8 783 firstLine = min3( selection.oldFirstLine, selection.lastLine, selection.oldLastLine );
joachim99@8 784 lastLine = max3( selection.oldFirstLine, selection.lastLine, selection.oldLastLine );
joachim99@8 785 }
joachim99@8 786 else
joachim99@8 787 {
joachim99@8 788 firstLine = min2( selection.lastLine, selection.oldLastLine );
joachim99@8 789 lastLine = max2( selection.lastLine, selection.oldLastLine );
joachim99@8 790 }
joachim99@66 791 int y1 = topLineYOffset + ( firstLine - m_firstLine ) * fontHeight;
joachim99@8 792 int y2 = min2( height(),
joachim99@66 793 topLineYOffset + ( lastLine - m_firstLine + 1 ) * fontHeight );
joachim99@8 794
joachim99@8 795 if ( y1<height() && y2>topLineYOffset )
joachim99@8 796 {
joachim99@8 797 m_invalidRect |= QRect( 0, y1, width(), y2-y1 );
joachim99@8 798 }
joachim99@8 799 }
joachim99@8 800
joachim99@8 801 if ( m_invalidRect.isEmpty() )
joachim99@8 802 return;
joachim99@8 803
joachim99@8 804 QPainter painter(this);
joachim99@8 805 //QPainter& p=painter;
joachim99@8 806 QPixmap pixmap( m_invalidRect.size() );
joachim99@8 807 QPainter p( &pixmap );
joachim99@8 808 p.translate( -m_invalidRect.x(), -m_invalidRect.y() );
joachim99@8 809
joachim99@8 810 p.fillRect( m_invalidRect, m_pOptionDialog->m_bgColor );
joachim99@8 811
joachim99@8 812 p.setFont( font() );
joachim99@8 813
joachim99@8 814 p.setPen( m_cThis );
joachim99@8 815 if( m_invalidRect.intersects( QRect(0,0,width(), topLineYOffset ) )
joachim99@8 816 || m_firstLine != m_oldFirstLine )
joachim99@8 817 {
joachim99@8 818 int l=-1;
joachim99@66 819 for ( int i = convertLineToDiff3LineIdx(m_firstLine); i<(int)m_pDiff3LineVector->size(); ++i )
joachim99@8 820 {
joachim99@8 821 const Diff3Line* d3l = (*m_pDiff3LineVector)[i];
joachim99@8 822 if ( m_winIdx==1 ) l=d3l->lineA;
joachim99@8 823 else if ( m_winIdx==2 ) l=d3l->lineB;
joachim99@8 824 else if ( m_winIdx==3 ) l=d3l->lineC;
joachim99@8 825 else assert(false);
joachim99@8 826 if (l!=-1) break;
joachim99@8 827 }
joachim99@8 828
joachim99@8 829 const char* winId = ( m_winIdx==1 ? (m_bTriple?"A (Base)":"A") :
joachim99@8 830 ( m_winIdx==2 ? "B" : "C" ) );
joachim99@8 831
joachim99@51 832 QString s = QString(" ")+ winId + " : " + m_filename + " : ";
joachim99@8 833 if ( l!=-1 )
joachim99@66 834 s += i18n("Top line %1").arg( l+1 );
joachim99@8 835 else
joachim99@51 836 s += i18n("End");
joachim99@8 837
joachim99@8 838 if (hasFocus())
joachim99@8 839 {
joachim99@8 840 painter.fillRect( 0, 0, width(), topLineYOffset, m_cThis );
joachim99@8 841 painter.setPen( m_pOptionDialog->m_bgColor );
joachim99@8 842 painter.drawText( 0, fontAscent+1, s );
joachim99@8 843 }
joachim99@8 844 else
joachim99@8 845 {
joachim99@8 846 painter.fillRect( 0, 0, width(), topLineYOffset, m_pOptionDialog->m_bgColor );
joachim99@8 847 painter.setPen( m_cThis );
joachim99@8 848 painter.drawLine( 0, fontHeight + 2, width(), fontHeight + 2 );
joachim99@8 849 painter.drawText( 0, fontAscent+1, s );
joachim99@8 850 }
joachim99@8 851 }
joachim99@8 852
joachim99@66 853 int lastVisibleLine = min2( m_firstLine + getNofVisibleLines()+2,
joachim99@66 854 (int)(m_bWordWrap ? m_diff3WrapLineVector.size() : m_pDiff3LineVector->size()) );
joachim99@8 855
joachim99@8 856 for ( int line = m_firstLine; line<lastVisibleLine; ++line )
joachim99@8 857 {
joachim99@66 858 int wrapLineOffset=0;
joachim99@66 859 int wrapLineLength=0;
joachim99@66 860 const Diff3Line* d3l =0;
joachim99@66 861 bool bWrapLine = false;
joachim99@66 862 if (m_bWordWrap)
joachim99@66 863 {
joachim99@66 864 Diff3WrapLine& d3wl = m_diff3WrapLineVector[line];
joachim99@66 865 wrapLineOffset = d3wl.wrapLineOffset;
joachim99@66 866 wrapLineLength = d3wl.wrapLineLength;
joachim99@66 867 d3l = d3wl.pD3L;
joachim99@66 868 bWrapLine = line > 0 && m_diff3WrapLineVector[line-1].pD3L == d3l;
joachim99@66 869 }
joachim99@66 870 else
joachim99@66 871 {
joachim99@66 872 d3l = (*m_pDiff3LineVector)[line];
joachim99@66 873 }
joachim99@8 874 DiffList* pFineDiff1;
joachim99@8 875 DiffList* pFineDiff2;
joachim99@8 876 int changed=0;
joachim99@8 877 int changed2=0;
joachim99@8 878 int lineIdx;
joachim99@8 879
joachim99@8 880 getLineInfo( *d3l, lineIdx, pFineDiff1, pFineDiff2, changed, changed2 );
joachim99@8 881
joachim99@8 882 writeLine(
joachim99@8 883 p, // QPainter
joachim99@8 884 lineIdx == -1 ? 0 : &m_pLineData[lineIdx], // Text in this line
joachim99@8 885 pFineDiff1,
joachim99@8 886 pFineDiff2,
joachim99@8 887 line, // Line on the screen
joachim99@8 888 changed,
joachim99@8 889 changed2,
joachim99@66 890 lineIdx+1,
joachim99@66 891 wrapLineOffset,
joachim99@66 892 wrapLineLength,
joachim99@66 893 bWrapLine
joachim99@8 894 );
joachim99@8 895 }
joachim99@8 896
joachim99@8 897 // p.drawLine( m_invalidRect.x(), m_invalidRect.y(), m_invalidRect.right(), m_invalidRect.bottom() );
joachim99@8 898 p.end();
joachim99@8 899
joachim99@8 900 painter.setClipRect ( 0, topLineYOffset, width(), height()-topLineYOffset );
joachim99@8 901
joachim99@8 902 painter.drawPixmap( m_invalidRect.x(), m_invalidRect.y(), pixmap );
joachim99@8 903
joachim99@8 904 m_oldFirstLine = m_firstLine;
joachim99@8 905 m_oldFirstColumn = m_firstColumn;
joachim99@8 906 m_invalidRect = QRect(0,0,0,0);
joachim99@8 907 selection.oldLastLine = -1;
joachim99@8 908 if ( selection.oldFirstLine !=-1 )
joachim99@8 909 selection.oldFirstLine = -1;
joachim99@8 910 if( !bOldSelectionContainsData && selection.bSelectionContainsData )
joachim99@8 911 emit newSelection();
joachim99@8 912
joachim99@8 913 }
joachim99@8 914
joachim99@66 915 QCString DiffTextWindow::getString( int d3lIdx )
joachim99@8 916 {
joachim99@66 917 const Diff3Line* d3l = (*m_pDiff3LineVector)[d3lIdx];
joachim99@8 918 DiffList* pFineDiff1;
joachim99@8 919 DiffList* pFineDiff2;
joachim99@8 920 int changed=0;
joachim99@8 921 int changed2=0;
joachim99@8 922 int lineIdx;
joachim99@8 923 getLineInfo( *d3l, lineIdx, pFineDiff1, pFineDiff2, changed, changed2 );
joachim99@8 924
joachim99@8 925 if (lineIdx==-1) return QCString();
joachim99@8 926 else
joachim99@8 927 {
joachim99@58 928 const LineData* ld = &m_pLineData[lineIdx];
joachim99@8 929 return QCString( ld->pLine, ld->size + 1 );
joachim99@8 930 }
joachim99@8 931 return QCString();
joachim99@8 932 }
joachim99@8 933
joachim99@66 934 QCString DiffTextWindow::getLineString( int line )
joachim99@66 935 {
joachim99@66 936 if ( m_bWordWrap )
joachim99@66 937 {
joachim99@66 938 int d3LIdx = convertLineToDiff3LineIdx(line);
joachim99@66 939 return getString( d3LIdx ).mid( m_diff3WrapLineVector[line].wrapLineOffset, m_diff3WrapLineVector[line].wrapLineLength );
joachim99@66 940 }
joachim99@66 941 else
joachim99@66 942 {
joachim99@66 943 return getString( line );
joachim99@66 944 }
joachim99@66 945 }
joachim99@8 946
joachim99@8 947 void DiffTextWindow::getLineInfo(
joachim99@8 948 const Diff3Line& d,
joachim99@8 949 int& lineIdx,
joachim99@8 950 DiffList*& pFineDiff1, DiffList*& pFineDiff2, // return values
joachim99@8 951 int& changed, int& changed2
joachim99@8 952 )
joachim99@8 953 {
joachim99@8 954 changed=0;
joachim99@8 955 changed2=0;
joachim99@8 956 bool bAEqB = d.bAEqB || ( d.bWhiteLineA && d.bWhiteLineB );
joachim99@8 957 bool bAEqC = d.bAEqC || ( d.bWhiteLineA && d.bWhiteLineC );
joachim99@8 958 bool bBEqC = d.bBEqC || ( d.bWhiteLineB && d.bWhiteLineC );
joachim99@8 959 if ( m_winIdx == 1 ) {
joachim99@8 960 lineIdx=d.lineA;
joachim99@8 961 pFineDiff1=d.pFineAB;
joachim99@8 962 pFineDiff2=d.pFineCA;
joachim99@8 963 changed |= ((d.lineB==-1)!=(lineIdx==-1) ? 1 : 0) +
joachim99@8 964 ((d.lineC==-1)!=(lineIdx==-1) && m_bTriple ? 2 : 0);
joachim99@8 965 changed2 |= ( bAEqB ? 0 : 1 ) + (bAEqC || !m_bTriple ? 0 : 2);
joachim99@8 966 }
joachim99@8 967 else if ( m_winIdx == 2 ) {
joachim99@8 968 lineIdx=d.lineB;
joachim99@8 969 pFineDiff1=d.pFineBC;
joachim99@8 970 pFineDiff2=d.pFineAB;
joachim99@8 971 changed |= ((d.lineC==-1)!=(lineIdx==-1) && m_bTriple ? 1 : 0) +
joachim99@8 972 ((d.lineA==-1)!=(lineIdx==-1) ? 2 : 0);
joachim99@8 973 changed2 |= ( bBEqC || !m_bTriple ? 0 : 1 ) + (bAEqB ? 0 : 2);
joachim99@8 974 }
joachim99@8 975 else if ( m_winIdx == 3 ) {
joachim99@8 976 lineIdx=d.lineC;
joachim99@8 977 pFineDiff1=d.pFineCA;
joachim99@8 978 pFineDiff2=d.pFineBC;
joachim99@8 979 changed |= ((d.lineA==-1)!=(lineIdx==-1) ? 1 : 0) +
joachim99@8 980 ((d.lineB==-1)!=(lineIdx==-1) ? 2 : 0);
joachim99@8 981 changed2 |= ( bAEqC ? 0 : 1 ) + (bBEqC ? 0 : 2);
joachim99@8 982 }
joachim99@8 983 else assert(false);
joachim99@8 984 }
joachim99@8 985
joachim99@8 986
joachim99@8 987
joachim99@8 988 void DiffTextWindow::resizeEvent( QResizeEvent* e )
joachim99@8 989 {
joachim99@8 990 QSize s = e->size();
joachim99@8 991 QFontMetrics fm = fontMetrics();
joachim99@8 992 int visibleLines = s.height()/fm.height()-2;
joachim99@8 993 int visibleColumns = s.width()/fm.width('W')-leftInfoWidth;
joachim99@8 994 emit resizeSignal( visibleColumns, visibleLines );
joachim99@8 995 QWidget::resizeEvent(e);
joachim99@8 996 }
joachim99@8 997
joachim99@8 998 int DiffTextWindow::getNofVisibleLines()
joachim99@8 999 {
joachim99@8 1000 QFontMetrics fm = fontMetrics();
joachim99@8 1001 int fmh = fm.height();
joachim99@8 1002 int h = height();
joachim99@8 1003 return h/fmh -2;//height()/fm.height()-2;
joachim99@8 1004 }
joachim99@8 1005
joachim99@8 1006 int DiffTextWindow::getNofVisibleColumns()
joachim99@8 1007 {
joachim99@8 1008 QFontMetrics fm = fontMetrics();
joachim99@8 1009 return width()/fm.width('W')-leftInfoWidth;
joachim99@8 1010 }
joachim99@8 1011
joachim99@8 1012 QString DiffTextWindow::getSelection()
joachim99@8 1013 {
joachim99@8 1014 QString selectionString;
joachim99@8 1015
joachim99@8 1016 int line=0;
joachim99@8 1017 int lineIdx=0;
joachim99@8 1018
joachim99@8 1019 int it;
joachim99@66 1020 int vectorSize = m_bWordWrap ? m_diff3WrapLineVector.size() : m_pDiff3LineVector->size();
joachim99@66 1021 for( it=0; it<vectorSize; ++it )
joachim99@8 1022 {
joachim99@66 1023 const Diff3Line* d = m_bWordWrap ? m_diff3WrapLineVector[it].pD3L : (*m_pDiff3LineVector)[it];
joachim99@8 1024 if ( m_winIdx == 1 ) { lineIdx=d->lineA; }
joachim99@8 1025 else if ( m_winIdx == 2 ) { lineIdx=d->lineB; }
joachim99@8 1026 else if ( m_winIdx == 3 ) { lineIdx=d->lineC; }
joachim99@8 1027 else assert(false);
joachim99@8 1028
joachim99@8 1029 if( lineIdx != -1 )
joachim99@8 1030 {
joachim99@8 1031 const char* pLine = m_pLineData[lineIdx].pLine;
joachim99@8 1032 int size = m_pLineData[lineIdx].size;
joachim99@66 1033
joachim99@66 1034 if ( m_bWordWrap )
joachim99@66 1035 {
joachim99@66 1036 pLine += m_diff3WrapLineVector[it].wrapLineOffset;
joachim99@66 1037 size = m_diff3WrapLineVector[it].wrapLineLength;
joachim99@66 1038 }
joachim99@8 1039
joachim99@8 1040 // Consider tabs
joachim99@8 1041 int outPos = 0;
joachim99@8 1042 for( int i=0; i<size; ++i )
joachim99@8 1043 {
joachim99@8 1044 int spaces = 1;
joachim99@8 1045 if ( pLine[i]=='\t' )
joachim99@8 1046 {
joachim99@8 1047 spaces = tabber( outPos, g_tabSize );
joachim99@8 1048 }
joachim99@8 1049
joachim99@8 1050 if( selection.within( line, outPos ) )
joachim99@8 1051 {
joachim99@58 1052 char buf[2];
joachim99@58 1053 buf[0] = pLine[i];
joachim99@58 1054 buf[1] = '\0';
joachim99@58 1055 selectionString += decodeString( buf, m_pOptionDialog );
joachim99@8 1056 }
joachim99@8 1057
joachim99@8 1058 outPos += spaces;
joachim99@8 1059 }
joachim99@8 1060
joachim99@66 1061
joachim99@66 1062
joachim99@66 1063 if( selection.within( line, outPos ) &&
joachim99@66 1064 !( m_bWordWrap && it+1<vectorSize && d == m_diff3WrapLineVector[it+1].pD3L )
joachim99@66 1065 )
joachim99@8 1066 {
joachim99@8 1067 #ifdef _WIN32
joachim99@8 1068 selectionString += '\r';
joachim99@8 1069 #endif
joachim99@8 1070 selectionString += '\n';
joachim99@8 1071 }
joachim99@8 1072 }
joachim99@8 1073
joachim99@8 1074 ++line;
joachim99@8 1075 }
joachim99@8 1076
joachim99@8 1077 return selectionString;
joachim99@8 1078 }
joachim99@8 1079
joachim99@8 1080 bool DiffTextWindow::findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive )
joachim99@8 1081 {
joachim99@8 1082 int it = d3vLine;
joachim99@8 1083 int endIt = bDirDown ? (int)m_pDiff3LineVector->size() : -1;
joachim99@8 1084 int step = bDirDown ? 1 : -1;
joachim99@8 1085 int startPos = posInLine;
joachim99@8 1086
joachim99@8 1087 for( ; it!=endIt; it+=step )
joachim99@8 1088 {
joachim99@8 1089 QCString line = getString( it );
joachim99@8 1090 if ( !line.isEmpty() )
joachim99@8 1091 {
joachim99@8 1092 int pos = line.find( s, startPos, bCaseSensitive );
joachim99@8 1093 if ( pos != -1 )
joachim99@8 1094 {
joachim99@8 1095 d3vLine = it;
joachim99@8 1096 posInLine = pos;
joachim99@8 1097 return true;
joachim99@8 1098 }
joachim99@8 1099
joachim99@8 1100 startPos = 0;
joachim99@8 1101 }
joachim99@8 1102 }
joachim99@8 1103 return false;
joachim99@8 1104 }
joachim99@8 1105
joachim99@66 1106 void DiffTextWindow::convertD3LCoordsToLineCoords( int d3LIdx, int d3LPos, int& line, int& pos )
joachim99@66 1107 {
joachim99@66 1108 if( m_bWordWrap )
joachim99@66 1109 {
joachim99@66 1110 int wrapPos = d3LPos;
joachim99@66 1111 int wrapLine = convertDiff3LineIdxToLine(d3LIdx);
joachim99@66 1112 while ( wrapPos > m_diff3WrapLineVector[wrapLine].wrapLineLength )
joachim99@66 1113 {
joachim99@66 1114 wrapPos -= m_diff3WrapLineVector[wrapLine].wrapLineLength;
joachim99@66 1115 ++wrapLine;
joachim99@66 1116 }
joachim99@66 1117 pos = wrapPos;
joachim99@66 1118 line = wrapLine;
joachim99@66 1119 }
joachim99@66 1120 else
joachim99@66 1121 {
joachim99@66 1122 pos = d3LPos;
joachim99@66 1123 line = d3LIdx;
joachim99@66 1124 }
joachim99@66 1125 }
joachim99@66 1126
joachim99@66 1127 void DiffTextWindow::convertLineCoordsToD3LCoords( int line, int pos, int& d3LIdx, int& d3LPos )
joachim99@66 1128 {
joachim99@66 1129 if( m_bWordWrap )
joachim99@66 1130 {
joachim99@66 1131 d3LPos = pos;
joachim99@66 1132 d3LIdx = convertLineToDiff3LineIdx( line );
joachim99@66 1133 int wrapLine = convertDiff3LineIdxToLine(d3LIdx); // First wrap line belonging to this d3LIdx
joachim99@66 1134 while ( wrapLine < line )
joachim99@66 1135 {
joachim99@66 1136 d3LPos += m_diff3WrapLineVector[wrapLine].wrapLineLength;
joachim99@66 1137 ++wrapLine;
joachim99@66 1138 }
joachim99@66 1139 }
joachim99@66 1140 else
joachim99@66 1141 {
joachim99@66 1142 d3LPos = pos;
joachim99@66 1143 d3LIdx = line;
joachim99@66 1144 }
joachim99@66 1145 }
joachim99@66 1146
joachim99@66 1147
joachim99@66 1148 void DiffTextWindow::setSelection( int firstLine, int startPos, int lastLine, int endPos, int& l, int& p )
joachim99@8 1149 {
joachim99@8 1150 selection.reset();
joachim99@66 1151 if ( m_bWordWrap && m_pDiff3LineVector!=0 )
joachim99@66 1152 {
joachim99@66 1153 QString s1 = getString(firstLine);
joachim99@66 1154 int firstWrapLine = convertDiff3LineIdxToLine(firstLine);
joachim99@66 1155 int wrapStartPos = startPos;
joachim99@66 1156 while ( wrapStartPos > m_diff3WrapLineVector[firstWrapLine].wrapLineLength )
joachim99@66 1157 {
joachim99@66 1158 wrapStartPos -= m_diff3WrapLineVector[firstWrapLine].wrapLineLength;
joachim99@66 1159 s1 = s1.mid(m_diff3WrapLineVector[firstWrapLine].wrapLineLength);
joachim99@66 1160 ++firstWrapLine;
joachim99@66 1161 }
joachim99@66 1162
joachim99@66 1163 QString s2 = getString(lastLine);
joachim99@66 1164 int lastWrapLine = convertDiff3LineIdxToLine(lastLine);
joachim99@66 1165 int wrapEndPos = endPos;
joachim99@66 1166 while ( wrapEndPos > m_diff3WrapLineVector[lastWrapLine].wrapLineLength )
joachim99@66 1167 {
joachim99@66 1168 wrapEndPos -= m_diff3WrapLineVector[lastWrapLine].wrapLineLength;
joachim99@66 1169 s2 = s2.mid(m_diff3WrapLineVector[lastWrapLine].wrapLineLength);
joachim99@66 1170 ++lastWrapLine;
joachim99@66 1171 }
joachim99@66 1172
joachim99@66 1173 selection.start( firstWrapLine, convertToPosOnScreen( s1, wrapStartPos ) );
joachim99@66 1174 selection.end( lastWrapLine, convertToPosOnScreen( s2, wrapEndPos ) );
joachim99@66 1175 l=firstWrapLine;
joachim99@66 1176 p=wrapStartPos;
joachim99@66 1177 }
joachim99@66 1178 else
joachim99@66 1179 {
joachim99@66 1180 selection.start( firstLine, convertToPosOnScreen( getString(firstLine), startPos ) );
joachim99@66 1181 selection.end( lastLine, convertToPosOnScreen( getString(lastLine), endPos ) );
joachim99@66 1182 l=firstLine;
joachim99@66 1183 p=startPos;
joachim99@66 1184 }
joachim99@8 1185 update();
joachim99@8 1186 }
joachim99@51 1187
joachim99@51 1188
joachim99@66 1189 // Returns the number of wrapped lines
joachim99@66 1190 // if pWrappedLines != 0 then the stringlist will contain the wrapped lines.
joachim99@66 1191 int wordWrap( const QString& origLine, int nofColumns, Diff3WrapLine* pDiff3WrapLine )
joachim99@66 1192 {
joachim99@66 1193 if (nofColumns<=0)
joachim99@66 1194 nofColumns = 1;
joachim99@66 1195
joachim99@66 1196 int nofNeededLines = 0;
joachim99@66 1197 int length = origLine.length();
joachim99@66 1198
joachim99@66 1199 if (length==0)
joachim99@66 1200 {
joachim99@66 1201 nofNeededLines = 1;
joachim99@66 1202 if( pDiff3WrapLine )
joachim99@66 1203 {
joachim99@66 1204 pDiff3WrapLine->wrapLineOffset=0;
joachim99@66 1205 pDiff3WrapLine->wrapLineLength=0;
joachim99@66 1206 }
joachim99@66 1207 }
joachim99@66 1208 else
joachim99@66 1209 {
joachim99@66 1210 int pos = 0;
joachim99@66 1211
joachim99@66 1212 while ( pos < length )
joachim99@66 1213 {
joachim99@66 1214 int wrapPos = pos + nofColumns;
joachim99@66 1215
joachim99@66 1216 if ( length-pos <= nofColumns )
joachim99@66 1217 {
joachim99@66 1218 wrapPos = length;
joachim99@66 1219 }
joachim99@66 1220 else
joachim99@66 1221 {
joachim99@66 1222 int wsPos = max2( origLine.findRev( ' ', wrapPos ), origLine.findRev( '\t', wrapPos ) );
joachim99@66 1223
joachim99@66 1224 if ( wsPos > pos )
joachim99@66 1225 {
joachim99@66 1226 // Wrap line at wsPos
joachim99@66 1227 wrapPos = wsPos;
joachim99@66 1228 }
joachim99@66 1229 }
joachim99@66 1230
joachim99@66 1231 if ( pDiff3WrapLine )
joachim99@66 1232 {
joachim99@66 1233 pDiff3WrapLine->wrapLineOffset = pos;
joachim99@66 1234 pDiff3WrapLine->wrapLineLength = wrapPos-pos;
joachim99@66 1235 ++pDiff3WrapLine;
joachim99@66 1236 }
joachim99@66 1237
joachim99@66 1238 pos = wrapPos;
joachim99@66 1239
joachim99@66 1240 ++nofNeededLines;
joachim99@66 1241 }
joachim99@66 1242 }
joachim99@66 1243 return nofNeededLines;
joachim99@66 1244 }
joachim99@66 1245
joachim99@66 1246 void DiffTextWindow::convertSelectionToD3LCoords()
joachim99@66 1247 {
joachim99@66 1248 if ( m_pDiff3LineVector==0 || ! m_bPaintingAllowed || !isVisible() || selection.isEmpty() )
joachim99@66 1249 {
joachim99@66 1250 return;
joachim99@66 1251 }
joachim99@66 1252
joachim99@66 1253 // convert the selection to unwrapped coordinates: Later restore to new coords
joachim99@66 1254 int firstD3LIdx, firstD3LPos;
joachim99@66 1255 QCString s = getLineString( selection.beginLine() );
joachim99@66 1256 int firstPosInText = convertToPosInText( s, s.length(), selection.beginPos() );
joachim99@66 1257 convertLineCoordsToD3LCoords( selection.beginLine(), firstPosInText, firstD3LIdx, firstD3LPos );
joachim99@66 1258
joachim99@66 1259 int lastD3LIdx, lastD3LPos;
joachim99@66 1260 s = getLineString( selection.endLine() );
joachim99@66 1261 int lastPosInText = convertToPosInText( s, s.length(), selection.endPos() );
joachim99@66 1262 convertLineCoordsToD3LCoords( selection.endLine(), lastPosInText, lastD3LIdx, lastD3LPos );
joachim99@66 1263
joachim99@66 1264 //selection.reset();
joachim99@66 1265 selection.start( firstD3LIdx, firstD3LPos );
joachim99@66 1266 selection.end( lastD3LIdx, lastD3LPos );
joachim99@66 1267 }
joachim99@66 1268
joachim99@66 1269 void DiffTextWindow::recalcWordWrap( bool bWordWrap, int wrapLineVectorSize )
joachim99@66 1270 {
joachim99@66 1271 if ( m_pDiff3LineVector==0 || ! m_bPaintingAllowed || !isVisible() )
joachim99@66 1272 {
joachim99@66 1273 m_bWordWrap = bWordWrap;
joachim99@66 1274 if (!bWordWrap) m_diff3WrapLineVector.resize( 0 );
joachim99@66 1275 return;
joachim99@66 1276 }
joachim99@66 1277
joachim99@66 1278 m_bWordWrap = bWordWrap;
joachim99@66 1279
joachim99@66 1280 if ( bWordWrap )
joachim99@66 1281 {
joachim99@66 1282 m_diff3WrapLineVector.resize( wrapLineVectorSize );
joachim99@66 1283
joachim99@66 1284 int nofVisibleColumns = getNofVisibleColumns();
joachim99@66 1285 int i;
joachim99@66 1286 int wrapLineIdx = 0;
joachim99@66 1287 int size = m_pDiff3LineVector->size();
joachim99@66 1288 for( i=0; i<size; ++i )
joachim99@66 1289 {
joachim99@66 1290 QString s = getString( i );
joachim99@66 1291 int linesNeeded = wordWrap( s, nofVisibleColumns, wrapLineVectorSize==0 ? 0 : &m_diff3WrapLineVector[wrapLineIdx] );
joachim99@66 1292 Diff3Line& d3l = *(*m_pDiff3LineVector)[i];
joachim99@66 1293 if ( d3l.linesNeededForDisplay<linesNeeded )
joachim99@66 1294 {
joachim99@66 1295 d3l.linesNeededForDisplay = linesNeeded;
joachim99@66 1296 }
joachim99@66 1297
joachim99@66 1298 if ( wrapLineVectorSize>0 )
joachim99@66 1299 {
joachim99@66 1300 int j;
joachim99@66 1301 for( j=0; j<d3l.linesNeededForDisplay; ++j, ++wrapLineIdx )
joachim99@66 1302 {
joachim99@66 1303 Diff3WrapLine& d3wl = m_diff3WrapLineVector[wrapLineIdx];
joachim99@66 1304 d3wl.diff3LineIndex = i;
joachim99@66 1305 d3wl.pD3L = (*m_pDiff3LineVector)[i];
joachim99@66 1306 if ( j>=linesNeeded )
joachim99@66 1307 {
joachim99@66 1308 d3wl.wrapLineOffset=0;
joachim99@66 1309 d3wl.wrapLineLength=0;
joachim99@66 1310 }
joachim99@66 1311 }
joachim99@66 1312 }
joachim99@66 1313 }
joachim99@66 1314
joachim99@66 1315 if ( wrapLineVectorSize>0 )
joachim99@66 1316 {
joachim99@66 1317 m_firstLine = min2( m_firstLine, wrapLineVectorSize-1 );
joachim99@66 1318 m_firstColumn = 0;
joachim99@66 1319 }
joachim99@66 1320 }
joachim99@66 1321 else
joachim99@66 1322 {
joachim99@66 1323 m_diff3WrapLineVector.resize( 0 );
joachim99@66 1324 }
joachim99@66 1325
joachim99@66 1326 if ( !selection.isEmpty() && ( !m_bWordWrap || wrapLineVectorSize>0 ) )
joachim99@66 1327 {
joachim99@66 1328 // Assume unwrapped coordinates
joachim99@66 1329 //( Why? ->Conversion to unwrapped coords happened a few lines above in this method.
joachim99@66 1330 // Also see KDiff3App::recalcWordWrap() on the role of wrapLineVectorSize)
joachim99@66 1331
joachim99@66 1332 // Wrap them now.
joachim99@66 1333
joachim99@66 1334 // convert the selection to unwrapped coordinates.
joachim99@66 1335 int firstLine, firstPos;
joachim99@66 1336 convertD3LCoordsToLineCoords( selection.beginLine(), selection.beginPos(), firstLine, firstPos );
joachim99@66 1337
joachim99@66 1338 int lastLine, lastPos;
joachim99@66 1339 convertD3LCoordsToLineCoords( selection.endLine(), selection.endPos(), lastLine, lastPos );
joachim99@66 1340
joachim99@66 1341 //selection.reset();
joachim99@66 1342 selection.start( firstLine, convertToPosOnScreen( getLineString( firstLine ), firstPos ) );
joachim99@66 1343 selection.end( lastLine, convertToPosOnScreen( getLineString( lastLine ),lastPos ) );
joachim99@66 1344 }
joachim99@66 1345 }
joachim99@66 1346
joachim99@66 1347
joachim99@66 1348
joachim99@66 1349
joachim99@51 1350 #include <qtextcodec.h>
joachim99@51 1351
joachim99@51 1352 QString decodeString( const char*s , OptionDialog* pOptions )
joachim99@51 1353 {
joachim99@51 1354 if ( pOptions->m_bStringEncoding )
joachim99@51 1355 {
joachim99@51 1356 QTextCodec* c = QTextCodec::codecForLocale();
joachim99@51 1357 if (c!=0)
joachim99@51 1358 return c->toUnicode( s );
joachim99@51 1359 else
joachim99@51 1360 return QString(s);
joachim99@51 1361 }
joachim99@51 1362 else
joachim99@51 1363 return QString(s);
joachim99@51 1364 }
joachim99@58 1365
joachim99@58 1366 QCString encodeString( const QString& s , OptionDialog* pOptions )
joachim99@58 1367 {
joachim99@58 1368 if ( pOptions->m_bStringEncoding )
joachim99@58 1369 {
joachim99@58 1370 QTextCodec* c = QTextCodec::codecForLocale();
joachim99@58 1371 if (c!=0)
joachim99@58 1372 return c->fromUnicode( s );
joachim99@58 1373 else
joachim99@58 1374 return QCString( s.ascii() );
joachim99@58 1375 }
joachim99@58 1376 else
joachim99@58 1377 return QCString( s.ascii() );
joachim99@58 1378 }