annotate kdiff3/src-QT4/diff.h @ 113:7bca1f1340f6 tip

Build fixes for Xcode 10 / Qt 5.12
author Chris Cannam
date Mon, 17 Dec 2018 11:13:01 +0000
parents fcd146072e0c
children
rev   line source
joachim99@8 1 /***************************************************************************
joachim99@8 2 diff.h - description
joachim99@8 3 -------------------
joachim99@8 4 begin : Mon Mar 18 2002
joachim99@77 5 copyright : (C) 2002-2007 by Joachim Eibl
joachim99@69 6 email : joachim.eibl at 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 #ifndef DIFF_H
joachim99@8 19 #define DIFF_H
joachim99@8 20
joachim99@75 21 #include <QPainter>
joachim99@8 22 #include <list>
joachim99@8 23 #include <vector>
joachim99@8 24 #include <assert.h>
joachim99@8 25 #include "common.h"
joachim99@8 26 #include "fileaccess.h"
joachim99@80 27 #include "optiondialog.h"
joachim99@80 28
joachim99@8 29
joachim99@75 30 class OptionDialog;
joachim99@8 31
joachim99@8 32 // Each range with matching elements is followed by a range with differences on either side.
joachim99@8 33 // Then again range of matching elements should follow.
joachim99@8 34 struct Diff
joachim99@8 35 {
joachim99@8 36 int nofEquals;
joachim99@8 37
joachim99@8 38 int diff1;
joachim99@8 39 int diff2;
joachim99@8 40
joachim99@8 41 Diff(int eq, int d1, int d2){nofEquals=eq; diff1=d1; diff2=d2; }
joachim99@8 42 };
joachim99@8 43
joachim99@8 44 typedef std::list<Diff> DiffList;
joachim99@8 45
joachim99@69 46 struct LineData
joachim99@69 47 {
joachim99@69 48 const QChar* pLine;
joachim99@69 49 const QChar* pFirstNonWhiteChar;
joachim99@69 50 int size;
joachim99@69 51
joachim99@69 52 LineData(){ pLine=0; pFirstNonWhiteChar=0; size=0; /*occurances=0;*/ bContainsPureComment=false; }
joachim99@69 53 int width(int tabSize) const; // Calcs width considering tabs.
joachim99@69 54 //int occurances;
joachim99@69 55 bool whiteLine() const { return pFirstNonWhiteChar-pLine == size; }
joachim99@69 56 bool bContainsPureComment;
joachim99@69 57 };
joachim99@69 58
joachim99@69 59 class Diff3LineList;
joachim99@69 60 class Diff3LineVector;
joachim99@69 61
joachim99@69 62 struct DiffBufferInfo
joachim99@69 63 {
joachim99@69 64 const LineData* m_pLineDataA;
joachim99@69 65 const LineData* m_pLineDataB;
joachim99@69 66 const LineData* m_pLineDataC;
joachim99@69 67 int m_sizeA;
joachim99@69 68 int m_sizeB;
joachim99@69 69 int m_sizeC;
joachim99@69 70 const Diff3LineList* m_pDiff3LineList;
joachim99@69 71 const Diff3LineVector* m_pDiff3LineVector;
joachim99@69 72 void init( Diff3LineList* d3ll, const Diff3LineVector* d3lv,
joachim99@69 73 const LineData* pldA, int sizeA, const LineData* pldB, int sizeB, const LineData* pldC, int sizeC );
joachim99@69 74 };
joachim99@69 75
joachim99@8 76 struct Diff3Line
joachim99@8 77 {
joachim99@8 78 int lineA;
joachim99@8 79 int lineB;
joachim99@8 80 int lineC;
joachim99@8 81
joachim99@69 82 bool bAEqC : 1; // These are true if equal or only white-space changes exist.
joachim99@69 83 bool bBEqC : 1;
joachim99@69 84 bool bAEqB : 1;
joachim99@8 85
joachim99@69 86 bool bWhiteLineA : 1;
joachim99@69 87 bool bWhiteLineB : 1;
joachim99@69 88 bool bWhiteLineC : 1;
joachim99@69 89
joachim99@69 90 DiffList* pFineAB; // These are 0 only if completely equal or if either source doesn't exist.
joachim99@8 91 DiffList* pFineBC;
joachim99@8 92 DiffList* pFineCA;
joachim99@8 93
joachim99@66 94 int linesNeededForDisplay; // Due to wordwrap
joachim99@66 95 int sumLinesNeededForDisplay; // For fast conversion to m_diff3WrapLineVector
joachim99@69 96
joachim99@69 97 DiffBufferInfo* m_pDiffBufferInfo; // For convenience
joachim99@69 98
joachim99@8 99 Diff3Line()
joachim99@8 100 {
joachim99@8 101 lineA=-1; lineB=-1; lineC=-1;
joachim99@8 102 bAEqC=false; bAEqB=false; bBEqC=false;
joachim99@8 103 pFineAB=0; pFineBC=0; pFineCA=0;
joachim99@66 104 linesNeededForDisplay=1;
joachim99@69 105 sumLinesNeededForDisplay=0;
joachim99@69 106 bWhiteLineA=false; bWhiteLineB=false; bWhiteLineC=false;
joachim99@69 107 m_pDiffBufferInfo=0;
joachim99@8 108 }
joachim99@8 109
joachim99@8 110 ~Diff3Line()
joachim99@8 111 {
joachim99@8 112 if (pFineAB!=0) delete pFineAB;
joachim99@8 113 if (pFineBC!=0) delete pFineBC;
joachim99@8 114 if (pFineCA!=0) delete pFineCA;
joachim99@8 115 pFineAB=0; pFineBC=0; pFineCA=0;
joachim99@8 116 }
joachim99@8 117
Chris@113 118 bool operator==( const Diff3Line& d3l ) const
joachim99@8 119 {
joachim99@8 120 return lineA == d3l.lineA && lineB == d3l.lineB && lineC == d3l.lineC
joachim99@8 121 && bAEqB == d3l.bAEqB && bAEqC == d3l.bAEqC && bBEqC == d3l.bBEqC;
joachim99@8 122 }
joachim99@69 123
joachim99@69 124 const LineData* getLineData( int src ) const
joachim99@69 125 {
joachim99@69 126 assert( m_pDiffBufferInfo!=0 );
joachim99@69 127 if ( src == 1 && lineA >= 0 ) return &m_pDiffBufferInfo->m_pLineDataA[lineA];
joachim99@69 128 if ( src == 2 && lineB >= 0 ) return &m_pDiffBufferInfo->m_pLineDataB[lineB];
joachim99@69 129 if ( src == 3 && lineC >= 0 ) return &m_pDiffBufferInfo->m_pLineDataC[lineC];
joachim99@69 130 return 0;
joachim99@69 131 }
joachim99@69 132 QString getString( int src ) const
joachim99@69 133 {
joachim99@69 134 const LineData* pld = getLineData(src);
joachim99@69 135 if ( pld )
joachim99@69 136 return QString( pld->pLine, pld->size);
joachim99@69 137 else
joachim99@69 138 return QString();
joachim99@69 139 }
joachim99@69 140 int getLineInFile( int src ) const
joachim99@69 141 {
joachim99@69 142 if ( src == 1 ) return lineA;
joachim99@69 143 if ( src == 2 ) return lineB;
joachim99@69 144 if ( src == 3 ) return lineC;
joachim99@69 145 return -1;
joachim99@69 146 }
joachim99@8 147 };
joachim99@8 148
joachim99@66 149
joachim99@69 150 class Diff3LineList : public std::list<Diff3Line>
joachim99@69 151 {
joachim99@69 152 };
joachim99@69 153 class Diff3LineVector : public std::vector<Diff3Line*>
joachim99@69 154 {
joachim99@69 155 };
joachim99@66 156
joachim99@66 157 class Diff3WrapLine
joachim99@66 158 {
joachim99@66 159 public:
joachim99@66 160 Diff3Line* pD3L;
joachim99@66 161 int diff3LineIndex;
joachim99@66 162 int wrapLineOffset;
joachim99@69 163 int wrapLineLength;
joachim99@66 164 };
joachim99@66 165
joachim99@66 166 typedef std::vector<Diff3WrapLine> Diff3WrapLineVector;
joachim99@66 167
joachim99@8 168
joachim99@8 169 class TotalDiffStatus
joachim99@8 170 {
joachim99@8 171 public:
joachim99@66 172 TotalDiffStatus(){ reset(); }
joachim99@8 173 void reset() {bBinaryAEqC=false; bBinaryBEqC=false; bBinaryAEqB=false;
joachim99@66 174 bTextAEqC=false; bTextBEqC=false; bTextAEqB=false;
joachim99@66 175 nofUnsolvedConflicts=0; nofSolvedConflicts=0;
joachim99@69 176 nofWhitespaceConflicts=0;
joachim99@66 177 }
joachim99@8 178 bool bBinaryAEqC;
joachim99@8 179 bool bBinaryBEqC;
joachim99@8 180 bool bBinaryAEqB;
joachim99@8 181
joachim99@8 182 bool bTextAEqC;
joachim99@8 183 bool bTextBEqC;
joachim99@8 184 bool bTextAEqB;
joachim99@69 185
joachim99@66 186 int nofUnsolvedConflicts;
joachim99@66 187 int nofSolvedConflicts;
joachim99@66 188 int nofWhitespaceConflicts;
joachim99@8 189 };
joachim99@8 190
joachim99@69 191 // Three corresponding ranges. (Minimum size of a valid range is one line.)
joachim99@69 192 class ManualDiffHelpEntry
joachim99@69 193 {
joachim99@69 194 public:
joachim99@69 195 ManualDiffHelpEntry() { lineA1=-1; lineA2=-1;
joachim99@69 196 lineB1=-1; lineB2=-1;
joachim99@69 197 lineC1=-1; lineC2=-1; }
joachim99@69 198 int lineA1;
joachim99@69 199 int lineA2;
joachim99@69 200 int lineB1;
joachim99@69 201 int lineB2;
joachim99@69 202 int lineC1;
joachim99@69 203 int lineC2;
joachim99@69 204 int& firstLine( int winIdx )
joachim99@69 205 {
joachim99@69 206 return winIdx==1 ? lineA1 : (winIdx==2 ? lineB1 : lineC1 );
joachim99@69 207 }
joachim99@69 208 int& lastLine( int winIdx )
joachim99@69 209 {
joachim99@69 210 return winIdx==1 ? lineA2 : (winIdx==2 ? lineB2 : lineC2 );
joachim99@69 211 }
joachim99@69 212 bool isLineInRange( int line, int winIdx )
joachim99@69 213 {
joachim99@69 214 return line>=0 && line>=firstLine(winIdx) && line<=lastLine(winIdx);
joachim99@69 215 }
joachim99@69 216 bool operator==(const ManualDiffHelpEntry& r) const
joachim99@69 217 {
joachim99@69 218 return lineA1 == r.lineA1 && lineB1 == r.lineB1 && lineC1 == r.lineC1 &&
joachim99@69 219 lineA2 == r.lineA2 && lineB2 == r.lineB2 && lineC2 == r.lineC2;
joachim99@69 220 }
joachim99@69 221 };
joachim99@69 222
joachim99@69 223 // A list of corresponding ranges
joachim99@69 224 typedef std::list<ManualDiffHelpEntry> ManualDiffHelpList;
joachim99@69 225
joachim99@51 226 void calcDiff3LineListUsingAB(
joachim99@8 227 const DiffList* pDiffListAB,
joachim99@8 228 Diff3LineList& d3ll
joachim99@8 229 );
joachim99@8 230
joachim99@8 231 void calcDiff3LineListUsingAC(
joachim99@8 232 const DiffList* pDiffListBC,
joachim99@8 233 Diff3LineList& d3ll
joachim99@8 234 );
joachim99@8 235
joachim99@68 236 void calcDiff3LineListUsingBC(
joachim99@8 237 const DiffList* pDiffListBC,
joachim99@8 238 Diff3LineList& d3ll
joachim99@8 239 );
joachim99@8 240
joachim99@69 241 void correctManualDiffAlignment( Diff3LineList& d3ll, ManualDiffHelpList* pManualDiffHelpList );
joachim99@8 242
joachim99@8 243 class SourceData
joachim99@8 244 {
joachim99@8 245 public:
joachim99@58 246 SourceData();
joachim99@58 247 ~SourceData();
joachim99@68 248
joachim99@58 249 void setOptionDialog( OptionDialog* pOptionDialog );
joachim99@68 250
joachim99@58 251 int getSizeLines() const;
joachim99@58 252 int getSizeBytes() const;
joachim99@58 253 const char* getBuf() const;
joachim99@58 254 const LineData* getLineDataForDisplay() const;
joachim99@58 255 const LineData* getLineDataForDiff() const;
joachim99@58 256
joachim99@8 257 void setFilename(const QString& filename);
joachim99@8 258 void setFileAccess( const FileAccess& fa );
joachim99@75 259 //FileAccess& getFileAccess();
joachim99@8 260 QString getFilename();
joachim99@8 261 void setAliasName(const QString& a);
joachim99@8 262 QString getAliasName();
joachim99@58 263 bool isEmpty(); // File was set
joachim99@58 264 bool hasData(); // Data was readable
joachim99@58 265 bool isText(); // is it pure text (vs. binary data)
joachim99@58 266 bool isFromBuffer(); // was it set via setData() (vs. setFileAccess() or setFilename())
joachim99@58 267 void setData( const QString& data );
joachim99@66 268 bool isValid(); // Either no file is specified or reading was successful
joachim99@68 269
joachim99@75 270 void readAndPreprocess(QTextCodec* pEncoding, bool bAutoDetectUnicode );
joachim99@58 271 bool saveNormalDataAs( const QString& fileName );
joachim99@68 272
joachim99@58 273 bool isBinaryEqualWith( const SourceData& other ) const;
joachim99@68 274
joachim99@58 275 void reset();
joachim99@58 276
joachim99@75 277 QTextCodec* getEncoding() const { return m_pEncoding; }
joachim99@80 278 e_LineEndStyle getLineEndStyle() const { return m_normalData.m_eLineEndStyle; }
joachim99@75 279
joachim99@68 280 private:
joachim99@75 281 QTextCodec* detectEncoding( const QString& fileName, QTextCodec* pFallbackCodec );
joachim99@8 282 QString m_aliasName;
joachim99@8 283 FileAccess m_fileAccess;
joachim99@58 284 OptionDialog* m_pOptionDialog;
joachim99@58 285 QString m_tempInputFileName;
joachim99@58 286
joachim99@58 287 struct FileData
joachim99@68 288 {
joachim99@80 289 FileData(){ m_pBuf=0; m_size=0; m_vSize=0; m_bIsText=false; m_eLineEndStyle=eLineEndStyleUndefined; }
joachim99@58 290 ~FileData(){ reset(); }
joachim99@58 291 const char* m_pBuf;
joachim99@58 292 int m_size;
joachim99@58 293 int m_vSize; // Nr of lines in m_pBuf1 and size of m_v1, m_dv12 and m_dv13
joachim99@68 294 QString m_unicodeBuf;
joachim99@58 295 std::vector<LineData> m_v;
joachim99@58 296 bool m_bIsText;
joachim99@80 297 e_LineEndStyle m_eLineEndStyle;
joachim99@58 298 bool readFile( const QString& filename );
joachim99@58 299 bool writeFile( const QString& filename );
joachim99@68 300 void preprocess(bool bPreserveCR, QTextCodec* pEncoding );
joachim99@58 301 void reset();
joachim99@58 302 void removeComments();
joachim99@58 303 void copyBufFrom( const FileData& src );
joachim99@58 304 };
joachim99@58 305 FileData m_normalData;
joachim99@68 306 FileData m_lmppData;
joachim99@68 307 QTextCodec* m_pEncoding;
joachim99@8 308 };
joachim99@8 309
joachim99@69 310 void calcDiff3LineListTrim( Diff3LineList& d3ll, const LineData* pldA, const LineData* pldB, const LineData* pldC, ManualDiffHelpList* pManualDiffHelpList );
joachim99@58 311 void calcWhiteDiff3Lines( Diff3LineList& d3ll, const LineData* pldA, const LineData* pldB, const LineData* pldC );
joachim99@8 312
joachim99@66 313 void calcDiff3LineVector( Diff3LineList& d3ll, Diff3LineVector& d3lv );
joachim99@8 314
joachim99@8 315 void debugLineCheck( Diff3LineList& d3ll, int size, int idx );
joachim99@8 316
joachim99@8 317
joachim99@8 318
joachim99@8 319 class Selection
joachim99@8 320 {
joachim99@8 321 public:
joachim99@8 322 Selection(){ reset(); oldLastLine=-1; lastLine=-1; oldFirstLine=-1; }
joachim99@8 323 int firstLine;
joachim99@8 324 int firstPos;
joachim99@8 325 int lastLine;
joachim99@8 326 int lastPos;
joachim99@8 327 int oldLastLine;
joachim99@8 328 int oldFirstLine;
joachim99@8 329 bool bSelectionContainsData;
joachim99@8 330 bool isEmpty() { return firstLine==-1 || (firstLine==lastLine && firstPos==lastPos) || bSelectionContainsData==false;}
joachim99@8 331 void reset(){
joachim99@8 332 oldFirstLine=firstLine;
joachim99@8 333 oldLastLine =lastLine;
joachim99@8 334 firstLine=-1;
joachim99@69 335 lastLine=-1;
joachim99@8 336 bSelectionContainsData = false;
joachim99@8 337 }
joachim99@8 338 void start( int l, int p ) { firstLine = l; firstPos = p; }
joachim99@8 339 void end( int l, int p ) {
joachim99@8 340 if ( oldLastLine == -1 )
joachim99@8 341 oldLastLine = lastLine;
joachim99@8 342 lastLine = l;
joachim99@8 343 lastPos = p;
joachim99@8 344 }
joachim99@8 345 bool within( int l, int p );
joachim99@8 346
joachim99@8 347 bool lineWithin( int l );
joachim99@8 348 int firstPosInLine(int l);
joachim99@8 349 int lastPosInLine(int l);
joachim99@69 350 int beginLine(){
joachim99@69 351 if (firstLine<0 && lastLine<0) return -1;
joachim99@69 352 return max2(0,min2(firstLine,lastLine));
joachim99@69 353 }
joachim99@69 354 int endLine(){
joachim99@69 355 if (firstLine<0 && lastLine<0) return -1;
joachim99@69 356 return max2(firstLine,lastLine);
joachim99@69 357 }
joachim99@8 358 int beginPos() { return firstLine==lastLine ? min2(firstPos,lastPos) :
joachim99@69 359 firstLine<lastLine ? (firstLine<0?0:firstPos) : (lastLine<0?0:lastPos); }
joachim99@8 360 int endPos() { return firstLine==lastLine ? max2(firstPos,lastPos) :
joachim99@8 361 firstLine<lastLine ? lastPos : firstPos; }
joachim99@8 362 };
joachim99@8 363
joachim99@8 364 class OptionDialog;
joachim99@8 365
joachim99@68 366
joachim99@68 367 // Helper class that swaps left and right for some commands.
joachim99@68 368 class MyPainter : public QPainter
joachim99@68 369 {
joachim99@68 370 int m_factor;
joachim99@68 371 int m_xOffset;
joachim99@68 372 int m_fontWidth;
joachim99@68 373 public:
joachim99@70 374 MyPainter(QPaintDevice* pd, bool bRTL, int width, int fontWidth)
joachim99@69 375 : QPainter(pd)
joachim99@68 376 {
joachim99@68 377 if (bRTL)
joachim99@68 378 {
joachim99@68 379 m_fontWidth = fontWidth;
joachim99@68 380 m_factor = -1;
joachim99@68 381 m_xOffset = width-1;
joachim99@68 382 }
joachim99@68 383 else
joachim99@68 384 {
joachim99@68 385 m_fontWidth = 0;
joachim99@68 386 m_factor = 1;
joachim99@68 387 m_xOffset = 0;
joachim99@68 388 }
joachim99@68 389 }
joachim99@68 390
joachim99@68 391 void fillRect( int x, int y, int w, int h, const QBrush& b )
joachim99@68 392 {
joachim99@69 393 if (m_factor==1)
joachim99@69 394 QPainter::fillRect( m_xOffset + x , y, w, h, b );
joachim99@69 395 else
joachim99@69 396 QPainter::fillRect( m_xOffset - x - w, y, w, h, b );
joachim99@68 397 }
joachim99@68 398
joachim99@68 399 void drawText( int x, int y, const QString& s, bool bAdapt=false )
joachim99@68 400 {
joachim99@70 401 Qt::LayoutDirection ld = (m_factor==1 || bAdapt == false) ? Qt::LeftToRight : Qt::RightToLeft;
joachim99@80 402 //QPainter::setLayoutDirection( ld );
joachim99@80 403 if ( ld==Qt::RightToLeft ) // Reverse the text
joachim99@80 404 {
joachim99@80 405 QString s2;
joachim99@80 406 for( int i=s.length()-1; i>=0; --i )
joachim99@80 407 {
joachim99@80 408 s2 += s[i];
joachim99@80 409 }
joachim99@80 410 QPainter::drawText( m_xOffset-m_fontWidth*s.length() + m_factor*x, y, s2 );
joachim99@80 411 return;
joachim99@80 412 }
joachim99@75 413 QPainter::drawText( m_xOffset-m_fontWidth*s.length() + m_factor*x, y, s );
joachim99@68 414 }
joachim99@68 415
joachim99@68 416 void drawLine( int x1, int y1, int x2, int y2 )
joachim99@68 417 {
joachim99@68 418 QPainter::drawLine( m_xOffset + m_factor*x1, y1, m_xOffset + m_factor*x2, y2 );
joachim99@68 419 }
joachim99@68 420 };
joachim99@51 421
joachim99@8 422 void fineDiff(
joachim99@8 423 Diff3LineList& diff3LineList,
joachim99@8 424 int selector,
joachim99@58 425 const LineData* v1,
joachim99@58 426 const LineData* v2,
joachim99@8 427 bool& bTextsTotalEqual
joachim99@8 428 );
joachim99@8 429
joachim99@8 430
joachim99@8 431 bool equal( const LineData& l1, const LineData& l2, bool bStrict );
joachim99@8 432
joachim99@8 433
joachim99@8 434
joachim99@8 435
joachim99@68 436 inline bool isWhite( QChar c )
joachim99@8 437 {
joachim99@8 438 return c==' ' || c=='\t' || c=='\r';
joachim99@8 439 }
joachim99@8 440
joachim99@8 441 /** Returns the number of equivalent spaces at position outPos.
joachim99@8 442 */
joachim99@8 443 inline int tabber( int outPos, int tabSize )
joachim99@8 444 {
joachim99@8 445 return tabSize - ( outPos % tabSize );
joachim99@8 446 }
joachim99@8 447
joachim99@8 448 /** Returns a line number where the linerange [line, line+nofLines] can
joachim99@8 449 be displayed best. If it fits into the currently visible range then
joachim99@8 450 the returned value is the current firstLine.
joachim99@8 451 */
joachim99@8 452 int getBestFirstLine( int line, int nofLines, int firstLine, int visibleLines );
joachim99@8 453
joachim99@8 454 extern bool g_bIgnoreWhiteSpace;
joachim99@8 455 extern bool g_bIgnoreTrivialMatches;
joachim99@8 456 extern int g_bAutoSolve;
joachim99@8 457
joachim99@8 458 // Cursor conversions that consider g_tabSize.
joachim99@69 459 int convertToPosInText( const QString& s, int posOnScreen, int tabSize );
joachim99@69 460 int convertToPosOnScreen( const QString& s, int posInText, int tabSize );
joachim99@69 461
joachim99@69 462 enum e_CoordType { eFileCoords, eD3LLineCoords, eWrapCoords };
joachim99@69 463
joachim99@69 464 void calcTokenPos( const QString&, int posOnScreen, int& pos1, int& pos2, int tabSize );
joachim99@69 465
joachim99@69 466 QString calcHistorySortKey( const QString& keyOrder, QRegExp& matchedRegExpr, const QStringList& parenthesesGroupList );
joachim99@69 467 bool findParenthesesGroups( const QString& s, QStringList& sl );
joachim99@8 468 #endif
joachim99@8 469