File: xml.h

package info (click to toggle)
musescore3 3.2.3%2Bdfsg2-11
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 210,672 kB
  • sloc: cpp: 291,093; xml: 200,238; sh: 3,779; ansic: 1,447; python: 393; makefile: 240; perl: 82; pascal: 79
file content (320 lines) | stat: -rw-r--r-- 12,971 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
//=============================================================================
//  MuseScore
//  Music Composition & Notation
//
//  Copyright (C) 2004-2011 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 __XML_H__
#define __XML_H__

#include "connector.h"
#include "stafftype.h"
#include "interval.h"
#include "element.h"
#include "select.h"

namespace Ms {

enum class PlaceText : char;
enum class ClefType : signed char;
class Spanner;
class Beam;
class Tuplet;
class Measure;
class LinkedElements;

//---------------------------------------------------------
//   SpannerValues
//---------------------------------------------------------

struct SpannerValues {
      int spannerId;
      Fraction tick2;
      int track2;
      };

//---------------------------------------------------------
//   TextStyleMap
//---------------------------------------------------------

struct TextStyleMap {
      QString name;
      Tid ss;
      };

//---------------------------------------------------------
//   LinksIndexer
//---------------------------------------------------------

class LinksIndexer {
      int _lastLocalIndex              { -1                    };
      Location _lastLinkedElementLoc   { Location::absolute()  };

   public:
      int assignLocalIndex(const Location& mainElementInfo);
      };

//---------------------------------------------------------
//   XmlReader
//---------------------------------------------------------

class XmlReader : public QXmlStreamReader {
      QString docName;  // used for error reporting

      // For readahead possibility.
      // If needed, must be explicitly set by setReadAheadDevice.
      QIODevice* _readAheadDevice = nullptr;

      // Score read context (for read optimizations):
      Fraction _tick             { Fraction(0, 1) };
      Fraction _tickOffset       { Fraction(0, 1) };
      int _intTick          { 0       };
      int _track            { 0       };
      int _trackOffset      { 0       };
      bool _pasteMode       { false   };        // modifies read behaviour on paste operation
      Measure* _lastMeasure { 0       };
      Measure* _curMeasure  { 0       };
      int _curMeasureIdx    { 0       };
      QHash<int, Beam*>    _beams;
      QHash<int, Tuplet*>  _tuplets;

      QList<SpannerValues> _spannerValues;
      QList<std::pair<int,Spanner*>> _spanner;
      QList<StaffType> _staffTypes;
      QList<std::pair<Element*, QPointF>> _fixOffsets;

      std::vector<std::unique_ptr<ConnectorInfoReader>> _connectors;
      std::vector<std::unique_ptr<ConnectorInfoReader>> _pendingConnectors; // connectors that are pending to be updated and added to _connectors. That will happen when checkConnectors() is called.

      void htmlToString(int level, QString*);
      Interval _transpose;
      QMap<int, LinkedElements*> _elinks; // for reading old files (< 3.01)
      QMap<int, QList<QPair<LinkedElements*, Location>>> _staffLinkedElements; // one list per staff
      LinksIndexer _linksIndexer;
      QMultiMap<int, int> _tracks;

      QList<TextStyleMap> userTextStyles;

      void addConnectorInfo(std::unique_ptr<ConnectorInfoReader>);
      void removeConnector(const ConnectorInfoReader*); // Removes the whole ConnectorInfo chain from the connectors list.

   public:
      XmlReader(QFile* f) : QXmlStreamReader(f), docName(f->fileName()) {}
      XmlReader(const QByteArray& d, const QString& st = QString()) : QXmlStreamReader(d), docName(st)  {}
      XmlReader(QIODevice* d, const QString& st = QString()) : QXmlStreamReader(d), docName(st) {}
      XmlReader(const QString& d, const QString& st = QString()) : QXmlStreamReader(d), docName(st) {}
      XmlReader(const XmlReader&) = delete;
      XmlReader& operator=(const XmlReader&) = delete;
      ~XmlReader();

      bool hasAccidental;                     // used for userAccidental backward compatibility
      void unknown();

      // attribute helper routines:
      QString attribute(const char* s) const { return attributes().value(s).toString(); }
      QString attribute(const char* s, const QString&) const;
      int intAttribute(const char* s) const;
      int intAttribute(const char* s, int _default) const;
      double doubleAttribute(const char* s) const;
      double doubleAttribute(const char* s, double _default) const;
      bool hasAttribute(const char* s) const;

      // helper routines based on readElementText():
      int readInt()            { return readElementText().toInt();      }
      int readInt(bool* ok)    { return readElementText().toInt(ok);    }
      int readIntHex()         { return readElementText().toInt(0, 16); }
      double readDouble()      { return readElementText().toDouble();   }
      qlonglong readLongLong() { return readElementText().toLongLong(); }

      double readDouble(double min, double max);
      bool readBool();
      QPointF readPoint();
      QSizeF readSize();
      QRectF readRect();
      QColor readColor();
      Fraction readFraction();
      QString readXml();

      void setDocName(const QString& s) { docName = s; }
      QString getDocName() const        { return docName; }

      Fraction tick()  const            { return _tick + _tickOffset; }
      Fraction rtick()  const ;
      void setTick(const Fraction& f);
      void incTick(const Fraction& f);
      void setTickOffset(const Fraction& val) { _tickOffset = val; }

      int track() const            { return _track + _trackOffset;     }
      void setTrackOffset(int val) { _trackOffset = val;   }
      int trackOffset() const      { return _trackOffset;   }
      void setTrack(int val)       { _track = val;      }
      bool pasteMode() const       { return _pasteMode; }
      void setPasteMode(bool v)    { _pasteMode = v;    }

      Location location(bool forceAbsFrac = false) const;
      void fillLocation(Location&, bool forceAbsFrac = false) const;
      void setLocation(const Location&); // sets a new reading point, taking into
                                         // account its type (absolute or relative).

      void addBeam(Beam* s);
      Beam* findBeam(int id) const          { return _beams.value(id);   }

      void addTuplet(Tuplet* s);
      Tuplet* findTuplet(int id) const      { return _tuplets.value(id); }
      QHash<int, Tuplet*>& tuplets()        { return _tuplets; }

      void setLastMeasure(Measure* m)       { _lastMeasure = m;    }
      Measure* lastMeasure() const          { return _lastMeasure; }
      void setCurrentMeasure(Measure* m)    { _curMeasure = m; }
      Measure* currentMeasure() const       { return _curMeasure; }
      void setCurrentMeasureIndex(int idx)  { _curMeasureIdx = idx;  }
      int currentMeasureIndex() const       { return _curMeasureIdx; }

      void removeSpanner(const Spanner*);
      void addSpanner(int id, Spanner*);
      Spanner* findSpanner(int id);

      int spannerId(const Spanner*);      // returns spanner id, allocates new one if none exists

      void addSpannerValues(const SpannerValues& sv) { _spannerValues.append(sv); }
      const SpannerValues* spannerValues(int id) const;

      void addConnectorInfoLater(std::unique_ptr<ConnectorInfoReader> c) { _pendingConnectors.push_back(std::move(c)); } // add connector info to be checked after calling checkConnectors()
      void checkConnectors();
      void reconnectBrokenConnectors();

      QList<StaffType>& staffType()     { return _staffTypes; }
      Interval transpose() const        { return _transpose; }
      void setTransposeChromatic(int v) { _transpose.chromatic = v; }
      void setTransposeDiatonic(int v)  { _transpose.diatonic = v; }

      LinkedElements* getLink(bool masterScore, const Location& l, int localIndexDiff);
      void addLink(Staff* staff, LinkedElements* link);
      QMap<int, LinkedElements*>& linkIds() { return _elinks;     }
      QMultiMap<int, int>& tracks()         { return _tracks;     }

      void checkTuplets();
      Tid addUserTextStyle(const QString& name);
      Tid lookupUserTextStyle(const QString& name);

      // Ownership on read ahead device is NOT transfered to XmlReader.
      void setReadAheadDevice(QIODevice* dev) { if (!dev->isSequential()) _readAheadDevice = dev; }
      bool readAheadAvailable() const { return bool(_readAheadDevice); }
      void performReadAhead(std::function<void(QIODevice&)> readAheadRoutine);

      QList<std::pair<Element*, QPointF>>& fixOffsets() { return  _fixOffsets; }
      };

//---------------------------------------------------------
//   XmlWriter
//---------------------------------------------------------

class XmlWriter : public QTextStream {
      static const int BS = 2048;

      Score* _score;
      QList<QString> stack;
      SelectionFilter _filter;

      Fraction _curTick    { 0, 1 };     // used to optimize output
      Fraction _tickDiff   { 0, 1 };
      int _curTrack        { -1 };
      int _trackDiff       { 0 };       // saved track is curTrack-trackDiff

      bool _clipboardmode  { false };   // used to modify write() behaviour
      bool _excerptmode    { false };   // true when writing a part
      bool _writeOmr       { true };    // false if writing into *.msc file
      bool _writeTrack     { false };
      bool _writePosition  { false };

      LinksIndexer _linksIndexer;
      QMap<int, int> _lidLocalIndices;

      std::vector<std::pair<const ScoreElement*, QString>> _elements;
      bool _recordElements = false;

      void putLevel();

   public:
      XmlWriter(Score*);
      XmlWriter(Score* s, QIODevice* dev);

      Fraction curTick() const            { return _curTick; }
      void setCurTick(const Fraction& v)  { _curTick   = v; }
      void incCurTick(const Fraction& v)  { _curTick += v; }

      int curTrack() const                { return _curTrack; }
      void setCurTrack(int v)             { _curTrack  = v; }

      Fraction tickDiff() const           { return _tickDiff; }
      void setTickDiff(const Fraction& v) { _tickDiff  = v; }

      int trackDiff() const               { return _trackDiff; }
      void setTrackDiff(int v)            { _trackDiff = v; }

      bool clipboardmode() const          { return _clipboardmode; }
      bool excerptmode() const            { return _excerptmode;   }
      bool writeOmr() const               { return _writeOmr;   }
      bool writeTrack() const             { return _writeTrack;    }
      bool writePosition() const          { return _writePosition; }

      void setClipboardmode(bool v)       { _clipboardmode = v; }
      void setExcerptmode(bool v)         { _excerptmode = v;   }
      void setWriteOmr(bool v)            { _writeOmr = v;      }
      void setWriteTrack(bool v)          { _writeTrack= v;     }
      void setWritePosition(bool v)       { _writePosition = v; }

      int assignLocalIndex(const Location& mainElementLocation);
      void setLidLocalIndex(int lid, int localIndex) { _lidLocalIndices.insert(lid, localIndex); }
      int lidLocalIndex(int lid) const { return _lidLocalIndices[lid]; }

      const std::vector<std::pair<const ScoreElement*, QString>>& elements() const { return _elements; }
      void setRecordElements(bool record) { _recordElements = record; }

      void sTag(const char* name, Spatium sp) { XmlWriter::tag(name, QVariant(sp.val())); }
      void pTag(const char* name, PlaceText);

      void header();

      void stag(const QString&);
      void etag();

      void stag(const ScoreElement* se, const QString& attributes = QString());
      void stag(const QString& name, const ScoreElement* se, const QString& attributes = QString());

      void tagE(const QString&);
      void tagE(const char* format, ...);
      void ntag(const char* name);
      void netag(const char* name);

      void tag(Pid id, void* data, void* defaultVal);
      void tag(Pid id, QVariant data, QVariant defaultData = QVariant());
      void tag(const char* name, QVariant data, QVariant defaultData = QVariant());
      void tag(const QString&, QVariant data);
      void tag(const char* name, const char* s)    { tag(name, QVariant(s)); }
      void tag(const char* name, const QString& s) { tag(name, QVariant(s)); }
      void tag(const char* name, const QWidget*);

      void comment(const QString&);

      void writeXml(const QString&, QString s);
      void dump(int len, const unsigned char* p);

      void setFilter(SelectionFilter f) { _filter = f; }
      bool canWrite(const Element*) const;
      bool canWriteVoice(int track) const;

      static QString xmlString(const QString&);
      static QString xmlString(ushort c);
      };

extern PlaceText readPlacement(XmlReader&);
}     // namespace Ms
#endif