Exemplo n.º 1
0
void TempoText::textChanged()
      {
      if (!_followText)
            return;
      QString s = text();

      static const TempoPattern tp[] = {
            TempoPattern("\\xd834\\xdd5f = (\\d+)", 1.0/60.0),      // 1/4
            TempoPattern("\\xd834\\xdd5e = (\\d+)", 1.0/30.0),      // 1/2
            TempoPattern("\\xd834\\xdd60 = (\\d+)", 1.0/120.0),     // 1/8
            TempoPattern("\\xd834\\xdd5f\\xd834\\xdd6d = (\\d+)", 1.5/60.0),   // dotted 1/4
            TempoPattern("\\xd834\\xdd5e\\xd834\\xdd6d = (\\d+)", 1.5/30.0),   // dotted 1/2
            TempoPattern("\\xd834\\xdd60\\xd834\\xdd6d = (\\d+)", 1.5/120.0),  // dotted 1/8
            };

      for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
            QRegExp re(tp[i].pattern);      // 1/4
            if (re.indexIn(s) != -1) {
                  QStringList sl = re.capturedTexts();
                  if (sl.size() == 2) {
                        qreal nt = qreal(sl[1].toInt()) * tp[i].f;
                        if (nt != _tempo) {
                              _tempo = qreal(sl[1].toInt()) * tp[i].f;
                              score()->setPlaylistDirty(true);
                              }
                        break;
                        }
                  }
            }
      }
Exemplo n.º 2
0
Palette* MuseScore::newTempoPalette()
      {
      Palette* sp = new Palette;
      sp->setName(QT_TRANSLATE_NOOP("Palette", "Tempo"));
      sp->setMag(0.65);
      sp->setGrid(60, 30);
      sp->setDrawGrid(true);

      static const TempoPattern tp[] = {
            TempoPattern("<sym>noteHalfUp</sym> = 80", 80.0/30.0),                        // 1/2
            TempoPattern("<sym>noteQuarterUp</sym> = 80", 80.0/60.0),                     // 1/4
            TempoPattern("<sym>note8thUp</sym> = 80", 80.0/120.0),                    // 1/8
            TempoPattern("<sym>noteHalfUp</sym><sym>textAugmentationDot</sym> = 80", 120/30.0),       // dotted 1/2
            TempoPattern("<sym>noteQuarterUp</sym><sym>textAugmentationDot</sym> = 80", 120/60.0),    // dotted 1/4
            TempoPattern("<sym>note8thUp</sym><sym>textAugmentationDot</sym> = 80", 120/120.0),   // dotted 1/8
            };
      for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
            TempoText* tt = new TempoText(gscore);
            tt->setFollowText(true);
            tt->setTrack(0);
            tt->setTempo(tp[i].f);
            tt->setText(tp[i].pattern);
            sp->append(tt, tr("Tempo Text"), QString(), 1.5);
            }
      return sp;
      }
Exemplo n.º 3
0
Palette* MuseScore::newTempoPalette()
{
    Palette* sp = new Palette;
    sp->setName(QT_TRANSLATE_NOOP("Palette", "Tempo"));
    sp->setMag(0.65);
    sp->setGrid(60, 30);
    sp->setDrawGrid(true);

    static const TempoPattern tp[] = {
        TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd5f)), 80.0/60.0),      // 1/4
        TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd5e)), 80.0/30.0),      // 1/2
        TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd60)), 80.0/120.0),     // 1/8
        TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120.0/60.0),  // dotted 1/4
        TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5e)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/30.0),    // dotted 1/2
        TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/120.0)    // dotted 1/8
    };
    for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
        TempoText* tt = new TempoText(gscore);
        tt->setFollowText(true);
        tt->setTrack(0);
        tt->setTempo(tp[i].f);
        tt->setText(tp[i].pattern);
        sp->append(tt, tr("Tempo Text"), QString(), 1.5);
    }
    return sp;
}
Exemplo n.º 4
0
Palette* MuseScore::newTempoPalette()
      {
      Palette* sp = new Palette;
      sp->setName(QT_TRANSLATE_NOOP("Palette", "Tempo"));
      sp->setMag(0.65);
      sp->setGrid(60, 30);
      sp->setDrawGrid(true);

      static const TempoPattern tp[] = {
            TempoPattern("<sym>metNoteHalfUp</sym> = 80", 80.0/30.0),                    // 1/2
            TempoPattern("<sym>metNoteQuarterUp</sym> = 80", 80.0/60.0),                 // 1/4
            TempoPattern("<sym>metNote8thUp</sym> = 80", 80.0/120.0),                    // 1/8
            TempoPattern("<sym>metNoteHalfUp</sym><sym>space</sym><sym>metAugmentationDot</sym> = 80", 120/30.0),       // dotted 1/2
            TempoPattern("<sym>metNoteQuarterUp</sym><sym>space</sym><sym>metAugmentationDot</sym> = 80", 120/60.0),    // dotted 1/4
            TempoPattern("<sym>metNote8thUp</sym><sym>space</sym><sym>metAugmentationDot</sym> = 80", 120/120.0),       // dotted 1/8
            };
      for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
            TempoText* tt = new TempoText(gscore);
            tt->setFollowText(true);
            // leave track at default (-1) to make it possible
            // for drop() to tell that this came from palette
            // (it will then be set to 0 there)
            //tt->setTrack(0);
            tt->setTempo(tp[i].f);
            tt->setXmlText(tp[i].pattern);
            sp->append(tt, tr("Tempo text"), QString(), 1.5);
            }
      return sp;
      }
Exemplo n.º 5
0
Palette* MuseScore::newTextPalette()
{
    Palette* sp = new Palette;
    sp->setName(QT_TRANSLATE_NOOP("Palette", "Text"));
    sp->setMag(0.65);
    sp->setGrid(84, 28);
    sp->setDrawGrid(true);

    StaffText* st = new StaffText(gscore);
    st->setTextStyleType(TEXT_STYLE_STAFF);
    st->setText(tr("staff-text"));
    sp->append(st, tr("Staff Text"));

    st = new StaffText(gscore);
    st->setTextStyleType(TEXT_STYLE_SYSTEM);
    st->setText(tr("system-text"));
    sp->append(st, tr("System Text"));

    RehearsalMark* rhm = new RehearsalMark(gscore);
    rhm->setTrack(0);
    rhm->setText("B1");
    sp->append(rhm, tr("Rehearsal Mark"));

    InstrumentChange* is = new InstrumentChange(gscore);
    is->setText(tr("Instrument"));
    sp->append(is, tr("Instrument Change"));

    Text* text = new Text(gscore);
    text->setTrack(0);
    text->setTextStyleType(TEXT_STYLE_LYRICS_VERSE_NUMBER);
    text->setText(tr("1."));
    sp->append(text, tr("Lyrics Verse Number"));

    static const TempoPattern tp[] = {
        TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd5f)), 80.0/60.0),      // 1/4
        TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd5e)), 80.0/30.0),      // 1/2
        TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd60)), 80.0/120.0),     // 1/8
        TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120.0/60.0),  // dotted 1/4
        TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5e)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/30.0),    // dotted 1/2
        TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/120.0)    // dotted 1/8
    };
    for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
        TempoText* tt = new TempoText(gscore);
        tt->setFollowText(true);
        tt->setTrack(0);
        tt->setTempo(tp[i].f);
        tt->setText(tp[i].pattern);
        sp->append(tt, tr("Tempo Text"), QString(), 1.5);
    }

    Harmony* harmony = new Harmony(gscore);
    harmony->setText("C7");
    sp->append(harmony, tr("Chord Name"));
    return sp;
}
Exemplo n.º 6
0
namespace Ms {

#define MIN_TEMPO 5.0/60
#define MAX_TEMPO 999.0/60

//---------------------------------------------------------
//   TempoText
//---------------------------------------------------------

TempoText::TempoText(Score* s)
   : Text(s)
      {
      _tempo      = 2.0;      // propertyDefault(P_TEMPO).toDouble();
      _followText = false;
      _relative = 1.0;
      _isRelative = false;
      setPlacement(Element::Placement::ABOVE);
      setTextStyleType(TextStyleType::TEMPO);
      }

//---------------------------------------------------------
//   write
//---------------------------------------------------------

void TempoText::write(Xml& xml) const
      {
      xml.stag("Tempo");
      xml.tag("tempo", _tempo);
      if (_followText)
            xml.tag("followText", _followText);
      Text::writeProperties(xml);
      xml.etag();
      }

//---------------------------------------------------------
//   read
//---------------------------------------------------------

void TempoText::read(XmlReader& e)
      {
      while (e.readNextStartElement()) {
            const QStringRef& tag(e.name());
            if (tag == "tempo")
                  setTempo(e.readDouble());
            else if (tag == "followText")
                  _followText = e.readInt();
            else if (!Text::readProperties(e))
                  e.unknown();
            }
      if (score()->mscVersion() <= 114) {
            //
            // Reset text in old version to
            // style.
            //
//TODO            if (textStyle() != TextStyleType::INVALID) {
//                  setStyled(true);
//                  styleChanged();
//                  }
            }
      // check sanity
      if (xmlText().isEmpty()) {
            setXmlText(QString("<sym>metNoteQuarterUp</sym> = %1").arg(lrint(60 * _tempo)));
            setVisible(false);
            }
      }

//---------------------------------------------------------
//   TempoPattern
//---------------------------------------------------------

struct TempoPattern {
      const char* pattern;
      qreal f;
      TDuration d;
      TempoPattern(const char* s, qreal v, TDuration::DurationType val, int dots = 0) : pattern(s), f(v), d(val) { d.setDots(dots); }
      };

// note: findTempoDuration requires the longer patterns to be before the shorter patterns in tp

static const TempoPattern tp[] = {
      TempoPattern("<sym>metNoteQuarterUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>",                         1.75/60.0, TDuration::DurationType::V_QUARTER, 2), // double dotted 1/4
      TempoPattern("<sym>metNoteQuarterUp</sym>\\s*<sym>metAugmentationDot</sym>",          1.5/60.0,  TDuration::DurationType::V_QUARTER, 1), // dotted 1/4
      TempoPattern("<sym>metNoteQuarterUp</sym>",                                           1.0/60.0,  TDuration::DurationType::V_QUARTER),  // 1/4
      TempoPattern("<sym>metNoteHalfUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>",                         1.75/30.0, TDuration::DurationType::V_HALF, 2), // double dotted 1/2
      TempoPattern("<sym>metNoteHalfUp</sym>\\s*<sym>metAugmentationDot</sym>",             1.5/30.0,  TDuration::DurationType::V_HALF, 1),    // dotted 1/2
      TempoPattern("<sym>metNoteHalfUp</sym>",                                              1.0/30.0,  TDuration::DurationType::V_HALF),     // 1/2
      TempoPattern("<sym>metNote8thUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>",         1.75/120.0, TDuration::DurationType::V_EIGHTH, 2), // double dotted 1/8
      TempoPattern("<sym>metNote8thUp</sym>\\s*<sym>metAugmentationDot</sym>",              1.5/120.0, TDuration::DurationType::V_EIGHTH, 1),  // dotted 1/8
      TempoPattern("<sym>metNote8thUp</sym>",                                               1.0/120.0, TDuration::DurationType::V_EIGHTH),   // 1/8
      TempoPattern("<sym>metNoteWhole</sym>\\s*<sym>metAugmentationDot</sym>",              1.5/15.0, TDuration::DurationType::V_WHOLE, 1),    // dotted whole
      TempoPattern("<sym>metNoteWhole</sym>",                                               1.0/15.0,  TDuration::DurationType::V_WHOLE),    // whole
      TempoPattern("<sym>metNote16thUp</sym>\\s*<sym>metAugmentationDot</sym>",             1.5/240.0, TDuration::DurationType::V_16TH, 1),  // dotted 1/16
      TempoPattern("<sym>metNote16thUp</sym>",                                              1.0/240.0, TDuration::DurationType::V_16TH),     // 1/16
      TempoPattern("<sym>metNote32ndUp</sym>\\s*<sym>metAugmentationDot</sym>",             1.5/480.0, TDuration::DurationType::V_32ND, 1),  // dotted 1/32
      TempoPattern("<sym>metNote32ndUp</sym>",                                              1.0/480.0, TDuration::DurationType::V_32ND),     // 1/32
      TempoPattern("<sym>metNoteDoubleWholeSquare</sym>",                                   1.0/7.5,   TDuration::DurationType::V_BREVE),    // longa
      TempoPattern("<sym>metNoteDoubleWhole</sym>",                                         1.0/7.5,   TDuration::DurationType::V_BREVE),    // double whole
      TempoPattern("<sym>metNote64thUp</sym>",                                              1.0/960.0, TDuration::DurationType::V_64TH),     // 1/64
      TempoPattern("<sym>metNote128thUp</sym>",                                             1.0/1920.0,TDuration::DurationType::V_128TH),    // 1/128
      };

//---------------------------------------------------------
//   findTempoDuration
//    find the duration part (note + dot) of a tempo text in string s
//    return the match position or -1 if not found
//    set len to the match length and dur to the duration value
//---------------------------------------------------------

int TempoText::findTempoDuration(const QString& s, int& len, TDuration& dur)
      {
      len = 0;
      dur = TDuration();

      for (const auto& i : tp) {
            QRegExp re(i.pattern);
            int pos = re.indexIn(s);
            if (pos != -1) {
                  len = re.matchedLength();
                  dur = i.d;
                  return pos;
                  }
            }
      return -1;
      }

//---------------------------------------------------------
//   duration2tempoTextString
//    find the tempoText string representation for duration
//---------------------------------------------------------

QString TempoText::duration2tempoTextString(const TDuration dur)
      {
      for (const TempoPattern& pa : tp) {
            if (pa.d == dur) {
                  QString res = pa.pattern;
                  res.remove("\\s*");
                  return res;
                  }
            }
      return "";
      }

//---------------------------------------------------------
// updateScore
//---------------------------------------------------------
void TempoText::updateScore()
      {
      if (segment())
            score()->setTempo(segment(), _tempo);
      score()->fixTicks();
      score()->setPlaylistDirty();
      }

//---------------------------------------------------------
// updateRelative
//---------------------------------------------------------
void TempoText::updateRelative()
      {
      qreal tempoBefore = score()->tempo(tick() - 1);
      setTempo(tempoBefore * _relative);
      }

//---------------------------------------------------------
//   textChanged
//    text may have changed
//---------------------------------------------------------

void TempoText::textChanged()
      {
      if (!_followText)
            return;
      QString s = plainText();
      s.replace(",", ".");
      s.replace("<sym>space</sym>"," ");
      for (const TempoPattern& pa : tp) {
            QRegExp re(QString(pa.pattern)+"\\s*=\\s*(\\d+[.]{0,1}\\d*)\\s*");
            if (re.indexIn(s) != -1) {
                  QStringList sl = re.capturedTexts();
                  if (sl.size() == 2) {
                        qreal nt = qreal(sl[1].toDouble()) * pa.f;
                        if (nt != _tempo) {
                              setTempo(qreal(sl[1].toDouble()) * pa.f);
                              _relative = 1.0;
                              _isRelative = false;
                              updateScore();
                              }
                        break;
                        }
                  }
            else {
                 for (const TempoPattern& pa2 : tp) {
                       QRegExp re(QString("%1\\s*=\\s*%2\\s*").arg(pa.pattern).arg(pa2.pattern));
                       if (re.indexIn(s) != -1) {
                             _relative = pa2.f / pa.f;
                             _isRelative = true;
                             updateRelative();
                             updateScore();
                             return;
                             }
                       }
                  }
            }
      }

//---------------------------------------------------------
//   setTempo
//---------------------------------------------------------

void TempoText::setTempo(qreal v)
      {
      if (v < MIN_TEMPO)
            v = MIN_TEMPO;
      else if (v > MAX_TEMPO)
            v = MAX_TEMPO;
      _tempo = v;
      }

//---------------------------------------------------------
//   undoSetTempo
//---------------------------------------------------------

void TempoText::undoSetTempo(qreal v)
      {
      undoChangeProperty(P_ID::TEMPO, v);
      }

//---------------------------------------------------------
//   undoSetFollowText
//---------------------------------------------------------

void TempoText::undoSetFollowText(bool v)
      {
      undoChangeProperty(P_ID::TEMPO_FOLLOW_TEXT, v);
      }

//---------------------------------------------------------
//   getProperty
//---------------------------------------------------------

QVariant TempoText::getProperty(P_ID propertyId) const
      {
      switch(propertyId) {
            case P_ID::TEMPO:             return _tempo;
            case P_ID::TEMPO_FOLLOW_TEXT: return _followText;
            default:
                  return Text::getProperty(propertyId);
            }
      }

//---------------------------------------------------------
//   setProperty
//---------------------------------------------------------

bool TempoText::setProperty(P_ID propertyId, const QVariant& v)
      {
      switch(propertyId) {
            case P_ID::TEMPO:
                  setTempo(v.toDouble());
                  score()->setTempo(segment(), _tempo);
                  score()->fixTicks();
                  break;
            case P_ID::TEMPO_FOLLOW_TEXT:
                  _followText = v.toBool();
                  break;
            default:
                  if (!Text::setProperty(propertyId, v))
                        return false;
                  break;
            }
      score()->setLayoutAll();
      return true;
      }

//---------------------------------------------------------
//   propertyDefault
//---------------------------------------------------------

QVariant TempoText::propertyDefault(P_ID id) const
      {
      switch(id) {
            case P_ID::TEMPO:             return 2.0;
            case P_ID::TEMPO_FOLLOW_TEXT: return false;
            case P_ID::PLACEMENT:         return int(Element::Placement::ABOVE);
            default:
                  return Text::propertyDefault(id);
            }
      }

//---------------------------------------------------------
//   layout
//    called after Measure->stretchMeasure()
//---------------------------------------------------------

void TempoText::layout()
      {
      setPos(textStyle().offset(spatium()));
      Text::layout1();

      // tempo text on first chordrest of measure should align over time sig if present
      //
      Segment* s = segment();
      if (s && !s->rtick()) {
            Segment* p = segment()->prev(Segment::Type::TimeSig);
            if (p) {
                  rxpos() -= s->x() - p->x();
                  Element* e = p->element(staffIdx() * VOICES);
                  if (e)
                        rxpos() += e->x();
                  }
            }

      if (placement() == Element::Placement::BELOW)
            rypos() = -rypos() + 4 * spatium();
      adjustReadPos();
      }

QString TempoText::duration2userName(const TDuration t)
      {
      QString dots;
      switch (t.dots()) {
            case 1: dots = tr("Dotted %1").arg(t.durationTypeUserName());
                  break;
            case 2: dots = tr("Double dotted %1").arg(t.durationTypeUserName());
                  break;
            case 3: dots = tr("Triple dotted %1").arg(t.durationTypeUserName());
                  break;
            case 4: dots = tr("Quadruple dotted %1").arg(t.durationTypeUserName());
                  break;
            default:
                  dots = t.durationTypeUserName();
                  break;
            }
      return dots;
      }

//---------------------------------------------------------
//   accessibleInfo
//---------------------------------------------------------

QString TempoText::accessibleInfo() const
      {
      TDuration t1;
      TDuration t2;
      int len1;
      int len2;
      QString text = plainText();
      QString firstPart = text.split(" = ").first();
      QString secondPart = text.split(" = ").back();
      int x1 = findTempoDuration(firstPart, len1, t1);
      int x2 = -1;
      if (_relative)
            x2 = findTempoDuration(secondPart, len2, t2);

      if (x1 != -1) {
            QString dots1;
            QString dots2;
            dots1 = duration2userName(t1);
            if (x2 != -1) {
                  dots2 = duration2userName(t2);
                  return QString("%1: %2 %3 = %4 %5").arg(Element::accessibleInfo()).arg(dots1).arg(tr("note")).arg(dots2).arg(tr("note"));
                  }
            else
                  return QString("%1: %2 %3 = %4").arg(Element::accessibleInfo()).arg(dots1).arg(tr("note")).arg(secondPart);
            }
      else
            return Text::accessibleInfo();
      }

}
Exemplo n.º 7
0
namespace Ms {

//---------------------------------------------------------
//   TempoText
//---------------------------------------------------------

TempoText::TempoText(Score* s)
   : Text(s)
      {
      _tempo      = 2.0;      // propertyDefault(P_TEMPO).toDouble();
      _followText = false;
      setPlacement(Placement::ABOVE);
      setTextStyleType(TEXT_STYLE_TEMPO);
      }

//---------------------------------------------------------
//   write
//---------------------------------------------------------

void TempoText::write(Xml& xml) const
      {
      xml.stag("Tempo");
      xml.tag("tempo", _tempo);
      if (_followText)
            xml.tag("followText", _followText);
      Text::writeProperties(xml);
      xml.etag();
      }

//---------------------------------------------------------
//   read
//---------------------------------------------------------

void TempoText::read(XmlReader& e)
      {
      while (e.readNextStartElement()) {
            const QStringRef& tag(e.name());
            if (tag == "tempo")
                  _tempo = e.readDouble();
            else if (tag == "followText")
                  _followText = e.readInt();
            else if (!Text::readProperties(e))
                  e.unknown();
            }
      if (score()->mscVersion() < 119) {
            //
            // Reset text in old version to
            // style.
            //
//TODO            if (textStyle() != TEXT_STYLE_INVALID) {
//                  setStyled(true);
//                  styleChanged();
//                  }
            }
      }

//---------------------------------------------------------
//   TempoPattern
//---------------------------------------------------------

struct TempoPattern {
      const char* pattern;
      qreal f;
      TDuration d;
      TempoPattern(const char* s, qreal v, TDuration::DurationType val, int dots = 0) : pattern(s), f(v), d(val) { d.setDots(dots); }
      };

// note: findTempoDuration requires the longer patterns to be before the shorter patterns in tp

static const TempoPattern tp[] = {
      TempoPattern("<sym>noteHalfUp</sym>\\s*<sym>textAugmentationDot</sym>",    1.5/30.0,  TDuration::DurationType::V_HALF, 1),    // dotted 1/2
      TempoPattern("<sym>noteQuarterUp</sym>\\s*<sym>textAugmentationDot</sym>", 1.5/60.0,  TDuration::DurationType::V_QUARTER, 1), // dotted 1/4
      TempoPattern("<sym>note8thUp</sym>\\s*<sym>textAugmentationDot</sym>",     1.5/120.0, TDuration::DurationType::V_EIGHT, 1),   // dotted 1/8
      TempoPattern("<sym>noteHalfUp</sym>",                                      1.0/30.0,  TDuration::DurationType::V_HALF),       // 1/2
      TempoPattern("<sym>noteQuarterUp</sym>",                                   1.0/60.0,  TDuration::DurationType::V_QUARTER),    // 1/4
      TempoPattern("<sym>note8thUp</sym>",                                       1.0/120.0, TDuration::DurationType::V_EIGHT),      // 1/8
      };
      
//---------------------------------------------------------
//   findTempoDuration
//    find the duration part (note + dot) of a tempo text in string s
//    return the match position or -1 if not found
//    set len to the match length and dur to the duration value
//---------------------------------------------------------

int TempoText::findTempoDuration(const QString& s, int& len, TDuration& dur)
      {
      len = 0;
      dur = TDuration();

      for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
            QRegExp re(tp[i].pattern);
            int pos = re.indexIn(s);
            if (pos != -1) {
                  len = re.matchedLength();
                  dur = tp[i].d;
                  return pos;
                  }
            }

      return -1;
      }
      
//---------------------------------------------------------
//   duration2tempoTextString
//    find the tempoText string representation for duration
//---------------------------------------------------------

QString TempoText::duration2tempoTextString(const TDuration dur)
      {
      for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
            if (tp[i].d == dur) {
                  QString res = tp[i].pattern;
                  res.remove("\\s*");
                  return res;
                  }
            }
      return "";
      }

//---------------------------------------------------------
//   textChanged
//    text may have changed
//---------------------------------------------------------

void TempoText::textChanged()
      {
      if (!_followText)
            return;
      QString s = text();

      for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
            QRegExp re(QString(tp[i].pattern)+"\\s*=\\s*(\\d+)");      // 1/4
            if (re.indexIn(s) != -1) {
                  QStringList sl = re.capturedTexts();
                  if (sl.size() == 2) {
                        qreal nt = qreal(sl[1].toInt()) * tp[i].f;
                        if (nt != _tempo) {
                              _tempo = qreal(sl[1].toInt()) * tp[i].f;
                              if(segment())
                                    score()->setTempo(segment(), _tempo);
                              score()->setPlaylistDirty(true);
                              }
                        break;
                        }
                  }
            }
      }

//---------------------------------------------------------
//   undoSetTempo
//---------------------------------------------------------

void TempoText::undoSetTempo(qreal v)
      {
      score()->undoChangeProperty(this, P_ID::TEMPO, v);
      }

//---------------------------------------------------------
//   undoSetFollowText
//---------------------------------------------------------

void TempoText::undoSetFollowText(bool v)
      {
      score()->undoChangeProperty(this, P_ID::TEMPO_FOLLOW_TEXT, v);
      }

//---------------------------------------------------------
//   getProperty
//---------------------------------------------------------

QVariant TempoText::getProperty(P_ID propertyId) const
      {
      switch(propertyId) {
            case P_ID::TEMPO:             return _tempo;
            case P_ID::TEMPO_FOLLOW_TEXT: return _followText;
            default:
                  return Text::getProperty(propertyId);
            }
      }

//---------------------------------------------------------
//   setProperty
//---------------------------------------------------------

bool TempoText::setProperty(P_ID propertyId, const QVariant& v)
      {
      switch(propertyId) {
            case P_ID::TEMPO:
                  _tempo = v.toDouble();
                  score()->setTempo(segment(), _tempo);
                  break;
            case P_ID::TEMPO_FOLLOW_TEXT:
                  _followText = v.toBool();
                  break;
            default:
                  if (!Text::setProperty(propertyId, v))
                        return false;
                  break;
            }
      score()->setLayoutAll(true);
      return true;
      }

//---------------------------------------------------------
//   propertyDefault
//---------------------------------------------------------

QVariant TempoText::propertyDefault(P_ID id) const
      {
      switch(id) {
            case P_ID::TEMPO:             return 120;
            case P_ID::TEMPO_FOLLOW_TEXT: return false;
            case P_ID::PLACEMENT:         return int(Placement::ABOVE);
            default:                  return Text::propertyDefault(id);
            }
      }

//---------------------------------------------------------
//   layout
//---------------------------------------------------------

void TempoText::layout()
      {
      Text::layout();
      if (placement() == Placement::BELOW) {
            rypos() = -rypos() + 4 * spatium();
            // rUserYoffset() *= -1;
            // text height ?
            }
      }

}
Exemplo n.º 8
0
namespace Ms {

#define MIN_TEMPO 5.0/60
#define MAX_TEMPO 999.0/60

//TODO: textChanged() needs to be called during/after editing

//---------------------------------------------------------
//   TempoText
//---------------------------------------------------------

TempoText::TempoText(Score* s)
   : TextBase(s, ElementFlags(ElementFlag::SYSTEM))
      {
      initSubStyle(SubStyleId::TEMPO);
      _tempo      = 2.0;      // propertyDefault(P_TEMPO).toDouble();
      _followText = false;
      _relative   = 1.0;
      _isRelative = false;
      }

//---------------------------------------------------------
//   write
//---------------------------------------------------------

void TempoText::write(XmlWriter& xml) const
      {
      xml.stag(name());
      xml.tag("tempo", _tempo);
      if (_followText)
            xml.tag("followText", _followText);
      TextBase::writeProperties(xml);
      xml.etag();
      }

//---------------------------------------------------------
//   read
//---------------------------------------------------------

void TempoText::read(XmlReader& e)
      {
      while (e.readNextStartElement()) {
            const QStringRef& tag(e.name());
            if (tag == "tempo")
                  setTempo(e.readDouble());
            else if (tag == "followText")
                  _followText = e.readInt();
            else if (!TextBase::readProperties(e))
                  e.unknown();
            }
      // check sanity
      if (xmlText().isEmpty()) {
            setXmlText(QString("<sym>metNoteQuarterUp</sym> = %1").arg(lrint(60 * _tempo)));
            setVisible(false);
            }
      }

//---------------------------------------------------------
//   TempoPattern
//---------------------------------------------------------

struct TempoPattern {
      const char* pattern;
      qreal f;
      TDuration d;
      TempoPattern(const char* s, qreal v, TDuration::DurationType val, int dots = 0) : pattern(s), f(v), d(val) { d.setDots(dots); }
      };

// note: findTempoDuration requires the longer patterns to be before the shorter patterns in tp

static const TempoPattern tp[] = {
      TempoPattern("\uECA5\\s*\uECB7\\s*\uECB7", 1.75/60.0,  TDuration::DurationType::V_QUARTER, 2), // double dotted 1/4
      TempoPattern("\uECA5\\s*\uECB7",           1.5/60.0,   TDuration::DurationType::V_QUARTER, 1), // dotted 1/4
      TempoPattern("\uECA5",                     1.0/60.0,   TDuration::DurationType::V_QUARTER),    // 1/4
      TempoPattern("\uECA3\\s*\uECB7\\s*\uECB7", 1.75/30.0,  TDuration::DurationType::V_HALF, 2),    // double dotted 1/2
      TempoPattern("\uECA3\\s*\uECB7",           1.5/30.0,   TDuration::DurationType::V_HALF, 1),    // dotted 1/2
      TempoPattern("\uECA3",                     1.0/30.0,   TDuration::DurationType::V_HALF),       // 1/2
      TempoPattern("\uECA7\\s*\uECB7\\s*\uECB7", 1.75/120.0, TDuration::DurationType::V_EIGHTH, 2),  // double dotted 1/8
      TempoPattern("\uECA7\\s*\uECB7",           1.5/120.0,  TDuration::DurationType::V_EIGHTH, 1),  // dotted 1/8
      TempoPattern("\uECA7",                     1.0/120.0,  TDuration::DurationType::V_EIGHTH),     // 1/8
      TempoPattern("\uECA2\\s*\uECB7",           1.5/15.0,   TDuration::DurationType::V_WHOLE, 1),   // dotted whole
      TempoPattern("\uECA2",                     1.0/15.0,   TDuration::DurationType::V_WHOLE),      // whole
      TempoPattern("\uECA9\\s*\uECB7",           1.5/240.0,  TDuration::DurationType::V_16TH, 1),    // dotted 1/16
      TempoPattern("\uECA9",                     1.0/240.0,  TDuration::DurationType::V_16TH),       // 1/16
      TempoPattern("\uECAB\\s*\uECB7",           1.5/480.0,  TDuration::DurationType::V_32ND, 1),    // dotted 1/32
      TempoPattern("\uECAB",                     1.0/480.0,  TDuration::DurationType::V_32ND),       // 1/32
      TempoPattern("\uECA1",                     1.0/7.5,    TDuration::DurationType::V_BREVE),      // longa
      TempoPattern("\uECA0",                     1.0/7.5,    TDuration::DurationType::V_BREVE),      // double whole
      TempoPattern("\uECAD",                     1.0/960.0,  TDuration::DurationType::V_64TH),       // 1/64
      TempoPattern("\uECAF",                     1.0/1920.0, TDuration::DurationType::V_128TH),      // 1/128
      };

//---------------------------------------------------------
//   findTempoDuration
//    find the duration part (note + dot) of a tempo text in string s
//    return the match position or -1 if not found
//    set len to the match length and dur to the duration value
//---------------------------------------------------------

int TempoText::findTempoDuration(const QString& s, int& len, TDuration& dur)
      {
      len = 0;
      dur = TDuration();
      for (const auto& i : tp) {
            QRegExp re(i.pattern);
            int pos = re.indexIn(s);
            if (pos != -1) {
                  len = re.matchedLength();
                  dur = i.d;
                  return pos;
                  }
            }
      return -1;
      }

static const TempoPattern tpSym[] = {
      TempoPattern("<sym>metNoteQuarterUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>",                         1.75/60.0, TDuration::DurationType::V_QUARTER, 2), // double dotted 1/4
      TempoPattern("<sym>metNoteQuarterUp</sym>\\s*<sym>metAugmentationDot</sym>",          1.5/60.0,  TDuration::DurationType::V_QUARTER, 1), // dotted 1/4
      TempoPattern("<sym>metNoteQuarterUp</sym>",                                           1.0/60.0,  TDuration::DurationType::V_QUARTER),  // 1/4
      TempoPattern("<sym>metNoteHalfUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>",                         1.75/30.0, TDuration::DurationType::V_HALF, 2), // double dotted 1/2
      TempoPattern("<sym>metNoteHalfUp</sym>\\s*<sym>metAugmentationDot</sym>",             1.5/30.0,  TDuration::DurationType::V_HALF, 1),    // dotted 1/2
      TempoPattern("<sym>metNoteHalfUp</sym>",                                              1.0/30.0,  TDuration::DurationType::V_HALF),     // 1/2
      TempoPattern("<sym>metNote8thUp</sym>\\s*<sym>metAugmentationDot</sym>\\s*<sym>metAugmentationDot</sym>",         1.75/120.0, TDuration::DurationType::V_EIGHTH, 2), // double dotted 1/8
      TempoPattern("<sym>metNote8thUp</sym>\\s*<sym>metAugmentationDot</sym>",              1.5/120.0, TDuration::DurationType::V_EIGHTH, 1),  // dotted 1/8
      TempoPattern("<sym>metNote8thUp</sym>",                                               1.0/120.0, TDuration::DurationType::V_EIGHTH),   // 1/8
      TempoPattern("<sym>metNoteWhole</sym>\\s*<sym>metAugmentationDot</sym>",              1.5/15.0, TDuration::DurationType::V_WHOLE, 1),    // dotted whole
      TempoPattern("<sym>metNoteWhole</sym>",                                               1.0/15.0,  TDuration::DurationType::V_WHOLE),    // whole
      TempoPattern("<sym>metNote16thUp</sym>\\s*<sym>metAugmentationDot</sym>",             1.5/240.0, TDuration::DurationType::V_16TH, 1),  // dotted 1/16
      TempoPattern("<sym>metNote16thUp</sym>",                                              1.0/240.0, TDuration::DurationType::V_16TH),     // 1/16
      TempoPattern("<sym>metNote32ndUp</sym>\\s*<sym>metAugmentationDot</sym>",             1.5/480.0, TDuration::DurationType::V_32ND, 1),  // dotted 1/32
      TempoPattern("<sym>metNote32ndUp</sym>",                                              1.0/480.0, TDuration::DurationType::V_32ND),     // 1/32
      TempoPattern("<sym>metNoteDoubleWholeSquare</sym>",                                   1.0/7.5,   TDuration::DurationType::V_BREVE),    // longa
      TempoPattern("<sym>metNoteDoubleWhole</sym>",                                         1.0/7.5,   TDuration::DurationType::V_BREVE),    // double whole
      TempoPattern("<sym>metNote64thUp</sym>",                                              1.0/960.0, TDuration::DurationType::V_64TH),     // 1/64
      TempoPattern("<sym>metNote128thUp</sym>",                                             1.0/1920.0,TDuration::DurationType::V_128TH),    // 1/128
      };

//---------------------------------------------------------
//   duration2tempoTextString
//    find the tempoText string representation for duration
//---------------------------------------------------------

QString TempoText::duration2tempoTextString(const TDuration dur)
      {
      for (const TempoPattern& pa : tpSym) {
            if (pa.d == dur) {
                  QString res = pa.pattern;
                  res.replace("\\s*", " ");
                  return res;
                  }
            }
      return "";
      }

//---------------------------------------------------------
// updateScore
//---------------------------------------------------------

void TempoText::updateScore()
      {
      if (segment())
            score()->setTempo(segment(), _tempo);
      score()->fixTicks();
      score()->setPlaylistDirty();
      }

//---------------------------------------------------------
// updateRelative
//---------------------------------------------------------

void TempoText::updateRelative()
      {
      qreal tempoBefore = score()->tempo(tick() - 1);
      setTempo(tempoBefore * _relative);
      }

//---------------------------------------------------------
//   textChanged
//    text may have changed
//---------------------------------------------------------

void TempoText::textChanged()
      {
      if (!_followText)
            return;
      // cache regexp, they are costly to create
      static QHash<QString, QRegExp> regexps;
      static QHash<QString, QRegExp> regexps2;
      QString s = plainText();
      s.replace(",", ".");
      s.replace("<sym>space</sym>"," ");
      for (const TempoPattern& pa : tp) {
            QRegExp re;
            if (!regexps.contains(pa.pattern)) {
                  re = QRegExp(QString("%1\\s*=\\s*(\\d+[.]{0,1}\\d*)\\s*").arg(pa.pattern));
                  regexps[pa.pattern] = re;
                  }
            re = regexps.value(pa.pattern);
            if (re.indexIn(s) != -1) {
                  QStringList sl = re.capturedTexts();
                  if (sl.size() == 2) {
                        qreal nt = qreal(sl[1].toDouble()) * pa.f;
                        if (nt != _tempo) {
                              setTempo(qreal(sl[1].toDouble()) * pa.f);
                              _relative = 1.0;
                              _isRelative = false;
                              updateScore();
                              }
                        break;
                        }
                  }
            else {
                 for (const TempoPattern& pa2 : tp) {
                       QString key = QString("%1_%2").arg(pa.pattern).arg(pa2.pattern);
                       QRegExp re2;
                       if (!regexps2.contains(key)) {
                             re2 = QRegExp(QString("%1\\s*=\\s*%2\\s*").arg(pa.pattern).arg(pa2.pattern));
                             regexps2[key] = re2;
                             }
                       re2 = regexps2.value(key);
                       if (re2.indexIn(s) != -1) {
                             _relative = pa2.f / pa.f;
                             _isRelative = true;
                             updateRelative();
                             updateScore();
                             return;
                             }
                       }
                  }
            }
      }

//---------------------------------------------------------
//   setTempo
//---------------------------------------------------------

void TempoText::setTempo(qreal v)
      {
      if (v < MIN_TEMPO)
            v = MIN_TEMPO;
      else if (v > MAX_TEMPO)
            v = MAX_TEMPO;
      _tempo = v;
      }

//---------------------------------------------------------
//   undoSetTempo
//---------------------------------------------------------

void TempoText::undoSetTempo(qreal v)
      {
      undoChangeProperty(Pid::TEMPO, v);
      }

//---------------------------------------------------------
//   undoSetFollowText
//---------------------------------------------------------

void TempoText::undoSetFollowText(bool v)
      {
      undoChangeProperty(Pid::TEMPO_FOLLOW_TEXT, v);
      }

//---------------------------------------------------------
//   getProperty
//---------------------------------------------------------

QVariant TempoText::getProperty(Pid propertyId) const
      {
      switch (propertyId) {
            case Pid::TEMPO:
                  return _tempo;
            case Pid::TEMPO_FOLLOW_TEXT:
                  return _followText;
            default:
                  return TextBase::getProperty(propertyId);
            }
      }

//---------------------------------------------------------
//   setProperty
//---------------------------------------------------------

bool TempoText::setProperty(Pid propertyId, const QVariant& v)
      {
      switch (propertyId) {
            case Pid::TEMPO:
                  setTempo(v.toDouble());
                  score()->setTempo(segment(), _tempo);
                  score()->fixTicks();
                  break;
            case Pid::TEMPO_FOLLOW_TEXT:
                  _followText = v.toBool();
                  break;
            default:
                  if (!TextBase::setProperty(propertyId, v))
                        return false;
                  break;
            }
      triggerLayout();
      return true;
      }

//---------------------------------------------------------
//   propertyDefault
//---------------------------------------------------------

QVariant TempoText::propertyDefault(Pid id) const
      {
      switch(id) {
            case Pid::SUB_STYLE:
                  return int(SubStyleId::TEMPO);
            case Pid::TEMPO:
                  return 2.0;
            case Pid::TEMPO_FOLLOW_TEXT:
                  return false;
            default:
                  return TextBase::propertyDefault(id);
            }
      }

//---------------------------------------------------------
//   layout
//    called after Measure->stretchMeasure()
//---------------------------------------------------------

void TempoText::layout()
      {
      qreal y = placeAbove() ? styleP(Sid::tempoPosAbove) : styleP(Sid::tempoPosBelow) + staff()->height();
      setPos(QPointF(0.0, y));
      TextBase::layout1();

      Segment* s = segment();
      if (!s)                       // for use in palette
            return;

      // tempo text on first chordrest of measure should align over time sig if present
      //
      if (!s->rtick()) {
            Segment* p = segment()->prev(SegmentType::TimeSig);
            if (p) {
                  rxpos() -= s->x() - p->x();
                  Element* e = p->element(staffIdx() * VOICES);
                  if (e)
                        rxpos() += e->x();
                  }
            }
      autoplaceSegmentElement(styleP(Sid::tempoMinDistance));
      }

//---------------------------------------------------------
//   duration2userName
//---------------------------------------------------------

QString TempoText::duration2userName(const TDuration t)
      {
      QString dots;
      switch (t.dots()) {
            case 1: dots = QObject::tr("Dotted %1").arg(t.durationTypeUserName());
                  break;
            case 2: dots = QObject::tr("Double dotted %1").arg(t.durationTypeUserName());
                  break;
            case 3: dots = QObject::tr("Triple dotted %1").arg(t.durationTypeUserName());
                  break;
            case 4: dots = QObject::tr("Quadruple dotted %1").arg(t.durationTypeUserName());
                  break;
            default:
                  dots = t.durationTypeUserName();
                  break;
            }
      return dots;
      }

//---------------------------------------------------------
//   accessibleInfo
//---------------------------------------------------------

QString TempoText::accessibleInfo() const
      {
      TDuration t1;
      TDuration t2;
      int len1;
      int len2;
      QString text = plainText();
      QString firstPart = text.split(" = ").first();
      QString secondPart = text.split(" = ").back();
      int x1 = findTempoDuration(firstPart, len1, t1);
      int x2 = -1;
      if (_relative)
            x2 = findTempoDuration(secondPart, len2, t2);

      if (x1 != -1) {
            QString dots1;
            QString dots2;
            dots1 = duration2userName(t1);
            if (x2 != -1) {
                  dots2 = duration2userName(t2);
                  return QString("%1: %2 %3 = %4 %5").arg(Element::accessibleInfo()).arg(dots1).arg(QObject::tr("note")).arg(dots2).arg(QObject::tr("note"));
                  }
            else
                  return QString("%1: %2 %3 = %4").arg(Element::accessibleInfo()).arg(dots1).arg(QObject::tr("note")).arg(secondPart);
            }
      else
            return TextBase::accessibleInfo();
      }

}
Exemplo n.º 9
0
void MuseScore::populatePalette()
      {
      //-----------------------------------
      //    notes
      //-----------------------------------

      Palette* notePalette = new Palette;
      notePalette->setName(tr("Grace Notes"));
      notePalette->setGrid(32, 40);
      notePalette->setDrawGrid(true);

      static const IconAction gna[] = {
            { ICON_ACCIACCATURA, "acciaccatura" },
            { ICON_APPOGGIATURA, "appoggiatura" },
            { ICON_GRACE4,       "grace4" },
            { ICON_GRACE16,      "grace16" },
            { ICON_GRACE32,      "grace32" },
            { -1, "" }
            };
      populateIconPalette(notePalette, gna);

      paletteBox->addPalette(notePalette);

      //-----------------------------------
      //    clefs
      //-----------------------------------

      Palette* sp = new Palette;
      sp->setName(tr("Clefs"));
      sp->setMag(0.8);
      sp->setGrid(33, 60);
      sp->setYOffset(1.0);
      static const ClefType clefs[21] = {
            CLEF_G, CLEF_G1, CLEF_G2, CLEF_G3, CLEF_G4,
            CLEF_C1, CLEF_C2, CLEF_C3, CLEF_C4, CLEF_C5,
            CLEF_F, CLEF_F_8VA, CLEF_F_15MA, CLEF_F8, CLEF_F15, CLEF_F_B, CLEF_F_C,
            CLEF_PERC, CLEF_TAB, CLEF_TAB2, CLEF_PERC2
            };
      for (int i = 0; i < 20; ++i) {
            ClefType j = clefs[i];
            Clef* k = new ::Clef(gscore);
            k->setClefType(ClefTypeList(j, j));
            sp->append(k, qApp->translate("clefTable", clefTable[j].name));
            }
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    key signatures
      //-----------------------------------

      sp = newKeySigPalette();
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Time
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Time Signatures"));
      sp->setMag(.8);
      sp->setGrid(42, 38);

      TimeSig* ts;
      ts = new TimeSig(gscore);
      ts->setSig(2, 2);
      sp->append(ts, "2/2");

      sp->append(new TimeSig(gscore,  2, 4), "2/4");
      sp->append(new TimeSig(gscore,  3, 4), "3/4");
      sp->append(new TimeSig(gscore,  4, 4), "4/4");
      sp->append(new TimeSig(gscore,  5, 4), "5/4");
      sp->append(new TimeSig(gscore,  6, 4), "6/4");
      sp->append(new TimeSig(gscore,  3, 8), "3/8");
      sp->append(new TimeSig(gscore,  6, 8), "6/8");
      sp->append(new TimeSig(gscore,  9, 8), "9/8");
      sp->append(new TimeSig(gscore, 12, 8), "12/8");

      sp->append(new TimeSig(gscore, TSIG_FOUR_FOUR),  tr("4/4 common time"));
      sp->append(new TimeSig(gscore, TSIG_ALLA_BREVE), tr("2/2 alla breve"));
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Bar Lines
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Barlines"));
      sp->setMag(0.8);
      sp->setGrid(42, 38);

      struct {
            BarLineType type;
            const char* name;
            } t[] = {
            { NORMAL_BAR,       QT_TR_NOOP("Normal") },
            { BROKEN_BAR,       QT_TR_NOOP("Dashed") },
            { END_BAR,          QT_TR_NOOP("End Bar") },
            { DOUBLE_BAR,       QT_TR_NOOP("Double Bar") },
            { START_REPEAT,     QT_TR_NOOP("Start Repeat") },
            { END_REPEAT,       QT_TR_NOOP("End Repeat") },
            { END_START_REPEAT, QT_TR_NOOP("End-Start Repeat") },
            };
      for (unsigned i = 0; i < sizeof(t)/sizeof(*t); ++i) {
            BarLine* b  = new BarLine(gscore);
            b->setSubtype(t[i].type);
            sp->append(b, tr(t[i].name));
            }
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Lines
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Lines"));
      sp->setMag(.8);
      sp->setGrid(82, 23);

      Slur* slur = new Slur(gscore);
      slur->setId(0);
      sp->append(slur, tr("Slur"));

      Hairpin* gabel0 = new Hairpin(gscore);
      gabel0->setSubtype(0);
      sp->append(gabel0, tr("Crescendo"));

      Hairpin* gabel1 = new Hairpin(gscore);
      gabel1->setSubtype(1);
      sp->append(gabel1, tr("Diminuendo"));

      Volta* volta = new Volta(gscore);
      volta->setSubtype(VOLTA_CLOSED);
      volta->setText("1.");
      QList<int> il;
      il.append(1);
      volta->setEndings(il);
      sp->append(volta, tr("Prima volta"));

      volta = new Volta(gscore);
      volta->setSubtype(VOLTA_CLOSED);
      volta->setText("2.");
      il.clear();
      il.append(2);
      volta->setEndings(il);
      sp->append(volta, tr("Seconda volta"));

      volta = new Volta(gscore);
      volta->setSubtype(VOLTA_CLOSED);
      volta->setText("3.");
      il.clear();
      il.append(3);
      volta->setEndings(il);
      sp->append(volta, tr("Terza volta"));

      volta = new Volta(gscore);
      volta->setSubtype(VOLTA_OPEN);
      volta->setText("2.");
      il.clear();
      il.append(2);
      volta->setEndings(il);
      sp->append(volta, tr("Seconda volta 2"));

      Ottava* ottava = new Ottava(gscore);
      ottava->setSubtype(0);
      sp->append(ottava, tr("8va"));

      ottava = new Ottava(gscore);
      ottava->setSubtype(1);
      sp->append(ottava, tr("15ma"));

      ottava = new Ottava(gscore);
      ottava->setSubtype(2);
      sp->append(ottava, tr("8vb"));

      ottava = new Ottava(gscore);
      ottava->setSubtype(3);
      sp->append(ottava, tr("15mb"));

      Pedal* pedal = new Pedal(gscore);
      //pedal->setLen(l);
      sp->append(pedal, tr("Pedal"));

      pedal = new Pedal(gscore);
      //pedal->setLen(l);
      pedal->setEndHookType(HOOK_45);
      sp->append(pedal, tr("Pedal"));

      pedal = new Pedal(gscore);
      //pedal->setLen(l);
      pedal->setBeginSymbol(-1);
      pedal->setBeginHook(true);
      pedal->setBeginHookType(HOOK_45);
      pedal->setEndHookType(HOOK_45);
      sp->append(pedal, tr("Pedal"));

      pedal = new Pedal(gscore);
      //pedal->setLen(l);
      pedal->setBeginSymbol(-1);
      pedal->setBeginHook(true);
      pedal->setBeginHookType(HOOK_45);
      sp->append(pedal, tr("Pedal"));

      Trill* trill = new Trill(gscore);
      sp->append(trill, tr("Trill line"));

      trill = new Trill(gscore);
      trill->setSubtype("upprall");
      sp->append(trill, tr("Upprall line"));

      trill = new Trill(gscore);
      trill->setSubtype("downprall");
      sp->append(trill, tr("Downprall line"));

      trill = new Trill(gscore);
      trill->setSubtype("prallprall");
      sp->append(trill, tr("Prallprall line"));

      TextLine* textLine = new TextLine(gscore);
      textLine->setBeginText("VII");
      textLine->setEndHook(true);
      sp->append(textLine, tr("Text line"));

      TextLine* line = new TextLine(gscore);
      line->setDiagonal(true);
      sp->append(line, tr("Line"));

      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Arpeggio && Glissando
      //-----------------------------------

      sp = new Palette();
      sp->setName(tr("Arpeggio && Glissando"));
      sp->setGrid(27, 60);

      for (int i = 0; i < 4; ++i) {
            Arpeggio* a = new Arpeggio(gscore);
            a->setSubtype(ArpeggioType(i));
            sp->append(a, tr("Arpeggio"));
            }
      for (int i = 0; i < 2; ++i) {
            Glissando* a = new Glissando(gscore);
            a->setSubtype(i);
            sp->append(a, tr("Glissando"));
            }
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Symbols: Breath
      //-----------------------------------

      sp = new Palette();
      sp->setName(tr("Breath && Pauses"));
      sp->setGrid(42, 40);

      for (int i = 0; i < 4; ++i) {
            Breath* a = new Breath(gscore);
            a->setSubtype(i);
            if (i < 2)
                  sp->append(a, tr("Breath"));
            else
                  sp->append(a, tr("Caesura"));
            }

      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Brackets
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Brackets"));
      sp->setMag(0.7);
      sp->setGrid(42, 60);

      Bracket* b1 = new Bracket(gscore);
      b1->setSubtype(BRACKET_NORMAL);
      Bracket* b2 = new Bracket(gscore);
      b2->setSubtype(BRACKET_AKKOLADE);
      // b1->setHeight(_spatium * 7);
      // b2->setHeight(_spatium * 7);

      sp->append(b1, tr("Square bracket"));
      sp->append(b2, tr("Curly bracket"));

      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Attributes, Ornaments
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Articulations && Ornaments"));
      sp->setGrid(42, 25);

      for (int i = 0; i < ARTICULATIONS; ++i) {
            Articulation* s = new Articulation(gscore);
            s->setSubtype(ArticulationType(i));
            sp->append(s, qApp->translate("articulation", qPrintable(s->subtypeUserName())));
            }
      Bend* bend = new Bend(gscore);
      bend->points().append(PitchValue(0,    0, false));
      bend->points().append(PitchValue(15, 100, false));
      bend->points().append(PitchValue(60, 100, false));
      sp->append(bend, qApp->translate("articulation", "Bend"));

      TremoloBar* tb = new TremoloBar(gscore);
      tb->points().append(PitchValue(0,     0, false));     // "Dip"
      tb->points().append(PitchValue(30, -100, false));
      tb->points().append(PitchValue(60,    0, false));
      sp->append(tb, qApp->translate("articulation", "Tremolo Bar"));

      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Accidentals
      //-----------------------------------

      sp = newAccidentalsPalette();
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Dynamics
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Dynamics"));
      sp->setMag(.8);
      sp->setGrid(42, 28);

      static const char* dynS[] = {
            "ppp", "pp", "p", "mp", "mf", "f", "ff", "fff"
            };
      for (unsigned i = 0; i < sizeof(dynS)/sizeof(*dynS); ++i) {
            Dynamic* dynamic = new Dynamic(gscore);
            dynamic->setSubtype(dynS[i]);
            sp->append(dynamic, dynamic->subtypeName());
            }
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Fingering
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Fingering"));
      sp->setMag(1.5);
      sp->setGrid(28, 30);
      sp->setDrawGrid(true);

      const char finger[] = "012345pimac";
      for (unsigned i = 0; i < strlen(finger); ++i) {
            Fingering* f = new Fingering(gscore);
            f->setText(QString(finger[i]));
            sp->append(f, tr("Fingering %1").arg(finger[i]));
            }
      const char stringnumber[] = "0123456";
      for (unsigned i = 0; i < strlen(stringnumber); ++i) {
            Fingering* f = new Fingering(gscore);
            f->setTextStyle(TEXT_STYLE_STRING_NUMBER);
            f->setText(QString(stringnumber[i]));
            sp->append(f, tr("String number %1").arg(stringnumber[i]));
            }
      Symbol* symbol = new Symbol(gscore, thumbSym);
      sp->append(symbol, tr("Thumb"));

      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Noteheads
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Note Heads"));
      sp->setMag(1.3);
      sp->setGrid(33, 36);
      sp->setDrawGrid(true);

      for (int i = 0; i < HEAD_GROUPS; ++i) {
            int sym = noteHeads[0][i][1];
            if (i == HEAD_BREVIS_ALT)
                  sym = noteHeads[0][i][3];
            NoteHead* nh = new NoteHead(gscore);
            nh->setSym(sym);
            sp->append(nh, qApp->translate("symbol", symbols[0][sym].name()));
            }
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Tremolo
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Tremolo"));
      sp->setGrid(27, 40);
      sp->setDrawGrid(true);
      const char* tremoloName[] = {
            QT_TR_NOOP("1/8 through stem"),
            QT_TR_NOOP("1/16 through stem"),
            QT_TR_NOOP("1/32 through stem"),
            QT_TR_NOOP("1/64 through stem"),
            QT_TR_NOOP("1/8 between notes"),
            QT_TR_NOOP("1/16 between notes"),
            QT_TR_NOOP("1/32 between notes"),
            QT_TR_NOOP("1/64 between notes")
            };

      for (int i = TREMOLO_R8; i <= TREMOLO_C64; ++i) {
            Tremolo* tremolo = new Tremolo(gscore);
            tremolo->setSubtype(TremoloType(i));
            sp->append(tremolo, tr(tremoloName[i - TREMOLO_R8]));
            }
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Fall, Doit
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Fall/Doit"));
      sp->setGrid(27, 40);
      sp->setDrawGrid(true);
      const char* scorelineNames[] = {
            QT_TR_NOOP("fall"),
            QT_TR_NOOP("doit"),
            };

      ChordLine* cl = new ChordLine(gscore);
      cl->setSubtype(1);
      sp->append(cl, tr(scorelineNames[0]));

      cl = new ChordLine(gscore);
      cl->setSubtype(2);
      sp->append(cl, tr(scorelineNames[1]));

      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Repeats
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Repeats"));
      sp->setMag(0.65);
      sp->setGrid(84, 28);
      sp->setDrawGrid(true);

      RepeatMeasure* rm = new RepeatMeasure(gscore);
      sp->append(rm, tr("Repeat measure sign"));

      Marker* mk = new Marker(gscore);
      mk->setMarkerType(MARKER_SEGNO);
      sp->append(mk, tr("Segno"));

      mk = new Marker(gscore);
      mk->setMarkerType(MARKER_VARSEGNO);
      sp->append(mk, tr("Segno Variation"));

      mk = new Marker(gscore);
      mk->setMarkerType(MARKER_CODA);
      sp->append(mk, tr("Coda"));

      mk = new Marker(gscore);
      mk->setMarkerType(MARKER_VARCODA);
      sp->append(mk, tr("Varied coda"));

      mk = new Marker(gscore);
      mk->setMarkerType(MARKER_CODETTA);
      sp->append(mk, tr("Codetta"));

      mk = new Marker(gscore);
      mk->setMarkerType(MARKER_FINE);
      sp->append(mk, tr("Fine"));

      Jump* jp = new Jump(gscore);
      jp->setJumpType(JUMP_DC);
      sp->append(jp, tr("Da Capo"));

      jp = new Jump(gscore);
      jp->setJumpType(JUMP_DC_AL_FINE);
      sp->append(jp, tr("Da Capo al Fine"));

      jp = new Jump(gscore);
      jp->setJumpType(JUMP_DC_AL_CODA);
      sp->append(jp, tr("Da Capo al Coda"));

      jp = new Jump(gscore);
      jp->setJumpType(JUMP_DS_AL_CODA);
      sp->append(jp, tr("D.S al Coda"));

      jp = new Jump(gscore);
      jp->setJumpType(JUMP_DS_AL_FINE);
      sp->append(jp, tr("D.S al Fine"));

      jp = new Jump(gscore);
      jp->setJumpType(JUMP_DS);
      sp->append(jp, tr("D.S"));

      mk = new Marker(gscore);
      mk->setMarkerType(MARKER_TOCODA);
      sp->append(mk, tr("To Coda"));

      paletteBox->addPalette(sp);

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

      sp = new Palette;
      sp->setName(tr("Text"));
      sp->setMag(0.65);
      sp->setGrid(84, 28);
      sp->setDrawGrid(true);

      StaffText* st = new StaffText(gscore);
      st->setSystemFlag(false);
      st->setTextStyle(TEXT_STYLE_STAFF);
//TODO      st->setSubtype(TEXT_STAFF);
      st->setText(tr("staff-text"));
      sp->append(st, tr("Staff Text"));

      st = new StaffText(gscore);
      st->setSystemFlag(true);
      st->setTextStyle(TEXT_STYLE_SYSTEM);
//      st->setSubtype(TEXT_SYSTEM);
      st->setText(tr("system-text"));
      sp->append(st, tr("System Text"));

      RehearsalMark* rhm = new RehearsalMark(gscore);
      rhm->setTrack(0);
      rhm->setText("B1");
      sp->append(rhm, tr("RRehearsal Mark"));

      InstrumentChange* is = new InstrumentChange(gscore);
      is->setText(tr("Instrument"));
      sp->append(is, tr("Instrument Change"));

      Text* text = new Text(gscore);
      text->setTrack(0);
      text->setTextStyle(TEXT_STYLE_LYRICS_VERSE_NUMBER);
      text->setText(tr("1."));
      text->setSystemFlag(true);
      sp->append(text, tr("Lyrics Verse Number"));

      static const TempoPattern tp[] = {
            TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd5f)), 80.0/60.0),      // 1/4
            TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd5e)), 80.0/30.0),      // 1/2
            TempoPattern(QString("%1%2 = 80").    arg(QChar(0xd834)).arg(QChar(0xdd60)), 80.0/120.0),     // 1/8
            TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120.0/60.0),  // dotted 1/4
            TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5e)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/30.0),    // dotted 1/2
            TempoPattern(QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)).arg(QChar(0xd834)).arg(QChar(0xdd6d)), 120/120.0)    // dotted 1/8
            };
      for (unsigned i = 0; i < sizeof(tp)/sizeof(*tp); ++i) {
            TempoText* tt = new TempoText(gscore);
            tt->setFollowText(true);
            tt->setTrack(0);
            tt->setTempo(tp[i].f);
            tt->setText(tp[i].pattern);
            sp->append(tt, tr("Tempo Text"), QString(), 1.5);
            }

      Harmony* harmony = new Harmony(gscore);
      harmony->setText("c7");
      sp->append(harmony, tr("Chord Name"));

      paletteBox->addPalette(sp);

      //-----------------------------------
      //    breaks
      //-----------------------------------

      qreal _spatium = gscore->spatium();
      sp = new Palette;
      sp->setName(tr("Breaks && Spacer"));
      sp->setMag(.7);
      sp->setGrid(42, 36);
      sp->setDrawGrid(true);

      LayoutBreak* lb = new LayoutBreak(gscore);
      lb->setSubtype(LAYOUT_BREAK_LINE);
      sp->append(lb, tr("Line break"));

      lb = new LayoutBreak(gscore);
      lb->setSubtype(LAYOUT_BREAK_PAGE);
      sp->append(lb, tr("Page break"));

      lb = new LayoutBreak(gscore);
      lb->setSubtype(LAYOUT_BREAK_SECTION);
      sp->append(lb, tr("Section break"));

      Spacer* spacer = new Spacer(gscore);
      spacer->setGap(3 * _spatium);
      spacer->setSubtype(SPACER_DOWN);
      sp->append(spacer, tr("Staff spacer down"));

      spacer = new Spacer(gscore);
      spacer->setGap(3 * _spatium);
      spacer->setSubtype(SPACER_UP);
      sp->append(spacer, tr("Staff spacer up"));

      paletteBox->addPalette(sp);

      //-----------------------------------
      //    staff state changes
      //-----------------------------------

#if 0
      sp = new Palette;
      sp->setName(tr("Staff Changes"));
      sp->setMag(.7);
      sp->setGrid(42, 36);
      sp->setDrawGrid(true);

      StaffState* st = new StaffState(gscore);
      st->setSubtype(STAFF_STATE_VISIBLE);
      sp->append(st, tr("set visible"));

      st = new StaffState(gscore);
      st->setSubtype(STAFF_STATE_INVISIBLE);
      sp->append(st, tr("set invisible"));

      st = new StaffState(gscore);
      st->setSubtype(STAFF_STATE_TYPE);
      sp->append(st, tr("change staff type"));

      st = new StaffState(gscore);
      st->setSubtype(STAFF_STATE_INSTRUMENT);
      sp->append(st, tr("change instrument"));

      paletteBox->addPalette(sp);
#endif

      //-----------------------------------
      //    beam properties
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Beam Properties"));
      sp->setGrid(27, 40);
      sp->setDrawGrid(true);

      static const IconAction bpa[] = {
            { ICON_SBEAM,    "beam-start" },
            { ICON_MBEAM,    "beam-mid" },
            { ICON_NBEAM,    "no-beam" },
            { ICON_BEAM32,   "beam32" },
            { ICON_BEAM64,   "beam64" },
            { ICON_AUTOBEAM, "auto-beam" },
            { ICON_FBEAM1,   "fbeam1" },
            { ICON_FBEAM2,   "fbeam2" },
            { -1, ""}
            };

      populateIconPalette(sp, bpa);
      paletteBox->addPalette(sp);

      //-----------------------------------
      //    Symbols
      //-----------------------------------

      sp = new Palette;
      sp->setName(tr("Symbols"));
      sp->setGrid(42, 45);
      sp->setDrawGrid(true);

      sp->append(accDiscantSym);
      sp->append(accDotSym);
      sp->append(accFreebaseSym);
      sp->append(accStdbaseSym);
      sp->append(accBayanbaseSym);
      sp->append(accOldEESym);
      sp->append(accpushSym);
      sp->append(accpullSym);

      FretDiagram* fret = new FretDiagram(gscore);
      fret->setDot(5, 1);
      fret->setDot(2, 2);
      fret->setDot(1, 3);
      fret->setMarker(0, 'X');
      fret->setMarker(3, 'O');
      fret->setMarker(4, 'O');
      sp->append(fret, tr("Fret Diagram"));

      paletteBox->addPalette(sp);
      }