PreviewWidget.cpp 7.71 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*****************************************************************************
 * PreviewWidget.cpp : Main widget for preview. Will dispatch on Clip or
 *                     Render preview
 *****************************************************************************
 * Copyright (C) 2008-2009 the VLMC team
 *
 * Authors: Hugo Beauzee-Luyssen <hugo@vlmc.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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include <QUrl>
25
#include <QtDebug>
26
#include <QMetaMethod>
27 28 29 30 31 32

#include "ui_PreviewWidget.h"
#include "gui/PreviewWidget.h"
#include "MediaListWidget.h"
#include "Library.h"

33
PreviewWidget::PreviewWidget( MainWorkflow* mainWorkflow, QWidget *parent ) :
34
    QWidget( parent ),
35 36
    m_ui( new Ui::PreviewWidget ),
    m_currentPreviewRenderer( NULL ),
37 38
    m_previewStopped( true ),
    m_sliderPosBackup( 0 )
39 40 41 42 43 44 45 46 47 48 49 50 51 52
{
    m_ui->setupUi( this );
    m_ui->groupBoxButton->hide();
    m_ui->seekSlider->setMinimum( 0 );
    m_ui->seekSlider->setMaximum( 1000 );
    m_ui->seekSlider->setSingleStep( 2 );
    m_ui->seekSlider->setFocusPolicy( Qt::NoFocus );

    setAcceptDrops( true );

    connect( m_ui->seekSlider, SIGNAL( sliderPressed() ),       this,   SLOT( seekSliderPressed() ) );
    connect( m_ui->seekSlider, SIGNAL( sliderPosChanged(int) ), this,   SLOT( seekSliderMoved(int) ) );
    connect( m_ui->seekSlider, SIGNAL( sliderReleased() ),      this,   SLOT( seekSliderReleased() ) );

53 54
    initClipPreview();
    initRenderPreview( mainWorkflow );
55 56

    m_currentMode = m_ui->tabWidget->currentIndex();
57
    m_currentPreviewRenderer = m_renderPreview;
58
    connect( m_ui->tabWidget, SIGNAL( currentChanged(int) ), this, SLOT( changedTab(int) ) );
59 60 61 62 63
}

PreviewWidget::~PreviewWidget()
{
    delete m_ui;
64 65
    delete m_clipPreview;
    delete m_renderPreview;
66 67
}

68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
void    PreviewWidget::initClipPreview()
{
    m_clipPreview = new ClipPreviewWidget( m_ui->clipPreviewRenderWidget );
    connectPreview( m_clipPreview );
}

void    PreviewWidget::initRenderPreview( MainWorkflow* mainWorkflow )
{
    m_renderPreview = new RenderPreviewWidget( mainWorkflow, m_ui->renderPreviewRenderWidget );
    connectPreview( m_renderPreview );
}

void    PreviewWidget::connectPreview( GenericPreviewWidget* target )
{
    //WARNING:  the slots must NOT be virtual, since this is called from the constructor
    //          which would be unsafe... if not fatal...
    connect( target,     SIGNAL( stopped() ),                this,       SLOT( videoPaused() ) );
    connect( target,     SIGNAL( paused() ),                 this,       SLOT( videoPaused() ) );
    connect( target,     SIGNAL( playing() ),                this,       SLOT( videoPlaying() ) );
    connect( target,     SIGNAL( positionChanged(float) ),   this,       SLOT( positionChanged(float) ) );
    connect( target,     SIGNAL( endReached() ),             this,       SLOT( endReached() ) );
}

void    PreviewWidget::changeEvent( QEvent *e )
92 93 94 95 96 97 98 99 100 101 102 103 104
{
    switch ( e->type() )
    {
    case QEvent::LanguageChange:
        m_ui->retranslateUi( this );
        break;
    default:
        break;
    }
}

void    PreviewWidget::dragEnterEvent( QDragEnterEvent* event )
{
105 106 107
    if ( event->mimeData()->hasFormat( "vlmc/uuid" ) || 
         event->mimeData()->urls().count() == 1 )
    {
108
        event->acceptProposedAction();
109
    }
110 111 112 113
}

void    PreviewWidget::dropEvent( QDropEvent* event )
{
114 115 116
    //If the dropped event is a clip to preview :
    if ( event->mimeData()->hasFormat( "vlmc/uuid" ) ||
         event->mimeData()->urls().count() == 1 )
117
    {
118 119 120 121 122 123 124
        Media* media;
        if ( event->mimeData()->urls().count() == 1 )
        {
            Library* lib = Library::getInstance();
            lib->newMediaLoadingAsked( event->mimeData()->urls()[0].path() );
            media = lib->getMedia( event->mimeData()->urls()[0].path() );
        }
125
        else //TODO: Could this rely on an implicit QString CTOR ?
126 127
            media = Library::getInstance()->getMedia( QUuid( ( const QString& )event->mimeData()->data( "vlmc/uuid" ) ) );

128 129 130
        if ( m_currentMode != PreviewWidget::clipPreviewMode )
            m_ui->tabWidget->setCurrentIndex( PreviewWidget::clipPreviewMode );

131 132 133
        m_clipPreview->startPreview( media );
        event->acceptProposedAction();
        m_previewStopped = false;
134
    }
135
    //else: I don't see how we could drag and drop a workflow :o (at the moment)
136 137 138 139 140 141 142 143 144 145
}

void    PreviewWidget::positionChanged( float newPos )
{
    m_ui->seekSlider->setValue( (int)( newPos * 1000.0 ) );
}


void    PreviewWidget::seekSliderPressed()
{
146
    disconnect( m_currentPreviewRenderer, SIGNAL( positionChanged( float ) ),
147 148 149 150 151 152 153 154 155 156 157
                this, SLOT( positionChanged( float ) ) );
}

void    PreviewWidget::seekSliderMoved( int )
{
    if ( m_ui->seekSlider->value() == m_ui->seekSlider->maximum() )
    {
        m_endReached = true;
        return;
    }
    m_endReached = false;
158 159
    //Putting back the slider value into vlc position
    m_currentPreviewRenderer->setPosition( (float)m_ui->seekSlider->value() / 1000.0f );
160 161 162 163 164 165 166 167 168 169
}

void    PreviewWidget::seekSliderReleased()
{
    if ( m_endReached == true && m_previewStopped == false )
    {
        //When cursor reaches the maximum right, end reached becomes true.
        //When we will release our slider, if endReached is true, we actually set the position.
        //Otherwise, we do nothing.
        //This prevents the video to stop if we put the slider to the maximum right by mistake
170
        m_currentPreviewRenderer->setPosition( (float)m_ui->seekSlider->maximum() );
171 172
        m_previewStopped = false;
    }
173 174
    connect( m_currentPreviewRenderer, SIGNAL( positionChanged( float ) ),
             this, SLOT( positionChanged( float ) ) );
175 176 177 178 179 180
}

void PreviewWidget::on_pushButtonPlay_clicked()
{
    if ( m_previewStopped == true )
        m_previewStopped = false;
181 182 183 184
//    int     methodIndex = m_currentPreviewRenderer->metaObject()->indexOfMethod("togglePlayPause(bool)");
//    qDebug() << methodIndex;
//    QMetaMethod method = m_currentPreviewRenderer->metaObject()->method( methodIndex );
//    qDebug() << method.invoke( m_currentPreviewRenderer, Qt::QueuedConnection, Q_ARG(bool, false) );
185
    m_currentPreviewRenderer->togglePlayPause();
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
}

void PreviewWidget::videoPaused()
{
    m_ui->pushButtonPlay->setIcon( QIcon( ":/images/play" ) );
}

void PreviewWidget::videoPlaying()
{
    m_ui->pushButtonPlay->setIcon( QIcon( ":/images/pause" ) );
}

void    PreviewWidget::endReached()
{
    m_previewStopped = true;

    m_ui->pushButtonPlay->setIcon( QIcon( ":/images/play" ) );
    m_ui->seekSlider->setValue( 0 );
}
205 206 207

void    PreviewWidget::changedTab( int tabId )
{
208 209
    m_currentPreviewRenderer->togglePlayPause( true );

210
    if ( tabId == PreviewWidget::clipPreviewMode )
211
    {
212
        m_currentPreviewRenderer = m_clipPreview;
213
    }
214
    else if ( tabId == PreviewWidget::renderPreviewMode )
215
    {
216
        m_currentPreviewRenderer = m_renderPreview;
217
    }
218 219 220
    else
        qDebug() << "Unknown and uncoherent tabId for PreviewWidget : " << tabId;
    m_currentMode = !m_currentMode;
221 222

    int   tmp = m_ui->seekSlider->value();
223 224
    m_ui->seekSlider->setValue( m_sliderPosBackup );
    m_sliderPosBackup = tmp;
225
}