diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-10 01:27:27 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-10 01:27:27 +0000 |
commit | 76718abdb2138623102398a10f3228e576dd0ae8 (patch) | |
tree | ddb098baac9689b9e661a41c2a28a8a23ef246d4 /src/diff.h | |
download | kdiff3-76718abdb2138623102398a10f3228e576dd0ae8.tar.gz kdiff3-76718abdb2138623102398a10f3228e576dd0ae8.zip |
Added abandoned KDE3 version of kdiff3
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kdiff3@1088041 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/diff.h')
-rw-r--r-- | src/diff.h | 462 |
1 files changed, 462 insertions, 0 deletions
diff --git a/src/diff.h b/src/diff.h new file mode 100644 index 0000000..1101752 --- /dev/null +++ b/src/diff.h @@ -0,0 +1,462 @@ +/*************************************************************************** + diff.h - description + ------------------- + begin : Mon Mar 18 2002 + copyright : (C) 2002-2007 by Joachim Eibl + email : joachim.eibl at gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef DIFF_H +#define DIFF_H + +#include <qwidget.h> +#include <qpixmap.h> +#include <qtimer.h> +#include <qframe.h> +#include <qtextstream.h> +#include <qpainter.h> +#include <list> +#include <vector> +#include <assert.h> +#include "common.h" +#include "fileaccess.h" + +class OptionDialog; + +// Each range with matching elements is followed by a range with differences on either side. +// Then again range of matching elements should follow. +struct Diff +{ + int nofEquals; + + int diff1; + int diff2; + + Diff(int eq, int d1, int d2){nofEquals=eq; diff1=d1; diff2=d2; } +}; + +typedef std::list<Diff> DiffList; + +struct LineData +{ + const QChar* pLine; + const QChar* pFirstNonWhiteChar; + int size; + + LineData(){ pLine=0; pFirstNonWhiteChar=0; size=0; /*occurances=0;*/ bContainsPureComment=false; } + int width(int tabSize) const; // Calcs width considering tabs. + //int occurances; + bool whiteLine() const { return pFirstNonWhiteChar-pLine == size; } + bool bContainsPureComment; +}; + +class Diff3LineList; +class Diff3LineVector; + +struct DiffBufferInfo +{ + const LineData* m_pLineDataA; + const LineData* m_pLineDataB; + const LineData* m_pLineDataC; + int m_sizeA; + int m_sizeB; + int m_sizeC; + const Diff3LineList* m_pDiff3LineList; + const Diff3LineVector* m_pDiff3LineVector; + void init( Diff3LineList* d3ll, const Diff3LineVector* d3lv, + const LineData* pldA, int sizeA, const LineData* pldB, int sizeB, const LineData* pldC, int sizeC ); +}; + +struct Diff3Line +{ + int lineA; + int lineB; + int lineC; + + bool bAEqC : 1; // These are true if equal or only white-space changes exist. + bool bBEqC : 1; + bool bAEqB : 1; + + bool bWhiteLineA : 1; + bool bWhiteLineB : 1; + bool bWhiteLineC : 1; + + DiffList* pFineAB; // These are 0 only if completely equal or if either source doesn't exist. + DiffList* pFineBC; + DiffList* pFineCA; + + int linesNeededForDisplay; // Due to wordwrap + int sumLinesNeededForDisplay; // For fast conversion to m_diff3WrapLineVector + + DiffBufferInfo* m_pDiffBufferInfo; // For convenience + + Diff3Line() + { + lineA=-1; lineB=-1; lineC=-1; + bAEqC=false; bAEqB=false; bBEqC=false; + pFineAB=0; pFineBC=0; pFineCA=0; + linesNeededForDisplay=1; + sumLinesNeededForDisplay=0; + bWhiteLineA=false; bWhiteLineB=false; bWhiteLineC=false; + m_pDiffBufferInfo=0; + } + + ~Diff3Line() + { + if (pFineAB!=0) delete pFineAB; + if (pFineBC!=0) delete pFineBC; + if (pFineCA!=0) delete pFineCA; + pFineAB=0; pFineBC=0; pFineCA=0; + } + + bool operator==( const Diff3Line& d3l ) + { + return lineA == d3l.lineA && lineB == d3l.lineB && lineC == d3l.lineC + && bAEqB == d3l.bAEqB && bAEqC == d3l.bAEqC && bBEqC == d3l.bBEqC; + } + + const LineData* getLineData( int src ) const + { + assert( m_pDiffBufferInfo!=0 ); + if ( src == 1 && lineA >= 0 ) return &m_pDiffBufferInfo->m_pLineDataA[lineA]; + if ( src == 2 && lineB >= 0 ) return &m_pDiffBufferInfo->m_pLineDataB[lineB]; + if ( src == 3 && lineC >= 0 ) return &m_pDiffBufferInfo->m_pLineDataC[lineC]; + return 0; + } + QString getString( int src ) const + { + const LineData* pld = getLineData(src); + if ( pld ) + return QString( pld->pLine, pld->size); + else + return QString(); + } + int getLineInFile( int src ) const + { + if ( src == 1 ) return lineA; + if ( src == 2 ) return lineB; + if ( src == 3 ) return lineC; + return -1; + } +}; + + +class Diff3LineList : public std::list<Diff3Line> +{ +}; +class Diff3LineVector : public std::vector<Diff3Line*> +{ +}; + +class Diff3WrapLine +{ +public: + Diff3Line* pD3L; + int diff3LineIndex; + int wrapLineOffset; + int wrapLineLength; +}; + +typedef std::vector<Diff3WrapLine> Diff3WrapLineVector; + + +class TotalDiffStatus +{ +public: + TotalDiffStatus(){ reset(); } + void reset() {bBinaryAEqC=false; bBinaryBEqC=false; bBinaryAEqB=false; + bTextAEqC=false; bTextBEqC=false; bTextAEqB=false; + nofUnsolvedConflicts=0; nofSolvedConflicts=0; + nofWhitespaceConflicts=0; + } + bool bBinaryAEqC; + bool bBinaryBEqC; + bool bBinaryAEqB; + + bool bTextAEqC; + bool bTextBEqC; + bool bTextAEqB; + + int nofUnsolvedConflicts; + int nofSolvedConflicts; + int nofWhitespaceConflicts; +}; + +// Three corresponding ranges. (Minimum size of a valid range is one line.) +class ManualDiffHelpEntry +{ +public: + ManualDiffHelpEntry() { lineA1=-1; lineA2=-1; + lineB1=-1; lineB2=-1; + lineC1=-1; lineC2=-1; } + int lineA1; + int lineA2; + int lineB1; + int lineB2; + int lineC1; + int lineC2; + int& firstLine( int winIdx ) + { + return winIdx==1 ? lineA1 : (winIdx==2 ? lineB1 : lineC1 ); + } + int& lastLine( int winIdx ) + { + return winIdx==1 ? lineA2 : (winIdx==2 ? lineB2 : lineC2 ); + } + bool isLineInRange( int line, int winIdx ) + { + return line>=0 && line>=firstLine(winIdx) && line<=lastLine(winIdx); + } + bool operator==(const ManualDiffHelpEntry& r) const + { + return lineA1 == r.lineA1 && lineB1 == r.lineB1 && lineC1 == r.lineC1 && + lineA2 == r.lineA2 && lineB2 == r.lineB2 && lineC2 == r.lineC2; + } +}; + +// A list of corresponding ranges +typedef std::list<ManualDiffHelpEntry> ManualDiffHelpList; + +void calcDiff3LineListUsingAB( + const DiffList* pDiffListAB, + Diff3LineList& d3ll + ); + +void calcDiff3LineListUsingAC( + const DiffList* pDiffListBC, + Diff3LineList& d3ll + ); + +void calcDiff3LineListUsingBC( + const DiffList* pDiffListBC, + Diff3LineList& d3ll + ); + +void correctManualDiffAlignment( Diff3LineList& d3ll, ManualDiffHelpList* pManualDiffHelpList ); + +class SourceData +{ +public: + SourceData(); + ~SourceData(); + + void setOptionDialog( OptionDialog* pOptionDialog ); + + int getSizeLines() const; + int getSizeBytes() const; + const char* getBuf() const; + const LineData* getLineDataForDisplay() const; + const LineData* getLineDataForDiff() const; + + void setFilename(const QString& filename); + void setFileAccess( const FileAccess& fa ); + //FileAccess& getFileAccess(); + QString getFilename(); + void setAliasName(const QString& a); + QString getAliasName(); + bool isEmpty(); // File was set + bool hasData(); // Data was readable + bool isText(); // is it pure text (vs. binary data) + bool isFromBuffer(); // was it set via setData() (vs. setFileAccess() or setFilename()) + void setData( const QString& data ); + bool isValid(); // Either no file is specified or reading was successful + + void readAndPreprocess(QTextCodec* pEncoding, bool bAutoDetectUnicode ); + bool saveNormalDataAs( const QString& fileName ); + + bool isBinaryEqualWith( const SourceData& other ) const; + + void reset(); + + QTextCodec* getEncoding() const { return m_pEncoding; } + +private: + QTextCodec* detectEncoding( const QString& fileName, QTextCodec* pFallbackCodec ); + QString m_aliasName; + FileAccess m_fileAccess; + OptionDialog* m_pOptionDialog; + QString m_tempInputFileName; + + struct FileData + { + FileData(){ m_pBuf=0; m_size=0; m_vSize=0; m_bIsText=false; } + ~FileData(){ reset(); } + const char* m_pBuf; + int m_size; + int m_vSize; // Nr of lines in m_pBuf1 and size of m_v1, m_dv12 and m_dv13 + QString m_unicodeBuf; + std::vector<LineData> m_v; + bool m_bIsText; + bool readFile( const QString& filename ); + bool writeFile( const QString& filename ); + void preprocess(bool bPreserveCR, QTextCodec* pEncoding ); + void reset(); + void removeComments(); + void copyBufFrom( const FileData& src ); + }; + FileData m_normalData; + FileData m_lmppData; + QTextCodec* m_pEncoding; +}; + +void calcDiff3LineListTrim( Diff3LineList& d3ll, const LineData* pldA, const LineData* pldB, const LineData* pldC, ManualDiffHelpList* pManualDiffHelpList ); +void calcWhiteDiff3Lines( Diff3LineList& d3ll, const LineData* pldA, const LineData* pldB, const LineData* pldC ); + +void calcDiff3LineVector( Diff3LineList& d3ll, Diff3LineVector& d3lv ); + +void debugLineCheck( Diff3LineList& d3ll, int size, int idx ); + +class QStatusBar; + + +class Selection +{ +public: + Selection(){ reset(); oldLastLine=-1; lastLine=-1; oldFirstLine=-1; } + int firstLine; + int firstPos; + int lastLine; + int lastPos; + int oldLastLine; + int oldFirstLine; + bool bSelectionContainsData; + bool isEmpty() { return firstLine==-1 || (firstLine==lastLine && firstPos==lastPos) || bSelectionContainsData==false;} + void reset(){ + oldFirstLine=firstLine; + oldLastLine =lastLine; + firstLine=-1; + lastLine=-1; + bSelectionContainsData = false; + } + void start( int l, int p ) { firstLine = l; firstPos = p; } + void end( int l, int p ) { + if ( oldLastLine == -1 ) + oldLastLine = lastLine; + lastLine = l; + lastPos = p; + } + bool within( int l, int p ); + + bool lineWithin( int l ); + int firstPosInLine(int l); + int lastPosInLine(int l); + int beginLine(){ + if (firstLine<0 && lastLine<0) return -1; + return max2(0,min2(firstLine,lastLine)); + } + int endLine(){ + if (firstLine<0 && lastLine<0) return -1; + return max2(firstLine,lastLine); + } + int beginPos() { return firstLine==lastLine ? min2(firstPos,lastPos) : + firstLine<lastLine ? (firstLine<0?0:firstPos) : (lastLine<0?0:lastPos); } + int endPos() { return firstLine==lastLine ? max2(firstPos,lastPos) : + firstLine<lastLine ? lastPos : firstPos; } +}; + +class OptionDialog; + +QCString encodeString( const QString& s ); + + +// Helper class that swaps left and right for some commands. +class MyPainter : public QPainter +{ + int m_factor; + int m_xOffset; + int m_fontWidth; +public: + MyPainter(const QPaintDevice* pd, bool bRTL, int width, int fontWidth) + : QPainter(pd) + { + if (bRTL) + { + m_fontWidth = fontWidth; + m_factor = -1; + m_xOffset = width-1; + } + else + { + m_fontWidth = 0; + m_factor = 1; + m_xOffset = 0; + } + } + + void fillRect( int x, int y, int w, int h, const QBrush& b ) + { + if (m_factor==1) + QPainter::fillRect( m_xOffset + x , y, w, h, b ); + else + QPainter::fillRect( m_xOffset - x - w, y, w, h, b ); + } + + void drawText( int x, int y, const QString& s, bool bAdapt=false ) + { + TextDirection td = (m_factor==1 || bAdapt == false) ? LTR : RTL; + QPainter::drawText( m_xOffset-m_fontWidth*s.length() + m_factor*x, y, s, -1, td ); + } + + void drawLine( int x1, int y1, int x2, int y2 ) + { + QPainter::drawLine( m_xOffset + m_factor*x1, y1, m_xOffset + m_factor*x2, y2 ); + } +}; + +void fineDiff( + Diff3LineList& diff3LineList, + int selector, + const LineData* v1, + const LineData* v2, + bool& bTextsTotalEqual + ); + + +bool equal( const LineData& l1, const LineData& l2, bool bStrict ); + + + + +inline bool isWhite( QChar c ) +{ + return c==' ' || c=='\t' || c=='\r'; +} + +/** Returns the number of equivalent spaces at position outPos. +*/ +inline int tabber( int outPos, int tabSize ) +{ + return tabSize - ( outPos % tabSize ); +} + +/** Returns a line number where the linerange [line, line+nofLines] can + be displayed best. If it fits into the currently visible range then + the returned value is the current firstLine. +*/ +int getBestFirstLine( int line, int nofLines, int firstLine, int visibleLines ); + +extern bool g_bIgnoreWhiteSpace; +extern bool g_bIgnoreTrivialMatches; +extern int g_bAutoSolve; + +// Cursor conversions that consider g_tabSize. +int convertToPosInText( const QString& s, int posOnScreen, int tabSize ); +int convertToPosOnScreen( const QString& s, int posInText, int tabSize ); + +enum e_CoordType { eFileCoords, eD3LLineCoords, eWrapCoords }; + +void calcTokenPos( const QString&, int posOnScreen, int& pos1, int& pos2, int tabSize ); + +QString calcHistorySortKey( const QString& keyOrder, QRegExp& matchedRegExpr, const QStringList& parenthesesGroupList ); +bool findParenthesesGroups( const QString& s, QStringList& sl ); +#endif + |