You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
262 lines
7.5 KiB
262 lines
7.5 KiB
/*
|
|
Rosegarden
|
|
A sequencer and musical notation editor.
|
|
|
|
This program is Copyright 2000-2008
|
|
Guillaume Laurent <glaurent@telegraph-road.org>,
|
|
Chris Cannam <cannam@all-day-breakfast.com>,
|
|
Richard Bown <bownie@bownie.com>
|
|
|
|
The moral right of the authors to claim authorship of this work
|
|
has been asserted.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version. See the file
|
|
COPYING included with this distribution for more information.
|
|
*/
|
|
|
|
#ifndef SELECTION_H
|
|
#define SELECTION_H
|
|
|
|
#include <set>
|
|
#include "PropertyName.h"
|
|
#include "Event.h"
|
|
#include "Segment.h"
|
|
#include "NotationTypes.h"
|
|
#include "Composition.h"
|
|
|
|
namespace Rosegarden {
|
|
|
|
/**
|
|
* EventSelection records a (possibly non-contiguous) selection
|
|
* of Events in a single Segment, used for cut'n paste operations.
|
|
* It does not take a copy of those Events, it just remembers
|
|
* which ones they are.
|
|
*/
|
|
|
|
class EventSelection : public SegmentObserver
|
|
{
|
|
public:
|
|
typedef std::multiset<Event*, Event::EventCmp> eventcontainer;
|
|
|
|
/**
|
|
* Construct an empty EventSelection based on the given Segment.
|
|
*/
|
|
EventSelection(Segment &);
|
|
|
|
/**
|
|
* Construct an EventSelection selecting all the events in the
|
|
* given range of the given Segment. Set overlap if you want
|
|
* to include Events overlapping the selection edges.
|
|
*/
|
|
EventSelection(Segment &, timeT beginTime, timeT endTime, bool overlap = false);
|
|
|
|
EventSelection(const EventSelection&);
|
|
|
|
virtual ~EventSelection();
|
|
|
|
/**
|
|
* Add an Event to the selection. The Event should come from
|
|
* the Segment that was passed to the constructor. Will
|
|
* silently drop any event that is already in the selection.
|
|
*/
|
|
void addEvent(Event* e);
|
|
|
|
/**
|
|
* Add all the Events in the given Selection to this one.
|
|
* Will silently drop any events that are already in the
|
|
* selection.
|
|
*/
|
|
void addFromSelection(EventSelection *sel);
|
|
|
|
/**
|
|
* If the given Event is in the selection, take it out.
|
|
*/
|
|
void removeEvent(Event *e);
|
|
|
|
/**
|
|
* Test whether a given Event (in the Segment) is part of
|
|
* this selection.
|
|
*/
|
|
bool contains(Event *e) const;
|
|
|
|
/**
|
|
* Return true if there are any events of the given type in
|
|
* this selection. Slow.
|
|
*/
|
|
bool contains(const std::string &eventType) const;
|
|
|
|
/**
|
|
* Return the time at which the first Event in the selection
|
|
* begins.
|
|
*/
|
|
timeT getStartTime() const { return m_beginTime; }
|
|
|
|
/**
|
|
* Return the time at which the last Event in the selection ends.
|
|
*/
|
|
timeT getEndTime() const { return m_endTime; }
|
|
|
|
/**
|
|
* Return the total duration spanned by the selection.
|
|
*/
|
|
timeT getTotalDuration() const;
|
|
|
|
typedef std::vector<std::pair<Segment::iterator,
|
|
Segment::iterator> > RangeList;
|
|
/**
|
|
* Return a set of ranges spanned by the selection, such that
|
|
* each range covers only events within the selection.
|
|
*/
|
|
RangeList getRanges() const;
|
|
|
|
typedef std::vector<std::pair<timeT, timeT> > RangeTimeList;
|
|
/**
|
|
* Return a set of times spanned by the selection, such that
|
|
* each time range covers only events within the selection.
|
|
*/
|
|
RangeTimeList getRangeTimes() const;
|
|
|
|
/**
|
|
* Return the number of events added to this selection.
|
|
*/
|
|
unsigned int getAddedEvents() const { return m_segmentEvents.size(); }
|
|
|
|
const eventcontainer &getSegmentEvents() const { return m_segmentEvents; }
|
|
eventcontainer &getSegmentEvents() { return m_segmentEvents; }
|
|
|
|
const Segment &getSegment() const { return m_originalSegment; }
|
|
Segment &getSegment() { return m_originalSegment; }
|
|
|
|
// SegmentObserver methods
|
|
virtual void eventAdded(const Segment *, Event *) { }
|
|
virtual void eventRemoved(const Segment *, Event *);
|
|
virtual void endMarkerTimeChanged(const Segment *, bool) { }
|
|
virtual void segmentDeleted(const Segment *);
|
|
|
|
private:
|
|
EventSelection &operator=(const EventSelection &);
|
|
|
|
protected:
|
|
//--------------- Data members ---------------------------------
|
|
|
|
Segment& m_originalSegment;
|
|
|
|
/// pointers to Events in the original Segment
|
|
eventcontainer m_segmentEvents;
|
|
|
|
timeT m_beginTime;
|
|
timeT m_endTime;
|
|
bool m_haveRealStartTime;
|
|
};
|
|
|
|
|
|
/**
|
|
* SegmentSelection is much simpler than EventSelection, we don't
|
|
* need to do much with this really
|
|
*/
|
|
|
|
class SegmentSelection : public std::set<Segment *>
|
|
{
|
|
public:
|
|
bool hasNonAudioSegment() const;
|
|
};
|
|
|
|
|
|
/**
|
|
* A selection that includes (only) time signatures. Unlike
|
|
* EventSelection, this does copy its contents, not just refer to
|
|
* them.
|
|
*/
|
|
class TimeSignatureSelection
|
|
{
|
|
public:
|
|
/**
|
|
* Construct an empty TimeSignatureSelection.
|
|
*/
|
|
TimeSignatureSelection();
|
|
|
|
/**
|
|
* Construct a TimeSignatureSelection containing all the time
|
|
* signatures in the given range of the given Composition.
|
|
*
|
|
* If includeOpeningTimeSig is true, the selection will start with
|
|
* a duplicate of the time signature (if any) that is already in
|
|
* force at beginTime. Otherwise the selection will only start
|
|
* with a time signature at beginTime if there is an explicit
|
|
* signature there in the source composition.
|
|
*/
|
|
TimeSignatureSelection(Composition &, timeT beginTime, timeT endTime,
|
|
bool includeOpeningTimeSig);
|
|
|
|
virtual ~TimeSignatureSelection();
|
|
|
|
/**
|
|
* Add a time signature to the selection.
|
|
*/
|
|
void addTimeSignature(timeT t, TimeSignature timeSig);
|
|
|
|
typedef std::multimap<timeT, TimeSignature> timesigcontainer;
|
|
|
|
const timesigcontainer &getTimeSignatures() const { return m_timeSignatures; }
|
|
timesigcontainer::const_iterator begin() const { return m_timeSignatures.begin(); }
|
|
timesigcontainer::const_iterator end() const { return m_timeSignatures.end(); }
|
|
bool empty() const { return begin() == end(); }
|
|
|
|
protected:
|
|
timesigcontainer m_timeSignatures;
|
|
};
|
|
|
|
|
|
/**
|
|
* A selection that includes (only) tempo changes.
|
|
*/
|
|
|
|
class TempoSelection
|
|
{
|
|
public:
|
|
/**
|
|
* Construct an empty TempoSelection.
|
|
*/
|
|
TempoSelection();
|
|
|
|
/**
|
|
* Construct a TempoSelection containing all the time
|
|
* signatures in the given range of the given Composition.
|
|
*
|
|
* If includeOpeningTempo is true, the selection will start with a
|
|
* duplicate of the tempo (if any) that is already in force at
|
|
* beginTime. Otherwise the selection will only start with a
|
|
* tempo at beginTime if there is an explicit tempo change there
|
|
* in the source composition.
|
|
*/
|
|
TempoSelection(Composition &, timeT beginTime, timeT endTime,
|
|
bool includeOpeningTempo);
|
|
|
|
virtual ~TempoSelection();
|
|
|
|
/**
|
|
* Add a time signature to the selection.
|
|
*/
|
|
void addTempo(timeT t, tempoT tempo, tempoT targetTempo = -1);
|
|
|
|
typedef std::pair<tempoT, tempoT> tempochange;
|
|
typedef std::multimap<timeT, tempochange> tempocontainer;
|
|
|
|
const tempocontainer &getTempos() const { return m_tempos; }
|
|
tempocontainer::const_iterator begin() const { return m_tempos.begin(); }
|
|
tempocontainer::const_iterator end() const { return m_tempos.end(); }
|
|
bool empty() const { return begin() == end(); }
|
|
|
|
protected:
|
|
tempocontainer m_tempos;
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|