RedPanda-CPP/RedPandaIDE/qsynedit/TextBuffer.h

282 lines
7.4 KiB
C
Raw Normal View History

2021-12-26 23:18:28 +08:00
/*
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
2021-05-14 23:56:43 +08:00
#ifndef SYNEDITSTRINGLIST_H
#define SYNEDITSTRINGLIST_H
#include <QStringList>
#include "highlighter/base.h"
#include <QFontMetrics>
#include <QMutex>
2021-05-14 23:56:43 +08:00
#include <QVector>
#include <memory>
#include "MiscProcs.h"
#include "../utils.h"
#include "Types.h"
enum SynEditStringFlag {
sfHasTabs = 0x0001,
sfHasNoTabs = 0x0002,
sfExpandedLengthUnknown = 0x0004
};
typedef int SynEditStringFlags;
struct SynDocumentLine {
2021-05-14 23:56:43 +08:00
QString fString;
SynRangeState fRange;
2021-05-18 15:49:58 +08:00
int fColumns; //
2021-05-14 23:56:43 +08:00
public:
explicit SynDocumentLine();
2021-05-14 23:56:43 +08:00
};
typedef std::shared_ptr<SynDocumentLine> PSynDocumentLine;
2021-05-14 23:56:43 +08:00
typedef QVector<PSynDocumentLine> SynDocumentLines;
2021-05-14 23:56:43 +08:00
typedef std::shared_ptr<SynDocumentLines> PSynDocumentLines;
2021-05-14 23:56:43 +08:00
class SynDocument;
2021-05-14 23:56:43 +08:00
typedef std::shared_ptr<SynDocument> PSynDocument;
2021-05-14 23:56:43 +08:00
class QFile;
2021-05-18 15:49:58 +08:00
class SynDocument : public QObject
2021-05-14 23:56:43 +08:00
{
Q_OBJECT
public:
explicit SynDocument(const QFont& font, QObject* parent=nullptr);
2021-05-14 23:56:43 +08:00
int parenthesisLevels(int Index);
int bracketLevels(int Index);
int braceLevels(int Index);
2021-05-18 15:49:58 +08:00
int lineColumns(int Index);
int leftBraces(int Index);
int rightBraces(int Index);
2021-05-14 23:56:43 +08:00
int lengthOfLongestLine();
2021-10-07 07:52:20 +08:00
QString lineBreak() const;
SynRangeState ranges(int Index);
2021-10-28 08:56:13 +08:00
void setRange(int Index, const SynRangeState& ARange);
QString getString(int Index);
int count();
QString text();
2021-05-14 23:56:43 +08:00
void setText(const QString& text);
void setContents(const QStringList& text);
QStringList contents();
2021-05-14 23:56:43 +08:00
2021-11-13 13:03:42 +08:00
void putString(int Index, const QString& s, bool notify=true);
2021-05-14 23:56:43 +08:00
void beginUpdate();
void endUpdate();
int add(const QString& s);
void addStrings(const QStringList& Strings);
2021-05-14 23:56:43 +08:00
int getTextLength();
void clear();
void deleteAt(int Index);
void deleteLines(int Index, int NumLines);
void exchange(int Index1, int Index2);
void insert(int Index, const QString& s);
void insertLines(int Index, int NumLines);
2022-07-02 14:06:10 +08:00
void loadFromFile(const QString& filename, const QByteArray& encoding, QByteArray& realEncoding);
void saveToFile(QFile& file, const QByteArray& encoding,
const QByteArray& defaultEncoding, QByteArray& realEncoding);
int stringColumns(const QString& line, int colsBefore) const;
int charColumns(QChar ch) const;
bool getAppendNewLineAtEOF();
2021-05-14 23:56:43 +08:00
void setAppendNewLineAtEOF(bool appendNewLineAtEOF);
FileEndingType getFileEndingType();
2021-05-14 23:56:43 +08:00
void setFileEndingType(const FileEndingType &fileEndingType);
2021-05-24 00:41:00 +08:00
bool empty();
2021-06-07 11:02:03 +08:00
void resetColumns();
int tabWidth() const {
return mTabWidth;
}
void setTabWidth(int newTabWidth);
const QFontMetrics &fontMetrics() const;
void setFontMetrics(const QFont &newFont);
2021-05-18 15:49:58 +08:00
public slots:
void invalidAllLineColumns();
2021-05-14 23:56:43 +08:00
signals:
void changed();
void changing();
void cleared();
void deleted(int index, int count);
void inserted(int index, int count);
void putted(int index, int count);
protected:
2021-10-07 07:52:20 +08:00
QString getTextStr() const;
void setUpdateState(bool Updating);
void insertItem(int Index, const QString& s);
2021-05-24 00:41:00 +08:00
void addItem(const QString& s);
void putTextStr(const QString& text);
void internalClear();
private:
bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file);
2021-05-14 23:56:43 +08:00
private:
SynDocumentLines mLines;
//SynEdit* mEdit;
2021-05-14 23:56:43 +08:00
QFontMetrics mFontMetrics;
int mTabWidth;
int mCharWidth;
2021-05-14 23:56:43 +08:00
//int mCount;
//int mCapacity;
FileEndingType mFileEndingType;
bool mAppendNewLineAtEOF;
int mIndexOfLongestLine;
int mUpdateCount;
2022-01-04 16:50:54 +08:00
QMutex mMutex;
2021-05-14 23:56:43 +08:00
2021-05-18 15:49:58 +08:00
int calculateLineColumns(int Index);
2021-05-14 23:56:43 +08:00
};
2022-07-02 06:44:01 +08:00
enum class SynChangeReason {
Insert,
Delete,
Caret, //just restore the Caret, allowing better Undo behavior
Selection, //restore Selection
GroupBreak,
LeftTop,
LineBreak,
MoveSelectionUp,
MoveSelectionDown,
Nothing // undo list empty
2021-05-14 23:56:43 +08:00
};
2022-07-05 22:25:28 +08:00
2021-05-14 23:56:43 +08:00
class SynEditUndoItem {
private:
SynChangeReason mChangeReason;
SynSelectionMode mChangeSelMode;
BufferCoord mChangeStartPos;
BufferCoord mChangeEndPos;
2022-07-02 10:39:31 +08:00
QStringList mChangeText;
2022-07-05 22:25:28 +08:00
size_t mChangeNumber;
2021-05-14 23:56:43 +08:00
public:
SynEditUndoItem(SynChangeReason reason,
SynSelectionMode selMode,
BufferCoord startPos,
BufferCoord endPos,
2022-07-02 10:39:31 +08:00
const QStringList& text,
2021-05-14 23:56:43 +08:00
int number);
SynChangeReason changeReason() const;
SynSelectionMode changeSelMode() const;
BufferCoord changeStartPos() const;
BufferCoord changeEndPos() const;
2022-07-02 10:39:31 +08:00
QStringList changeText() const;
2022-07-06 00:06:07 +08:00
size_t changeNumber() const;
2021-05-14 23:56:43 +08:00
};
2021-05-14 23:56:43 +08:00
using PSynEditUndoItem = std::shared_ptr<SynEditUndoItem>;
class SynEditUndoList : public QObject {
Q_OBJECT
public:
explicit SynEditUndoList();
void addChange(SynChangeReason AReason, const BufferCoord& AStart, const BufferCoord& AEnd,
2022-07-02 10:39:31 +08:00
const QStringList& ChangeText, SynSelectionMode SelMode);
2021-05-14 23:56:43 +08:00
void restoreChange(SynChangeReason AReason, const BufferCoord& AStart, const BufferCoord& AEnd,
const QStringList& ChangeText, SynSelectionMode SelMode, size_t changeNumber);
void restoreChange(PSynEditUndoItem item);
void addGroupBreak();
void beginBlock();
2022-07-05 22:25:28 +08:00
void endBlock();
void clear();
SynChangeReason lastChangeReason();
bool isEmpty();
PSynEditUndoItem peekItem();
PSynEditUndoItem popItem();
bool canUndo();
int itemCount();
2021-05-14 23:56:43 +08:00
int maxUndoActions() const;
void setMaxUndoActions(int maxUndoActions);
2022-07-06 00:06:07 +08:00
bool initialState();
void setInitialState();
2021-05-14 23:56:43 +08:00
bool insideRedo() const;
void setInsideRedo(bool insideRedo);
bool fullUndoImposible() const;
signals:
void addedUndo();
protected:
void ensureMaxEntries();
2022-07-05 22:25:28 +08:00
bool inBlock();
unsigned int getNextChangeNumber();
2021-05-14 23:56:43 +08:00
protected:
2022-07-05 22:25:28 +08:00
size_t mBlockChangeNumber;
int mBlockLock;
2022-07-06 00:06:07 +08:00
int mBlockCount; // count of action blocks;
size_t mLastPoppedItemChangeNumber;
size_t mLastRestoredItemChangeNumber;
2021-05-14 23:56:43 +08:00
bool mFullUndoImposible;
QVector<PSynEditUndoItem> mItems;
int mMaxUndoActions;
2022-07-05 22:25:28 +08:00
size_t mNextChangeNumber;
2022-07-06 00:06:07 +08:00
size_t mInitialChangeNumber;
2021-05-14 23:56:43 +08:00
bool mInsideRedo;
};
class SynEditRedoList : public QObject {
Q_OBJECT
public:
explicit SynEditRedoList();
void addRedo(SynChangeReason AReason, const BufferCoord& AStart, const BufferCoord& AEnd,
const QStringList& ChangeText, SynSelectionMode SelMode, size_t changeNumber);
void addRedo(PSynEditUndoItem item);
void clear();
SynChangeReason lastChangeReason();
bool isEmpty();
PSynEditUndoItem peekItem();
PSynEditUndoItem popItem();
bool canRedo();
int itemCount();
protected:
QVector<PSynEditUndoItem> mItems;
};
2021-05-14 23:56:43 +08:00
using PSynEditUndoList = std::shared_ptr<SynEditUndoList>;
using PSynEditRedoList = std::shared_ptr<SynEditRedoList>;
2021-05-14 23:56:43 +08:00
#endif // SYNEDITSTRINGLIST_H