diff options
| author | Robert Jonsson <spamatica@gmail.com> | 2011-05-08 21:20:35 +0000 | 
|---|---|---|
| committer | Robert Jonsson <spamatica@gmail.com> | 2011-05-08 21:20:35 +0000 | 
| commit | c00e79dd68a68ab0ec30034612d3c8826107b8db (patch) | |
| tree | ca92cbea4eacdf26eb8ac799075b3be7381467cc | |
| parent | 27cc37410cf3d0994f105fbadf135e6a43a440eb (diff) | |
structure menu fixes
| -rw-r--r-- | muse2/ChangeLog | 2 | ||||
| -rw-r--r-- | muse2/awl/posedit.cpp | 2 | ||||
| -rw-r--r-- | muse2/muse/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | muse2/muse/app.cpp | 280 | ||||
| -rw-r--r-- | muse2/muse/app.h | 5 | ||||
| -rw-r--r-- | muse2/muse/marker/marker.h | 2 | ||||
| -rw-r--r-- | muse2/muse/master/lmaster.cpp | 4 | ||||
| -rw-r--r-- | muse2/muse/part.h | 1 | ||||
| -rw-r--r-- | muse2/muse/song.cpp | 160 | ||||
| -rw-r--r-- | muse2/muse/song.h | 4 | ||||
| -rw-r--r-- | muse2/muse/songfile.cpp | 3 | ||||
| -rw-r--r-- | muse2/muse/structure.cpp | 368 | ||||
| -rw-r--r-- | muse2/muse/undo.cpp | 30 | ||||
| -rw-r--r-- | muse2/muse/widgets/songinfo.ui | 7 | 
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>  | 
