annotate kdiff3/src/mergeresultwindow.cpp @ 58:8af4bb9d9a5a

Version 0.9.83
author joachim99
date Sun, 07 Mar 2004 09:59:09 +0000
parents 32d5cbf9db71
children efe33e938730
rev   line source
joachim99@8 1 /***************************************************************************
joachim99@8 2 mergeresultwindow.cpp - description
joachim99@8 3 -------------------
joachim99@8 4 begin : Sun Apr 14 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 "diff.h"
joachim99@8 19 #include <stdio.h>
joachim99@8 20 #include <qpainter.h>
joachim99@8 21 #include <qapplication.h>
joachim99@8 22 #include <qclipboard.h>
joachim99@8 23 #include <qdir.h>
joachim99@8 24 #include <qfile.h>
joachim99@8 25 #include <qcursor.h>
joachim99@8 26 #include <qpopupmenu.h>
joachim99@8 27 #include <optiondialog.h>
joachim99@8 28 #include <klocale.h>
joachim99@8 29 #include <kmessagebox.h>
joachim99@58 30 #include <iostream>
joachim99@8 31
joachim99@8 32 int g_bAutoSolve = true;
joachim99@8 33
joachim99@53 34 #undef leftInfoWidth
joachim99@8 35 #define leftInfoWidth 3
joachim99@8 36
joachim99@8 37 MergeResultWindow::MergeResultWindow(
joachim99@8 38 QWidget* pParent,
joachim99@8 39 OptionDialog* pOptionDialog
joachim99@8 40 )
joachim99@8 41 : QWidget( pParent, 0, WRepaintNoErase )
joachim99@8 42 {
joachim99@8 43 setFocusPolicy( QWidget::ClickFocus );
joachim99@8 44
joachim99@8 45 m_firstLine = 0;
joachim99@8 46 m_firstColumn = 0;
joachim99@8 47 m_nofColumns = 0;
joachim99@8 48 m_nofLines = 0;
joachim99@58 49 m_totalSize = 0;
joachim99@8 50 m_bMyUpdate = false;
joachim99@8 51 m_bInsertMode = true;
joachim99@8 52 m_scrollDeltaX = 0;
joachim99@8 53 m_scrollDeltaY = 0;
joachim99@8 54 m_bModified = false;
joachim99@8 55
joachim99@8 56 m_fileName = "";
joachim99@8 57 m_pldA = 0;
joachim99@8 58 m_pldB = 0;
joachim99@8 59 m_pldC = 0;
joachim99@8 60
joachim99@8 61 m_pDiff3LineList = 0;
joachim99@8 62 m_pTotalDiffStatus = 0;
joachim99@58 63
joachim99@8 64 m_pOptionDialog = pOptionDialog;
joachim99@58 65 m_bPaintingAllowed = false;
joachim99@8 66
joachim99@8 67 m_cursorXPos=0;
joachim99@8 68 m_cursorOldXPos=0;
joachim99@8 69 m_cursorYPos=0;
joachim99@8 70 m_bCursorOn = true;
joachim99@8 71 connect( &m_cursorTimer, SIGNAL(timeout()), this, SLOT( slotCursorUpdate() ) );
joachim99@8 72 m_cursorTimer.start( 500 /*ms*/, true /*single shot*/ );
joachim99@8 73 m_selection.reset();
joachim99@8 74
joachim99@8 75 setMinimumSize( QSize(20,20) );
joachim99@27 76 setFont( m_pOptionDialog->m_font );
joachim99@8 77 }
joachim99@8 78
joachim99@8 79 void MergeResultWindow::init(
joachim99@8 80 const LineData* pLineDataA,
joachim99@8 81 const LineData* pLineDataB,
joachim99@8 82 const LineData* pLineDataC,
joachim99@8 83 const Diff3LineList* pDiff3LineList,
joachim99@8 84 const TotalDiffStatus* pTotalDiffStatus,
joachim99@8 85 QString fileName
joachim99@8 86 )
joachim99@8 87 {
joachim99@8 88 m_firstLine = 0;
joachim99@8 89 m_firstColumn = 0;
joachim99@8 90 m_nofColumns = 0;
joachim99@8 91 m_nofLines = 0;
joachim99@8 92 m_bMyUpdate = false;
joachim99@8 93 m_bInsertMode = true;
joachim99@8 94 m_scrollDeltaX = 0;
joachim99@8 95 m_scrollDeltaY = 0;
joachim99@8 96 m_bModified = false;
joachim99@8 97
joachim99@8 98 m_fileName = fileName;
joachim99@8 99 m_pldA = pLineDataA;
joachim99@8 100 m_pldB = pLineDataB;
joachim99@8 101 m_pldC = pLineDataC;
joachim99@8 102
joachim99@8 103 m_pDiff3LineList = pDiff3LineList;
joachim99@8 104 m_pTotalDiffStatus = pTotalDiffStatus;
joachim99@8 105
joachim99@8 106 m_selection.reset();
joachim99@8 107 m_cursorXPos=0;
joachim99@8 108 m_cursorOldXPos=0;
joachim99@8 109 m_cursorYPos=0;
joachim99@8 110
joachim99@8 111 merge( g_bAutoSolve, -1 );
joachim99@8 112 g_bAutoSolve = true;
joachim99@8 113 update();
joachim99@8 114 }
joachim99@8 115
joachim99@8 116
joachim99@8 117 // Calculate the merge information for the given Diff3Line.
joachim99@8 118 // Results will be stored in mergeDetails, bConflict, bLineRemoved and src.
joachim99@8 119 void mergeOneLine(
joachim99@8 120 const Diff3Line& d, e_MergeDetails& mergeDetails, bool& bConflict,
joachim99@8 121 bool& bLineRemoved, int& src, bool bTwoInputs
joachim99@8 122 )
joachim99@8 123 {
joachim99@8 124 mergeDetails = eDefault;
joachim99@8 125 bConflict = false;
joachim99@8 126 bLineRemoved = false;
joachim99@8 127 src = 0;
joachim99@8 128
joachim99@8 129 if ( bTwoInputs ) // Only two input files
joachim99@8 130 {
joachim99@8 131 if ( d.lineA!=-1 && d.lineB!=-1 )
joachim99@8 132 {
joachim99@8 133 if ( d.pFineAB == 0 )
joachim99@8 134 {
joachim99@8 135 mergeDetails = eNoChange; src = A;
joachim99@8 136 }
joachim99@8 137 else
joachim99@8 138 {
joachim99@8 139 mergeDetails = eBChanged; bConflict = true;
joachim99@8 140 }
joachim99@8 141 }
joachim99@8 142 else
joachim99@8 143 {
joachim99@8 144 if ( d.lineA!=-1 && d.lineB==-1 )
joachim99@8 145 {
joachim99@8 146 mergeDetails = eBDeleted; bConflict = true;
joachim99@8 147 }
joachim99@8 148 else if ( d.lineA==-1 && d.lineB!=-1 )
joachim99@8 149 {
joachim99@8 150 mergeDetails = eBDeleted; bConflict = true;
joachim99@8 151 }
joachim99@8 152 }
joachim99@8 153 return;
joachim99@8 154 }
joachim99@8 155
joachim99@8 156 // A is base.
joachim99@8 157 if ( d.lineA!=-1 && d.lineB!=-1 && d.lineC!=-1 )
joachim99@8 158 {
joachim99@8 159 if ( d.pFineAB == 0 && d.pFineBC == 0 && d.pFineCA == 0)
joachim99@8 160 {
joachim99@8 161 mergeDetails = eNoChange; src = A;
joachim99@8 162 }
joachim99@8 163 else if( d.pFineAB == 0 && d.pFineBC != 0 && d.pFineCA != 0 )
joachim99@8 164 {
joachim99@8 165 mergeDetails = eCChanged; src = C;
joachim99@8 166 }
joachim99@8 167 else if( d.pFineAB != 0 && d.pFineBC != 0 && d.pFineCA == 0 )
joachim99@8 168 {
joachim99@8 169 mergeDetails = eBChanged; src = B;
joachim99@8 170 }
joachim99@8 171 else if( d.pFineAB != 0 && d.pFineBC == 0 && d.pFineCA != 0 )
joachim99@8 172 {
joachim99@8 173 mergeDetails = eBCChangedAndEqual; src = C;
joachim99@8 174 }
joachim99@8 175 else if( d.pFineAB != 0 && d.pFineBC != 0 && d.pFineCA != 0 )
joachim99@8 176 {
joachim99@8 177 mergeDetails = eBCChanged; bConflict = true;
joachim99@8 178 }
joachim99@8 179 else
joachim99@8 180 assert(false);
joachim99@8 181 }
joachim99@8 182 else if ( d.lineA!=-1 && d.lineB!=-1 && d.lineC==-1 )
joachim99@8 183 {
joachim99@8 184 if( d.pFineAB != 0 )
joachim99@8 185 {
joachim99@8 186 mergeDetails = eBChanged_CDeleted; bConflict = true;
joachim99@8 187 }
joachim99@8 188 else
joachim99@8 189 {
joachim99@8 190 mergeDetails = eCDeleted; bLineRemoved = true; src = C;
joachim99@8 191 }
joachim99@8 192 }
joachim99@8 193 else if ( d.lineA!=-1 && d.lineB==-1 && d.lineC!=-1 )
joachim99@8 194 {
joachim99@8 195 if( d.pFineCA != 0 )
joachim99@8 196 {
joachim99@8 197 mergeDetails = eCChanged_BDeleted; bConflict = true;
joachim99@8 198 }
joachim99@8 199 else
joachim99@8 200 {
joachim99@8 201 mergeDetails = eBDeleted; bLineRemoved = true; src = B;
joachim99@8 202 }
joachim99@8 203 }
joachim99@8 204 else if ( d.lineA==-1 && d.lineB!=-1 && d.lineC!=-1 )
joachim99@8 205 {
joachim99@8 206 if( d.pFineBC != 0 )
joachim99@8 207 {
joachim99@8 208 mergeDetails = eBCAdded; bConflict = true;
joachim99@8 209 }
joachim99@8 210 else // B==C
joachim99@8 211 {
joachim99@8 212 mergeDetails = eBCAddedAndEqual; src = C;
joachim99@8 213 }
joachim99@8 214 }
joachim99@8 215 else if ( d.lineA==-1 && d.lineB==-1 && d.lineC!= -1 )
joachim99@8 216 {
joachim99@8 217 mergeDetails = eCAdded; src = C;
joachim99@8 218 }
joachim99@8 219 else if ( d.lineA==-1 && d.lineB!=-1 && d.lineC== -1 )
joachim99@8 220 {
joachim99@8 221 mergeDetails = eBAdded; src = B;
joachim99@8 222 }
joachim99@8 223 else if ( d.lineA!=-1 && d.lineB==-1 && d.lineC==-1 )
joachim99@8 224 {
joachim99@8 225 mergeDetails = eBCDeleted; bLineRemoved = true; src = C;
joachim99@8 226 }
joachim99@8 227 else
joachim99@8 228 assert(false);
joachim99@8 229 }
joachim99@8 230
joachim99@8 231 bool MergeResultWindow::sameKindCheck( const MergeLine& ml1, const MergeLine& ml2 )
joachim99@8 232 {
joachim99@8 233 if ( ml1.bConflict && ml2.bConflict )
joachim99@8 234 {
joachim99@51 235 // Both lines have conflicts: If one is only a white space conflict and
joachim99@51 236 // the other one is a real conflict, then this line returns false.
joachim99@8 237 return ml1.id3l->bAEqC == ml2.id3l->bAEqC && ml1.id3l->bAEqB == ml2.id3l->bAEqB;
joachim99@8 238 }
joachim99@8 239 else
joachim99@8 240 return (
joachim99@8 241 !ml1.bConflict && !ml2.bConflict && ml1.bDelta && ml2.bDelta && ml1.srcSelect == ml2.srcSelect ||
joachim99@8 242 !ml1.bDelta && !ml2.bDelta
joachim99@8 243 );
joachim99@8 244 }
joachim99@8 245
joachim99@51 246 void MergeResultWindow::merge(bool bAutoSolve, int defaultSelector, bool bConflictsOnly, bool bWhiteSpaceOnly )
joachim99@51 247 {
joachim99@51 248 if ( !bConflictsOnly )
joachim99@8 249 {
joachim99@51 250 if(m_bModified)
joachim99@8 251 {
joachim99@51 252 int result = KMessageBox::warningYesNo(this,
joachim99@51 253 i18n("The output has been modified.\n"
joachim99@51 254 "If you continue your changes will be lost."),
joachim99@51 255 i18n("Warning"), i18n("C&ontinue"), i18n("&Cancel"));
joachim99@51 256 if ( result==KMessageBox::No )
joachim99@51 257 return;
joachim99@8 258 }
joachim99@8 259
joachim99@51 260 m_mergeLineList.clear();
joachim99@58 261 m_totalSize = 0;
joachim99@51 262 int lineIdx = 0;
joachim99@51 263 Diff3LineList::const_iterator it;
joachim99@51 264 for( it=m_pDiff3LineList->begin(); it!=m_pDiff3LineList->end(); ++it, ++lineIdx )
joachim99@8 265 {
joachim99@51 266 const Diff3Line& d = *it;
joachim99@51 267
joachim99@51 268 MergeLine ml;
joachim99@51 269 bool bLineRemoved;
joachim99@51 270 mergeOneLine( d, ml.mergeDetails, ml.bConflict, bLineRemoved, ml.srcSelect, m_pldC==0 );
joachim99@51 271
joachim99@51 272 // Automatic solving for only whitespace changes.
joachim99@51 273 if ( ml.bConflict &&
joachim99@51 274 ( m_pldC==0 && (d.bAEqB || d.bWhiteLineA && d.bWhiteLineB) ||
joachim99@51 275 m_pldC!=0 && (d.bAEqB && d.bAEqC || d.bWhiteLineA && d.bWhiteLineB && d.bWhiteLineC ) ) )
joachim99@51 276 {
joachim99@51 277 ml.bWhiteSpaceConflict = true;
joachim99@51 278 }
joachim99@51 279
joachim99@51 280 ml.d3lLineIdx = lineIdx;
joachim99@51 281 ml.bDelta = ml.srcSelect != A;
joachim99@51 282 ml.id3l = it;
joachim99@51 283 ml.srcRangeLength = 1;
joachim99@51 284
joachim99@51 285 MergeLine* back = m_mergeLineList.empty() ? 0 : &m_mergeLineList.back();
joachim99@51 286
joachim99@51 287 bool bSame = back!=0 && sameKindCheck( ml, *back );
joachim99@51 288 if( bSame )
joachim99@51 289 {
joachim99@51 290 ++back->srcRangeLength;
joachim99@51 291 if ( back->bWhiteSpaceConflict && !ml.bWhiteSpaceConflict )
joachim99@51 292 back->bWhiteSpaceConflict = false;
joachim99@51 293 }
joachim99@51 294 else
joachim99@51 295 {
joachim99@51 296 if (back!=0 && back->bWhiteSpaceConflict )
joachim99@51 297 {
joachim99@51 298 if ( m_pldC==0 && m_pOptionDialog->m_whiteSpace2FileMergeDefault != 0 ) // Only two inputs
joachim99@51 299 {
joachim99@51 300 back->srcSelect = m_pOptionDialog->m_whiteSpace2FileMergeDefault;
joachim99@51 301 back->bConflict = false;
joachim99@51 302 }
joachim99@51 303 else if ( m_pldC!=0 && m_pOptionDialog->m_whiteSpace3FileMergeDefault != 0 )
joachim99@51 304 {
joachim99@51 305 back->srcSelect = m_pOptionDialog->m_whiteSpace3FileMergeDefault;
joachim99@51 306 back->bConflict = false;
joachim99@51 307 }
joachim99@51 308 }
joachim99@58 309 ml.mergeEditLineList.setTotalSizePtr(&m_totalSize);
joachim99@51 310 m_mergeLineList.push_back( ml );
joachim99@51 311 }
joachim99@51 312
joachim99@51 313 if ( ! ml.bConflict )
joachim99@51 314 {
joachim99@51 315 MergeLine& tmpBack = m_mergeLineList.back();
joachim99@51 316 MergeEditLine mel;
joachim99@51 317 mel.setSource( ml.srcSelect, ml.id3l, bLineRemoved );
joachim99@51 318 tmpBack.mergeEditLineList.push_back(mel);
joachim99@51 319 }
joachim99@51 320 else if ( back==0 || ! back->bConflict || !bSame )
joachim99@51 321 {
joachim99@51 322 MergeLine& tmpBack = m_mergeLineList.back();
joachim99@51 323 MergeEditLine mel;
joachim99@51 324 mel.setConflict();
joachim99@51 325 tmpBack.mergeEditLineList.push_back(mel);
joachim99@51 326 }
joachim99@8 327 }
joachim99@8 328 }
joachim99@8 329
joachim99@8 330 if ( !bAutoSolve )
joachim99@8 331 {
joachim99@8 332 // Change all auto selections
joachim99@8 333 MergeLineList::iterator mlIt;
joachim99@8 334 for( mlIt=m_mergeLineList.begin(); mlIt!=m_mergeLineList.end(); ++mlIt )
joachim99@8 335 {
joachim99@8 336 MergeLine& ml = *mlIt;
joachim99@51 337 bool bConflict = ml.mergeEditLineList.empty() || ml.mergeEditLineList.begin()->isConflict();
joachim99@51 338 if ( ml.bDelta && ( !bConflictsOnly || bConflict ) && (!bWhiteSpaceOnly || ml.bWhiteSpaceConflict ))
joachim99@8 339 {
joachim99@8 340 ml.mergeEditLineList.clear();
joachim99@8 341 if ( defaultSelector==-1 && ml.bDelta )
joachim99@8 342 {
joachim99@8 343 MergeEditLine mel;
joachim99@8 344 mel.setConflict();
joachim99@8 345 ml.bConflict = true;
joachim99@8 346 ml.mergeEditLineList.push_back(mel);
joachim99@8 347 }
joachim99@8 348 else
joachim99@8 349 {
joachim99@8 350 Diff3LineList::const_iterator d3llit=ml.id3l;
joachim99@8 351 int j;
joachim99@8 352
joachim99@8 353 for( j=0; j<ml.srcRangeLength; ++j )
joachim99@8 354 {
joachim99@8 355 MergeEditLine mel;
joachim99@8 356 mel.setSource( defaultSelector, d3llit, false );
joachim99@51 357
joachim99@8 358 int srcLine = defaultSelector==1 ? d3llit->lineA :
joachim99@8 359 defaultSelector==2 ? d3llit->lineB :
joachim99@8 360 defaultSelector==3 ? d3llit->lineC : -1;
joachim99@51 361
joachim99@8 362 if ( srcLine != -1 )
joachim99@8 363 {
joachim99@8 364 ml.mergeEditLineList.push_back(mel);
joachim99@8 365 }
joachim99@8 366
joachim99@8 367 ++d3llit;
joachim99@8 368 }
joachim99@8 369
joachim99@8 370 if ( ml.mergeEditLineList.empty() ) // Make a line nevertheless
joachim99@8 371 {
joachim99@8 372 MergeEditLine mel;
joachim99@8 373 mel.setSource( defaultSelector, ml.id3l, false );
joachim99@8 374 mel.setRemoved( defaultSelector );
joachim99@8 375 ml.mergeEditLineList.push_back(mel);
joachim99@8 376 }
joachim99@8 377 }
joachim99@8 378 }
joachim99@8 379 }
joachim99@8 380 }
joachim99@8 381
joachim99@8 382 MergeLineList::iterator mlIt;
joachim99@8 383 for( mlIt=m_mergeLineList.begin(); mlIt!=m_mergeLineList.end(); ++mlIt )
joachim99@8 384 {
joachim99@8 385 MergeLine& ml = *mlIt;
joachim99@8 386 // Remove all lines that are empty, because no src lines are there.
joachim99@8 387
joachim99@8 388 int oldSrcLine = -1;
joachim99@8 389 int oldSrc = -1;
joachim99@8 390 MergeEditLineList::iterator melIt;
joachim99@8 391 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); )
joachim99@8 392 {
joachim99@8 393 MergeEditLine& mel = *melIt;
joachim99@8 394 int melsrc = mel.src();
joachim99@8 395
joachim99@8 396 int srcLine = melsrc==1 ? mel.id3l()->lineA :
joachim99@8 397 melsrc==2 ? mel.id3l()->lineB :
joachim99@8 398 melsrc==3 ? mel.id3l()->lineC : -1;
joachim99@8 399
joachim99@8 400 if ( srcLine == -1 && oldSrcLine==-1 && oldSrc == melsrc )
joachim99@8 401 melIt = ml.mergeEditLineList.erase( melIt );
joachim99@8 402 else
joachim99@8 403 ++melIt;
joachim99@8 404
joachim99@8 405 oldSrcLine = srcLine;
joachim99@8 406 oldSrc = melsrc;
joachim99@8 407 }
joachim99@8 408 }
joachim99@8 409
joachim99@8 410 m_currentMergeLineIt = m_mergeLineList.begin();
joachim99@8 411 m_cursorXPos=0;
joachim99@8 412 m_cursorOldXPos=0;
joachim99@8 413 m_cursorYPos=0;
joachim99@8 414 m_firstLine = 0;
joachim99@8 415 m_firstColumn = 0;
joachim99@51 416
joachim99@8 417 m_bModified = false;
joachim99@8 418 updateAvailabilities();
joachim99@8 419 update();
joachim99@8 420 }
joachim99@8 421
joachim99@8 422 void MergeResultWindow::setFirstLine(int firstLine)
joachim99@8 423 {
joachim99@8 424 m_firstLine = max2(0,firstLine);
joachim99@8 425 update();
joachim99@8 426 }
joachim99@8 427
joachim99@8 428 void MergeResultWindow::setFirstColumn(int firstCol)
joachim99@8 429 {
joachim99@8 430 m_firstColumn = max2(0,firstCol);
joachim99@8 431 update();
joachim99@8 432 }
joachim99@8 433
joachim99@8 434 int MergeResultWindow::getNofColumns()
joachim99@8 435 {
joachim99@8 436 return m_nofColumns;
joachim99@8 437 }
joachim99@8 438
joachim99@8 439 int MergeResultWindow::getNofLines()
joachim99@8 440 {
joachim99@58 441 return m_totalSize;
joachim99@8 442 }
joachim99@8 443
joachim99@8 444 int MergeResultWindow::getNofVisibleColumns()
joachim99@8 445 {
joachim99@8 446 QFontMetrics fm = fontMetrics();
joachim99@8 447 return width()/fm.width('W')-4;
joachim99@8 448 }
joachim99@8 449
joachim99@8 450 int MergeResultWindow::getNofVisibleLines()
joachim99@8 451 {
joachim99@8 452 QFontMetrics fm = fontMetrics();
joachim99@8 453 return (height()-3)/fm.height()-2;
joachim99@8 454 }
joachim99@8 455
joachim99@8 456 void MergeResultWindow::resizeEvent( QResizeEvent* e )
joachim99@8 457 {
joachim99@8 458 QWidget::resizeEvent(e);
joachim99@8 459 emit resizeSignal();
joachim99@8 460 }
joachim99@8 461
joachim99@8 462 // Go to prev/next delta/conflict or first/last delta.
joachim99@8 463 void MergeResultWindow::go( e_Direction eDir, e_EndPoint eEndPoint )
joachim99@8 464 {
joachim99@8 465 assert( eDir==eUp || eDir==eDown );
joachim99@8 466 MergeLineList::iterator i = m_currentMergeLineIt;
joachim99@51 467 bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace;
joachim99@8 468 if( eEndPoint==eEnd )
joachim99@8 469 {
joachim99@8 470 if (eDir==eUp) i = m_mergeLineList.begin(); // first mergeline
joachim99@8 471 else i = --m_mergeLineList.end(); // last mergeline
joachim99@8 472
joachim99@51 473 while ( i!=m_mergeLineList.end() && ! i->bDelta )
joachim99@8 474 {
joachim99@8 475 if ( eDir==eUp ) ++i; // search downwards
joachim99@8 476 else --i; // search upwards
joachim99@8 477 }
joachim99@8 478 }
joachim99@8 479 else if ( eEndPoint == eDelta && i!=m_mergeLineList.end())
joachim99@8 480 {
joachim99@8 481 do
joachim99@8 482 {
joachim99@8 483 if ( eDir==eUp ) --i;
joachim99@8 484 else ++i;
joachim99@8 485 }
joachim99@51 486 while ( i!=m_mergeLineList.end() && ( i->bDelta == false || bSkipWhiteConflicts && i->bWhiteSpaceConflict ) );
joachim99@8 487 }
joachim99@51 488 else if ( eEndPoint == eConflict && i!=m_mergeLineList.end() )
joachim99@8 489 {
joachim99@8 490 do
joachim99@8 491 {
joachim99@8 492 if ( eDir==eUp ) --i;
joachim99@8 493 else ++i;
joachim99@8 494 }
joachim99@51 495 while ( i!=m_mergeLineList.end() && (i->bConflict == false || bSkipWhiteConflicts && i->bWhiteSpaceConflict ) );
joachim99@8 496 }
joachim99@51 497 else if ( i!=m_mergeLineList.end() && eEndPoint == eUnsolvedConflict )
joachim99@8 498 {
joachim99@8 499 do
joachim99@8 500 {
joachim99@8 501 if ( eDir==eUp ) --i;
joachim99@8 502 else ++i;
joachim99@8 503 }
joachim99@8 504 while ( i!=m_mergeLineList.end() && ! i->mergeEditLineList.begin()->isConflict() );
joachim99@8 505 }
joachim99@8 506
joachim99@8 507 setFastSelector( i );
joachim99@53 508
joachim99@53 509 if ( isVisible() )
joachim99@53 510 setFocus();
joachim99@8 511 }
joachim99@8 512
joachim99@8 513 bool MergeResultWindow::isDeltaAboveCurrent()
joachim99@8 514 {
joachim99@51 515 bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace;
joachim99@8 516 MergeLineList::iterator i = m_currentMergeLineIt;
joachim99@8 517 --i;
joachim99@8 518 for( ; i!=m_mergeLineList.end(); --i )
joachim99@8 519 {
joachim99@51 520 if ( i->bDelta && !( bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ) return true;
joachim99@8 521 }
joachim99@8 522 return false;
joachim99@8 523 }
joachim99@8 524
joachim99@8 525 bool MergeResultWindow::isDeltaBelowCurrent()
joachim99@8 526 {
joachim99@51 527 bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace;
joachim99@8 528 MergeLineList::iterator i = m_currentMergeLineIt;
joachim99@8 529 ++i;
joachim99@8 530 for( ; i!=m_mergeLineList.end(); ++i )
joachim99@8 531 {
joachim99@51 532 if ( i->bDelta && !( bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ) return true;
joachim99@8 533 }
joachim99@8 534 return false;
joachim99@8 535 }
joachim99@8 536
joachim99@8 537 bool MergeResultWindow::isConflictAboveCurrent()
joachim99@8 538 {
joachim99@8 539 MergeLineList::iterator i = m_currentMergeLineIt;
joachim99@8 540 --i;
joachim99@8 541 for( ; i!=m_mergeLineList.end(); --i )
joachim99@8 542 {
joachim99@8 543 if ( i->bConflict ) return true;
joachim99@8 544 }
joachim99@8 545 return false;
joachim99@8 546 }
joachim99@8 547
joachim99@8 548 bool MergeResultWindow::isConflictBelowCurrent()
joachim99@8 549 {
joachim99@8 550 MergeLineList::iterator i = m_currentMergeLineIt;
joachim99@8 551 ++i;
joachim99@8 552 for( ; i!=m_mergeLineList.end(); ++i )
joachim99@8 553 {
joachim99@8 554 if ( i->bConflict ) return true;
joachim99@8 555 }
joachim99@8 556 return false;
joachim99@8 557 }
joachim99@8 558
joachim99@8 559 bool MergeResultWindow::isUnsolvedConflictAboveCurrent()
joachim99@8 560 {
joachim99@8 561 MergeLineList::iterator i = m_currentMergeLineIt;
joachim99@8 562 --i;
joachim99@8 563 for( ; i!=m_mergeLineList.end(); --i )
joachim99@8 564 {
joachim99@8 565 if ( i->mergeEditLineList.begin()->isConflict() ) return true;
joachim99@8 566 }
joachim99@8 567 return false;
joachim99@8 568 }
joachim99@8 569
joachim99@8 570 bool MergeResultWindow::isUnsolvedConflictBelowCurrent()
joachim99@8 571 {
joachim99@8 572 MergeLineList::iterator i = m_currentMergeLineIt;
joachim99@8 573 ++i;
joachim99@8 574 for( ; i!=m_mergeLineList.end(); ++i )
joachim99@8 575 {
joachim99@8 576 if ( i->mergeEditLineList.begin()->isConflict() ) return true;
joachim99@8 577 }
joachim99@8 578 return false;
joachim99@8 579 }
joachim99@8 580
joachim99@8 581 void MergeResultWindow::slotGoTop()
joachim99@8 582 {
joachim99@8 583 go( eUp, eEnd );
joachim99@8 584 }
joachim99@8 585
joachim99@8 586 void MergeResultWindow::slotGoCurrent()
joachim99@8 587 {
joachim99@8 588 setFastSelector( m_currentMergeLineIt );
joachim99@8 589 }
joachim99@8 590
joachim99@8 591 void MergeResultWindow::slotGoBottom()
joachim99@8 592 {
joachim99@8 593 go( eDown, eEnd );
joachim99@8 594 }
joachim99@8 595
joachim99@8 596 void MergeResultWindow::slotGoPrevDelta()
joachim99@8 597 {
joachim99@8 598 go( eUp, eDelta );
joachim99@8 599 }
joachim99@8 600
joachim99@8 601 void MergeResultWindow::slotGoNextDelta()
joachim99@8 602 {
joachim99@8 603 go( eDown, eDelta );
joachim99@8 604 }
joachim99@8 605
joachim99@8 606 void MergeResultWindow::slotGoPrevConflict()
joachim99@8 607 {
joachim99@8 608 go( eUp, eConflict );
joachim99@8 609 }
joachim99@8 610
joachim99@8 611 void MergeResultWindow::slotGoNextConflict()
joachim99@8 612 {
joachim99@8 613 go( eDown, eConflict );
joachim99@8 614 }
joachim99@8 615
joachim99@8 616 void MergeResultWindow::slotGoPrevUnsolvedConflict()
joachim99@8 617 {
joachim99@8 618 go( eUp, eUnsolvedConflict );
joachim99@8 619 }
joachim99@8 620
joachim99@8 621 void MergeResultWindow::slotGoNextUnsolvedConflict()
joachim99@8 622 {
joachim99@8 623 go( eDown, eUnsolvedConflict );
joachim99@8 624 }
joachim99@8 625
joachim99@8 626 /** The line is given as a index in the Diff3LineList.
joachim99@8 627 The function calculates the corresponding iterator. */
joachim99@8 628 void MergeResultWindow::slotSetFastSelectorLine( int line )
joachim99@8 629 {
joachim99@8 630 MergeLineList::iterator i;
joachim99@8 631 for ( i = m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i )
joachim99@8 632 {
joachim99@8 633 if ( line>=i->d3lLineIdx && line < i->d3lLineIdx + i->srcRangeLength )
joachim99@8 634 {
joachim99@8 635 if ( i->bDelta )
joachim99@8 636 {
joachim99@8 637 setFastSelector( i );
joachim99@8 638 }
joachim99@8 639 break;
joachim99@8 640 }
joachim99@8 641 }
joachim99@8 642 }
joachim99@8 643
joachim99@8 644 int MergeResultWindow::getNrOfUnsolvedConflicts()
joachim99@8 645 {
joachim99@8 646 int nrOfUnsolvedConflicts = 0;
joachim99@8 647
joachim99@8 648 MergeLineList::iterator mlIt = m_mergeLineList.begin();
joachim99@8 649 for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt)
joachim99@8 650 {
joachim99@8 651 MergeLine& ml = *mlIt;
joachim99@8 652 MergeEditLineList::iterator melIt = ml.mergeEditLineList.begin();
joachim99@8 653 if ( melIt->isConflict() )
joachim99@8 654 ++nrOfUnsolvedConflicts;
joachim99@8 655 }
joachim99@8 656
joachim99@8 657 return nrOfUnsolvedConflicts;
joachim99@8 658 }
joachim99@8 659
joachim99@8 660 void MergeResultWindow::showNrOfConflicts()
joachim99@8 661 {
joachim99@8 662 int nrOfSolvedConflicts = 0;
joachim99@8 663 int nrOfUnsolvedConflicts = 0;
joachim99@8 664
joachim99@8 665 MergeLineList::iterator i;
joachim99@8 666 for ( i = m_mergeLineList.begin(); i!=m_mergeLineList.end(); ++i )
joachim99@8 667 {
joachim99@8 668 if ( i->bConflict )
joachim99@8 669 ++nrOfUnsolvedConflicts;
joachim99@8 670 else if ( i->bDelta )
joachim99@8 671 ++nrOfSolvedConflicts;
joachim99@8 672 }
joachim99@8 673 QString totalInfo;
joachim99@8 674 if ( m_pTotalDiffStatus->bBinaryAEqB && m_pTotalDiffStatus->bBinaryAEqC )
joachim99@8 675 totalInfo += i18n("All input files are binary equal.");
joachim99@8 676 else if ( m_pTotalDiffStatus->bTextAEqB && m_pTotalDiffStatus->bTextAEqC )
joachim99@8 677 totalInfo += i18n("All input files contain the same text.");
joachim99@8 678 else {
joachim99@8 679 if ( m_pTotalDiffStatus->bBinaryAEqB ) totalInfo += i18n("Files A and B are binary equal.\n");
joachim99@8 680 else if ( m_pTotalDiffStatus->bTextAEqB ) totalInfo += i18n("Files A and B have equal text. \n");
joachim99@8 681 if ( m_pTotalDiffStatus->bBinaryAEqC ) totalInfo += i18n("Files A and C are binary equal.\n");
joachim99@8 682 else if ( m_pTotalDiffStatus->bTextAEqC ) totalInfo += i18n("Files A and C have equal text. \n");
joachim99@8 683 if ( m_pTotalDiffStatus->bBinaryBEqC ) totalInfo += i18n("Files B and C are binary equal.\n");
joachim99@8 684 else if ( m_pTotalDiffStatus->bTextBEqC ) totalInfo += i18n("Files B and C have equal text. \n");
joachim99@8 685 }
joachim99@8 686 KMessageBox::information( this,
joachim99@8 687 i18n("Total number of conflicts: ") + QString::number(nrOfSolvedConflicts + nrOfUnsolvedConflicts) +
joachim99@8 688 i18n("\nNr of automatically solved conflicts: ") + QString::number(nrOfSolvedConflicts) +
joachim99@8 689 i18n("\nNr of unsolved conflicts: ") + QString::number(nrOfUnsolvedConflicts) +
joachim99@8 690 "\n"+totalInfo,
joachim99@8 691 i18n("Conflicts")
joachim99@8 692 );
joachim99@8 693 }
joachim99@8 694
joachim99@8 695 void MergeResultWindow::setFastSelector(MergeLineList::iterator i)
joachim99@8 696 {
joachim99@8 697 if ( i==m_mergeLineList.end() )
joachim99@8 698 return;
joachim99@8 699 m_currentMergeLineIt = i;
joachim99@8 700 emit setFastSelectorRange( i->d3lLineIdx, i->srcRangeLength );
joachim99@8 701
joachim99@8 702 int line1 = 0;
joachim99@8 703
joachim99@8 704 MergeLineList::iterator mlIt = m_mergeLineList.begin();
joachim99@8 705 for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt)
joachim99@8 706 {
joachim99@8 707 if(mlIt==m_currentMergeLineIt)
joachim99@8 708 break;
joachim99@8 709 line1 += mlIt->mergeEditLineList.size();
joachim99@8 710 }
joachim99@8 711
joachim99@8 712 int nofLines = m_currentMergeLineIt->mergeEditLineList.size();
joachim99@8 713 int newFirstLine = getBestFirstLine( line1, nofLines, m_firstLine, getNofVisibleLines() );
joachim99@8 714 if ( newFirstLine != m_firstLine )
joachim99@8 715 {
joachim99@8 716 scroll( 0, newFirstLine - m_firstLine );
joachim99@8 717 }
joachim99@8 718
joachim99@8 719 if ( m_selection.isEmpty() )
joachim99@8 720 {
joachim99@8 721 m_cursorXPos = 0;
joachim99@8 722 m_cursorOldXPos = 0;
joachim99@8 723 m_cursorYPos = line1;
joachim99@8 724 }
joachim99@8 725
joachim99@8 726 update();
joachim99@8 727 emit updateAvailabilities();
joachim99@8 728 }
joachim99@8 729
joachim99@8 730 void MergeResultWindow::choose( int selector )
joachim99@8 731 {
joachim99@8 732 setModified();
joachim99@8 733
joachim99@8 734 // First find range for which this change works.
joachim99@8 735 MergeLine& ml = *m_currentMergeLineIt;
joachim99@8 736
joachim99@8 737 MergeEditLineList::iterator melIt;
joachim99@8 738
joachim99@8 739 // Now check if selector is active for this range already.
joachim99@8 740 bool bActive = false;
joachim99@8 741
joachim99@8 742 // Remove unneeded lines in the range.
joachim99@8 743 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); )
joachim99@8 744 {
joachim99@8 745 MergeEditLine& mel = *melIt;
joachim99@8 746 if ( mel.src()==selector )
joachim99@8 747 bActive = true;
joachim99@8 748
joachim99@8 749 if ( mel.src()==selector || !mel.isEditableText() || mel.isModified() )
joachim99@8 750 melIt = ml.mergeEditLineList.erase( melIt );
joachim99@8 751 else
joachim99@8 752 ++melIt;
joachim99@8 753 }
joachim99@8 754
joachim99@8 755 if ( !bActive ) // Selected source wasn't active.
joachim99@8 756 { // Append the lines from selected source here at rangeEnd.
joachim99@8 757 Diff3LineList::const_iterator d3llit=ml.id3l;
joachim99@8 758 int j;
joachim99@8 759
joachim99@8 760 for( j=0; j<ml.srcRangeLength; ++j )
joachim99@8 761 {
joachim99@8 762 MergeEditLine mel;
joachim99@8 763 mel.setSource( selector, d3llit, false );
joachim99@8 764 ml.mergeEditLineList.push_back(mel);
joachim99@8 765
joachim99@8 766 ++d3llit;
joachim99@8 767 }
joachim99@8 768 }
joachim99@8 769
joachim99@8 770 if ( ! ml.mergeEditLineList.empty() )
joachim99@8 771 {
joachim99@8 772 // Remove all lines that are empty, because no src lines are there.
joachim99@8 773 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); )
joachim99@8 774 {
joachim99@8 775 MergeEditLine& mel = *melIt;
joachim99@8 776
joachim99@8 777 int srcLine = mel.src()==1 ? mel.id3l()->lineA :
joachim99@8 778 mel.src()==2 ? mel.id3l()->lineB :
joachim99@8 779 mel.src()==3 ? mel.id3l()->lineC : -1;
joachim99@8 780
joachim99@8 781 if ( srcLine == -1 )
joachim99@8 782 melIt = ml.mergeEditLineList.erase( melIt );
joachim99@8 783 else
joachim99@8 784 ++melIt;
joachim99@8 785 }
joachim99@8 786 }
joachim99@8 787
joachim99@8 788 if ( ml.mergeEditLineList.empty() )
joachim99@8 789 {
joachim99@8 790 // Insert a dummy line:
joachim99@8 791 MergeEditLine mel;
joachim99@8 792
joachim99@8 793 if ( bActive ) mel.setConflict(); // All src entries deleted => conflict
joachim99@8 794 else mel.setRemoved(selector); // No lines in corresponding src found.
joachim99@8 795
joachim99@8 796 ml.mergeEditLineList.push_back(mel);
joachim99@8 797 }
joachim99@58 798
joachim99@58 799 if ( m_cursorYPos >= m_totalSize )
joachim99@58 800 {
joachim99@58 801 m_cursorYPos = m_totalSize-1;
joachim99@58 802 m_cursorXPos = 0;
joachim99@58 803 }
joachim99@8 804
joachim99@8 805 update();
joachim99@8 806 emit updateAvailabilities();
joachim99@8 807 }
joachim99@8 808
joachim99@51 809 // bConflictsOnly: automatically choose for conflicts only (true) or for everywhere (false)
joachim99@51 810 void MergeResultWindow::chooseGlobal(int selector, bool bConflictsOnly, bool bWhiteSpaceOnly )
joachim99@8 811 {
joachim99@8 812 resetSelection();
joachim99@8 813
joachim99@51 814 merge( false, selector, bConflictsOnly, bWhiteSpaceOnly );
joachim99@8 815 emit modified();
joachim99@8 816 update();
joachim99@8 817 }
joachim99@8 818
joachim99@8 819 void MergeResultWindow::slotAutoSolve()
joachim99@8 820 {
joachim99@8 821 resetSelection();
joachim99@8 822 merge( true, -1 );
joachim99@8 823 emit modified();
joachim99@8 824 update();
joachim99@8 825 }
joachim99@8 826
joachim99@8 827 void MergeResultWindow::slotUnsolve()
joachim99@8 828 {
joachim99@8 829 resetSelection();
joachim99@8 830 merge( false, -1 );
joachim99@8 831 emit modified();
joachim99@8 832 update();
joachim99@8 833 }
joachim99@8 834
joachim99@8 835 void MergeResultWindow::myUpdate(int afterMilliSecs)
joachim99@8 836 {
joachim99@8 837 killTimers();
joachim99@8 838 m_bMyUpdate = true;
joachim99@8 839 startTimer( afterMilliSecs );
joachim99@8 840 }
joachim99@8 841
joachim99@8 842 void MergeResultWindow::timerEvent(QTimerEvent*)
joachim99@8 843 {
joachim99@8 844 killTimers();
joachim99@8 845
joachim99@8 846 if ( m_bMyUpdate )
joachim99@8 847 {
joachim99@8 848 update();//paintEvent( 0 );
joachim99@8 849 m_bMyUpdate = false;
joachim99@8 850 }
joachim99@8 851
joachim99@8 852 if ( m_scrollDeltaX != 0 || m_scrollDeltaY != 0 )
joachim99@8 853 {
joachim99@8 854 m_selection.end( m_selection.lastLine + m_scrollDeltaY, m_selection.lastPos + m_scrollDeltaX );
joachim99@8 855 emit scroll( m_scrollDeltaX, m_scrollDeltaY );
joachim99@8 856 killTimers();
joachim99@8 857 startTimer(50);
joachim99@8 858 }
joachim99@8 859 }
joachim99@8 860
joachim99@8 861 const char* MergeResultWindow::MergeEditLine::getString( const MergeResultWindow* mrw, int& size )
joachim99@8 862 {
joachim99@8 863 size=-1;
joachim99@8 864 if ( isRemoved() ) { size=0; return ""; }
joachim99@8 865
joachim99@8 866 if ( ! isModified() )
joachim99@8 867 {
joachim99@8 868 int src = m_src;
joachim99@8 869 const Diff3Line& d3l = *m_id3l;
joachim99@8 870 if ( src == 0 ) { size=0; return ""; }
joachim99@8 871
joachim99@8 872 const LineData* pld = 0;
joachim99@8 873 assert( src == A || src == B || src == C );
joachim99@8 874 if ( src == A && d3l.lineA!=-1 ) pld = &mrw->m_pldA[ d3l.lineA ];
joachim99@8 875 else if ( src == B && d3l.lineB!=-1 ) pld = &mrw->m_pldB[ d3l.lineB ];
joachim99@8 876 else if ( src == C && d3l.lineC!=-1 ) pld = &mrw->m_pldC[ d3l.lineC ];
joachim99@8 877
joachim99@8 878 if ( pld == 0 )
joachim99@8 879 {
joachim99@8 880 // assert(false); This is no error.
joachim99@8 881 size = 0;
joachim99@8 882 return "";
joachim99@8 883 }
joachim99@8 884
joachim99@8 885 size = pld->size;
joachim99@8 886 return pld->pLine;
joachim99@8 887 }
joachim99@8 888 else
joachim99@8 889 {
joachim99@8 890 size = m_str.length();
joachim99@8 891 return m_str;
joachim99@8 892 }
joachim99@8 893 return 0;
joachim99@8 894 }
joachim99@8 895
joachim99@8 896 /// Converts the cursor-posOnScreen into a text index, considering tabulators.
joachim99@8 897 int convertToPosInText( const char* p, int size, int posOnScreen )
joachim99@8 898 {
joachim99@8 899 int localPosOnScreen = 0;
joachim99@8 900 for ( int i=0; i<size; ++i )
joachim99@8 901 {
joachim99@8 902 if ( localPosOnScreen>=posOnScreen )
joachim99@8 903 return i;
joachim99@8 904
joachim99@8 905 // All letters except tabulator have width one.
joachim99@8 906 int letterWidth = p[i]!='\t' ? 1 : tabber( localPosOnScreen, g_tabSize );
joachim99@8 907
joachim99@8 908 localPosOnScreen += letterWidth;
joachim99@8 909
joachim99@8 910 if ( localPosOnScreen>posOnScreen )
joachim99@8 911 return i;
joachim99@8 912 }
joachim99@8 913 return size;
joachim99@8 914 }
joachim99@8 915
joachim99@8 916
joachim99@8 917 /// Converts the index into the text to a cursor-posOnScreen considering tabulators.
joachim99@8 918 int convertToPosOnScreen( const char* p, int posInText )
joachim99@8 919 {
joachim99@8 920 int posOnScreen = 0;
joachim99@8 921 for ( int i=0; i<posInText; ++i )
joachim99@8 922 {
joachim99@8 923 // All letters except tabulator have width one.
joachim99@8 924 int letterWidth = p[i]!='\t' ? 1 : tabber( posOnScreen, g_tabSize );
joachim99@8 925
joachim99@8 926 posOnScreen += letterWidth;
joachim99@8 927 }
joachim99@8 928 return posOnScreen;
joachim99@8 929 }
joachim99@8 930
joachim99@8 931 void MergeResultWindow::writeLine(
joachim99@8 932 QPainter& p, int line, const char* pStr, int size,
joachim99@8 933 int srcSelect, e_MergeDetails mergeDetails, int rangeMark, bool bUserModified, bool bLineRemoved
joachim99@8 934 )
joachim99@8 935 {
joachim99@8 936 const QFontMetrics& fm = fontMetrics();
joachim99@8 937 int fontHeight = fm.height();
joachim99@8 938 int fontWidth = fm.width("W");
joachim99@8 939 int fontAscent = fm.ascent();
joachim99@8 940
joachim99@8 941 int topLineYOffset = fontHeight + 3;
joachim99@8 942 int xOffset = fontWidth * leftInfoWidth;
joachim99@8 943
joachim99@8 944 int yOffset = ( line-m_firstLine ) * fontHeight;
joachim99@8 945 if ( yOffset < 0 || yOffset > height() )
joachim99@8 946 return;
joachim99@8 947
joachim99@8 948 yOffset += topLineYOffset;
joachim99@8 949
joachim99@8 950 QString srcName = " ";
joachim99@8 951 if ( bUserModified ) srcName = "m";
joachim99@8 952 else if ( srcSelect == A && mergeDetails != eNoChange ) srcName = "A";
joachim99@8 953 else if ( srcSelect == B ) srcName = "B";
joachim99@8 954 else if ( srcSelect == C ) srcName = "C";
joachim99@8 955
joachim99@8 956 if ( rangeMark & 4 )
joachim99@8 957 {
joachim99@8 958 p.fillRect( xOffset, yOffset, width(), fontHeight, m_pOptionDialog->m_currentRangeBgColor );
joachim99@8 959 }
joachim99@8 960
joachim99@8 961 if( (srcSelect > 0 || bUserModified ) && !bLineRemoved )
joachim99@8 962 {
joachim99@8 963 int outPos = 0;
joachim99@8 964 QCString s;
joachim99@8 965 for ( int i=0; i<size; ++i )
joachim99@8 966 {
joachim99@8 967 int spaces = 1;
joachim99@8 968 if ( pStr[i]=='\t' )
joachim99@8 969 {
joachim99@8 970 spaces = tabber( outPos, g_tabSize );
joachim99@8 971 for( int j=0; j<spaces; ++j )
joachim99@8 972 s+=' ';
joachim99@8 973 }
joachim99@8 974 else
joachim99@8 975 {
joachim99@8 976 s+=pStr[i];
joachim99@8 977 }
joachim99@8 978 outPos += spaces;
joachim99@8 979 }
joachim99@8 980
joachim99@8 981 if ( m_selection.lineWithin( line ) )
joachim99@8 982 {
joachim99@8 983 int firstPosInLine = convertToPosOnScreen( pStr, convertToPosInText( pStr, size, m_selection.firstPosInLine(line) ) );
joachim99@8 984 int lastPosInLine = convertToPosOnScreen( pStr, convertToPosInText( pStr, size, m_selection.lastPosInLine(line) ) );
joachim99@8 985 int lengthInLine = max2(0,lastPosInLine - firstPosInLine);
joachim99@8 986 if (lengthInLine>0) m_selection.bSelectionContainsData = true;
joachim99@8 987
joachim99@8 988 if ( lengthInLine < int(s.length()) )
joachim99@8 989 { // Draw a normal line first
joachim99@8 990 p.setPen( m_pOptionDialog->m_fgColor );
joachim99@51 991 p.drawText( xOffset, yOffset+fontAscent, decodeString( s.mid(m_firstColumn),m_pOptionDialog) );
joachim99@8 992 }
joachim99@8 993 int firstPosInLine2 = max2( firstPosInLine, m_firstColumn );
joachim99@8 994 int lengthInLine2 = max2(0,lastPosInLine - firstPosInLine2);
joachim99@8 995
joachim99@8 996 if( m_selection.lineWithin( line+1 ) )
joachim99@8 997 p.fillRect( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset,
joachim99@8 998 width(), fontHeight, colorGroup().highlight() );
joachim99@8 999 else
joachim99@8 1000 p.fillRect( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset,
joachim99@8 1001 fontWidth*lengthInLine2, fontHeight, colorGroup().highlight() );
joachim99@8 1002
joachim99@8 1003 p.setPen( colorGroup().highlightedText() );
joachim99@8 1004 p.drawText( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset+fontAscent,
joachim99@51 1005 decodeString( s.mid(firstPosInLine2,lengthInLine2), m_pOptionDialog ) );
joachim99@8 1006 }
joachim99@8 1007 else
joachim99@8 1008 {
joachim99@8 1009 p.setPen( m_pOptionDialog->m_fgColor );
joachim99@51 1010 p.drawText( xOffset, yOffset+fontAscent, decodeString( s.mid(m_firstColumn), m_pOptionDialog ) );
joachim99@8 1011 }
joachim99@8 1012
joachim99@8 1013 p.setPen( m_pOptionDialog->m_fgColor );
joachim99@8 1014 if ( m_cursorYPos==line )
joachim99@8 1015 {
joachim99@8 1016 m_cursorXPos = minMaxLimiter( m_cursorXPos, 0, outPos );
joachim99@8 1017 m_cursorXPos = convertToPosOnScreen( pStr, convertToPosInText( pStr, size, m_cursorXPos ) );
joachim99@8 1018 }
joachim99@8 1019
joachim99@8 1020 p.drawText( 1, yOffset+fontAscent, srcName );
joachim99@8 1021 }
joachim99@8 1022 else if ( bLineRemoved )
joachim99@8 1023 {
joachim99@8 1024 p.setPen( m_pOptionDialog->m_colorForConflict );
joachim99@8 1025 p.drawText( xOffset, yOffset+fontAscent, i18n("<No src line>") );
joachim99@8 1026 p.drawText( 1, yOffset+fontAscent, srcName );
joachim99@8 1027 if ( m_cursorYPos==line ) m_cursorXPos = 0;
joachim99@8 1028 }
joachim99@8 1029 else if ( srcSelect == 0 )
joachim99@8 1030 {
joachim99@8 1031 p.setPen( m_pOptionDialog->m_colorForConflict );
joachim99@8 1032 p.drawText( xOffset, yOffset+fontAscent, i18n("<Merge Conflict>") );
joachim99@8 1033 p.drawText( 1, yOffset+fontAscent, "?" );
joachim99@8 1034 if ( m_cursorYPos==line ) m_cursorXPos = 0;
joachim99@8 1035 }
joachim99@8 1036 else assert(false);
joachim99@8 1037
joachim99@8 1038 xOffset -= fontWidth;
joachim99@8 1039 p.setPen( m_pOptionDialog->m_fgColor );
joachim99@8 1040 if ( rangeMark & 1 ) // begin mark
joachim99@8 1041 {
joachim99@8 1042 p.drawLine( xOffset, yOffset+1, xOffset, yOffset+fontHeight/2 );
joachim99@8 1043 p.drawLine( xOffset, yOffset+1, xOffset-2, yOffset+1 );
joachim99@8 1044 }
joachim99@8 1045 else
joachim99@8 1046 {
joachim99@8 1047 p.drawLine( xOffset, yOffset, xOffset, yOffset+fontHeight/2 );
joachim99@8 1048 }
joachim99@8 1049
joachim99@8 1050 if ( rangeMark & 2 ) // end mark
joachim99@8 1051 {
joachim99@8 1052 p.drawLine( xOffset, yOffset+fontHeight/2, xOffset, yOffset+fontHeight-1 );
joachim99@8 1053 p.drawLine( xOffset, yOffset+fontHeight-1, xOffset-2, yOffset+fontHeight-1 );
joachim99@8 1054 }
joachim99@8 1055 else
joachim99@8 1056 {
joachim99@8 1057 p.drawLine( xOffset, yOffset+fontHeight/2, xOffset, yOffset+fontHeight );
joachim99@8 1058 }
joachim99@8 1059
joachim99@8 1060 if ( rangeMark & 4 )
joachim99@8 1061 {
joachim99@8 1062 p.fillRect( xOffset + 3, yOffset, 3, fontHeight, m_pOptionDialog->m_fgColor );
joachim99@8 1063 /* p.setPen( blue );
joachim99@8 1064 p.drawLine( xOffset+2, yOffset, xOffset+2, yOffset+fontHeight-1 );
joachim99@8 1065 p.drawLine( xOffset+3, yOffset, xOffset+3, yOffset+fontHeight-1 );*/
joachim99@8 1066 }
joachim99@8 1067 }
joachim99@8 1068
joachim99@58 1069 void MergeResultWindow::setPaintingAllowed(bool bPaintingAllowed)
joachim99@58 1070 {
joachim99@58 1071 m_bPaintingAllowed = bPaintingAllowed;
joachim99@58 1072 }
joachim99@58 1073
joachim99@8 1074 void MergeResultWindow::paintEvent( QPaintEvent* e )
joachim99@8 1075 {
joachim99@58 1076 if (m_pDiff3LineList==0 || !m_bPaintingAllowed) return;
joachim99@8 1077
joachim99@8 1078 bool bOldSelectionContainsData = m_selection.bSelectionContainsData;
joachim99@8 1079 const QFontMetrics& fm = fontMetrics();
joachim99@8 1080 int fontHeight = fm.height();
joachim99@8 1081 int fontWidth = fm.width("W");
joachim99@8 1082 int fontAscent = fm.ascent();
joachim99@8 1083
joachim99@8 1084 if ( e!= 0 ) // e==0 for blinking cursor
joachim99@8 1085 {
joachim99@8 1086 m_selection.bSelectionContainsData = false;
joachim99@8 1087 if ( size() != m_pixmap.size() )
joachim99@8 1088 m_pixmap.resize(size());
joachim99@8 1089
joachim99@8 1090 QPainter p(&m_pixmap);
joachim99@8 1091 p.setFont( font() );
joachim99@8 1092 p.fillRect( rect(), m_pOptionDialog->m_bgColor );
joachim99@8 1093
joachim99@8 1094 //int visibleLines = height() / fontHeight;
joachim99@8 1095
joachim99@8 1096 { // Draw the topline
joachim99@58 1097 QString s = " " +i18n("Output") + " : " + m_fileName + " ";
joachim99@8 1098 if (m_bModified)
joachim99@8 1099 s += i18n("[Modified]");
joachim99@8 1100
joachim99@8 1101 int topLineYOffset = fontHeight + 3;
joachim99@8 1102
joachim99@8 1103 if (hasFocus())
joachim99@8 1104 {
joachim99@8 1105 p.fillRect( 0, 0, width(), topLineYOffset, lightGray /*m_pOptionDialog->m_diffBgColor*/ );
joachim99@8 1106 }
joachim99@8 1107 else
joachim99@8 1108 {
joachim99@8 1109 p.fillRect( 0, 0, width(), topLineYOffset, m_pOptionDialog->m_bgColor );
joachim99@8 1110 }
joachim99@8 1111 p.setPen( m_pOptionDialog->m_fgColor );
joachim99@8 1112 p.drawText( 0, fontAscent+1, s );
joachim99@8 1113 p.drawLine( 0, fontHeight + 2, width(), fontHeight + 2 );
joachim99@8 1114 }
joachim99@8 1115
joachim99@8 1116 int lastVisibleLine = m_firstLine + getNofVisibleLines() + 5;
joachim99@8 1117 int nofColumns = 0;
joachim99@8 1118 int line = 0;
joachim99@8 1119 MergeLineList::iterator mlIt = m_mergeLineList.begin();
joachim99@8 1120 for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt)
joachim99@8 1121 {
joachim99@8 1122 MergeLine& ml = *mlIt;
joachim99@8 1123 if ( line > lastVisibleLine || line + ml.mergeEditLineList.size() < m_firstLine)
joachim99@8 1124 {
joachim99@8 1125 line += ml.mergeEditLineList.size();
joachim99@8 1126 }
joachim99@8 1127 else
joachim99@8 1128 {
joachim99@8 1129 MergeEditLineList::iterator melIt;
joachim99@8 1130 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt )
joachim99@8 1131 {
joachim99@8 1132 if (line>=m_firstLine && line<=lastVisibleLine)
joachim99@8 1133 {
joachim99@8 1134 MergeEditLine& mel = *melIt;
joachim99@8 1135 MergeEditLineList::iterator melIt1 = melIt;
joachim99@8 1136 ++melIt1;
joachim99@8 1137
joachim99@8 1138 int rangeMark = 0;
joachim99@8 1139 if ( melIt==ml.mergeEditLineList.begin() ) rangeMark |= 1; // Begin range mark
joachim99@8 1140 if ( melIt1==ml.mergeEditLineList.end() ) rangeMark |= 2; // End range mark
joachim99@8 1141
joachim99@8 1142 if ( mlIt == m_currentMergeLineIt ) rangeMark |= 4; // Mark of the current line
joachim99@8 1143
joachim99@8 1144 const char* s;
joachim99@8 1145 int size;
joachim99@8 1146 s = mel.getString( this, size );
joachim99@8 1147 if (size>nofColumns)
joachim99@8 1148 nofColumns = size;
joachim99@8 1149
joachim99@8 1150 writeLine( p, line, s, size, mel.src(), ml.mergeDetails, rangeMark,
joachim99@8 1151 mel.isModified(), mel.isRemoved() );
joachim99@8 1152 }
joachim99@8 1153 ++line;
joachim99@8 1154 }
joachim99@8 1155 }
joachim99@8 1156 }
joachim99@8 1157
joachim99@8 1158 if ( line != m_nofLines || nofColumns != m_nofColumns )
joachim99@8 1159 {
joachim99@8 1160 m_nofLines = line;
joachim99@58 1161 assert( m_nofLines == m_totalSize );
joachim99@8 1162
joachim99@8 1163 m_nofColumns = nofColumns;
joachim99@8 1164 emit resizeSignal();
joachim99@8 1165 }
joachim99@8 1166
joachim99@8 1167 if( m_currentMergeLineIt == m_mergeLineList.end() )
joachim99@8 1168 emit sourceMask( 0, 0 );
joachim99@8 1169 else
joachim99@8 1170 {
joachim99@8 1171 int enabledMask = m_pldC==0 ? 3 : 7;
joachim99@8 1172 MergeLine& ml = *m_currentMergeLineIt;
joachim99@8 1173
joachim99@8 1174 int srcMask = 0;
joachim99@8 1175 bool bModified = false;
joachim99@8 1176 MergeEditLineList::iterator melIt;
joachim99@8 1177 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt )
joachim99@8 1178 {
joachim99@8 1179 MergeEditLine& mel = *melIt;
joachim99@8 1180 if ( mel.src()==1 ) srcMask |= 1;
joachim99@8 1181 if ( mel.src()==2 ) srcMask |= 2;
joachim99@8 1182 if ( mel.src()==3 ) srcMask |= 4;
joachim99@8 1183 if ( mel.isModified() || !mel.isEditableText() ) bModified = true;
joachim99@8 1184 }
joachim99@8 1185
joachim99@53 1186 if (hasFocus())
joachim99@53 1187 {
joachim99@53 1188 if ( ml.mergeDetails == eNoChange ) emit sourceMask( 0, bModified ? 1 : 0 );
joachim99@53 1189 else emit sourceMask( srcMask, enabledMask );
joachim99@53 1190 }
joachim99@8 1191 }
joachim99@8 1192 p.end();
joachim99@8 1193 }
joachim99@8 1194
joachim99@8 1195 QPainter painter(this);
joachim99@8 1196 if ( e!= 0 )
joachim99@8 1197 {
joachim99@8 1198 painter.drawPixmap(0,0, m_pixmap);
joachim99@8 1199 }
joachim99@8 1200
joachim99@8 1201 int topLineYOffset = fontHeight + 3;
joachim99@8 1202 int xOffset = fontWidth * leftInfoWidth;
joachim99@8 1203 int yOffset = ( m_cursorYPos - m_firstLine ) * fontHeight + topLineYOffset;
joachim99@8 1204 int xCursor = ( m_cursorXPos - m_firstColumn ) * fontWidth + xOffset;
joachim99@8 1205
joachim99@8 1206 if ( e!= 0 )
joachim99@8 1207 painter.drawPixmap(0,0, m_pixmap);
joachim99@8 1208 else
joachim99@8 1209 painter.drawPixmap(xCursor-2, yOffset, m_pixmap,
joachim99@8 1210 xCursor-2, yOffset, 5, fontAscent+2 );
joachim99@8 1211
joachim99@8 1212
joachim99@8 1213 if ( m_bCursorOn && hasFocus() && m_cursorYPos>=m_firstLine )
joachim99@8 1214 {
joachim99@8 1215 int topLineYOffset = fontHeight + 3;
joachim99@8 1216 int xOffset = fontWidth * leftInfoWidth;
joachim99@8 1217
joachim99@8 1218 int yOffset = ( m_cursorYPos-m_firstLine ) * fontHeight + topLineYOffset;
joachim99@8 1219
joachim99@8 1220 int xCursor = ( m_cursorXPos - m_firstColumn ) * fontWidth + xOffset;
joachim99@8 1221 painter.drawLine( xCursor, yOffset, xCursor, yOffset+fontAscent );
joachim99@8 1222 painter.drawLine( xCursor-2, yOffset, xCursor+2, yOffset );
joachim99@8 1223 painter.drawLine( xCursor-2, yOffset+fontAscent+1, xCursor+2, yOffset+fontAscent+1 );
joachim99@8 1224 }
joachim99@8 1225
joachim99@8 1226 if( !bOldSelectionContainsData && m_selection.bSelectionContainsData )
joachim99@8 1227 emit newSelection();
joachim99@8 1228 }
joachim99@8 1229
joachim99@8 1230 void MergeResultWindow::convertToLinePos( int x, int y, int& line, int& pos )
joachim99@8 1231 {
joachim99@8 1232 const QFontMetrics& fm = fontMetrics();
joachim99@8 1233 int fontHeight = fm.height();
joachim99@8 1234 int fontWidth = fm.width('W');
joachim99@8 1235 int xOffset = (leftInfoWidth-m_firstColumn)*fontWidth;
joachim99@8 1236 int topLineYOffset = fontHeight + 3;
joachim99@8 1237
joachim99@8 1238 int yOffset = topLineYOffset - m_firstLine * fontHeight;
joachim99@8 1239
joachim99@58 1240 line = min2( ( y - yOffset ) / fontHeight, m_totalSize-1 );
joachim99@8 1241 pos = ( x - xOffset ) / fontWidth;
joachim99@8 1242 }
joachim99@8 1243
joachim99@8 1244 void MergeResultWindow::mousePressEvent ( QMouseEvent* e )
joachim99@8 1245 {
joachim99@8 1246 m_bCursorOn = true;
joachim99@8 1247
joachim99@8 1248 int line;
joachim99@8 1249 int pos;
joachim99@8 1250 convertToLinePos( e->x(), e->y(), line, pos );
joachim99@8 1251
joachim99@8 1252 bool bLMB = e->button() == LeftButton;
joachim99@8 1253 bool bMMB = e->button() == MidButton;
joachim99@8 1254 bool bRMB = e->button() == RightButton;
joachim99@8 1255
joachim99@8 1256 if ( bLMB && pos < m_firstColumn || bRMB ) // Fast range selection
joachim99@8 1257 {
joachim99@8 1258 m_cursorXPos = 0;
joachim99@8 1259 m_cursorOldXPos = 0;
joachim99@8 1260 m_cursorYPos = max2(line,0);
joachim99@8 1261 int l = 0;
joachim99@8 1262 MergeLineList::iterator i = m_mergeLineList.begin();
joachim99@8 1263 for(i = m_mergeLineList.begin();i!=m_mergeLineList.end(); ++i)
joachim99@8 1264 {
joachim99@8 1265 if (l==line)
joachim99@8 1266 break;
joachim99@8 1267
joachim99@8 1268 l += i->mergeEditLineList.size();
joachim99@8 1269 if (l>line)
joachim99@8 1270 break;
joachim99@8 1271 }
joachim99@8 1272 m_selection.reset(); // Disable current selection
joachim99@8 1273
joachim99@8 1274 m_bCursorOn = true;
joachim99@8 1275 setFastSelector( i );
joachim99@8 1276
joachim99@8 1277 if (bRMB)
joachim99@8 1278 {
joachim99@8 1279 showPopupMenu( QCursor::pos() );
joachim99@8 1280 }
joachim99@8 1281 }
joachim99@8 1282 else if ( bLMB ) // Normal cursor placement
joachim99@8 1283 {
joachim99@8 1284 pos = max2(pos,0);
joachim99@8 1285 line = max2(line,0);
joachim99@8 1286 if ( e->state() & ShiftButton )
joachim99@8 1287 {
joachim99@8 1288 if (m_selection.firstLine==-1)
joachim99@8 1289 m_selection.start( line, pos );
joachim99@8 1290 m_selection.end( line, pos );
joachim99@8 1291 }
joachim99@8 1292 else
joachim99@8 1293 {
joachim99@8 1294 // Selection
joachim99@8 1295 m_selection.reset();
joachim99@8 1296 m_selection.start( line, pos );
joachim99@8 1297 m_selection.end( line, pos );
joachim99@8 1298 }
joachim99@8 1299 m_cursorXPos = pos;
joachim99@8 1300 m_cursorOldXPos = pos;
joachim99@8 1301 m_cursorYPos = line;
joachim99@8 1302
joachim99@8 1303 update();
joachim99@8 1304 //showStatusLine( line, m_winIdx, m_pFilename, m_pDiff3LineList, m_pStatusBar );
joachim99@8 1305 }
joachim99@8 1306 else if ( bMMB ) // Paste clipboard
joachim99@8 1307 {
joachim99@8 1308 pos = max2(pos,0);
joachim99@8 1309 line = max2(line,0);
joachim99@8 1310
joachim99@8 1311 m_selection.reset();
joachim99@8 1312 m_cursorXPos = pos;
joachim99@8 1313 m_cursorOldXPos = pos;
joachim99@8 1314 m_cursorYPos = line;
joachim99@8 1315
joachim99@8 1316 pasteClipboard();
joachim99@8 1317 }
joachim99@8 1318 }
joachim99@8 1319
joachim99@8 1320 void MergeResultWindow::mouseDoubleClickEvent( QMouseEvent* e )
joachim99@8 1321 {
joachim99@8 1322 if ( e->button() == LeftButton )
joachim99@8 1323 {
joachim99@8 1324 int line;
joachim99@8 1325 int pos;
joachim99@8 1326 convertToLinePos( e->x(), e->y(), line, pos );
joachim99@8 1327 m_cursorXPos = pos;
joachim99@8 1328 m_cursorOldXPos = pos;
joachim99@8 1329 m_cursorYPos = line;
joachim99@8 1330
joachim99@8 1331 // Get the string data of the current line
joachim99@8 1332
joachim99@8 1333 int size;
joachim99@8 1334 MergeLineList::iterator mlIt;
joachim99@8 1335 MergeEditLineList::iterator melIt;
joachim99@8 1336 calcIteratorFromLineNr( line, mlIt, melIt );
joachim99@8 1337 const char* s = melIt->getString( this, size );
joachim99@8 1338
joachim99@8 1339 if ( s!=0 && size>0 )
joachim99@8 1340 {
joachim99@8 1341 int pos1, pos2;
joachim99@8 1342
joachim99@8 1343 calcTokenPos( s, size, pos, pos1, pos2 );
joachim99@8 1344
joachim99@8 1345 resetSelection();
joachim99@8 1346 m_selection.start( line, convertToPosOnScreen( s, pos1 ) );
joachim99@8 1347 m_selection.end( line, convertToPosOnScreen( s, pos2 ) );
joachim99@8 1348
joachim99@8 1349 update();
joachim99@8 1350 // emit selectionEnd() happens in the mouseReleaseEvent.
joachim99@8 1351 }
joachim99@8 1352 }
joachim99@8 1353 }
joachim99@8 1354
joachim99@8 1355 void MergeResultWindow::mouseReleaseEvent ( QMouseEvent * e )
joachim99@8 1356 {
joachim99@8 1357 if ( e->button() == LeftButton )
joachim99@8 1358 {
joachim99@8 1359 killTimers();
joachim99@8 1360
joachim99@8 1361 if (m_selection.firstLine != -1 )
joachim99@8 1362 {
joachim99@8 1363 emit selectionEnd();
joachim99@8 1364 }
joachim99@8 1365 }
joachim99@8 1366 }
joachim99@8 1367
joachim99@8 1368 void MergeResultWindow::mouseMoveEvent ( QMouseEvent * e )
joachim99@8 1369 {
joachim99@8 1370 int line;
joachim99@8 1371 int pos;
joachim99@8 1372 convertToLinePos( e->x(), e->y(), line, pos );
joachim99@8 1373 m_cursorXPos = pos;
joachim99@8 1374 m_cursorOldXPos = pos;
joachim99@8 1375 m_cursorYPos = line;
joachim99@8 1376 if (m_selection.firstLine != -1 )
joachim99@8 1377 {
joachim99@8 1378 m_selection.end( line, pos );
joachim99@8 1379 myUpdate(0);
joachim99@8 1380
joachim99@8 1381 //showStatusLine( line, m_winIdx, m_pFilename, m_pDiff3LineList, m_pStatusBar );
joachim99@8 1382
joachim99@8 1383 // Scroll because mouse moved out of the window
joachim99@8 1384 const QFontMetrics& fm = fontMetrics();
joachim99@8 1385 int fontHeight = fm.height();
joachim99@8 1386 int fontWidth = fm.width('W');
joachim99@8 1387 int topLineYOffset = fontHeight + 3;
joachim99@8 1388 int deltaX=0;
joachim99@8 1389 int deltaY=0;
joachim99@8 1390 if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1;
joachim99@8 1391 if ( e->x() > width() ) deltaX=+1;
joachim99@8 1392 if ( e->y() < topLineYOffset ) deltaY=-1;
joachim99@8 1393 if ( e->y() > height() ) deltaY=+1;
joachim99@8 1394 m_scrollDeltaX = deltaX;
joachim99@8 1395 m_scrollDeltaY = deltaY;
joachim99@8 1396 if ( deltaX != 0 || deltaY!= 0)
joachim99@8 1397 {
joachim99@8 1398 emit scroll( deltaX, deltaY );
joachim99@8 1399 }
joachim99@8 1400 }
joachim99@8 1401 }
joachim99@8 1402
joachim99@8 1403
joachim99@8 1404 void MergeResultWindow::slotCursorUpdate()
joachim99@8 1405 {
joachim99@8 1406 m_cursorTimer.stop();
joachim99@8 1407 m_bCursorOn = !m_bCursorOn;
joachim99@8 1408
joachim99@8 1409 if ( isVisible() )
joachim99@8 1410 paintEvent(0);
joachim99@8 1411
joachim99@8 1412 m_cursorTimer.start(500,true);
joachim99@8 1413 }
joachim99@8 1414
joachim99@8 1415
joachim99@8 1416 void MergeResultWindow::wheelEvent( QWheelEvent* e )
joachim99@8 1417 {
joachim99@8 1418 int d = -e->delta()*QApplication::wheelScrollLines()/120;
joachim99@8 1419 e->accept();
joachim99@8 1420 scroll( 0, min2(d, getNofVisibleLines()) );
joachim99@8 1421 }
joachim99@8 1422
joachim99@51 1423
joachim99@8 1424 void MergeResultWindow::keyPressEvent( QKeyEvent* e )
joachim99@8 1425 {
joachim99@8 1426 int y = m_cursorYPos;
joachim99@8 1427 MergeLineList::iterator mlIt;
joachim99@8 1428 MergeEditLineList::iterator melIt;
joachim99@8 1429 calcIteratorFromLineNr( y, mlIt, melIt );
joachim99@8 1430
joachim99@8 1431 int stringLength;
joachim99@8 1432 const char* ps = melIt->getString( this, stringLength );
joachim99@8 1433 int x = convertToPosInText( ps, stringLength, m_cursorXPos );
joachim99@8 1434
joachim99@8 1435 bool bCtrl = ( e->state() & ControlButton ) != 0 ;
joachim99@8 1436 bool bShift = ( e->state() & ShiftButton ) != 0 ;
joachim99@8 1437 #ifdef _WIN32
joachim99@8 1438 bool bAlt = ( e->state() & AltButton ) != 0 ;
joachim99@8 1439 if ( bCtrl && bAlt ){ bCtrl=false; bAlt=false; } // AltGr-Key pressed.
joachim99@8 1440 #endif
joachim99@8 1441
joachim99@8 1442 bool bYMoveKey = false;
joachim99@8 1443 // Special keys
joachim99@8 1444 switch ( e->key() )
joachim99@8 1445 {
joachim99@8 1446 case Key_Escape: break;
joachim99@8 1447 //case Key_Tab: break;
joachim99@8 1448 case Key_Backtab: break;
joachim99@8 1449 case Key_Delete:
joachim99@8 1450 {
joachim99@8 1451 if ( deleteSelection2( ps, stringLength, x, y, mlIt, melIt )) break;
joachim99@8 1452 if( !melIt->isEditableText() ) break;
joachim99@8 1453 if (x>=stringLength)
joachim99@8 1454 {
joachim99@58 1455 if ( y<m_totalSize-1 )
joachim99@8 1456 {
joachim99@8 1457 setModified();
joachim99@8 1458 QCString s1( ps, stringLength+1 );
joachim99@8 1459 MergeLineList::iterator mlIt1;
joachim99@8 1460 MergeEditLineList::iterator melIt1;
joachim99@8 1461 calcIteratorFromLineNr( y+1, mlIt1, melIt1 );
joachim99@8 1462 if ( melIt1->isEditableText() )
joachim99@8 1463 {
joachim99@8 1464 int stringLength1;
joachim99@8 1465 ps = melIt1->getString( this, stringLength1 );
joachim99@8 1466 assert(ps!=0);
joachim99@8 1467 QCString s2( ps, stringLength1+1 );
joachim99@8 1468 melIt->setString( s1 + s2 );
joachim99@8 1469
joachim99@8 1470 // Remove the line
joachim99@8 1471 if ( mlIt1->mergeEditLineList.size()>1 )
joachim99@8 1472 mlIt1->mergeEditLineList.erase( melIt1 );
joachim99@8 1473 else
joachim99@8 1474 melIt1->setRemoved();
joachim99@8 1475 }
joachim99@8 1476 }
joachim99@8 1477 }
joachim99@8 1478 else
joachim99@8 1479 {
joachim99@8 1480 QCString s( ps, x+1 );
joachim99@8 1481 s += QCString( ps+x+1, stringLength - x );
joachim99@8 1482 melIt->setString( s );
joachim99@8 1483 setModified();
joachim99@8 1484 }
joachim99@8 1485 break;
joachim99@8 1486 }
joachim99@8 1487 case Key_Backspace:
joachim99@8 1488 {
joachim99@8 1489 if ( deleteSelection2( ps, stringLength, x, y, mlIt, melIt )) break;
joachim99@8 1490 if( !melIt->isEditableText() ) break;
joachim99@8 1491 if (x==0)
joachim99@8 1492 {
joachim99@8 1493 if ( y>0 )
joachim99@8 1494 {
joachim99@8 1495 setModified();
joachim99@8 1496 QCString s2( ps, stringLength+1 );
joachim99@8 1497 MergeLineList::iterator mlIt1;
joachim99@8 1498 MergeEditLineList::iterator melIt1;
joachim99@8 1499 calcIteratorFromLineNr( y-1, mlIt1, melIt1 );
joachim99@8 1500 if ( melIt1->isEditableText() )
joachim99@8 1501 {
joachim99@8 1502 int stringLength1;
joachim99@8 1503 ps = melIt1->getString( this, stringLength1 );
joachim99@8 1504 QCString s1( ps, stringLength1+1 );
joachim99@8 1505 melIt1->setString( s1 + s2 );
joachim99@8 1506
joachim99@8 1507 // Remove the previous line
joachim99@8 1508 if ( mlIt->mergeEditLineList.size()>1 )
joachim99@8 1509 mlIt->mergeEditLineList.erase( melIt );
joachim99@8 1510 else
joachim99@8 1511 melIt->setRemoved();
joachim99@8 1512
joachim99@8 1513 --y;
joachim99@8 1514 x=stringLength1;
joachim99@8 1515 }
joachim99@8 1516 }
joachim99@8 1517 }
joachim99@8 1518 else
joachim99@8 1519 {
joachim99@8 1520 QCString s( ps, x );
joachim99@8 1521 s += QCString( ps+x, stringLength - x + 1 );
joachim99@8 1522 --x;
joachim99@8 1523 melIt->setString( s );
joachim99@8 1524 setModified();
joachim99@8 1525 }
joachim99@8 1526 break;
joachim99@8 1527 }
joachim99@8 1528 case Key_Return:
joachim99@8 1529 case Key_Enter:
joachim99@8 1530 {
joachim99@8 1531 if( !melIt->isEditableText() ) break;
joachim99@8 1532 deleteSelection2( ps, stringLength, x, y, mlIt, melIt );
joachim99@8 1533 setModified();
joachim99@8 1534 QCString indentation;
joachim99@8 1535 if ( m_pOptionDialog->m_bAutoIndentation )
joachim99@8 1536 { // calc last indentation
joachim99@8 1537 MergeLineList::iterator mlIt1 = mlIt;
joachim99@8 1538 MergeEditLineList::iterator melIt1 = melIt;
joachim99@8 1539 for(;;) {
joachim99@8 1540 int size;
joachim99@8 1541 const char* s = melIt1->getString(this, size);
joachim99@8 1542 if ( s!=0 ) {
joachim99@8 1543 int i;
joachim99@8 1544 for( i=0; i<size; ++i ){ if(s[i]!=' ' && s[i]!='\t') break; }
joachim99@8 1545 if (i<size) {
joachim99@8 1546 indentation = QCString( s, i+1 );
joachim99@8 1547 break;
joachim99@8 1548 }
joachim99@8 1549 }
joachim99@8 1550 --melIt1;
joachim99@8 1551 if ( melIt1 == mlIt1->mergeEditLineList.end() ) {
joachim99@8 1552 --mlIt1;
joachim99@8 1553 if ( mlIt1 == m_mergeLineList.end() ) break;
joachim99@8 1554 melIt1 = mlIt1->mergeEditLineList.end();
joachim99@8 1555 --melIt1;
joachim99@8 1556 }
joachim99@8 1557 }
joachim99@8 1558 }
joachim99@8 1559 MergeEditLine mel;
joachim99@8 1560 mel.setString( indentation + QCString( ps+x, stringLength - x + 1 ) );
joachim99@8 1561
joachim99@8 1562 if ( x<stringLength ) // Cut off the old line.
joachim99@8 1563 {
joachim99@8 1564 // Since ps possibly points into melIt->str, first copy it into a temporary.
joachim99@8 1565 QCString temp = QCString( ps, x + 1 );
joachim99@8 1566 melIt->setString( temp );
joachim99@8 1567 }
joachim99@8 1568
joachim99@8 1569 ++melIt;
joachim99@8 1570 mlIt->mergeEditLineList.insert( melIt, mel );
joachim99@8 1571 x=indentation.length();
joachim99@8 1572 ++y;
joachim99@8 1573 break;
joachim99@8 1574 }
joachim99@8 1575 case Key_Insert: m_bInsertMode = !m_bInsertMode; break;
joachim99@8 1576 case Key_Pause: break;
joachim99@8 1577 case Key_Print: break;
joachim99@8 1578 case Key_SysReq: break;
joachim99@8 1579 case Key_Home: x=0; if(bCtrl){y=0; } break; // cursor movement
joachim99@8 1580 case Key_End: x=INT_MAX; if(bCtrl){y=INT_MAX;} break;
joachim99@8 1581
joachim99@8 1582 case Key_Left:
joachim99@8 1583 if ( !bCtrl )
joachim99@8 1584 {
joachim99@8 1585 --x;
joachim99@8 1586 if(x<0 && y>0){--y; x=INT_MAX;}
joachim99@8 1587 }
joachim99@8 1588 else
joachim99@8 1589 {
joachim99@8 1590 while( x>0 && (ps[x-1]==' ' || ps[x-1]=='\t') ) --x;
joachim99@8 1591 while( x>0 && (ps[x-1]!=' ' && ps[x-1]!='\t') ) --x;
joachim99@8 1592 }
joachim99@8 1593 break;
joachim99@8 1594
joachim99@8 1595 case Key_Right:
joachim99@8 1596 if ( !bCtrl )
joachim99@8 1597 {
joachim99@58 1598 ++x; if(x>stringLength && y<m_totalSize-1){ ++y; x=0; }
joachim99@8 1599 }
joachim99@8 1600
joachim99@8 1601 else
joachim99@8 1602 {
joachim99@8 1603 while( x<stringLength && (ps[x]==' ' || ps[x]=='\t') ) ++x;
joachim99@8 1604 while( x<stringLength && (ps[x]!=' ' && ps[x]!='\t') ) ++x;
joachim99@8 1605 }
joachim99@8 1606 break;
joachim99@8 1607
joachim99@8 1608 case Key_Up: --y; bYMoveKey=true; break;
joachim99@8 1609 case Key_Down: ++y; bYMoveKey=true; break;
joachim99@8 1610 case Key_PageUp: y-=getNofVisibleLines(); bYMoveKey=true; break;
joachim99@8 1611 case Key_PageDown: y+=getNofVisibleLines(); bYMoveKey=true; break;
joachim99@8 1612 default:
joachim99@8 1613 {
joachim99@8 1614 QString t = e->text();
joachim99@8 1615 if( t.isEmpty() || bCtrl )
joachim99@8 1616 { e->ignore(); return; }
joachim99@8 1617 else
joachim99@8 1618 {
joachim99@8 1619 if( bCtrl )
joachim99@8 1620 {
joachim99@8 1621 e->ignore(); return;
joachim99@8 1622 }
joachim99@8 1623 else
joachim99@8 1624 {
joachim99@8 1625 if( !melIt->isEditableText() ) break;
joachim99@8 1626 deleteSelection2( ps, stringLength, x, y, mlIt, melIt );
joachim99@8 1627
joachim99@8 1628 setModified();
joachim99@8 1629 // Characters to insert
joachim99@8 1630 QCString s( ps, stringLength+1 );
joachim99@8 1631 if ( t[0]=='\t' && m_pOptionDialog->m_bReplaceTabs )
joachim99@8 1632 {
joachim99@8 1633 int spaces = (m_cursorXPos / g_tabSize + 1)*g_tabSize - m_cursorXPos;
joachim99@8 1634 t.fill( ' ', spaces );
joachim99@8 1635 }
joachim99@8 1636 if ( m_bInsertMode )
joachim99@58 1637 s.insert( x, encodeString(t, m_pOptionDialog) );
joachim99@8 1638 else
joachim99@58 1639 s.replace( x, t.length(), encodeString(t, m_pOptionDialog) );
joachim99@8 1640
joachim99@8 1641 melIt->setString( s );
joachim99@8 1642 x += t.length();
joachim99@8 1643 bShift = false;
joachim99@8 1644 }
joachim99@8 1645 }
joachim99@8 1646 }
joachim99@8 1647 }
joachim99@8 1648
joachim99@58 1649 y = minMaxLimiter( y, 0, m_totalSize-1 );
joachim99@8 1650
joachim99@8 1651 calcIteratorFromLineNr( y, mlIt, melIt );
joachim99@8 1652 ps = melIt->getString( this, stringLength );
joachim99@8 1653
joachim99@8 1654 x = minMaxLimiter( x, 0, stringLength );
joachim99@8 1655
joachim99@8 1656 int newFirstLine = m_firstLine;
joachim99@8 1657 int newFirstColumn = m_firstColumn;
joachim99@8 1658
joachim99@8 1659 if ( y<m_firstLine )
joachim99@8 1660 newFirstLine = y;
joachim99@8 1661 else if ( y > m_firstLine + getNofVisibleLines() )
joachim99@8 1662 newFirstLine = y - getNofVisibleLines();
joachim99@8 1663
joachim99@8 1664 if (bYMoveKey)
joachim99@8 1665 x=convertToPosInText( ps, stringLength, m_cursorOldXPos );
joachim99@8 1666
joachim99@8 1667 int xOnScreen = convertToPosOnScreen( ps, x );
joachim99@8 1668 if ( xOnScreen<m_firstColumn )
joachim99@8 1669 newFirstColumn = xOnScreen;
joachim99@8 1670 else if ( xOnScreen > m_firstColumn + getNofVisibleColumns() )
joachim99@8 1671 newFirstColumn = xOnScreen - getNofVisibleColumns();
joachim99@8 1672
joachim99@8 1673 if ( bShift )
joachim99@8 1674 {
joachim99@8 1675 if (m_selection.firstLine==-1)
joachim99@8 1676 m_selection.start( m_cursorYPos, m_cursorXPos );
joachim99@8 1677
joachim99@8 1678 m_selection.end( y, xOnScreen );
joachim99@8 1679 }
joachim99@8 1680 else
joachim99@8 1681 m_selection.reset();
joachim99@8 1682
joachim99@8 1683 m_cursorYPos = y;
joachim99@8 1684 m_cursorXPos = xOnScreen;
joachim99@8 1685 if ( ! bYMoveKey )
joachim99@8 1686 m_cursorOldXPos = m_cursorXPos;
joachim99@8 1687
joachim99@8 1688 m_bCursorOn = false;
joachim99@8 1689
joachim99@8 1690 if ( newFirstLine!=m_firstLine || newFirstColumn!=m_firstColumn )
joachim99@8 1691 {
joachim99@8 1692 m_bCursorOn = true;
joachim99@8 1693 scroll( newFirstColumn-m_firstColumn, newFirstLine-m_firstLine );
joachim99@8 1694 return;
joachim99@8 1695 }
joachim99@8 1696
joachim99@8 1697 m_bCursorOn = true;
joachim99@8 1698 update();
joachim99@8 1699 }
joachim99@8 1700
joachim99@8 1701 void MergeResultWindow::calcIteratorFromLineNr(
joachim99@8 1702 int line,
joachim99@8 1703 MergeResultWindow::MergeLineList::iterator& mlIt,
joachim99@8 1704 MergeResultWindow::MergeEditLineList::iterator& melIt
joachim99@8 1705 )
joachim99@8 1706 {
joachim99@8 1707 for( mlIt = m_mergeLineList.begin(); mlIt!=m_mergeLineList.end(); ++mlIt)
joachim99@8 1708 {
joachim99@8 1709 MergeLine& ml = *mlIt;
joachim99@8 1710 if ( line > ml.mergeEditLineList.size() )
joachim99@8 1711 {
joachim99@8 1712 line -= ml.mergeEditLineList.size();
joachim99@8 1713 }
joachim99@8 1714 else
joachim99@8 1715 {
joachim99@8 1716 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt )
joachim99@8 1717 {
joachim99@8 1718 --line;
joachim99@8 1719 if (line<0) return;
joachim99@8 1720 }
joachim99@8 1721 }
joachim99@8 1722 }
joachim99@8 1723 assert(false);
joachim99@8 1724 }
joachim99@8 1725
joachim99@8 1726
joachim99@8 1727 QString MergeResultWindow::getSelection()
joachim99@8 1728 {
joachim99@8 1729 QString selectionString;
joachim99@8 1730
joachim99@8 1731 int line = 0;
joachim99@8 1732 MergeLineList::iterator mlIt = m_mergeLineList.begin();
joachim99@8 1733 for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt)
joachim99@8 1734 {
joachim99@8 1735 MergeLine& ml = *mlIt;
joachim99@8 1736 MergeEditLineList::iterator melIt;
joachim99@8 1737 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt )
joachim99@8 1738 {
joachim99@8 1739 MergeEditLine& mel = *melIt;
joachim99@8 1740
joachim99@8 1741 if ( m_selection.lineWithin(line) )
joachim99@8 1742 {
joachim99@8 1743 int outPos = 0;
joachim99@8 1744 if (mel.isEditableText())
joachim99@8 1745 {
joachim99@8 1746 int size;
joachim99@8 1747 const char* pLine = mel.getString( this, size );
joachim99@8 1748
joachim99@8 1749 // Consider tabs
joachim99@8 1750
joachim99@8 1751 for( int i=0; i<size; ++i )
joachim99@8 1752 {
joachim99@8 1753 int spaces = 1;
joachim99@8 1754 if ( pLine[i]=='\t' )
joachim99@8 1755 {
joachim99@8 1756 spaces = tabber( outPos, g_tabSize );
joachim99@8 1757 }
joachim99@8 1758
joachim99@8 1759 if( m_selection.within( line, outPos ) )
joachim99@8 1760 {
joachim99@58 1761 char buf[2];
joachim99@58 1762 buf[0] = pLine[i];
joachim99@58 1763 buf[1] = '\0';
joachim99@58 1764 selectionString += decodeString( buf, m_pOptionDialog );
joachim99@8 1765 }
joachim99@8 1766
joachim99@8 1767 outPos += spaces;
joachim99@8 1768 }
joachim99@8 1769 }
joachim99@8 1770 else if ( mel.isConflict() )
joachim99@8 1771 {
joachim99@58 1772 selectionString += i18n("<Merge Conflict>");
joachim99@8 1773 }
joachim99@8 1774
joachim99@8 1775 if( m_selection.within( line, outPos ) )
joachim99@8 1776 {
joachim99@8 1777 #ifdef _WIN32
joachim99@8 1778 selectionString += '\r';
joachim99@8 1779 #endif
joachim99@8 1780 selectionString += '\n';
joachim99@8 1781 }
joachim99@8 1782 }
joachim99@8 1783
joachim99@8 1784 ++line;
joachim99@8 1785 }
joachim99@8 1786 }
joachim99@8 1787
joachim99@8 1788 return selectionString;
joachim99@8 1789 }
joachim99@8 1790
joachim99@8 1791 bool MergeResultWindow::deleteSelection2( const char*& ps, int& stringLength, int& x, int& y,
joachim99@8 1792 MergeLineList::iterator& mlIt, MergeEditLineList::iterator& melIt )
joachim99@8 1793 {
joachim99@8 1794 if (m_selection.firstLine!=-1 && m_selection.bSelectionContainsData )
joachim99@8 1795 {
joachim99@8 1796 deleteSelection();
joachim99@8 1797 y = m_cursorYPos;
joachim99@8 1798 calcIteratorFromLineNr( y, mlIt, melIt );
joachim99@8 1799 ps = melIt->getString( this, stringLength );
joachim99@8 1800 x = convertToPosInText( ps, stringLength, m_cursorXPos );
joachim99@8 1801 return true;
joachim99@8 1802 }
joachim99@8 1803 return false;
joachim99@8 1804 }
joachim99@8 1805
joachim99@8 1806 void MergeResultWindow::deleteSelection()
joachim99@8 1807 {
joachim99@8 1808 if ( m_selection.firstLine==-1 || !m_selection.bSelectionContainsData )
joachim99@8 1809 {
joachim99@8 1810 return;
joachim99@8 1811 }
joachim99@8 1812 setModified();
joachim99@8 1813
joachim99@8 1814 int line = 0;
joachim99@8 1815 MergeLineList::iterator mlItFirst;
joachim99@8 1816 MergeEditLineList::iterator melItFirst;
joachim99@8 1817 QCString firstLineString;
joachim99@8 1818
joachim99@8 1819 int firstLine = -1;
joachim99@8 1820 int lastLine = -1;
joachim99@8 1821
joachim99@8 1822 MergeLineList::iterator mlIt;
joachim99@8 1823 for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt)
joachim99@8 1824 {
joachim99@8 1825 MergeLine& ml = *mlIt;
joachim99@8 1826 MergeEditLineList::iterator melIt;
joachim99@8 1827 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt )
joachim99@8 1828 {
joachim99@8 1829 MergeEditLine& mel = *melIt;
joachim99@8 1830
joachim99@8 1831 if ( mel.isEditableText() && m_selection.lineWithin(line) )
joachim99@8 1832 {
joachim99@8 1833 if ( firstLine==-1 )
joachim99@8 1834 firstLine = line;
joachim99@8 1835 lastLine = line;
joachim99@8 1836 }
joachim99@8 1837
joachim99@8 1838 ++line;
joachim99@8 1839 }
joachim99@8 1840 }
joachim99@8 1841
joachim99@8 1842 if ( firstLine == -1 )
joachim99@8 1843 {
joachim99@8 1844 return; // Nothing to delete.
joachim99@8 1845 }
joachim99@8 1846
joachim99@8 1847 line = 0;
joachim99@8 1848 for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt)
joachim99@8 1849 {
joachim99@8 1850 MergeLine& ml = *mlIt;
joachim99@8 1851 MergeEditLineList::iterator melIt, melIt1;
joachim99@8 1852 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); )
joachim99@8 1853 {
joachim99@8 1854 MergeEditLine& mel = *melIt;
joachim99@8 1855 melIt1 = melIt;
joachim99@8 1856 ++melIt1;
joachim99@8 1857
joachim99@8 1858 if ( mel.isEditableText() && m_selection.lineWithin(line) )
joachim99@8 1859 {
joachim99@8 1860 int size;
joachim99@8 1861 const char* pLine = mel.getString( this, size );
joachim99@8 1862
joachim99@8 1863 int firstPosInLine = m_selection.firstPosInLine(line);
joachim99@8 1864 int lastPosInLine = m_selection.lastPosInLine(line);
joachim99@8 1865
joachim99@8 1866 if ( line==firstLine )
joachim99@8 1867 {
joachim99@8 1868 mlItFirst = mlIt;
joachim99@8 1869 melItFirst = melIt;
joachim99@8 1870 int pos = convertToPosInText( pLine, size, firstPosInLine );
joachim99@8 1871 firstLineString = QCString( pLine, pos+1 );
joachim99@8 1872 }
joachim99@8 1873
joachim99@8 1874 if ( line==lastLine )
joachim99@8 1875 {
joachim99@8 1876 // This is the last line in the selection
joachim99@8 1877 int pos = convertToPosInText( pLine, size, lastPosInLine );
joachim99@8 1878 firstLineString += QCString( pLine+pos, 1+max2( 0,size-pos));
joachim99@8 1879 melItFirst->setString( firstLineString );
joachim99@8 1880 }
joachim99@8 1881
joachim99@8 1882 if ( line!=firstLine )
joachim99@8 1883 {
joachim99@8 1884 // Remove the line
joachim99@8 1885 if ( mlIt->mergeEditLineList.size()>1 )
joachim99@58 1886 mlIt->mergeEditLineList.erase( melIt );
joachim99@8 1887 else
joachim99@58 1888 melIt->setRemoved();
joachim99@8 1889 }
joachim99@8 1890 }
joachim99@8 1891
joachim99@8 1892 ++line;
joachim99@8 1893 melIt = melIt1;
joachim99@8 1894 }
joachim99@8 1895 }
joachim99@8 1896
joachim99@8 1897 m_cursorYPos = m_selection.beginLine();
joachim99@8 1898 m_cursorXPos = m_selection.beginPos();
joachim99@8 1899 m_cursorOldXPos = m_cursorXPos;
joachim99@8 1900
joachim99@8 1901 m_selection.reset();
joachim99@8 1902 }
joachim99@8 1903
joachim99@8 1904 void MergeResultWindow::pasteClipboard()
joachim99@8 1905 {
joachim99@8 1906 if (m_selection.firstLine != -1 )
joachim99@8 1907 deleteSelection();
joachim99@8 1908
joachim99@8 1909 setModified();
joachim99@8 1910
joachim99@8 1911 int y = m_cursorYPos;
joachim99@8 1912 MergeLineList::iterator mlIt;
joachim99@8 1913 MergeEditLineList::iterator melIt, melItAfter;
joachim99@8 1914 calcIteratorFromLineNr( y, mlIt, melIt );
joachim99@8 1915 melItAfter = melIt;
joachim99@8 1916 ++melItAfter;
joachim99@8 1917 int stringLength;
joachim99@8 1918 const char* ps = melIt->getString( this, stringLength );
joachim99@8 1919 int x = convertToPosInText( ps, stringLength, m_cursorXPos );
joachim99@8 1920
joachim99@58 1921 QCString clipBoard = encodeString( QApplication::clipboard()->text(), m_pOptionDialog );
joachim99@8 1922
joachim99@8 1923 QCString currentLine = QCString( ps, x+1 );
joachim99@8 1924 QCString endOfLine = QCString( ps+x, stringLength-x+1 );
joachim99@8 1925 int i;
joachim99@8 1926 for( i=0; i<(int)clipBoard.length(); ++i )
joachim99@8 1927 {
joachim99@58 1928 char c = clipBoard[i];
joachim99@8 1929 if ( c == '\r' ) continue;
joachim99@8 1930 if ( c == '\n' )
joachim99@8 1931 {
joachim99@8 1932 melIt->setString( currentLine );
joachim99@8 1933
joachim99@8 1934 melIt = mlIt->mergeEditLineList.insert( melItAfter, MergeEditLine() );
joachim99@8 1935 currentLine = "";
joachim99@8 1936 x=0;
joachim99@8 1937 ++y;
joachim99@8 1938 }
joachim99@8 1939 else
joachim99@8 1940 {
joachim99@8 1941 currentLine += c;
joachim99@8 1942 ++x;
joachim99@8 1943 }
joachim99@8 1944 }
joachim99@8 1945
joachim99@8 1946 currentLine += endOfLine;
joachim99@8 1947 melIt->setString( currentLine );
joachim99@8 1948
joachim99@8 1949 m_cursorYPos = y;
joachim99@8 1950 m_cursorXPos = convertToPosOnScreen( currentLine, x );
joachim99@8 1951 m_cursorOldXPos = m_cursorXPos;
joachim99@8 1952
joachim99@8 1953 update();
joachim99@8 1954 }
joachim99@8 1955
joachim99@8 1956 void MergeResultWindow::resetSelection()
joachim99@8 1957 {
joachim99@8 1958 m_selection.reset();
joachim99@8 1959 update();
joachim99@8 1960 }
joachim99@8 1961
joachim99@8 1962 void MergeResultWindow::setModified()
joachim99@8 1963 {
joachim99@8 1964 if (!m_bModified)
joachim99@8 1965 {
joachim99@8 1966 m_bModified = true;
joachim99@8 1967 emit modified();
joachim99@8 1968 }
joachim99@8 1969 }
joachim99@8 1970
joachim99@8 1971 /// Saves and returns true when successful.
joachim99@8 1972 bool MergeResultWindow::saveDocument( const QString& fileName )
joachim99@8 1973 {
joachim99@8 1974 m_fileName = fileName;
joachim99@8 1975
joachim99@8 1976 // Are still conflicts somewhere?
joachim99@8 1977 if ( getNrOfUnsolvedConflicts()>0 )
joachim99@8 1978 {
joachim99@8 1979 KMessageBox::error( this,
joachim99@8 1980 i18n("Not all conflicts are solved yet.\n"
joachim99@8 1981 "File not saved.\n"),
joachim99@51 1982 i18n("Conflicts Left"));
joachim99@8 1983 return false;
joachim99@8 1984 }
joachim99@8 1985
joachim99@8 1986 update();
joachim99@8 1987
joachim99@8 1988 FileAccess file( fileName, true /*bWantToWrite*/ );
joachim99@8 1989 if ( m_pOptionDialog->m_bDmCreateBakFiles && file.exists() )
joachim99@8 1990 {
joachim99@8 1991 bool bSuccess = file.createBackup(".orig");
joachim99@8 1992 if ( !bSuccess )
joachim99@8 1993 {
joachim99@51 1994 KMessageBox::error( this, file.getStatusText() + i18n("\n\nFile not saved."), i18n("File Save Error") );
joachim99@8 1995 return false;
joachim99@8 1996 }
joachim99@8 1997 }
joachim99@8 1998
joachim99@8 1999 // Loop twice over all data: First to calculate the needed size,
joachim99@8 2000 // then alloc memory and in the second loop copy the data into the memory.
joachim99@8 2001 long neededBufferSize = 0;
joachim99@8 2002 long dataIndex = 0;
joachim99@8 2003 QByteArray dataArray;
joachim99@8 2004 for ( int i=0; i<2; ++i )
joachim99@8 2005 {
joachim99@8 2006 if(i==1)
joachim99@8 2007 {
joachim99@8 2008 if ( ! dataArray.resize(neededBufferSize) )
joachim99@8 2009 {
joachim99@8 2010 KMessageBox::error(this, i18n("Out of memory while preparing to save.") );
joachim99@8 2011 return false;
joachim99@8 2012 }
joachim99@8 2013 }
joachim99@8 2014
joachim99@8 2015 int line = 0;
joachim99@8 2016 MergeLineList::iterator mlIt = m_mergeLineList.begin();
joachim99@8 2017 for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt)
joachim99@8 2018 {
joachim99@8 2019 MergeLine& ml = *mlIt;
joachim99@8 2020 MergeEditLineList::iterator melIt;
joachim99@8 2021 for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt )
joachim99@8 2022 {
joachim99@8 2023 MergeEditLine& mel = *melIt;
joachim99@8 2024
joachim99@8 2025 if ( mel.isEditableText() )
joachim99@8 2026 {
joachim99@8 2027 int size;
joachim99@8 2028 const char* pLine = mel.getString( this, size );
joachim99@8 2029
joachim99@8 2030 QCString s(pLine, size+1);
joachim99@8 2031
joachim99@8 2032 if (line>0) // Prepend line feed, but not for first line
joachim99@8 2033 {
joachim99@58 2034 if ( m_pOptionDialog->m_lineEndStyle == eLineEndDos )
joachim99@58 2035 { s.prepend("\r\n"); size+=2; }
joachim99@58 2036 else
joachim99@58 2037 { s.prepend("\n"); size+=1; }
joachim99@8 2038 }
joachim99@8 2039
joachim99@8 2040 if (i==0) neededBufferSize += size;
joachim99@8 2041 else
joachim99@8 2042 {
joachim99@8 2043 memcpy( dataArray.data() + dataIndex, s, size );
joachim99@8 2044 dataIndex+=size;
joachim99@8 2045 }
joachim99@8 2046 }
joachim99@8 2047
joachim99@8 2048 ++line;
joachim99@8 2049 }
joachim99@8 2050 }
joachim99@8 2051 }
joachim99@8 2052 bool bSuccess = file.writeFile( dataArray.data(), neededBufferSize );
joachim99@8 2053 if ( ! bSuccess )
joachim99@8 2054 {
joachim99@51 2055 KMessageBox::error( this, i18n("Error while writing."), i18n("File Save Error") );
joachim99@8 2056 return false;
joachim99@8 2057 }
joachim99@8 2058 g_pProgressDialog->hide();
joachim99@8 2059
joachim99@8 2060 m_bModified = false;
joachim99@8 2061 update();
joachim99@8 2062
joachim99@8 2063 return true;
joachim99@8 2064 }
joachim99@8 2065
joachim99@8 2066 QCString MergeResultWindow::getString( int lineIdx )
joachim99@8 2067 {
joachim99@8 2068 MergeResultWindow::MergeLineList::iterator mlIt;
joachim99@8 2069 MergeResultWindow::MergeEditLineList::iterator melIt;
joachim99@8 2070 calcIteratorFromLineNr( lineIdx, mlIt, melIt );
joachim99@8 2071 int length=0;
joachim99@8 2072 const char* p = melIt->getString( this, length );
joachim99@8 2073 QCString line( p, length+1 );
joachim99@8 2074 return line;
joachim99@8 2075 }
joachim99@8 2076
joachim99@8 2077 bool MergeResultWindow::findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive )
joachim99@8 2078 {
joachim99@8 2079 int it = d3vLine;
joachim99@8 2080 int endIt = bDirDown ? getNofLines() : -1;
joachim99@8 2081 int step = bDirDown ? 1 : -1;
joachim99@8 2082 int startPos = posInLine;
joachim99@8 2083
joachim99@8 2084 for( ; it!=endIt; it+=step )
joachim99@8 2085 {
joachim99@8 2086 QCString line = getString( it );
joachim99@8 2087 if ( !line.isEmpty() )
joachim99@8 2088 {
joachim99@8 2089 int pos = line.find( s, startPos, bCaseSensitive );
joachim99@8 2090 if ( pos != -1 )
joachim99@8 2091 {
joachim99@8 2092 d3vLine = it;
joachim99@8 2093 posInLine = pos;
joachim99@8 2094 return true;
joachim99@8 2095 }
joachim99@8 2096
joachim99@8 2097 startPos = 0;
joachim99@8 2098 }
joachim99@8 2099 }
joachim99@8 2100 return false;
joachim99@8 2101 }
joachim99@8 2102
joachim99@8 2103 void MergeResultWindow::setSelection( int firstLine, int startPos, int lastLine, int endPos )
joachim99@8 2104 {
joachim99@8 2105 m_selection.reset();
joachim99@8 2106 m_selection.start( firstLine, convertToPosOnScreen( getString(firstLine), startPos ) );
joachim99@8 2107 m_selection.end( lastLine, convertToPosOnScreen( getString(lastLine), endPos ) );
joachim99@8 2108 update();
joachim99@8 2109 }
joachim99@8 2110
joachim99@8 2111 Overview::Overview( QWidget* pParent, OptionDialog* pOptions )
joachim99@8 2112 : QWidget( pParent, 0, WRepaintNoErase )
joachim99@8 2113 {
joachim99@8 2114 m_pDiff3LineList = 0;
joachim99@8 2115 m_pOptions = pOptions;
joachim99@8 2116 m_bTripleDiff = false;
joachim99@8 2117 setFixedWidth(20);
joachim99@8 2118 }
joachim99@8 2119
joachim99@8 2120 void Overview::init( Diff3LineList* pDiff3LineList, bool bTripleDiff )
joachim99@8 2121 {
joachim99@8 2122 m_pDiff3LineList = pDiff3LineList;
joachim99@8 2123 m_bTripleDiff = bTripleDiff;
joachim99@8 2124 m_pixmap.resize( QSize(0,0) ); // make sure that a redraw happens
joachim99@8 2125 update();
joachim99@8 2126 }
joachim99@8 2127
joachim99@51 2128 void Overview::slotRedraw()
joachim99@51 2129 {
joachim99@51 2130 m_pixmap.resize( QSize(0,0) ); // make sure that a redraw happens
joachim99@51 2131 update();
joachim99@51 2132 }
joachim99@51 2133
joachim99@8 2134 void Overview::setRange( int firstLine, int pageHeight )
joachim99@8 2135 {
joachim99@8 2136 m_firstLine = firstLine;
joachim99@8 2137 m_pageHeight = pageHeight;
joachim99@8 2138 update();
joachim99@8 2139 }
joachim99@8 2140 void Overview::setFirstLine( int firstLine )
joachim99@8 2141 {
joachim99@8 2142 m_firstLine = firstLine;
joachim99@8 2143 update();
joachim99@8 2144 }
joachim99@8 2145
joachim99@8 2146 void Overview::mousePressEvent( QMouseEvent* e )
joachim99@8 2147 {
joachim99@8 2148 int h = height()-1;
joachim99@8 2149 int nofLines = m_pDiff3LineList->size();
joachim99@8 2150 int h1 = h * m_pageHeight / nofLines+3;
joachim99@8 2151 if ( h>0 )
joachim99@8 2152 emit setLine( ( e->y() - h1/2 )*nofLines/h );
joachim99@8 2153 }
joachim99@8 2154
joachim99@8 2155 void Overview::mouseMoveEvent( QMouseEvent* e )
joachim99@8 2156 {
joachim99@8 2157 mousePressEvent(e);
joachim99@8 2158 }
joachim99@8 2159
joachim99@8 2160 void Overview::setPaintingAllowed( bool bAllowPainting )
joachim99@8 2161 {
joachim99@8 2162 if (m_bPaintingAllowed != bAllowPainting)
joachim99@8 2163 {
joachim99@8 2164 m_bPaintingAllowed = bAllowPainting;
joachim99@8 2165 if ( m_bPaintingAllowed ) update();
joachim99@8 2166 }
joachim99@8 2167 }
joachim99@8 2168
joachim99@8 2169 void Overview::paintEvent( QPaintEvent* )
joachim99@8 2170 {
joachim99@8 2171 if (m_pDiff3LineList==0 || !m_bPaintingAllowed ) return;
joachim99@8 2172 int h = height()-1;
joachim99@8 2173 int w = width();
joachim99@8 2174 int nofLines = m_pDiff3LineList->size();
joachim99@8 2175
joachim99@8 2176 if ( m_pixmap.size() != size() )
joachim99@8 2177 {
joachim99@8 2178 m_pixmap.resize( size() );
joachim99@8 2179
joachim99@8 2180 QPainter p(&m_pixmap);
joachim99@8 2181
joachim99@8 2182 p.fillRect( rect(), m_pOptions->m_bgColor );
joachim99@8 2183 p.setPen(black);
joachim99@8 2184 p.drawLine( 0, 0, 0, h );
joachim99@8 2185
joachim99@8 2186 if (nofLines==0) return;
joachim99@8 2187
joachim99@8 2188 int line = 0;
joachim99@8 2189 int oldY = 0;
joachim99@8 2190 int oldConflictY = -1;
joachim99@8 2191 Diff3LineList::const_iterator i;
joachim99@8 2192 for( i = m_pDiff3LineList->begin(); i!= m_pDiff3LineList->end(); ++i )
joachim99@8 2193 {
joachim99@8 2194 const Diff3Line& d3l = *i;
joachim99@8 2195 int y = h * (line+1) / nofLines;
joachim99@8 2196 e_MergeDetails md;
joachim99@8 2197 bool bConflict;
joachim99@8 2198 bool bLineRemoved;
joachim99@8 2199 int src;
joachim99@8 2200 mergeOneLine( d3l, md, bConflict, bLineRemoved, src, !m_bTripleDiff );
joachim99@8 2201
joachim99@8 2202 QColor c;
joachim99@8 2203 bool bWhiteSpaceChange = false;
joachim99@8 2204 //if( bConflict ) c=m_pOptions->m_colorForConflict;
joachim99@8 2205 //else
joachim99@8 2206 {
joachim99@8 2207 switch( md )
joachim99@8 2208 {
joachim99@8 2209 case eDefault:
joachim99@8 2210 case eNoChange:
joachim99@8 2211 c = m_pOptions->m_bgColor;
joachim99@8 2212 break;
joachim99@8 2213
joachim99@8 2214 case eBAdded:
joachim99@8 2215 case eBDeleted:
joachim99@8 2216 case eBChanged:
joachim99@8 2217 c = bConflict ? m_pOptions->m_colorForConflict : m_pOptions->m_colorB;
joachim99@8 2218 bWhiteSpaceChange = d3l.bAEqB || d3l.bWhiteLineA && d3l.bWhiteLineB;
joachim99@8 2219 break;
joachim99@8 2220
joachim99@8 2221 case eCAdded:
joachim99@8 2222 case eCDeleted:
joachim99@8 2223 case eCChanged:
joachim99@8 2224 bWhiteSpaceChange = d3l.bAEqC || d3l.bWhiteLineA && d3l.bWhiteLineC;
joachim99@8 2225 c = bConflict ? m_pOptions->m_colorForConflict : m_pOptions->m_colorC;
joachim99@8 2226 break;
joachim99@8 2227
joachim99@8 2228 case eBCChanged: // conflict
joachim99@8 2229 case eBCChangedAndEqual: // possible conflict
joachim99@8 2230 case eBCDeleted: // possible conflict
joachim99@8 2231 case eBChanged_CDeleted: // conflict
joachim99@8 2232 case eCChanged_BDeleted: // conflict
joachim99@8 2233 case eBCAdded: // conflict
joachim99@8 2234 case eBCAddedAndEqual: // possible conflict
joachim99@8 2235 c=m_pOptions->m_colorForConflict;
joachim99@8 2236 break;
joachim99@8 2237 default: assert(false); break;
joachim99@8 2238 }
joachim99@8 2239 }
joachim99@8 2240
joachim99@51 2241 if (!bWhiteSpaceChange || m_pOptions->m_bShowWhiteSpace )
joachim99@8 2242 {
joachim99@51 2243 // Make sure that lines with conflict are not overwritten.
joachim99@51 2244 if ( c == m_pOptions->m_colorForConflict )
joachim99@51 2245 {
joachim99@51 2246 p.fillRect(1, oldY, w, max2(1,y-oldY), bWhiteSpaceChange ? QBrush(c,Dense4Pattern) : c );
joachim99@51 2247 oldConflictY = oldY;
joachim99@51 2248 }
joachim99@51 2249 else if ( c!=m_pOptions->m_bgColor && oldY>oldConflictY )
joachim99@51 2250 {
joachim99@51 2251 p.fillRect(1, oldY, w, max2(1,y-oldY), bWhiteSpaceChange ? QBrush(c,Dense4Pattern) : c );
joachim99@51 2252 }
joachim99@8 2253 }
joachim99@8 2254
joachim99@8 2255 oldY = y;
joachim99@8 2256
joachim99@8 2257 ++line;
joachim99@8 2258 }
joachim99@8 2259 }
joachim99@8 2260
joachim99@8 2261 QPainter painter( this );
joachim99@8 2262 painter.drawPixmap( 0,0, m_pixmap );
joachim99@8 2263
joachim99@8 2264 int y1 = h * m_firstLine / nofLines-1;
joachim99@8 2265 int h1 = h * m_pageHeight / nofLines+3;
joachim99@8 2266 painter.setPen(black);
joachim99@8 2267 painter.drawRect( 1, y1, w-1, h1 );
joachim99@8 2268 }
joachim99@8 2269
joachim99@8 2270