]> git.sesse.net Git - kdenlive/blobdiff - src/monitor.cpp
Fix the jkl keys for forward/backwards/pause monitor: http://www.kdenlive.org/mantis...
[kdenlive] / src / monitor.cpp
index 9dc2aa3383e769672629166643714dcf157a4b31..3242e71eaa53bdd50d034c971279f90538085884 100644 (file)
 #include <QVBoxLayout>
 
 
+#define SEEK_INACTIVE (-1)
+
+
 Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profile, QWidget *parent) :
     AbstractMonitor(id, manager, parent),
     render(NULL),
     m_currentClip(NULL),
-    m_ruler(new SmallRuler(m_monitorManager)),
     m_overlay(NULL),
     m_scale(1),
     m_length(0),
     m_dragStarted(false),
-    m_monitorRefresh(NULL),
     m_contextMenu(NULL),
     m_effectWidget(NULL),
     m_selectedClip(NULL),
@@ -64,15 +65,13 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
     layout->setSpacing(0);
 
     // Video widget holder
-    m_videoBox = new VideoContainer(this);
-    layout->addWidget(m_videoBox, 10);
+    layout->addWidget(videoBox, 10);
     layout->addStretch();
 
     // Get base size for icons
     int s = style()->pixelMetric(QStyle::PM_SmallIconSize);
 
-    // Monitor ruler
-    layout->addWidget(m_ruler);
+
     // Tool bar buttons
     m_toolbar = new QToolBar(this);
     m_toolbar->setIconSize(QSize(s, s));
@@ -80,11 +79,10 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
     m_playIcon = KIcon("media-playback-start");
     m_pauseIcon = KIcon("media-playback-pause");
 
+
     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()));
-    } else {
-        m_ruler->setZone(-3, -2);
     }
 
     m_toolbar->addAction(KIcon("media-seek-backward"), i18n("Rewind"), this, SLOT(slotRewind()));
@@ -149,32 +147,34 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
 
     bool monitorCreated = false;
 #ifdef Q_WS_MAC
-    createOpenGlWidget(m_videoBox, profile);
+    createOpenGlWidget(videoBox, profile);
     monitorCreated = true;
     //m_glWidget->setFixedSize(width, height);
 #elif defined(USE_OPENGL)
     if (KdenliveSettings::openglmonitors()) {
-        monitorCreated = createOpenGlWidget(m_videoBox, profile);
+        monitorCreated = createOpenGlWidget(videoBox, profile);
     }
 #endif
-    QVBoxLayout *lay = new QVBoxLayout;
-    lay->setContentsMargins(0, 0, 0, 0);
     if (!monitorCreated) {
-        m_monitorRefresh = new MonitorRefresh;
-        lay->addWidget(m_monitorRefresh);
-        m_videoBox->setLayout(lay);
-        render = new Render(m_id, (int) m_monitorRefresh->winId(), profile, this);
-        m_monitorRefresh->setRenderer(render);
+       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);
-        m_videoBox->setLayout(lay);
+        videoBox->setLayout(lay);
     }
 #endif
 
+    // Monitor ruler
+    m_ruler = new SmallRuler(m_monitorManager, render);
+    if (id == Kdenlive::dvdMonitor) m_ruler->setZone(-3, -2);
+    layout->addWidget(m_ruler);
+    
     connect(m_audioSlider, SIGNAL(valueChanged(int)), this, SLOT(slotSetVolume(int)));
-    connect(m_ruler, SIGNAL(seekRenderer(int)), this, SLOT(slotSeek(int)));
     connect(render, SIGNAL(durationChanged(int)), this, SLOT(adjustRulerSize(int)));
     connect(render, SIGNAL(rendererStopped(int)), this, SLOT(rendererStopped(int)));
     connect(render, SIGNAL(rendererPosition(int)), this, SLOT(seekCursor(int)));
@@ -187,12 +187,13 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
         connect(m_ruler, SIGNAL(zoneChanged(QPoint)), this, SLOT(setClipZone(QPoint)));
     }
 
-    if (m_monitorRefresh) m_monitorRefresh->show();
+    if (videoSurface) videoSurface->show();
 
     if (id == Kdenlive::projectMonitor) {
-        m_effectWidget = new MonitorEditWidget(render, m_videoBox);
+        m_effectWidget = new MonitorEditWidget(render, videoBox);
+       connect(m_effectWidget, SIGNAL(showEdit(bool, bool)), this, SLOT(slotShowEffectScene(bool, bool)));
         m_toolbar->addAction(m_effectWidget->getVisibilityAction());
-        lay->addWidget(m_effectWidget);
+        videoBox->layout()->addWidget(m_effectWidget);
         m_effectWidget->hide();
     }
 
@@ -201,7 +202,7 @@ Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profil
     m_toolbar->addWidget(spacer);
     m_timePos = new TimecodeDisplay(m_monitorManager->timecode(), this);
     m_toolbar->addWidget(m_timePos);
-    connect(m_timePos, SIGNAL(editingFinished()), this, SLOT(slotSeek()));
+    connect(m_timePos, SIGNAL(timeCodeEditingFinished()), this, SLOT(slotSeek()));
     m_toolbar->setMaximumHeight(s * 1.5);
     layout->addWidget(m_toolbar);
 }
@@ -213,19 +214,19 @@ Monitor::~Monitor()
     delete m_overlay;
     if (m_effectWidget)
         delete m_effectWidget;
-    delete m_monitorRefresh;
     delete render;
 }
 
 QWidget *Monitor::container()
 {
-    return m_videoBox;
+    return videoBox;
 }
 
 #ifdef USE_OPENGL
 bool Monitor::createOpenGlWidget(QWidget *parent, const QString profile)
 {
     render = new Render(id(), 0, profile, this);
+    kDebug()<<"+++++++++++++\nCREATED OPENGL WIDG\n++++++++++++++";
     m_glWidget = new VideoGLWidget(parent);
     if (m_glWidget == NULL) {
         // Creation failed, we are in trouble...
@@ -315,7 +316,7 @@ void Monitor::slotSetSizeOneToOne()
         height = height * 0.8;
     }
     kDebug() << "// MONITOR; set SIZE: " << width << ", " << height;
-    m_videoBox->setFixedSize(width, height);
+    videoBox->setFixedSize(width, height);
     updateGeometry();
     adjustSize();
     //m_ui.video_frame->setMinimumSize(0, 0);
@@ -335,7 +336,7 @@ void Monitor::slotSetSizeOneToTwo()
         height = height * 0.8;
     }
     kDebug() << "// MONITOR; set SIZE: " << width << ", " << height;
-    m_videoBox->setFixedSize(width, height);
+    videoBox->setFixedSize(width, height);
     updateGeometry();
     adjustSize();
     //m_ui.video_frame->setMinimumSize(0, 0);
@@ -344,7 +345,7 @@ void Monitor::slotSetSizeOneToTwo()
 
 void Monitor::resetSize()
 {
-    m_videoBox->setMinimumSize(0, 0);
+    videoBox->setMinimumSize(0, 0);
 }
 
 DocClipBase *Monitor::activeClip()
@@ -366,8 +367,8 @@ void Monitor::updateMarkers(DocClipBase *source)
                 QAction *go = m_markerMenu->addAction(position);
                 go->setData(pos);
             }
-            m_ruler->setMarkers(marks);
-        } else m_ruler->setMarkers(QList <int>());
+        }
+       m_ruler->setMarkers(markers);
         m_markerMenu->setEnabled(!m_markerMenu->isEmpty());
     }
 }
@@ -423,7 +424,7 @@ void Monitor::slotZoneMoved(int start, int end)
 
 void Monitor::slotSetZoneStart()
 {
-    m_ruler->setZone(m_ruler->position(), -1);
+    m_ruler->setZoneStart();
     emit zoneUpdated(m_ruler->zone());
     checkOverlay();
     setClipZone(m_ruler->zone());
@@ -431,7 +432,7 @@ void Monitor::slotSetZoneStart()
 
 void Monitor::slotSetZoneEnd()
 {
-    m_ruler->setZone(-1, m_ruler->position());
+    m_ruler->setZoneEnd();
     emit zoneUpdated(m_ruler->zone());
     checkOverlay();
     setClipZone(m_ruler->zone());
@@ -441,7 +442,7 @@ void Monitor::slotSetZoneEnd()
 void Monitor::mousePressEvent(QMouseEvent * event)
 {
     if (event->button() != Qt::RightButton) {
-        if (m_videoBox->geometry().contains(event->pos()) && (!m_overlay || !m_overlay->underMouse())) {
+        if (videoBox->geometry().contains(event->pos()) && (!m_overlay || !m_overlay->underMouse())) {
             m_dragStarted = true;
             m_DragStartPosition = event->pos();
         }
@@ -456,17 +457,16 @@ void Monitor::resizeEvent(QResizeEvent *event)
     if (render && isVisible() && isActive()) render->doRefresh();
 }
 
-
 void Monitor::slotSwitchFullScreen()
 {
-    m_videoBox->switchFullScreen();
+    videoBox->switchFullScreen();
 }
 
 // virtual
 void Monitor::mouseReleaseEvent(QMouseEvent * event)
 {
     if (m_dragStarted && event->button() != Qt::RightButton) {
-        if (m_videoBox->geometry().contains(event->pos()) && (!m_effectWidget || !m_effectWidget->isVisible())) {
+        if (videoBox->geometry().contains(event->pos()) && (!m_effectWidget || !m_effectWidget->isVisible())) {
             if (isActive()) slotPlay();
             else slotActivateMonitor();
         } //else event->ignore(); //QWidget::mouseReleaseEvent(event);
@@ -541,7 +541,7 @@ void Monitor::wheelEvent(QWheelEvent * event)
 void Monitor::mouseDoubleClickEvent(QMouseEvent * event)
 {
     if (!KdenliveSettings::openglmonitors()) {
-        m_videoBox->switchFullScreen();
+        videoBox->switchFullScreen();
         event->accept();
     }
 }
@@ -551,7 +551,9 @@ void Monitor::slotMouseSeek(int eventDelta, bool fast)
     if (fast) {
         int delta = m_monitorManager->timecode().fps();
         if (eventDelta > 0) delta = 0 - delta;
-        slotSeek(m_ruler->position() - delta);
+       if (render->requestedSeekPosition != SEEK_INACTIVE)
+           slotSeek(render->requestedSeekPosition - delta);
+       else slotSeek(render->seekFramePosition() - delta);
     } else {
         if (eventDelta >= 0) slotForwardOneFrame();
         else slotRewindOneFrame();
@@ -582,13 +584,14 @@ void Monitor::slotExtractCurrentFrame()
         frame = render->extractFrame(render->seekFramePosition(), m_currentClip->fileURL().path());
     }
     else frame = render->extractFrame(render->seekFramePosition());
-    KFileDialog *fs = new KFileDialog(KUrl(), "image/png", this);
+    QPointer<KFileDialog> fs = new KFileDialog(KUrl(), "image/png", this);
     fs->setOperationMode(KFileDialog::Saving);
     fs->setMode(KFile::File);
     fs->setConfirmOverwrite(true);
     fs->setKeepLocation(true);
     fs->exec();
-    QString path = fs->selectedFile();
+    QString path;
+    if (fs) path = fs->selectedFile();
     delete fs;
     if (!path.isEmpty()) {
         frame.save(path);
@@ -611,26 +614,30 @@ void Monitor::slotSeek(int pos)
     if (render == NULL) return;
     slotActivateMonitor();
     render->seekToFrame(pos);
+    m_ruler->update();
 }
 
 void Monitor::checkOverlay()
 {
     if (m_overlay == NULL) return;
-    int pos = m_ruler->position();
+    QString overlayText;
+    int pos = render->seekFramePosition();
     QPoint zone = m_ruler->zone();
     if (pos == zone.x())
-        m_overlay->setOverlayText(i18n("In Point"));
+        overlayText = i18n("In Point");
     else if (pos == zone.y())
-        m_overlay->setOverlayText(i18n("Out Point"));
+        overlayText = i18n("Out Point");
     else {
         if (m_currentClip) {
-            QString markerComment = m_currentClip->markerComment(GenTime(pos, m_monitorManager->timecode().fps()));
-            if (markerComment.isEmpty())
-                m_overlay->setHidden(true);
-            else
-                m_overlay->setOverlayText(markerComment, false);
-        } else m_overlay->setHidden(true);
+            overlayText = m_currentClip->markerComment(GenTime(pos, m_monitorManager->timecode().fps()));
+           if (!overlayText.isEmpty()) {
+               m_overlay->setOverlayText(overlayText, false);
+               return;
+           }
+       }
     }
+    if (m_overlay->isVisible() && overlayText.isEmpty()) m_overlay->setOverlayText(QString(), false);
+    else m_overlay->setOverlayText(overlayText);
 }
 
 void Monitor::slotStart()
@@ -666,8 +673,20 @@ void Monitor::slotRewind(double speed)
     slotActivateMonitor();
     if (speed == 0) {
         double currentspeed = render->playSpeed();
-        if (currentspeed >= 0) render->play(-2);
-        else render->play(currentspeed * 2);
+       if (currentspeed >= 0) render->play(-1);
+       else switch((int) currentspeed) {
+           case -1:
+               render->play(-2);
+               break;
+           case -2:
+               render->play(-3);
+               break;
+           case -3:
+               render->play(-5);
+               break;
+           default:
+               render->play(-8);
+       }
     } else render->play(speed);
     //m_playAction->setChecked(true);
     m_playAction->setIcon(m_pauseIcon);
@@ -678,8 +697,20 @@ void Monitor::slotForward(double speed)
     slotActivateMonitor();
     if (speed == 0) {
         double currentspeed = render->playSpeed();
-        if (currentspeed <= 1) render->play(2);
-        else render->play(currentspeed * 2);
+       if (currentspeed <= 0) render->play(1);
+        else switch((int) currentspeed) {
+           case 1:
+               render->play(2);
+               break;
+           case 2:
+               render->play(3);
+               break;
+           case 3:
+               render->play(5);
+               break;
+           default:
+               render->play(8);
+       }
     } else render->play(speed);
     //m_playAction->setChecked(true);
     m_playAction->setIcon(m_pauseIcon);
@@ -690,6 +721,7 @@ void Monitor::slotRewindOneFrame(int diff)
     slotActivateMonitor();
     render->play(0);
     render->seekToFrameDiff(-diff);
+    m_ruler->update();
 }
 
 void Monitor::slotForwardOneFrame(int diff)
@@ -697,11 +729,11 @@ void Monitor::slotForwardOneFrame(int diff)
     slotActivateMonitor();
     render->play(0);
     render->seekToFrameDiff(diff);
+    m_ruler->update();
 }
 
 void Monitor::seekCursor(int pos)
 {
-    //slotActivateMonitor();
     if (m_ruler->slotNewValue(pos)) {
         checkOverlay();
         m_timePos->setValue(pos);
@@ -734,8 +766,8 @@ void Monitor::stop()
 
 void Monitor::start()
 {
-    if (!isVisible()) return;
-    if (render) render->start();
+    if (!isVisible() || !isActive()) return;
+    if (render) render->startConsumer();
 }
 
 void Monitor::refreshMonitor(bool visible)
@@ -779,6 +811,7 @@ void Monitor::slotPlay()
         m_playAction->setIcon(m_playIcon);
         render->switchPlay(false);
     }
+    m_ruler->refreshRuler();
 }
 
 void Monitor::slotPlayZone()
@@ -821,6 +854,7 @@ 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;
@@ -829,8 +863,9 @@ void Monitor::slotSetClipProducer(DocClipBase *clip, QPoint zone, bool forceUpda
     }
 
     if (clip != m_currentClip || forceUpdate) {
+       if (m_currentClip) m_currentClip->lastSeekPosition = render->seekFramePosition();
         m_currentClip = clip;
-        if (m_currentClip) slotActivateMonitor();
+       if (position == -1) position = clip->lastSeekPosition;
         updateMarkers(clip);
         Mlt::Producer *prod = NULL;
         if (clip) prod = clip->getCloneProducer();
@@ -913,7 +948,7 @@ void Monitor::slotSwitchMonitorInfo(bool show)
     KdenliveSettings::setDisplayMonitorInfo(show);
     if (show) {
         if (m_overlay) return;
-        if (m_monitorRefresh == NULL) {
+        if (videoSurface == NULL) {
             // Using OpenGL display
 #ifdef USE_OPENGL
             if (m_glWidget->layout()) delete m_glWidget->layout();
@@ -925,13 +960,13 @@ void Monitor::slotSwitchMonitorInfo(bool show)
             m_glWidget->setLayout(layout);
 #endif
         } else {
-            if (m_monitorRefresh->layout()) delete m_monitorRefresh->layout();
+            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);
-            m_monitorRefresh->setLayout(layout);
+            videoSurface->setLayout(layout);
             m_overlay->raise();
             m_overlay->setHidden(true);
         }
@@ -989,24 +1024,46 @@ void Monitor::slotSetSelectedClip(Transition* item)
 }
 
 
-void Monitor::slotEffectScene(bool show)
+void Monitor::slotShowEffectScene(bool show, bool manuallyTriggered)
 {
     if (m_id == Kdenlive::projectMonitor) {
-        if (m_monitorRefresh) {
-            m_monitorRefresh->setVisible(!show);
-        } else {
+        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
-            m_glWidget->setVisible(!show);
+            } else {
+                m_glWidget->setVisible(false);
 #endif
-        }
-        m_effectWidget->setVisible(show);
-        m_effectWidget->getVisibilityAction()->setChecked(show);
-        emit requestFrameForAnalysis(show);
-        if (show) {
+            }
+            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_videoBox->setEnabled(show);
-        render->doRefresh();
+        if (!manuallyTriggered)
+            m_effectWidget->showVisibilityButton(show);
+        setUpdatesEnabled(true);
+        videoBox->setEnabled(show);
+        //render->doRefresh();
     }
 }
 
@@ -1054,23 +1111,13 @@ void Monitor::reloadProducer(const QString &id)
         slotSetClipProducer(m_currentClip, m_currentClip->zone(), true);
 }
 
-MonitorRefresh::MonitorRefresh(QWidget* parent) :
-    QWidget(parent)
-    , m_renderer(NULL)
-{
-    // MonitorRefresh is used as container for the SDL display (it's window id is passed to SDL)
-    setAttribute(Qt::WA_PaintOnScreen);
-    setAttribute(Qt::WA_OpaquePaintEvent);
-    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
-    //setAttribute(Qt::WA_NoSystemBackground);
-}
-
-void MonitorRefresh::setRenderer(Render* render)
+void Monitor::setPalette ( const QPalette & p)
 {
-    m_renderer = render;
+    QWidget::setPalette(p);
+    if (m_ruler) m_ruler->updatePalette();
+    
 }
 
-
 Overlay::Overlay(QWidget* parent) :
     QLabel(parent)
 {
@@ -1102,16 +1149,23 @@ void Overlay::mouseDoubleClickEvent ( QMouseEvent * event )
 
 void Overlay::setOverlayText(const QString &text, bool isZone)
 {
+    if (text.isEmpty()) {
+       QPalette p;
+       p.setColor(QPalette::Base, KdenliveSettings::window_background());
+       setPalette(p);
+       setText(QString());
+       repaint();
+       setHidden(true);
+       return;
+    }
     setHidden(true);
-    m_isZone = isZone;
     QPalette p;
     p.setColor(QPalette::Text, Qt::white);
-    if (m_isZone) p.setColor(QPalette::Base, QColor(200, 0, 0));
+    if (isZone) p.setColor(QPalette::Base, QColor(200, 0, 0));
     else p.setColor(QPalette::Base, QColor(0, 0, 200));
     setPalette(p);
     setText(' ' + text + ' ');
     setHidden(false);
-    update();
 }