Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/engraving/dom/masterscore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ void MasterScore::setUpdateAll()
void MasterScore::setLayoutAll(staff_idx_t staff, const EngravingItem* e)
{
m_cmdState.setTick(Fraction(0, 1));
m_cmdState.setTick(measures()->last() ? measures()->last()->endTick() : Fraction(0, 1));
m_cmdState.setTick(Fraction::max());

if (e && e->score() == this) {
// TODO: map staff number properly
Expand Down
16 changes: 0 additions & 16 deletions src/engraving/rendering/score/layoutcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,22 +597,6 @@ LayoutState& LayoutContext::mutState()
return m_state;
}

void LayoutContext::setLayout(const Fraction& tick1, const Fraction& tick2, staff_idx_t staff1, staff_idx_t staff2, const EngravingItem* e)
{
IF_ASSERT_FAILED(m_score) {
return;
}
m_score->setLayout(tick1, tick2, staff1, staff2, e);
}

void LayoutContext::addRefresh(const RectF& r)
{
IF_ASSERT_FAILED(m_score) {
return;
}
m_score->addRefresh(r);
}

const Selection& LayoutContext::selection() const
{
IF_ASSERT_FAILED(m_score) {
Expand Down
4 changes: 0 additions & 4 deletions src/engraving/rendering/score/layoutcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,6 @@ class LayoutContext : public IGetScoreInternal
const LayoutState& state() const;
LayoutState& mutState();

// Mark
void setLayout(const Fraction& tick1, const Fraction& tick2, staff_idx_t staff1, staff_idx_t staff2, const EngravingItem* e);
void addRefresh(const RectF& r);

// Other
const Selection& selection() const;
void select(EngravingItem* item, SelectType = SelectType::SINGLE, staff_idx_t staff = 0);
Expand Down
4 changes: 2 additions & 2 deletions src/engraving/rendering/score/scorelayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ void ScoreLayout::layoutRange(Score* score, const Fraction& st, const Fraction&
}

// Check range
bool isLayoutAll = stick <= Fraction(0, 1) && (etick < Fraction(0, 1) || etick >= score->masterScore()->last()->endTick());
bool isLayoutAll = stick <= Fraction(0, 1) && (etick < Fraction(0, 1) || etick == Fraction::max());
if (stick < Fraction(0, 1)) {
stick = Fraction(0, 1);
}
if (etick < Fraction(0, 1)) {
if (etick < Fraction(0, 1) || etick == Fraction::max()) {
etick = score->last()->endTick();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ InspectorSectionView {
navigation.row: root.navigationRowStart + 3

toolTipTitle: qsTrc("inspector", "Reset to default")
enabled: root.model?.canResetEmptyStavesVisibility
enabled: root.model && root.model.canResetEmptyStavesVisibility

onClicked: {
if (root.model) {
Expand Down
105 changes: 67 additions & 38 deletions src/notation/view/internal/staffvisibilitypopupmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <iterator>
#include <memory>

#include "async/async.h"
#include "containers.h"

#include "engraving/dom/measure.h"
Expand Down Expand Up @@ -105,6 +106,8 @@ void EmptyStavesVisibilityModel::reload()
{
engraving::Fraction tick = m_system->tick();

assert(m_system && m_system->staves().size() == m_system->score()->nstaves());

beginResetModel();
m_parts.clear();

Expand Down Expand Up @@ -290,7 +293,7 @@ void EmptyStavesVisibilityModel::resetAllVisibility()

m_notation->undoStack()->commitChanges();

reload();
scheduleUpdateData();
}

bool EmptyStavesVisibilityModel::canResetAll() const
Expand Down Expand Up @@ -331,7 +334,7 @@ void EmptyStavesVisibilityModel::setPartVisibility(PartItem* partItem, engraving

m_notation->undoStack()->commitChanges();

updateData(partItem);
scheduleUpdateData();
}

void EmptyStavesVisibilityModel::setStaffVisibility(StaffItem* staffItem, engraving::AutoOnOff value)
Expand All @@ -346,53 +349,79 @@ void EmptyStavesVisibilityModel::setStaffVisibility(StaffItem* staffItem, engrav

m_notation->undoStack()->commitChanges();

updateData(staffItem->part);
scheduleUpdateData();
}

void EmptyStavesVisibilityModel::updateData(PartItem* partItem)
void EmptyStavesVisibilityModel::scheduleUpdateData()
{
partItem->isVisible = false;
partItem->canChangeVisibility = false;
partItem->canReset = false;
//! NOTE: Changing empty staves visibility might cause `m_system` to be
//! deleted. If that happens, its StaffVisibilityIndicator will also be
//! deleted, and thus removed from the selection; as a result, the popup will
//! be closed on the next event loop tick, and this model will be deleted.
//!
//! Therefore, we delay the call to `doUpdateData()` by two event loop ticks.
//! If the model is still alive at that point, the popup will not have been
//! closed, so `m_system` will still be valid, so we can safely call
//! `doUpdateData()`. Otherwise, if `m_system` was deleted, the model will
//! also have been deleted, so the async call will be cancelled
//! automatically.
muse::async::Async::call(this, [this]() {
muse::async::Async::call(this, [this]() {
doUpdateData();
});
});
}

for (const auto& staffItem : partItem->staves) {
staffItem->isVisible = m_system->staff(staffItem->staffIndex)->show();
if (staffItem->isVisible) {
// Part is visible if any of its staves is visible
partItem->isVisible = true;
}
void EmptyStavesVisibilityModel::doUpdateData()
{
assert(m_system && m_system->staves().size() == m_system->score()->nstaves());

staffItem->canChangeVisibility = SystemLayout::canChangeSysStaffVisibility(m_system, staffItem->staffIndex);
if (staffItem->canChangeVisibility) {
// Part visibility can be changed if any of its staves can change visibility
partItem->canChangeVisibility = true;
}
int row = 0;
for (const auto& partItem : m_parts) {
partItem->isVisible = false;
partItem->canChangeVisibility = false;
partItem->canReset = false;

// Staff can reset visibility if any measure in the range contains an override
staffItem->canReset = false;
for (const engraving::MeasureBase* mb : m_system->measures()) {
if (!mb->isMeasure()) {
continue;
for (const auto& staffItem : partItem->staves) {
staffItem->isVisible = m_system->staff(staffItem->staffIndex)->show();
if (staffItem->isVisible) {
// Part is visible if any of its staves is visible
partItem->isVisible = true;
}
if (engraving::toMeasure(mb)->hideStaffIfEmpty(staffItem->staffIndex) != engraving::AutoOnOff::AUTO) {
staffItem->canReset = true;
break;

staffItem->canChangeVisibility = SystemLayout::canChangeSysStaffVisibility(m_system, staffItem->staffIndex);
if (staffItem->canChangeVisibility) {
// Part visibility can be changed if any of its staves can change visibility
partItem->canChangeVisibility = true;
}

// Staff can reset visibility if any measure in the range contains an override
staffItem->canReset = false;
for (const engraving::MeasureBase* mb : m_system->measures()) {
if (!mb->isMeasure()) {
continue;
}
if (engraving::toMeasure(mb)->hideStaffIfEmpty(staffItem->staffIndex) != engraving::AutoOnOff::AUTO) {
staffItem->canReset = true;
break;
}
}
if (staffItem->canReset) {
// Part can reset visibility if any of its staves can reset
partItem->canReset = true;
}
}
if (staffItem->canReset) {
// Part can reset visibility if any of its staves can reset
partItem->canReset = true;
}
}

int row = partIndex(partItem);
QModelIndex partModelIndex = index(row, 0, QModelIndex());
emit dataChanged(partModelIndex, partModelIndex, { IsVisible, CanReset });
QModelIndex partModelIndex = index(row, 0, QModelIndex());
emit dataChanged(partModelIndex, partModelIndex, { IsVisible, CanReset });

if (partItem->staves.size() > 1) {
emit dataChanged(index(0, 0, partModelIndex),
index(static_cast<int>(partItem->staves.size()) - 1, 0, partModelIndex),
{ IsVisible, CanReset });
}

if (partItem->staves.size() > 1) {
emit dataChanged(index(0, 0, partModelIndex),
index(static_cast<int>(partItem->staves.size()) - 1, 0, partModelIndex),
{ IsVisible, CanReset });
++row;
}

emit canResetAllChanged();
Expand Down
17 changes: 11 additions & 6 deletions src/notation/view/internal/staffvisibilitypopupmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@

#pragma once

#include <QAbstractItemModel>
#include <QQmlParserStatus>
#include <memory>
#include <vector>

#include <QAbstractItemModel>
#include <QQmlParserStatus>

#include "async/asyncable.h"
#include "context/iglobalcontext.h"
#include "inotation.h"
#include "modularity/ioc.h"
#include "types/types.h"

#include "engraving/types/types.h"

#include "inotation.h"
#include "view/abstractelementpopupmodel.h"

namespace mu::engraving {
Expand Down Expand Up @@ -67,7 +71,7 @@ class StaffVisibilityPopupModel : public AbstractElementPopupModel, public QQmlP
size_t m_systemIndex = 0;
};

class EmptyStavesVisibilityModel : public QAbstractItemModel, public muse::Injectable
class EmptyStavesVisibilityModel : public QAbstractItemModel, public muse::Injectable, public muse::async::Asyncable
{
Q_OBJECT

Expand Down Expand Up @@ -115,7 +119,8 @@ class EmptyStavesVisibilityModel : public QAbstractItemModel, public muse::Injec
void setPartVisibility(PartItem* partItem, engraving::AutoOnOff value);
void setStaffVisibility(StaffItem* staffItem, engraving::AutoOnOff value);

void updateData(PartItem* partItem);
void scheduleUpdateData();
void doUpdateData();

int partIndex(const PartItem* partItem) const;

Expand Down
Loading