summaryrefslogtreecommitdiff
path: root/muse2/muse/song.cpp
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2012-01-03 19:13:48 +0000
committerFlorian Jung <flo@windfisch.org>2012-01-03 19:13:48 +0000
commit7993a73cece885bac45021dd021ac43f6f332040 (patch)
tree2f8296b31efa6d93cb53b8b735519163ec163a84 /muse2/muse/song.cpp
parent845d28b2fba8f2c1d4211aee7beb5ab041315531 (diff)
parent1bc4ba9dfc00b6e7511fbf4765296a2002f83315 (diff)
merged with trunk
added "copy drummap" to duplicate track dialog
Diffstat (limited to 'muse2/muse/song.cpp')
-rw-r--r--muse2/muse/song.cpp189
1 files changed, 182 insertions, 7 deletions
diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp
index 69900bbc..6d7e419e 100644
--- a/muse2/muse/song.cpp
+++ b/muse2/muse/song.cpp
@@ -31,6 +31,7 @@
#include <QMessageBox>
#include <QPoint>
#include <QSignalMapper>
+#include <QString>
#include <QTextStream>
#include <QProcess>
#include <QByteArray>
@@ -56,6 +57,7 @@
#include "sync.h"
#include "midictrl.h"
#include "menutitleitem.h"
+#include "tracks_duplicate.h"
#include "midi.h"
///#include "sig.h"
#include "al/sig.h"
@@ -381,6 +383,168 @@ Track* Song::addTrack(Undo& operations, Track::TrackType type, Track* insertAt)
}
//---------------------------------------------------------
+// duplicateTracks
+// Called from GUI context
+//---------------------------------------------------------
+
+void Song::duplicateTracks()
+{
+ // Make a temporary copy.
+ TrackList tl = _tracks;
+
+ int audio_found = 0;
+ int midi_found = 0;
+ int drum_found = 0;
+ int new_drum_found = 0;
+ for(iTrack it = tl.begin(); it != tl.end(); ++it)
+ if((*it)->selected())
+ {
+ Track::TrackType type = (*it)->type();
+ // TODO: Handle synths. p4.0.47
+ if(type == Track::AUDIO_SOFTSYNTH)
+ continue;
+
+ if(type == Track::DRUM)
+ ++drum_found;
+ else if(type == Track::NEW_DRUM)
+ ++new_drum_found;
+ else if(type == Track::MIDI)
+ ++midi_found;
+ else
+ ++audio_found;
+ }
+
+ if(audio_found == 0 && midi_found == 0 && drum_found == 0 && new_drum_found==0)
+ return;
+
+
+ MusEGui::DuplicateTracksDialog* dlg = new MusEGui::DuplicateTracksDialog(audio_found, midi_found, drum_found, new_drum_found);
+
+ int rv = dlg->exec();
+ if(rv == QDialog::Rejected)
+ {
+ delete dlg;
+ return;
+ }
+
+ int copies = dlg->copies();
+
+ int flags = Track::ASSIGN_PROPERTIES;
+ if(dlg->copyStdCtrls())
+ flags |= Track::ASSIGN_STD_CTRLS;
+ if(dlg->copyPlugins())
+ flags |= Track::ASSIGN_PLUGINS;
+ if(dlg->copyPluginCtrls())
+ flags |= Track::ASSIGN_PLUGIN_CTRLS;
+ if(dlg->allRoutes())
+ flags |= Track::ASSIGN_ROUTES;
+ if(dlg->defaultRoutes())
+ flags |= Track::ASSIGN_DEFAULT_ROUTES;
+ if(dlg->copyParts())
+ flags |= Track::ASSIGN_PARTS;
+ if(dlg->copyDrumlist())
+ flags |= Track::ASSIGN_DRUMLIST;
+
+ delete dlg;
+
+ QString track_name;
+ int idx;
+ int trackno = tl.size();
+ MusEGlobal::song->startUndo();
+ for(TrackList::reverse_iterator it = tl.rbegin(); it != tl.rend(); ++it)
+ {
+ Track* track = *it;
+ if(track->selected())
+ {
+ track_name = track->name();
+
+ for(int cp = 0; cp < copies; ++cp)
+ {
+ // There are two ways to copy a track now. Using the copy constructor or using new + assign().
+ // Tested: Both ways seem OK. Prefer copy constructors for simplicity. But new + assign() may be
+ // required for fine-grained control over initializing various track types.
+ //
+
+ // Set to 0 to use the copy constructor. Set to 1 to use new + assign().
+ #if 0
+
+ Track* new_track = 0;
+ int lastAuxIdx = _auxs.size();
+ switch(track->type())
+ {
+ case Track::AUDIO_SOFTSYNTH: // TODO: Handle synths. p4.0.47
+ // ((AudioTrack*)new_track)->addAuxSend(lastAuxIdx);
+ break;
+
+ case Track::MIDI:
+ new_track = new MidiTrack();
+ new_track->setType(Track::MIDI);
+ break;
+ case Track::DRUM:
+ new_track = new MidiTrack();
+ new_track->setType(Track::DRUM);
+ //((MidiTrack*)new_track)->setOutChannel(9);
+ break;
+ case Track::WAVE:
+ new_track = new MusECore::WaveTrack();
+ //((AudioTrack*)new_track)->addAuxSend(lastAuxIdx);
+ break;
+ case Track::AUDIO_OUTPUT:
+ new_track = new AudioOutput();
+ break;
+ case Track::AUDIO_GROUP:
+ new_track = new AudioGroup();
+ //((AudioTrack*)new_track)->addAuxSend(lastAuxIdx);
+ break;
+ case Track::AUDIO_AUX:
+ new_track = new AudioAux();
+ break;
+ case Track::AUDIO_INPUT:
+ new_track = new AudioInput();
+ //((AudioTrack*)new_track)->addAuxSend(lastAuxIdx);
+ break;
+ default:
+ printf("Song::duplicateTracks: Illegal type %d\n", track->type());
+ break;
+ }
+
+ if(new_track)
+ {
+ new_track->assign(*track, flags);
+ #else
+ if(track->type() != Track::AUDIO_SOFTSYNTH) // TODO: Handle synths. p4.0.47
+ {
+ Track* new_track = track->clone(flags);
+ #endif
+
+ //new_track->setDefaultName(track_name); // Handled in class now.
+
+ idx = trackno + cp;
+ insertTrack1(new_track, idx);
+ addUndo(MusECore::UndoOp(MusECore::UndoOp::AddTrack, idx, new_track));
+ msgInsertTrack(new_track, idx, false); // No undo.
+ insertTrack3(new_track, idx);
+ }
+ }
+ }
+ --trackno;
+ }
+
+ int update_flags = SC_TRACK_INSERTED;
+ if(flags & (Track::ASSIGN_ROUTES | Track::ASSIGN_DEFAULT_ROUTES))
+ update_flags |= SC_ROUTE;
+ MusEGlobal::song->endUndo(update_flags);
+ MusEGlobal::audio->msgUpdateSoloStates();
+
+ //if (t->isVisible())
+ //{
+ ////deselectTracks();
+ //t->setSelected(true);
+ ////update(SC_SELECTION);
+ //}
+}
+
+//---------------------------------------------------------
// cmdRemoveTrack
//---------------------------------------------------------
@@ -421,6 +585,7 @@ void Song::deselectTracks()
(*t)->setSelected(false);
}
+/*
//---------------------------------------------------------
// changeTrack
// oldTrack - copy of the original track befor modification
@@ -436,7 +601,8 @@ void Song::changeTrack(Track* oldTrack, Track* newTrack)
addUndo(UndoOp(UndoOp::ModifyTrack, idx, oldTrack, newTrack));
updateFlags |= SC_TRACK_MODIFIED;
}
-
+*/
+
//---------------------------------------------------------
// addEvent
// return true if event was added
@@ -1702,7 +1868,8 @@ void Song::rescanAlsaPorts()
void Song::endMsgCmd()
{
if (updateFlags) {
- redoList->clear(); // TODO: delete elements in list
+ //redoList->clear(); // TODO: delete elements in list
+ redoList->clearDelete(); // p4.0.46 Tim. NOTE Hm, shouldn't this be above?
MusEGlobal::undoAction->setEnabled(true);
MusEGlobal::redoAction->setEnabled(false);
emit songChanged(updateFlags);
@@ -1823,9 +1990,9 @@ void Song::processMsg(AudioMsg* msg)
//removeTrack2(msg->track);
cmdRemoveTrack(msg->track);
break;
- case SEQM_CHANGE_TRACK:
- changeTrack((Track*)(msg->p1), (Track*)(msg->p2));
- break;
+ //case SEQM_CHANGE_TRACK:
+ // changeTrack((Track*)(msg->p1), (Track*)(msg->p2));
+ // break;
case SEQM_ADD_PART:
cmdAddPart((Part*)msg->p1);
break;
@@ -2039,8 +2206,15 @@ void Song::clear(bool signal, bool clear_all)
MusEGlobal::tempomap.clear();
AL::sigmap.clear();
MusEGlobal::keymap.clear();
+
undoList->clearDelete();
- redoList->clear();
+ //redoList->clear(); // Check this - Should we do a clearDelete? IIRC it was OK this way - no clearDelete in case of same items in both lists.
+ redoList->clearDelete(); // p4.0.46 Tim
+ if(MusEGlobal::undoAction)
+ MusEGlobal::undoAction->setEnabled(false); //
+ if(MusEGlobal::redoAction)
+ MusEGlobal::redoAction->setEnabled(false); //
+
_markerList->clear();
pos[0].setTick(0);
pos[1].setTick(0);
@@ -2131,7 +2305,8 @@ void Song::cleanupForQuit()
if(MusEGlobal::debugMsg)
printf("deleting undoList, clearing redoList\n");
undoList->clearDelete();
- redoList->clear(); // Check this - Should we do a clearDelete? IIRC it was OK this way - no clearDelete in case of same items in both lists.
+ //redoList->clear(); // Check this - Should we do a clearDelete? IIRC it was OK this way - no clearDelete in case of same items in both lists.
+ redoList->clearDelete(); // p4.0.46 Tim
_markerList->clear();