247 lines
9.0 KiB
C++
247 lines
9.0 KiB
C++
/*
|
|
* SPDX-License-Identifier: GPL-3.0-only
|
|
* MuseScore-CLA-applies
|
|
*
|
|
* MuseScore
|
|
* Music Composition & Notation
|
|
*
|
|
* Copyright (C) 2021 MuseScore BVBA and others
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 3 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef MU_ENGRAVING_MASTERSCORE_H
|
|
#define MU_ENGRAVING_MASTERSCORE_H
|
|
|
|
#include "infrastructure/io/ifileinfoprovider.h"
|
|
|
|
#include "score.h"
|
|
#include "instrument.h"
|
|
|
|
namespace mu::engraving {
|
|
class EngravingProject;
|
|
class MscReader;
|
|
class MscWriter;
|
|
class ScoreReader;
|
|
class Read400;
|
|
}
|
|
|
|
namespace mu::engraving::compat {
|
|
class ScoreAccess;
|
|
class Read114;
|
|
class Read206;
|
|
class Read302;
|
|
class ReadStyleHook;
|
|
}
|
|
|
|
namespace Ms {
|
|
class Excerpt;
|
|
class MasterScore;
|
|
class Part;
|
|
class RepeatList;
|
|
class Revisions;
|
|
class TempoMap;
|
|
class TimeSigMap;
|
|
class UndoStack;
|
|
|
|
class MidiMapping
|
|
{
|
|
Part* _part;
|
|
std::unique_ptr<Channel> _articulation;
|
|
signed char _port;
|
|
signed char _channel;
|
|
Channel* masterChannel;
|
|
PartChannelSettingsLink link;
|
|
|
|
MidiMapping() = default; // should be created only within MasterScore
|
|
friend class MasterScore;
|
|
|
|
public:
|
|
Part* part() { return _part; }
|
|
const Part* part() const { return _part; }
|
|
Channel* articulation() { return _articulation.get(); }
|
|
const Channel* articulation() const { return _articulation.get(); }
|
|
signed char port() const { return _port; }
|
|
signed char channel() const { return _channel; }
|
|
};
|
|
|
|
class MasterScore : public Score
|
|
{
|
|
UndoStack* _undoStack = nullptr;
|
|
TimeSigMap* _sigmap;
|
|
TempoMap* _tempomap;
|
|
RepeatList* _repeatList;
|
|
RepeatList* _repeatList2;
|
|
bool _expandRepeats = MScore::playRepeats;
|
|
bool _playlistDirty = true;
|
|
std::vector<Excerpt*> _excerpts;
|
|
std::vector<PartChannelSettingsLink> _playbackSettingsLinks;
|
|
Score* _playbackScore = nullptr;
|
|
Revisions* _revisions;
|
|
|
|
bool _readOnly = false;
|
|
|
|
CmdState _cmdState; // modified during cmd processing
|
|
|
|
Fraction _pos[3]; ///< 0 - current, 1 - left loop, 2 - right loop
|
|
|
|
int _midiPortCount = 0; // A count of ALSA midi out ports
|
|
QQueue<MidiInputEvent> _midiInputQueue; // MIDI events that have yet to be processed
|
|
std::list<MidiInputEvent> _activeMidiPitches; // MIDI keys currently being held down
|
|
std::vector<MidiMapping> _midiMapping;
|
|
bool isSimpleMidiMapping = false; // midi mapping is simple if all ports and channels
|
|
// don't decrease and don't have gaps
|
|
QSet<int> occupiedMidiChannels; // each entry is port*16+channel, port range: 0-inf, channel: 0-15
|
|
unsigned int searchMidiMappingFrom = 0; // makes getting next free MIDI mapping faster
|
|
|
|
qreal m_widthOfSegmentCell = 3;
|
|
|
|
std::weak_ptr<mu::engraving::EngravingProject> m_project;
|
|
|
|
// FIXME: Move to EngravingProject
|
|
// We can't yet, because m_project is not set on every MasterScore
|
|
IFileInfoProviderPtr m_fileInfoProvider;
|
|
|
|
bool m_isNewlyCreated { false }; /// true if the file has never been saved yet
|
|
bool m_saved { false };
|
|
bool m_autosaveDirty { true };
|
|
|
|
void reorderMidiMapping();
|
|
void rebuildExcerptsMidiMapping();
|
|
void removeDeletedMidiMapping();
|
|
int updateMidiMapping();
|
|
|
|
friend class mu::engraving::EngravingProject;
|
|
friend class mu::engraving::compat::ScoreAccess;
|
|
friend class mu::engraving::compat::Read114;
|
|
friend class mu::engraving::compat::Read206;
|
|
friend class mu::engraving::compat::Read302;
|
|
friend class mu::engraving::Read400;
|
|
|
|
MasterScore(std::weak_ptr<mu::engraving::EngravingProject> project = std::weak_ptr<mu::engraving::EngravingProject>());
|
|
MasterScore(const MStyle&, std::weak_ptr<mu::engraving::EngravingProject> project = std::weak_ptr<mu::engraving::EngravingProject>());
|
|
|
|
bool writeMscz(mu::engraving::MscWriter& mscWriter, bool onlySelection = false, bool createThumbnail = true);
|
|
bool exportPart(mu::engraving::MscWriter& mscWriter, Score* partScore);
|
|
|
|
public:
|
|
|
|
~MasterScore();
|
|
MasterScore* clone();
|
|
|
|
Score* createScore();
|
|
Score* createScore(const MStyle& s);
|
|
|
|
std::weak_ptr<mu::engraving::EngravingProject> project() const { return m_project; }
|
|
|
|
bool isMaster() const override { return true; }
|
|
bool readOnly() const override { return _readOnly; }
|
|
void setReadOnly(bool ro) { _readOnly = ro; }
|
|
UndoStack* undoStack() const override { return _undoStack; }
|
|
TimeSigMap* sigmap() const override { return _sigmap; }
|
|
TempoMap* tempomap() const override { return _tempomap; }
|
|
|
|
bool playlistDirty() const override { return _playlistDirty; }
|
|
void setPlaylistDirty() override;
|
|
void setPlaylistClean() { _playlistDirty = false; }
|
|
|
|
void setExpandRepeats(bool expandRepeats);
|
|
bool expandRepeats() const { return _expandRepeats; }
|
|
void updateRepeatListTempo();
|
|
const RepeatList& repeatList() const override;
|
|
const RepeatList& repeatList2() const override;
|
|
|
|
std::vector<Excerpt*>& excerpts() { return _excerpts; }
|
|
const std::vector<Excerpt*>& excerpts() const { return _excerpts; }
|
|
QQueue<MidiInputEvent>* midiInputQueue() override { return &_midiInputQueue; }
|
|
std::list<MidiInputEvent>& activeMidiPitches() override { return _activeMidiPitches; }
|
|
|
|
void setUpdateAll() override;
|
|
|
|
void setLayoutAll(staff_idx_t staff = mu::nidx, const EngravingItem* e = nullptr);
|
|
void setLayout(const Fraction& tick, staff_idx_t staff, const EngravingItem* e = nullptr);
|
|
void setLayout(const Fraction& tick1, const Fraction& tick2, staff_idx_t staff1, staff_idx_t staff2, const EngravingItem* e = nullptr);
|
|
|
|
CmdState& cmdState() override { return _cmdState; }
|
|
const CmdState& cmdState() const override { return _cmdState; }
|
|
void addLayoutFlags(LayoutFlags val) override { _cmdState.layoutFlags |= val; }
|
|
void setInstrumentsChanged(bool val) override { _cmdState._instrumentsChanged = val; }
|
|
|
|
void setExcerptsChanged(bool val) { _cmdState._excerptsChanged = val; }
|
|
bool excerptsChanged() const { return _cmdState._excerptsChanged; }
|
|
bool instrumentsChanged() const { return _cmdState._instrumentsChanged; }
|
|
|
|
Revisions* revisions() { return _revisions; }
|
|
|
|
void setTempomap(TempoMap* tm);
|
|
|
|
int midiPortCount() const { return _midiPortCount; }
|
|
void setMidiPortCount(int val) { _midiPortCount = val; }
|
|
std::vector<MidiMapping>& midiMapping() { return _midiMapping; }
|
|
MidiMapping* midiMapping(int channel) { return &_midiMapping[channel]; }
|
|
void addMidiMapping(Channel* channel, Part* part, int midiPort, int midiChannel);
|
|
void updateMidiMapping(Channel* channel, Part* part, int midiPort, int midiChannel);
|
|
int midiPort(int idx) const { return _midiMapping[idx].port(); }
|
|
int midiChannel(int idx) const { return _midiMapping[idx].channel(); }
|
|
void rebuildMidiMapping();
|
|
void checkMidiMapping();
|
|
bool exportMidiMapping() { return !isSimpleMidiMapping; }
|
|
int getNextFreeMidiMapping(int p = -1, int ch = -1);
|
|
int getNextFreeDrumMidiMapping();
|
|
void enqueueMidiEvent(MidiInputEvent ev) { _midiInputQueue.enqueue(ev); }
|
|
void rebuildAndUpdateExpressive(Synthesizer* synth);
|
|
void updateExpressive(Synthesizer* synth);
|
|
void updateExpressive(Synthesizer* synth, bool expressive, bool force = false);
|
|
void setSoloMute();
|
|
|
|
using Score::pos;
|
|
Fraction pos(POS pos) const { return _pos[int(pos)]; }
|
|
void setPos(POS pos, Fraction tick);
|
|
|
|
void addExcerpt(Excerpt*, size_t index = mu::nidx);
|
|
void removeExcerpt(Excerpt*);
|
|
void deleteExcerpt(Excerpt*);
|
|
|
|
void initAndAddExcerpt(Excerpt*, bool);
|
|
void initEmptyExcerpt(Excerpt*);
|
|
|
|
void setPlaybackScore(Score*);
|
|
Score* playbackScore() { return _playbackScore; }
|
|
const Score* playbackScore() const { return _playbackScore; }
|
|
Channel* playbackChannel(const Channel* c) { return _midiMapping[c->channel()].articulation(); }
|
|
const Channel* playbackChannel(const Channel* c) const { return _midiMapping[c->channel()].articulation(); }
|
|
|
|
MasterScore* unrollRepeats();
|
|
|
|
IFileInfoProviderPtr fileInfo() const;
|
|
void setFileInfoProvider(IFileInfoProviderPtr fileInfoProvider);
|
|
|
|
bool isNewlyCreated() const;
|
|
void setNewlyCreated(bool val);
|
|
|
|
bool saved() const;
|
|
void setSaved(bool v);
|
|
|
|
bool autosaveDirty() const;
|
|
void setAutosaveDirty(bool v);
|
|
|
|
QString name() const override;
|
|
|
|
void setWidthOfSegmentCell(qreal val) { m_widthOfSegmentCell = val; }
|
|
qreal widthOfSegmentCell() const { return m_widthOfSegmentCell; }
|
|
};
|
|
|
|
extern Ms::MasterScore* gpaletteScore;
|
|
}
|
|
|
|
#endif // MU_ENGRAVING_MASTERSCORE_H
|