]> git.sesse.net Git - kdenlive/commitdiff
Missing files from scope manager merge
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 6 Mar 2012 17:58:31 +0000 (18:58 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 6 Mar 2012 17:58:31 +0000 (18:58 +0100)
src/mainwindow.cpp
src/scopes/CMakeLists.txt [new file with mode: 0644]
src/scopes/scopemanager.cpp [new file with mode: 0644]
src/scopes/scopemanager.h [new file with mode: 0644]

index 8b60492e705e6ff69a182729e97cf6fe53959bca..3de2d7722bd581d41373fb13943cd365adebdfd7 100644 (file)
@@ -177,7 +177,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
     dbus.registerObject("/MainWindow", this);
 
     if (!KdenliveSettings::colortheme().isEmpty()) slotChangePalette(NULL, KdenliveSettings::colortheme());
-    //setFont(KGlobalSettings::toolBarFont());
+    setFont(KGlobalSettings::toolBarFont());
     parseProfiles(MltPath);
     KdenliveSettings::setCurrent_profile(KdenliveSettings::default_profile());
     m_commandStack = new QUndoGroup;
@@ -962,7 +962,7 @@ void MainWindow::setupActions()
     QColor buttonBg = scheme.background(KColorScheme::LinkBackground).color();
     QColor buttonBord = scheme.foreground(KColorScheme::LinkText).color();
     QColor buttonBord2 = scheme.shade(KColorScheme::LightShade);
-    //statusBar()->setStyleSheet(QString("QStatusBar QLabel {font-size:%1pt;} QStatusBar::item { border: 0px; font-size:%1pt;padding:0px; }").arg(statusBar()->font().pointSize()));
+    statusBar()->setStyleSheet(QString("QStatusBar QLabel {font-size:%1pt;} QStatusBar::item { border: 0px; font-size:%1pt;padding:0px; }").arg(statusBar()->font().pointSize()));
     QString style1 = QString("QToolBar { border: 0px } QToolButton { border-style: inset; border:1px solid transparent;border-radius: 3px;margin: 0px 3px;padding: 0px;} QToolButton:hover { background: rgb(%7, %8, %9);border-style: inset; border:1px solid rgb(%7, %8, %9);border-radius: 3px;} QToolButton:checked { background-color: rgb(%1, %2, %3); border-style: inset; border:1px solid rgb(%4, %5, %6);border-radius: 3px;}").arg(buttonBg.red()).arg(buttonBg.green()).arg(buttonBg.blue()).arg(buttonBord.red()).arg(buttonBord.green()).arg(buttonBord.blue()).arg(buttonBord2.red()).arg(buttonBord2.green()).arg(buttonBord2.blue());
     QString styleBorderless = "QToolButton { border-width: 0px;margin: 1px 3px 0px;padding: 0px;}";
 
diff --git a/src/scopes/CMakeLists.txt b/src/scopes/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bd61d72
--- /dev/null
@@ -0,0 +1,10 @@
+
+add_subdirectory(colorscopes)
+add_subdirectory(audioscopes)
+
+set(kdenlive_SRCS
+  ${kdenlive_SRCS}
+  scopes/scopemanager.cpp
+  scopes/abstractscopewidget.cpp
+  PARENT_SCOPE
+)
diff --git a/src/scopes/scopemanager.cpp b/src/scopes/scopemanager.cpp
new file mode 100644 (file)
index 0000000..a51a136
--- /dev/null
@@ -0,0 +1,293 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Simon Andreas Eugster (simon.eu@gmail.com)      *
+ *   This file is part of kdenlive. See www.kdenlive.org.                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#include "scopemanager.h"
+
+#include <QDockWidget>
+
+#include "definitions.h"
+#include "monitormanager.h"
+#include "kdenlivesettings.h"
+
+//#define DEBUG_SM
+#ifdef DEBUG_SM
+#include <QtCore/QDebug>
+#endif
+
+ScopeManager::ScopeManager(MonitorManager *monitorManager) :
+    m_monitorManager(monitorManager),
+    m_lastConnectedRenderer(NULL)
+{
+    m_signalMapper = new QSignalMapper(this);
+
+    bool b = true;
+    b &= connect(m_monitorManager, SIGNAL(checkColorScopes()), this, SLOT(slotUpdateActiveRenderer()));
+    b &= connect(m_signalMapper, SIGNAL(mapped(QString)), this, SLOT(slotRequestFrame(QString)));
+    Q_ASSERT(b);
+
+    slotUpdateActiveRenderer();
+}
+
+bool ScopeManager::addScope(AbstractAudioScopeWidget *audioScope, QDockWidget *audioScopeWidget)
+{
+    bool added = false;
+    int exists = false;
+    // Only add the scope if it does not exist yet in the list
+    for (int i = 0; i < m_audioScopes.size(); i++) {
+        if (m_audioScopes[i].scope == audioScope) {
+            exists = true;
+            break;
+        }
+    }
+    if (!exists) {
+        // Add scope to the list, set up signal/slot connections
+#ifdef DEBUG_SM
+        qDebug() << "Adding scope to scope manager: " << audioScope->widgetName();
+#endif
+
+        m_signalMapper->setMapping(audioScopeWidget, QString(audioScope->widgetName()));
+
+        AudioScopeData asd;
+        asd.scope = audioScope;
+        asd.scopeDockWidget = audioScopeWidget;
+        m_audioScopes.append(asd);
+
+        bool b = true;
+        b &= connect(audioScope, SIGNAL(requestAutoRefresh(bool)), this, SLOT(slotCheckActiveScopes()));
+//         b &= connect(audioScope, SIGNAL(signalFrameRequest(QString)), this, SLOT(slotRequestFrame(QString)));
+        if (audioScopeWidget != NULL) {
+            b &= connect(audioScopeWidget, SIGNAL(visibilityChanged(bool)), this, SLOT(slotCheckActiveScopes()));
+            b &= connect(audioScopeWidget, SIGNAL(visibilityChanged(bool)), m_signalMapper, SLOT(map()));
+        }
+        Q_ASSERT(b);
+
+        added = true;
+    }
+    return added;
+}
+bool ScopeManager::addScope(AbstractGfxScopeWidget *colorScope, QDockWidget *colorScopeWidget)
+{
+    bool added = false;
+    int exists = false;
+    for (int i = 0; i < m_colorScopes.size(); i++) {
+        if (m_colorScopes[i].scope == colorScope) {
+            exists = true;
+            break;
+        }
+    }
+    if (!exists) {
+#ifdef DEBUG_SM
+        qDebug() << "Adding scope to scope manager: " << colorScope->widgetName();
+#endif
+
+        m_signalMapper->setMapping(colorScopeWidget, QString(colorScope->widgetName()));
+
+        GfxScopeData gsd;
+        gsd.scope = colorScope;
+        gsd.scopeDockWidget = colorScopeWidget;
+        m_colorScopes.append(gsd);
+
+        bool b = true;
+        b &= connect(colorScope, SIGNAL(requestAutoRefresh(bool)), this, SLOT(slotCheckActiveScopes()));
+        b &= connect(colorScope, SIGNAL(signalFrameRequest(QString)), this, SLOT(slotRequestFrame(QString)));
+        if (colorScopeWidget != NULL) {
+            b &= connect(colorScopeWidget, SIGNAL(visibilityChanged(bool)), this, SLOT(slotCheckActiveScopes()));
+            b &= connect(colorScopeWidget, SIGNAL(visibilityChanged(bool)), m_signalMapper, SLOT(map()));
+        }
+        Q_ASSERT(b);
+
+        added = true;
+    }
+    return added;
+}
+
+
+void ScopeManager::slotDistributeAudio(QVector<int16_t> sampleData, int freq, int num_channels, int num_samples)
+{
+#ifdef DEBUG_SM
+    qDebug() << "ScopeManager: Starting to distribute audio.";
+#endif
+    for (int i = 0; i < m_audioScopes.size(); i++) {
+        // Distribute audio to all scopes that are visible and want to be refreshed
+        if (!m_audioScopes[i].scope->visibleRegion().isEmpty()) {
+            if (m_audioScopes[i].scope->autoRefreshEnabled()) {
+                m_audioScopes[i].scope->slotReceiveAudio(sampleData, freq, num_channels, num_samples);
+#ifdef DEBUG_SM
+                qDebug() << "ScopeManager: Distributed audio to " << m_audioScopes[i].scope->widgetName();
+#endif
+            }
+        }
+    }
+
+    checkActiveAudioScopes();
+}
+void ScopeManager::slotDistributeFrame(QImage image)
+{
+#ifdef DEBUG_SM
+    qDebug() << "ScopeManager: Starting to distribute frame.";
+#endif
+    for (int i = 0; i < m_colorScopes.size(); i++) {
+        if (!m_colorScopes[i].scope->visibleRegion().isEmpty()) {
+            if (m_colorScopes[i].scope->autoRefreshEnabled()) {
+                m_colorScopes[i].scope->slotRenderZoneUpdated(image);
+#ifdef DEBUG_SM
+                qDebug() << "ScopeManager: Distributed frame to " << m_colorScopes[i].scope->widgetName();
+#endif
+            } else if (m_colorScopes[i].singleFrameRequested) {
+                // Special case: Auto refresh is disabled, but user requested an update (e.g. by clicking).
+                // Force the scope to update.
+                m_colorScopes[i].singleFrameRequested = false;
+                m_colorScopes[i].scope->slotRenderZoneUpdated(image);
+                m_colorScopes[i].scope->forceUpdateScope();
+#ifdef DEBUG_SM
+                qDebug() << "ScopeManager: Distributed forced frame to " << m_colorScopes[i].scope->widgetName();
+#endif
+            }
+        }
+    }
+
+    checkActiveColourScopes();
+}
+
+
+void ScopeManager::slotRequestFrame(const QString widgetName)
+{
+#ifdef DEBUG_SM
+    qDebug() << "ScopeManager: New frame was requested by " << widgetName;
+#endif
+
+    // Search for the scope in the lists and tag it to trigger a forced update
+    // in the distribution slots
+    for (int i = 0; i < m_colorScopes.size(); i++) {
+        if (m_colorScopes[i].scope->widgetName() == widgetName) {
+            m_colorScopes[i].singleFrameRequested = true;
+            break;
+        }
+    }
+    for (int i = 0; i < m_audioScopes.size(); i++) {
+        if (m_audioScopes[i].scope->widgetName() == widgetName) {
+            m_audioScopes[i].singleFrameRequested = true;
+            break;
+        }
+    }
+    m_lastConnectedRenderer->sendFrameUpdate();
+}
+
+
+
+void ScopeManager::slotUpdateActiveRenderer()
+{
+    bool b = true;
+
+    // Disconnect old connections
+    if (m_lastConnectedRenderer != NULL) {
+#ifdef DEBUG_SM
+        qDebug() << "Disconnected previous renderer: " << m_lastConnectedRenderer->name();
+#endif
+        b &= m_lastConnectedRenderer->disconnect(this);
+        Q_ASSERT(b);
+    }
+
+    m_lastConnectedRenderer = m_monitorManager->activeRenderer();
+
+    // Connect new renderer
+    if (m_lastConnectedRenderer != NULL) {
+        b &= connect(m_lastConnectedRenderer, SIGNAL(frameUpdated(QImage)),
+                this, SLOT(slotDistributeFrame(QImage)), Qt::UniqueConnection);
+        b &= connect(m_lastConnectedRenderer, SIGNAL(audioSamplesSignal(QVector<int16_t>,int,int,int)),
+                this, SLOT(slotDistributeAudio(QVector<int16_t>,int,int,int)), Qt::UniqueConnection);
+        Q_ASSERT(b);
+
+#ifdef DEBUG_SM
+        qDebug() << "Renderer connected to ScopeManager: " << m_lastConnectedRenderer->name();
+#endif
+
+        if (imagesAcceptedByScopes()) {
+#ifdef DEBUG_SM
+            qDebug() << "Some scopes accept images, triggering frame update.";
+#endif
+            m_lastConnectedRenderer->sendFrameUpdate();
+        }
+    }
+}
+
+
+void ScopeManager::slotCheckActiveScopes()
+{
+#ifdef DEBUG_SM
+    qDebug() << "Checking active scopes ...";
+#endif
+    checkActiveAudioScopes();
+    checkActiveColourScopes();
+}
+
+
+bool ScopeManager::audioAcceptedByScopes() const
+{
+    bool accepted = false;
+    for (int i = 0; i < m_audioScopes.size(); i++) {
+        if (!m_audioScopes[i].scope->visibleRegion().isEmpty() && m_audioScopes[i].scope->autoRefreshEnabled()) {
+            accepted = true;
+            break;
+        }
+    }
+#ifdef DEBUG_SM
+    qDebug() << "Any scope accepting audio? " << accepted;
+#endif
+    return accepted;
+}
+bool ScopeManager::imagesAcceptedByScopes() const
+{
+    bool accepted = false;
+    for (int i = 0; i < m_colorScopes.size(); i++) {
+        if (!m_colorScopes[i].scope->visibleRegion().isEmpty() && m_colorScopes[i].scope->autoRefreshEnabled()) {
+            accepted = true;
+            break;
+        }
+    }
+#ifdef DEBUG_SM
+    qDebug() << "Any scope accepting images? " << accepted;
+#endif
+    return accepted;
+}
+
+
+
+void ScopeManager::checkActiveAudioScopes()
+{
+    bool audioStillRequested = audioAcceptedByScopes();
+
+#ifdef DEBUG_SM
+    qDebug() << "ScopeManager: New audio data still requested? " << audioStillRequested;
+#endif
+
+    KdenliveSettings::setMonitor_audio(audioStillRequested);
+    m_monitorManager->slotUpdateAudioMonitoring();
+}
+void ScopeManager::checkActiveColourScopes()
+{
+    bool imageStillRequested = imagesAcceptedByScopes();
+
+#ifdef DEBUG_SM
+    qDebug() << "ScopeManager: New frames still requested? " << imageStillRequested;
+#endif
+
+    // Notify monitors whether frames are still required
+    Monitor *monitor;
+    monitor = static_cast<Monitor*>( m_monitorManager->monitor(Kdenlive::projectMonitor) );
+    if (monitor != NULL) { monitor->render->sendFrameForAnalysis = imageStillRequested; }
+
+    monitor = static_cast<Monitor*>( m_monitorManager->monitor(Kdenlive::clipMonitor) );
+    if (monitor != NULL) { monitor->render->sendFrameForAnalysis = imageStillRequested; }
+
+    RecMonitor *recMonitor = static_cast<RecMonitor*>( m_monitorManager->monitor(Kdenlive::recordMonitor) );
+    if (recMonitor != NULL) { recMonitor->analyseFrames(imageStillRequested); }
+}
+
diff --git a/src/scopes/scopemanager.h b/src/scopes/scopemanager.h
new file mode 100644 (file)
index 0000000..ca5f1bd
--- /dev/null
@@ -0,0 +1,115 @@
+/***************************************************************************
+ *   Copyright (C) 2011 by Simon Andreas Eugster (simon.eu@gmail.com)      *
+ *   This file is part of kdenlive. See www.kdenlive.org.                  *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ ***************************************************************************/
+
+#ifndef SCOPEMANAGER_H
+#define SCOPEMANAGER_H
+
+#include <QtCore/QList>
+
+#include "scopes/audioscopes/abstractaudioscopewidget.h"
+#include "scopes/colorscopes/abstractgfxscopewidget.h"
+
+class QDockWidget;
+class MonitorManager;
+class AbstractRender;
+
+/**
+  \brief Manages communication between Scopes and Renderer
+
+  The scope manager handles the data transfer between the active Renderer and
+  all scopes that have been registered via ScopeManager::addScope(AbstractAudioScopeWidget, QDockWidget)
+  or ScopeManager::addScope(AbstractGfxScopeWidget, QDockWidget). It checks whether the renderer really
+  needs to send data (it does not, for example, if no scopes are visible).
+  */
+class ScopeManager : QObject
+{
+    Q_OBJECT
+
+    struct GfxScopeData {
+        AbstractGfxScopeWidget *scope;
+        QDockWidget *scopeDockWidget;
+        bool singleFrameRequested;
+        GfxScopeData() { singleFrameRequested = false; }
+    };
+
+    struct AudioScopeData {
+        AbstractAudioScopeWidget *scope;
+        QDockWidget *scopeDockWidget;
+        bool singleFrameRequested;
+        AudioScopeData() { singleFrameRequested = false; }
+    };
+
+public:
+    ScopeManager(MonitorManager *monitorManager);
+
+    /**
+      Adds a scope and sets up signal/slot connections to ensure that the scope
+      receives data when required.
+      \see addScope(AbstractGfxScopeWidget, QDockWidget)
+      */
+    bool addScope(AbstractAudioScopeWidget *audioScope, QDockWidget *audioScopeWidget = NULL);
+    /**
+      \see addScope(AbstractAudioScopeWidget, QDockWidget)
+      */
+    bool addScope(AbstractGfxScopeWidget *colorScope, QDockWidget *colorScopeWidget = NULL);
+
+private:
+    MonitorManager *m_monitorManager;
+    QList<AudioScopeData> m_audioScopes;
+    QList<GfxScopeData> m_colorScopes;
+
+    AbstractRender *m_lastConnectedRenderer;
+
+    QSignalMapper *m_signalMapper;
+
+    /**
+      Checks whether there is any scope accepting audio data, or if all of them are hidden
+      or if auto refresh is disabled.
+      \see imagesAcceptedByScopes(): Same for image data
+      */
+    bool audioAcceptedByScopes() const;
+    /**
+      \see audioAcceptedByScopes()
+      */
+    bool imagesAcceptedByScopes() const;
+
+
+    /**
+      Checks whether audio data is required, and notifies the renderer (enable or disable data sending).
+      \see checkActiveAudioScopes() for image data
+      */
+    void checkActiveAudioScopes();
+    /**
+      Checks whether any scope accepts frames, and notifies the renderer.
+      \see checkActiveAudioScopes() for audio data
+      */
+    void checkActiveColourScopes();
+
+private slots:
+    /**
+      Updates the signal/slot connection since the active renderer has changed.
+      */
+    void slotUpdateActiveRenderer();
+    /**
+      \see checkActiveAudioScopes()
+      \see checkActiveColourScopes()
+      */
+    void slotCheckActiveScopes();
+    void slotDistributeFrame(QImage image);
+    void slotDistributeAudio(QVector<int16_t> sampleData, int freq, int num_channels, int num_samples);
+    /**
+      Allows a scope to explicitly request a new frame, even if the scope's autoRefresh is disabled.
+      */
+    void slotRequestFrame(const QString widgetName);
+
+
+};
+
+#endif // SCOPEMANAGER_H