1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2002-2013 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 #include "jump.h"
14 #include "score.h"
15 #include "xml.h"
16 #include "measure.h"
17 
18 namespace Ms {
19 
20 //---------------------------------------------------------
21 //   jumpStyle
22 //---------------------------------------------------------
23 
24 static const ElementStyle jumpStyle {
25       { Sid::repeatRightPlacement, Pid::PLACEMENT },
26       { Sid::repeatMinDistance,    Pid::MIN_DISTANCE },
27       };
28 
29 //---------------------------------------------------------
30 //   JumpTypeTable
31 //---------------------------------------------------------
32 
33 const JumpTypeTable jumpTypeTable[] = {
34       { Jump::Type::DC,         "D.C.",         "start", "end",  "",      QT_TRANSLATE_NOOP("jumpType", "Da Capo")        },
35       { Jump::Type::DC_AL_FINE, "D.C. al Fine", "start", "fine", "" ,     QT_TRANSLATE_NOOP("jumpType", "Da Capo al Fine")},
36       { Jump::Type::DC_AL_CODA, "D.C. al Coda", "start", "coda", "codab", QT_TRANSLATE_NOOP("jumpType", "Da Capo al Coda")},
37       { Jump::Type::DS_AL_CODA, "D.S. al Coda", "segno", "coda", "codab", QT_TRANSLATE_NOOP("jumpType", "D.S. al Coda")   },
38       { Jump::Type::DS_AL_FINE, "D.S. al Fine", "segno", "fine", "",      QT_TRANSLATE_NOOP("jumpType", "D.S. al Fine")   },
39       { Jump::Type::DS,         "D.S.",         "segno", "end",  "",      QT_TRANSLATE_NOOP("jumpType", "D.S.")           }
40       };
41 
jumpTypeTableSize()42 int jumpTypeTableSize()
43       {
44       return sizeof(jumpTypeTable)/sizeof(JumpTypeTable);
45       }
46 
47 //---------------------------------------------------------
48 //   Jump
49 //---------------------------------------------------------
50 
Jump(Score * s)51 Jump::Jump(Score* s)
52    : TextBase(s, Tid::REPEAT_RIGHT, ElementFlag::MOVABLE | ElementFlag::SYSTEM)
53       {
54       initElementStyle(&jumpStyle);
55       setLayoutToParentWidth(true);
56       _playRepeats = false;
57       }
58 
59 //---------------------------------------------------------
60 //   setJumpType
61 //---------------------------------------------------------
62 
setJumpType(Type t)63 void Jump::setJumpType(Type t)
64       {
65       for (const JumpTypeTable& p : jumpTypeTable) {
66             if (p.type == t) {
67                   setXmlText(p.text);
68                   setJumpTo(p.jumpTo);
69                   setPlayUntil(p.playUntil);
70                   setContinueAt(p.continueAt);
71                   initTid(Tid::REPEAT_RIGHT);
72                   break;
73                   }
74             }
75       }
76 
77 //---------------------------------------------------------
78 //   jumpType
79 //---------------------------------------------------------
80 
jumpType() const81 Jump::Type Jump::jumpType() const
82       {
83       for (const JumpTypeTable& t : jumpTypeTable) {
84             if (_jumpTo == t.jumpTo && _playUntil == t.playUntil && _continueAt == t.continueAt)
85                   return t.type;
86             }
87       return Type::USER;
88       }
89 
jumpTypeUserName() const90 QString Jump::jumpTypeUserName() const
91       {
92       int idx = static_cast<int>(this->jumpType());
93       if (idx < jumpTypeTableSize())
94             return qApp->translate("jumpType", jumpTypeTable[idx].userText.toUtf8().constData());
95       return QObject::tr("Custom");
96       }
97 
98 //---------------------------------------------------------
99 //   layout
100 //---------------------------------------------------------
101 
layout()102 void Jump::layout()
103       {
104       TextBase::layout();
105       autoplaceMeasureElement();
106       }
107 
108 //---------------------------------------------------------
109 //   read
110 //---------------------------------------------------------
111 
read(XmlReader & e)112 void Jump::read(XmlReader& e)
113       {
114       while (e.readNextStartElement()) {
115             const QStringRef& tag(e.name());
116             if (tag == "jumpTo")
117                   _jumpTo = e.readElementText();
118             else if (tag == "playUntil")
119                   _playUntil = e.readElementText();
120             else if (tag == "continueAt")
121                   _continueAt = e.readElementText();
122             else if (tag == "playRepeats")
123                   _playRepeats = e.readBool();
124             else if (!TextBase::readProperties(e))
125                   e.unknown();
126             }
127       }
128 
129 //---------------------------------------------------------
130 //   write
131 //---------------------------------------------------------
132 
write(XmlWriter & xml) const133 void Jump::write(XmlWriter& xml) const
134       {
135       xml.stag(this);
136       TextBase::writeProperties(xml);
137       xml.tag("jumpTo", _jumpTo);
138       xml.tag("playUntil", _playUntil);
139       xml.tag("continueAt", _continueAt);
140       writeProperty(xml, Pid::PLAY_REPEATS);
141       xml.etag();
142       }
143 
144 //---------------------------------------------------------
145 //   undoSetJumpTo
146 //---------------------------------------------------------
147 
undoSetJumpTo(const QString & s)148 void Jump::undoSetJumpTo(const QString& s)
149       {
150       undoChangeProperty(Pid::JUMP_TO, s);
151       }
152 
153 //---------------------------------------------------------
154 //   undoSetPlayUntil
155 //---------------------------------------------------------
156 
undoSetPlayUntil(const QString & s)157 void Jump::undoSetPlayUntil(const QString& s)
158       {
159       undoChangeProperty(Pid::PLAY_UNTIL, s);
160       }
161 
162 //---------------------------------------------------------
163 //   undoSetContinueAt
164 //---------------------------------------------------------
165 
undoSetContinueAt(const QString & s)166 void Jump::undoSetContinueAt(const QString& s)
167       {
168       undoChangeProperty(Pid::CONTINUE_AT, s);
169       }
170 
171 //---------------------------------------------------------
172 //   getProperty
173 //---------------------------------------------------------
174 
getProperty(Pid propertyId) const175 QVariant Jump::getProperty(Pid propertyId) const
176       {
177       switch (propertyId) {
178             case Pid::JUMP_TO:
179                   return jumpTo();
180             case Pid::PLAY_UNTIL:
181                   return playUntil();
182             case Pid::CONTINUE_AT:
183                   return continueAt();
184             case Pid::PLAY_REPEATS:
185                   return playRepeats();
186             default:
187                   break;
188             }
189       return TextBase::getProperty(propertyId);
190       }
191 
192 //---------------------------------------------------------
193 //   setProperty
194 //---------------------------------------------------------
195 
setProperty(Pid propertyId,const QVariant & v)196 bool Jump::setProperty(Pid propertyId, const QVariant& v)
197       {
198       switch (propertyId) {
199             case Pid::JUMP_TO:
200                   setJumpTo(v.toString());
201                   break;
202             case Pid::PLAY_UNTIL:
203                   setPlayUntil(v.toString());
204                   break;
205             case Pid::CONTINUE_AT:
206                   setContinueAt(v.toString());
207                   break;
208             case Pid::PLAY_REPEATS:
209                   setPlayRepeats(v.toInt());
210                   break;
211             default:
212                   if (!TextBase::setProperty(propertyId, v))
213                         return false;
214                   break;
215             }
216       triggerLayout();
217       score()->setPlaylistDirty();
218       return true;
219       }
220 
221 //---------------------------------------------------------
222 //   propertyDefault
223 //---------------------------------------------------------
224 
propertyDefault(Pid propertyId) const225 QVariant Jump::propertyDefault(Pid propertyId) const
226       {
227       switch (propertyId) {
228             case Pid::JUMP_TO:
229             case Pid::PLAY_UNTIL:
230             case Pid::CONTINUE_AT:
231                   return QString("");
232             case Pid::PLAY_REPEATS:
233                   return false;
234             case Pid::PLACEMENT:
235                   return int(Placement::ABOVE);
236             default:
237                   break;
238             }
239       return TextBase::propertyDefault(propertyId);
240       }
241 
242 //---------------------------------------------------------
243 //   nextSegmentElement
244 //---------------------------------------------------------
245 
nextSegmentElement()246 Element* Jump::nextSegmentElement()
247       {
248       Segment* seg = measure()->last();
249       return seg->firstElement(staffIdx());
250       }
251 
252 //---------------------------------------------------------
253 //   prevSegmentElement
254 //---------------------------------------------------------
255 
prevSegmentElement()256 Element* Jump::prevSegmentElement()
257       {
258       return nextSegmentElement();
259       }
260 
261 //---------------------------------------------------------
262 //   accessibleInfo
263 //---------------------------------------------------------
264 
accessibleInfo() const265 QString Jump::accessibleInfo() const
266       {
267       return QString("%1: %2").arg(Element::accessibleInfo(), this->jumpTypeUserName());
268       }
269 
270 }
271 
272