changeset 404:08a45e4cf1b1 tonioni

Update subrepos and merge from default branch
author Chris Cannam
date Tue, 02 Sep 2014 16:23:48 +0100
parents ad33fdc4ad92 (current diff) eb84b06301da (diff)
children c1b2b8b84165
files
diffstat 8 files changed, 176 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/audioio/AudioCallbackPlaySource.cpp	Fri Jul 18 13:25:11 2014 +0100
+++ b/audioio/AudioCallbackPlaySource.cpp	Tue Sep 02 16:23:48 2014 +0100
@@ -361,14 +361,22 @@
 {
     if (!haveLock) m_mutex.lock();
 
+    cerr << "clearRingBuffers" << endl;
+
     rebuildRangeLists();
 
     if (count == 0) {
 	if (m_writeBuffers) count = m_writeBuffers->size();
     }
 
+    cerr << "current playing frame = " << getCurrentPlayingFrame() << endl;
+
+    cerr << "write buffer fill (before) = " << m_writeBufferFill << endl;
+
     m_writeBufferFill = getCurrentBufferedFrame();
 
+    cerr << "current buffered frame = " << m_writeBufferFill << endl;
+
     if (m_readBuffers != m_writeBuffers) {
 	delete m_writeBuffers;
     }
@@ -602,7 +610,11 @@
 
     int targetRate = getTargetSampleRate();
     int latency = m_playLatency; // at target rate
-    RealTime latency_t = RealTime::frame2RealTime(latency, targetRate);
+    RealTime latency_t = RealTime::zeroTime;
+
+    if (targetRate != 0) {
+        latency_t = RealTime::frame2RealTime(latency, targetRate);
+    }
 
     return getCurrentFrame(latency_t);
 }
--- a/audioio/AudioGenerator.cpp	Fri Jul 18 13:25:11 2014 +0100
+++ b/audioio/AudioGenerator.cpp	Tue Sep 02 16:23:48 2014 +0100
@@ -284,6 +284,8 @@
 {
     QMutexLocker locker(&m_mutex);
 
+    cerr << "AudioGenerator::reset()" << endl;
+
     for (ClipMixerMap::iterator i = m_clipMixerMap.begin(); i != m_clipMixerMap.end(); ++i) {
 	if (i->second) {
 	    i->second->reset();
--- a/audioio/ClipMixer.cpp	Fri Jul 18 13:25:11 2014 +0100
+++ b/audioio/ClipMixer.cpp	Tue Sep 02 16:23:48 2014 +0100
@@ -131,6 +131,12 @@
 
     float *levels = new float[m_channels];
 
+#ifdef DEBUG_CLIP_MIXER
+    cerr << "ClipMixer::mix: have " << m_playing.size() << " playing note(s)"
+         << " and " << endingNotes.size() << " note(s) ending here"
+         << endl;
+#endif
+
     foreach (NoteStart note, m_playing) {
 
         for (int c = 0; c < m_channels; ++c) {
--- a/framework/Document.cpp	Fri Jul 18 13:25:11 2014 +0100
+++ b/framework/Document.cpp	Tue Sep 02 16:23:48 2014 +0100
@@ -565,6 +565,7 @@
     }
 
     if (m_autoAlignment) {
+        SVDEBUG << "Document::setMainModel: auto-alignment is on, aligning model if possible" << endl;
         alignModel(m_mainModel);
     }
 
@@ -641,7 +642,12 @@
     cerr << endl;
 #endif
 
-    if (m_autoAlignment) alignModel(model);
+    if (m_autoAlignment) {
+        SVDEBUG << "Document::addImportedModel: auto-alignment is on, aligning model if possible" << endl;
+        alignModel(model);
+    } else {
+        SVDEBUG << "Document(" << this << "): addImportedModel: auto-alignment is off" << endl;
+    }
 
     emit modelAdded(model);
 }
@@ -671,7 +677,10 @@
     cerr << endl;
 #endif
 
-    if (m_autoAlignment) alignModel(model);
+    if (m_autoAlignment) {
+        SVDEBUG << "Document::addAdditionalModel: auto-alignment is on, aligning model if possible" << endl;
+        alignModel(model);
+    }
 
     emit modelAdded(model);
 }
@@ -1044,14 +1053,22 @@
 void
 Document::alignModel(Model *model)
 {
-    if (!m_mainModel) return;
+    SVDEBUG << "Document::alignModel(" << model << ")" << endl;
+
+    if (!m_mainModel) {
+        SVDEBUG << "(no main model to align to)" << endl;
+        return;
+    }
 
     RangeSummarisableTimeValueModel *rm = 
         dynamic_cast<RangeSummarisableTimeValueModel *>(model);
-    if (!rm) return;
+    if (!rm) {
+        SVDEBUG << "(main model is not alignable-to)" << endl;
+        return;
+    }
 
     if (rm->getAlignmentReference() == m_mainModel) {
-        SVDEBUG << "Document::alignModel: model " << rm << " is already aligned to main model " << m_mainModel << endl;
+        SVDEBUG << "(model " << rm << " is already aligned to main model " << m_mainModel << ")" << endl;
         return;
     }
     
--- a/framework/MainWindowBase.cpp	Fri Jul 18 13:25:11 2014 +0100
+++ b/framework/MainWindowBase.cpp	Tue Sep 02 16:23:48 2014 +0100
@@ -155,7 +155,8 @@
     m_lastPlayStatusSec(0),
     m_initialDarkBackground(false),
     m_defaultFfwdRwdStep(2, 0),
-    m_statusLabel(0)
+    m_statusLabel(0),
+    m_menuShortcutMapper(0)
 {
     Profiler profiler("MainWindowBase::MainWindowBase");
 
@@ -276,8 +277,28 @@
 void
 MainWindowBase::finaliseMenus()
 {
+    delete m_menuShortcutMapper;
+    m_menuShortcutMapper = 0;
+
+    foreach (QShortcut *sc, m_appShortcuts) {
+        delete sc;
+    }
+    m_appShortcuts.clear();
+
     QMenuBar *mb = menuBar();
-    QList<QMenu *> menus = mb->findChildren<QMenu *>();
+
+    // This used to find all children of QMenu type, and call
+    // finaliseMenu on those. But it seems we are getting hold of some
+    // menus that way that are not actually active in the menu bar and
+    // are not returned in their parent menu's actions() list, and if
+    // we finalise those, we end up with duplicate shortcuts in the
+    // app shortcut mapper. So we should do this by descending the
+    // menu tree through only those menus accessible via actions()
+    // from their parents instead.
+
+    QList<QMenu *> menus = mb->findChildren<QMenu *>
+        (QString(), Qt::FindDirectChildrenOnly);
+
     foreach (QMenu *menu, menus) {
         if (menu) finaliseMenu(menu);
     }
@@ -323,26 +344,44 @@
     // "ambiguous shortcut" errors from the menu entry actions and
     // will need to update the code.)
 
-    QSignalMapper *mapper = new QSignalMapper(this);
-
-    connect(mapper, SIGNAL(mapped(QObject *)),
-            this, SLOT(menuActionMapperInvoked(QObject *)));
+    if (!m_menuShortcutMapper) {
+        m_menuShortcutMapper = new QSignalMapper(this);
+        connect(m_menuShortcutMapper, SIGNAL(mapped(QObject *)),
+                this, SLOT(menuActionMapperInvoked(QObject *)));
+    }
 
     foreach (QAction *a, menu->actions()) {
-        QWidgetList ww = a->associatedWidgets();
-        bool hasButton = false;
-        foreach (QWidget *w, ww) {
-            if (qobject_cast<QAbstractButton *>(w)) {
-                hasButton = true;
-                break;
+
+        if (a->isSeparator()) {
+            continue;
+        } else if (a->menu()) {
+            finaliseMenu(a->menu());
+        } else {
+
+            QWidgetList ww = a->associatedWidgets();
+            bool hasButton = false;
+            foreach (QWidget *w, ww) {
+                if (qobject_cast<QAbstractButton *>(w)) {
+                    hasButton = true;
+                    break;
+                }
             }
-        }
-        if (hasButton) continue;
-        QKeySequence sc = a->shortcut();
-        if (sc.count() == 1 && !(sc[0] & Qt::KeyboardModifierMask)) {
-            QShortcut *newSc = new QShortcut(sc, a->parentWidget());
-            QObject::connect(newSc, SIGNAL(activated()), mapper, SLOT(map()));
-            mapper->setMapping(newSc, a);
+            if (hasButton) continue;
+            QKeySequence sc = a->shortcut();
+
+            // Note that the set of "single-key shortcuts" that aren't
+            // working and that we need to handle here includes those
+            // with the Shift modifier mask as well as those with no
+            // modifier at all
+            if (sc.count() == 1 &&
+                ((sc[0] & Qt::KeyboardModifierMask) == Qt::NoModifier ||
+                 (sc[0] & Qt::KeyboardModifierMask) == Qt::ShiftModifier)) {
+                QShortcut *newSc = new QShortcut(sc, a->parentWidget());
+                QObject::connect(newSc, SIGNAL(activated()),
+                                 m_menuShortcutMapper, SLOT(map()));
+                m_menuShortcutMapper->setMapping(newSc, a);
+                m_appShortcuts.push_back(newSc);
+            }
         }
     }
 #endif
@@ -470,14 +509,13 @@
                 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;
-                }
-            }
+        // the prev/next layer commands actually include the pane
+        // itself as one of the selectables -- so we always have a
+        // prev and next layer, as long as we have a pane with at
+        // least one layer in it
+        if (currentPane->getLayerCount() > 0) {
+            havePrevLayer = true;
+            haveNextLayer = true;
         }
     }        
 
@@ -654,7 +692,7 @@
 
     int frame = m_playSource->getCurrentBufferedFrame();
 
-//    cerr << "currentPaneChanged: current frame (in ref model) = " << frame << endl;
+    cerr << "currentPaneChanged: current frame (in ref model) = " << frame << endl;
 
     View::ModelSet soloModels = p->getModels();
     
@@ -1220,7 +1258,7 @@
 MainWindowBase::openAudio(FileSource source, AudioFileOpenMode mode,
                           QString templateName)
 {
-    SVDEBUG << "MainWindowBase::openAudio(" << source.getLocation() << ")" << endl;
+    SVDEBUG << "MainWindowBase::openAudio(" << source.getLocation() << ") with mode " << mode << " and template " << templateName << endl;
 
     if (templateName == "") {
         templateName = getDefaultSessionTemplate();
@@ -1317,6 +1355,7 @@
     }
 
     if (mode == CreateAdditionalModel && !getMainModel()) {
+        SVDEBUG << "Mode is CreateAdditionalModel but we have no main model, switching to ReplaceSession mode" << endl;
         mode = ReplaceSession;
     }
 
@@ -1326,7 +1365,7 @@
 
         if (!checkSaveModified()) return FileOpenCancelled;
 
-        cerr << "SV looking for template " << templateName << endl;
+        SVDEBUG << "SV looking for template " << templateName << endl;
         if (templateName != "") {
             FileOpenStatus tplStatus = openSessionTemplate(templateName);
             if (tplStatus == FileOpenCancelled) {
@@ -1340,10 +1379,12 @@
         }
 
         if (!loadedTemplate) {
+            SVDEBUG << "No template found: closing session, creating new empty document" << endl;
             closeSession();
             createDocument();
         }
 
+        SVDEBUG << "Now switching to ReplaceMainModel mode" << endl;
         mode = ReplaceMainModel;
     }
 
@@ -3010,49 +3051,71 @@
 void
 MainWindowBase::previousLayer()
 {
-    //!!! Not right -- pane lists layers in stacking order
-
     if (!m_paneStack) return;
 
     Pane *currentPane = m_paneStack->getCurrentPane();
     if (!currentPane) return;
 
+    int count = currentPane->getLayerCount();
+    if (count == 0) 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;
+
+    if (!currentLayer) {
+        // The pane itself is current
+        m_paneStack->setCurrentLayer
+            (currentPane, currentPane->getFixedOrderLayer(count-1));
+    } else {
+        for (int i = 0; i < count; ++i) {
+            if (currentPane->getFixedOrderLayer(i) == currentLayer) {
+                if (i == 0) {
+                    m_paneStack->setCurrentLayer
+                        (currentPane, 0); // pane
+                } else {
+                    m_paneStack->setCurrentLayer
+                        (currentPane, currentPane->getFixedOrderLayer(i-1));
+                }
+                break;
+            }
         }
     }
+
+    updateMenuStates();
 }
 
 void
 MainWindowBase::nextLayer()
 {
-    //!!! Not right -- pane lists layers in stacking order
-
     if (!m_paneStack) return;
 
     Pane *currentPane = m_paneStack->getCurrentPane();
     if (!currentPane) return;
 
+    int count = currentPane->getLayerCount();
+    if (count == 0) 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;
+
+    if (!currentLayer) {
+        // The pane itself is current
+        m_paneStack->setCurrentLayer
+            (currentPane, currentPane->getFixedOrderLayer(0));
+    } else {
+        for (int i = 0; i < count; ++i) {
+            if (currentPane->getFixedOrderLayer(i) == currentLayer) {
+                if (i == currentPane->getLayerCount()-1) {
+                    m_paneStack->setCurrentLayer
+                        (currentPane, 0); // pane
+                } else {
+                    m_paneStack->setCurrentLayer
+                        (currentPane, currentPane->getFixedOrderLayer(i+1));
+                }
+                break;
+            }
         }
     }
+
+    updateMenuStates();
 }
 
 void
--- a/framework/MainWindowBase.h	Fri Jul 18 13:25:11 2014 +0100
+++ b/framework/MainWindowBase.h	Tue Sep 02 16:23:48 2014 +0100
@@ -60,6 +60,8 @@
 class KeyReference;
 class Labeller;
 class ModelDataTableDialog;
+class QSignalMapper;
+class QShortcut;
 
 /**
  * The base class for the SV main window.  This includes everything to
@@ -428,6 +430,10 @@
     virtual void finaliseMenus();
     virtual void finaliseMenu(QMenu *);
 
+    // Only used on OS/X to work around a Qt/Cocoa bug, see finaliseMenus
+    QSignalMapper *m_menuShortcutMapper;
+    QList<QShortcut *> m_appShortcuts;
+
     virtual bool shouldCreateNewSessionForRDFAudio(bool *) { return true; }
 
     virtual void connectLayerEditDialog(ModelDataTableDialog *dialog);
--- a/framework/TransformUserConfigurator.cpp	Fri Jul 18 13:25:11 2014 +0100
+++ b/framework/TransformUserConfigurator.cpp	Tue Sep 02 16:23:48 2014 +0100
@@ -30,6 +30,14 @@
 
 #include <typeinfo>
 
+static QWidget *parentWidget = 0;
+
+void
+TransformUserConfigurator::setParentWidget(QWidget *w)
+{
+    parentWidget = w;
+}
+
 bool
 TransformUserConfigurator::getChannelRange(TransformId identifier,
 					   Vamp::PluginBase *plugin,
@@ -142,7 +150,8 @@
 
     int defaultChannel = -1; //!!! no longer saved! [was context.channel]
 
-    PluginParameterDialog *dialog = new PluginParameterDialog(plugin);
+    PluginParameterDialog *dialog = new PluginParameterDialog
+        (plugin, parentWidget);
 
     dialog->setMoreInfoUrl(TransformFactory::getInstance()->
 			   getTransformInfoUrl(transform.getIdentifier()));
--- a/framework/TransformUserConfigurator.h	Fri Jul 18 13:25:11 2014 +0100
+++ b/framework/TransformUserConfigurator.h	Tue Sep 02 16:23:48 2014 +0100
@@ -33,6 +33,8 @@
                            QStringList candidateModelNames,
                            QString defaultModelName);
 
+    static void setParentWidget(QWidget *);
+
 private:
     bool getChannelRange(TransformId identifier,
                          Vamp::PluginBase *plugin, int &min, int &max);