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