MediaCellView.cpp 8.69 KB
Newer Older
1 2 3
/*****************************************************************************
 * MediaCellView.cpp
 *****************************************************************************
Ludovic Fauvet's avatar
Ludovic Fauvet committed
4
 * Copyright (C) 2008-2010 VideoLAN
5 6
 *
 * Authors: Thomas Boquet <thomas.boquet@gmail.com>
7
 *          Hugo Beauzée-Luyssen <hugo@beauzee.fr>
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * 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.
 *****************************************************************************/

Thomas Boquet's avatar
Thomas Boquet committed
24 25
#include "MediaCellView.h"
#include "ui_MediaCellView.h"
26

27 28
#include "Clip.h"
#include "ClipProperty.h"
29
#include "ISource.h"
30
#include "Library.h"
31 32
#include "Media.h"
#include "MetaDataManager.h"
33
#include "MainWorkflow.h"
34
#include "Workspace.h"
35

36
#include <QMenu>
37
#include <QMessageBox>
38
#include <QTime>
39 40
#include <QMimeData>
#include <QDrag>
Thomas Boquet's avatar
Thomas Boquet committed
41

42 43 44 45
MediaCellView::MediaCellView( Clip* clip, QWidget *parent ) :
        QWidget( parent ),
        m_ui( new Ui::MediaCellView ),
        m_clip( clip )
Thomas Boquet's avatar
Thomas Boquet committed
46 47
{
    m_ui->setupUi( this );
48
    setFocusPolicy( Qt::ClickFocus );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
49
    setAutoFillBackground( true );
50 51
    connect( m_ui->delLabel, SIGNAL( clicked( QWidget*, QMouseEvent* ) ),
             this, SLOT( deleteButtonClicked( QWidget*, QMouseEvent* ) ) );
52 53 54 55 56
    connect( m_ui->arrow,
             SIGNAL( clicked( QWidget*, QMouseEvent* ) ),
             SLOT( arrowButtonClicked( QWidget*, QMouseEvent* ) ) );
    m_ui->clipCount->setText( QString::number( clip->getChilds()->count() ) );
    connect( clip->getChilds(), SIGNAL( newClipLoaded( Clip* ) ),
57 58 59
             this, SLOT( nbClipUpdated() ) );
    connect( clip->getChilds(), SIGNAL( clipRemoved( const QUuid& ) ),
             this, SLOT( nbClipUpdated() ) );
60
    if ( clip->getChilds()->count() == 0 )
61 62 63 64 65
    {
        m_ui->clipCount->hide();
        m_ui->clipCountLabel->hide();
        m_ui->arrow->hide();
    }
66
    if ( clip->getMedia()->isMetadataComputed() == false )
67 68
    {
        m_ui->thumbnail->setEnabled( false );
69 70
        connect( MetaDataManager::getInstance(), SIGNAL( startingComputing( const Media* )),
                 this, SLOT( metadataComputingStarted( const Media* ) ), Qt::DirectConnection );
71
    }
72
    connect( clip->getMedia(), SIGNAL( metaDataComputed(const Media*) ),
73
             this, SLOT( metadataUpdated( const Media*) ) );
74
    connect( clip->getMedia(), SIGNAL( snapshotComputed(const Media*) ),
75
             this, SLOT( snapshotUpdated(const Media*) ) );
76

77 78
    setThumbnail( clip->getMedia()->snapshot() );
    setTitle( clip->getMedia()->fileName() );
79
    setLength( clip->lengthSecond() * 1000 );
80 81
}

82 83 84 85 86
MediaCellView::~MediaCellView()
{
    delete m_ui;
}

87 88 89 90 91 92 93 94 95 96 97 98
void
MediaCellView::metadataComputingStarted( const Media *media )
{
    if ( media != m_clip->getMedia() )
        return ;
    //Disable the delete button to avoid deleting the media while metadata are computed.
    m_ui->delLabel->setEnabled( false );
    //We don't need this event anymore now.
    disconnect( MetaDataManager::getInstance(), SIGNAL( startingComputing( const Media* )),
             this, SLOT( metadataComputingStarted( const Media* ) ) );
}

99 100 101
void
MediaCellView::metadataUpdated( const Media *media )
{
102
    setLength( media->source()->length() );
103
    m_ui->thumbnail->setEnabled( true );
104 105 106 107
    //If the media is a Video or an Image, we must wait for the snapshot to be computer
    //before allowing deletion.
    if ( media->fileType() == Media::Audio )
        m_ui->delLabel->setEnabled( true );
108 109 110 111 112 113
}

void
MediaCellView::snapshotUpdated( const Media *media )
{
    setThumbnail( media->snapshot() );
114
    m_ui->delLabel->setEnabled( true );
Thomas Boquet's avatar
Thomas Boquet committed
115 116
}

117 118
void
MediaCellView::changeEvent( QEvent *e )
Thomas Boquet's avatar
Thomas Boquet committed
119 120 121 122 123 124
{
    QWidget::changeEvent( e );
    switch ( e->type() )
    {
    case QEvent::LanguageChange:
        m_ui->retranslateUi( this );
125 126
        nbClipUpdated();
        setLength( m_clip->lengthSecond() * 1000 );
Thomas Boquet's avatar
Thomas Boquet committed
127 128 129 130 131 132
        break;
    default:
        break;
    }
}

133 134
void
MediaCellView::setTitle( const QString& title )
Thomas Boquet's avatar
Thomas Boquet committed
135 136 137 138
{
    m_ui->title->setText( title );
}

139
void
140
MediaCellView::nbClipUpdated()
141
{
142 143 144 145 146 147
    quint32     nbClips;

    if ( m_clip->isRootClip() == true )
        nbClips = m_clip->getChilds()->count();
    else
        nbClips = m_clip->getParent()->getChilds()->count();
148 149 150 151 152 153 154 155 156 157 158 159 160

    if ( nbClips == 0 )
    {
        m_ui->clipCount->hide();
        m_ui->clipCountLabel->hide();
        m_ui->arrow->hide();
    }
    else
    {
        m_ui->clipCount->show();
        m_ui->clipCountLabel->show();
        m_ui->arrow->show();
    }
161 162
    //Use QString::number in any case, so we use the current locale.
    m_ui->clipCount->setText( QString::number( nbClips ) );
163 164
}

165 166
void
MediaCellView::setThumbnail( const QPixmap &pixmap )
Thomas Boquet's avatar
Thomas Boquet committed
167
{
Thomas Boquet's avatar
Thomas Boquet committed
168
    m_ui->thumbnail->setScaledContents( false );
169
    m_ui->thumbnail->setPixmap( pixmap.scaled( 64, 64, Qt::KeepAspectRatio ) );
Thomas Boquet's avatar
Thomas Boquet committed
170 171
}

172 173
const QPixmap*
MediaCellView::getThumbnail() const
Thomas Boquet's avatar
Thomas Boquet committed
174 175 176 177
{
    return m_ui->thumbnail->pixmap();
}

178 179
QString
MediaCellView::title() const
Thomas Boquet's avatar
Thomas Boquet committed
180 181 182 183
{
    return m_ui->title->text();
}

184 185
void
MediaCellView::mouseDoubleClickEvent( QMouseEvent* event )
186
{
187
    if ( ( event->buttons() | Qt::LeftButton ) == Qt::LeftButton )
188
    {
189
        ClipProperty* cp = new ClipProperty( m_clip, this );
190
        cp->setModal( true );
191
        cp->exec();
192
        delete cp;
193 194
    }
}
195

196 197
void
MediaCellView::mousePressEvent( QMouseEvent* event )
198
{
Thomas Boquet's avatar
Thomas Boquet committed
199 200
    QWidget::mousePressEvent( event );

201 202
    if ( ( event->buttons() | Qt::LeftButton ) == Qt::LeftButton )
    {
Thomas Boquet's avatar
Thomas Boquet committed
203
        m_dragStartPos = event->pos();
204
        emit cellSelected( m_clip->uuid() );
205 206
    }
}
Thomas Boquet's avatar
Thomas Boquet committed
207

208 209
void
MediaCellView::mouseMoveEvent( QMouseEvent* event )
Thomas Boquet's avatar
Thomas Boquet committed
210 211 212 213 214 215 216 217 218
{
    if ( ( event->buttons() | Qt::LeftButton ) != Qt::LeftButton )
         return;

    if ( ( event->pos() - m_dragStartPos ).manhattanLength()
          < QApplication::startDragDistance() )
        return;

    QMimeData* mimeData = new QMimeData;
219
    mimeData->setData( "vlmc/uuid", m_clip->fullId().toLatin1() );
Thomas Boquet's avatar
Thomas Boquet committed
220 221
    QDrag* drag = new QDrag( this );
    drag->setMimeData( mimeData );
222
    const Media*  parent = m_clip->getMedia();
223
    drag->setPixmap( parent->snapshot().scaled( 100, 100, Qt::KeepAspectRatio ) );
Thomas Boquet's avatar
Thomas Boquet committed
224 225
    drag->exec( Qt::CopyAction | Qt::MoveAction, Qt::CopyAction );
}
226

227 228
void
MediaCellView::deleteButtonClicked( QWidget*, QMouseEvent* )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
229
{
230 231 232 233
    if ( MainWorkflow::getInstance()->contains( m_clip->uuid() ) == true )
    {
        QMessageBox msgBox;
        msgBox.setText( tr( "This clip or some of its children are contained in the timeline." ) );
Nikoli's avatar
Nikoli committed
234
        msgBox.setInformativeText( tr( "Removing it will delete it from the timeline. Do you want to proceed?" ) );
235 236 237 238 239 240 241 242 243 244 245 246 247
        msgBox.setStandardButtons( QMessageBox::Ok | QMessageBox::Cancel );
        msgBox.setDefaultButton( QMessageBox::Ok );
        int     ret = msgBox.exec();

        switch ( ret )
        {
            case QMessageBox::Ok:
                break ;
            case QMessageBox::Cancel:
            default:
                return ;
        }
    }
248
    emit cellDeleted( m_clip );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
249
}
250

251 252
void
MediaCellView::arrowButtonClicked( QWidget*, QMouseEvent* )
253
{
254
    emit arrowClicked( m_clip->uuid() );
255 256
}

257
void
258
MediaCellView::setLength( qint64 length )
259 260
{
    QTime   duration;
261
    duration = duration.addMSecs( length );
262 263
    m_ui->length->setText( duration.toString( "hh:mm:ss" ) );
}
264

265 266 267 268 269
const QUuid&
MediaCellView::uuid() const
{
    return m_clip->uuid();
}
270 271 272 273 274 275

const Clip*
MediaCellView::clip() const
{
    return m_clip;
}
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292

void
MediaCellView::contextMenuEvent( QContextMenuEvent *event )
{
    QMenu menu( this );

    //For now, as we only have the copy to workspace option, don't do anything if the clip
    //is not the root clip. Obviously, this will have to be removed if other actions are to be added.
    if ( m_clip->isRootClip() == false )
        return ;

    QAction* copyInWorkspace = menu.addAction( "Copy in workspace" );

    QAction* selectedAction = menu.exec( event->globalPos() );
    if ( selectedAction == NULL )
        return ;
    if ( copyInWorkspace == selectedAction )
293 294 295 296 297 298 299
    {
        if ( Workspace::getInstance()->copyToWorkspace( m_clip->getMedia() ) == false )
        {
            QMessageBox::warning( NULL, tr( "Can't copy to workspace" ),
                                  tr( "Can't copy this media to workspace: %1" ).arg( Workspace::getInstance()->lastError() ) );
        }
    }
300
}