diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
commit | 145364a8af6a1fec06556221e66d4b724a62fc9a (patch) | |
tree | 53bd71a544008c518034f208d64c932dc2883f50 /src/base/Clipboard.cpp | |
download | rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip |
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/base/Clipboard.cpp')
-rw-r--r-- | src/base/Clipboard.cpp | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/src/base/Clipboard.cpp b/src/base/Clipboard.cpp new file mode 100644 index 0000000..71ff03f --- /dev/null +++ b/src/base/Clipboard.cpp @@ -0,0 +1,387 @@ +// -*- c-basic-offset: 4 -*- + +/* + Rosegarden + A sequencer and musical notation editor. + + This program is Copyright 2000-2008 + Guillaume Laurent <[email protected]>, + Chris Cannam <[email protected]>, + Richard Bown <[email protected]> + + 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. +*/ + +#include "Clipboard.h" +#include "Selection.h" + +namespace Rosegarden +{ + +Clipboard::Clipboard() : + m_partial(false), + m_haveTimeSigSelection(false), + m_haveTempoSelection(false), + m_nominalStart(0), + m_nominalEnd(0) +{ + // nothing +} + +Clipboard::Clipboard(const Clipboard &c) : + m_partial(false) +{ + copyFrom(&c); +} + +Clipboard & +Clipboard::operator=(const Clipboard &c) +{ + copyFrom(&c); + return *this; +} + +Clipboard::~Clipboard() +{ + clear(); +} + +void +Clipboard::clear() +{ + for (iterator i = begin(); i != end(); ++i) { + delete *i; + } + m_segments.clear(); + clearTimeSignatureSelection(); + clearTempoSelection(); + clearNominalRange(); + m_partial = false; +} + +bool +Clipboard::isEmpty() const +{ + return (m_segments.size() == 0 && + !m_haveTimeSigSelection && + !m_haveTempoSelection && + m_nominalStart == m_nominalEnd); +} + +bool +Clipboard::isSingleSegment() const +{ + return (m_segments.size() == 1 && + !m_haveTimeSigSelection && + !m_haveTempoSelection); +} + +Segment * +Clipboard::getSingleSegment() const +{ + if (isSingleSegment()) return *begin(); + else return 0; +} + +bool +Clipboard::isPartial() const +{ + return m_partial; +} + +Segment * +Clipboard::newSegment() +{ + Segment *s = new Segment(); + m_segments.insert(s); + // don't change m_partial + return s; +} + +Segment * +Clipboard::newSegment(const Segment *copyFrom) +{ + Segment *s = new Segment(*copyFrom); + m_segments.insert(s); + // don't change m_partial + return s; +} + +void +Clipboard::newSegment(const Segment *copyFrom, timeT from, timeT to, + bool expandRepeats) +{ + // create with copy ctor so as to inherit track, instrument etc + Segment *s = new Segment(*copyFrom); + + if (from <= s->getStartTime() && to >= s->getEndMarkerTime()) { + m_segments.insert(s); + s->setEndTime(s->getEndMarkerTime()); + // don't change m_partial + return; + } + + timeT segStart = copyFrom->getStartTime(); + timeT segEnd = copyFrom->getEndMarkerTime(); + timeT segDuration = segEnd - segStart; + + int firstRepeat = 0; + int lastRepeat = 0; + + if (!copyFrom->isRepeating() || segDuration <= 0) { + expandRepeats = false; + } + + if (expandRepeats) { + firstRepeat = (from - segStart) / segDuration; + lastRepeat = (to - segStart) / segDuration; + to = std::min(to, copyFrom->getRepeatEndTime()); + } + + s->setRepeating(false); + + if (s->getType() == Segment::Audio) { + + Composition *c = copyFrom->getComposition(); + + for (int repeat = firstRepeat; repeat <= lastRepeat; ++repeat) { + + timeT wrappedFrom = segStart; + timeT wrappedTo = segEnd; + + if (!expandRepeats) { + wrappedFrom = from; + wrappedTo = to; + } else { + if (repeat == firstRepeat) { + wrappedFrom = segStart + (from - segStart) % segDuration; + } + if (repeat == lastRepeat) { + wrappedTo = segStart + (to - segStart) % segDuration; + } + } + + if (wrappedFrom > segStart) { + if (c) { + s->setAudioStartTime + (s->getAudioStartTime() + + c->getRealTimeDifference(segStart + repeat * segDuration, + from)); + } + s->setStartTime(from); + } else { + s->setStartTime(segStart + repeat * segDuration); + } + + if (wrappedTo < segEnd) { + s->setEndMarkerTime(to); + if (c) { + s->setAudioEndTime + (s->getAudioStartTime() + + c->getRealTimeDifference(segStart + repeat * segDuration, + to)); + } + } else { + s->setEndMarkerTime(segStart + (repeat + 1) * segDuration); + } + + m_segments.insert(s); + if (repeat < lastRepeat) { + s = new Segment(*copyFrom); + s->setRepeating(false); + } + } + + m_partial = true; + return; + } + + s->erase(s->begin(), s->end()); + + for (int repeat = firstRepeat; repeat <= lastRepeat; ++repeat) { + + Segment::const_iterator ifrom = copyFrom->begin(); + Segment::const_iterator ito = copyFrom->end(); + + if (!expandRepeats) { + ifrom = copyFrom->findTime(from); + ito = copyFrom->findTime(to); + } else { + if (repeat == firstRepeat) { + ifrom = copyFrom->findTime + (segStart + (from - segStart) % segDuration); + } + if (repeat == lastRepeat) { + ito = copyFrom->findTime + (segStart + (to - segStart) % segDuration); + } + } + + for (Segment::const_iterator i = ifrom; + i != ito && copyFrom->isBeforeEndMarker(i); ++i) { + + timeT absTime = (*i)->getAbsoluteTime() + repeat * segDuration; + timeT duration = (*i)->getDuration(); + + Event *e = (*i)->copyMoving(repeat * segDuration); + + if (absTime + duration <= to) { + + s->insert(e); + + } else { + + s->insert(new Event(*e, + e->getAbsoluteTime(), + duration, + e->getSubOrdering(), + e->getNotationAbsoluteTime(), + e->getNotationDuration())); + delete e; + } + } + } + + // need to call getEndMarkerTime() on copyFrom, not on s, because + // its return value may depend on the composition it's in + if (copyFrom->getEndMarkerTime() > to) { + s->setEndMarkerTime(to); + } + + m_segments.insert(s); + m_partial = true; + return; +} + +Segment * +Clipboard::newSegment(const EventSelection *copyFrom) +{ + // create with copy ctor so as to inherit track, instrument etc + Segment *s = new Segment(copyFrom->getSegment()); + s->erase(s->begin(), s->end()); + + const EventSelection::eventcontainer &events(copyFrom->getSegmentEvents()); + for (EventSelection::eventcontainer::const_iterator i = events.begin(); + i != events.end(); ++i) { + s->insert(new Event(**i)); + } + + m_segments.insert(s); + m_partial = true; + return s; +} + +void +Clipboard::setTimeSignatureSelection(const TimeSignatureSelection &ts) +{ + m_timeSigSelection = ts; + m_haveTimeSigSelection = true; +} + +void +Clipboard::clearTimeSignatureSelection() +{ + m_timeSigSelection = TimeSignatureSelection(); + m_haveTimeSigSelection = false; +} + +const TimeSignatureSelection & +Clipboard::getTimeSignatureSelection() const +{ + return m_timeSigSelection; +} + +void +Clipboard::setTempoSelection(const TempoSelection &ts) +{ + m_tempoSelection = ts; + m_haveTempoSelection = true; +} + +void +Clipboard::clearTempoSelection() +{ + m_tempoSelection = TempoSelection(); + m_haveTempoSelection = false; +} + +const TempoSelection & +Clipboard::getTempoSelection() const +{ + return m_tempoSelection; +} + +void +Clipboard::copyFrom(const Clipboard *c) +{ + if (c == this) return; + clear(); + + for (Clipboard::const_iterator i = c->begin(); i != c->end(); ++i) { + newSegment(*i); + } + + m_partial = c->m_partial; + + m_timeSigSelection = c->m_timeSigSelection; + m_haveTimeSigSelection = c->m_haveTimeSigSelection; + + m_tempoSelection = c->m_tempoSelection; + m_haveTempoSelection = c->m_haveTempoSelection; + + m_nominalStart = c->m_nominalStart; + m_nominalEnd = c->m_nominalEnd; +} + +timeT +Clipboard::getBaseTime() const +{ + if (hasNominalRange()) { + return m_nominalStart; + } + + timeT t = 0; + + for (iterator i = begin(); i != end(); ++i) { + if (i == begin() || (*i)->getStartTime() < t) { + t = (*i)->getStartTime(); + } + } + + if (m_haveTimeSigSelection && !m_timeSigSelection.empty()) { + if (m_timeSigSelection.begin()->first < t) { + t = m_timeSigSelection.begin()->first; + } + } + + if (m_haveTempoSelection && !m_tempoSelection.empty()) { + if (m_tempoSelection.begin()->first < t) { + t = m_tempoSelection.begin()->first; + } + } + + return t; +} + +void +Clipboard::setNominalRange(timeT start, timeT end) +{ + m_nominalStart = start; + m_nominalEnd = end; +} + +void +Clipboard::getNominalRange(timeT &start, timeT &end) +{ + start = m_nominalStart; + end = m_nominalEnd; +} + +} |