1 //=============================================================================
2 //  MuseScore
3 //  Music Composition & Notation
4 //
5 //  Copyright (C) 2002-2011 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 "libmscore/score.h"
14 #include "libmscore/element.h"
15 #include "libmscore/note.h"
16 #include "libmscore/rest.h"
17 #include "libmscore/measure.h"
18 #include "libmscore/system.h"
19 #include "libmscore/segment.h"
20 #include "libmscore/page.h"
21 #include "libmscore/image.h"
22 #include "libmscore/text.h"
23 #include "libmscore/spanner.h"
24 #include "libmscore/chord.h"
25 #include "libmscore/icon.h"
26 #include "libmscore/xml.h"
27 #include "libmscore/stafflines.h"
28 #include "musescore.h"
29 #include "scoreview.h"
30 #include "continuouspanel.h"
31 #include "tourhandler.h"
32 
33 namespace Ms {
34 
35 //---------------------------------------------------------
36 //   setDropTarget
37 //---------------------------------------------------------
38 
setDropTarget(const Element * el)39 void ScoreView::setDropTarget(const Element* el)
40       {
41       if (dropTarget != el) {
42             if (dropTarget) {
43                   dropTarget->setDropTarget(false);
44                   dropTarget = 0;
45                   }
46             dropTarget = el;
47             if (dropTarget) {
48                   dropTarget->setDropTarget(true);
49                   }
50             }
51       if (!m_dropAnchorLines.isEmpty())
52             m_dropAnchorLines.clear();
53 
54       if (dropRectangle.isValid()) {
55             dropRectangle = QRectF();
56             }
57       update();
58       }
59 
60 //---------------------------------------------------------
61 //   setDropRectangle
62 //---------------------------------------------------------
63 
setDropRectangle(const QRectF & r)64 void ScoreView::setDropRectangle(const QRectF& r)
65       {
66       if (dropRectangle.isValid())
67             _score->addRefresh(dropRectangle);
68       dropRectangle = r;
69       if (dropTarget) {
70             dropTarget->setDropTarget(false);
71             _score->addRefresh(dropTarget->canvasBoundingRect());
72             dropTarget = 0;
73             }
74       else if (!m_dropAnchorLines.isEmpty()) {
75             QRectF rf;
76             rf.setTopLeft(m_dropAnchorLines.first().p1());
77             rf.setBottomRight(m_dropAnchorLines.first().p2());
78             _score->addRefresh(rf.normalized());
79             m_dropAnchorLines.clear();
80             }
81 
82       update();
83       }
84 
85 //---------------------------------------------------------
86 //   setDropAnchorList
87 //---------------------------------------------------------
setDropAnchorLines(const QVector<QLineF> & anchorList)88 void ScoreView::setDropAnchorLines(const QVector<QLineF>& anchorList)
89       {
90       if (m_dropAnchorLines != anchorList)
91             m_dropAnchorLines = anchorList;
92 
93       if (dropRectangle.isValid())
94             dropRectangle = QRectF();
95 
96       update();
97       }
98 
99 //---------------------------------------------------------
100 //   setViewRect
101 //---------------------------------------------------------
102 
setViewRect(const QRectF & r)103 void ScoreView::setViewRect(const QRectF& r)
104       {
105       QRectF rr = _matrix.mapRect(r);
106       QPoint d = rr.topLeft().toPoint();
107       int dx   = -d.x();
108       int dy   = -d.y();
109       QApplication::sendPostedEvents(this, 0);
110       _matrix.setMatrix(_matrix.m11(), _matrix.m12(), _matrix.m13(), _matrix.m21(),
111          _matrix.m22(), _matrix.m23(), _matrix.dx()+dx, _matrix.dy()+dy, _matrix.m33());
112       imatrix = _matrix.inverted();
113       scroll(dx, dy, QRect(0, 0, width(), height()));
114       emit offsetChanged(_matrix.dx(), _matrix.dy());
115       if (_continuousPanel->visible())
116             update();
117       }
118 
119 //---------------------------------------------------------
120 //   dragTimeAnchorElement
121 //    pos is in canvas coordinates
122 //    return true if there is a valid target
123 //---------------------------------------------------------
124 
dragTimeAnchorElement(const QPointF & pos)125 bool ScoreView::dragTimeAnchorElement(const QPointF& pos)
126       {
127       int staffIdx;
128       Segment* seg;
129       MeasureBase* mb = _score->pos2measure(pos, &staffIdx, 0, &seg, 0);
130       int track  = staffIdx * VOICES;
131 
132       if (mb && mb->isMeasure() && seg->element(track)) {
133             Measure* m = toMeasure(mb);
134             System* s  = m->system();
135             qreal y    = s->staff(staffIdx)->y() + s->pos().y() + s->page()->pos().y();
136             QPointF anchor(seg->canvasBoundingRect().x(), y);
137             setDropAnchorLines({ QLineF(pos, anchor) });
138             editData.dropElement->score()->addRefresh(editData.dropElement->canvasBoundingRect());
139             editData.dropElement->setTrack(track);
140             editData.dropElement->score()->addRefresh(editData.dropElement->canvasBoundingRect());
141             return true;
142             }
143       editData.dropElement->score()->addRefresh(editData.dropElement->canvasBoundingRect());
144       setDropTarget(0);
145       return false;
146       }
147 
148 //---------------------------------------------------------
149 //   dragMeasureAnchorElement
150 //---------------------------------------------------------
151 
dragMeasureAnchorElement(const QPointF & pos)152 bool ScoreView::dragMeasureAnchorElement(const QPointF& pos)
153       {
154       int staffIdx;
155       Segment* seg;
156       MeasureBase* mb = _score->pos2measure(pos, &staffIdx, 0, &seg, 0);
157       if (!(editData.modifiers & Qt::ControlModifier))
158             staffIdx = 0;
159       int track = staffIdx * VOICES;
160 
161       if (mb && mb->isMeasure()) {
162             Measure* m = toMeasure(mb);
163             System* s  = m->system();
164             qreal y    = s->staff(staffIdx)->y() + s->pos().y() + s->page()->pos().y();
165             QRectF b(m->canvasBoundingRect());
166             if (pos.x() >= (b.x() + b.width() * .5) && m != _score->lastMeasureMM() && m->nextMeasure()->system() == m->system())
167                   m = m->nextMeasure();
168             QPointF anchor(m->canvasBoundingRect().x(), y);
169             setDropAnchorLines({ QLineF(pos, anchor) });
170             editData.dropElement->score()->addRefresh(editData.dropElement->canvasBoundingRect());
171             editData.dropElement->setTrack(track);
172             editData.dropElement->score()->addRefresh(editData.dropElement->canvasBoundingRect());
173             return true;
174             }
175       editData.dropElement->score()->addRefresh(editData.dropElement->canvasBoundingRect());
176       setDropTarget(0);
177       return false;
178       }
179 
180 //---------------------------------------------------------
181 //   dragEnterEvent
182 //---------------------------------------------------------
183 
dragEnterEvent(QDragEnterEvent * event)184 void ScoreView::dragEnterEvent(QDragEnterEvent* event)
185       {
186       double _spatium = score()->spatium();
187       editData.dropElement = 0;
188 
189       const QMimeData* dta = event->mimeData();
190 
191       if (dta->hasFormat(mimeSymbolListFormat) || dta->hasFormat(mimeStaffListFormat)) {
192             if (event->possibleActions() & Qt::CopyAction)
193                   event->setDropAction(Qt::CopyAction);
194             if (event->dropAction() == Qt::CopyAction)
195                   event->accept();
196             return;
197             }
198 
199       if (dta->hasFormat(mimeSymbolFormat)) {
200             if (event->possibleActions() & Qt::CopyAction)
201                   event->setDropAction(Qt::CopyAction);
202             if (event->dropAction() == Qt::CopyAction)
203                   event->accept();
204 
205             mscore->notifyElementDraggedToScoreView();
206 
207             QByteArray a = dta->data(mimeSymbolFormat);
208 
209             if (MScore::debugMode)
210                   qDebug("ScoreView::dragEnterEvent Symbol: <%s>", a.data());
211 
212             XmlReader e(a);
213             editData.dragOffset = QPoint();
214             Fraction duration;  // dummy
215             ElementType type = Element::readType(e, &editData.dragOffset, &duration);
216 
217             Element* el = Element::create(type, score());
218             if (el) {
219                   if (type == ElementType::BAR_LINE || type == ElementType::ARPEGGIO || type == ElementType::BRACKET)
220                         el->setHeight(_spatium * 5);
221                   editData.dropElement = el;
222                   editData.dropElement->setParent(0);
223                   editData.dropElement->read(e);
224                   editData.dropElement->layout();
225                   }
226             return;
227             }
228 
229       if (dta->hasUrls()) {
230             QList<QUrl>ul = dta->urls();
231             QUrl u = ul.front();
232 
233             QMimeDatabase db;
234             if (!QImageReader::supportedMimeTypes().contains(db.mimeTypeForUrl(u).name().toLatin1())) {
235                   event->ignore();
236                   return;
237                   }
238 
239             Image* image = 0;
240             if (u.scheme() == "file") {
241                   image = new Image(score());
242                   QString str(u.toLocalFile());
243                   image->load(str);
244                   }
245             else if (u.scheme() == "http" || u.scheme() == "https") {
246                   QNetworkAccessManager manager;
247                   QNetworkReply* reply = manager.get(QNetworkRequest(u));
248 
249                   // TODO:
250                   //    feed progress bar in loop
251                   //    implement timeout/abort
252 
253                   QMutex mutex;
254                   QWaitCondition wc;
255                   while (!reply->isFinished()) {
256                         mutex.lock();
257                         wc.wait(&mutex, 100);
258                         qApp->processEvents();
259                         mutex.unlock();
260                         }
261                   QByteArray ba = reply->readAll();
262 
263                   image = new Image(score());
264                   image->loadFromData(u.path(), ba);
265                   delete reply;
266                   }
267             if (image) {
268                   editData.dropElement = image;
269                   editData.dropElement->setParent(0);
270                   editData.dropElement->layout();
271                   event->accept();
272                   }
273             return;
274             }
275       qDebug("unknown drop format: formats:");
276       for (const QString& s : dta->formats())
277             qDebug("  <%s>", qPrintable(s));
278       event->ignore();
279       }
280 
281 //---------------------------------------------------------
282 //   getDropTarget
283 //---------------------------------------------------------
284 
getDropTarget(EditData & ed)285 Element* ScoreView::getDropTarget(EditData& ed)
286       {
287       QList<Element*> el = elementsAt(ed.pos);
288       setDropTarget(0);
289       for (Element* e : qAsConst(el)) {
290             if (e->isStaffLines()) {
291                   if (el.size() > 2)      // is not first class drop target
292                         continue;
293                   e = toStaffLines(e)->measure();
294                   }
295             if (e->acceptDrop(ed)) {
296                   if (!e->isMeasure())
297                         setDropTarget(e);
298                   return e;
299                   }
300             }
301       return nullptr;
302       }
303 
304 //---------------------------------------------------------
305 //   dragMoveEvent
306 //---------------------------------------------------------
307 
dragMoveEvent(QDragMoveEvent * event)308 void ScoreView::dragMoveEvent(QDragMoveEvent* event)
309       {
310       // we always accept the drop action
311       // to get a "drop" Event:
312 
313       if (MScore::debugMode) {
314             if (!editData.dropElement)
315                   qDebug("no drop element");
316             else
317                   qDebug("<%s>", editData.dropElement->name());
318             }
319 
320       if (!editData.dropElement || mscore->state() == STATE_PLAY) {  // no editing during play
321             event->ignore();
322             return;
323             }
324 
325       const QMimeData* dta = event->mimeData();
326       if (dta->hasFormat(mimeSymbolFormat)
327          || dta->hasFormat(mimeSymbolListFormat)
328          || dta->hasFormat(mimeStaffListFormat)) {
329             if (event->possibleActions() & Qt::CopyAction)
330                   event->setDropAction(Qt::CopyAction);
331             }
332 
333       // convert window to canvas position
334       QPointF pos(imatrix.map(QPointF(event->pos())));
335       editData.pos       = pos;
336       editData.modifiers = event->keyboardModifiers();
337 
338       switch (editData.dropElement->type()) {
339             case ElementType::VOLTA:
340                   event->setAccepted(dragMeasureAnchorElement(pos));
341                   break;
342             case ElementType::PEDAL:
343             case ElementType::LET_RING:
344             case ElementType::VIBRATO:
345             case ElementType::PALM_MUTE:
346             case ElementType::OTTAVA:
347             case ElementType::TRILL:
348             case ElementType::HAIRPIN:
349             case ElementType::TEXTLINE:
350                   event->setAccepted(dragTimeAnchorElement(pos));
351                   break;
352             case ElementType::IMAGE:
353             case ElementType::SYMBOL:
354             case ElementType::FSYMBOL:
355             case ElementType::DYNAMIC:
356             case ElementType::KEYSIG:
357             case ElementType::CLEF:
358             case ElementType::TIMESIG:
359             case ElementType::BAR_LINE:
360             case ElementType::ARPEGGIO:
361             case ElementType::BREATH:
362             case ElementType::GLISSANDO:
363             case ElementType::MEASURE_NUMBER:
364             case ElementType::MMREST_RANGE:
365             case ElementType::BRACKET:
366             case ElementType::ARTICULATION:
367             case ElementType::FERMATA:
368             case ElementType::CHORDLINE:
369             case ElementType::BEND:
370             case ElementType::ACCIDENTAL:
371             case ElementType::TEXT:
372             case ElementType::FINGERING:
373             case ElementType::TEMPO_TEXT:
374             case ElementType::STAFF_TEXT:
375             case ElementType::SYSTEM_TEXT:
376             case ElementType::NOTEHEAD:
377             case ElementType::TREMOLO:
378             case ElementType::LAYOUT_BREAK:
379             case ElementType::MARKER:
380             case ElementType::STAFF_STATE:
381             case ElementType::INSTRUMENT_CHANGE:
382             case ElementType::REHEARSAL_MARK:
383             case ElementType::JUMP:
384             case ElementType::REPEAT_MEASURE:
385             case ElementType::ICON:
386             case ElementType::CHORD:
387             case ElementType::SPACER:
388             case ElementType::SLUR:
389             case ElementType::HARMONY:
390             case ElementType::BAGPIPE_EMBELLISHMENT:
391             case ElementType::AMBITUS:
392             case ElementType::TREMOLOBAR:
393             case ElementType::FIGURED_BASS:
394             case ElementType::LYRICS:
395             case ElementType::FRET_DIAGRAM:
396             case ElementType::STAFFTYPE_CHANGE:
397                   event->setAccepted(getDropTarget(editData));
398                   break;
399             default:
400                   if (MScore::debugMode)
401                         qDebug("no target");
402                   event->ignore();
403                   break;
404             }
405       }
406 
407 //---------------------------------------------------------
408 //   dropEvent
409 //---------------------------------------------------------
410 
dropEvent(QDropEvent * event)411 void ScoreView::dropEvent(QDropEvent* event)
412       {
413       if (state == ViewState::PLAY) {
414             event->ignore();
415             return;
416             }
417       QPointF pos(imatrix.map(QPointF(event->pos())));
418 
419       editData.pos       = pos;
420       editData.modifiers = event->keyboardModifiers();
421 
422       if (editData.dropElement) {
423             bool firstStaffOnly = false;
424             bool applyUserOffset = false;
425             bool triggerSpannerDropApplyTour = editData.dropElement->isSpanner();
426             editData.dropElement->styleChanged();
427             _score->startCmd();
428             Q_ASSERT(editData.dropElement->score() == score());
429             _score->addRefresh(editData.dropElement->canvasBoundingRect());
430             switch (editData.dropElement->type()) {
431                   case ElementType::VOLTA:
432                         // voltas drop to first staff by default, or closest staff if Control is held
433                         firstStaffOnly = !(editData.modifiers & Qt::ControlModifier);
434                         // fall-thru
435                   case ElementType::OTTAVA:
436                   case ElementType::TRILL:
437                   case ElementType::PEDAL:
438                   case ElementType::LET_RING:
439                   case ElementType::VIBRATO:
440                   case ElementType::PALM_MUTE:
441                   case ElementType::HAIRPIN:
442                   case ElementType::TEXTLINE:
443                         {
444                         Spanner* spanner = static_cast<Spanner*>(editData.dropElement);
445                         score()->cmdAddSpanner(spanner, pos, firstStaffOnly);
446                         score()->setUpdateAll();
447                         event->acceptProposedAction();
448                         }
449                         break;
450                   case ElementType::SYMBOL:
451                   case ElementType::FSYMBOL:
452                   case ElementType::IMAGE:
453                         applyUserOffset = true;
454                         // fall-thru
455                   case ElementType::DYNAMIC:
456                   case ElementType::FRET_DIAGRAM:
457                   case ElementType::HARMONY:
458                         {
459                         Element* el = elementAt(pos);
460                         if (el == 0 || el->type() == ElementType::STAFF_LINES) {
461                               int staffIdx;
462                               Segment* seg;
463                               QPointF offset;
464                               el = _score->pos2measure(pos, &staffIdx, 0, &seg, &offset);
465                               if (el && el->isMeasure()) {
466                                     editData.dropElement->setTrack(staffIdx * VOICES);
467                                     editData.dropElement->setParent(seg);
468                                     if (applyUserOffset)
469                                           editData.dropElement->setOffset(offset);
470                                     score()->undoAddElement(editData.dropElement);
471                                     }
472                               else {
473                                     qDebug("cannot drop here");
474                                     delete editData.dropElement;
475                                     }
476                               }
477                         else {
478                               _score->addRefresh(el->canvasBoundingRect());
479                               _score->addRefresh(editData.dropElement->canvasBoundingRect());
480 
481                               if (!el->acceptDrop(editData)) {
482                                     qDebug("drop %s onto %s not accepted", editData.dropElement->name(), el->name());
483                                     break;
484                                     }
485                               Element* dropElement = el->drop(editData);
486                               _score->addRefresh(el->canvasBoundingRect());
487                               if (dropElement) {
488                                     _score->select(dropElement, SelectType::SINGLE, 0);
489                                     _score->addRefresh(dropElement->canvasBoundingRect());
490                                     }
491                               }
492                         }
493                         event->acceptProposedAction();
494                         break;
495                   case ElementType::HBOX:
496                   case ElementType::VBOX:
497                   case ElementType::KEYSIG:
498                   case ElementType::CLEF:
499                   case ElementType::TIMESIG:
500                   case ElementType::BAR_LINE:
501                   case ElementType::ARPEGGIO:
502                   case ElementType::BREATH:
503                   case ElementType::GLISSANDO:
504                   case ElementType::MEASURE_NUMBER:
505                   case ElementType::MMREST_RANGE:
506                   case ElementType::BRACKET:
507                   case ElementType::ARTICULATION:
508                   case ElementType::FERMATA:
509                   case ElementType::CHORDLINE:
510                   case ElementType::BEND:
511                   case ElementType::ACCIDENTAL:
512                   case ElementType::TEXT:
513                   case ElementType::FINGERING:
514                   case ElementType::TEMPO_TEXT:
515                   case ElementType::STAFF_TEXT:
516                   case ElementType::SYSTEM_TEXT:
517                   case ElementType::NOTEHEAD:
518                   case ElementType::TREMOLO:
519                   case ElementType::LAYOUT_BREAK:
520                   case ElementType::MARKER:
521                   case ElementType::STAFF_STATE:
522                   case ElementType::INSTRUMENT_CHANGE:
523                   case ElementType::REHEARSAL_MARK:
524                   case ElementType::JUMP:
525                   case ElementType::REPEAT_MEASURE:
526                   case ElementType::ICON:
527                   case ElementType::NOTE:
528                   case ElementType::CHORD:
529                   case ElementType::SPACER:
530                   case ElementType::SLUR:
531                   case ElementType::BAGPIPE_EMBELLISHMENT:
532                   case ElementType::AMBITUS:
533                   case ElementType::TREMOLOBAR:
534                   case ElementType::FIGURED_BASS:
535                   case ElementType::LYRICS:
536                   case ElementType::STAFFTYPE_CHANGE: {
537                         Element* el = getDropTarget(editData);
538                         if (!el) {
539                               if (!dropCanvas(editData.dropElement)) {
540                                     qDebug("cannot drop %s(%p) to canvas", editData.dropElement->name(), editData.dropElement);
541                                     delete editData.dropElement;
542                                     }
543                               break;
544                               }
545                         _score->addRefresh(el->canvasBoundingRect());
546 
547                         // TODO: HACK ALERT!
548                         if (el->isMeasure() && editData.dropElement->isLayoutBreak()) {
549                               Measure* m = toMeasure(el);
550                               if (m->isMMRest())
551                                     el = m->mmRestLast();
552                               }
553 
554                         Element* dropElement = el->drop(editData);
555                         if (dropElement && dropElement->isInstrumentChange()) {
556                               mscore->currentScoreView()->selectInstrument(toInstrumentChange(dropElement));
557                               }
558                         _score->addRefresh(el->canvasBoundingRect());
559                         if (dropElement) {
560                               if (!_score->noteEntryMode())
561                                     _score->select(dropElement, SelectType::SINGLE, 0);
562                               _score->addRefresh(dropElement->canvasBoundingRect());
563                               }
564                         event->acceptProposedAction();
565                         }
566                         break;
567                   default:
568                         delete editData.dropElement;
569                         break;
570                   }
571             editData.dropElement = 0;
572             setDropTarget(0); // this also resets dropRectangle and dropAnchor
573             score()->endCmd();
574             // update input cursor position (must be done after layout)
575             if (noteEntryMode())
576                   moveCursor();
577             if (triggerSpannerDropApplyTour)
578                   TourHandler::startTour("spanner-drop-apply");
579             return;
580             }
581 
582       editData.dropElement = 0;
583       const QMimeData* md = event->mimeData();
584       QByteArray dta;
585       ElementType etype;
586       if (md->hasFormat(mimeSymbolListFormat)) {
587             etype = ElementType::ELEMENT_LIST;
588             dta = md->data(mimeSymbolListFormat);
589             }
590       else if (md->hasFormat(mimeStaffListFormat)) {
591             etype = ElementType::STAFF_LIST;
592             dta = md->data(mimeStaffListFormat);
593             }
594       else {
595             qDebug("cannot drop this object: unknown mime type");
596             QStringList sl = md->formats();
597             for (const QString& s : qAsConst(sl))
598                   qDebug("  %s", qPrintable(s));
599             _score->update();
600             return;
601             }
602 
603 qDebug("drop <%s>", dta.data());
604 
605       Element* el = elementAt(pos);
606       if (el == 0 || el->type() != ElementType::MEASURE) {
607             setDropTarget(0);
608             return;
609             }
610       Measure* measure = (Measure*) el;
611 
612       if (etype == ElementType::ELEMENT_LIST) {
613             qDebug("drop element list");
614             }
615       else if (etype == ElementType::MEASURE_LIST || etype == ElementType::STAFF_LIST) {
616             _score->startCmd();
617             XmlReader xml(dta);
618             System* s = measure->system();
619             int idx   = s->y2staff(pos.y());
620             if (idx != -1) {
621                   Segment* seg = measure->first();
622                   // assume there is always a ChordRest segment
623                   while (!seg->isChordRestType())
624                         seg = seg->next();
625                   score()->pasteStaff(xml, seg, idx);
626                   }
627             event->acceptProposedAction();
628             _score->endCmd();
629             }
630       setDropTarget(0); // this also resets dropRectangle and dropAnchor
631       }
632 
633 //---------------------------------------------------------
634 //   dragLeaveEvent
635 //---------------------------------------------------------
636 
dragLeaveEvent(QDragLeaveEvent *)637 void ScoreView::dragLeaveEvent(QDragLeaveEvent*)
638       {
639       if (editData.dropElement) {
640             _score->setUpdateAll();
641             delete editData.dropElement;
642             editData.dropElement = 0;
643             _score->update();
644             }
645       setDropTarget(0);
646       }
647 
648 //---------------------------------------------------------
649 //   dropCanvas
650 //---------------------------------------------------------
651 
dropCanvas(Element * e)652 bool ScoreView::dropCanvas(Element* e)
653       {
654       if (e->isIcon()) {
655             switch (toIcon(e)->iconType()) {
656                   case IconType::VFRAME:
657                         score()->insertMeasure(ElementType::VBOX, 0);
658                         break;
659                   case IconType::HFRAME:
660                         score()->insertMeasure(ElementType::HBOX, 0);
661                         break;
662                   case IconType::TFRAME:
663                         score()->insertMeasure(ElementType::TBOX, 0);
664                         break;
665                   case IconType::FFRAME:
666                         score()->insertMeasure(ElementType::FBOX, 0);
667                         break;
668                   case IconType::MEASURE:
669                         score()->insertMeasure(ElementType::MEASURE, 0);
670                         break;
671                   default:
672                         return false;
673                   }
674             delete e;
675             return true;
676             }
677       return false;
678       }
679 
680 } // namespace Ms
681