annotate kdiff3/src/diff.h @ 8:86d21651c8db

KDiff3 version 0.9.70
author joachim99
date Mon, 06 Oct 2003 18:50:45 +0000
parents
children c59d5a3a8ff3
rev   line source
joachim99@8 1 /***************************************************************************
joachim99@8 2 diff.h - description
joachim99@8 3 -------------------
joachim99@8 4 begin : Mon Mar 18 2002
joachim99@8 5 copyright : (C) 2002 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 /***************************************************************************
joachim99@8 19 * $Log$
joachim99@8 20 * Revision 1.1 2003/10/06 18:38:48 joachim99
joachim99@8 21 * KDiff3 version 0.9.70
joachim99@8 22 * *
joachim99@8 23 ***************************************************************************/
joachim99@8 24
joachim99@8 25 #ifndef DIFF_H
joachim99@8 26 #define DIFF_H
joachim99@8 27
joachim99@8 28 #include <qwidget.h>
joachim99@8 29 #include <qpixmap.h>
joachim99@8 30 #include <qtimer.h>
joachim99@8 31 #include <qframe.h>
joachim99@8 32 #include <list>
joachim99@8 33 #include <vector>
joachim99@8 34 #include <assert.h>
joachim99@8 35 #include "common.h"
joachim99@8 36 #include "fileaccess.h"
joachim99@8 37
joachim99@8 38
joachim99@8 39
joachim99@8 40 // Each range with matching elements is followed by a range with differences on either side.
joachim99@8 41 // Then again range of matching elements should follow.
joachim99@8 42 struct Diff
joachim99@8 43 {
joachim99@8 44 int nofEquals;
joachim99@8 45
joachim99@8 46 int diff1;
joachim99@8 47 int diff2;
joachim99@8 48
joachim99@8 49 Diff(int eq, int d1, int d2){nofEquals=eq; diff1=d1; diff2=d2; }
joachim99@8 50 };
joachim99@8 51
joachim99@8 52 typedef std::list<Diff> DiffList;
joachim99@8 53
joachim99@8 54 struct Diff3Line
joachim99@8 55 {
joachim99@8 56 int lineA;
joachim99@8 57 int lineB;
joachim99@8 58 int lineC;
joachim99@8 59
joachim99@8 60 bool bAEqC; // These are true if equal or only white-space changes exist.
joachim99@8 61 bool bBEqC;
joachim99@8 62 bool bAEqB;
joachim99@8 63
joachim99@8 64 DiffList* pFineAB; // These are 0 only if completely equal.
joachim99@8 65 DiffList* pFineBC;
joachim99@8 66 DiffList* pFineCA;
joachim99@8 67
joachim99@8 68 bool bWhiteLineA;
joachim99@8 69 bool bWhiteLineB;
joachim99@8 70 bool bWhiteLineC;
joachim99@8 71
joachim99@8 72 Diff3Line()
joachim99@8 73 {
joachim99@8 74 lineA=-1; lineB=-1; lineC=-1;
joachim99@8 75 bAEqC=false; bAEqB=false; bBEqC=false;
joachim99@8 76 pFineAB=0; pFineBC=0; pFineCA=0;
joachim99@8 77 }
joachim99@8 78
joachim99@8 79 ~Diff3Line()
joachim99@8 80 {
joachim99@8 81 if (pFineAB!=0) delete pFineAB;
joachim99@8 82 if (pFineBC!=0) delete pFineBC;
joachim99@8 83 if (pFineCA!=0) delete pFineCA;
joachim99@8 84 pFineAB=0; pFineBC=0; pFineCA=0;
joachim99@8 85 }
joachim99@8 86
joachim99@8 87 bool operator==( const Diff3Line& d3l )
joachim99@8 88 {
joachim99@8 89 return lineA == d3l.lineA && lineB == d3l.lineB && lineC == d3l.lineC
joachim99@8 90 && bAEqB == d3l.bAEqB && bAEqC == d3l.bAEqC && bBEqC == d3l.bBEqC;
joachim99@8 91 }
joachim99@8 92 };
joachim99@8 93
joachim99@8 94 typedef std::list<Diff3Line> Diff3LineList;
joachim99@8 95 typedef std::vector<const Diff3Line*> Diff3LineVector;
joachim99@8 96
joachim99@8 97 class TotalDiffStatus
joachim99@8 98 {
joachim99@8 99 public:
joachim99@8 100 void reset() {bBinaryAEqC=false; bBinaryBEqC=false; bBinaryAEqB=false;
joachim99@8 101 bTextAEqC=false; bTextBEqC=false; bTextAEqB=false;}
joachim99@8 102 bool bBinaryAEqC;
joachim99@8 103 bool bBinaryBEqC;
joachim99@8 104 bool bBinaryAEqB;
joachim99@8 105
joachim99@8 106 bool bTextAEqC;
joachim99@8 107 bool bTextBEqC;
joachim99@8 108 bool bTextAEqB;
joachim99@8 109 };
joachim99@8 110
joachim99@8 111 void calcDiff3LineListUsingAB(
joachim99@8 112 const DiffList* pDiffListAB,
joachim99@8 113 Diff3LineList& d3ll
joachim99@8 114 );
joachim99@8 115
joachim99@8 116 void calcDiff3LineListUsingAC(
joachim99@8 117 const DiffList* pDiffListBC,
joachim99@8 118 Diff3LineList& d3ll
joachim99@8 119 );
joachim99@8 120
joachim99@8 121 void calcDiff3LineListUsingBC(
joachim99@8 122 const DiffList* pDiffListBC,
joachim99@8 123 Diff3LineList& d3ll
joachim99@8 124 );
joachim99@8 125
joachim99@8 126 struct LineData
joachim99@8 127 {
joachim99@8 128 const char* pLine;
joachim99@8 129 const char* pFirstNonWhiteChar;
joachim99@8 130 int size;
joachim99@8 131
joachim99@8 132 LineData(){ pLine=0; size=0; occurances=0; }
joachim99@8 133 int width(); // Calcs width considering tabs.
joachim99@8 134 int occurances;
joachim99@8 135 bool whiteLine(){ return pFirstNonWhiteChar-pLine == size; }
joachim99@8 136 };
joachim99@8 137
joachim99@8 138 void prepareOccurances( LineData* p, int size );
joachim99@8 139
joachim99@8 140
joachim99@8 141 class SourceData
joachim99@8 142 {
joachim99@8 143 public:
joachim99@8 144 SourceData(){ m_pBuf=0;m_size=0;m_vSize=0;m_bIsText=false;m_bPreserve=false; }
joachim99@8 145 const char* m_pBuf;
joachim99@8 146 int m_size;
joachim99@8 147 int m_vSize; // Nr of lines in m_pBuf1 and size of m_v1, m_dv12 and m_dv13
joachim99@8 148 std::vector<LineData> m_v;
joachim99@8 149 bool m_bIsText;
joachim99@8 150 bool m_bPreserve;
joachim99@8 151 void reset();
joachim99@8 152 void readPPFile( bool bPreserveCR, const QString& ppCmd, bool bUpCase );
joachim99@8 153 void readLMPPFile( SourceData* pOrigSource, const QString& ppCmd, bool bUpCase );
joachim99@8 154 void readFile(const QString& filename, bool bFollowLinks, bool bUpCase );
joachim99@8 155 void preprocess(bool bPreserveCR );
joachim99@8 156 void setData( const QString& data, bool bUpCase );
joachim99@8 157 void setFilename(const QString& filename);
joachim99@8 158 void setFileAccess( const FileAccess& fa );
joachim99@8 159 FileAccess& getFileAccess();
joachim99@8 160 QString getFilename();
joachim99@8 161 void setAliasName(const QString& a);
joachim99@8 162 QString getAliasName();
joachim99@8 163 bool isEmpty() { return getFilename().isEmpty(); }
joachim99@8 164 private:
joachim99@8 165 QString m_fileName;
joachim99@8 166 QString m_aliasName;
joachim99@8 167 FileAccess m_fileAccess;
joachim99@8 168 };
joachim99@8 169
joachim99@8 170 void calcDiff3LineListTrim( Diff3LineList& d3ll, LineData* pldA, LineData* pldB, LineData* pldC );
joachim99@8 171 void calcWhiteDiff3Lines( Diff3LineList& d3ll, LineData* pldA, LineData* pldB, LineData* pldC );
joachim99@8 172
joachim99@8 173 void calcDiff3LineVector( const Diff3LineList& d3ll, Diff3LineVector& d3lv );
joachim99@8 174
joachim99@8 175 void debugLineCheck( Diff3LineList& d3ll, int size, int idx );
joachim99@8 176
joachim99@8 177 class QStatusBar;
joachim99@8 178
joachim99@8 179
joachim99@8 180
joachim99@8 181 class Selection
joachim99@8 182 {
joachim99@8 183 public:
joachim99@8 184 Selection(){ reset(); oldLastLine=-1; lastLine=-1; oldFirstLine=-1; }
joachim99@8 185 int firstLine;
joachim99@8 186 int firstPos;
joachim99@8 187 int lastLine;
joachim99@8 188 int lastPos;
joachim99@8 189 int oldLastLine;
joachim99@8 190 int oldFirstLine;
joachim99@8 191 bool bSelectionContainsData;
joachim99@8 192 bool isEmpty() { return firstLine==-1 || (firstLine==lastLine && firstPos==lastPos) || bSelectionContainsData==false;}
joachim99@8 193 void reset(){
joachim99@8 194 oldFirstLine=firstLine;
joachim99@8 195 oldLastLine =lastLine;
joachim99@8 196 firstLine=-1;
joachim99@8 197 bSelectionContainsData = false;
joachim99@8 198 }
joachim99@8 199 void start( int l, int p ) { firstLine = l; firstPos = p; }
joachim99@8 200 void end( int l, int p ) {
joachim99@8 201 if ( oldLastLine == -1 )
joachim99@8 202 oldLastLine = lastLine;
joachim99@8 203 lastLine = l;
joachim99@8 204 lastPos = p;
joachim99@8 205 }
joachim99@8 206 bool within( int l, int p );
joachim99@8 207
joachim99@8 208 bool lineWithin( int l );
joachim99@8 209 int firstPosInLine(int l);
joachim99@8 210 int lastPosInLine(int l);
joachim99@8 211 int beginLine(){ return min2(firstLine,lastLine); }
joachim99@8 212 int endLine(){ return max2(firstLine,lastLine); }
joachim99@8 213 int beginPos() { return firstLine==lastLine ? min2(firstPos,lastPos) :
joachim99@8 214 firstLine<lastLine ? firstPos : lastPos; }
joachim99@8 215 int endPos() { return firstLine==lastLine ? max2(firstPos,lastPos) :
joachim99@8 216 firstLine<lastLine ? lastPos : firstPos; }
joachim99@8 217 };
joachim99@8 218
joachim99@8 219 class OptionDialog;
joachim99@8 220
joachim99@8 221 class DiffTextWindow : public QWidget
joachim99@8 222 {
joachim99@8 223 Q_OBJECT
joachim99@8 224 public:
joachim99@8 225 DiffTextWindow(
joachim99@8 226 QWidget* pParent,
joachim99@8 227 QStatusBar* pStatusBar,
joachim99@8 228 OptionDialog* pOptionDialog
joachim99@8 229 );
joachim99@8 230 void init(
joachim99@8 231 const QString& fileName,
joachim99@8 232 LineData* pLineData,
joachim99@8 233 int size,
joachim99@8 234 const Diff3LineVector* pDiff3LineVector,
joachim99@8 235 int winIdx,
joachim99@8 236 bool bTriple
joachim99@8 237 );
joachim99@8 238 virtual void mousePressEvent ( QMouseEvent * );
joachim99@8 239 virtual void mouseReleaseEvent ( QMouseEvent * );
joachim99@8 240 virtual void mouseMoveEvent ( QMouseEvent * );
joachim99@8 241 virtual void mouseDoubleClickEvent ( QMouseEvent * e );
joachim99@8 242 void convertToLinePos( int x, int y, int& line, int& pos );
joachim99@8 243
joachim99@8 244 virtual void paintEvent( QPaintEvent* );
joachim99@8 245 virtual void dragEnterEvent( QDragEnterEvent* e );
joachim99@8 246 //void setData( const char* pText);
joachim99@8 247
joachim99@8 248 virtual void resizeEvent( QResizeEvent* );
joachim99@8 249
joachim99@8 250 QString getSelection();
joachim99@8 251 int getFirstLine() { return m_firstLine; }
joachim99@8 252
joachim99@8 253 int getNofColumns();
joachim99@8 254 int getNofLines();
joachim99@8 255 int getNofVisibleLines();
joachim99@8 256 int getNofVisibleColumns();
joachim99@8 257
joachim99@8 258 bool findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive );
joachim99@8 259 void setSelection( int firstLine, int startPos, int lastLine, int endPos );
joachim99@8 260
joachim99@8 261 void setPaintingAllowed( bool bAllowPainting );
joachim99@8 262 signals:
joachim99@8 263 void resizeSignal( int nofVisibleColumns, int nofVisibleLines );
joachim99@8 264 void scroll( int deltaX, int deltaY );
joachim99@8 265 void newSelection();
joachim99@8 266 void selectionEnd();
joachim99@8 267 void setFastSelectorLine( int line );
joachim99@8 268
joachim99@8 269 public slots:
joachim99@8 270 void setFirstLine( int line );
joachim99@8 271 void setFirstColumn( int col );
joachim99@8 272 void resetSelection();
joachim99@8 273 void setFastSelectorRange( int line1, int nofLines );
joachim99@8 274
joachim99@8 275 private:
joachim99@8 276 bool m_bPaintingAllowed;
joachim99@8 277 LineData* m_pLineData;
joachim99@8 278 int m_size;
joachim99@8 279 QString m_filename;
joachim99@8 280
joachim99@8 281 const Diff3LineVector* m_pDiff3LineVector;
joachim99@8 282
joachim99@8 283 OptionDialog* m_pOptionDialog;
joachim99@8 284 QColor m_cThis;
joachim99@8 285 QColor m_cDiff1;
joachim99@8 286 QColor m_cDiff2;
joachim99@8 287 QColor m_cDiffBoth;
joachim99@8 288
joachim99@8 289 int m_fastSelectorLine1;
joachim99@8 290 int m_fastSelectorNofLines;
joachim99@8 291
joachim99@8 292 bool m_bTriple;
joachim99@8 293 int m_winIdx;
joachim99@8 294 int m_firstLine;
joachim99@8 295 int m_oldFirstLine;
joachim99@8 296 int m_oldFirstColumn;
joachim99@8 297 int m_firstColumn;
joachim99@8 298 int m_lineNumberWidth;
joachim99@8 299
joachim99@8 300 void getLineInfo(
joachim99@8 301 const Diff3Line& d,
joachim99@8 302 int& lineIdx,
joachim99@8 303 DiffList*& pFineDiff1, DiffList*& pFineDiff2, // return values
joachim99@8 304 int& changed, int& changed2 );
joachim99@8 305
joachim99@8 306 QCString getString( int line );
joachim99@8 307
joachim99@8 308 void writeLine(
joachim99@8 309 QPainter& p, const LineData* pld,
joachim99@8 310 const DiffList* pLineDiff1, const DiffList* pLineDiff2, int line,
joachim99@8 311 int whatChanged, int whatChanged2, int srcLineNr );
joachim99@8 312
joachim99@8 313 QStatusBar* m_pStatusBar;
joachim99@8 314
joachim99@8 315 Selection selection;
joachim99@8 316
joachim99@8 317 int m_scrollDeltaX;
joachim99@8 318 int m_scrollDeltaY;
joachim99@8 319 virtual void timerEvent(QTimerEvent*);
joachim99@8 320 bool m_bMyUpdate;
joachim99@8 321 void myUpdate(int afterMilliSecs );
joachim99@8 322
joachim99@8 323 QRect m_invalidRect;
joachim99@8 324 };
joachim99@8 325
joachim99@8 326
joachim99@8 327
joachim99@8 328 class Overview : public QWidget
joachim99@8 329 {
joachim99@8 330 Q_OBJECT
joachim99@8 331 public:
joachim99@8 332 Overview( QWidget* pParent, OptionDialog* pOptions );
joachim99@8 333
joachim99@8 334 void init( Diff3LineList* pDiff3LineList, bool bTripleDiff );
joachim99@8 335 void setRange( int firstLine, int pageHeight );
joachim99@8 336 void setPaintingAllowed( bool bAllowPainting );
joachim99@8 337
joachim99@8 338 public slots:
joachim99@8 339 void setFirstLine(int firstLine);
joachim99@8 340 signals:
joachim99@8 341 void setLine(int);
joachim99@8 342 private:
joachim99@8 343 const Diff3LineList* m_pDiff3LineList;
joachim99@8 344 OptionDialog* m_pOptions;
joachim99@8 345 bool m_bTripleDiff;
joachim99@8 346 int m_firstLine;
joachim99@8 347 int m_pageHeight;
joachim99@8 348 QPixmap m_pixmap;
joachim99@8 349 bool m_bPaintingAllowed;
joachim99@8 350
joachim99@8 351 virtual void paintEvent( QPaintEvent* e );
joachim99@8 352 virtual void mousePressEvent( QMouseEvent* e );
joachim99@8 353 virtual void mouseMoveEvent( QMouseEvent* e );
joachim99@8 354 };
joachim99@8 355
joachim99@8 356
joachim99@8 357 enum e_MergeDetails
joachim99@8 358 {
joachim99@8 359 eDefault,
joachim99@8 360 eNoChange,
joachim99@8 361 eBChanged,
joachim99@8 362 eCChanged,
joachim99@8 363 eBCChanged, // conflict
joachim99@8 364 eBCChangedAndEqual, // possible conflict
joachim99@8 365 eBDeleted,
joachim99@8 366 eCDeleted,
joachim99@8 367 eBCDeleted, // possible conflict
joachim99@8 368
joachim99@8 369 eBChanged_CDeleted, // conflict
joachim99@8 370 eCChanged_BDeleted, // conflict
joachim99@8 371 eBAdded,
joachim99@8 372 eCAdded,
joachim99@8 373 eBCAdded, // conflict
joachim99@8 374 eBCAddedAndEqual // possible conflict
joachim99@8 375 };
joachim99@8 376
joachim99@8 377 void mergeOneLine( const Diff3Line& d, e_MergeDetails& mergeDetails, bool& bConflict, bool& bLineRemoved, int& src, bool bTwoInputs );
joachim99@8 378
joachim99@8 379
joachim99@8 380 class MergeResultWindow : public QWidget
joachim99@8 381 {
joachim99@8 382 Q_OBJECT
joachim99@8 383 public:
joachim99@8 384 MergeResultWindow(
joachim99@8 385 QWidget* pParent,
joachim99@8 386 OptionDialog* pOptionDialog
joachim99@8 387 );
joachim99@8 388
joachim99@8 389 void init(
joachim99@8 390 const LineData* pLineDataA,
joachim99@8 391 const LineData* pLineDataB,
joachim99@8 392 const LineData* pLineDataC,
joachim99@8 393 const Diff3LineList* pDiff3LineList,
joachim99@8 394 const TotalDiffStatus* pTotalDiffStatus,
joachim99@8 395 QString fileName
joachim99@8 396 );
joachim99@8 397
joachim99@8 398 bool saveDocument( const QString& fileName );
joachim99@8 399 int getNrOfUnsolvedConflicts();
joachim99@8 400 void choose(int selector);
joachim99@8 401
joachim99@8 402 int getNofColumns();
joachim99@8 403 int getNofLines();
joachim99@8 404 int getNofVisibleColumns();
joachim99@8 405 int getNofVisibleLines();
joachim99@8 406 virtual void resizeEvent( QResizeEvent* e );
joachim99@8 407 virtual void keyPressEvent( QKeyEvent* e );
joachim99@8 408 virtual void wheelEvent( QWheelEvent* e );
joachim99@8 409 QString getSelection();
joachim99@8 410 void resetSelection();
joachim99@8 411 void showNrOfConflicts();
joachim99@8 412 bool isDeltaAboveCurrent();
joachim99@8 413 bool isDeltaBelowCurrent();
joachim99@8 414 bool isConflictAboveCurrent();
joachim99@8 415 bool isConflictBelowCurrent();
joachim99@8 416 bool isUnsolvedConflictAboveCurrent();
joachim99@8 417 bool isUnsolvedConflictBelowCurrent();
joachim99@8 418 bool findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive );
joachim99@8 419 void setSelection( int firstLine, int startPos, int lastLine, int endPos );
joachim99@8 420 public slots:
joachim99@8 421 void setFirstLine(int firstLine);
joachim99@8 422 void setFirstColumn(int firstCol);
joachim99@8 423
joachim99@8 424 void slotGoCurrent();
joachim99@8 425 void slotGoTop();
joachim99@8 426 void slotGoBottom();
joachim99@8 427 void slotGoPrevDelta();
joachim99@8 428 void slotGoNextDelta();
joachim99@8 429 void slotGoPrevUnsolvedConflict();
joachim99@8 430 void slotGoNextUnsolvedConflict();
joachim99@8 431 void slotGoPrevConflict();
joachim99@8 432 void slotGoNextConflict();
joachim99@8 433 void slotChooseA();
joachim99@8 434 void slotChooseB();
joachim99@8 435 void slotChooseC();
joachim99@8 436 void slotChooseAEverywhere();
joachim99@8 437 void slotChooseBEverywhere();
joachim99@8 438 void slotChooseCEverywhere();
joachim99@8 439 void slotAutoSolve();
joachim99@8 440 void slotUnsolve();
joachim99@8 441 void slotSetFastSelectorLine(int);
joachim99@8 442
joachim99@8 443 signals:
joachim99@8 444 void scroll( int deltaX, int deltaY );
joachim99@8 445 void modified();
joachim99@8 446 void setFastSelectorRange( int line1, int nofLines );
joachim99@8 447 void sourceMask( int srcMask, int enabledMask );
joachim99@8 448 void resizeSignal();
joachim99@8 449 void selectionEnd();
joachim99@8 450 void newSelection();
joachim99@8 451 void updateAvailabilities();
joachim99@8 452 void showPopupMenu( const QPoint& point );
joachim99@8 453
joachim99@8 454 private:
joachim99@8 455 void merge(bool bAutoSolve, int defaultSelector);
joachim99@8 456 QCString getString( int lineIdx );
joachim99@8 457
joachim99@8 458 OptionDialog* m_pOptionDialog;
joachim99@8 459
joachim99@8 460 const LineData* m_pldA;
joachim99@8 461 const LineData* m_pldB;
joachim99@8 462 const LineData* m_pldC;
joachim99@8 463
joachim99@8 464 const Diff3LineList* m_pDiff3LineList;
joachim99@8 465 const TotalDiffStatus* m_pTotalDiffStatus;
joachim99@8 466
joachim99@8 467 private:
joachim99@8 468 class MergeEditLine
joachim99@8 469 {
joachim99@8 470 public:
joachim99@8 471 MergeEditLine(){ m_src=0; m_bLineRemoved=false; }
joachim99@8 472 void setConflict() { m_src=0; m_bLineRemoved=false; m_str=QCString(); }
joachim99@8 473 bool isConflict() { return m_src==0 && !m_bLineRemoved && m_str.isNull(); }
joachim99@8 474 void setRemoved(int src=0) { m_src=src; m_bLineRemoved=true; m_str=QCString(); }
joachim99@8 475 bool isRemoved() { return m_bLineRemoved; }
joachim99@8 476 bool isEditableText() { return !isConflict() && !isRemoved(); }
joachim99@8 477 void setString( const QCString& s ){ m_str=s; m_bLineRemoved=false; m_src=0; }
joachim99@8 478 const char* getString( const MergeResultWindow*, int& size );
joachim99@8 479 bool isModified() { return ! m_str.isNull() || (m_bLineRemoved && m_src==0); }
joachim99@8 480
joachim99@8 481 void setSource( int src, Diff3LineList::const_iterator i, bool bLineRemoved )
joachim99@8 482 {
joachim99@8 483 m_src=src; m_id3l=i; m_bLineRemoved =bLineRemoved;
joachim99@8 484 }
joachim99@8 485 int src() { return m_src; }
joachim99@8 486 Diff3LineList::const_iterator id3l(){return m_id3l;}
joachim99@8 487 // getString() is implemented as MergeResultWindow::getString()
joachim99@8 488 private:
joachim99@8 489 Diff3LineList::const_iterator m_id3l;
joachim99@8 490 int m_src; // 1, 2 or 3 for A, B or C respectively, or 0 when line is from neither source.
joachim99@8 491 QCString m_str; // String when modified by user or null-string when orig data is used.
joachim99@8 492 bool m_bLineRemoved;
joachim99@8 493 };
joachim99@8 494
joachim99@8 495 class MergeEditLineList : private std::list<MergeEditLine>
joachim99@8 496 { // I want to know the size immediately!
joachim99@8 497 private:
joachim99@8 498 typedef std::list<MergeEditLine> BASE;
joachim99@8 499 int m_size;
joachim99@8 500 public:
joachim99@8 501 typedef std::list<MergeEditLine>::iterator iterator;
joachim99@8 502 typedef std::list<MergeEditLine>::const_iterator const_iterator;
joachim99@8 503 MergeEditLineList(){m_size=0;}
joachim99@8 504 void clear() { m_size=0; BASE::clear(); }
joachim99@8 505 void push_back( const MergeEditLine& m) { ++m_size; BASE::push_back(m); }
joachim99@8 506 void push_front( const MergeEditLine& m) { ++m_size; BASE::push_front(m); }
joachim99@8 507 iterator erase( iterator i ) { --m_size; return BASE::erase(i); }
joachim99@8 508 iterator insert( iterator i, const MergeEditLine& m ) { ++m_size; return BASE::insert(i,m); }
joachim99@8 509 int size(){ /*assert(int(BASE::size())==m_size);*/ return m_size;}
joachim99@8 510 iterator begin(){return BASE::begin();}
joachim99@8 511 iterator end(){return BASE::end();}
joachim99@8 512 bool empty() { return m_size==0; }
joachim99@8 513 };
joachim99@8 514
joachim99@8 515 friend class MergeEditLine;
joachim99@8 516
joachim99@8 517 struct MergeLine
joachim99@8 518 {
joachim99@8 519 MergeLine()
joachim99@8 520 { srcSelect=0; mergeDetails=eDefault; d3lLineIdx = -1; srcRangeLength=0; bConflict=false; bDelta=false;}
joachim99@8 521 Diff3LineList::const_iterator id3l;
joachim99@8 522 e_MergeDetails mergeDetails;
joachim99@8 523 int d3lLineIdx; // Needed to show the correct window pos.
joachim99@8 524 int srcRangeLength; // how many src-lines have this properties
joachim99@8 525 bool bConflict;
joachim99@8 526 bool bDelta;
joachim99@8 527 int srcSelect;
joachim99@8 528 MergeEditLineList mergeEditLineList;
joachim99@8 529 };
joachim99@8 530
joachim99@8 531 private:
joachim99@8 532 static bool sameKindCheck( const MergeLine& ml1, const MergeLine& ml2 );
joachim99@8 533
joachim99@8 534 typedef std::list<MergeLine> MergeLineList;
joachim99@8 535 MergeLineList m_mergeLineList;
joachim99@8 536 MergeLineList::iterator m_currentMergeLineIt;
joachim99@8 537 int m_currentPos;
joachim99@8 538
joachim99@8 539 enum e_Direction { eUp, eDown };
joachim99@8 540 enum e_EndPoint { eDelta, eConflict, eUnsolvedConflict, eLine, eEnd };
joachim99@8 541 void go( e_Direction eDir, e_EndPoint eEndPoint );
joachim99@8 542 void calcIteratorFromLineNr(
joachim99@8 543 int line,
joachim99@8 544 MergeLineList::iterator& mlIt,
joachim99@8 545 MergeEditLineList::iterator& melIt
joachim99@8 546 );
joachim99@8 547
joachim99@8 548 virtual void paintEvent( QPaintEvent* e );
joachim99@8 549
joachim99@8 550
joachim99@8 551 void myUpdate(int afterMilliSecs);
joachim99@8 552 virtual void timerEvent(QTimerEvent*);
joachim99@8 553 void writeLine(
joachim99@8 554 QPainter& p, int line, const char* pStr, int size,
joachim99@8 555 int srcSelect, e_MergeDetails mergeDetails, int rangeMark, bool bUserModified, bool bLineRemoved
joachim99@8 556 );
joachim99@8 557 void setFastSelector(MergeLineList::iterator i);
joachim99@8 558 void convertToLinePos( int x, int y, int& line, int& pos );
joachim99@8 559 virtual void mousePressEvent ( QMouseEvent* e );
joachim99@8 560 virtual void mouseDoubleClickEvent ( QMouseEvent* e );
joachim99@8 561 virtual void mouseReleaseEvent ( QMouseEvent * );
joachim99@8 562 virtual void mouseMoveEvent ( QMouseEvent * );
joachim99@8 563
joachim99@8 564 QPixmap m_pixmap;
joachim99@8 565 int m_firstLine;
joachim99@8 566 int m_firstColumn;
joachim99@8 567 int m_nofColumns;
joachim99@8 568 int m_nofLines;
joachim99@8 569 bool m_bMyUpdate;
joachim99@8 570 bool m_bInsertMode;
joachim99@8 571 QString m_fileName;
joachim99@8 572 bool m_bModified;
joachim99@8 573 void setModified();
joachim99@8 574
joachim99@8 575 int m_scrollDeltaX;
joachim99@8 576 int m_scrollDeltaY;
joachim99@8 577 int m_cursorXPos;
joachim99@8 578 int m_cursorYPos;
joachim99@8 579 int m_cursorOldXPos;
joachim99@8 580 bool m_bCursorOn; // blinking on and off each second
joachim99@8 581 QTimer m_cursorTimer;
joachim99@8 582
joachim99@8 583 Selection m_selection;
joachim99@8 584
joachim99@8 585 bool deleteSelection2( const char*& ps, int& stringLength, int& x, int& y,
joachim99@8 586 MergeLineList::iterator& mlIt, MergeEditLineList::iterator& melIt );
joachim99@8 587 public slots:
joachim99@8 588 void deleteSelection();
joachim99@8 589 void pasteClipboard();
joachim99@8 590 private slots:
joachim99@8 591 void slotCursorUpdate();
joachim99@8 592 };
joachim99@8 593
joachim99@8 594 void fineDiff(
joachim99@8 595 Diff3LineList& diff3LineList,
joachim99@8 596 int selector,
joachim99@8 597 LineData* v1,
joachim99@8 598 LineData* v2,
joachim99@8 599 int maxSearchLength,
joachim99@8 600 bool& bTextsTotalEqual
joachim99@8 601 );
joachim99@8 602
joachim99@8 603
joachim99@8 604 bool equal( const LineData& l1, const LineData& l2, bool bStrict );
joachim99@8 605
joachim99@8 606 inline bool equal( char c1, char c2, bool /*bStrict*/ )
joachim99@8 607 {
joachim99@8 608 // If bStrict then white space doesn't match
joachim99@8 609
joachim99@8 610 //if ( bStrict && ( c1==' ' || c1=='\t' ) )
joachim99@8 611 // return false;
joachim99@8 612
joachim99@8 613 return c1==c2;
joachim99@8 614 }
joachim99@8 615
joachim99@8 616
joachim99@8 617 // My own diff-invention:
joachim99@8 618 template <class T>
joachim99@8 619 void calcDiff( const T* p1, int size1, const T* p2, int size2, DiffList& diffList, int match, int maxSearchRange )
joachim99@8 620 {
joachim99@8 621 diffList.clear();
joachim99@8 622
joachim99@8 623 const T* p1start = p1;
joachim99@8 624 const T* p2start = p2;
joachim99@8 625 const T* p1end=p1+size1;
joachim99@8 626 const T* p2end=p2+size2;
joachim99@8 627 for(;;)
joachim99@8 628 {
joachim99@8 629 int nofEquals = 0;
joachim99@8 630 while( p1!=p1end && p2!=p2end && equal(*p1, *p2, false) )
joachim99@8 631 {
joachim99@8 632
joachim99@8 633
joachim99@8 634 ++p1;
joachim99@8 635 ++p2;
joachim99@8 636 ++nofEquals;
joachim99@8 637 }
joachim99@8 638
joachim99@8 639 bool bBestValid=false;
joachim99@8 640 int bestI1=0;
joachim99@8 641 int bestI2=0;
joachim99@8 642 int i1=0;
joachim99@8 643 int i2=0;
joachim99@8 644 for( i1=0; ; ++i1 )
joachim99@8 645 {
joachim99@8 646 if ( &p1[i1]==p1end || ( bBestValid && i1>= bestI1+bestI2))
joachim99@8 647 {
joachim99@8 648 break;
joachim99@8 649 }
joachim99@8 650 for(i2=0;i2<maxSearchRange;++i2)
joachim99@8 651 {
joachim99@8 652 if( &p2[i2]==p2end || ( bBestValid && i1+i2>=bestI1+bestI2) )
joachim99@8 653 {
joachim99@8 654 break;
joachim99@8 655 }
joachim99@8 656 else if( equal( p2[i2], p1[i1], true ) &&
joachim99@8 657 ( match==1 || abs(i1-i2)<3 || ( &p2[i2+1]==p2end && &p1[i1+1]==p1end ) ||
joachim99@8 658 ( &p2[i2+1]!=p2end && &p1[i1+1]!=p1end && equal( p2[i2+1], p1[i1+1], false ))
joachim99@8 659 )
joachim99@8 660 )
joachim99@8 661 {
joachim99@8 662 if ( i1+i2 < bestI1+bestI2 || bBestValid==false )
joachim99@8 663 {
joachim99@8 664 bestI1 = i1;
joachim99@8 665 bestI2 = i2;
joachim99@8 666 bBestValid = true;
joachim99@8 667 break;
joachim99@8 668 }
joachim99@8 669 }
joachim99@8 670 }
joachim99@8 671 }
joachim99@8 672
joachim99@8 673 // The match was found using the strict search. Go back if there are non-strict
joachim99@8 674 // matches.
joachim99@8 675 while( bestI1>=1 && bestI2>=1 && equal( p1[bestI1-1], p2[bestI2-1], false ) )
joachim99@8 676 {
joachim99@8 677 --bestI1;
joachim99@8 678 --bestI2;
joachim99@8 679 }
joachim99@8 680
joachim99@8 681
joachim99@8 682 bool bEndReached = false;
joachim99@8 683 if (bBestValid)
joachim99@8 684 {
joachim99@8 685 // continue somehow
joachim99@8 686 Diff d(nofEquals, bestI1, bestI2);
joachim99@8 687 diffList.push_back( d );
joachim99@8 688
joachim99@8 689 p1 += bestI1;
joachim99@8 690 p2 += bestI2;
joachim99@8 691 }
joachim99@8 692 else
joachim99@8 693 {
joachim99@8 694 // Nothing else to match.
joachim99@8 695 Diff d(nofEquals, p1end-p1, p2end-p2);
joachim99@8 696 diffList.push_back( d );
joachim99@8 697
joachim99@8 698 bEndReached = true; //break;
joachim99@8 699 }
joachim99@8 700
joachim99@8 701 // Sometimes the algorithm that chooses the first match unfortunately chooses
joachim99@8 702 // a match where later actually equal parts don't match anymore.
joachim99@8 703 // A different match could be achieved, if we start at the end.
joachim99@8 704 // Do it, if it would be a better match.
joachim99@8 705 int nofUnmatched = 0;
joachim99@8 706 const T* pu1 = p1-1;
joachim99@8 707 const T* pu2 = p2-1;
joachim99@8 708 while ( pu1>=p1start && pu2>=p2start && equal( *pu1, *pu2, false ) )
joachim99@8 709 {
joachim99@8 710 ++nofUnmatched;
joachim99@8 711 --pu1;
joachim99@8 712 --pu2;
joachim99@8 713 }
joachim99@8 714
joachim99@8 715 Diff d = diffList.back();
joachim99@8 716 if ( nofUnmatched > 0 )
joachim99@8 717 {
joachim99@8 718 // We want to go backwards the nofUnmatched elements and redo
joachim99@8 719 // the matching
joachim99@8 720 d = diffList.back();
joachim99@8 721 Diff origBack = d;
joachim99@8 722 diffList.pop_back();
joachim99@8 723
joachim99@8 724 while ( nofUnmatched > 0 )
joachim99@8 725 {
joachim99@8 726 if ( d.diff1 > 0 && d.diff2 > 0 )
joachim99@8 727 {
joachim99@8 728 --d.diff1;
joachim99@8 729 --d.diff2;
joachim99@8 730 --nofUnmatched;
joachim99@8 731 }
joachim99@8 732 else if ( d.nofEquals > 0 )
joachim99@8 733 {
joachim99@8 734 --d.nofEquals;
joachim99@8 735 --nofUnmatched;
joachim99@8 736 }
joachim99@8 737
joachim99@8 738 if ( d.nofEquals==0 && (d.diff1==0 || d.diff2==0) && nofUnmatched>0 )
joachim99@8 739 {
joachim99@8 740 if ( diffList.empty() )
joachim99@8 741 break;
joachim99@8 742 d.nofEquals += diffList.back().nofEquals;
joachim99@8 743 d.diff1 += diffList.back().diff1;
joachim99@8 744 d.diff2 += diffList.back().diff2;
joachim99@8 745 diffList.pop_back();
joachim99@8 746 bEndReached = false;
joachim99@8 747 }
joachim99@8 748 }
joachim99@8 749
joachim99@8 750 if ( bEndReached )
joachim99@8 751 diffList.push_back( origBack );
joachim99@8 752 else
joachim99@8 753 {
joachim99@8 754
joachim99@8 755 p1 = pu1 + 1 + nofUnmatched;
joachim99@8 756 p2 = pu2 + 1 + nofUnmatched;
joachim99@8 757 diffList.push_back( d );
joachim99@8 758 }
joachim99@8 759 }
joachim99@8 760 if ( bEndReached )
joachim99@8 761 break;
joachim99@8 762 }
joachim99@8 763
joachim99@8 764 #ifndef NDEBUG
joachim99@8 765 // Verify difflist
joachim99@8 766 {
joachim99@8 767 int l1=0;
joachim99@8 768 int l2=0;
joachim99@8 769 DiffList::iterator i;
joachim99@8 770 for( i = diffList.begin(); i!=diffList.end(); ++i )
joachim99@8 771 {
joachim99@8 772 l1+= i->nofEquals + i->diff1;
joachim99@8 773 l2+= i->nofEquals + i->diff2;
joachim99@8 774 }
joachim99@8 775
joachim99@8 776 //if( l1!=p1-p1start || l2!=p2-p2start )
joachim99@8 777 if( l1!=size1 || l2!=size2 )
joachim99@8 778 assert( false );
joachim99@8 779 }
joachim99@8 780 #endif
joachim99@8 781 }
joachim99@8 782
joachim99@8 783
joachim99@8 784
joachim99@8 785 inline bool isWhite( char c )
joachim99@8 786 {
joachim99@8 787 return c==' ' || c=='\t' || c=='\r';
joachim99@8 788 }
joachim99@8 789
joachim99@8 790 /** Returns the number of equivalent spaces at position outPos.
joachim99@8 791 */
joachim99@8 792 inline int tabber( int outPos, int tabSize )
joachim99@8 793 {
joachim99@8 794 return tabSize - ( outPos % tabSize );
joachim99@8 795 }
joachim99@8 796
joachim99@8 797 /** Returns a line number where the linerange [line, line+nofLines] can
joachim99@8 798 be displayed best. If it fits into the currently visible range then
joachim99@8 799 the returned value is the current firstLine.
joachim99@8 800 */
joachim99@8 801 int getBestFirstLine( int line, int nofLines, int firstLine, int visibleLines );
joachim99@8 802
joachim99@8 803 extern int g_tabSize;
joachim99@8 804 extern bool g_bIgnoreWhiteSpace;
joachim99@8 805 extern bool g_bIgnoreTrivialMatches;
joachim99@8 806 extern int g_bAutoSolve;
joachim99@8 807
joachim99@8 808 // Cursor conversions that consider g_tabSize.
joachim99@8 809 int convertToPosInText( const char* p, int size, int posOnScreen );
joachim99@8 810 int convertToPosOnScreen( const char* p, int posInText );
joachim99@8 811 void calcTokenPos( const char* p, int size, int posOnScreen, int& pos1, int& pos2 );
joachim99@8 812 #endif
joachim99@8 813