File indexing completed on 2024-12-22 04:40:04

0001 /*
0002     SPDX-FileCopyrightText: 2007-2009 Sergio Pistone <sergio_pistone@yahoo.com.ar>
0003     SPDX-FileCopyrightText: 2010-2022 Mladen Milinkovic <max@smoothware.net>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef RICHSTRING_H
0009 #define RICHSTRING_H
0010 
0011 #include <cstring>
0012 
0013 #include <QColor>
0014 #include <QDataStream>
0015 #include <QDebug>
0016 #include <QList>
0017 #include <QString>
0018 
0019 QT_FORWARD_DECLARE_CLASS(QRegularExpression)
0020 
0021 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
0022 namespace Qt {
0023 enum SplitBehaviorFlags {
0024     KeepEmptyParts = 0,
0025     SkipEmptyParts = 0x1,
0026 };
0027 Q_DECLARE_FLAGS(SplitBehavior, SplitBehaviorFlags)
0028 Q_DECLARE_OPERATORS_FOR_FLAGS(SplitBehavior)
0029 }
0030 #endif
0031 
0032 namespace SubtitleComposer {
0033 class RichString;
0034 class RichStringStyle;
0035 }
0036 
0037 QDataStream & operator<<(QDataStream &stream, const SubtitleComposer::RichString &string);
0038 QDataStream & operator>>(QDataStream &stream, SubtitleComposer::RichString &string);
0039 
0040 namespace SubtitleComposer {
0041 class RichStringList : public QList<RichString>
0042 {
0043 public:
0044     RichStringList();
0045     RichStringList(const RichString &str);
0046     RichStringList(const RichStringList &list);
0047     RichStringList(const QList<RichString> &list);
0048     explicit RichStringList(const QStringList &list);
0049 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0050     explicit RichStringList(const QList<QString> &list);
0051 #endif
0052 
0053     RichString join(const RichString &sep) const;
0054 
0055     RichStringList& operator=(const RichStringList& other) = default;
0056 };
0057 
0058 class RichString : public QString
0059 {
0060 public:
0061     typedef enum {
0062         Bold = 0x1,
0063         Italic = 0x2,
0064         Underline = 0x4,
0065         StrikeThrough = 0x8,
0066         Color = 0x10,
0067         AllStyles = Bold | Italic | Underline | StrikeThrough | Color
0068     } StyleFlag;
0069 
0070     using StyleFlags = quint8;
0071 
0072     explicit RichString(const QString &string = QString(), quint8 styleFlags = 0, QRgb styleColor = 0, const QSet<QString> &classList=QSet<QString>(), const QString &voice=QString());
0073     RichString(const RichString &other);
0074     RichString & operator=(const QString &string);
0075     RichString & operator=(const RichString &other);
0076 
0077     ~RichString();
0078 
0079     inline QString string() const { return *this; }
0080     void setString(const QString &string, quint8 styleFlags = 0, QRgb styleColor = 0, const QString klass=QString(), const QString voice=QString());
0081 
0082     static RichString fromRichString(const QString &richstring);
0083     QString richString() const;
0084 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0085     RichString & setRichString(const QStringRef &string);
0086     inline RichString & setRichString(const QString &string) { return setRichString(QStringRef(&string)); }
0087 #else
0088     RichString & setRichString(const QStringView &string);
0089     inline RichString & setRichString(const QString &string) { return setRichString(QStringView(string)); }
0090 #endif
0091 
0092     StyleFlags styleFlagsAt(int index) const;
0093     void setStyleFlagsAt(int index, StyleFlags styleFlags) const;
0094     StyleFlags cummulativeStyleFlags() const;
0095     bool hasStyleFlags(quint8 styleFlags) const;
0096     RichString & setStyleFlags(int index, int len, StyleFlags styleFlags);
0097     RichString & setStyleFlags(int index, int len, StyleFlags styleFlags, bool on);
0098 
0099     QRgb styleColorAt(int index) const;
0100     void setStyleColorAt(int index, QRgb rgbColor) const;
0101     QSet<QRgb> cummulativeColors() const;
0102     RichString & setStyleColor(int index, int len, QRgb color);
0103 
0104     QSet<QString> styleClassesAt(int index) const;
0105     QSet<QString> cummulativeClasses() const;
0106     void setStyleClassesAt(int index, const QSet<QString> &classes) const;
0107 
0108     QString styleVoiceAt(int index) const;
0109     QSet<QString> cummulativeVoices() const;
0110     void setStyleVoiceAt(int index, const QString &voice) const;
0111 
0112     void clear();
0113 
0114     RichString & insert(int index, QChar ch);
0115     RichString & insert(int index, const QString &str);
0116     RichString & insert(int index, const RichString &str);
0117 
0118     inline RichString & append(QChar ch) { return insert(length(), ch); }
0119     inline RichString & append(const QString &str) { return insert(length(), str); }
0120     inline RichString & append(const RichString &str) { return insert(length(), str); }
0121     inline RichString & prepend(QChar ch) { return insert(0, ch); }
0122     inline RichString & prepend(const QString &str) { return insert(0, str); }
0123     inline RichString & prepend(const RichString &str) { return insert(0, str); }
0124     inline RichString & operator+=(QChar ch) { return append(ch); }
0125     inline RichString & operator+=(const QString &str) { return append(str); }
0126     inline RichString & operator+=(const RichString &str) { return append(str); }
0127 
0128     inline RichString & remove(int index, int len) { return replace(index, len, QString()); }
0129     inline RichString & remove(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace(str, QString(), cs); }
0130     inline RichString & remove(QChar ch, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace(ch, QString(), cs); }
0131 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0132     RichString & remove(const QRegExp &rx) = delete;
0133 #endif
0134     RichString & remove(const QRegularExpression &rx) { return replace(rx, QString()); }
0135 
0136     RichString & replace(int index, int len, const QString &replacement);
0137     RichString & replace(int index, int len, const RichString &replacement);
0138     RichString & replace(const QString &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0139     RichString & replace(const QString &before, const RichString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0140     RichString & replace(QChar before, QChar after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0141     RichString & replace(QChar ch, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0142     RichString & replace(QChar ch, const RichString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
0143 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0144     RichString & replace(const QRegExp &regExp, const QString &replacement) = delete;
0145     RichString & replace(const QRegExp &regExp, const RichString &replacement) = delete;
0146 #endif
0147     RichString & replace(const QRegularExpression &regExp, const QString &replacement);
0148     RichString & replace(const QRegularExpression &regExp, const RichString &replacement);
0149 
0150     RichStringList split(const QString &sep, Qt::SplitBehaviorFlags behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0151     RichStringList split(const QChar &sep, Qt::SplitBehaviorFlags behavior = Qt::KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
0152     RichStringList split(const QRegularExpression &sep, Qt::SplitBehaviorFlags behavior = Qt::KeepEmptyParts) const;
0153 
0154     RichString left(int len) const;
0155     RichString right(int len) const;
0156     RichString mid(int index, int len = -1) const;
0157 
0158     RichString toLower() const;
0159     RichString toUpper() const;
0160     RichString toTitleCase(bool lowerFirst) const;
0161     RichString toSentenceCase(bool lowerFirst, bool *cont) const;
0162 
0163     RichString simplified() const;
0164     RichString trimmed() const;
0165 
0166     static void simplifyWhiteSpace(QString &text);
0167     void simplifyWhiteSpace();
0168 
0169     inline bool operator==(const RichString &richstring) const { return !operator!=(richstring); }
0170     bool operator!=(const RichString &richstring) const;
0171 
0172     inline int length() const { return QString::length(); }
0173 
0174 private:
0175     inline int length(int index, int len) const { return len < 0 || (index + len) > length() ? length() - index : len; }
0176 
0177 private:
0178     friend QDataStream & ::operator<<(QDataStream &stream, const RichString &string);
0179     friend QDataStream & ::operator>>(QDataStream &stream, RichString &string);
0180     friend struct ReplaceHelper;
0181     RichStringStyle *m_style;
0182 };
0183 
0184 }
0185 
0186 #endif