Warning, file /utilities/okteta/core/piecetable/piecetablechangehistory.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     This file is part of the Okteta Core library, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2008 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "piecetablechangehistory.hpp"
0010 
0011 // lib
0012 #include "grouppiecetablechange.hpp"
0013 //
0014 #include <addressrangelist.hpp>
0015 #include <arraychangemetricslist.hpp>
0016 
0017 namespace KPieceTable {
0018 
0019 void PieceTableChangeHistory::clear()
0020 {
0021     while (!mChangeStack.isEmpty()) {
0022         delete mChangeStack.pop();
0023     }
0024 
0025     mTryToMergeAppendedChange = false;
0026     mAppliedChangesCount = 0;
0027     mBaseBeforeChangeIndex = 0;
0028     mAppliedChangesDataSize = 0;
0029 
0030     mActiveGroupChange = nullptr;
0031 }
0032 
0033 void PieceTableChangeHistory::getChangeData(ArrayChangeMetrics* metrics, Address* storageOffset,
0034                                             int versionIndex) const
0035 {
0036     AbstractPieceTableChange* change = mChangeStack.at(versionIndex);
0037     *metrics = change->metrics();
0038     *storageOffset = change->storageOffset();
0039 }
0040 
0041 void PieceTableChangeHistory::setBeforeCurrentChangeAsBase(bool hide)
0042 {
0043     mBaseBeforeChangeIndex = hide ? -1 : mAppliedChangesCount;
0044     mTryToMergeAppendedChange = false;
0045 }
0046 
0047 void PieceTableChangeHistory::openGroupedChange(const QString& description)
0048 {
0049     auto* groupChange = new GroupPieceTableChange(mActiveGroupChange, description);
0050 
0051     appendChange(groupChange);
0052     mActiveGroupChange = groupChange;
0053 }
0054 
0055 void PieceTableChangeHistory::closeGroupedChange(const QString& description)
0056 {
0057     if (mActiveGroupChange) {
0058         if (!description.isEmpty()) {
0059             mActiveGroupChange->setDescription(description);
0060         }
0061         mActiveGroupChange = mActiveGroupChange->parent();
0062     }
0063 }
0064 
0065 void PieceTableChangeHistory::finishChange()
0066 {
0067     if (mActiveGroupChange) {
0068         mActiveGroupChange->finishChange();
0069     } else {
0070         mTryToMergeAppendedChange = false;
0071     }
0072 }
0073 
0074 bool PieceTableChangeHistory::appendChange(AbstractPieceTableChange* change)
0075 {
0076     // chop unapplied changes
0077     if (mAppliedChangesCount < mChangeStack.size()) {
0078         // hide baseindex if needed
0079         if (mBaseBeforeChangeIndex > mAppliedChangesCount) {
0080             mBaseBeforeChangeIndex = -1;
0081         }
0082         do {
0083             AbstractPieceTableChange* droppedChange = mChangeStack.pop();
0084             delete droppedChange;
0085         } while (mAppliedChangesCount < mChangeStack.size());
0086     }
0087 
0088     mAppliedChangesDataSize += change->dataSize();
0089 
0090     bool isNotMerged = true;
0091     if (mActiveGroupChange) {
0092         mActiveGroupChange->appendChange(change);
0093         isNotMerged = false; // TODO: hack for as long as subgroups are not undoable
0094     } else {
0095         if (mTryToMergeAppendedChange && mAppliedChangesCount > 0) {
0096             isNotMerged = !mChangeStack.top()->merge(change);
0097         } else {
0098             mTryToMergeAppendedChange = true;
0099         }
0100 
0101         if (isNotMerged) {
0102             mChangeStack.push(change);
0103             ++mAppliedChangesCount;
0104         } else {
0105             delete change;
0106         }
0107     }
0108 
0109     return isNotMerged;
0110 }
0111 
0112 bool PieceTableChangeHistory::revertBeforeChange(PieceTable* pieceTable, int changeId,
0113                                                  AddressRangeList* changedRanges,
0114                                                  ArrayChangeMetricsList* changeList)
0115 {
0116     int currentChangeId = mAppliedChangesCount;
0117 
0118     if (currentChangeId == changeId) {
0119         return false;
0120     }
0121 
0122     // close any grouped changes
0123     while (mActiveGroupChange) {
0124         mActiveGroupChange = mActiveGroupChange->parent();
0125     }
0126 
0127     if (currentChangeId < changeId) {
0128         for (; currentChangeId < changeId; ++currentChangeId) {
0129             const AbstractPieceTableChange* change = mChangeStack[currentChangeId];
0130 
0131             if (change->type() == AbstractPieceTableChange::GroupId) {
0132                 const auto* groupChange = static_cast<const GroupPieceTableChange*>(change);
0133                 const AddressRangeList changedRangeList = groupChange->applyGroup(pieceTable);
0134                 changedRanges->addAddressRangeList(changedRangeList);
0135 
0136                 const QVector<ArrayChangeMetrics> changeMetricsList = groupChange->groupMetrics();
0137                 *changeList += changeMetricsList;
0138             } else {
0139                 const AddressRange changedRange = change->apply(pieceTable);
0140                 changedRanges->addAddressRange(changedRange);
0141 
0142                 const ArrayChangeMetrics changeMetrics = change->metrics();
0143                 changeList->append(changeMetrics);
0144             }
0145 
0146             mAppliedChangesDataSize += change->dataSize();
0147         }
0148     } else {
0149         for (--currentChangeId; changeId <= currentChangeId; --currentChangeId) {
0150             const AbstractPieceTableChange* change = mChangeStack[currentChangeId];
0151 
0152             if (change->type() == AbstractPieceTableChange::GroupId) {
0153                 const auto* groupChange = static_cast<const GroupPieceTableChange*>(change);
0154                 const AddressRangeList changedRangeList = groupChange->revertGroup(pieceTable);
0155                 changedRanges->addAddressRangeList(changedRangeList);
0156 
0157                 const QVector<ArrayChangeMetrics> changeMetricsList = groupChange->groupMetrics(true);
0158                 *changeList += changeMetricsList;
0159             } else {
0160                 const AddressRange changedRange = change->revert(pieceTable);
0161                 changedRanges->addAddressRange(changedRange);
0162 
0163                 ArrayChangeMetrics changeMetrics = change->metrics();
0164                 changeMetrics.revert();
0165                 changeList->append(changeMetrics);
0166             }
0167             mAppliedChangesDataSize -= change->dataSize();
0168         }
0169     }
0170     mAppliedChangesCount = changeId;
0171     mTryToMergeAppendedChange = false;
0172 
0173     return true;
0174 }
0175 
0176 }