LCOV - code coverage report
Current view: top level - src/engraving/dom - masterscore.h Coverage Total Hit
Test: filtered_coverage.info Lines: 84.8 % 33 28
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2021 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #pragma once
      24              : 
      25              : #include <array>
      26              : #include <memory>
      27              : 
      28              : #include "../infrastructure/ifileinfoprovider.h"
      29              : #include "../infrastructure/eidregister.h"
      30              : 
      31              : #include "instrument.h"
      32              : #include "score.h"
      33              : 
      34              : namespace mu::engraving {
      35              : class EngravingProject;
      36              : class MscReader;
      37              : class MscWriter;
      38              : class MscLoader;
      39              : class TransactionManager;
      40              : }
      41              : 
      42              : namespace mu::engraving::compat {
      43              : class ScoreAccess;
      44              : class ReadStyleHook;
      45              : }
      46              : 
      47              : namespace mu::engraving {
      48              : class Excerpt;
      49              : class MasterScore;
      50              : class Part;
      51              : class RepeatList;
      52              : struct RepeatSegmentInfo;
      53              : class Revisions;
      54              : class TempoTimeline;
      55              : class TimeSigMap;
      56              : class UndoStack;
      57              : class ScoreAutomationController;
      58              : 
      59              : class MidiMapping
      60              : {
      61              : public:
      62         8380 :     Part* part() { return m_part; }
      63              :     const Part* part() const { return m_part; }
      64        12390 :     InstrChannel* articulation() { return m_articulation.get(); }
      65          103 :     const InstrChannel* articulation() const { return m_articulation.get(); }
      66        18533 :     signed char port() const { return m_port; }
      67        13486 :     signed char channel() const { return m_channel; }
      68              : 
      69              : private:
      70              : 
      71              :     MidiMapping() = default;   // should be created only within MasterScore
      72              :     friend class MasterScore;
      73              : 
      74              :     Part* m_part = nullptr;
      75              :     std::unique_ptr<InstrChannel> m_articulation;
      76              :     signed char m_port = 0;
      77              :     signed char m_channel = 0;
      78              :     InstrChannel* m_masterChannel = nullptr;
      79              :     PartChannelSettingsLink m_link;
      80              : };
      81              : 
      82              : class MasterScore : public Score
      83              : {
      84         4113 :     OBJECT_ALLOCATOR(engraving, MasterScore)
      85              : 
      86              : public:
      87              : 
      88              :     ~MasterScore();
      89              :     MasterScore* clone();
      90              : 
      91              :     Score* createScore();
      92              :     Score* createScore(const MStyle& s);
      93              : 
      94            0 :     std::weak_ptr<EngravingProject> project() const { return m_project; }
      95              : 
      96        32154 :     bool isMaster() const override { return true; }
      97              : 
      98       475764 :     EIDRegister* eidRegister() { return &m_eidRegister; }
      99              :     const EIDRegister* eidRegister() const { return &m_eidRegister; }
     100              : 
     101         1468 :     bool readOnly() const override { return m_readOnly; }
     102              :     void setReadOnly(bool ro) { m_readOnly = ro; }
     103        50843 :     TransactionManager* transactionManager() const { return m_transactionManager.get(); }
     104         4691 :     UndoStack* undoStack() const { return m_undoStack; }
     105        11824 :     TimeSigMap* sigmap() const override { return m_sigmap; }
     106          997 :     muse::async::Channel<ScoreChanges> changesChannel() const override { return m_changesChannel; }
     107              : 
     108              :     AutomationDataConstPtr automationData() const override;
     109              :     void setAutomationData(AutomationDataPtr data);
     110              :     void editAutomationPoints(const AutomationCurveKey& key, AutomationPointEdits& edits, bool undoable = true) override;
     111              : 
     112              :     /// Always call this before calling `repeatList()`
     113              :     /// No need to set it back after use, because everyone always calls it before using `repeatList()`
     114              :     void setExpandRepeats(bool expandRepeats);
     115         8644 :     bool expandRepeats() const { return m_expandRepeats; }
     116              : 
     117              :     void updateRepeatListTempo();
     118              :     void updateRepeatList();
     119              : 
     120              :     const RepeatList& repeatList() const;
     121              :     const RepeatList& repeatList(bool expandRepeats, bool updateTies = true) const;
     122              : 
     123              :     void invalidateRepeatList();
     124              : 
     125              :     const TempoTimeline& tempoTimeline() const;
     126              :     const TempoTimeline& tempoTimeline(bool expandRepeats) const;
     127              :     bool setTempoMultiplier(BeatsPerSecond val);
     128              :     void setTempoTimelineOverride(std::optional<TempoTimeline> timeline);
     129              : 
     130        15206 :     std::vector<Excerpt*>& excerpts() { return m_excerpts; }
     131            0 :     const std::vector<Excerpt*>& excerpts() const { return m_excerpts; }
     132              : 
     133              :     void setUpdateAll() override;
     134              : 
     135              :     void setLayoutAll(staff_idx_t staff = muse::nidx, const EngravingItem* e = nullptr);
     136              :     void setLayout(const Fraction& tick, staff_idx_t staff, const EngravingItem* e = nullptr);
     137              :     void setLayout(const Fraction& tick1, const Fraction& tick2, staff_idx_t staff1, staff_idx_t staff2, const EngravingItem* e = nullptr);
     138              : 
     139       264484 :     CmdState& cmdState() override { return m_cmdState; }
     140            0 :     const CmdState& cmdState() const override { return m_cmdState; }
     141          274 :     void addLayoutFlags(LayoutFlags val) override { m_cmdState.layoutFlags |= val; }
     142          103 :     void setInstrumentsChanged(bool val) override { m_cmdState.instrumentsChanged = val; }
     143              : 
     144         1170 :     void setExcerptsChanged(bool val) { m_cmdState.excerptsChanged = val; }
     145            0 :     bool excerptsChanged() const { return m_cmdState.excerptsChanged; }
     146              :     bool instrumentsChanged() const { return m_cmdState.instrumentsChanged; }
     147              : 
     148           87 :     void update() { update(true); }
     149              :     void lockUpdates(bool locked);
     150              : 
     151              :     int midiPortCount() const { return m_midiPortCount; }
     152         3022 :     void setMidiPortCount(int val) { m_midiPortCount = val; }
     153           16 :     std::vector<MidiMapping>& midiMapping() { return m_midiMapping; }
     154         3931 :     MidiMapping* midiMapping(int channel) { return &m_midiMapping[channel]; }
     155              :     void addMidiMapping(InstrChannel* channel, Part* part, int midiPort, int midiChannel);
     156              :     void updateMidiMapping(InstrChannel* channel, Part* part, int midiPort, int midiChannel);
     157         1712 :     int midiPort(int idx) const { return m_midiMapping[idx].port(); }
     158         3001 :     int midiChannel(int idx) const { return m_midiMapping[idx].channel(); }
     159              :     void rebuildMidiMapping();
     160              :     void checkMidiMapping();
     161         1966 :     bool exportMidiMapping() { return !m_isSimpleMidiMapping; }
     162              :     int getNextFreeMidiMapping(std::set<int>& occupiedMidiChannels, unsigned int& searchMidiMappingFrom, int p = -1, int ch = -1);
     163              :     int getNextFreeDrumMidiMapping(std::set<int>& occupiedMidiChannels);
     164              :     void rebuildAndUpdateExpressive(Synthesizer* synth);
     165              :     void updateExpressive(Synthesizer* synth);
     166              :     void updateExpressive(Synthesizer* synth, bool expressive, bool force = false);
     167              : 
     168              :     using Score::loopBoundaryTick;
     169              :     Fraction loopBoundaryTick(LoopBoundaryType type) const;
     170              :     void setLoopBoundaryTick(LoopBoundaryType type, Fraction tick);
     171              : 
     172              :     void addExcerpt(Excerpt*, size_t index = muse::nidx);
     173              :     void removeExcerpt(Excerpt*);
     174              :     void deleteExcerpt(Excerpt*);
     175              : 
     176              :     void initAndAddExcerpt(Excerpt*, bool);
     177              :     void initExcerpt(Excerpt*);
     178              :     void initEmptyExcerpt(Excerpt*);
     179              : 
     180              :     void initAutomation(); // TODO: Placeholder?
     181              : 
     182              :     void setPlaybackScore(Score*);
     183            0 :     Score* playbackScore() { return m_playbackScore; }
     184              :     const Score* playbackScore() const { return m_playbackScore; }
     185         5507 :     InstrChannel* playbackChannel(const InstrChannel* c) { return m_midiMapping[c->channel()].articulation(); }
     186          103 :     const InstrChannel* playbackChannel(const InstrChannel* c) const { return m_midiMapping[c->channel()].articulation(); }
     187              : 
     188              :     MasterScore* unrollRepeats();
     189              : 
     190              :     MeasureBase* insertMeasure(MeasureBase* beforeMeasure = nullptr, const InsertMeasureOptions& options = InsertMeasureOptions());
     191              : 
     192              :     IFileInfoProviderPtr fileInfo() const;
     193              :     void setFileInfoProvider(IFileInfoProviderPtr fileInfoProvider);
     194              : 
     195              :     String name() const override;
     196              : 
     197              :     muse::Ret sanityCheck();
     198              : 
     199              : private:
     200              :     void update(bool resetCmdState, bool layoutAllParts = false);
     201              : 
     202              :     void updateAutomation(const ScoreChanges& changes);
     203              : 
     204              :     void onTimeInserted(const Fraction& tick, const Fraction& len, const std::vector<RepeatSegmentInfo>& oldSegments) override;
     205              : 
     206              :     void reorderMidiMapping();
     207              :     void rebuildExcerptsMidiMapping();
     208              :     void removeDeletedMidiMapping();
     209              : 
     210              :     int updateMidiMapping();
     211              :     void doUpdateMidiMapping(int& maxport, std::set<int>& occupiedMidiChannels, unsigned int& searchMidiMappingFrom, Part* part,
     212              :                              InstrChannel* channel, bool useDrumset);
     213              : 
     214              :     friend class EngravingProject;
     215              :     friend class compat::ScoreAccess;
     216              :     friend class read114::Read114;
     217              :     friend class read400::Read400;
     218              :     friend class TransactionManager;
     219              : 
     220              :     MasterScore(const muse::modularity::ContextPtr& iocCtx, std::weak_ptr<EngravingProject> project = std::weak_ptr<EngravingProject>());
     221              :     MasterScore(const muse::modularity::ContextPtr& iocCtx, const MStyle&,
     222              :                 std::weak_ptr<EngravingProject> project  = std::weak_ptr<EngravingProject>());
     223              : 
     224              :     void initParts(Excerpt*);
     225              : 
     226              :     EIDRegister m_eidRegister;
     227              :     std::unique_ptr<TransactionManager> m_transactionManager;
     228              :     UndoStack* m_undoStack = nullptr;
     229              :     TimeSigMap* m_sigmap = nullptr;
     230              :     RepeatList* m_expandedRepeatList = nullptr;
     231              :     RepeatList* m_nonExpandedRepeatList = nullptr;
     232              :     ScoreAutomationController* m_automationController = nullptr;
     233              :     bool m_expandRepeats = true;
     234              : 
     235              :     std::vector<Excerpt*> m_excerpts;
     236              :     std::vector<PartChannelSettingsLink> m_playbackSettingsLinks;
     237              :     Score* m_playbackScore = nullptr;
     238              :     muse::async::Channel<ScoreChanges> m_changesChannel;
     239              : 
     240              :     bool m_readOnly = false;
     241              : 
     242              :     CmdState m_cmdState;       // modified during cmd processing
     243              :     bool m_updatesLocked = false;
     244              : 
     245              :     std::array<Fraction, 2> m_loopBoundaries; ///< 0 - LoopIn, 1 - LoopOut
     246              : 
     247              :     int m_midiPortCount = 0;                           // A count of ALSA midi out ports
     248              :     std::vector<MidiMapping> m_midiMapping;
     249              :     bool m_isSimpleMidiMapping = false;                 // midi mapping is simple if all ports and channels
     250              :     // don't decrease and don't have gaps
     251              : 
     252              :     std::weak_ptr<EngravingProject> m_project;
     253              : 
     254              :     // FIXME: Move to EngravingProject
     255              :     // We can't yet, because m_project is not set on every MasterScore
     256              :     IFileInfoProviderPtr m_fileInfoProvider;
     257              : };
     258              : }
        

Generated by: LCOV version 2.0-1