File indexing completed on 2024-04-21 05:53:00
0001 /* 0002 This file is part of the Okteta Core library, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2008-2009 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 #ifndef OKTETA_PIECETABLEBYTEARRAYMODEL_P_HPP 0010 #define OKTETA_PIECETABLEBYTEARRAYMODEL_P_HPP 0011 0012 // lib 0013 #include "abstractbytearraymodel_p.hpp" 0014 #include "piecetablebytearraymodel.hpp" 0015 #include "bookmarksconstiterator.hpp" 0016 #include "bookmarklistconstiteratoradapter.hpp" 0017 #include "bookmarklist.hpp" 0018 #include "changesdatastorage.hpp" 0019 #include "arraychangemetricslist.hpp" 0020 // piecetable 0021 #include "piecetable/revertablepiecetable.hpp" 0022 0023 namespace Okteta { 0024 0025 class PieceTableByteArrayModelPrivate : public AbstractByteArrayModelPrivate 0026 { 0027 public: 0028 /** */ 0029 explicit PieceTableByteArrayModelPrivate(PieceTableByteArrayModel* parent, const QByteArray& data); 0030 /** creates a writeable buffer which is deleted at the end */ 0031 explicit PieceTableByteArrayModelPrivate(PieceTableByteArrayModel* parent, int size, Byte fillByte = '\0'); 0032 0033 ~PieceTableByteArrayModelPrivate() override; 0034 0035 public: // AbstractByteArrayModel API 0036 Byte byte(Address offset) const; 0037 Size size() const; 0038 bool isReadOnly() const; 0039 bool isModified() const; 0040 0041 Size insert(Address offset, const Byte* insertData, int insertLength); 0042 Size remove(const AddressRange& removeRange); 0043 Size replace(const AddressRange& removeRange, const Byte* insertData, int insertLength); 0044 bool swap(Address firstStart, const AddressRange& secondRange); 0045 Size fill(Byte fillByte, Address offset = 0, Size fillLength = -1); 0046 void setByte(Address offset, Byte byte); 0047 0048 void setModified(bool modified = true); 0049 void setReadOnly(bool isReadOnly = true); 0050 0051 public: // Versionable API 0052 int versionIndex() const; 0053 int versionCount() const; 0054 QString versionDescription(int versionIndex) const; 0055 0056 public: // set/action 0057 void revertToVersionByIndex(int versionIndex); 0058 0059 public: 0060 void addBookmarks(const QVector<Bookmark>& bookmarks); 0061 void removeBookmarks(const QVector<Bookmark>& bookmarks); 0062 void removeAllBookmarks(); 0063 void setBookmark(unsigned int index, const Bookmark& bookmark); 0064 0065 BookmarksConstIterator createBookmarksConstIterator() const; 0066 const Bookmark& bookmarkAt(unsigned int index) const; 0067 const Bookmark& bookmarkFor(int offset) const; 0068 bool containsBookmarkFor(int offset) const; 0069 unsigned int bookmarksCount() const; 0070 0071 public: // ChangesDescribable API 0072 void openGroupedChange(const QString& description); 0073 void cancelGroupedChange(); 0074 void closeGroupedChange(const QString& description); 0075 0076 public: // ChangeHistory API 0077 QVector<ByteArrayChange> changes(int firstVersionIndex, int lastVersionIndex) const; 0078 const QByteArray& initialData() const; 0079 void doChanges(const QVector<Okteta::ByteArrayChange>& changes, 0080 int oldVersionIndex, int newVersionIndex); 0081 0082 public: 0083 void setData(const QByteArray& data); 0084 0085 private: 0086 void doInsertChange(Address offset, const Byte* insertData, int insertLength); 0087 void doRemoveChange(const AddressRange& removeRange); 0088 void doReplaceChange(const AddressRange& removeRange, const Byte* insertData, int insertLength); 0089 void doSwapChange(Address firstStart, const AddressRange& secondRange); 0090 void doFillChange(Address offset, Size filledLength, 0091 Byte fillByte, int fillLength); 0092 0093 void beginChanges(); 0094 void endChanges(); 0095 0096 private: // data 0097 /** */ 0098 bool mReadOnly : 1; 0099 0100 QByteArray mInitialData; 0101 KPieceTable::RevertablePieceTable mPieceTable; 0102 ChangesDataStorage mChangesDataStorage; 0103 /** */ 0104 BookmarkList mBookmarks; 0105 /** temporary workaround for cancelling groups. If -1 no group is opened. */ 0106 int mBeforeGroupedChangeVersionIndex; 0107 0108 int mBeforeChangesVersionIndex; 0109 ArrayChangeMetricsList mChangeMetrics; 0110 QVector<ByteArrayChange> mChanges; 0111 bool mBeforeChangesModified : 1; 0112 bool mBookmarksModified : 1; 0113 0114 private: 0115 Q_DECLARE_PUBLIC(PieceTableByteArrayModel) 0116 }; 0117 0118 inline const QByteArray& PieceTableByteArrayModelPrivate::initialData() const { return mInitialData; } 0119 inline Size PieceTableByteArrayModelPrivate::size() const { return mPieceTable.size(); } 0120 0121 inline bool PieceTableByteArrayModelPrivate::isReadOnly() const { return mReadOnly; } 0122 inline bool PieceTableByteArrayModelPrivate::isModified() const { return !mPieceTable.isAtBase(); } 0123 0124 inline void PieceTableByteArrayModelPrivate::setReadOnly(bool readOnly) 0125 { 0126 Q_Q(PieceTableByteArrayModel); 0127 0128 if (mReadOnly != readOnly) { 0129 mReadOnly = readOnly; 0130 Q_EMIT q->readOnlyChanged(readOnly); 0131 } 0132 } 0133 inline void PieceTableByteArrayModelPrivate::setModified(bool modified) 0134 { 0135 Q_Q(PieceTableByteArrayModel); 0136 0137 if (isModified() != modified) { 0138 mPieceTable.setBeforeCurrentChangeAsBase(modified); 0139 // TODO: is the call setModified of any use? 0140 // shouldn't there be only a setUnmodified(void) or else call? 0141 Q_EMIT q->modifiedChanged(modified); 0142 } 0143 } 0144 0145 inline int PieceTableByteArrayModelPrivate::versionIndex() const { return mPieceTable.appliedChangesCount(); } 0146 inline int PieceTableByteArrayModelPrivate::versionCount() const { return mPieceTable.changesCount() + 1; } 0147 inline QString PieceTableByteArrayModelPrivate::versionDescription(int versionIndex) const 0148 { return mPieceTable.changeDescription(versionIndex - 1); } 0149 0150 inline void PieceTableByteArrayModelPrivate::addBookmarks(const QVector<Bookmark>& bookmarks) 0151 { 0152 Q_Q(PieceTableByteArrayModel); 0153 0154 mBookmarks.addBookmarks(bookmarks); 0155 Q_EMIT q->bookmarksAdded(bookmarks); 0156 } 0157 inline void PieceTableByteArrayModelPrivate::removeBookmarks(const QVector<Bookmark>& bookmarks) 0158 { 0159 Q_Q(PieceTableByteArrayModel); 0160 0161 mBookmarks.removeBookmarks(bookmarks); 0162 Q_EMIT q->bookmarksRemoved(bookmarks); 0163 } 0164 0165 inline void PieceTableByteArrayModelPrivate::removeAllBookmarks() 0166 { 0167 Q_Q(PieceTableByteArrayModel); 0168 0169 const QVector<Bookmark> bookmarks = mBookmarks.list(); 0170 mBookmarks.clear(); 0171 Q_EMIT q->bookmarksRemoved(bookmarks); 0172 } 0173 inline void PieceTableByteArrayModelPrivate::setBookmark(unsigned int index, const Bookmark& bookmark) 0174 { 0175 Q_Q(PieceTableByteArrayModel); 0176 0177 mBookmarks.setBookmark(index, bookmark); 0178 0179 const QVector<int> changedBookmarkIndizes { 0180 static_cast<int>(index) 0181 }; 0182 Q_EMIT q->bookmarksModified(changedBookmarkIndizes); 0183 } 0184 0185 inline BookmarksConstIterator PieceTableByteArrayModelPrivate::createBookmarksConstIterator() const 0186 { 0187 return BookmarksConstIterator(new BookmarkListConstIteratorAdapter(mBookmarks)); 0188 } 0189 0190 inline const Bookmark& PieceTableByteArrayModelPrivate::bookmarkAt(unsigned int index) const 0191 { 0192 return mBookmarks.at(index); 0193 } 0194 inline const Bookmark& PieceTableByteArrayModelPrivate::bookmarkFor(int offset) const 0195 { 0196 return mBookmarks.bookmark(offset); 0197 } 0198 inline bool PieceTableByteArrayModelPrivate::containsBookmarkFor(int offset) const { return mBookmarks.contains(offset); } 0199 inline unsigned int PieceTableByteArrayModelPrivate::bookmarksCount() const { return mBookmarks.size(); } 0200 0201 } 0202 0203 #endif