diff framework/MainWindowBase.cpp @ 101:89a689720ee9 spectrogram-cache-rejig

* Merge from trunk
author Chris Cannam
date Wed, 27 Feb 2008 11:59:42 +0000
parents eb596ef12041
children
line wrap: on
line diff
--- a/framework/MainWindowBase.cpp	Sun Nov 11 20:34:41 2007 +0000
+++ b/framework/MainWindowBase.cpp	Wed Feb 27 11:59:42 2008 +0000
@@ -201,7 +201,8 @@
 
 MainWindowBase::~MainWindowBase()
 {
-    delete m_playTarget;
+    if (m_playTarget) m_playTarget->shutdown();
+//    delete m_playTarget;
     delete m_playSource;
     delete m_viewManager;
     delete m_oscQueue;
@@ -277,6 +278,28 @@
     if (m_paneStack) currentPane = m_paneStack->getCurrentPane();
     if (currentPane) currentLayer = currentPane->getSelectedLayer();
 
+    bool havePrevPane = false, haveNextPane = false;
+    bool havePrevLayer = false, haveNextLayer = false;
+
+    if (currentPane) {
+        for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
+            if (m_paneStack->getPane(i) == currentPane) {
+                if (i > 0) havePrevPane = true;
+                if (i < m_paneStack->getPaneCount()-1) haveNextPane = true;
+                break;
+            }
+        }
+        if (currentLayer) {
+            for (int i = 0; i < currentPane->getLayerCount(); ++i) {
+                if (currentPane->getLayer(i) == currentLayer) {
+                    if (i > 0) havePrevLayer = true;
+                    if (i < currentPane->getLayerCount()-1) haveNextLayer = true;
+                    break;
+                }
+            }
+        }
+    }        
+
     bool haveCurrentPane =
         (currentPane != 0);
     bool haveCurrentLayer =
@@ -321,7 +344,7 @@
     emit canPlay(havePlayTarget);
     emit canFfwd(true);
     emit canRewind(true);
-    emit canPaste(haveCurrentEditableLayer && haveClipboardContents);
+    emit canPaste(haveClipboardContents);
     emit canInsertInstant(haveCurrentPane);
     emit canInsertInstantsAtBoundaries(haveCurrentPane && haveSelection);
     emit canRenumberInstants(haveCurrentTimeInstantsLayer && haveSelection);
@@ -329,6 +352,10 @@
     emit canClearSelection(haveSelection);
     emit canEditSelection(haveSelection && haveCurrentEditableLayer);
     emit canSave(m_sessionFile != "" && m_documentModified);
+    emit canSelectPreviousPane(havePrevPane);
+    emit canSelectNextPane(haveNextPane);
+    emit canSelectPreviousLayer(havePrevLayer);
+    emit canSelectNextLayer(haveNextLayer);
 }
 
 void
@@ -423,6 +450,18 @@
 
     Model *prevPlaybackModel = m_viewManager->getPlaybackModel();
 
+    // What we want here is not the currently playing frame (unless we
+    // are about to clear out the audio playback buffers -- which may
+    // or may not be possible, depending on the audio driver).  What
+    // we want is the frame that was last committed to the soundcard
+    // buffers, as the audio driver will continue playing up to that
+    // frame before switching to whichever one we decide we want to
+    // switch to, regardless of our efforts.
+
+    int frame = m_playSource->getCurrentBufferedFrame();
+
+//    std::cerr << "currentPaneChanged: current frame (in ref model) = " << frame << std::endl;
+
     View::ModelSet soloModels = p->getModels();
     
     View::ModelSet sources;
@@ -437,6 +476,11 @@
         soloModels.insert(*mi);
     }
 
+    //!!! Need an "atomic" way of telling the play source that the
+    //playback model has changed, and changing it on ViewManager --
+    //the play source should be making the setPlaybackModel call to
+    //ViewManager
+
     for (View::ModelSet::iterator mi = soloModels.begin();
          mi != soloModels.end(); ++mi) {
         if (dynamic_cast<RangeSummarisableTimeValueModel *>(*mi)) {
@@ -453,11 +497,7 @@
     m_playSource->setSoloModelSet(soloModels);
 
     if (a && b && (a != b)) {
-        int frame = m_playSource->getCurrentPlayingFrame();
-        //!!! I don't really believe that these functions are the right way around
-        int rframe = a->alignFromReference(frame);
-        int bframe = b->alignToReference(rframe);
-        if (m_playSource->isPlaying()) m_playSource->play(bframe);
+        if (m_playSource->isPlaying()) m_playSource->play(frame);
     }
 }
 
@@ -536,7 +576,7 @@
 
     for (MultiSelection::SelectionList::iterator i = selections.begin();
          i != selections.end(); ++i) {
-        layer->copy(*i, clipboard);
+        layer->copy(currentPane, *i, clipboard);
         layer->deleteSelection(*i);
     }
 
@@ -559,7 +599,7 @@
 
     for (MultiSelection::SelectionList::iterator i = selections.begin();
          i != selections.end(); ++i) {
-        layer->copy(*i, clipboard);
+        layer->copy(currentPane, *i, clipboard);
     }
 }
 
@@ -569,30 +609,38 @@
     Pane *currentPane = m_paneStack->getCurrentPane();
     if (!currentPane) return;
 
-    //!!! if we have no current layer, we should create one of the most
-    // appropriate type
-
     Layer *layer = currentPane->getSelectedLayer();
-    if (!layer) return;
 
     Clipboard &clipboard = m_viewManager->getClipboard();
-    Clipboard::PointList contents = clipboard.getPoints();
-/*
-    long minFrame = 0;
-    bool have = false;
-    for (int i = 0; i < contents.size(); ++i) {
-        if (!contents[i].haveFrame()) continue;
-        if (!have || contents[i].getFrame() < minFrame) {
-            minFrame = contents[i].getFrame();
-            have = true;
+//    Clipboard::PointList contents = clipboard.getPoints();
+
+    bool inCompound = false;
+
+    if (!layer || !layer->isLayerEditable()) {
+        
+        CommandHistory::getInstance()->startCompoundOperation
+            (tr("Paste"), true);
+
+        // no suitable current layer: create one of the most
+        // appropriate sort
+        LayerFactory::LayerType type =
+            LayerFactory::getInstance()->getLayerTypeForClipboardContents(clipboard);
+        layer = m_document->createEmptyLayer(type);
+
+        if (!layer) {
+            CommandHistory::getInstance()->endCompoundOperation();
+            return;
         }
+
+        m_document->addLayerToView(currentPane, layer);
+        m_paneStack->setCurrentLayer(currentPane, layer);
+
+        inCompound = true;
     }
 
-    long frameOffset = long(m_viewManager->getGlobalCentreFrame()) - minFrame;
+    layer->paste(currentPane, clipboard, 0, true);
 
-    layer->paste(clipboard, frameOffset);
-*/
-    layer->paste(clipboard, 0, true);
+    if (inCompound) CommandHistory::getInstance()->endCompoundOperation();
 }
 
 void
@@ -651,6 +699,8 @@
         return;
     }
 
+    frame = pane->alignFromReference(frame);
+
     Layer *layer = dynamic_cast<TimeInstantLayer *>
         (pane->getSelectedLayer());
 
@@ -687,7 +737,7 @@
             SparseOneDimensionalModel::EditCommand *command =
                 new SparseOneDimensionalModel::EditCommand(sodm, tr("Add Point"));
 
-            if (m_labeller->actingOnPrevPoint()) {
+            if (m_labeller->requiresPrevPoint()) {
 
                 SparseOneDimensionalModel::PointList prevPoints =
                     sodm->getPreviousPoints(frame);
@@ -702,14 +752,14 @@
 
                 m_labeller->setSampleRate(sodm->getSampleRate());
 
-                if (havePrevPoint) {
+                if (m_labeller->actingOnPrevPoint()) {
                     command->deletePoint(prevPoint);
                 }
 
                 m_labeller->label<SparseOneDimensionalModel::Point>
                     (point, havePrevPoint ? &prevPoint : 0);
 
-                if (havePrevPoint) {
+                if (m_labeller->actingOnPrevPoint()) {
                     command->addPoint(prevPoint);
                 }
             }
@@ -756,7 +806,7 @@
 MainWindowBase::FileOpenStatus
 MainWindowBase::open(QString fileOrUrl, AudioFileOpenMode mode)
 {
-    return open(FileSource(fileOrUrl, true), mode);
+    return open(FileSource(fileOrUrl, FileSource::ProgressDialog), mode);
 }
 
 MainWindowBase::FileOpenStatus
@@ -998,7 +1048,8 @@
     for (PlaylistFileReader::Playlist::const_iterator i = playlist.begin();
          i != playlist.end(); ++i) {
 
-        FileOpenStatus status = openAudio(*i, mode);
+        FileOpenStatus status = openAudio
+            (FileSource(*i, FileSource::ProgressDialog), mode);
 
         if (status == FileOpenCancelled) {
             return FileOpenCancelled;
@@ -1049,6 +1100,12 @@
         }
         
         SVFileReader reader(m_document, callback, source.getLocation());
+        connect
+            (&reader, SIGNAL(modelRegenerationFailed(QString, QString, QString)),
+             this, SLOT(modelRegenerationFailed(QString, QString, QString)));
+        connect
+            (&reader, SIGNAL(modelRegenerationWarning(QString, QString, QString)),
+             this, SLOT(modelRegenerationWarning(QString, QString, QString)));
         reader.setCurrentPane(pane);
         
         QXmlInputSource inputSource(&file);
@@ -1068,6 +1125,8 @@
             registerLastOpenedFilePath(FileFinder::LayerFile, path); // for file dialog
         }
 
+        return FileOpenSucceeded;
+
     } else {
         
         try {
@@ -1084,6 +1143,8 @@
                 if (newLayer) {
 
                     m_document->addLayerToView(pane, newLayer);
+                    m_paneStack->setCurrentLayer(pane, newLayer);
+
                     m_recentFiles.addFile(source.getLocation());
                     
                     if (!source.isRemote()) {
@@ -1091,7 +1152,7 @@
                             (FileFinder::LayerFile,
                              path); // for file dialog
                     }
-                    
+
                     return FileOpenSucceeded;
                 }
             }
@@ -1102,7 +1163,6 @@
         }
     }
     
-    source.setLeaveLocalFile(true);
     return FileOpenFailed;
 }
 
@@ -1159,7 +1219,7 @@
 MainWindowBase::FileOpenStatus
 MainWindowBase::openSessionFile(QString fileOrUrl)
 {
-    return openSession(FileSource(fileOrUrl, true));
+    return openSession(FileSource(fileOrUrl, FileSource::ProgressDialog));
 }
 
 MainWindowBase::FileOpenStatus
@@ -1182,6 +1242,12 @@
     m_viewManager->clearSelections();
 
     SVFileReader reader(m_document, callback, source.getLocation());
+    connect
+        (&reader, SIGNAL(modelRegenerationFailed(QString, QString, QString)),
+         this, SLOT(modelRegenerationFailed(QString, QString, QString)));
+    connect
+        (&reader, SIGNAL(modelRegenerationWarning(QString, QString, QString)),
+         this, SLOT(modelRegenerationWarning(QString, QString, QString)));
     QXmlInputSource inputSource(&bzFile);
     reader.parse(inputSource);
     
@@ -1272,10 +1338,16 @@
     connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)),
 	    this, SLOT(modelAboutToBeDeleted(Model *)));
 
-    connect(m_document, SIGNAL(modelGenerationFailed(QString)),
-            this, SLOT(modelGenerationFailed(QString)));
-    connect(m_document, SIGNAL(modelRegenerationFailed(QString, QString)),
-            this, SLOT(modelRegenerationFailed(QString, QString)));
+    connect(m_document, SIGNAL(modelGenerationFailed(QString, QString)),
+            this, SLOT(modelGenerationFailed(QString, QString)));
+    connect(m_document, SIGNAL(modelRegenerationWarning(QString, QString, QString)),
+            this, SLOT(modelRegenerationWarning(QString, QString, QString)));
+    connect(m_document, SIGNAL(modelGenerationFailed(QString, QString)),
+            this, SLOT(modelGenerationFailed(QString, QString)));
+    connect(m_document, SIGNAL(modelRegenerationWarning(QString, QString, QString)),
+            this, SLOT(modelRegenerationWarning(QString, QString, QString)));
+    connect(m_document, SIGNAL(alignmentFailed(QString, QString)),
+            this, SLOT(alignmentFailed(QString, QString)));
 }
 
 bool
@@ -1375,6 +1447,7 @@
     
     size_t start = model->getStartFrame();
     size_t end = model->getEndFrame();
+    if (m_playSource) end = std::max(end, m_playSource->getPlayEndFrame());
     size_t pixels = currentPane->width();
 
     size_t sw = currentPane->getVerticalScaleWidth();
@@ -1534,6 +1607,7 @@
     int frame = m_viewManager->getPlaybackFrame();
     ++frame;
 
+    Pane *pane = m_paneStack->getCurrentPane();
     Layer *layer = getSnapLayer();
     size_t sr = getMainModel()->getSampleRate();
 
@@ -1548,8 +1622,10 @@
     } else {
 
         size_t resolution = 0;
-        if (!layer->snapToFeatureFrame(m_paneStack->getCurrentPane(),
-                                       frame, resolution, Layer::SnapRight)) {
+        if (layer->snapToFeatureFrame(m_paneStack->getCurrentPane(),
+                                      frame, resolution, Layer::SnapRight)) {
+            if (pane) frame = pane->alignToReference(frame);
+        } else {
             frame = getMainModel()->getEndFrame();
         }
     }
@@ -1585,6 +1661,7 @@
     int frame = m_viewManager->getPlaybackFrame();
     if (frame > 0) --frame;
 
+    Pane *pane = m_paneStack->getCurrentPane();
     Layer *layer = getSnapLayer();
     size_t sr = getMainModel()->getSampleRate();
     
@@ -1611,8 +1688,11 @@
     } else {
 
         size_t resolution = 0;
-        if (!layer->snapToFeatureFrame(m_paneStack->getCurrentPane(),
-                                       frame, resolution, Layer::SnapLeft)) {
+        if (layer->snapToFeatureFrame(m_paneStack->getCurrentPane(),
+                                      frame, resolution, Layer::SnapLeft)) {
+            
+            if (pane) frame = pane->alignToReference(frame);
+        } else {
             frame = getMainModel()->getStartFrame();
         }
     }
@@ -1801,6 +1881,90 @@
 }
 
 void
+MainWindowBase::previousPane()
+{
+    if (!m_paneStack) return;
+
+    Pane *currentPane = m_paneStack->getCurrentPane();
+    if (!currentPane) return;
+
+    for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
+        if (m_paneStack->getPane(i) == currentPane) {
+            if (i == 0) return;
+            m_paneStack->setCurrentPane(m_paneStack->getPane(i-1));
+            updateMenuStates();
+            return;
+        }
+    }
+}
+
+void
+MainWindowBase::nextPane()
+{
+    if (!m_paneStack) return;
+
+    Pane *currentPane = m_paneStack->getCurrentPane();
+    if (!currentPane) return;
+
+    for (int i = 0; i < m_paneStack->getPaneCount(); ++i) {
+        if (m_paneStack->getPane(i) == currentPane) {
+            if (i == m_paneStack->getPaneCount()-1) return;
+            m_paneStack->setCurrentPane(m_paneStack->getPane(i+1));
+            updateMenuStates();
+            return;
+        }
+    }
+}
+
+void
+MainWindowBase::previousLayer()
+{
+    //!!! Not right -- pane lists layers in stacking order
+
+    if (!m_paneStack) return;
+
+    Pane *currentPane = m_paneStack->getCurrentPane();
+    if (!currentPane) return;
+
+    Layer *currentLayer = currentPane->getSelectedLayer();
+    if (!currentLayer) return;
+
+    for (int i = 0; i < currentPane->getLayerCount(); ++i) {
+        if (currentPane->getLayer(i) == currentLayer) {
+            if (i == 0) return;
+            m_paneStack->setCurrentLayer(currentPane,
+                                         currentPane->getLayer(i-1));
+            updateMenuStates();
+            return;
+        }
+    }
+}
+
+void
+MainWindowBase::nextLayer()
+{
+    //!!! Not right -- pane lists layers in stacking order
+
+    if (!m_paneStack) return;
+
+    Pane *currentPane = m_paneStack->getCurrentPane();
+    if (!currentPane) return;
+
+    Layer *currentLayer = currentPane->getSelectedLayer();
+    if (!currentLayer) return;
+
+    for (int i = 0; i < currentPane->getLayerCount(); ++i) {
+        if (currentPane->getLayer(i) == currentLayer) {
+            if (i == currentPane->getLayerCount()-1) return;
+            m_paneStack->setCurrentLayer(currentPane,
+                                         currentPane->getLayer(i+1));
+            updateMenuStates();
+            return;
+        }
+    }
+}
+
+void
 MainWindowBase::playbackFrameChanged(unsigned long frame)
 {
     if (!(m_playSource && m_playSource->isPlaying()) || !getMainModel()) return;