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() { 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); }
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); }
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); }
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); }
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(); }