summaryrefslogtreecommitdiffstats
path: root/src/commands/segment/DeleteTracksCommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands/segment/DeleteTracksCommand.cpp')
-rw-r--r--src/commands/segment/DeleteTracksCommand.cpp161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/commands/segment/DeleteTracksCommand.cpp b/src/commands/segment/DeleteTracksCommand.cpp
new file mode 100644
index 0000000..bad2be0
--- /dev/null
+++ b/src/commands/segment/DeleteTracksCommand.cpp
@@ -0,0 +1,161 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ Rosegarden
+ A MIDI and audio 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 <richard.bown@ferventsoftware.com>
+
+ The moral rights of Guillaume Laurent, Chris Cannam, and Richard
+ Bown to claim authorship of this work have been asserted.
+
+ Other copyrights also apply to some parts of this work. Please
+ see the AUTHORS file and individual file headers for details.
+
+ 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 "DeleteTracksCommand.h"
+
+#include "misc/Debug.h"
+#include "base/Composition.h"
+#include "base/Segment.h"
+#include <qstring.h>
+
+
+namespace Rosegarden
+{
+
+DeleteTracksCommand::DeleteTracksCommand(Composition *composition,
+ std::vector<TrackId> tracks):
+ KNamedCommand(getGlobalName()),
+ m_composition(composition),
+ m_tracks(tracks),
+ m_detached(false)
+{}
+
+DeleteTracksCommand::~DeleteTracksCommand()
+{
+ if (m_detached) {
+ for (unsigned int i = 0; i < m_oldTracks.size(); ++i)
+ delete m_oldTracks[i];
+
+ for (unsigned int i = 0; i < m_oldSegments.size(); ++i)
+ delete m_oldSegments[i];
+
+ m_oldTracks.clear();
+ m_oldSegments.clear();
+ }
+}
+
+void DeleteTracksCommand::execute()
+{
+ Track *track = 0;
+ const Composition::segmentcontainer &segments =
+ m_composition->getSegments();
+
+ //cout << "DeleteTracksCommand::execute()" << endl;
+
+ m_oldSegments.clear();
+ m_oldTracks.clear();
+
+ // Remap positions and track numbers
+ //
+
+ Composition::trackiterator tit;
+ Composition::trackcontainer
+ &tracks = m_composition->getTracks();
+
+ for (unsigned int i = 0; i < m_tracks.size(); ++i) {
+ // detach segments and store tracks somewhere
+ track = m_composition->getTrackById(m_tracks[i]);
+
+ if (track) {
+ // detach all segments for that track
+ //
+ for (Composition::segmentcontainer::const_iterator
+ it = segments.begin();
+ it != segments.end(); ++it) {
+ if ((*it)->getTrack() == m_tracks[i]) {
+ m_oldSegments.push_back(*it);
+ m_composition->detachSegment(*it);
+ }
+ }
+
+ // store old tracks
+ m_oldTracks.push_back(track);
+ if (m_composition->detachTrack(track) == false) {
+ RG_DEBUG << "DeleteTracksCommand::execute - can't detach track" << endl;
+ }
+ }
+ }
+
+ std::vector<Track*>::iterator otIt;
+ for (otIt = m_oldTracks.begin(); otIt != m_oldTracks.end(); ++otIt) {
+ for (tit = tracks.begin(); tit != tracks.end(); ++tit) {
+ if ((*tit).second->getPosition() > (*otIt)->getPosition()) {
+ // If the track we've removed was after the current
+ // track then decrement the track position.
+ //
+ int newPosition = (*tit).second->getPosition() - 1;
+
+ (*tit).second->setPosition(newPosition);
+
+ }
+ }
+ }
+
+ m_detached = true;
+}
+
+void DeleteTracksCommand::unexecute()
+{
+ // Add the tracks and the segments back in
+ //
+
+ // Remap positions and track numbers
+ //
+ Composition::trackcontainer
+ &tracks = m_composition->getTracks();
+ Composition::trackiterator tit;
+
+ std::vector<Track*>::iterator otIt;
+ for (otIt = m_oldTracks.begin(); otIt != m_oldTracks.end(); ++otIt) {
+ // From the back we shuffle out the tracks to allow the new
+ // (old) track some space to come back in.
+ //
+ tit = tracks.end();
+ while (true) {
+ --tit;
+
+ if ((*tit).second->getPosition() >= (*otIt)->getPosition()) {
+ // If the track we're adding has position after the
+ // current track then increment position.
+ //
+ int newPosition = (*tit).second->getPosition() + 1;
+
+ (*tit).second->setPosition(newPosition);
+ }
+
+ if (tit == tracks.begin())
+ break;
+ }
+
+ m_composition->addTrack(*otIt);
+ }
+
+ for (unsigned int i = 0; i < m_oldSegments.size(); ++i)
+ m_composition->addSegment(m_oldSegments[i]);
+
+ m_detached = false;
+}
+
+}