]> git.sesse.net Git - kdenlive/blobdiff - src/monitor.cpp
Various changes for getting an OpenGL context (almost) everywhere it is needed.
[kdenlive] / src / monitor.cpp
index 33155581d036a1c4cb525b84bbf8ef80cd487ee1..29a7a3d8463116cc0e280f3567667fa2332c7f49 100644 (file)
 #include "docclipbase.h"
 #include "abstractclipitem.h"
 #include "monitorscene.h"
-#include "monitoreditwidget.h"
+#include "widgets/monitoreditwidget.h"
+#include "widgets/videosurface.h"
+#include "widgets/videoglwidget.h"
 #include "kdenlivesettings.h"
 
 #include <KDebug>
-#include <KLocale>
+#include <KLocalizedString>
 #include <KFileDialog>
 #include <KApplication>
 #include <KMessageBox>
+#include <KSelectAction>
 
 #include <QMouseEvent>
 #include <QStylePainter>
 #include <QLabel>
 #include <QIntValidator>
 #include <QVBoxLayout>
+#include <QSlider>
 
 
 #define SEEK_INACTIVE (-1)
 
 
-Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profile, QWidget *parent) :
+Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QGLWidget *glContext, QString profile, QWidget *parent) :
     AbstractMonitor(id, manager, parent)
     , render(NULL)
-    , m_name(Kdenlive::noMonitor)
     , m_currentClip(NULL)
     , m_overlay(NULL)
     , m_scale(1)
@@ -60,9 +63,8 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
     , m_effectWidget(NULL)
     , m_selectedClip(NULL)
     , m_loopClipTransition(true)
-#ifdef USE_OPENGL
+    , m_parentGLContext(glContext)
     , m_glWidget(NULL)
-#endif
     , m_editMarker(NULL)
 {
     QVBoxLayout *layout = new QVBoxLayout;
@@ -85,7 +87,7 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
     m_pauseIcon = KIcon("media-playback-pause");
 
 
-    if (id != Kdenlive::dvdMonitor) {
+    if (id != Kdenlive::DvdMonitor) {
         m_toolbar->addAction(KIcon("kdenlive-zone-start"), i18n("Set zone start"), this, SLOT(slotSetZoneStart()));
         m_toolbar->addAction(KIcon("kdenlive-zone-end"), i18n("Set zone end"), this, SLOT(slotSetZoneEnd()));
     }
@@ -108,7 +110,7 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
 
     playButton->setDefaultAction(m_playAction);
 
-    if (id != Kdenlive::dvdMonitor) {
+    if (id != Kdenlive::DvdMonitor) {
         QToolButton *configButton = new QToolButton(m_toolbar);
         m_configMenu = new QMenu(i18n("Misc..."), this);
         configButton->setIcon(KIcon("system-run"));
@@ -116,11 +118,11 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
         configButton->setPopupMode(QToolButton::QToolButton::InstantPopup);
         m_toolbar->addWidget(configButton);
 
-        if (id == Kdenlive::clipMonitor) {
+        if (id == Kdenlive::ClipMonitor) {
             m_markerMenu = new QMenu(i18n("Go to marker..."), this);
             m_markerMenu->setEnabled(false);
             m_configMenu->addMenu(m_markerMenu);
-            connect(m_markerMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotGoToMarker(QAction *)));
+            connect(m_markerMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotGoToMarker(QAction*)));
         }
         m_configMenu->addAction(KIcon("transform-scale"), i18n("Resize (100%)"), this, SLOT(slotSetSizeOneToOne()));
         m_configMenu->addAction(KIcon("transform-scale"), i18n("Resize (50%)"), this, SLOT(slotSetSizeOneToTwo()));
@@ -148,35 +150,18 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
     setLayout(layout);
     setMinimumHeight(200);
 
-    if (profile.isEmpty()) profile = KdenliveSettings::current_profile();
+    if (profile.isEmpty())
+        profile = KdenliveSettings::current_profile();
 
-    bool monitorCreated = false;
-#ifdef Q_WS_MAC
     createOpenGlWidget(videoBox, profile);
-    monitorCreated = true;
-    //m_glWidget->setFixedSize(width, height);
-#elif defined(USE_OPENGL)
-    if (KdenliveSettings::openglmonitors()) {
-        monitorCreated = createOpenGlWidget(videoBox, profile);
-    }
-#endif
-    if (!monitorCreated) {
-       createVideoSurface();
-        render = new Render(m_id, (int) videoSurface->winId(), profile, this);
-       connect(videoSurface, SIGNAL(refreshMonitor()), render, SLOT(doRefresh()));
-    }
-#ifdef USE_OPENGL
-    else if (m_glWidget) {
-       QVBoxLayout *lay = new QVBoxLayout;
-       lay->setContentsMargins(0, 0, 0, 0);
-        lay->addWidget(m_glWidget);
-        videoBox->setLayout(lay);
-    }
-#endif
+    QVBoxLayout *lay = new QVBoxLayout;
+    lay->setContentsMargins(0, 0, 0, 0);
+    lay->addWidget(m_glWidget);
+    videoBox->setLayout(lay);
 
     // Monitor ruler
     m_ruler = new SmallRuler(this, render);
-    if (id == Kdenlive::dvdMonitor) m_ruler->setZone(-3, -2);
+    if (id == Kdenlive::DvdMonitor) m_ruler->setZone(-3, -2);
     layout->addWidget(m_ruler);
     
     connect(m_audioSlider, SIGNAL(valueChanged(int)), this, SLOT(slotSetVolume(int)));
@@ -184,7 +169,7 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
     connect(render, SIGNAL(rendererStopped(int)), this, SLOT(rendererStopped(int)));
     connect(render, SIGNAL(rendererPosition(int)), this, SLOT(seekCursor(int)));
 
-    if (id != Kdenlive::clipMonitor) {
+    if (id != Kdenlive::ClipMonitor) {
         connect(render, SIGNAL(rendererPosition(int)), this, SIGNAL(renderPosition(int)));
         connect(render, SIGNAL(durationChanged(int)), this, SIGNAL(durationChanged(int)));
         connect(m_ruler, SIGNAL(zoneChanged(QPoint)), this, SIGNAL(zoneUpdated(QPoint)));
@@ -192,11 +177,9 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
         connect(m_ruler, SIGNAL(zoneChanged(QPoint)), this, SLOT(setClipZone(QPoint)));
     }
 
-    if (videoSurface) videoSurface->show();
-
-    if (id == Kdenlive::projectMonitor) {
+    if (id == Kdenlive::ProjectMonitor) {
         m_effectWidget = new MonitorEditWidget(render, videoBox);
-       connect(m_effectWidget, SIGNAL(showEdit(bool, bool)), this, SLOT(slotShowEffectScene(bool, bool)));
+       connect(m_effectWidget, SIGNAL(showEdit(bool,bool)), this, SLOT(slotShowEffectScene(bool,bool)));
         m_toolbar->addAction(m_effectWidget->getVisibilityAction());
         videoBox->layout()->addWidget(m_effectWidget);
         m_effectWidget->hide();
@@ -227,21 +210,21 @@ QWidget *Monitor::container()
     return videoBox;
 }
 
-#ifdef USE_OPENGL
-bool Monitor::createOpenGlWidget(QWidget *parent, const QString profile)
+void Monitor::createOpenGlWidget(QWidget *parent, const QString &profile)
 {
-    render = new Render(id(), 0, profile, this);
-    m_glWidget = new VideoGLWidget(parent);
+    m_glWidget = new VideoGLWidget(parent, m_parentGLContext);
+    render = new Render(id(), 0, profile, this, m_glWidget);
     if (m_glWidget == NULL) {
         // Creation failed, we are in trouble...
-        return false;
+        QMessageBox::critical(this, i18n("Missing OpenGL support"),
+                             i18n("You need working OpenGL support to run Kdenlive. Exiting."));
+        qApp->quit();
     }
     m_glWidget->setImageAspectRatio(render->dar());
     m_glWidget->setBackgroundColor(KdenliveSettings::window_background());
     connect(render, SIGNAL(showImageSignal(QImage)), m_glWidget, SLOT(showImage(QImage)));
-    return true;
+    connect(render, SIGNAL(showImageSignal(GLuint)), m_glWidget, SLOT(showImage(GLuint)));
 }
-#endif
 
 void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMenu *markerMenu, QAction *loopClip)
 {
@@ -252,7 +235,7 @@ void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMe
     if (markerMenu) {
         m_contextMenu->addMenu(markerMenu);
         QList <QAction *>list = markerMenu->actions();
-        for (int i = 0; i < list.count(); i++) {
+        for (int i = 0; i < list.count(); ++i) {
             if (list.at(i)->data().toString() == "edit_marker") {
                 m_editMarker = list.at(i);
                 break;
@@ -268,7 +251,7 @@ void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMe
     }
 
     //TODO: add save zone to timeline monitor when fixed
-    if (m_id == Kdenlive::clipMonitor) {
+    if (m_id == Kdenlive::ClipMonitor) {
         m_contextMenu->addMenu(m_markerMenu);
         m_contextMenu->addAction(KIcon("document-save"), i18n("Save zone"), this, SLOT(slotSaveZone()));
         QAction *extractZone = m_configMenu->addAction(KIcon("document-new"), i18n("Extract Zone"), this, SLOT(slotExtractCurrentZone()));
@@ -277,7 +260,7 @@ void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMe
     QAction *extractFrame = m_configMenu->addAction(KIcon("document-new"), i18n("Extract frame"), this, SLOT(slotExtractCurrentFrame()));
     m_contextMenu->addAction(extractFrame);
 
-    if (m_id != Kdenlive::clipMonitor) {
+    if (m_id != Kdenlive::ClipMonitor) {
         QAction *splitView = m_contextMenu->addAction(KIcon("view-split-left-right"), i18n("Split view"), render, SLOT(slotSplitView(bool)));
         splitView->setCheckable(true);
         m_configMenu->addAction(splitView);
@@ -295,10 +278,9 @@ void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMe
     dropFrames->setCheckable(true);
     dropFrames->setChecked(true);
     connect(dropFrames, SIGNAL(toggled(bool)), this, SLOT(slotSwitchDropFrames(bool)));
-
+    
     m_configMenu->addAction(showTips);
     m_configMenu->addAction(dropFrames);
-
 }
 
 void Monitor::slotGoToMarker(QAction *action)
@@ -374,7 +356,7 @@ void Monitor::updateMarkers(DocClipBase *source)
         QList <CommentedTime> markers = m_currentClip->commentedSnapMarkers();
         if (!markers.isEmpty()) {
             QList <int> marks;
-            for (int i = 0; i < markers.count(); i++) {
+            for (int i = 0; i < markers.count(); ++i) {
                 int pos = (int) markers.at(i).time().frames(m_monitorManager->timecode().fps());
                 marks.append(pos);
                 QString position = m_monitorManager->timecode().getTimecode(markers.at(i).time()) + ' ' + markers.at(i).comment();
@@ -387,7 +369,7 @@ void Monitor::updateMarkers(DocClipBase *source)
     }
 }
 
-void Monitor::setMarkers(QList <CommentedTime> markers)
+void Monitor::setMarkers(const QList<CommentedTime> &markers)
 {
     m_ruler->setMarkers(markers);
 }
@@ -460,6 +442,7 @@ void Monitor::slotSetZoneEnd()
 // virtual
 void Monitor::mousePressEvent(QMouseEvent * event)
 {
+    if (render) render->setActiveMonitor();
     if (event->button() != Qt::RightButton) {
         if (videoBox->geometry().contains(event->pos()) && (!m_overlay || !m_overlay->underMouse())) {
             m_dragStarted = true;
@@ -472,7 +455,7 @@ void Monitor::mousePressEvent(QMouseEvent * event)
 
 void Monitor::resizeEvent(QResizeEvent *event)
 {
-    Q_UNUSED(event);
+    Q_UNUSED(event)
     if (render && isVisible() && isActive()) render->doRefresh();
 }
 
@@ -559,14 +542,6 @@ void Monitor::wheelEvent(QWheelEvent * event)
     event->accept();
 }
 
-void Monitor::mouseDoubleClickEvent(QMouseEvent * event)
-{
-    if (!KdenliveSettings::openglmonitors()) {
-        videoBox->switchFullScreen();
-        event->accept();
-    }
-}
-
 void Monitor::slotMouseSeek(int eventDelta, bool fast)
 {
     if (fast) {
@@ -610,13 +585,13 @@ void Monitor::slotExtractCurrentFrame()
     fs->setMode(KFile::File);
     fs->setConfirmOverwrite(true);
     fs->setKeepLocation(true);
-    fs->exec();
-    QString path;
-    if (fs) path = fs->selectedFile();
-    delete fs;
-    if (!path.isEmpty()) {
-        frame.save(path);
+    if (fs->exec()) {
+        QString path = fs->selectedFile();
+        if (!path.isEmpty()) {
+            frame.save(path);
+        }
     }
+    delete fs;
 }
 
 void Monitor::setTimePos(const QString &pos)
@@ -788,9 +763,7 @@ void Monitor::stop()
 void Monitor::start()
 {
     if (!isVisible() || !isActive()) return;
-#ifdef USE_OPENGL    
     if (m_glWidget) m_glWidget->activateMonitor();
-#endif
     if (render) render->startConsumer();
 }
 
@@ -872,7 +845,7 @@ void Monitor::slotLoopClip()
 void Monitor::updateClipProducer(Mlt::Producer *prod)
 {
     if (render == NULL) return;
-   render->setProducer(prod, render->seekFramePosition());
+    render->setProducer(prod, render->seekFramePosition());
 }
 
 void Monitor::slotSetClipProducer(DocClipBase *clip, QPoint zone, bool forceUpdate, int position)
@@ -880,7 +853,6 @@ void Monitor::slotSetClipProducer(DocClipBase *clip, QPoint zone, bool forceUpda
     if (render == NULL) return;
     if (clip == NULL && m_currentClip != NULL) {
        m_currentClip->lastSeekPosition = render->seekFramePosition();
-        kDebug()<<"// SETTING NULL CLIP MONITOR";
         m_currentClip = NULL;
         m_length = -1;
         render->setProducer(NULL, -1);
@@ -897,7 +869,7 @@ void Monitor::slotSetClipProducer(DocClipBase *clip, QPoint zone, bool forceUpda
         if (render->setProducer(prod, position) == -1) {
             // MLT CONSUMER is broken
             kDebug(QtWarningMsg) << "ERROR, Cannot start monitor";
-        }
+        } else start();
     } else {
         if (m_currentClip) {
             slotActivateMonitor();
@@ -931,16 +903,14 @@ void Monitor::slotSaveZone()
     //render->setSceneList(doc, 0);
 }
 
-void Monitor::setCustomProfile(const QString &profile, Timecode tc)
+void Monitor::setCustomProfile(const QString &profile, const Timecode &tc)
 {
     m_timePos->updateTimeCode(tc);
     if (render == NULL) return;
     if (!render->hasProfile(profile)) {
         slotActivateMonitor();
         render->resetProfile(profile);
-#ifdef USE_OPENGL    
        if (m_glWidget) m_glWidget->setImageAspectRatio(render->dar());
-#endif
     }
 }
 
@@ -951,15 +921,13 @@ void Monitor::resetProfile(const QString &profile)
     if (!render->hasProfile(profile)) {
         slotActivateMonitor();
         render->resetProfile(profile);
-#ifdef USE_OPENGL
        if (m_glWidget) m_glWidget->setImageAspectRatio(render->dar());
-#endif
     }
     if (m_effectWidget)
         m_effectWidget->resetProfile(render);
 }
 
-void Monitor::saveSceneList(QString path, QDomElement info)
+void Monitor::saveSceneList(const QString &path, const QDomElement &info)
 {
     if (render == NULL) return;
     render->saveSceneList(path, info);
@@ -971,7 +939,7 @@ const QString Monitor::sceneList()
     return render->sceneList();
 }
 
-void Monitor::setClipZone(QPoint pos)
+void Monitor::setClipZone(const QPoint &pos)
 {
     if (m_currentClip == NULL) return;
     m_currentClip->setZone(pos);
@@ -987,28 +955,13 @@ void Monitor::slotSwitchMonitorInfo(bool show)
     KdenliveSettings::setDisplayMonitorInfo(show);
     if (show) {
         if (m_overlay) return;
-        if (videoSurface == NULL) {
-            // Using OpenGL display
-#ifdef USE_OPENGL
-            if (m_glWidget->layout()) delete m_glWidget->layout();
-            m_overlay = new Overlay();
-            connect(m_overlay, SIGNAL(editMarker()), this, SLOT(slotEditMarker()));
-            QVBoxLayout *layout = new QVBoxLayout;
-            layout->addStretch(10);
-            layout->addWidget(m_overlay);
-            m_glWidget->setLayout(layout);
-#endif
-        } else {
-            if (videoSurface->layout()) delete videoSurface->layout();
-            m_overlay = new Overlay();
-            connect(m_overlay, SIGNAL(editMarker()), this, SLOT(slotEditMarker()));
-            QVBoxLayout *layout = new QVBoxLayout;
-            layout->addStretch(10);
-            layout->addWidget(m_overlay);
-            videoSurface->setLayout(layout);
-            m_overlay->raise();
-            m_overlay->setHidden(true);
-        }
+        if (m_glWidget->layout()) delete m_glWidget->layout();
+        m_overlay = new Overlay();
+        connect(m_overlay, SIGNAL(editMarker()), this, SLOT(slotEditMarker()));
+        QVBoxLayout *layout = new QVBoxLayout;
+        layout->addStretch(10);
+        layout->addWidget(m_overlay);
+        m_glWidget->setLayout(layout);
         checkOverlay();
     } else {
         delete m_overlay;
@@ -1065,38 +1018,21 @@ void Monitor::slotSetSelectedClip(Transition* item)
 
 void Monitor::slotShowEffectScene(bool show, bool manuallyTriggered)
 {
-    if (m_id == Kdenlive::projectMonitor) {
+    if (m_id == Kdenlive::ProjectMonitor) {
         if (!m_effectWidget->getVisibilityAction()->isChecked())
             show = false;
         if (m_effectWidget->isVisible() == show)
             return;
         setUpdatesEnabled(false);
         if (show) {
-            if (videoSurface) {
-                videoSurface->setVisible(false);
-                // Preview is handeled internally through the Render::showFrame method
-                render->disablePreview(true);
-#ifdef USE_OPENGL
-            } else {
-                m_glWidget->setVisible(false);
-#endif
-            }
+            m_glWidget->setVisible(false);
             m_effectWidget->setVisible(true);
             m_effectWidget->getScene()->slotZoomFit();
             emit requestFrameForAnalysis(true);
         } else {    
             m_effectWidget->setVisible(false);
             emit requestFrameForAnalysis(false);
-            if (videoSurface) {
-                videoSurface->setVisible(true);
-                // Preview is handeled internally through the Render::showFrame method
-                render->disablePreview(false);
-            
-#ifdef USE_OPENGL
-            } else {
-                m_glWidget->setVisible(true);
-#endif
-            }
+            m_glWidget->setVisible(true);
         }
         if (!manuallyTriggered)
             m_effectWidget->showVisibilityButton(show);