    //=============================================================================
    //  MuseScore
    //  Music Composition & Notation
    //
    //  Copyright (C) 2014 Werner Schweer
    //
    //  This program is free software; you can redistribute it and/or modify
    //  it under the terms of the GNU General Public License version 2
    //  as published by the Free Software Foundation and appearing in
    //  the file LICENCE.GPL
    //=============================================================================

    #ifndef __SIMPLETEXT_H__
    #define __SIMPLETEXT_H__

    #include "element.h"
    #include "elementlayout.h"
    #include "property.h"

    namespace Ms {

    class MuseScoreView;
    struct SymCode;
    class Text;
    class TextBlock;
    class ChangeText;

    enum class VerticalAlignment : char { AlignNormal, AlignSuperScript, AlignSubScript };
    enum class FormatId : char          { Bold, Italic, Underline, Valign, FontSize, FontFamily };

    //---------------------------------------------------------
    //   CharFormat
    //---------------------------------------------------------

    class CharFormat {
          bool _bold                { false };
          bool _italic              { false };
          bool _underline           { false };
          bool _preedit             { false };
          VerticalAlignment _valign { VerticalAlignment::AlignNormal };
          qreal _fontSize           { 12.0  };
          QString _fontFamily;

       public:
          CharFormat() {}
          bool operator==(const CharFormat&) const;
          bool bold() const                      { return _bold;        }
          bool italic() const                    { return _italic;      }
          bool underline() const                 { return _underline;   }
          bool preedit() const                   { return _preedit;     }
          VerticalAlignment valign() const       { return _valign;      }
          qreal fontSize() const                 { return _fontSize;    }
          QString fontFamily() const             { return _fontFamily;  }

          void setBold(bool val)                 { _bold        = val;  }
          void setItalic(bool val)               { _italic      = val;  }
          void setUnderline(bool val)            { _underline   = val;  }
          void setPreedit(bool val)              { _preedit     = val;  }
          void setValign(VerticalAlignment val)  { _valign      = val;  }
          void setFontSize(qreal val)            { Q_ASSERT(val > 0.0); _fontSize = val; }
          void setFontFamily(const QString& val) { _fontFamily  = val;  }

          void setFormat(FormatId, QVariant);
          };

    //---------------------------------------------------------
    //   TextCursor
    //    Contains current position and start of selection
    //    during editing.
    //---------------------------------------------------------

    class TextCursor {
          Text*      _text;
          CharFormat _format;
          int _row           { 0 };
          int _column        { 0 };
          int _selectLine    { 0 };         // start of selection
          int _selectColumn  { 0 };

       public:
          TextCursor(Text* t) : _text(t) {}

          Text* text() const        { return _text; }
          bool hasSelection() const { return (_selectLine != _row) || (_selectColumn != _column); }
          void clearSelection();

          CharFormat* format()                { return &_format;  }
          const CharFormat* format() const    { return &_format;  }
          void setFormat(const CharFormat& f) { _format = f;      }

          int row() const               { return _row; }
          int column() const            { return _column; }
          int selectLine() const        { return _selectLine; }
          int selectColumn() const      { return _selectColumn; }
          void setRow(int val)          { _row = val; }
          void setColumn(int val)       { _column = val; }
          void setSelectLine(int val)   { _selectLine = val; }
          void setSelectColumn(int val) { _selectColumn = val; }
          void setText(Text* t)         { _text = t; }
          int columns() const;
          void init();

          TextBlock& curLine() const;
          QRectF cursorRect() const;
          bool movePosition(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor, int count = 1);
          void moveCursorToEnd()   { movePosition(QTextCursor::End);   }
          void moveCursorToStart() { movePosition(QTextCursor::Start); }
          QChar currentCharacter() const;
          bool set(const QPointF& p, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
          QString selectedText() const;
          void updateCursorFormat();
          void setFormat(FormatId, QVariant);
          void changeSelectionFormat(FormatId id, QVariant val);
          bool deleteChar() const;
          };

    class Text;

    //---------------------------------------------------------
    //   TextFragment
    //    contains a styled text
    //---------------------------------------------------------

    class TextFragment {

       public:
          mutable CharFormat format;
          QPointF pos;                  // y is relative to TextBlock->y()

          mutable QString text;

          bool operator ==(const TextFragment& f) const;

          TextFragment();
          TextFragment(const QString& s);
          TextFragment(TextCursor*, const QString&);
          TextFragment split(int column);
          void draw(QPainter*, const Text*) const;
          QFont font(const Text*) const;
          int columns() const;
          void changeFormat(FormatId id, QVariant data);
          };

    //---------------------------------------------------------
    //   TextBlock
    //    represents a block of formatted text
    //---------------------------------------------------------

    class TextBlock {
          QList<TextFragment> _fragments;
          qreal  _y = 0;
          qreal _lineSpacing;
          QRectF _bbox;
          bool _eol = false;

          void simplify();

       public:
          TextBlock() {}
          bool operator ==(const TextBlock& x)         { return _fragments == x._fragments; }
          bool operator !=(const TextBlock& x)         { return _fragments != x._fragments; }
          void draw(QPainter*, const Text*) const;
          void layout(Text*);
          const QList<TextFragment>& fragments() const { return _fragments; }
          QList<TextFragment>& fragments()             { return _fragments; }
          const QRectF& boundingRect() const           { return _bbox; }
          QRectF boundingRect(int col1, int col2, const Text*) const;
          int columns() const;
          void insert(TextCursor*, const QString&);
          QString remove(int column);
          QString remove(int start, int n);
          int column(qreal x, Text*) const;
          TextBlock split(int column);
          qreal xpos(int col, const Text*) const;
          const CharFormat* formatAt(int) const;
          const TextFragment* fragment(int col) const;
          QList<TextFragment>::iterator fragment(int column, int* rcol, int* ridx);
          qreal y() const           { return _y; }
          void setY(qreal val)      { _y = val; }
          qreal lineSpacing() const { return _lineSpacing; }
          QString text(int, int) const;
          bool eol() const          { return _eol; }
          void setEol(bool val)     { _eol = val; }
          void changeFormat(FormatId, QVariant val, int start, int n);
          };

    //---------------------------------------------------------
    //   Text
    //---------------------------------------------------------

    class Text : public Element {
          Q_GADGET

    #define PROP(a,b,c)                                            \
          a _ ## b;                                                \
          PropertyFlags _ ## b ## Style { PropertyFlags::STYLED }; \
       public:                                                     \
          const a& b() const   { return _ ## b; }                  \
          void c(const a& val) { _ ## b = val;  }                  \
       private:

          PROP(QString, family,                 setFamily)
          PROP(qreal,   size,                   setSize)
          PROP(bool,    bold,                   setBold)
          PROP(bool,    italic,                 setItalic)
          PROP(bool,    underline,              setUnderline)
          PROP(QColor,  bgColor,                setBgColor)
          PROP(QColor,  frameColor,             setFrameColor)
          PROP(Align,   align,                  setAlign)
          PROP(bool,    hasFrame,               setHasFrame)
          PROP(bool,    circle,                 setCircle)
          PROP(bool,    square,                 setSquare)
          PROP(bool,    sizeIsSpatiumDependent, setSizeIsSpatiumDependent)
          PROP(Spatium, frameWidth,             setFrameWidth)
          PROP(Spatium, paddingWidth,           setPaddingWidth)
          PROP(int,     frameRound,             setFrameRound)
          PROP(QPointF, offset,                 setOffset)            // inch or spatium
          PROP(OffsetType, offsetType,          setOffsetType)
    #undef PROP

          SubStyle _subStyle;

          // there are two representations of text; only one
          // might be valid and the other can be constructed from it

          QString _text;
          QList<TextBlock> _layout;
          bool textInvalid              { true  };
          bool layoutInvalid            { true  };

          QString preEdit;              // move to EditData?
          bool _layoutToParentWidth     { false };

          int  hexState                 { -1    };

          void drawSelection(QPainter*, const QRectF&) const;

          void insert(TextCursor*, uint code);
          void genText();

          PropertyFlags* propertyFlagsP(P_ID id);

       protected:
          QColor textColor() const;
          QRectF frame;           // calculated in layout()
          void layoutFrame();
          void layoutEdit();
          void createLayout();
          void insertSym(EditData& ed, SymId id);

       public:
          Text(Score* = 0);
          Text(SubStyle, Score* = 0);
          Text(const Text&);
          ~Text();

          SubStyle subStyle() const                    { return _subStyle; }
          void setSubStyle(SubStyle ss)                { _subStyle = ss;   }
          virtual void initSubStyle(SubStyle) override;

          virtual Text* clone() const override         { return new Text(*this); }
          virtual ElementType type() const override    { return ElementType::TEXT; }
          virtual bool mousePress(EditData&) override;

          Text &operator=(const Text&) = delete;

          virtual void draw(QPainter*) const override;
          virtual void drawEditMode(QPainter* p, EditData& ed) override;

          void setPlainText(const QString&);
          void setXmlText(const QString&);
          QString xmlText() const;
          QString plainText() const;

          void insertText(EditData&, const QString&);

          virtual void layout() override;
          virtual void layout1();
          qreal lineSpacing() const;
          qreal lineHeight() const;
          virtual qreal baseLine() const override;

          bool empty() const                  { return xmlText().isEmpty(); }
          void clear()                        { setXmlText(QString());      }

          bool layoutToParentWidth() const    { return _layoutToParentWidth; }
          void setLayoutToParentWidth(bool v) { _layoutToParentWidth = v;   }

          virtual void startEdit(EditData&) override;
          virtual bool edit(EditData&) override;
          virtual void editCut(EditData&) override;
          virtual void editCopy(EditData&) override;
          virtual void endEdit(EditData&) override;

          bool deleteSelectedText(EditData&);

          void selectAll(TextCursor*);

          virtual void write(XmlWriter& xml) const override;
          virtual void read(XmlReader&) override;
          virtual void writeProperties(XmlWriter& xml) const { writeProperties(xml, true, true); }
          void writeProperties(XmlWriter& xml, bool writeText) const { writeProperties(xml, writeText, true); }
          void writeProperties(XmlWriter&, bool, bool) const;
          bool readProperties(XmlReader&);

          void spellCheckUnderline(bool) {}
          virtual void styleChanged() override;

          virtual void paste(EditData&);

          QRectF pageRectangle() const;

          void dragTo(EditData&);

          virtual QLineF dragAnchor() const override;

          virtual bool acceptDrop(EditData&) const override;
          virtual Element* drop(EditData&) override;

          friend class TextBlock;
          friend class TextFragment;
          virtual void textChanged() {}
          QString convertFromHtml(const QString& ss) const;
          static QString convertToHtml(const QString&, const TextStyle&);
          static QString tagEscape(QString s);
          static QString unEscape(QString s);
          static QString escape(QString s);

          void undoSetText(const QString& s) { undoChangeProperty(P_ID::TEXT, s); }
          virtual QString accessibleInfo() const override;
          virtual QString screenReaderInfo() const override;

          virtual int subtype() const;
          virtual QString subtypeName() const;

          QList<TextFragment> fragmentList() const; // for MusicXML formatted export

          static bool validateText(QString& s);
          bool inHexState() const { return hexState >= 0; }
          void endHexState();
          void inputTransition(QInputMethodEvent*);

          QFont font() const;
          QFontMetricsF fontMetrics() const;

          virtual QVariant getProperty(P_ID propertyId) const override;
          virtual bool setProperty(P_ID propertyId, const QVariant& v) override;
          virtual QVariant propertyDefault(P_ID id) const override;
          virtual void setPropertyFlags(P_ID, PropertyFlags) override;
          virtual PropertyFlags propertyFlags(P_ID) const override;
          virtual void resetProperty(P_ID id) override;
          virtual StyleIdx getPropertyStyle(P_ID) const override;
          virtual void reset() override;

          void editInsertText(TextCursor*, const QString&);

          TextCursor* cursor(EditData&);
          const TextBlock& textBlock(int line) const { return _layout[line]; }
          TextBlock& textBlock(int line)             { return _layout[line]; }
          QList<TextBlock>& textBlockList()          { return _layout; }
          int rows() const                           { return _layout.size(); }

          void setTextInvalid()                      { textInvalid = true;  };

          friend class TextCursor;
          };

    }     // namespace Ms

    #endif

↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: _lineSpacing.