File indexing completed on 2025-02-23 04:35:29
0001 /* 0002 SPDX-FileCopyrightText: 2020-2022 Mladen Milinkovic <max@smoothware.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef RICHDOCUMENT_H 0008 #define RICHDOCUMENT_H 0009 0010 #include "core/richstring.h" 0011 #include "core/richtext/richcss.h" 0012 #include "core/richtext/richdom.h" 0013 #include "core/richtext/richdocumentlayout.h" 0014 0015 #include <QTextBlock> 0016 #include <QTextCursor> 0017 #include <QTextDocument> 0018 #include <QTextFormat> 0019 #include <QObject> 0020 #include <QPalette> 0021 0022 QT_FORWARD_DECLARE_CLASS(QStyle) 0023 QT_FORWARD_DECLARE_CLASS(QStyleOptionViewItem) 0024 0025 namespace SubtitleComposer { 0026 class RichDOM; 0027 0028 class RichDocument : public QTextDocument 0029 { 0030 Q_OBJECT 0031 0032 public: 0033 enum Property { 0034 Class = QTextFormat::UserProperty, 0035 Voice = QTextFormat::UserProperty + 1, 0036 Merged = QTextFormat::UserProperty + 2, 0037 }; 0038 Q_ENUM(Property) 0039 0040 explicit RichDocument(QObject *parent=nullptr); 0041 virtual ~RichDocument(); 0042 0043 RichString toRichText() const; 0044 void setRichText(const RichString &text, bool resetUndo=false); 0045 0046 QString toHtml() const; 0047 void setHtml(const QString &html, bool resetUndo=false); 0048 0049 void setPlainText(const QString &text, bool resetUndo=false); 0050 0051 void setDocument(const QTextDocument *doc, bool resetUndo=false); 0052 0053 inline void setDocumentLayout(RichDocumentLayout *layout) { QTextDocument::setDocumentLayout(layout); } 0054 inline RichDocumentLayout * documentLayout() const { return static_cast<RichDocumentLayout *>(QTextDocument::documentLayout()); } 0055 0056 void clear(bool resetUndo); 0057 inline void clear() override { clear(false); } 0058 0059 inline int length() const { const QTextBlock &b = lastBlock(); return b.position() + b.length(); } 0060 0061 void joinLines(); 0062 0063 void replace(const QRegularExpression &search, const QString &replacement, bool replacementIsHtml=true); 0064 void replace(QChar before, QChar after, Qt::CaseSensitivity cs = Qt::CaseSensitive); 0065 void replace(int index, int len, const QString &replacement); 0066 int indexOf(const QRegularExpression &re, int from = 0); 0067 int cummulativeStyleFlags() const; 0068 QRgb styleColorAt(int index) const; 0069 0070 void cleanupSpaces(); 0071 void fixPunctuation(bool spaces, bool quotes, bool englishI, bool ellipsis, bool *cont, bool testOnly=false); 0072 void toLower(); 0073 void toUpper(); 0074 void toSentenceCase(bool *isSentenceStart, bool convertLowerCase=true, bool titleCase=false, bool testOnly=false); 0075 void breakText(int minBreakLength); 0076 0077 inline QTextCursor *undoableCursor() { return &m_undoableCursor; } 0078 0079 void setStylesheet(const RichCSS *css); 0080 inline const RichCSS *stylesheet() const { return m_stylesheet; } 0081 0082 RichDOM *dom(); 0083 QString crumbAt(RichDOM::Node *n); 0084 RichDOM::Node *nodeAt(quint32 pos, RichDOM::Node *root=nullptr); 0085 inline QString crumbAt(quint32 pos) { return crumbAt(nodeAt(pos ? pos - 1 : 0, dom()->m_root)); } 0086 0087 signals: 0088 void domChanged(); 0089 0090 public slots: 0091 inline void undo() { QTextDocument::undo(&m_undoableCursor); } 0092 inline void redo() { QTextDocument::redo(&m_undoableCursor); } 0093 0094 private: 0095 inline void setUndoRedoEnabled(bool enable) { QTextDocument::setUndoRedoEnabled(enable); } 0096 inline int length(int index, int len) const { const int dl = length(); return len < 0 || (index + len) > dl ? dl - index : len; } 0097 void linesToBlocks(); 0098 0099 void markStylesheetDirty(); 0100 0101 private: 0102 QTextCursor m_undoableCursor; 0103 const RichCSS *m_stylesheet; 0104 bool m_domDirty; 0105 RichDOM *m_dom; 0106 0107 void applyChanges(const void *changeList); 0108 0109 Q_DISABLE_COPY(RichDocument) 0110 }; 0111 0112 } 0113 0114 #endif // RICHDOCUMENT_H