Esempio n. 1
0
void ScoreAccessibility::updateAccessibilityInfo()
      {
      ScoreView* w = static_cast<MuseScore*>(mainWindow)->currentScoreView();
      if (!w) return;

      currentInfoChanged();

      //getInspector->isAncestorOf is used so that inspector and search dialog don't loose focus
      //when this method is called
      //TODO: create a class to manage focus and replace this massive if
      if ( (qApp->focusWidget() != w) &&
           !mscore->inspector()->isAncestorOf(qApp->focusWidget()) &&
           !(mscore->searchDialog() && mscore->searchDialog()->isAncestorOf(qApp->focusWidget())) &&
           !(mscore->getSelectionWindow() && mscore->getSelectionWindow()->isAncestorOf(qApp->focusWidget())) &&
           !(mscore->getPlayPanel() && mscore->getPlayPanel()->isAncestorOf(qApp->focusWidget())) &&
           !(mscore->getSynthControl() && mscore->getSynthControl()->isAncestorOf(qApp->focusWidget())) &&
           !(mscore->getMixer() && mscore->getMixer()->isAncestorOf(qApp->focusWidget())) &&
           !(mscore->searchDialog() && mscore->searchDialog()->isAncestorOf(qApp->focusWidget())) &&
           !(mscore->getDrumrollEditor() && mscore->getDrumrollEditor()->isAncestorOf(qApp->focusWidget())) &&
           !(mscore->getPianorollEditor() && mscore->getPianorollEditor()->isAncestorOf(qApp->focusWidget()))) {
            mscore->activateWindow();
            w->setFocus();
            }
      QObject* obj = static_cast<QObject*>(w);
      QAccessibleValueChangeEvent ev(obj, w->score()->accessibleInfo());
      QAccessible::updateAccessibility(&ev);
      }
Esempio n. 2
0
QSplitter* ScoreTab::viewSplitter(int n) const
{
    TabScoreView* tsv = static_cast<TabScoreView*>(tab->tabData(n).value<void*>());
    if (tsv == 0) {
        // qDebug("ScoreTab::viewSplitter %d is zero", n);
        return 0;
    }
    Score* score = tsv->score;
    if (tsv->part) {
        QList<Excerpt*>& excerpts = score->excerpts();
        if (!excerpts.isEmpty() && ((tsv->part - 1) < excerpts.size()))
            score = excerpts.at(tsv->part - 1)->partScore();
    }

    int nn = stack->count();
    for (int i = 0; i < nn; ++i) {
        QSplitter* sp = static_cast<QSplitter*>(stack->widget(i));
        if (sp->count() == 0)
            return 0;
        ScoreView* v = static_cast<ScoreView*>(sp->widget(0));
        if (v->score() == score)
            return sp;
    }
    return 0;
}
void ScoreAccessibility::updateAccessibilityInfo()
      {
      currentInfoChanged();
      ScoreView* w = static_cast<MuseScore*>(mainWindow)->currentScoreView();

      //getInspector->isAncestorOf is used so that inspector doesn't lose focus
      //when this method is called
      if ( (qApp->focusWidget() != w) && !mscore->getInspector()->isAncestorOf(qApp->focusWidget())) {
            w->setFocus();
            }
      QObject* obj = static_cast<QObject*>(w);
      QAccessibleValueChangeEvent ev(obj, w->score()->accessibleInfo());
      QAccessible::updateAccessibility(&ev);
      }
Esempio n. 4
0
void MuseScore::showContextHelp()
      {
      QString s;
      QWidget* w = qApp->widgetAt(globalX, globalY);
      while (w) {
            if (!w->statusTip().isEmpty()) {
                  s = w->statusTip();
                  break;
                  }
            w = w->parentWidget();
            }
      if (w && s == "scoreview") {
            ScoreView* canvas = static_cast<ScoreView*>(w);
            QPoint pt = w->mapFromGlobal(QPoint(globalX, globalY));
            QPointF p = canvas->toLogical(pt);
            Element* e = canvas->elementNear(p);
            if (e)
                  s = QString("element:%1").arg(e->name());
            }
      showHelp(s);
      }
Esempio n. 5
0
void ScoreTab::setCurrent(int n)
{
    if (n == -1) {
        clearTab2();
        tab2->setVisible(false);
        // clearTab2();      //??
        emit currentScoreViewChanged(0);
        return;
    }
    TabScoreView* tsv = static_cast<TabScoreView*>(tab->tabData(n).value<void*>());
    QSplitter* vs = viewSplitter(n);

    ScoreView* v;
    if (!vs) {
        vs = new QSplitter;
        v  = new ScoreView;
        tab2->blockSignals(true);
        tab2->setCurrentIndex(0);
        tab2->blockSignals(false);
        vs->addWidget(v);
        v->setScore(scoreList->value(n));
        stack->addWidget(vs);
    }
    else {
        v = static_cast<ScoreView*>(vs->widget(0));
    }
#ifdef OMR
    if (v) {
        Score* score = v->score();
        if (score->showOmr() && score->omr()) {
            if (vs->count() < 2) {
                Omr* omr    = score->omr();
                OmrView* sv = omr->newOmrView(v);
                v->setOmrView(sv);
                vs->addWidget(sv);
                connect(v, SIGNAL(scaleChanged(double)), sv, SLOT(setScale(double)));
                connect(v, SIGNAL(offsetChanged(double,double)), sv, SLOT(setOffset(double,double)));
                const QTransform _matrix = v->matrix();
                double _spatium = score->spatium();
                double scale = _matrix.m11() * _spatium;
                sv->setScale(scale);
                sv->setOffset(_matrix.dx(), _matrix.dy());
                QList<int> sizes;
                sizes << 100 << 100;
                vs->setSizes(sizes);
            }
        }
        else {
            if (vs->count() > 1) {
                QWidget* w = vs->widget(1);
                delete w;
            }
        }
    }
#endif
    stack->setCurrentWidget(vs);
    clearTab2();
    if (v) {
        Score* score = v->score();
        if (score->parentScore())
            score = score->parentScore();
        QList<Excerpt*>& excerpts = score->excerpts();
        if (!excerpts.isEmpty()) {
            tab2->blockSignals(true);
            tab2->addTab(score->name().replace("&","&&"));
            foreach(const Excerpt* excerpt, excerpts) {
                tab2->addTab(excerpt->partScore()->name().replace("&","&&"));
            }
            tab2->setCurrentIndex(tsv->part);
            tab2->blockSignals(false);
            tab2->setVisible(true);
        }
Esempio n. 6
0
void ScoreAccessibility::currentInfoChanged()
      {
      clearAccessibilityInfo();
      statusBarLabel  = new QLabel(mainWindow->statusBar());
      ScoreView* scoreView =  static_cast<MuseScore*>(mainWindow)->currentScoreView();
      Score* score = scoreView->score();
      if (score->selection().isSingle()) {
            Element* e = score->selection().element();
            if (!e) {
                  return;
                  }
            Element* el = e->isSpannerSegment() ? static_cast<SpannerSegment*>(e)->spanner() : e;
            QString barsAndBeats = "";
            std::pair<int, float> bar_beat;
            if (el->isSpanner()){
                  Spanner* s = static_cast<Spanner*>(el);
                  bar_beat = barbeat(s->startSegment());
                  barsAndBeats += tr("Start Measure: %1; Start Beat: %2").arg(QString::number(bar_beat.first)).arg(QString::number(bar_beat.second));
                  Segment* seg = s->endSegment();
                  if(!seg)
                        seg = score->lastSegment()->prev1MM(Segment::Type::ChordRest);

                  if (seg->tick() != score->lastSegment()->prev1MM(Segment::Type::ChordRest)->tick() &&
                      s->type() != Element::Type::SLUR                                               &&
                      s->type() != Element::Type::TIE                                                )
                        seg = seg->prev1MM(Segment::Type::ChordRest);

                  bar_beat = barbeat(seg);
                  barsAndBeats += "; " + tr("End Measure: %1; End Beat: %2").arg(QString::number(bar_beat.first)).arg(QString::number(bar_beat.second));
                  }
            else {
                  std::pair<int, float>bar_beat = barbeat(el);
                  if (bar_beat.first) {
                        barsAndBeats += " " + tr("Measure: %1").arg(QString::number(bar_beat.first));
                        if (bar_beat.second)
                              barsAndBeats += "; " + tr("Beat: %1").arg(QString::number(bar_beat.second));
                        }
                  }

            QString rez = e->accessibleInfo();
            if (!barsAndBeats.isEmpty())
                  rez += "; " + barsAndBeats;

            QString staff = "";
            if (e->staffIdx() + 1) {
                  staff = tr("Staff %1").arg(QString::number(e->staffIdx() + 1));
                  rez = QString("%1; %2").arg(rez).arg(staff);
                  }

            statusBarLabel->setText(rez);
            QString screenReaderRez = QString("%1%2 %3 %4").arg(e->screenReaderInfo()).arg(barsAndBeats).arg(staff).arg(e->accessibleExtraInfo());
            score->setAccessibleInfo(screenReaderRez);
            }
      else if (score->selection().isRange()) {
            QString barsAndBeats = "";
            std::pair<int, float> bar_beat;

            bar_beat = barbeat(score->selection().startSegment());
            barsAndBeats += " " + tr("Start Measure: %1; Start Beat: %2").arg(QString::number(bar_beat.first)).arg(QString::number(bar_beat.second));
            Segment* endSegment = score->selection().endSegment();

            if (!endSegment)
                  endSegment = score->lastSegment();
            else
                  endSegment = endSegment->prev1MM();

            bar_beat = barbeat(endSegment);
            barsAndBeats += " " + tr("End Measure: %1; End Beat: %2").arg(QString::number(bar_beat.first)).arg(QString::number(bar_beat.second));
            statusBarLabel->setText(tr("Range Selection") + barsAndBeats);
            score->setAccessibleInfo(tr("Range Selection") + barsAndBeats);
            }
      else if (score->selection().isList()) {
            statusBarLabel->setText(tr("List Selection"));
            score->setAccessibleInfo(tr("List Selection"));
            }
      mainWindow->statusBar()->addWidget(statusBarLabel);
      }
Esempio n. 7
0
void Palette::mouseDoubleClickEvent(QMouseEvent* ev)
      {
      int i = idx(ev->pos());
      if (i == -1)
            return;
      Score* score   = mscore->currentScore();
      if (score == 0)
            return;
      const Selection& sel = score->selection();

      if (sel.state() == SEL_NONE)
            return;

      Element* element = 0;
      if (i < size() &&  cells[i])
            element = cells[i]->element;
      if (element == 0)
            return;
      ScoreView* viewer = mscore->currentScoreView();


      if (viewer->mscoreState() != STATE_EDIT
         && viewer->mscoreState() != STATE_LYRICS_EDIT
         && viewer->mscoreState() != STATE_HARMONY_FIGBASS_EDIT
         && viewer->mscoreState() != STATE_TEXT_EDIT) { // Already in startCmd in this case
            score->startCmd();
            }
      if (sel.state() == SEL_LIST) {
            foreach(Element* e, sel.elements())
                  applyDrop(score, viewer, e, element);
            }
      else if (sel.state() == SEL_RANGE) {
            // TODO: check for other element types:
            if (element->type() == Element::BAR_LINE) {
                  // TODO: apply to multiple measures
                  Measure* m = sel.startSegment()->measure();
                  QRectF r = m->staffabbox(sel.staffStart());
                  QPointF pt(r.x() + r.width() * .5, r.y() + r.height() * .5);
                  applyDrop(score, viewer, m, element, pt);
                  }
            else {
                  int track1 = sel.staffStart() * VOICES;
                  int track2 = sel.staffEnd() * VOICES;
                  Segment* startSegment = sel.startSegment();
                  Segment* endSegment = sel.endSegment(); //keep it, it could change during the loop
                  for (Segment* s = startSegment; s && s != endSegment; s = s->next1()) {
                        for (int track = track1; track < track2; ++track) {
                              Element* e = s->element(track);
                              if (e == 0)
                                    continue;
                              if (e->type() == Element::CHORD) {
                                    Chord* chord = static_cast<Chord*>(e);
                                    foreach(Note* n, chord->notes())
                                          applyDrop(score, viewer, n, element);
                                    }
                              else {
                                    // do not apply articulation to barline in a range selection
                                    if(e->type() != Element::BAR_LINE || element->type() != Element::ARTICULATION)
                                          applyDrop(score, viewer, e, element);
                                    }
                              }
                        }
                  }
            }
      else
            qDebug("unknown selection state\n");
      if (viewer->mscoreState() != STATE_EDIT
         && viewer->mscoreState() != STATE_LYRICS_EDIT
         && viewer->mscoreState() != STATE_HARMONY_FIGBASS_EDIT
         && viewer->mscoreState() != STATE_TEXT_EDIT) { //Already in startCmd mode in this case
            score->endCmd();
            }
      mscore->endCmd();
      }
Esempio n. 8
0
void MuseScore::editInstrList()
      {
      if (cs == 0)
            return;
      if (!instrList)
            instrList = new InstrumentsDialog(this);
      else if (instrList->isVisible()) {
            instrList->done(0);
            return;
            }
      instrList->init();
      MasterScore* masterScore = cs->masterScore();
      instrList->genPartList(masterScore);
      masterScore->startCmd();
      masterScore->deselectAll();
      int rv = instrList->exec();

      if (rv == 0) {
            masterScore->endCmd();
            return;
            }
      ScoreView* csv = currentScoreView();
      if (csv && csv->noteEntryMode()) {
		csv->cmd(getAction("escape"));
            qApp->processEvents();
            updateInputState(csv->score());
            }
      masterScore->inputState().setTrack(-1);

      // keep the keylist of the first pitched staff to apply it to new ones
      KeyList tmpKeymap;
      Staff* firstStaff = 0;
      for (Staff* s : masterScore->staves()) {
            KeyList* km = s->keyList();
            if (!s->isDrumStaff(Fraction(0,1))) {     // TODO
                  tmpKeymap.insert(km->begin(), km->end());
                  firstStaff = s;
                  break;
                  }
            }
      Key normalizedC = Key::C;
      // normalize the keyevents to concert pitch if necessary
      if (firstStaff && !masterScore->styleB(Sid::concertPitch) && firstStaff->part()->instrument()->transpose().chromatic ) {
            int interval = firstStaff->part()->instrument()->transpose().chromatic;
            normalizedC = transposeKey(normalizedC, interval);
            for (auto i = tmpKeymap.begin(); i != tmpKeymap.end(); ++i) {
                  int tick = i->first;
                  Key oKey = i->second.key();
                  tmpKeymap[tick].setKey(transposeKey(oKey, interval));
                  }
            }
      // create initial keyevent for transposing instrument if necessary
      auto i = tmpKeymap.begin();
      if (i == tmpKeymap.end() || i->first != 0)
            tmpKeymap[0].setKey(normalizedC);

      //
      // process modified partitur list
      //
      QTreeWidget* pl = instrList->partiturList();
      Part* part   = 0;
      int staffIdx = 0;

      QTreeWidgetItem* item = 0;
      for (int idx = 0; (item = pl->topLevelItem(idx)); ++idx) {
            PartListItem* pli = static_cast<PartListItem*>(item);
            // check if the part contains any remaining staves
            // mark to remove part if not
            QTreeWidgetItem* ci = 0;
            int staves = 0;
            for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) {
                  StaffListItem* sli = static_cast<StaffListItem*>(ci);
                  if (sli->op() != ListItemOp::I_DELETE)
                        ++staves;
                  }
            if (staves == 0)
                  pli->op = ListItemOp::I_DELETE;
            }

      item = 0;
      for (int idx = 0; (item = pl->topLevelItem(idx)); ++idx) {
            int rstaff = 0;
            PartListItem* pli = static_cast<PartListItem*>(item);
            if (pli->op == ListItemOp::I_DELETE)
                  masterScore->cmdRemovePart(pli->part);
            else if (pli->op == ListItemOp::ADD) {
                  const InstrumentTemplate* t = ((PartListItem*)item)->it;
                  part = new Part(masterScore);
                  part->initFromInstrTemplate(t);
                  masterScore->undo(new InsertPart(part, staffIdx));

                  pli->part = part;
                  QList<Staff*> linked;
                  for (int cidx = 0; pli->child(cidx); ++cidx) {
                        StaffListItem* sli = static_cast<StaffListItem*>(pli->child(cidx));
                        Staff* staff       = new Staff(masterScore);
                        staff->setPart(part);
                        sli->setStaff(staff);

                        staff->init(t, sli->staffType(), cidx);
                        staff->setDefaultClefType(sli->defaultClefType());
                        if (staffIdx > 0)
                              staff->setBarLineSpan(masterScore->staff(staffIdx - 1)->barLineSpan());

                        masterScore->undoInsertStaff(staff, cidx);
                        ++staffIdx;

                        Staff* linkedStaff = part->staves()->front();
                        if (sli->linked() && linkedStaff != staff) {
                              Excerpt::cloneStaff(linkedStaff, staff);
                              linked.append(staff);
                              }
                        }

                  //insert keysigs
                  int sidx = masterScore->staffIdx(part);
                  int eidx = sidx + part->nstaves();
                  if (firstStaff)
                        masterScore->adjustKeySigs(sidx, eidx, tmpKeymap);
                  }
            else {
                  part = pli->part;
                  if (part->show() != pli->visible())
                        part->undoChangeProperty(Pid::VISIBLE, pli->visible());
                  for (int cidx = 0; pli->child(cidx); ++cidx) {
                        StaffListItem* sli = static_cast<StaffListItem*>(pli->child(cidx));
                        if (sli->op() == ListItemOp::I_DELETE) {
                              Staff* staff = sli->staff();
                              int sidx = staff->idx();
                              masterScore->cmdRemoveStaff(sidx);
                              }
                        else if (sli->op() == ListItemOp::ADD) {
                              Staff* staff = new Staff(masterScore);
                              staff->setPart(part);
                              staff->initFromStaffType(sli->staffType());
                              sli->setStaff(staff);
                              staff->setDefaultClefType(sli->defaultClefType());
                              if (staffIdx > 0)
                                    staff->setBarLineSpan(masterScore->staff(staffIdx - 1)->barLineSpan());

                              KeySigEvent ke;
                              if (part->staves()->empty())
                                    ke.setKey(Key::C);
                              else
                                    ke = part->staff(0)->keySigEvent(Fraction(0,1));

                              staff->setKey(Fraction(0,1), ke);

                              Staff* linkedStaff = 0;
                              if (sli->linked()) {
                                    if (rstaff > 0)
                                          linkedStaff = part->staves()->front();
                                    else {
                                          for (Staff* st : *part->staves()) {
                                                if (st != staff) {
                                                      linkedStaff = st;
                                                      break;
                                                      }
                                                }
                                          }
                                    }
                              if (linkedStaff) {
                                    // do not create a link if linkedStaff will be removed,
                                    for (int k = 0; pli->child(k); ++k) {
                                          StaffListItem* li = static_cast<StaffListItem*>(pli->child(k));
                                          if (li->op() == ListItemOp::I_DELETE && li->staff() == linkedStaff) {
                                                linkedStaff = 0;
                                                break;
                                                }
                                          }
                                    }
                              masterScore->undoInsertStaff(staff, rstaff, linkedStaff == 0);
                              if (linkedStaff)
                                    Excerpt::cloneStaff(linkedStaff, staff);
                              else {
                                    if (firstStaff)
                                          masterScore->adjustKeySigs(staffIdx, staffIdx+1, tmpKeymap);
                                    }
                              ++staffIdx;
                              ++rstaff;
                              }
                        else if (sli->op() == ListItemOp::UPDATE) {
                              // check changes in staff type
                              Staff* staff = sli->staff();
                              const StaffType* stfType = sli->staffType();

                              // use selected staff type
                              if (stfType->name() != staff->staffType(Fraction(0,1))->name())
                                    masterScore->undo(new ChangeStaffType(staff, *stfType));
                              }
                        else {
                              ++staffIdx;
                              ++rstaff;
                              }
                        }
                  }
            }

      //
      //    sort staves
      //
      QList<Staff*> dst;
      for (int idx = 0; idx < pl->topLevelItemCount(); ++idx) {
            PartListItem* pli = (PartListItem*)pl->topLevelItem(idx);
            if (pli->op == ListItemOp::I_DELETE)
                  continue;
            QTreeWidgetItem* ci = 0;
            for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) {
                  StaffListItem* sli = (StaffListItem*) ci;
                  if (sli->op() == ListItemOp::I_DELETE)
                        continue;
                  dst.push_back(sli->staff());
                  }
            }

      QList<int> dl;
      int idx2 = 0;
      bool sort = false;
      for (Staff* staff : dst) {
            int idx = masterScore->staves().indexOf(staff);
            if (idx == -1)
                  qDebug("staff in dialog(%p) not found in score", staff);
            else
                  dl.push_back(idx);
            if (idx != idx2)
                  sort = true;
            ++idx2;
            }

      if (sort)
            masterScore->undo(new SortStaves(masterScore, dl));

      //
      // check for valid barLineSpan and bracketSpan
      // in all staves
      //
      for (Score* s : masterScore->scoreList()) {
            int n = s->nstaves();
            int curSpan = 0;
            for (int j = 0; j < n; ++j) {
                  Staff* staff = s->staff(j);
                  int span = staff->barLineSpan();
                  int setSpan = -1;

                  // determine if we need to update barline span
                  if (curSpan == 0) {
                        // no current span; this staff must start a new one
                        if (span == 0) {
                              // no span; this staff must have been within a span
                              // update it to a span of 1
                              setSpan = j;
                              }
                        else if (span > (n - j)) {
                              // span too big; staves must have been removed
                              // reduce span to last staff
                              setSpan = n - j;
                              }
                        else if (span > 1 && staff->barLineTo() > 0) {
                              // TODO: check if span is still valid
                              // (true if the last staff is the same as it was before this edit)
                              // the code here fixes https://musescore.org/en/node/41786
                              // but by forcing an update,
                              // we lose custom modifications to staff barLineTo
                              // at least this happens only for span > 1, and not for Mensurstrich (barLineTo<=0)
                              setSpan = span;   // force update to pick up new barLineTo value
                              }
                        else {
                              // this staff starts a span
                              curSpan = span;
                              }
                        }
                  else if (span && staff->barLineTo() > 0) {
                        // within a current span; staff must have span of 0
                        // except for Mensurstrich (barLineTo<=0)
                        // for consistency with Barline::endEdit,
                        // don't special case 1-line staves
//TODO                        s->undoChangeBarLineSpan(staff, 0, 0, (staff->lines() - 1) * 2);
                        }

                  // update barline span if necessary
                  if (setSpan > 0) {
                        // this staff starts a span
                        curSpan = setSpan;
                        // calculate spanFrom and spanTo values
//                        int spanFrom = staff->lines() == 1 ? BARLINE_SPAN_1LINESTAFF_FROM : 0;
//                        int linesTo = masterScore->staff(i + setSpan - 1)->lines();
//                        int spanTo = linesTo == 1 ? BARLINE_SPAN_1LINESTAFF_TO : (linesTo - 1) * 2;
//TODO                         s->undoChangeBarLineSpan(staff, setSpan, spanFrom, spanTo);
                        }

                  // count off one from barline span
                  --curSpan;

                  // update brackets
                  for (BracketItem* bi : staff->brackets()) {
                        if ((bi->bracketSpan() > (n - j)))
                              bi->undoChangeProperty(Pid::BRACKET_SPAN, n - j);
                        }
                  }
            }

      //
      // there should be at least one measure
      //
      if (masterScore->measures()->size() == 0)
            masterScore->insertMeasure(ElementType::MEASURE, 0, false);

      const QList<Excerpt*> excerpts(masterScore->excerpts()); // excerpts list may change in the loop below
      for (Excerpt* excerpt : excerpts) {
            QList<Staff*> sl       = excerpt->partScore()->staves();
            QMultiMap<int, int> tr = excerpt->tracks();
            if (sl.size() == 0)
                  masterScore->undo(new RemoveExcerpt(excerpt));
            else {
                  for (Staff* s : sl) {
                        const LinkedElements* sll = s->links();
                        for (auto le : *sll) {
                              Staff* ss = toStaff(le);
                              if (ss->primaryStaff()) {
                                    for (int j = s->idx() * VOICES; j < (s->idx() + 1) * VOICES; j++) {
                                          int strack = tr.key(j, -1);
                                          if (strack != -1 && ((strack & ~3) == ss->idx()))
                                                break;
                                          else if (strack != -1)
                                                tr.insert(ss->idx() + strack % VOICES, tr.value(strack, -1));
                                          }
                                    }
                              }
                        }
                  }
            }

      masterScore->setLayoutAll();
      masterScore->endCmd();
      masterScore->rebuildAndUpdateExpressive(MuseScore::synthesizer("Fluid"));
      seq->initInstruments();
      }