diff --git a/audio/midi/fluid/sfont.cpp b/audio/midi/fluid/sfont.cpp index 6c04279268ea8..6bbc08ae1b45e 100644 --- a/audio/midi/fluid/sfont.cpp +++ b/audio/midi/fluid/sfont.cpp @@ -693,9 +693,10 @@ void Sample::load() // // now add some extra sanity checks from the SF2 spec (biased so they work with unsigned int); // just a warning, they probably work with Fluid, possibly with audible artefacts though... - if (!(start + 7 < loopstart) || !(loopstart + 31 < loopend) || !(loopend + 7 < end)) - qDebug("SoundFont(%s) Sample(%s) start(%u) startloop(%u) endloop(%u) end(%u) smaller than SoundFont 2.04 spec chapter 7.10 recommendation", - qPrintable(sf->get_name()), name, start, loopstart, loopend, end); + if (!(start + 7 < loopstart) || !(loopstart + 31 < loopend) || !(loopend + 7 < end)) { + // qDebug("SoundFont(%s) Sample(%s) start(%u) startloop(%u) endloop(%u) end(%u) smaller than SoundFont 2.04 spec chapter 7.10 recommendation", + // qPrintable(sf->get_name()), name, start, loopstart, loopend, end); + } // this used to cause a crash if (!data) { diff --git a/config.cmake b/config.cmake index 0d4a0494cb013..b57c55cda6177 100644 --- a/config.cmake +++ b/config.cmake @@ -21,7 +21,7 @@ SET(MUSESCORE_NAME "MuseScore") SET(MUSESCORE_VERSION_MAJOR "3") SET(MUSESCORE_VERSION_MINOR "7") -SET(MUSESCORE_VERSION_PATCH "0") +SET(MUSESCORE_VERSION_PATCH "1") SET(MUSESCORE_VERSION_LABEL "") message(STATUS "MUSESCORE_BUILD_CONFIG ${MUSESCORE_BUILD_CONFIG}") diff --git a/global/settings/types/preferencekeys.h b/global/settings/types/preferencekeys.h index dd77d2f40aef5..5ac4aed6ecf51 100644 --- a/global/settings/types/preferencekeys.h +++ b/global/settings/types/preferencekeys.h @@ -59,9 +59,6 @@ #define PREF_APP_TELEMETRY_ALLOWED "application/telemetry/allowed" #define PREF_APP_BACKUP_GENERATE_BACKUP "application/backup/generateBackup" #define PREF_APP_BACKUP_SUBFOLDER "application/backup/subfolder" -#define PREF_APP_SHOW_PROGRESS_LAYOUT "application/show/progressBar/layout" -#define PREF_APP_SHOW_PROGRESS_SAVE "application/show/progressBar/save" -#define PREF_APP_SHOW_PROGRESS_AUTOSAVE "application/show/progressBar/autosave" #define PREF_EXPORT_AUDIO_NORMALIZE "export/audio/normalize" #define PREF_EXPORT_AUDIO_SAMPLERATE "export/audio/sampleRate" #define PREF_EXPORT_AUDIO_PCMRATE "export/audio/PCMRate" diff --git a/libmscore/check.cpp b/libmscore/check.cpp index 3061dd9b7dd25..915e4f3df1c9f 100644 --- a/libmscore/check.cpp +++ b/libmscore/check.cpp @@ -318,9 +318,9 @@ bool Score::checkClefs() void Measure::fillGap(const Fraction& pos, const Fraction& len, int track, const Fraction& stretch, bool useGapRests) { - qDebug().nospace().noquote() - << "measure " << tick().print() << " pos " << pos.print() << ", " - << "len " << len.print() << " stretch " << stretch.print() << " track " << track; + // qDebug().nospace().noquote() + // << "measure " << tick().print() << " pos " << pos.print() << ", " + // << "len " << len.print() << " stretch " << stretch.print() << " track " << track; TDuration d; d.setVal(len.ticks()); if (d.isValid()) { @@ -363,17 +363,17 @@ void Measure::checkMeasure(int staffIdx, bool useGapRests) currentPos = seg->rtick() * stretch; if (currentPos < expectedPos) { - qDebug().nospace().noquote() - << "in measure overrun" << tick().print() - << "at " << (currentPos/stretch).ticks() << "-" << (expectedPos/stretch).ticks() - << " track " << track; + // qDebug().nospace().noquote() + // << "in measure overrun" << tick().print() + // << "at " << (currentPos/stretch).ticks() << "-" << (expectedPos/stretch).ticks() + // << " track " << track; break; } else if (currentPos > expectedPos) { - qDebug().nospace().noquote() - << "in measure underrun " << tick().print() - << " at " << (currentPos/stretch).ticks() << "-" << (expectedPos/stretch).ticks() - << " track " << track; + // qDebug().nospace().noquote() + // << "in measure underrun " << tick().print() + // << " at " << (currentPos/stretch).ticks() << "-" << (expectedPos/stretch).ticks() + // << " track " << track; fillGap(expectedPos, currentPos - expectedPos, track, stretch); } diff --git a/libmscore/cmd.cpp b/libmscore/cmd.cpp index 3e6b751f55c74..c5bca886d6c98 100644 --- a/libmscore/cmd.cpp +++ b/libmscore/cmd.cpp @@ -130,6 +130,8 @@ void CmdState::setTick(TickType tt, const Fraction& t) _startTick = t; else if (tt == TickType::EndTick) _endTick = t; + else + _startTick = _endTick = t; setUpdateMode(UpdateMode::Layout); } @@ -300,10 +302,14 @@ void Score::endCmd(bool rollback) void CmdState::dump() { - qDebug("CmdState: mode %d %d-%d", int(_updateMode), _startTick.ticks(), _endTick.ticks()); + qDebug().noquote().nospace() + << "CmdState: mode " << int(_updateMode) << " " << _startTick.print() << "-" << _endTick.print() << " " + << (_el ? _el->name() : "no element") << " " + << (_el ? _el->tick().print() : "") << " " + << "mbase: " << (_mb ? _mb->index() : 0) + ; // bool _excerptsChanged { false }; // bool _instrumentsChanged { false }; - } #endif @@ -320,8 +326,8 @@ void Score::update(bool resetCmdState) CmdState& cs = ms->cmdState(); Fraction layoutStart = cs.startTick(); Fraction layoutEnd = cs.endTick(); - - if (auto singleElement = cs.element()) { + const auto singleElement = cs.element(); + if (singleElement) { if (singleElement->isFingering() || singleElement->isArticulation()) { layoutEntirePage = true; diff --git a/libmscore/layout.cpp b/libmscore/layout.cpp index 1598d433cc48f..e13ffd522fd60 100644 --- a/libmscore/layout.cpp +++ b/libmscore/layout.cpp @@ -2248,7 +2248,7 @@ void LayoutContext::layoutArticAndFingeringOnCrossStaffBeams(System* system) void LayoutContext::layoutPage(Page* page, qreal restHeight, qreal footerPadding) { if (restHeight < 0.0) { - qDebug("restHeight < 0.0: %f\n", restHeight); + // qDebug("restHeight < 0.0: %f\n", restHeight); restHeight = 0; } @@ -5704,27 +5704,11 @@ void LayoutContext::layout() { MeasureBase* lmb; - QProgressDialog progress; - const bool layoutAll = (startTick <= Fraction(0,1) && (endTick < Fraction(0,1) || endTick >= score->last()->endTick())); - - const bool showProgress = (MScore::showProgressBarForLayout && layoutAll) || (MScore::showProgressBarForPartialLayout); - if (showProgress) { - const int totalMeasures = score->measures() ? score->measures()->size() : 0; - QString label; - if (layoutAll) - label = QObject::tr("Performing full layout") + QObject::tr(" for") + ":\n" + score->title() + "…"; - else - label = QObject::tr("Performing partial layout between ") + startTick.print() + " and " + endTick.print() - + QObject::tr(" for") + ":\n" + score->title() + "…"; - - progress.setLabelText(label); - progress.setWindowFlags(Qt::WindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint)); - progress.setRange(0, totalMeasures); - progress.setCancelButton(nullptr); - progress.setWindowModality(Qt::WindowModal); - progress.setValue(0); - progress.setMinimumDuration(0); - } + const int min = 0; + const int max = score->measures() ? score->measures()->size() : 0; + const QString progressFormat = "Layout: %p%"; + int progressValue = min; + emit score->updateProgress(progressFormat, min, min, max); do { getNextPage(); @@ -5732,8 +5716,8 @@ void LayoutContext::layout() if (page && !page->systems().isEmpty()) { lmb = page->systems().back()->measures().back(); - if (showProgress) - progress.setValue(lmb->index()); + progressValue = lmb->index(); + emit score->updateProgress(progressFormat, progressValue, min, max); } else lmb = nullptr; @@ -5750,7 +5734,8 @@ void LayoutContext::layout() } while (curSystem && !(rangeDone && lmb == pageOldMeasure)); // && page->system(0)->measures().back()->tick() > endTick // FIXME: perhaps the first measure was meant? Or last system? - progress.close(); + if (progressValue != max) + emit score->updateProgress(progressFormat, max, min, max); if (!curSystem) { // The end of the score. The remaining systems are not needed... diff --git a/libmscore/mscore.cpp b/libmscore/mscore.cpp index 5dfdf0d464b01..141d599ad2313 100644 --- a/libmscore/mscore.cpp +++ b/libmscore/mscore.cpp @@ -56,11 +56,6 @@ bool MScore::showSystemBoundingRect = false; bool MScore::showCorruptedMeasures = true; bool MScore::useFallbackFont = true; -bool MScore::showProgressBarForLayout = true; -bool MScore::showProgressBarForPartialLayout = false; -bool MScore::showProgressBarForSave = true; -bool MScore::showProgressBarForAutosave = true; - bool MScore::saveTemplateMode = false; bool MScore::noGui = false; diff --git a/libmscore/mscore.h b/libmscore/mscore.h index bf2c7f6f377c0..587296ee5719a 100644 --- a/libmscore/mscore.h +++ b/libmscore/mscore.h @@ -456,11 +456,6 @@ class MScore { static bool debugMode; static bool testMode; - static bool showProgressBarForLayout; - static bool showProgressBarForPartialLayout; - static bool showProgressBarForSave; - static bool showProgressBarForAutosave; - static int division; static int sampleRate; static int mtcType; diff --git a/libmscore/rendermidi.cpp b/libmscore/rendermidi.cpp index b722e3a5ef0a7..d30649f79b524 100644 --- a/libmscore/rendermidi.cpp +++ b/libmscore/rendermidi.cpp @@ -2643,33 +2643,37 @@ void MidiRenderer::renderScore(EventMap* events, const Context& ctx) int currentChunk = 0; QProgressDialog progress; - if (MScore::showProgressBarForLayout) { - const int totalChunks = chunks.size(); - QString label = QObject::tr("Rendering MIDI events") + " " + const int min = 0; + const int max = chunks.size(); + const QString& progressFormat = "Rendering MIDI: %p%"; + emit score->updateProgress(progressFormat, min, min, max); + + // When loading score, allow early termination, but not if in some other ctx + if (ScoreLoad::loading() ) { + QString label = QObject::tr("Loading score") + ": " + QObject::tr("Rendering MIDI events") + " " + QObject::tr("for") + ":\n" + score->title() + "…\n" - + QObject::tr("Safe to cancel early"); + + QObject::tr("Cancelling is safe"); progress.setLabelText(label); progress.setCancelButtonText(QObject::tr("Cancel")); progress.setWindowFlags(Qt::WindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint)); - progress.setRange(0, totalChunks); + progress.setRange(min, max); progress.setWindowModality(Qt::WindowModal); progress.setValue(0); progress.setMinimumDuration(2500); } for (const Chunk& chunk : chunks) { - if (MScore::showProgressBarForLayout) { - progress.setValue(++currentChunk); - // Allow user to prematurely break rendering: + emit score->updateProgress(progressFormat, ++currentChunk, min, max); + progress.setValue(currentChunk); if (progress.wasCanceled()) break; - } renderChunk(chunk, events, ctx); } progress.close(); + emit score->updateProgress(progressFormat, max, min, max); } void MidiRenderer::renderChunk(const Chunk& chunk, EventMap* events, const Context& ctx) diff --git a/libmscore/score.cpp b/libmscore/score.cpp index c1f3191e0f45a..473311fa256b1 100644 --- a/libmscore/score.cpp +++ b/libmscore/score.cpp @@ -4386,7 +4386,7 @@ ChordRest* Score::findCR(Fraction tick, int track) const { Measure* m = tick2measureMM(tick); if (!m) { - qDebug("findCR: no measure for tick %d", tick.ticks()); + // qDebug("findCR: no measure for tick %d", tick.ticks()); return nullptr; } // attach to first rest all spanner when mmRest @@ -4422,7 +4422,7 @@ ChordRest* Score::findCRinStaff(const Fraction& tick, int staffIdx) const Fraction ptick = tick - Fraction::fromTicks(1); Measure* m = tick2measureMM(ptick); if (!m) { - qDebug("findCRinStaff: no measure for tick %d", ptick.ticks()); + // qDebug("findCRinStaff: no measure for tick %d", ptick.ticks()); return 0; } // attach to first rest all spanner when mmRest diff --git a/libmscore/score.h b/libmscore/score.h index 475d477bc374e..991c43367c1a1 100644 --- a/libmscore/score.h +++ b/libmscore/score.h @@ -259,6 +259,7 @@ enum class UpdateMode { enum class TickType { // for explicit cmdState updates StartTick, EndTick, + StartAndEndTick, }; //--------------------------------------------------------- @@ -593,6 +594,7 @@ class Score : public QObject, public ScoreElement { signals: void posChanged(POS, unsigned, bool); void playlistChanged(); + void updateProgress(const QString&, int, int, int); public: Score(); diff --git a/libmscore/scorefile.cpp b/libmscore/scorefile.cpp index 725dc94ce19bb..eb7b8c8a5f528 100644 --- a/libmscore/scorefile.cpp +++ b/libmscore/scorefile.cpp @@ -220,25 +220,12 @@ void Score::writeMovement(XmlWriter& xml, bool selectionOnly) xml.setCurTrack(0); xml.setTrackDiff(-staffStart * VOICES); if (measureStart) { - - // progress bar - const bool showOnSave = (!isAutosaving() && MScore::showProgressBarForSave); - const bool showOnAutosave = (isAutosaving() && MScore::showProgressBarForAutosave); int currentMeasureIdx = 0; - QProgressDialog progress; - if (showOnSave || showOnAutosave) { - int totalMeasuresByStaff = (staffEnd - staffStart) * score()->measures()->size(); - QString label = (showOnAutosave ? QObject::tr("Performing Autosave") - : QObject::tr("Save File")) + ":\n" - + score()->title() + "…"; - progress.setLabelText(label); - progress.setWindowFlags(Qt::WindowFlags(Qt::Dialog | Qt::FramelessWindowHint)); - progress.setCancelButton(nullptr); - progress.setRange(0, totalMeasuresByStaff); - progress.setWindowModality(Qt::WindowModal); - progress.setValue(0); - progress.setMinimumDuration(0); - } + const int totalMeasuresByStaff = (staffEnd - staffStart) * score()->measures()->size(); + const int min = 0; + const int max = totalMeasuresByStaff; + const QString& progressFormat = isAutosaving() ? "Autosave: %p%" : "Saving: %p%"; + emit updateProgress(progressFormat, min, min, max); for (int staffIdx = staffStart; staffIdx < staffEnd; ++staffIdx) { xml.stag(staff(staffIdx), QString("id=\"%1\"").arg(staffIdx + 1 - staffStart)); @@ -259,16 +246,14 @@ void Score::writeMovement(XmlWriter& xml, bool selectionOnly) forceTimeSig = false; } - if (showOnSave || showOnAutosave) - progress.setValue(++currentMeasureIdx); + emit updateProgress(progressFormat, ++currentMeasureIdx, min, max); // Largest consumption of time for file-saving: writeMeasure(xml, m, staffIdx, writeSystemElements, forceTimeSig); } xml.etag(); } - - progress.close(); + emit updateProgress(progressFormat, max, min, max); } xml.setCurTrack(-1); if (isMaster()) { @@ -1191,6 +1176,28 @@ void Score::print(QPainter* painter, int pageNo) painter->restore(); } } + + // PASS #4 Always draw noteheads with information inside them (Solfegge/Pitch) on top of ledger/staff lines + // NOTE: Must be manually applied and not AUTO Notehead with staff properties, otherwise BehindStaff+BehindLedger + // will still be honored + if (MScore::noteheadsBehindStaff || MScore::noteheadsBehindLedger) { + for (const Element* e : elements) { + if (!e->isNote()) + continue; + if (!e->visible()) + continue; + + auto n = toNote(e); + if (!n->onTabStaff() && !n->headSchemeHasAlphaNumerics()) + continue; + + painter->save(); + painter->translate(e->pagePos()); + e->draw(painter); + painter->translate(-e->pagePos()); + painter->restore(); + } + } MScore::pdfPrinting = false; _printing = false; } diff --git a/libmscore/textedit.cpp b/libmscore/textedit.cpp index 307a8fdd42ecc..f16e82ab3f05e 100644 --- a/libmscore/textedit.cpp +++ b/libmscore/textedit.cpp @@ -167,6 +167,10 @@ void TextBase::endEdit(EditData& ed) Filter::Link, }; + // Force updating the cmdState, otherwise a 0/1 starting tick will trigger a full layout + // when the endCmd performs score->update() + score()->cmdState().setTick(TickType::StartAndEndTick, tick()); + if (!emptyUndo && newlyAdded && !undo->current()->hasUnfilteredChildren(filters, this)) { for (Filter f : filters) undo->current()->filterChildren(f, this); @@ -295,6 +299,28 @@ bool TextBase::edit(EditData& ed) //printf("======%x\n", s.isEmpty() ? -1 : s[0].unicode()); switch (ed.key) { + case Qt::Key_QuoteDbl: + case Qt::Key_Apostrophe: + { + // Use CTRL modifier for default vertical quotes (instead of undo stack à la 4.x) + if (ed.control(true)) + break; + + const bool isSingle = (s == QStringLiteral("'")); + bool useCloseQuote = false; + const int row = _cursor->row(); + const int col = _cursor->column(); + + if (col > 0) { + const QString prev { _cursor->extractText(row, col - 1, row, col) }; + const bool spaceBeforeNewInput = (prev == QStringLiteral(" ")); + useCloseQuote = !spaceBeforeNewInput; + } + auto curlyReplacement = isSingle ? QString(useCloseQuote ? QStringLiteral("’") : QStringLiteral("‘")) + : QString(useCloseQuote ? QStringLiteral("”") : QStringLiteral("“")); + s = curlyReplacement; + break; + } case Qt::Key_Z: // happens when the undo stack is empty if (ed.modifiers == Qt::ControlModifier) return true; @@ -441,8 +467,8 @@ bool TextBase::edit(EditData& ed) case Qt::Key_A: if (ctrlPressed) { - _cursor->movePosition(QTextCursor::Start, QTextCursor::MoveMode::MoveAnchor); - _cursor->movePosition(QTextCursor::End, QTextCursor::MoveMode::KeepAnchor); + _cursor->movePosition(QTextCursor::End, QTextCursor::MoveMode::MoveAnchor); + _cursor->movePosition(QTextCursor::Start, QTextCursor::MoveMode::KeepAnchor); s.clear(); } break; diff --git a/libmscore/utils.cpp b/libmscore/utils.cpp index 31f7b0ead925e..8b19dce625833 100644 --- a/libmscore/utils.cpp +++ b/libmscore/utils.cpp @@ -147,7 +147,7 @@ Segment* Score::tick2segment(const Fraction& t, bool first, SegmentType st, bool m = tick2measure(tick); if (m == 0) { - qDebug("no measure for tick %d", tick.ticks()); + // qDebug("no measure for tick %d", tick.ticks()); return 0; } for (Segment* segment = m->first(st); segment;) { diff --git a/mscore/events.cpp b/mscore/events.cpp index 5bd50b9c47d1e..0d0f63dd07bb6 100644 --- a/mscore/events.cpp +++ b/mscore/events.cpp @@ -1101,8 +1101,10 @@ void ScoreView::keyPressEvent(QKeyEvent* ev) mscore->endCmd(); return; } - if (textEdit) + if (textEdit) { mscore->textTools()->updateTools(editData); + adjustCanvasPosition(e, false); + } return; } } diff --git a/mscore/file.cpp b/mscore/file.cpp index 048ec37c4f465..e44f4edf98354 100644 --- a/mscore/file.cpp +++ b/mscore/file.cpp @@ -422,11 +422,17 @@ Score* MuseScore::openScore(const QString& fn, bool switchTab, const bool consid migrator.migrateScore(score); + setCurrentScore(score); + + connect(score, &Score::updateProgress, mscore, &MuseScore::updateProgress); + score->updateCapo(); score->update(); score->styleChanged(); score->doLayout(); + disconnect(score, &Score::updateProgress, mscore, &MuseScore::updateProgress); + if (considerInCurrentSession) { const int tabIdx = appendScore(score); if (switchTab && !isModalDialogOpen()) diff --git a/mscore/mssplashscreen.cpp b/mscore/mssplashscreen.cpp index bf642f5934d4a..a00e7f9815d4a 100644 --- a/mscore/mssplashscreen.cpp +++ b/mscore/mssplashscreen.cpp @@ -32,12 +32,12 @@ const QSize MsSplashScreen::designSize { 720, 405 }; const QRectF MsSplashScreen::designDevBuildIconRect { 25.0, 51.0, 670.0, 38.0 }; const QRectF MsSplashScreen::designDevBuildTextRect { 25.0, 98.0, 670.0, 46.0 }; const QRectF MsSplashScreen::designLogotypeRect { 25.0, 153.0, 670.0, 74.0 }; -const QRectF MsSplashScreen::designMessageTextRect { 25.0, 270.0, 670.0, 56.0 }; +const QRectF MsSplashScreen::designMessageTextRect { 25.0, 270.0, 670.0, 64.0 }; const QRectF MsSplashScreen::designMiscTextRect { 25.0, 326.0, 670.0, 56.0 }; const double MsSplashScreen::gradientDitherAmount { 0.25 }; -const std::tuple MsSplashScreen::stableBuildGradientColors { "#508BFF", "#1043A9" }; +const std::tuple MsSplashScreen::stableBuildGradientColors { "#d6dfea", "#465c83" }; const std::tuple MsSplashScreen::unstableBuildGradientColors { "#3464C1", "#0C2B6B" }; const QColor MsSplashScreen::textColor { 0xCCFFFFFF }; @@ -106,6 +106,25 @@ void MsSplashScreen::drawContents(QPainter* painter) painter->drawText(_messageTextRect, Qt::AlignHCenter | Qt::AlignTop, message()); drawDebugRect(painter, _messageTextRect, 0x80, 0xFF, 0x80); + // Loading progress bar: + if (_progress) { + const int barWidth = 333; + const int barHeight = 27; + const int x = (width() - barWidth) / 2; + const int y = height() - 50; + + // Progress: Background + painter->setPen(Qt::NoPen); + painter->setBrush(QColor(255, 255, 255)); + painter->drawRect(x, y, barWidth, barHeight); + + // Progress: Fill + painter->setBrush(QColor(155, 202, 250)); + double ratio = double(_progress) / double(_maxProgress); + int fillWidth = int(barWidth * ratio); + painter->drawRect(x, y, fillWidth, barHeight); + } + // Miscellaneous text (version information and Web site). painter->drawText(_miscTextRect, Qt::AlignRight | Qt::AlignBottom, _miscText); #if defined(WIN_PORTABLE) diff --git a/mscore/mssplashscreen.h b/mscore/mssplashscreen.h index 99b62b30ffdf7..b3263b7ce7026 100644 --- a/mscore/mssplashscreen.h +++ b/mscore/mssplashscreen.h @@ -17,6 +17,9 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //============================================================================= +#ifndef __MSSPLASHSCREEN_H__ +#define __MSSPLASHSCREEN_H__ + namespace Ms { //--------------------------------------------------------- @@ -46,6 +49,9 @@ class MsSplashScreen : public QSplashScreen { QSvgRenderer _logotypeRenderer; QString _miscText; + int _progress = 0; + int _maxProgress = 0; + const QRectF _devBuildIconRect; const QRectF _devBuildTextRect; QRectF _logotypeRect; @@ -64,6 +70,9 @@ class MsSplashScreen : public QSplashScreen { public: MsSplashScreen(); void drawContents(QPainter* painter) override; + void setProgress(int x) { _progress = x; } + void setProgressMax(int x) { _maxProgress = x; } }; } +#endif diff --git a/mscore/musescore.cpp b/mscore/musescore.cpp index 2fe19cb5d3f09..f8795c54915d0 100644 --- a/mscore/musescore.cpp +++ b/mscore/musescore.cpp @@ -203,6 +203,8 @@ bool enableExperimental = false; QString dataPath; QString iconPath; +MsSplashScreen* sc { nullptr }; + bool converterMode = false; static bool rawDiffMode = false; static bool diffMode = false; @@ -549,10 +551,6 @@ void updateExternalValuesFromPreferences() { MScore::dropColor = preferences.getColor(PREF_UI_SCORE_NOTE_DROPCOLOR); MScore::defaultColor = preferences.getColor(PREF_UI_SCORE_DEFAULTCOLOR); - MScore::showProgressBarForLayout = preferences.getBool(PREF_APP_SHOW_PROGRESS_LAYOUT); - MScore::showProgressBarForSave = preferences.getBool(PREF_APP_SHOW_PROGRESS_SAVE); - MScore::showProgressBarForAutosave = preferences.getBool(PREF_APP_SHOW_PROGRESS_AUTOSAVE); - MScore::palettesHideWhenApplied = preferences.getBool(PREF_UI_APP_AUTOHIDE_PALETTES); MScore::pianoHighlightColor = preferences.getColor(PREF_UI_PIANO_HIGHLIGHTCOLOR); @@ -1488,6 +1486,11 @@ MuseScore::MuseScore() _modeText->setAutoFillBackground(false); _modeText->setObjectName("modeLabel"); + _progressBar = new QProgressBar; + _progressBar->setObjectName("progressBar"); + _progressBar->setMinimumWidth(300/*px*/); + _progressBar->hide(); + hRasterAction = getAction("hraster"); vRasterAction = getAction("vraster"); loopAction = getAction("loop"); @@ -1500,6 +1503,7 @@ MuseScore::MuseScore() _statusBar = new QStatusBar; _statusBar->addPermanentWidget(new QWidget(this), 2); _statusBar->addPermanentWidget(new QWidget(this), 100); + _statusBar->addPermanentWidget(_progressBar, 0); _statusBar->addPermanentWidget(_modeText, 0); searchCombo = new SearchComboBox; @@ -2490,6 +2494,9 @@ MuseScore::~MuseScore() // be deleted before paletteWorkspace. delete paletteWidget; paletteWidget = nullptr; + + delete _progressBar; + _progressBar = nullptr; } //--------------------------------------------------------- @@ -7097,14 +7104,6 @@ void MuseScore::cmd(QAction* a, const QString& cmd) for (auto _score : scores()) closeScore(_score); } - else if (cmd == "file-reload") { - saveFile(); - const auto ms = cs->masterScore(); - const auto fi = ms->fileInfo(); - const auto fn = fi->absoluteFilePath(); - closeScore(cs); - openScore(fn); - } else if (cmd == "file-save") saveFile(); else if (cmd == "file-save-as") @@ -7523,6 +7522,7 @@ void MuseScore::cmd(QAction* a, const QString& cmd) else if (cmd == "cycle-head-scheme") { if (cs) { using NHS = NoteHead::Scheme; + cs->startCmd(); for (auto n : cs->selection().noteList()) { const auto scheme = n->headScheme(); const auto beginScheme = NHS::HEAD_NORMAL; @@ -7531,10 +7531,9 @@ void MuseScore::cmd(QAction* a, const QString& cmd) const bool isPitch = (scheme == NHS::HEAD_PITCHNAME); // Normal → Pitch → Solfeggio (Movable): const auto next = isBegin ? NHS::HEAD_PITCHNAME : isPitch ? endScheme : beginScheme; - n->setHeadScheme(next); + n->undoChangeProperty(Pid::HEAD_SCHEME, QVariant::fromValue(next)); } - cs->setLayoutAll(); - cs->update(); + cs->endCmd(); } } else if (cmd == "show-system-bounding-rect") { @@ -7571,7 +7570,6 @@ void MuseScore::cmd(QAction* a, const QString& cmd) MScore::showBoundingRect = a->isChecked(); MScore::showSegmentShapes = a->isChecked(); MScore::showSkylines = a->isChecked(); - MScore::showProgressBarForPartialLayout = MScore::showSkylines; if (cs) { cs->setLayoutAll(); cs->update(); @@ -7839,6 +7837,42 @@ void MuseScore::endSearch() cv->setFocus(); } +//--------------------------------------------------------- +// updateProgress +//--------------------------------------------------------- + +void MuseScore::updateProgress(const QString& format, int val, int min, int max) + { + if (sc) { + QString message = tr("Loading score:\n") + (cs ? cs->title() : "NO SCORE INFORMATION"); + sc->showMessage(message); + sc->setProgress(val); + sc->setProgressMax(max); + } + + if (!_progressBar) + return; + + const int curMin = _progressBar->minimum(); + const int curMax = _progressBar->maximum(); + + if (curMin != min) + _progressBar->setMinimum(min); + if (curMax != max) + _progressBar->setMaximum(max); + + _progressBar->setFormat(format); + _progressBar->setValue(val); + + if (val == max) { + _progressBar->hide(); + if (sc) + sc->setProgress(0); + } + else if (_progressBar->isHidden()) + _progressBar->show(); + } + //--------------------------------------------------------- // showSearchDialog //--------------------------------------------------------- @@ -8552,7 +8586,7 @@ MuseScoreApplication* MuseScoreApplication::initApplication(int& argc, char** ar appName = "MuseScore3Development"; } else { - appName2 = "mscore3"; + appName2 = "mscore3www"; // allow multiple instances between other builds using different names, but not this very project appName = "MuseScore3Evolution-WWW"; // to maintain separate .ini file in ~/.config etc } @@ -8887,6 +8921,10 @@ MuseScoreApplication::CommandLineParseResult MuseScoreApplication::parseCommandL return parseResult; } } + else if (app->sendMessage(QString(""))) { + parseResult.exit = true; + return parseResult; + } } if (rawDiffMode || diffMode) { if (argv.size() != 2) { @@ -9093,7 +9131,6 @@ void MuseScore::init(QStringList& argv) if (!MScore::testMode) MScore::readDefaultStyle(preferences.getString(PREF_SCORE_STYLE_DEFAULTSTYLEFILE)); - MsSplashScreen* sc = nullptr; if (!MScore::noGui && preferences.getBool(PREF_UI_APP_STARTUP_SHOWSPLASHSCREEN)) { sc = new MsSplashScreen(); sc->show(); @@ -9345,6 +9382,8 @@ void MuseScore::init(QStringList& argv) if (sc) { sc->close(); + sc->deleteLater(); + sc = nullptr; qApp->processEvents(); } diff --git a/mscore/musescore.h b/mscore/musescore.h index 3b153ce69ab58..74e8398539cbe 100644 --- a/mscore/musescore.h +++ b/mscore/musescore.h @@ -633,6 +633,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore { void restartAudioEngine(); void updateTimer(); void endSearch(); + void updateProgress(const QString&, int, int, int); public: MuseScore(); diff --git a/mscore/preferences.cpp b/mscore/preferences.cpp index 80de15e3e4637..fba65fbeffe95 100644 --- a/mscore/preferences.cpp +++ b/mscore/preferences.cpp @@ -164,9 +164,6 @@ void Preferences::init(bool storeInMemoryOnly) {PREF_MIGRATION_DO_NOT_ASK_ME_AGAIN_XML, new BoolPreference(false, false)}, {PREF_APP_BACKUP_GENERATE_BACKUP, new BoolPreference(true)}, {PREF_APP_BACKUP_SUBFOLDER, new StringPreference(".mscbackup")}, - {PREF_APP_SHOW_PROGRESS_LAYOUT, new BoolPreference(true)}, - {PREF_APP_SHOW_PROGRESS_SAVE, new BoolPreference(true)}, - {PREF_APP_SHOW_PROGRESS_AUTOSAVE, new BoolPreference(true)}, {PREF_EXPORT_AUDIO_NORMALIZE, new BoolPreference(true, false)}, {PREF_EXPORT_AUDIO_SAMPLERATE, new IntPreference(44100, false)}, {PREF_EXPORT_AUDIO_PCMRATE, new IntPreference(16)}, diff --git a/mscore/scoreaccessibility.cpp b/mscore/scoreaccessibility.cpp index 39f489d33b050..e4dab39498620 100644 --- a/mscore/scoreaccessibility.cpp +++ b/mscore/scoreaccessibility.cpp @@ -236,6 +236,7 @@ void ScoreAccessibility::currentInfoChanged(Element* hover) { ScoreView* scoreView = static_cast(mainWindow)->currentScoreView(); Score* score = scoreView->score(); + const Selection& sel = score->selection(); int oldStaff = _oldStaff; int oldBar = _oldBar; _oldStaff = -1; @@ -243,8 +244,24 @@ void ScoreAccessibility::currentInfoChanged(Element* hover) QString oldStatus = statusBarLabel->text(); QString oldScreenReaderInfo = score->accessibleInfo(); clearAccessibilityInfo(); - if (score->selection().isSingle() || hover) { - Element* e = hover ? hover : score->selection().element(); + + Element* singleEl = sel.element(); + QString listString(tr("List Selection")); + if (sel.isList() && !singleEl) { + for (auto el : sel.elements()) { + if (!singleEl) + singleEl = el; + else if (el->type() != singleEl->type()) { + singleEl = nullptr; + break; + } + } + if (singleEl) + listString += " " + tr("of") + " " + QString(singleEl->name()) + "s" + " " + tr("starting with") + ":"; + } + + if (singleEl || hover) { + Element* e = hover ? hover : singleEl; if (!e) { return; } @@ -305,7 +322,13 @@ void ScoreAccessibility::currentInfoChanged(Element* hover) } } - QString rez = e->accessibleInfo(); + QString rez; + if (hover) + rez += tr("Hovering over"); + else if (!sel.isSingle()) + rez += listString; + rez += " " + e->accessibleInfo(); + if (!barsAndBeats.isEmpty()) rez += "; " + barsAndBeats; else @@ -362,13 +385,13 @@ void ScoreAccessibility::currentInfoChanged(Element* hover) } score->setAccessibleInfo(screenReaderRez); } - else if (score->selection().isRange()) { + else if (sel.isRange()) { QString barsAndBeats = ""; std::pair bar_beat; - bar_beat = score->selection().startSegment()->barbeat(); + bar_beat = sel.startSegment()->barbeat(); barsAndBeats += " " + tr("Start Measure: %1; Start Beat: %2").arg(QString::number(bar_beat.first), QString::number(bar_beat.second)); - Segment* endSegment = score->selection().endSegment(); + Segment* endSegment = sel.endSegment(); if (!endSegment) endSegment = score->lastSegment(); @@ -380,9 +403,10 @@ void ScoreAccessibility::currentInfoChanged(Element* hover) 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")); + else if (sel.isList()) { + listString += " " + tr("of varying types"); + statusBarLabel->setText(listString); + score->setAccessibleInfo(listString); } } diff --git a/mscore/scoreview.cpp b/mscore/scoreview.cpp index 176817d573fbf..b7151e57e2ec8 100644 --- a/mscore/scoreview.cpp +++ b/mscore/scoreview.cpp @@ -252,6 +252,8 @@ void ScoreView::setScore(Score* s) connect(s, SIGNAL(posChanged(POS,unsigned,bool)), SLOT(posChanged(POS,unsigned,bool))); connect(this, SIGNAL(viewRectChanged()), this, SLOT(updateContinuousPanel())); + + connect(_score, &Score::updateProgress, mscore, &MuseScore::updateProgress); } } @@ -1754,15 +1756,17 @@ void ScoreView::drawElements(QPainter& painter, QList& el, Element* ed if (!e->visible() && (score()->printing() || !score()->showInvisible())) continue; - if (!(toNote(e)->headSchemeHasAlphaNumerics())) + auto n = toNote(e); + if (!n->onTabStaff() && !n->headSchemeHasAlphaNumerics()) continue; + QPointF pos(e->pagePos()); painter.translate(pos); e->draw(&painter); painter.translate(-pos); + } } - } if (haveHover && !hoverUnder) { if (state != ViewState::LASSO) { @@ -2334,8 +2338,9 @@ void ScoreView::updateHover(const QPointF& position) { QPoint point = position.toPoint(); - auto selected = score()->selection().element(); - auto pastHover = dropTarget; + bool noSelection = score()->selection().isNone(); + auto selectedEl = score()->selection().element(); + auto pastHover = dropTarget; const qreal zoomThresh = 0.33; Element* presentHover = logicalZoomLevel() > zoomThresh ? elementNear(toLogical(point)) : nullptr; @@ -2345,7 +2350,7 @@ void ScoreView::updateHover(const QPointF& position) QRectF view; if (pastHover != presentHover) { - if (presentHover && (presentHover != selected)) { + if (presentHover && (presentHover != selectedEl)) { view = presentHover->canvasBoundingRect(); setDropTarget(presentHover, false /*no highlight*/); ScoreAccessibility::instance()->currentInfoChanged(presentHover); @@ -2353,12 +2358,13 @@ void ScoreView::updateHover(const QPointF& position) else if (pastHover) { view = pastHover->canvasBoundingRect(); setDropTarget(nullptr); + ScoreAccessibility::instance()->currentInfoChanged(); } const int margin = 2; update(toPhysical(view).adjusted(-margin, -margin, +margin, +margin)); update(); } - if (!selected && !presentHover) { + if (noSelection && !presentHover) { if (Page* currentPage = point2page(editData.startMove)) { int currentPageNumber = currentPage->no() + 1; int totalPages = score()->npages(); @@ -5570,6 +5576,8 @@ void ScoreView::adjustCanvasPosition(const Element* el, bool playBack, int staff else if (editing){ auto ry = sys->canvasBoundingRect().y(); auto h = sys->canvasBoundingRect().height(); + ry -= sys->minTop(); + h += sys->minBottom(); showRect.setY(ry); showRect.setHeight(h); } diff --git a/mscore/shortcut.cpp b/mscore/shortcut.cpp index be1f82908eea6..68268c4f575b0 100644 --- a/mscore/shortcut.cpp +++ b/mscore/shortcut.cpp @@ -181,16 +181,6 @@ Shortcut Shortcut::_sc[] = { QT_TRANSLATE_NOOP("action","File > Close"), QT_TRANSLATE_NOOP("action","Close current score") }, - { - MsWidget::MAIN_WINDOW, - STATE_NORMAL | STATE_NOTE_ENTRY | STATE_EDIT | STATE_PLAY, - "file-reload", - QT_TRANSLATE_NOOP("action","Reload Current Score"), - QT_TRANSLATE_NOOP("action","File > Reload Current Score"), - QT_TRANSLATE_NOOP("action","Reload current score"), - Icons::fileReload_ICON, - Qt::ApplicationShortcut - }, { MsWidget::MAIN_WINDOW, STATE_NORMAL | STATE_NOTE_ENTRY | STATE_EDIT | STATE_PLAY,