MuseScore  3.4
Music composition and notation
textbase.h
Go to the documentation of this file.
1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2014 Werner Schweer
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2
9 // as published by the Free Software Foundation and appearing in
10 // the file LICENCE.GPL
11 //=============================================================================
12 
13 #ifndef __TEXTBASE_H__
14 #define __TEXTBASE_H__
15 
16 #include "element.h"
17 #include "property.h"
18 #include "style.h"
19 
20 namespace Ms {
21 
22 class MuseScoreView;
23 struct SymCode;
24 class TextBase;
25 class TextBlock;
26 class ChangeText;
27 
28 //---------------------------------------------------------
29 // FrameType
30 //---------------------------------------------------------
31 
32 enum class FrameType : char {
34  };
35 
36 //---------------------------------------------------------
37 // VerticalAlignment
38 //---------------------------------------------------------
39 
40 enum class VerticalAlignment : char {
42  };
43 
44 //---------------------------------------------------------
45 // FormatId
46 //---------------------------------------------------------
47 
48 enum class FormatId : char {
50  };
51 
52 //---------------------------------------------------------
53 // MultiClick
54 //---------------------------------------------------------
55 
56 enum class MultiClick : char {
57  Double, Triple
58  };
59 
60 //---------------------------------------------------------
61 // CharFormat
62 //---------------------------------------------------------
63 
64 class CharFormat {
66  bool _preedit { false };
68  qreal _fontSize { 12.0 };
69  QString _fontFamily;
70 
71  public:
73  bool operator==(const CharFormat&) const;
74 
75  FontStyle style() const { return _style; }
76  void setStyle(FontStyle s) { _style = s; }
77  bool bold() const { return _style & FontStyle::Bold; }
78  bool italic() const { return _style & FontStyle::Italic; }
79  bool underline() const { return _style & FontStyle::Underline; }
80  void setBold(bool val) { _style = val ? _style + FontStyle::Bold : _style - FontStyle::Bold; }
81  void setItalic(bool val) { _style = val ? _style + FontStyle::Italic : _style - FontStyle::Italic; }
82  void setUnderline(bool val) { _style = val ? _style + FontStyle::Underline : _style - FontStyle::Underline; }
83 
84  bool preedit() const { return _preedit; }
85  VerticalAlignment valign() const { return _valign; }
86  qreal fontSize() const { return _fontSize; }
87  QString fontFamily() const { return _fontFamily; }
88  void setPreedit(bool val) { _preedit = val; }
89  void setValign(VerticalAlignment val) { _valign = val; }
90  void setFontSize(qreal val) { Q_ASSERT(val > 0.0); _fontSize = val; }
91  void setFontFamily(const QString& val) { _fontFamily = val; }
92 
93  void setFormat(FormatId, QVariant);
94  };
95 
96 //---------------------------------------------------------
97 // TextCursor
98 // Contains current position and start of selection
99 // during editing.
100 //---------------------------------------------------------
101 
102 class TextCursor {
105  int _row { 0 };
106  int _column { 0 };
107  int _selectLine { 0 }; // start of selection
108  int _selectColumn { 0 };
109 
110  public:
111  TextCursor(TextBase* t) : _text(t) {}
112 
113  TextBase* text() const { return _text; }
114  bool hasSelection() const { return (_selectLine != _row) || (_selectColumn != _column); }
115  void clearSelection();
116 
117  CharFormat* format() { return &_format; }
118  const CharFormat* format() const { return &_format; }
119  void setFormat(const CharFormat& f) { _format = f; }
120 
121  int row() const { return _row; }
122  int column() const { return _column; }
123  int selectLine() const { return _selectLine; }
124  int selectColumn() const { return _selectColumn; }
125  void setRow(int val) { _row = val; }
126  void setColumn(int val) { _column = val; }
127  void setSelectLine(int val) { _selectLine = val; }
128  void setSelectColumn(int val) { _selectColumn = val; }
129  int columns() const;
130  void init();
131 
132  TextBlock& curLine() const;
133  QRectF cursorRect() const;
134  bool movePosition(QTextCursor::MoveOperation op, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor, int count = 1);
135  void doubleClickSelect();
136  void moveCursorToEnd() { movePosition(QTextCursor::End); }
137  void moveCursorToStart() { movePosition(QTextCursor::Start); }
138  QChar currentCharacter() const;
139  bool set(const QPointF& p, QTextCursor::MoveMode mode = QTextCursor::MoveAnchor);
140  QString selectedText() const;
141  void updateCursorFormat();
142  void setFormat(FormatId, QVariant);
143  void changeSelectionFormat(FormatId id, QVariant val);
144  };
145 
146 //---------------------------------------------------------
147 // TextFragment
148 // contains a styled text
149 //---------------------------------------------------------
150 
152 
153  public:
155  QPointF pos; // y is relative to TextBlock->y()
156  mutable QString text;
157 
158  bool operator ==(const TextFragment& f) const;
159 
160  TextFragment();
161  TextFragment(const QString& s);
162  TextFragment(TextCursor*, const QString&);
163  TextFragment split(int column);
164  void draw(QPainter*, const TextBase*) const;
165  QFont font(const TextBase*) const;
166  int columns() const;
167  void changeFormat(FormatId id, QVariant data);
168  };
169 
170 //---------------------------------------------------------
171 // TextBlock
172 // represents a block of formatted text
173 //---------------------------------------------------------
174 
175 class TextBlock {
176  QList<TextFragment> _fragments;
177  qreal _y = 0;
179  QRectF _bbox;
180  bool _eol = false;
181 
182  void simplify();
183 
184  public:
186  bool operator ==(const TextBlock& x) { return _fragments == x._fragments; }
187  bool operator !=(const TextBlock& x) { return _fragments != x._fragments; }
188  void draw(QPainter*, const TextBase*) const;
189  void layout(TextBase*);
190  const QList<TextFragment>& fragments() const { return _fragments; }
191  QList<TextFragment>& fragments() { return _fragments; }
192  const QRectF& boundingRect() const { return _bbox; }
193  QRectF boundingRect(int col1, int col2, const TextBase*) const;
194  int columns() const;
195  void insert(TextCursor*, const QString&);
196  QString remove(int column);
197  QString remove(int start, int n);
198  int column(qreal x, TextBase*) const;
199  TextBlock split(int column);
200  qreal xpos(int col, const TextBase*) const;
201  const CharFormat* formatAt(int) const;
202  const TextFragment* fragment(int col) const;
203  QList<TextFragment>::iterator fragment(int column, int* rcol, int* ridx);
204  qreal y() const { return _y; }
205  void setY(qreal val) { _y = val; }
206  qreal lineSpacing() const { return _lineSpacing; }
207  QString text(int, int) const;
208  bool eol() const { return _eol; }
209  void setEol(bool val) { _eol = val; }
210  void changeFormat(FormatId, QVariant val, int start, int n);
211  };
212 
213 //---------------------------------------------------------
214 // TextBase
215 //---------------------------------------------------------
216 
217 class TextBase : public Element {
218  // sorted by size to allow for most compact memory layout
219  M_PROPERTY(FontStyle, fontStyle, setFontStyle)
220  M_PROPERTY(Align, align, setAlign)
221  M_PROPERTY(FrameType, frameType, setFrameType)
222  M_PROPERTY(QString, family, setFamily)
223  M_PROPERTY(qreal, size, setSize)
224  M_PROPERTY(QColor, bgColor, setBgColor)
225  M_PROPERTY(QColor, frameColor, setFrameColor)
226  M_PROPERTY(Spatium, frameWidth, setFrameWidth)
227  M_PROPERTY(Spatium, paddingWidth, setPaddingWidth)
228  M_PROPERTY(int, frameRound, setFrameRound)
229 
230  // there are two representations of text; only one
231  // might be valid and the other can be constructed from it
232 
233  mutable QString _text; // cached
234  mutable bool textInvalid { true };
235 
236  QList<TextBlock> _layout;
237  bool layoutInvalid { true };
238  Tid _tid; // text style id
239 
240  QString preEdit; // move to EditData?
241  bool _layoutToParentWidth { false };
242 
243  int hexState { -1 };
244  bool _primed { 0 };
245 
246  void drawSelection(QPainter*, const QRectF&) const;
247  void insert(TextCursor*, uint code);
248  void genText() const;
249  virtual int getPropertyFlagsIdx(Pid id) const override;
250  QString stripText(bool, bool, bool) const;
251 
252  protected:
253  QColor textColor() const;
254  QRectF frame; // calculated in layout()
255  void layoutFrame();
256  void layoutEdit();
257  void createLayout();
258  void insertSym(EditData& ed, SymId id);
259 
260  public:
263  TextBase(const TextBase&);
264 
265  virtual bool mousePress(EditData&) override;
266 
267  Text &operator=(const Text&) = delete;
268 
269  virtual void draw(QPainter*) const override;
270  virtual void drawEditMode(QPainter* p, EditData& ed) override;
271 
272  void setPlainText(const QString&);
273  void setXmlText(const QString&);
274  QString xmlText() const;
275  QString plainText() const;
276 
277  void insertText(EditData&, const QString&);
278 
279  virtual void layout() override;
280  virtual void layout1();
281  qreal lineSpacing() const;
282  qreal lineHeight() const;
283  virtual qreal baseLine() const override;
284 
285  bool empty() const { return xmlText().isEmpty(); }
286  void clear() { setXmlText(QString()); }
287 
288  bool layoutToParentWidth() const { return _layoutToParentWidth; }
289  void setLayoutToParentWidth(bool v) { _layoutToParentWidth = v; }
290 
291  virtual void startEdit(EditData&) override;
292  virtual bool edit(EditData&) override;
293  virtual void editCut(EditData&) override;
294  virtual void editCopy(EditData&) override;
295  virtual void endEdit(EditData&) override;
296  void movePosition(EditData&, QTextCursor::MoveOperation);
297 
298  bool deleteSelectedText(EditData&);
299 
300  void selectAll(TextCursor*);
301  void multiClickSelect(EditData&, MultiClick);
302  bool isPrimed() const { return _primed; }
303  void setPrimed(bool primed) { _primed = primed; }
304 
305  virtual void write(XmlWriter& xml) const override;
306  virtual void read(XmlReader&) override;
307  virtual void writeProperties(XmlWriter& xml) const { writeProperties(xml, true, true); }
308  void writeProperties(XmlWriter& xml, bool writeText) const { writeProperties(xml, writeText, true); }
309  void writeProperties(XmlWriter&, bool, bool) const;
310  bool readProperties(XmlReader&);
311 
312  virtual void paste(EditData&);
313 
314  QRectF pageRectangle() const;
315 
316  void dragTo(EditData&);
317 
318  virtual QLineF dragAnchor() const override;
319 
320  virtual bool acceptDrop(EditData&) const override;
321  virtual Element* drop(EditData&) override;
322 
323  friend class TextBlock;
324  friend class TextFragment;
325  QString convertFromHtml(const QString& ss) const;
326  static QString convertToHtml(const QString&, const TextStyle&);
327  static QString tagEscape(QString s);
328  static QString unEscape(QString s);
329  static QString escape(QString s);
330 
331  virtual QString accessibleInfo() const override;
332  virtual QString screenReaderInfo() const override;
333 
334  virtual int subtype() const override;
335  virtual QString subtypeName() const override;
336 
337  QList<TextFragment> fragmentList() const; // for MusicXML formatted export
338 
339  static bool validateText(QString& s);
340  bool inHexState() const { return hexState >= 0; }
341  void endHexState(EditData&);
342  void inputTransition(EditData&, QInputMethodEvent*);
343 
344  QFont font() const;
345  QFontMetricsF fontMetrics() const;
346 
347  virtual QVariant getProperty(Pid propertyId) const override;
348  virtual bool setProperty(Pid propertyId, const QVariant& v) override;
349  virtual QVariant propertyDefault(Pid id) const override;
350  virtual void undoChangeProperty(Pid id, const QVariant& v, PropertyFlags ps) override;
351  virtual Pid propertyId(const QStringRef& xmlName) const override;
352  virtual Sid getPropertyStyle(Pid) const;
353  virtual void styleChanged();
354  void editInsertText(TextCursor*, const QString&);
355 
356  TextCursor* cursor(const EditData&);
357  const TextBlock& textBlock(int line) const { return _layout[line]; }
358  TextBlock& textBlock(int line) { return _layout[line]; }
359  QList<TextBlock>& textBlockList() { return _layout; }
360  int rows() const { return _layout.size(); }
361 
362  void setTextInvalid() { textInvalid = true; }
363  bool isTextInvalid() const { return textInvalid; }
364  void setLayoutInvalid() { layoutInvalid = true; }
365  bool isLayoutInvalid() const { return layoutInvalid; }
366 
367  // helper functions
368  bool hasFrame() const { return _frameType != FrameType::NO_FRAME; }
369  bool circle() const { return _frameType == FrameType::CIRCLE; }
370  bool square() const { return _frameType == FrameType::SQUARE; }
371 
372  Tid tid() const { return _tid; }
373  void setTid(Tid id) { _tid = id; }
374  void initTid(Tid id);
375  void initTid(Tid id, bool preserveDifferent);
376  virtual void initElementStyle(const ElementStyle*) override;
377 
378  bool bold() const { return _fontStyle & FontStyle::Bold; }
379  bool italic() const { return _fontStyle & FontStyle::Italic; }
380  bool underline() const { return _fontStyle & FontStyle::Underline; }
381  void setBold(bool val) { _fontStyle = val ? _fontStyle + FontStyle::Bold : _fontStyle - FontStyle::Bold; }
382  void setItalic(bool val) { _fontStyle = val ? _fontStyle + FontStyle::Italic : _fontStyle - FontStyle::Italic; }
383  void setUnderline(bool val) { _fontStyle = val ? _fontStyle + FontStyle::Underline : _fontStyle - FontStyle::Underline; }
384 
385  bool hasCustomFormatting() const;
386 
387  friend class TextCursor;
389  };
390 
391 } // namespace Ms
392 
393 #endif
394 
bool circle() const
Definition: textbase.h:369
TextBlock & textBlock(int line)
Definition: textbase.h:358
void setFontFamily(const QString &val)
Definition: textbase.h:91
void setLayoutInvalid()
Definition: textbase.h:364
void setTid(Tid id)
Definition: textbase.h:373
int row() const
Definition: textbase.h:121
QList< TextFragment > _fragments
Definition: textbase.h:176
void setPreedit(bool val)
Definition: textbase.h:88
Pid
Definition: property.h:62
Definition: textbase.h:151
Definition: xml.h:67
virtual void undoChangeProperty(Pid id, const QVariant &, PropertyFlags ps)
Definition: scoreElement.cpp:291
void setItalic(bool val)
Definition: textbase.h:382
bool underline() const
Definition: textbase.h:79
void writeProperties(XmlWriter &xml, bool writeText) const
Definition: textbase.h:308
TextBlock()
Definition: textbase.h:185
void setBold(bool val)
Definition: textbase.h:80
QRectF frame
Definition: textbase.h:254
qreal _lineSpacing
Definition: textbase.h:178
QFlags< ElementFlag > ElementFlags
Definition: element.h:101
FormatId
Definition: textbase.h:48
Definition: textbase.h:64
bool bold() const
Definition: textbase.h:378
Definition: textbase.h:102
QList< TextBlock > _layout
Definition: textbase.h:236
void setStyle(FontStyle s)
Definition: textbase.h:76
std::vector< StyledProperty > ElementStyle
Definition: style.h:1339
bool inHexState() const
Definition: textbase.h:340
void setUnderline(bool val)
Definition: textbase.h:383
SymId
Definition: sym.h:30
Base class of score layout elements.
Definition: element.h:158
bool isLayoutInvalid() const
Definition: textbase.h:365
FontStyle
Definition: types.h:468
QString convertFromHtml(TextBase *t, const QString &ss)
Definition: read114.cpp:240
QString text
Definition: textbase.h:156
QString preEdit
Definition: textbase.h:240
bool isTextInvalid() const
Definition: textbase.h:363
CharFormat()
Definition: textbase.h:72
qreal lineSpacing() const
Definition: textbase.h:206
QString _fontFamily
Definition: textbase.h:69
bool preedit() const
Definition: textbase.h:84
TextBase * text() const
Definition: textbase.h:113
Definition: score.h:391
bool hasSelection() const
Definition: textbase.h:114
std::array< StyledProperty, TEXT_STYLE_SIZE > TextStyle
Definition: style.h:1343
void moveCursorToEnd()
Definition: textbase.h:136
int rows() const
Definition: textbase.h:360
PropertyFlags
Definition: property.h:54
const CharFormat * format() const
Definition: textbase.h:118
void setUnderline(bool val)
Definition: textbase.h:82
bool italic() const
Definition: textbase.h:379
void setBold(bool val)
Definition: textbase.h:381
VerticalAlignment valign() const
Definition: textbase.h:85
TextBase * _text
Definition: textbase.h:103
Definition: textbase.h:175
FrameType
Definition: textbase.h:32
bool isPrimed() const
Definition: textbase.h:302
Tid
Enumerates the list of built-in text substyles.
Definition: types.h:371
const QList< TextFragment > & fragments() const
Definition: textbase.h:190
#define M_PROPERTY(a, b, c)
Definition: property.h:36
bool underline() const
Definition: textbase.h:380
QList< TextBlock > & textBlockList()
Definition: textbase.h:359
VerticalAlignment
Definition: textbase.h:40
Definition: textbase.h:217
Definition: aeolus.cpp:26
void setFontSize(qreal val)
Definition: textbase.h:90
bool bold() const
Definition: textbase.h:77
const QRectF & boundingRect() const
Definition: textbase.h:192
Definition: spatium.h:25
QString fontFamily() const
Definition: textbase.h:87
void setItalic(bool val)
Definition: textbase.h:81
Sid
Definition: style.h:33
void setFormat(const CharFormat &f)
Definition: textbase.h:119
bool italic() const
Definition: textbase.h:78
Definition: xml.h:218
bool square() const
Definition: textbase.h:370
QPointF pos
Definition: textbase.h:155
int column() const
Definition: textbase.h:122
FontStyle style() const
Definition: textbase.h:75
qreal fontSize() const
Definition: textbase.h:86
void setTextInvalid()
Definition: textbase.h:362
void setLayoutToParentWidth(bool v)
Definition: textbase.h:289
void setSelectLine(int val)
Definition: textbase.h:127
MultiClick
Definition: textbase.h:56
CharFormat * format()
Definition: textbase.h:117
Definition: element.h:111
void setEol(bool val)
Definition: textbase.h:209
CharFormat _format
Definition: textbase.h:104
void setPrimed(bool primed)
Definition: textbase.h:303
const TextBlock & textBlock(int line) const
Definition: textbase.h:357
QRectF _bbox
Definition: textbase.h:179
bool layoutToParentWidth() const
Definition: textbase.h:288
Tid tid() const
Definition: textbase.h:372
QList< TextFragment > & fragments()
Definition: textbase.h:191
bool hasFrame() const
Definition: textbase.h:368
CharFormat format
Definition: textbase.h:154
int selectLine() const
Definition: textbase.h:123
Align
Definition: types.h:439
Definition: text.h:24
void setRow(int val)
Definition: textbase.h:125
void moveCursorToStart()
Definition: textbase.h:137
virtual void writeProperties(XmlWriter &xml) const
Definition: textbase.h:307
Pid propertyId(const QStringRef &s)
Definition: property.cpp:347
void setValign(VerticalAlignment val)
Definition: textbase.h:89
Tid _tid
Definition: textbase.h:238
bool empty() const
Definition: textbase.h:285
void setColumn(int val)
Definition: textbase.h:126
void clear()
Definition: textbase.h:286
int selectColumn() const
Definition: textbase.h:124
TextCursor(TextBase *t)
Definition: textbase.h:111
void setY(qreal val)
Definition: textbase.h:205
void setSelectColumn(int val)
Definition: textbase.h:128
qreal y() const
Definition: textbase.h:204
bool eol() const
Definition: textbase.h:208