1 | /*************************************************************************** |
2 | difference.h |
3 | ------------ |
4 | begin : Sun Mar 4 2001 |
5 | Copyright 2001-2004,2009 Otto Bruggeman <bruggie@gmail.com> |
6 | Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org> |
7 | ****************************************************************************/ |
8 | |
9 | /*************************************************************************** |
10 | ** |
11 | ** This program is free software; you can redistribute it and/or modify |
12 | ** it under the terms of the GNU General Public License as published by |
13 | ** the Free Software Foundation; either version 2 of the License, or |
14 | ** (at your option) any later version. |
15 | ** |
16 | ***************************************************************************/ |
17 | |
18 | #ifndef DIFFERENCE_H |
19 | #define DIFFERENCE_H |
20 | |
21 | #include <qvector.h> |
22 | |
23 | #include <kdebug.h> |
24 | #include "diff2export.h" |
25 | #include "marker.h" |
26 | |
27 | class QString; |
28 | |
29 | namespace Diff2 |
30 | { |
31 | |
32 | class DIFF2_EXPORT DifferenceString |
33 | { |
34 | public: |
35 | DifferenceString() |
36 | { |
37 | // kDebug(8101) << "DifferenceString::DifferenceString()" << endl; |
38 | } |
39 | explicit DifferenceString( const QString& string, const MarkerList& markerList = MarkerList() ) : |
40 | m_string( string ), |
41 | m_markerList( markerList ) |
42 | { |
43 | // kDebug(8101) << "DifferenceString::DifferenceString( " << string << ", " << markerList << " )" << endl; |
44 | calculateHash(); |
45 | } |
46 | DifferenceString( const DifferenceString& ds ) : |
47 | m_string( ds.m_string ), |
48 | m_conflict( ds.m_conflict ), |
49 | m_hash( ds.m_hash ), |
50 | m_markerList( ds.m_markerList ) |
51 | { |
52 | // kDebug(8101) << "DifferenceString::DifferenceString( const DifferenceString& " << ds << " )" << endl; |
53 | } |
54 | ~DifferenceString() |
55 | { |
56 | qDeleteAll( m_markerList ); |
57 | } |
58 | |
59 | public: |
60 | const QString& string() const |
61 | { |
62 | return m_string; |
63 | } |
64 | const QString& conflictString() const |
65 | { |
66 | return m_conflict; |
67 | } |
68 | const MarkerList& markerList() |
69 | { |
70 | return m_markerList; |
71 | } |
72 | void setString( const QString& string ) |
73 | { |
74 | m_string = string; |
75 | calculateHash(); |
76 | } |
77 | void setConflictString( const QString& conflict ) |
78 | { |
79 | m_conflict = conflict; |
80 | } |
81 | void setMarkerList( const MarkerList& markerList ) |
82 | { |
83 | m_markerList = markerList; |
84 | } |
85 | void prepend( Marker* marker ) |
86 | { |
87 | m_markerList.prepend( marker ); |
88 | } |
89 | bool operator==( const DifferenceString& ks ) |
90 | { |
91 | if ( m_hash != ks.m_hash ) |
92 | return false; |
93 | return m_string == ks.m_string; |
94 | } |
95 | |
96 | protected: |
97 | void calculateHash() |
98 | { |
99 | unsigned short const* str = reinterpret_cast<unsigned short const*>( m_string.unicode() ); |
100 | const unsigned int len = m_string.length(); |
101 | |
102 | m_hash = 1315423911; |
103 | |
104 | for ( unsigned int i = 0; i < len; i++ ) |
105 | { |
106 | m_hash ^= ( m_hash << 5 ) + str[i] + ( m_hash >> 2 ); |
107 | } |
108 | } |
109 | |
110 | private: |
111 | QString m_string; |
112 | QString m_conflict; |
113 | unsigned int m_hash; |
114 | MarkerList m_markerList; |
115 | }; |
116 | |
117 | typedef QVector<DifferenceString*> DifferenceStringList; |
118 | typedef QVector<DifferenceString*>::iterator DifferenceStringListIterator; |
119 | typedef QVector<DifferenceString*>::const_iterator DifferenceStringListConstIterator; |
120 | |
121 | class DIFF2_EXPORT Difference : public QObject |
122 | { |
123 | Q_OBJECT |
124 | public: |
125 | enum Type { Change, Insert, Delete, Unchanged }; |
126 | |
127 | public: |
128 | Difference( int sourceLineNo, int destinationLineNo, int type = Difference::Unchanged ); |
129 | ~Difference(); |
130 | |
131 | public: |
132 | int type() const { return m_type; }; |
133 | |
134 | int sourceLineNumber() const { return m_sourceLineNo; } |
135 | int destinationLineNumber() const { return m_destinationLineNo; } |
136 | |
137 | int sourceLineCount() const; |
138 | int destinationLineCount() const; |
139 | |
140 | int sourceLineEnd() const; |
141 | int destinationLineEnd() const; |
142 | |
143 | /// Destination line number that tracks applying/unapplying of other differences |
144 | /// Essentially a line number in a patch consisting of applied diffs only |
145 | int trackingDestinationLineNumber() const { return m_trackingDestinationLineNo; } |
146 | int trackingDestinationLineEnd() const; |
147 | void setTrackingDestinationLineNumber( int i ) { m_trackingDestinationLineNo = i; } |
148 | |
149 | DifferenceString* sourceLineAt( int i ) const { return m_sourceLines[ i ]; } |
150 | DifferenceString* destinationLineAt( int i ) const { return m_destinationLines[ i ]; } |
151 | |
152 | const DifferenceStringList sourceLines() const { return m_sourceLines; } |
153 | const DifferenceStringList destinationLines() const { return m_destinationLines; } |
154 | |
155 | bool hasConflict() const |
156 | { |
157 | return m_conflicts; |
158 | } |
159 | void setConflict( bool conflicts ) |
160 | { |
161 | m_conflicts = conflicts; |
162 | } |
163 | |
164 | bool isUnsaved() const |
165 | { |
166 | return m_unsaved; |
167 | } |
168 | void setUnsaved( bool unsaved ) |
169 | { |
170 | m_unsaved = unsaved; |
171 | } |
172 | |
173 | void apply( bool apply ); |
174 | /// Apply without emitting any signals |
175 | void applyQuietly( bool apply ); |
176 | bool applied() const { return m_applied; } |
177 | |
178 | void setType( int type ) { m_type = type; } |
179 | |
180 | void addSourceLine( QString line ); |
181 | void addDestinationLine( QString line ); |
182 | |
183 | /** This method will calculate the differences between the individual strings and store them as Markers */ |
184 | void determineInlineDifferences(); |
185 | |
186 | QString recreateDifference() const; |
187 | |
188 | signals: |
189 | void differenceApplied( Difference* ); |
190 | |
191 | private: |
192 | int m_type; |
193 | |
194 | int m_sourceLineNo; |
195 | int m_destinationLineNo; |
196 | int m_trackingDestinationLineNo; |
197 | |
198 | DifferenceStringList m_sourceLines; |
199 | DifferenceStringList m_destinationLines; |
200 | |
201 | bool m_applied; |
202 | bool m_conflicts; |
203 | bool m_unsaved; |
204 | }; |
205 | |
206 | typedef QList<Difference*> DifferenceList; |
207 | typedef QList<Difference*>::iterator DifferenceListIterator; |
208 | typedef QList<Difference*>::const_iterator DifferenceListConstIterator; |
209 | |
210 | } // End of namespace Diff2 |
211 | |
212 | #endif |
213 | |
214 | |