MuseScore/libmscore/select.h

230 lines
8.2 KiB
C
Raw Normal View History

2012-05-26 14:26:10 +02:00
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2011 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#ifndef __SELECT_H__
#define __SELECT_H__
#include "pitchspelling.h"
#include "mscore.h"
#include "durationtype.h"
2013-05-13 18:49:17 +02:00
namespace Ms {
2012-05-26 14:26:10 +02:00
class Score;
class Page;
class System;
class ChordRest;
class Element;
class Segment;
class Note;
class Measure;
class Chord;
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// ElementPattern
//---------------------------------------------------------
struct ElementPattern {
QList<Element*> el;
int type;
int subtype;
int staffStart;
int staffEnd; // exclusive
2012-05-26 14:26:10 +02:00
int voice;
const System* system;
bool subtypeValid;
Fraction durationTicks;
2012-05-26 14:26:10 +02:00
};
//---------------------------------------------------------
// NotePattern
//---------------------------------------------------------
struct NotePattern {
QList<Note*> el;
int pitch = -1;
int string = STRING_NONE;
int tpc = Tpc::TPC_INVALID;;
NoteHead::Group notehead = NoteHead::Group::HEAD_INVALID;
TDuration durationType = TDuration();
Fraction durationTicks;
NoteType type = NoteType::INVALID;
int staffStart;
int staffEnd; // exclusive
int voice;
const System* system;
};
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// SelState
//---------------------------------------------------------
enum class SelState : char {
2014-05-26 13:21:04 +02:00
NONE, // nothing is selected
LIST, // disjoint selection
RANGE, // adjacent selection, a range in one or more staves
2012-05-26 14:26:10 +02:00
// is selected
};
//---------------------------------------------------------
// SelectionFilterType
// see also `static const char* labels[]` in mscore/selectionwindow.cpp
// need to keep those in sync!
//---------------------------------------------------------
enum class SelectionFilterType {
NONE = 0,
FIRST_VOICE = 1 << 0,
SECOND_VOICE = 1 << 1,
THIRD_VOICE = 1 << 2,
FOURTH_VOICE = 1 << 3,
DYNAMIC = 1 << 4,
FINGERING = 1 << 5,
LYRICS = 1 << 6,
2014-06-15 14:22:32 +02:00
CHORD_SYMBOL = 1 << 7,
2014-07-02 23:53:18 +02:00
OTHER_TEXT = 1 << 8,
ARTICULATION = 1 << 9,
SLUR = 1 << 10,
FIGURED_BASS = 1 << 11,
OTTAVA = 1 << 12,
PEDAL_LINE = 1 << 13,
2014-07-03 23:57:08 +02:00
OTHER_LINE = 1 << 14,
ARPEGGIO = 1 << 15,
GLISSANDO = 1 << 16,
FRET_DIAGRAM = 1 << 17,
BREATH = 1 << 18,
2014-07-04 18:19:52 +02:00
TREMOLO = 1 << 19,
2014-07-12 16:26:25 +02:00
GRACE_NOTE = 1 << 20,
ALL = -1
};
//---------------------------------------------------------
// SelectionFilter
//---------------------------------------------------------
class SelectionFilter {
Score* _score;
int _filtered;
public:
SelectionFilter() { _score = 0; _filtered = (int)SelectionFilterType::ALL;}
SelectionFilter(SelectionFilterType f) : _score(nullptr), _filtered(int(f)) {}
SelectionFilter(Score* score) { _score = score; _filtered = (int)SelectionFilterType::ALL;}
int& filtered() { return _filtered; }
void setFiltered(SelectionFilterType type, bool set);
2014-07-24 12:06:12 +02:00
bool isFiltered(SelectionFilterType type) const { return _filtered & (int)type; }
bool canSelect(const Element*) const;
2014-08-07 00:30:50 +02:00
bool canSelectVoice(int track) const;
};
2012-08-06 12:15:42 +02:00
//-------------------------------------------------------------------
2012-05-26 14:26:10 +02:00
// Selection
2014-05-26 13:21:04 +02:00
// For SelState::LIST state only visible elements can be selected
2012-08-06 12:15:42 +02:00
// (no Chord element etc.).
//-------------------------------------------------------------------
2012-05-26 14:26:10 +02:00
class Selection {
Score* _score;
SelState _state;
2014-05-26 13:21:04 +02:00
QList<Element*> _el; // valid in mode SelState::LIST
2012-05-26 14:26:10 +02:00
2014-05-26 13:21:04 +02:00
int _staffStart; // valid if selState is SelState::RANGE
2012-05-26 14:26:10 +02:00
int _staffEnd;
Segment* _startSegment;
Segment* _endSegment; // next segment after selection
Fraction _plannedTick1 { -1, 1 }; // Will be actually selected on updateSelectedElements() call.
Fraction _plannedTick2 { -1, 1 }; // Used by setRangeTicks() to restore proper selection after
// command end in case some changes are expected to segments'
// structure (e.g. MMRests reconstruction).
2012-05-26 14:26:10 +02:00
Segment* _activeSegment;
int _activeTrack;
Fraction _currentTick; // tracks the most recent selection
int _currentTrack;
2012-05-26 14:26:10 +02:00
QByteArray staffMimeData() const;
QByteArray symbolListMimeData() const;
SelectionFilter selectionFilter() const;
2014-08-07 00:30:50 +02:00
bool canSelect(Element* e) const { return selectionFilter().canSelect(e); }
bool canSelectVoice(int track) const { return selectionFilter().canSelectVoice(track); }
void appendFiltered(Element* e);
void appendChord(Chord* chord);
2012-05-26 14:26:10 +02:00
public:
2014-05-26 13:21:04 +02:00
Selection() { _score = 0; _state = SelState::NONE; }
2012-05-26 14:26:10 +02:00
Selection(Score*);
Score* score() const { return _score; }
SelState state() const { return _state; }
2014-05-24 12:53:50 +02:00
bool isNone() const { return _state == SelState::NONE; }
bool isRange() const { return _state == SelState::RANGE; }
bool isList() const { return _state == SelState::LIST; }
2012-05-26 14:26:10 +02:00
void setState(SelState s);
const QList<Element*>& elements() const { return _el; }
2016-02-06 22:03:43 +01:00
std::vector<Note*> noteList(int track = -1) const;
2014-05-26 12:10:59 +02:00
const QList<Element*> uniqueElements() const;
QList<Note*> uniqueNotes(int track = -1) const;
2014-05-26 13:21:04 +02:00
bool isSingle() const { return (_state == SelState::LIST) && (_el.size() == 1); }
2014-05-26 12:10:59 +02:00
2012-05-26 14:26:10 +02:00
void add(Element*);
void deselectAll();
void remove(Element*);
void clear();
Element* element() const;
2014-11-22 13:05:23 +01:00
ChordRest* cr() const;
Segment* firstChordRestSegment() const;
2012-05-26 14:26:10 +02:00
ChordRest* firstChordRest(int track = -1) const;
ChordRest* lastChordRest(int track = -1) const;
Measure* findMeasure() const;
2012-05-26 14:26:10 +02:00
void update();
void updateState();
void dump();
QString mimeType() const;
QByteArray mimeData() const;
Segment* startSegment() const { return _startSegment; }
Segment* endSegment() const { return _endSegment; }
void setStartSegment(Segment* s) { _startSegment = s; }
void setEndSegment(Segment* s) { _endSegment = s; }
2014-05-24 22:24:48 +02:00
void setRange(Segment* startSegment, Segment* endSegment, int staffStart, int staffEnd);
void setRangeTicks(const Fraction& tick1, const Fraction& tick2, int staffStart, int staffEnd);
2012-05-26 14:26:10 +02:00
Segment* activeSegment() const { return _activeSegment; }
void setActiveSegment(Segment* s) { _activeSegment = s; }
ChordRest* activeCR() const;
bool isStartActive() const;
bool isEndActive() const;
ChordRest* currentCR() const;
Fraction tickStart() const;
Fraction tickEnd() const;
2012-05-26 14:26:10 +02:00
int staffStart() const { return _staffStart; }
int staffEnd() const { return _staffEnd; }
int activeTrack() const { return _activeTrack; }
void setStaffStart(int v) { _staffStart = v; }
void setStaffEnd(int v) { _staffEnd = v; }
void setActiveTrack(int v) { _activeTrack = v; }
bool canCopy() const;
void updateSelectedElements();
bool measureRange(Measure** m1, Measure** m2) const;
2014-05-31 21:14:25 +02:00
void extendRangeSelection(ChordRest* cr);
void extendRangeSelection(Segment* seg, Segment* segAfter, int staffIdx, const Fraction& tick, const Fraction& etick);
2012-05-26 14:26:10 +02:00
};
2013-05-13 18:49:17 +02:00
} // namespace Ms
2012-05-26 14:26:10 +02:00
#endif