File indexing completed on 2024-04-14 05:37:12

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 #include "difference.h"
0009 #include "difference_p.h"
0010 
0011 // lib
0012 #include "differencestringpair.h"
0013 #include "levenshteintable.h"
0014 
0015 using namespace KompareDiff2;
0016 
0017 Difference::Difference(int sourceLineNo, int destinationLineNo, int type)
0018     : d_ptr(new DifferencePrivate(sourceLineNo, destinationLineNo, type))
0019 {
0020 }
0021 
0022 Difference::~Difference() = default;
0023 
0024 int Difference::type() const
0025 {
0026     Q_D(const Difference);
0027 
0028     return d->type;
0029 };
0030 
0031 int Difference::sourceLineNumber() const
0032 {
0033     Q_D(const Difference);
0034 
0035     return d->sourceLineNo;
0036 }
0037 
0038 int Difference::destinationLineNumber() const
0039 {
0040     Q_D(const Difference);
0041 
0042     return d->destinationLineNo;
0043 }
0044 
0045 int Difference::trackingDestinationLineNumber() const
0046 {
0047     Q_D(const Difference);
0048 
0049     return d->trackingDestinationLineNo;
0050 }
0051 
0052 void Difference::setTrackingDestinationLineNumber(int i)
0053 {
0054     Q_D(Difference);
0055 
0056     d->trackingDestinationLineNo = i;
0057 }
0058 
0059 DifferenceString *Difference::sourceLineAt(int i) const
0060 {
0061     Q_D(const Difference);
0062 
0063     return d->sourceLines[i];
0064 }
0065 
0066 DifferenceString *Difference::destinationLineAt(int i) const
0067 {
0068     Q_D(const Difference);
0069 
0070     return d->destinationLines[i];
0071 }
0072 
0073 DifferenceStringList Difference::sourceLines() const
0074 {
0075     Q_D(const Difference);
0076 
0077     return d->sourceLines;
0078 }
0079 
0080 DifferenceStringList Difference::destinationLines() const
0081 {
0082     Q_D(const Difference);
0083 
0084     return d->destinationLines;
0085 }
0086 
0087 bool Difference::hasConflict() const
0088 {
0089     Q_D(const Difference);
0090 
0091     return d->conflicts;
0092 }
0093 
0094 void Difference::setConflict(bool conflicts)
0095 {
0096     Q_D(Difference);
0097 
0098     d->conflicts = conflicts;
0099 }
0100 
0101 bool Difference::isUnsaved() const
0102 {
0103     Q_D(const Difference);
0104 
0105     return d->unsaved;
0106 }
0107 
0108 void Difference::setUnsaved(bool unsaved)
0109 {
0110     Q_D(Difference);
0111 
0112     d->unsaved = unsaved;
0113 }
0114 
0115 bool Difference::applied() const
0116 {
0117     Q_D(const Difference);
0118 
0119     return d->applied;
0120 }
0121 
0122 void Difference::setType(int type)
0123 {
0124     Q_D(Difference);
0125 
0126     d->type = type;
0127 }
0128 
0129 void Difference::addSourceLine(const QString &line)
0130 {
0131     Q_D(Difference);
0132 
0133     d->sourceLines.append(new DifferenceString(line));
0134 }
0135 
0136 void Difference::addDestinationLine(const QString &line)
0137 {
0138     Q_D(Difference);
0139 
0140     d->destinationLines.append(new DifferenceString(line));
0141 }
0142 
0143 int Difference::sourceLineCount() const
0144 {
0145     Q_D(const Difference);
0146 
0147     return d->sourceLines.count();
0148 }
0149 
0150 int Difference::destinationLineCount() const
0151 {
0152     Q_D(const Difference);
0153 
0154     return d->destinationLines.count();
0155 }
0156 
0157 int Difference::sourceLineEnd() const
0158 {
0159     Q_D(const Difference);
0160 
0161     return d->sourceLineNo + d->sourceLines.count();
0162 }
0163 
0164 int Difference::destinationLineEnd() const
0165 {
0166     Q_D(const Difference);
0167 
0168     return d->destinationLineNo + d->destinationLines.count();
0169 }
0170 
0171 int Difference::trackingDestinationLineEnd() const
0172 {
0173     Q_D(const Difference);
0174 
0175     return d->trackingDestinationLineNo + d->destinationLines.count();
0176 }
0177 
0178 void Difference::apply(bool apply)
0179 {
0180     Q_D(Difference);
0181 
0182     if (apply == d->applied) {
0183         return;
0184     }
0185 
0186     d->applied = apply;
0187     d->unsaved = !d->unsaved;
0188     Q_EMIT differenceApplied(this);
0189 }
0190 
0191 void Difference::applyQuietly(bool apply)
0192 {
0193     Q_D(Difference);
0194 
0195     if (d->applied == apply) {
0196         return;
0197     }
0198 
0199     d->unsaved = !d->unsaved;
0200     d->applied = apply;
0201 }
0202 
0203 void Difference::determineInlineDifferences()
0204 {
0205     Q_D(Difference);
0206 
0207     if (d->type != Difference::Change)
0208         return;
0209 
0210     // Do nothing for now when the slc != dlc
0211     // One could try to find the closest matching destination string for any
0212     // of the source strings but this is compute intensive
0213     int slc = sourceLineCount();
0214 
0215     if (slc != destinationLineCount())
0216         return;
0217 
0218     LevenshteinTable<DifferenceStringPair> table;
0219 
0220     for (int i = 0; i < slc; ++i) {
0221         DifferenceString *sl = sourceLineAt(i);
0222         DifferenceString *dl = destinationLineAt(i);
0223         DifferenceStringPair *pair = new DifferenceStringPair(sl, dl);
0224 
0225         // return value 0 means something went wrong creating the table so don't bother finding markers
0226         if (table.createTable(pair) != 0)
0227             table.createListsOfMarkers();
0228     }
0229 }
0230 
0231 QString Difference::recreateDifference() const
0232 {
0233     Q_D(const Difference);
0234 
0235     QString difference;
0236 
0237     // source
0238     for (const DifferenceString *diffString : d->sourceLines) {
0239         switch (d->type) {
0240         case Change:
0241         case Delete:
0242             difference += QLatin1Char('-');
0243             break;
0244         default:
0245             // Insert but this is not possible in source
0246             // Unchanged will be handled in destination
0247             // since they are the same
0248 //             qCDebug(KOMPAREDIFF2_LOG) << "Go away, nothing to do for you in source...";
0249             continue;
0250         }
0251         difference += diffString->string();
0252     }
0253 
0254     // destination
0255     for (const DifferenceString *diffString : d->destinationLines) {
0256         switch (d->type) {
0257         case Change:
0258         case Insert:
0259             difference += QLatin1Char('+');
0260             break;
0261         case Unchanged:
0262             difference += QLatin1Char(' ');
0263             break;
0264         default: // Delete but this is not possible in destination
0265 //             qCDebug(KOMPAREDIFF2_LOG) << "Go away, nothing to do for you in destination...";
0266             continue;
0267         }
0268         difference += diffString->string();
0269     }
0270 
0271     return difference;
0272 }
0273 
0274 #include "moc_difference.cpp"