File indexing completed on 2024-04-28 17:01:39

0001 /*
0002 SPDX-FileCopyrightText: 2001-2004,2009 Otto Bruggeman <bruggie@gmail.com>
0003 SPDX-FileCopyrightText: 2001-2003 John Firebaugh <jfirebaugh@kde.org>
0004 
0005 SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef KOMPAREDIFF2_DIFFERENCE_H
0009 #define KOMPAREDIFF2_DIFFERENCE_H
0010 
0011 #include <QVector>
0012 #include <QObject>
0013 
0014 #include "komparediff2_export.h"
0015 #include "marker.h"
0016 
0017 // #include <komparediffdebug.h>
0018 
0019 class QString;
0020 
0021 namespace Diff2
0022 {
0023 
0024 /**
0025  * @class DifferenceString difference.h <KompareDiff2/Difference>
0026  *
0027  * A difference string.
0028  */
0029 class KOMPAREDIFF2_EXPORT DifferenceString
0030 {
0031 public:
0032     DifferenceString()
0033     {
0034 //         qCDebug(LIBKOMPAREDIFF2) << "DifferenceString::DifferenceString()";
0035     }
0036     explicit DifferenceString(const QString& string, const MarkerList& markerList = MarkerList()) :
0037         m_string(string),
0038         m_markerList(markerList)
0039     {
0040 //         qCDebug(LIBKOMPAREDIFF2) << "DifferenceString::DifferenceString( " << string << ", " << markerList << " )";
0041         calculateHash();
0042     }
0043     DifferenceString(const DifferenceString& ds) :
0044         m_string(ds.m_string),
0045         m_conflict(ds.m_conflict),
0046         m_hash(ds.m_hash),
0047         m_markerList(ds.m_markerList)
0048     {
0049 //         qCDebug(LIBKOMPAREDIFF2) << "DifferenceString::DifferenceString( const DifferenceString& " << ds << " )";
0050     }
0051     ~DifferenceString()
0052     {
0053         qDeleteAll(m_markerList);
0054     }
0055 
0056 public:
0057     const QString& string() const
0058     {
0059         return m_string;
0060     }
0061     const QString& conflictString() const
0062     {
0063         return m_conflict;
0064     }
0065     const MarkerList& markerList()
0066     {
0067         return m_markerList;
0068     }
0069     void setString(const QString& string)
0070     {
0071         m_string = string;
0072         calculateHash();
0073     }
0074     void setConflictString(const QString& conflict)
0075     {
0076         m_conflict = conflict;
0077     }
0078     void setMarkerList(const MarkerList& markerList)
0079     {
0080         m_markerList = markerList;
0081     }
0082     void prepend(Marker* marker)
0083     {
0084         m_markerList.prepend(marker);
0085     }
0086     bool operator==(const DifferenceString& ks)
0087     {
0088         if (m_hash != ks.m_hash)
0089             return false;
0090         return m_string == ks.m_string;
0091     }
0092 
0093 protected:
0094     void calculateHash()
0095     {
0096         unsigned short const* str = reinterpret_cast<unsigned short const*>(m_string.unicode());
0097         const unsigned int len = m_string.length();
0098 
0099         m_hash = 1315423911;
0100 
0101         for (unsigned int i = 0; i < len; ++i)
0102         {
0103             m_hash ^= (m_hash << 5) + str[i] + (m_hash >> 2);
0104         }
0105     }
0106 
0107 private:
0108     QString      m_string;
0109     QString      m_conflict;
0110     unsigned int m_hash;
0111     MarkerList   m_markerList;
0112 };
0113 
0114 using DifferenceStringList =              QVector<DifferenceString*>;
0115 using DifferenceStringListIterator =      QVector<DifferenceString*>::iterator;
0116 using DifferenceStringListConstIterator = QVector<DifferenceString*>::const_iterator;
0117 
0118 /**
0119  * @class Difference difference.h <KompareDiff2/Difference>
0120  *
0121  * A difference.
0122  */
0123 class KOMPAREDIFF2_EXPORT Difference : public QObject
0124 {
0125     Q_OBJECT
0126 public:
0127     enum Type { Change, Insert, Delete, Unchanged };
0128 
0129 public:
0130     Difference(int sourceLineNo, int destinationLineNo, int type = Difference::Unchanged);
0131     ~Difference() override;
0132 
0133 public:
0134     int type() const { return m_type; };
0135 
0136     int sourceLineNumber() const { return m_sourceLineNo; }
0137     int destinationLineNumber() const { return m_destinationLineNo; }
0138 
0139     int sourceLineCount() const;
0140     int destinationLineCount() const;
0141 
0142     int sourceLineEnd() const;
0143     int destinationLineEnd() const;
0144 
0145     /// Destination line number that tracks applying/unapplying of other differences
0146     /// Essentially a line number in a patch consisting of applied diffs only
0147     int trackingDestinationLineNumber() const { return m_trackingDestinationLineNo; }
0148     int trackingDestinationLineEnd() const;
0149     void setTrackingDestinationLineNumber(int i) { m_trackingDestinationLineNo = i; }
0150 
0151     DifferenceString* sourceLineAt(int i) const { return m_sourceLines[i]; }
0152     DifferenceString* destinationLineAt(int i) const { return m_destinationLines[i]; }
0153 
0154     const DifferenceStringList sourceLines() const { return m_sourceLines; }
0155     const DifferenceStringList destinationLines() const { return m_destinationLines; }
0156 
0157     bool hasConflict() const
0158     {
0159         return m_conflicts;
0160     }
0161     void setConflict(bool conflicts)
0162     {
0163         m_conflicts = conflicts;
0164     }
0165 
0166     bool isUnsaved() const
0167     {
0168         return m_unsaved;
0169     }
0170     void setUnsaved(bool unsaved)
0171     {
0172         m_unsaved = unsaved;
0173     }
0174 
0175     void apply(bool apply);
0176     /// Apply without emitting any signals
0177     void applyQuietly(bool apply);
0178     bool applied() const { return m_applied; }
0179 
0180     void setType(int type) { m_type = type; }
0181 
0182     void addSourceLine(QString line);
0183     void addDestinationLine(QString line);
0184 
0185     /** This method will calculate the differences between the individual strings and store them as Markers */
0186     void determineInlineDifferences();
0187 
0188     QString recreateDifference() const;
0189 
0190 Q_SIGNALS:
0191     void differenceApplied(Difference*);
0192 
0193 private:
0194     int                   m_type;
0195 
0196     int                   m_sourceLineNo;
0197     int                   m_destinationLineNo;
0198     int                   m_trackingDestinationLineNo;
0199 
0200     DifferenceStringList  m_sourceLines;
0201     DifferenceStringList  m_destinationLines;
0202 
0203     bool                  m_applied;
0204     bool                  m_conflicts;
0205     bool                  m_unsaved;
0206 };
0207 
0208 using DifferenceList =              QList<Difference*>;
0209 using DifferenceListIterator =      QList<Difference*>::iterator;
0210 using DifferenceListConstIterator = QList<Difference*>::const_iterator;
0211 
0212 } // End of namespace Diff2
0213 
0214 #endif
0215