summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse2/ChangeLog2
-rw-r--r--muse2/awl/posedit.cpp2
-rw-r--r--muse2/muse/CMakeLists.txt1
-rw-r--r--muse2/muse/app.cpp280
-rw-r--r--muse2/muse/app.h5
-rw-r--r--muse2/muse/marker/marker.h2
-rw-r--r--muse2/muse/master/lmaster.cpp4
-rw-r--r--muse2/muse/part.h1
-rw-r--r--muse2/muse/song.cpp160
-rw-r--r--muse2/muse/song.h4
-rw-r--r--muse2/muse/songfile.cpp3
-rw-r--r--muse2/muse/structure.cpp368
-rw-r--r--muse2/muse/undo.cpp30
-rw-r--r--muse2/muse/widgets/songinfo.ui7
14 files changed, 524 insertions, 345 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog
index ab11a07b..291bcd6f 100644
--- a/muse2/ChangeLog
+++ b/muse2/ChangeLog
@@ -1,5 +1,7 @@
08.05.2011:
- Draw event canvas notes if they extend past part end. (Tim)
+ - Added checkbox to select if songinfo should be displayed on song start (rj)
+ - fixups to structure functions, now inserts/cuts markers, and master track events with undo (rj)
06.05.2011:
- MusE 2.0beta2 released (rj)
- Added Yamaha-CS1x.idf instrument from Ernie Rymer <ethylene77 A T yahoo D O T com> Thanks! (Tim)
diff --git a/muse2/awl/posedit.cpp b/muse2/awl/posedit.cpp
index e9cddd44..6ca49566 100644
--- a/muse2/awl/posedit.cpp
+++ b/muse2/awl/posedit.cpp
@@ -433,6 +433,8 @@ QValidator::State PosEdit::validate(QString& s,int& /*i*/) const
int tb = AL::sigmap.ticksBeat(_pos.tick());
unsigned tm = AL::sigmap.ticksMeasure(_pos.tick());
+ if (tm==0)
+ return QValidator::Invalid;
int bm = tm / tb;
validator->setRange(1, 9999);
diff --git a/muse2/muse/CMakeLists.txt b/muse2/muse/CMakeLists.txt
index 2d2a9fe3..d89bb007 100644
--- a/muse2/muse/CMakeLists.txt
+++ b/muse2/muse/CMakeLists.txt
@@ -120,6 +120,7 @@ file (GLOB core_source_files
song.cpp
songfile.cpp
stringparam.cpp
+ structure.cpp
sync.cpp
synth.cpp
tempo.cpp
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index 052bb48b..59993911 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -974,10 +974,10 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
editCopyAction = new QAction(QIcon(*editcopyIconSet), tr("&Copy"), this);
editPasteAction = new QAction(QIcon(*editpasteIconSet), tr("&Paste"), this);
editInsertAction = new QAction(QIcon(*editpasteIconSet), tr("&Insert"), this);
+ editInsertEMAction = new QAction(QIcon(*editpasteIconSet), tr("&Insert Empty Measure"), this);
editPasteCloneAction = new QAction(QIcon(*editpasteCloneIconSet), tr("Paste c&lone"), this);
editPaste2TrackAction = new QAction(QIcon(*editpaste2TrackIconSet), tr("Paste to &track"), this);
editPasteC2TAction = new QAction(QIcon(*editpasteClone2TrackIconSet), tr("Paste clone to trac&k"), this);
- editInsertEMAction = new QAction(QIcon(*editpasteIconSet), tr("&Insert Empty Measure"), this);
editDeleteSelectedAction = new QAction(QIcon(*edit_track_delIcon), tr("Delete Selected Tracks"), this);
@@ -1123,10 +1123,10 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
connect(editCopyAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
connect(editPasteAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
connect(editInsertAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
+ connect(editInsertEMAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
connect(editPasteCloneAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
connect(editPaste2TrackAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
connect(editPasteC2TAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
- connect(editInsertEMAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
connect(editDeleteSelectedAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
connect(editSelectAllAction, SIGNAL(triggered()), editSignalMapper, SLOT(map()));
@@ -1183,7 +1183,7 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
connect(strGlobalCutAction, SIGNAL(activated()), SLOT(globalCut()));
connect(strGlobalInsertAction, SIGNAL(activated()), SLOT(globalInsert()));
connect(strGlobalSplitAction, SIGNAL(activated()), SLOT(globalSplit()));
- connect(strCopyRangeAction, SIGNAL(activated()), SLOT(copyRange()));
+ connect(strCopyRangeAction, SIGNAL(activated()), SLOT(copyRange()));
connect(strCutEventsAction, SIGNAL(activated()), SLOT(cutEvents()));
//-------- Midi connections
@@ -1357,10 +1357,10 @@ MusE::MusE(int argc, char** argv) : QMainWindow()
menuEdit->addAction(editCopyAction);
menuEdit->addAction(editPasteAction);
menuEdit->addAction(editInsertAction);
+ menuEdit->addAction(editInsertEMAction);
menuEdit->addAction(editPasteCloneAction);
menuEdit->addAction(editPaste2TrackAction);
menuEdit->addAction(editPasteC2TAction);
- menuEdit->addAction(editInsertEMAction);
menuEdit->addSeparator();
menuEdit->addAction(editDeleteSelectedAction);
@@ -1738,14 +1738,16 @@ void MusE::loadProjectFile(const QString& name, bool songTemplate, bool loadAll)
if (restartSequencer)
seqStart();
- if (song->getSongInfo().length()>0)
- startSongInfo(false);
-
visTracks->updateVisibleTracksButtons();
progress->setValue(100);
delete progress;
progress=0;
+
QApplication::restoreOverrideCursor();
+
+ if (song->getSongInfo().length()>0 && song->showSongInfoOnStartup()) {
+ startSongInfo(false);
+ }
}
//---------------------------------------------------------
@@ -3378,7 +3380,7 @@ bool MusE::saveAs()
return false;
}
- song->setSongInfo(pci.getSongInfo());
+ song->setSongInfo(pci.getSongInfo(), true);
name = pci.getProjectPath();
} else {
name = getSaveFileName(QString(""), med_file_save_pattern, this, tr("MusE: Save As"));
@@ -3670,12 +3672,16 @@ void MusE::startWaveEditor(PartList* pl)
void MusE::startSongInfo(bool editable)
{
SongInfoWidget info;
+ info.viewCheckBox->setChecked(song->showSongInfoOnStartup());
+ info.viewCheckBox->setEnabled(editable);
info.songInfoText->setPlainText(song->getSongInfo());
info.songInfoText->setReadOnly(!editable);
+ info.setModal(true);
info.show();
if( info.exec() == QDialog::Accepted) {
- if (editable)
- song->setSongInfo(info.songInfoText->toPlainText());
+ if (editable) {
+ song->setSongInfo(info.songInfoText->toPlainText(), info.viewCheckBox->isChecked());
+ }
}
}
@@ -3691,7 +3697,7 @@ void MusE::showDidYouKnowDialog()
dyk.show();
if( dyk.exec()) {
if (dyk.dontShowCheckBox->isChecked()) {
- printf("disables dialog!\n");
+ //printf("disables dialog!\n");
config.showDidYouKnow=false;
muse->changeConfig(true); // save settings
}
@@ -4389,256 +4395,6 @@ void MusE::configShortCuts()
changeConfig(true);
}
-//---------------------------------------------------------
-// globalCut
-// - remove area between left and right locator
-// - do not touch muted track
-// - cut master track
-//---------------------------------------------------------
-
-void MusE::globalCut()
- {
- int lpos = song->lpos();
- int rpos = song->rpos();
- if ((lpos - rpos) >= 0)
- return;
-
- song->startUndo();
- TrackList* tracks = song->tracks();
- for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
- MidiTrack* track = dynamic_cast<MidiTrack*>(*it);
- if (track == 0 || track->mute())
- continue;
- PartList* pl = track->parts();
- for (iPart p = pl->begin(); p != pl->end(); ++p) {
- Part* part = p->second;
- int t = part->tick();
- int l = part->lenTick();
- if (t + l <= lpos)
- continue;
- if ((t >= lpos) && ((t+l) <= rpos)) {
- audio->msgRemovePart(part, false);
- }
- else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) {
- // remove part tail
- int len = lpos - t;
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- nPart->setLenTick(len);
- //
- // cut Events in nPart
- EventList* el = nPart->events();
- iEvent ie = el->lower_bound(t + len);
- for (; ie != el->end();) {
- iEvent i = ie;
- ++ie;
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(i->second, nPart, false);
- audio->msgDeleteEvent(i->second, nPart, false, false, false);
- }
- // Indicate no undo, and do port controller values and clone parts.
- //audio->msgChangePart(part, nPart, false);
- audio->msgChangePart(part, nPart, false, true, true);
- }
- else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) {
- //----------------------
- // remove part middle
- //----------------------
-
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- EventList* el = nPart->events();
- iEvent is = el->lower_bound(lpos);
- iEvent ie = el->upper_bound(rpos);
- for (iEvent i = is; i != ie;) {
- iEvent ii = i;
- ++i;
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ii->second, nPart, false);
- audio->msgDeleteEvent(ii->second, nPart, false, false, false);
- }
-
- ie = el->lower_bound(rpos);
- for (; ie != el->end();) {
- iEvent i = ie;
- ++ie;
- Event event = i->second;
- Event nEvent = event.clone();
- nEvent.setTick(nEvent.tick() - (rpos-lpos));
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, nEvent, nPart, false);
- audio->msgChangeEvent(event, nEvent, nPart, false, false, false);
- }
- nPart->setLenTick(l - (rpos-lpos));
- // Indicate no undo, and do port controller values and clone parts.
- //audio->msgChangePart(part, nPart, false);
- audio->msgChangePart(part, nPart, false, true, true);
- }
- else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) {
- // TODO: remove part head
- }
- else if (t >= rpos) {
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- int nt = part->tick();
- nPart->setTick(nt - (rpos -lpos));
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgChangePart(part, nPart, false);
- audio->msgChangePart(part, nPart, false, true, false);
- }
- }
- }
- // TODO: cut tempo track
- // TODO: process marker
- song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_REMOVED);
- }
-
-//---------------------------------------------------------
-// globalInsert
-// - insert empty space at left locator position upto
-// right locator
-// - do not touch muted track
-// - insert in master track
-//---------------------------------------------------------
-
-void MusE::globalInsert()
- {
- unsigned lpos = song->lpos();
- unsigned rpos = song->rpos();
- if (lpos >= rpos)
- return;
-
- song->startUndo();
- TrackList* tracks = song->tracks();
- for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
- MidiTrack* track = dynamic_cast<MidiTrack*>(*it);
- //
- // process only non muted midi tracks
- //
- if (track == 0 || track->mute())
- continue;
- PartList* pl = track->parts();
- for (iPart p = pl->begin(); p != pl->end(); ++p) {
- Part* part = p->second;
- unsigned t = part->tick();
- int l = part->lenTick();
- if (t + l <= lpos)
- continue;
- if (lpos >= t && lpos < (t+l)) {
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- nPart->setLenTick(l + (rpos-lpos));
- EventList* el = nPart->events();
-
- iEvent i = el->end();
- while (i != el->begin()) {
- --i;
- if (i->first < lpos)
- break;
- Event event = i->second;
- Event nEvent = i->second.clone();
- nEvent.setTick(nEvent.tick() + (rpos-lpos));
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, nEvent, nPart, false);
- audio->msgChangeEvent(event, nEvent, nPart, false, false, false);
- }
- // Indicate no undo, and do port controller values and clone parts.
- //audio->msgChangePart(part, nPart, false);
- audio->msgChangePart(part, nPart, false, true, true);
- }
- else if (t > lpos) {
- MidiPart* nPart = new MidiPart(*(MidiPart*)part);
- nPart->setTick(t + (rpos -lpos));
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgChangePart(part, nPart, false);
- audio->msgChangePart(part, nPart, false, true, false);
- }
- }
- }
- // TODO: process tempo track
- // TODO: process marker
- song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_REMOVED);
- }
-
-//---------------------------------------------------------
-// globalSplit
-// - split all parts at the song position pointer
-// - do not touch muted track
-//---------------------------------------------------------
-
-void MusE::globalSplit()
- {
- int pos = song->cpos();
- song->startUndo();
- TrackList* tracks = song->tracks();
- for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
- Track* track = *it;
- PartList* pl = track->parts();
- for (iPart p = pl->begin(); p != pl->end(); ++p) {
- Part* part = p->second;
- int p1 = part->tick();
- int l0 = part->lenTick();
- if (pos > p1 && pos < (p1+l0)) {
- Part* p1;
- Part* p2;
- track->splitPart(part, pos, p1, p2);
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgChangePart(part, p1, false);
- audio->msgChangePart(part, p1, false, true, false);
- audio->msgAddPart(p2, false);
- break;
- }
- }
- }
- song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED);
- }
-
-//---------------------------------------------------------
-// copyRange
-// - copy space between left and right locator position
-// to song position pointer
-// - dont process muted tracks
-// - create a new part for every track containing the
-// copied events
-//---------------------------------------------------------
-
-void MusE::copyRange()
- {
- QMessageBox::critical(this,
- tr("MusE: Copy Range"),
- tr("not implemented")
- );
- }
-
-//---------------------------------------------------------
-// cutEvents
-// - make sure that all events in a part end where the
-// part ends
-// - process only marked parts
-//---------------------------------------------------------
-
-void MusE::cutEvents()
- {
- QMessageBox::critical(this,
- tr("MusE: Cut Events"),
- tr("not implemented")
- );
- }
-
-//---------------------------------------------------------
-// checkRegionNotNull
-// return true if (rPos - lPos) <= 0
-//---------------------------------------------------------
-
-bool MusE::checkRegionNotNull()
- {
- int start = song->lPos().frame();
- int end = song->rPos().frame();
- if (end - start <= 0) {
- QMessageBox::critical(this,
- tr("MusE: Bounce"),
- tr("set left/right marker for bounce range")
- );
- return true;
- }
- return false;
- }
#if 0
//---------------------------------------------------------
@@ -5050,10 +4806,10 @@ void MusE::updateConfiguration()
editCopyAction->setShortcut(shortcuts[SHRT_COPY].key);
editPasteAction->setShortcut(shortcuts[SHRT_PASTE].key);
editInsertAction->setShortcut(shortcuts[SHRT_INSERT].key);
+ editInsertEMAction->setShortcut(shortcuts[SHRT_INSERTMEAS].key);
editPasteCloneAction->setShortcut(shortcuts[SHRT_PASTE_CLONE].key);
editPaste2TrackAction->setShortcut(shortcuts[SHRT_PASTE_TO_TRACK].key);
editPasteC2TAction->setShortcut(shortcuts[SHRT_PASTE_CLONE_TO_TRACK].key);
- editInsertEMAction->setShortcut(shortcuts[SHRT_INSERTMEAS].key);
//editDeleteSelectedAction has no acceleration
diff --git a/muse2/muse/app.h b/muse2/muse/app.h
index 2fd83854..42aebf3b 100644
--- a/muse2/muse/app.h
+++ b/muse2/muse/app.h
@@ -108,7 +108,7 @@ class MusE : public QMainWindow
// Edit Menu actions
QAction *editCutAction, *editCopyAction, *editPasteAction, *editInsertAction, *editPasteCloneAction, *editPaste2TrackAction;
- QAction *editPasteC2TAction, *editInsertEMAction, *editDeleteSelectedAction, *editSelectAllAction, *editDeselectAllAction;
+ QAction *editInsertEMAction, *editPasteC2TAction, *editDeleteSelectedAction, *editSelectAllAction, *editDeselectAllAction;
QAction *editInvertSelectionAction, *editInsideLoopAction, *editOutsideLoopAction, *editAllPartsAction;
QAction *trackMidiAction, *trackDrumAction, *trackWaveAction, *trackAOutputAction, *trackAGroupAction;
QAction *trackAInputAction, *trackAAuxAction;
@@ -334,6 +334,9 @@ class MusE : public QMainWindow
void execDeliveredScript(int);
void execUserScript(int);
+ private:
+ void adjustGlobalLists(int startPos, int diff);
+
public slots:
bool saveAs();
diff --git a/muse2/muse/marker/marker.h b/muse2/muse/marker/marker.h
index f1a587f7..012cce80 100644
--- a/muse2/muse/marker/marker.h
+++ b/muse2/muse/marker/marker.h
@@ -24,7 +24,7 @@ class Marker : public Pos {
bool _current;
public:
- Marker() : _current(false) {}
+ Marker() : _name(""),_current(false) {}
Marker(const QString& s, bool cur = false)
: _name(s), _current(cur) {}
void read(Xml&);
diff --git a/muse2/muse/master/lmaster.cpp b/muse2/muse/master/lmaster.cpp
index 21cadfdd..2f921cdc 100644
--- a/muse2/muse/master/lmaster.cpp
+++ b/muse2/muse/master/lmaster.cpp
@@ -207,13 +207,17 @@ LMaster::LMaster()
updateList();
tempo_editor = new QLineEdit(view->viewport());
+ tempo_editor->hide();
connect(tempo_editor, SIGNAL(returnPressed()), SLOT(returnPressed()));
sig_editor = new SigEdit(view->viewport());
+ sig_editor->hide();
connect(sig_editor, SIGNAL(returnPressed()), SLOT(returnPressed()));
pos_editor = new Awl::PosEdit(view->viewport());
+ pos_editor->hide();
connect(pos_editor, SIGNAL(returnPressed()), SLOT(returnPressed()));
key_editor = new QComboBox(view->viewport());
key_editor->addItems(keyStrs);
+ key_editor->hide();
connect(key_editor, SIGNAL(currentIndexChanged(int)), SLOT(returnPressed()));
connect(view, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), SLOT(select(QTreeWidgetItem*, QTreeWidgetItem*)));
diff --git a/muse2/muse/part.h b/muse2/muse/part.h
index 11ff2fd4..f7a864e5 100644
--- a/muse2/muse/part.h
+++ b/muse2/muse/part.h
@@ -143,6 +143,7 @@ class WavePart : public Part {
//---------------------------------------------------------
typedef std::multimap<int, Part*, std::less<unsigned> >::iterator iPart;
+typedef std::multimap<int, Part*, std::less<unsigned> >::reverse_iterator riPart;
typedef std::multimap<int, Part*, std::less<unsigned> >::const_iterator ciPart;
class PartList : public std::multimap<int, Part*, std::less<unsigned> > {
diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp
index cf040348..e6fa9cab 100644
--- a/muse2/muse/song.cpp
+++ b/muse2/muse/song.cpp
@@ -17,6 +17,8 @@
#include <QPoint>
#include <QSignalMapper>
#include <QTextStream>
+#include <QProcess>
+#include <QByteArray>
#include "app.h"
#include "driver/jackmidi.h"
@@ -85,6 +87,7 @@ Song::Song(const char* name)
redoList = new UndoList;
_markerList = new MarkerList;
_globalPitchShift = 0;
+ showSongInfo=true;
clear(false);
}
@@ -1767,6 +1770,24 @@ Marker* Song::setMarkerLock(Marker* m, bool f)
return m;
}
+// kommer inte att gå göra undo på, kanske skulle fixa det.
+
+//void Song::moveMarkers(int startOffset, int ticks)
+//{
+// iMarker markerI;
+// for (markerI=_markerList->rbegin(); markerI != _markerList->rend(); ++markerI) {
+// if (markerI->second.tick() > startOffset) {
+// if (markerI-> )
+// }
+//
+//
+//
+// if (unsigned(t) == markerI->second.tick())//prevent of copmiler warning: comparison signed/unsigned
+// return &markerI->second;
+// }
+//
+//}
+
//---------------------------------------------------------
// setRecordFlag
//---------------------------------------------------------
@@ -3696,79 +3717,74 @@ void Song::executeScript(const char* scriptfile, PartList* parts, int quant, boo
}
fclose(fp);
- // Call external program, let it manipulate the file
- int pid = fork();
- if (pid == 0) {
- if (execlp(scriptfile, scriptfile, tmp, NULL) == -1) {
- perror("Failed to launch script!");
- // Get out of here
-
- // cannot report error through gui, we are in another fork!
- //@!TODO: Handle unsuccessful attempts
- exit(99);
- }
- exit(0);
- }
- else if (pid == -1) {
- perror("fork failed");
- }
- else {
- int status;
- waitpid(pid, &status, 0);
- if (WEXITSTATUS(status) != 0 ) {
- QMessageBox::warning(muse, tr("MusE - external script failed"),
- tr("MusE was unable to launch the script\n")
- );
- endUndo(SC_EVENT_REMOVED);
- return;
- }
- else { // d0 the fun55or5!
- // TODO: Create a new part, update the entire editor from it, hehh....
-
- QFile file(tmp);
- if ( file.open( QIODevice::ReadOnly ) ) {
- QTextStream stream( &file );
- QString line;
- while ( !stream.atEnd() ) {
- line = stream.readLine(); // line of text excluding '\n'
- if (line.startsWith("NOTE"))
- {
- QStringList sl = line.split(" ");
-
- Event e(Note);
- int tick = sl[1].toInt();
- int pitch = sl[2].toInt();
- int len = sl[3].toInt();
- int velo = sl[4].toInt();
- printf ("tick=%d pitch=%d velo=%d len=%d\n", tick,pitch,velo,len);
- e.setTick(tick);
- e.setPitch(pitch);
- e.setVelo(velo);
- e.setLenTick(len);
- // Indicate no undo, and do not do port controller values and clone parts.
- audio->msgAddEvent(e, part, false, false, false);
- }
- if (line.startsWith("CONTROLLER"))
- {
- QStringList sl = line.split(" ");
-
- Event e(Controller);
- int tick = sl[1].toInt();
- int a = sl[2].toInt();
- int b = sl[3].toInt();
- int c = sl[4].toInt();
- printf ("tick=%d a=%d b=%d c=%d\n", tick,a,b,c);
- e.setA(a);
- e.setB(b);
- e.setB(c);
- // Indicate no undo, and do not do port controller values and clone parts.
- audio->msgAddEvent(e, part, false, false, false);
- }
- }
- file.close();
- }
- }
+// QString program(scriptfile);
+ QStringList arguments;
+ arguments << tmp;
+
+ QProcess *myProcess = new QProcess(muse);
+ myProcess->start(scriptfile, arguments);
+ myProcess->waitForFinished();
+ QByteArray errStr = myProcess->readAllStandardError();
+ if (errStr.size()) {
+ QMessageBox::warning(muse, tr("MusE - external script failed"),
+ "Script returned the following error\n"+ QString(errStr));
+ endUndo(SC_EVENT_REMOVED);
+ return;
+
+ } else if (myProcess->exitCode()) {
+ QMessageBox::warning(muse, tr("MusE - external script failed"),
+ tr("MusE was unable to launch the script\n")
+ );
+ endUndo(SC_EVENT_REMOVED);
+ return;
}
+ else { // d0 the fun55or5!
+ // TODO: Create a new part, update the entire editor from it, hehh....
+
+ QFile file(tmp);
+ if ( file.open( QIODevice::ReadOnly ) ) {
+ QTextStream stream( &file );
+ QString line;
+ while ( !stream.atEnd() ) {
+ line = stream.readLine(); // line of text excluding '\n'
+ if (line.startsWith("NOTE"))
+ {
+ QStringList sl = line.split(" ");
+
+ Event e(Note);
+ int tick = sl[1].toInt();
+ int pitch = sl[2].toInt();
+ int len = sl[3].toInt();
+ int velo = sl[4].toInt();
+ //printf ("tick=%d pitch=%d velo=%d len=%d\n", tick,pitch,velo,len);
+ e.setTick(tick);
+ e.setPitch(pitch);
+ e.setVelo(velo);
+ e.setLenTick(len);
+ // Indicate no undo, and do not do port controller values and clone parts.
+ audio->msgAddEvent(e, part, false, false, false);
+ }
+ if (line.startsWith("CONTROLLER"))
+ {
+ QStringList sl = line.split(" ");
+
+ Event e(Controller);
+ int tick = sl[1].toInt();
+ int a = sl[2].toInt();
+ int b = sl[3].toInt();
+ int c = sl[4].toInt();
+ //printf ("tick=%d a=%d b=%d c=%d\n", tick,a,b,c);
+ e.setA(a);
+ e.setB(b);
+ e.setB(c);
+ // Indicate no undo, and do not do port controller values and clone parts.
+ audio->msgAddEvent(e, part, false, false, false);
+ }
+ }
+ file.close();
+ }
+ }
+
remove(tmp);
}
diff --git a/muse2/muse/song.h b/muse2/muse/song.h
index b097a5ee..e1378480 100644
--- a/muse2/muse/song.h
+++ b/muse2/muse/song.h
@@ -139,6 +139,7 @@ class Song : public QObject {
void readMarker(Xml&);
QString songInfoStr; // contains user supplied song information, stored in song file.
+ bool showSongInfo;
QStringList deliveredScriptNames;
QStringList userScriptNames;
@@ -167,7 +168,8 @@ class Song : public QObject {
const QFont& font) const;
QFont readFont(Xml& xml, const char* name);
QString getSongInfo() { return songInfoStr; }
- void setSongInfo(QString info) { songInfoStr = info; }
+ void setSongInfo(QString info, bool show) { songInfoStr = info; showSongInfo = show; }
+ bool showSongInfoOnStartup() { return showSongInfo; }
// If clear_all is false, it will not touch things like midi ports.
void clear(bool signal, bool clear_all = true);
diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp
index 9a577308..a8134b1d 100644
--- a/muse2/muse/songfile.cpp
+++ b/muse2/muse/songfile.cpp
@@ -1232,6 +1232,8 @@ void Song::read(Xml& xml)
setMasterFlag(xml.parseInt());
else if (tag == "info")
songInfoStr = xml.parse1();
+ else if (tag == "showinfo")
+ showSongInfo = xml.parseInt();
else if (tag == "loop")
setLoop(xml.parseInt());
else if (tag == "punchin")
@@ -1437,6 +1439,7 @@ void Song::write(int level, Xml& xml) const
{
xml.tag(level++, "song");
xml.strTag(level, "info", songInfoStr);
+ xml.intTag(level, "showinfo", showSongInfo);
xml.intTag(level, "automation", automation);
xml.intTag(level, "cpos", song->cpos());
xml.intTag(level, "rpos", song->rpos());
diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp
new file mode 100644
index 00000000..f0a4308a
--- /dev/null
+++ b/muse2/muse/structure.cpp
@@ -0,0 +1,368 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: app.cpp,v 1.113.2.68 2009/12/21 14:51:51 spamatica Exp $
+//
+// (C) Copyright 1999-2004 Werner Schweer (ws@seh.de)
+// (C) Copyright 2011 Robert Jonsson (rj@spamatica.se)
+//=========================================================
+
+#include <qmessagebox.h>
+#include "app.h"
+#include "track.h"
+#include "song.h"
+#include "tempo.h"
+#include "al/sig.h"
+#include "keyevent.h"
+#include "audio.h"
+#include "marker/marker.h"
+
+
+//---------------------------------------------------------
+// adjustGlobalLists
+// helper that adjusts tempo, sig, key and marker
+// lists everything from startPos is adjusted
+// 'diff' number of ticks.
+// function requires undo to be handled outside
+//---------------------------------------------------------
+
+void MusE::adjustGlobalLists(int startPos, int diff)
+{
+ const TempoList* t = &tempomap;
+ const AL::SigList* s = &AL::sigmap;
+ const KeyList* k = &keymap;
+
+ criTEvent it = t->rbegin();
+ AL::criSigEvent is = s->rbegin();
+ criKeyEvent ik = k->rbegin();
+
+ // key
+ for (; ik != k->rend(); ik++) {
+ const KeyEvent &ev = (KeyEvent)ik->second;
+ int tick = ev.tick;
+ int key = ev.key;
+ if (tick < startPos )
+ break;
+
+ if (tick > startPos && tick +diff < startPos ) { // remove
+ audio->msgRemoveKey(tick, key, false);
+ }
+ else {
+ audio->msgRemoveKey(tick, key, false);
+ audio->msgAddKey(tick+diff, key, false);
+ }
+ }
+
+ // tempo
+ for (; it != t->rend(); it++) {
+ const TEvent* ev = (TEvent*)it->second;
+ int tick = ev->tick;
+ int tempo = ev->tempo;
+ if (tick < startPos )
+ break;
+
+ if (tick > startPos && tick +diff < startPos ) { // remove
+ audio->msgDeleteTempo(tick, tempo, false);
+ }
+ else {
+ audio->msgDeleteTempo(tick, tempo, false);
+ audio->msgAddTempo(tick+diff, tempo, false);
+ }
+ }
+
+ // sig
+ for (; is != s->rend(); is++) {
+ const AL::SigEvent* ev = (AL::SigEvent*)is->second;
+ int tick = ev->tick;
+ if (tick < startPos )
+ break;
+
+ int z = ev->sig.z;
+ int n = ev->sig.n;
+ if (tick > startPos && tick +diff < startPos ) { // remove
+ audio->msgRemoveSig(tick, z, n, false);
+ }
+ else {
+ audio->msgRemoveSig(tick, z, n, false);
+ audio->msgAddSig(tick+diff, z, n, false);
+ }
+ }
+
+ MarkerList *markerlist = song->marker();
+ for(iMarker i = markerlist->begin(); i != markerlist->end(); ++i)
+ {
+ Marker* m = &i->second;
+ int tick = m->tick();
+ if (tick > startPos)
+ {
+ if (tick + diff < startPos ) { // these ticks should be removed
+ Marker *oldMarker = new Marker();
+ *oldMarker = *m;
+ markerlist->remove(m);
+ song->undoOp(UndoOp::ModifyMarker,oldMarker, 0);
+ } else {
+ Marker *oldMarker = new Marker();
+ *oldMarker = *m;
+ m->setTick(tick + diff);
+ song->undoOp(UndoOp::ModifyMarker,oldMarker, m);
+ }
+ }
+ }
+
+}
+
+//---------------------------------------------------------
+// globalCut
+// - remove area between left and right locator
+// - do not touch muted track
+// - cut master track
+//---------------------------------------------------------
+
+void MusE::globalCut()
+ {
+ int lpos = song->lpos();
+ int rpos = song->rpos();
+ if ((lpos - rpos) >= 0)
+ return;
+
+ song->startUndo();
+ TrackList* tracks = song->tracks();
+ for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
+ MidiTrack* track = dynamic_cast<MidiTrack*>(*it);
+ if (track == 0 || track->mute())
+ continue;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ Part* part = p->second;
+ int t = part->tick();
+ int l = part->lenTick();
+ if (t + l <= lpos)
+ continue;
+ if ((t >= lpos) && ((t+l) <= rpos)) {
+ audio->msgRemovePart(part, false);
+ }
+ else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) {
+ // remove part tail
+ int len = lpos - t;
+ MidiPart* nPart = new MidiPart(*(MidiPart*)part);
+ nPart->setLenTick(len);
+ //
+ // cut Events in nPart
+ EventList* el = nPart->events();
+ iEvent ie = el->lower_bound(t + len);
+ for (; ie != el->end();) {
+ iEvent i = ie;
+ ++ie;
+ // Indicate no undo, and do not do port controller values and clone parts.
+ //audio->msgDeleteEvent(i->second, nPart, false);
+ audio->msgDeleteEvent(i->second, nPart, false, false, false);
+ }
+ // Indicate no undo, and do port controller values and clone parts.
+ //audio->msgChangePart(part, nPart, false);
+ audio->msgChangePart(part, nPart, false, true, true);
+ }
+ else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) {
+ //----------------------
+ // remove part middle
+ //----------------------
+
+ MidiPart* nPart = new MidiPart(*(MidiPart*)part);
+ EventList* el = nPart->events();
+ iEvent is = el->lower_bound(lpos);
+ iEvent ie = el->upper_bound(rpos);
+ for (iEvent i = is; i != ie;) {
+ iEvent ii = i;
+ ++i;
+ // Indicate no undo, and do not do port controller values and clone parts.
+ //audio->msgDeleteEvent(ii->second, nPart, false);
+ audio->msgDeleteEvent(ii->second, nPart, false, false, false);
+ }
+
+ ie = el->lower_bound(rpos);
+ for (; ie != el->end();) {
+ iEvent i = ie;
+ ++ie;
+ Event event = i->second;
+ Event nEvent = event.clone();
+ nEvent.setTick(nEvent.tick() - (rpos-lpos));
+ // Indicate no undo, and do not do port controller values and clone parts.
+ //audio->msgChangeEvent(event, nEvent, nPart, false);
+ audio->msgChangeEvent(event, nEvent, nPart, false, false, false);
+ }
+ nPart->setLenTick(l - (rpos-lpos));
+ // Indicate no undo, and do port controller values and clone parts.
+ //audio->msgChangePart(part, nPart, false);
+ audio->msgChangePart(part, nPart, false, true, true);
+ }
+ else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) {
+ // TODO: remove part head
+ }
+ else if (t >= rpos) {
+ MidiPart* nPart = new MidiPart(*(MidiPart*)part);
+ int nt = part->tick();
+ nPart->setTick(nt - (rpos -lpos));
+ // Indicate no undo, and do port controller values but not clone parts.
+ //audio->msgChangePart(part, nPart, false);
+ audio->msgChangePart(part, nPart, false, true, false);
+ }
+ }
+ }
+ int diff = lpos - rpos;
+ adjustGlobalLists(lpos, diff);
+
+ song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_REMOVED | SC_TEMPO | SC_KEY | SC_SIG);
+ }
+
+//---------------------------------------------------------
+// globalInsert
+// - insert empty space at left locator position upto
+// right locator
+// - do not touch muted track
+// - insert in master track
+//---------------------------------------------------------
+
+void MusE::globalInsert()
+ {
+ unsigned lpos = song->lpos();
+ unsigned rpos = song->rpos();
+ if (lpos >= rpos)
+ return;
+
+ song->startUndo();
+ TrackList* tracks = song->tracks();
+ for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
+ MidiTrack* track = dynamic_cast<MidiTrack*>(*it);
+ //
+ // process only non muted midi tracks
+ //
+ if (track == 0 || track->mute())
+ continue;
+ PartList* pl = track->parts();
+ for (riPart p = pl->rbegin(); p != pl->rend(); ++p) {
+ Part* part = p->second;
+ unsigned t = part->tick();
+ int l = part->lenTick();
+ if (t + l <= lpos)
+ continue;
+ if (lpos >= t && lpos < (t+l)) {
+ MidiPart* nPart = new MidiPart(*(MidiPart*)part);
+ nPart->setLenTick(l + (rpos-lpos));
+ EventList* el = nPart->events();
+
+ iEvent i = el->end();
+ while (i != el->begin()) {
+ --i;
+ if (i->first < lpos)
+ break;
+ Event event = i->second;
+ Event nEvent = i->second.clone();
+ nEvent.setTick(nEvent.tick() + (rpos-lpos));
+ // Indicate no undo, and do not do port controller values and clone parts.
+ //audio->msgChangeEvent(event, nEvent, nPart, false);
+ audio->msgChangeEvent(event, nEvent, nPart, false, false, false);
+ }
+ // Indicate no undo, and do port controller values and clone parts.
+ //audio->msgChangePart(part, nPart, false);
+ audio->msgChangePart(part, nPart, false, true, true);
+ }
+ else if (t > lpos) {
+ MidiPart* nPart = new MidiPart(*(MidiPart*)part);
+ nPart->setTick(t + (rpos -lpos));
+ // Indicate no undo, and do port controller values but not clone parts.
+ //audio->msgChangePart(part, nPart, false);
+ audio->msgChangePart(part, nPart, false, true, false);
+ }
+ }
+ }
+
+ int diff = rpos - lpos;
+ adjustGlobalLists(lpos, diff);
+
+ song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_REMOVED | SC_TEMPO | SC_KEY | SC_SIG );
+ }
+
+
+//---------------------------------------------------------
+// globalSplit
+// - split all parts at the song position pointer
+// - do not touch muted track
+//---------------------------------------------------------
+
+void MusE::globalSplit()
+ {
+ int pos = song->cpos();
+ song->startUndo();
+ TrackList* tracks = song->tracks();
+ for (iTrack it = tracks->begin(); it != tracks->end(); ++it) {
+ Track* track = *it;
+ PartList* pl = track->parts();
+ for (iPart p = pl->begin(); p != pl->end(); ++p) {
+ Part* part = p->second;
+ int p1 = part->tick();
+ int l0 = part->lenTick();
+ if (pos > p1 && pos < (p1+l0)) {
+ Part* p1;
+ Part* p2;
+ track->splitPart(part, pos, p1, p2);
+ // Indicate no undo, and do port controller values but not clone parts.
+ //audio->msgChangePart(part, p1, false);
+ audio->msgChangePart(part, p1, false, true, false);
+ audio->msgAddPart(p2, false);
+ break;
+ }
+ }
+ }
+ song->endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED);
+ }
+
+//---------------------------------------------------------
+// copyRange
+// - copy space between left and right locator position
+// to song position pointer
+// - dont process muted tracks
+// - create a new part for every track containing the
+// copied events
+//---------------------------------------------------------
+
+void MusE::copyRange()
+ {
+ QMessageBox::critical(this,
+ tr("MusE: Copy Range"),
+ tr("not implemented")
+ );
+ }
+
+//---------------------------------------------------------
+// cutEvents
+// - make sure that all events in a part end where the
+// part ends
+// - process only marked parts
+//---------------------------------------------------------
+
+void MusE::cutEvents()
+ {
+ QMessageBox::critical(this,
+ tr("MusE: Cut Events"),
+ tr("not implemented")
+ );
+ }
+
+//---------------------------------------------------------
+// checkRegionNotNull
+// return true if (rPos - lPos) <= 0
+//---------------------------------------------------------
+
+bool MusE::checkRegionNotNull()
+ {
+ int start = song->lPos().frame();
+ int end = song->rPos().frame();
+ if (end - start <= 0) {
+ QMessageBox::critical(this,
+ tr("MusE: Bounce"),
+ tr("set left/right marker for bounce range")
+ );
+ return true;
+ }
+ return false;
+ }
+
diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp
index 44d37591..a31b8e7a 100644
--- a/muse2/muse/undo.cpp
+++ b/muse2/muse/undo.cpp
@@ -897,10 +897,18 @@ void Song::doUndo3()
break;
case UndoOp::ModifyMarker:
{
- //printf("performing undo for one marker at %d\n", i->realMarker->tick());
- Marker tmpMarker = *i->realMarker;
- *i->realMarker = *i->copyMarker; // swap them
- *i->copyMarker = tmpMarker;
+ //printf("performing undo for one marker at copy %d real %d\n", i->copyMarker, i->realMarker);
+ if (i->realMarker) {
+ Marker tmpMarker = *i->realMarker;
+ *i->realMarker = *i->copyMarker; // swap them
+ *i->copyMarker = tmpMarker;
+ }
+ else {
+ //printf("flipping marker\n");
+ i->realMarker = _markerList->add(*i->copyMarker);
+ delete i->copyMarker;
+ i->copyMarker = 0;
+ }
}
break;
default:
@@ -979,10 +987,16 @@ void Song::doRedo3()
break;
case UndoOp::ModifyMarker:
{
- //printf("performing redo for one marker at %d\n", i->realMarker->tick());
- Marker tmpMarker = *i->realMarker;
- *i->realMarker = *i->copyMarker; // swap them
- *i->copyMarker = tmpMarker;
+ //printf("performing redo for one marker at copy %d real %d\n", i->copyMarker, i->realMarker);
+ if (i->copyMarker) {
+ Marker tmpMarker = *i->realMarker;
+ *i->realMarker = *i->copyMarker; // swap them
+ *i->copyMarker = tmpMarker;
+ } else {
+ i->copyMarker = new Marker(*i->realMarker);
+ _markerList->remove(i->realMarker);
+ i->realMarker = 0;
+ }
}
break;
default:
diff --git a/muse2/muse/widgets/songinfo.ui b/muse2/muse/widgets/songinfo.ui
index 0944ce93..c313fd9f 100644
--- a/muse2/muse/widgets/songinfo.ui
+++ b/muse2/muse/widgets/songinfo.ui
@@ -25,6 +25,13 @@
<item>
<layout class="QHBoxLayout">
<item>
+ <widget class="QCheckBox" name="viewCheckBox">
+ <property name="text">
+ <string>Show on song load</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="spacer1">
<property name="orientation">
<enum>Qt::Horizontal</enum>