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