ImportController.cpp 10.2 KB
Newer Older
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
1 2 3
/*****************************************************************************
 * ImportController.cpp
 *****************************************************************************
Ludovic Fauvet's avatar
Ludovic Fauvet committed
4
 * Copyright (C) 2008-2010 VideoLAN
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
5 6 7
 *
 * Authors: Geoffroy Lacarriere <geoffroylaca@gmail.com>
 *          Thomas Boquet <thomas.boquet@gmail.com>
8
 *          Clement Chavance <chavance.c@gmail.com>
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
9
 *          Hugo Beauzée-Luyssen <hugo@vlmc.org>
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * 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
26
#include "ui_ImportController.h"
27

Thomas Boquet's avatar
Thomas Boquet committed
28
#include "ClipRenderer.h"
29
#include "ImportController.h"
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
30
#include "Library.h"
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
31
#include "MetaDataManager.h"
32
#include "MediaCellView.h"
33 34

#include <QPalette>
35
#include <QSettings>
36
#include <QTime>
37
#include <QTimer>
Thomas Boquet's avatar
Thomas Boquet committed
38 39 40

ImportController::ImportController(QWidget *parent) :
    QDialog(parent),
41 42
    m_ui(new Ui::ImportController),
    m_clipListController( 0 ),
43 44
    m_nbMediaToLoad( 0 ),
    m_nbMediaLoaded( 0 )
Thomas Boquet's avatar
Thomas Boquet committed
45 46 47 48
{
    m_ui->setupUi(this);
    m_preview = new PreviewWidget( new ClipRenderer, m_ui->previewContainer );
    m_stackNav = new StackViewController( m_ui->stackViewContainer, false );
49 50
    m_temporaryMedias = new MediaContainer;
    m_mediaListController = new MediaListViewController( m_stackNav, m_temporaryMedias );
Thomas Boquet's avatar
Thomas Boquet committed
51
    m_tag = new TagWidget( m_ui->tagContainer, 6 );
52
    m_filesModel = new QFileSystemModel( this );
Thomas Boquet's avatar
Thomas Boquet committed
53 54 55
    m_stackNav->pushViewController( m_mediaListController );

    QStringList filters;
56 57 58 59
    filters << Media::AudioExtensions.split(' ', QString::SkipEmptyParts)
            << Media::VideoExtensions.split(' ', QString::SkipEmptyParts)
            << Media::ImageExtensions.split(' ', QString::SkipEmptyParts);
    m_filesModel->setFilter( QDir::AllDirs | QDir::AllEntries | QDir::NoDotAndDotDot );
Thomas Boquet's avatar
Thomas Boquet committed
60 61 62
    m_filesModel->sort( 2, Qt::AscendingOrder );
    m_filesModel->sort( 0, Qt::AscendingOrder );
    m_filesModel->setNameFilters( filters );
63
    m_filesModel->setRootPath( "/" );
64
    m_filesModel->setNameFilterDisables( false );
65 66 67

    restoreCurrentPath();

Thomas Boquet's avatar
Thomas Boquet committed
68
    m_ui->treeView->setModel( m_filesModel );
69
    m_ui->treeView->setHeaderHidden( true );
70
    m_ui->treeView->setCurrentIndex( m_filesModel->index( m_currentlyWatchedDir ) );
Thomas Boquet's avatar
Thomas Boquet committed
71
    m_ui->treeView->setExpanded( m_ui->treeView->currentIndex() , true );
72 73
    m_ui->treeView->header()->setStretchLastSection( false );
    m_ui->treeView->header()->setResizeMode( QHeaderView::ResizeToContents );
Thomas Boquet's avatar
Thomas Boquet committed
74 75 76
    m_ui->treeView->setColumnHidden( 1, true );
    m_ui->treeView->setColumnHidden( 2, true );
    m_ui->treeView->setColumnHidden( 3, true );
77
    m_ui->forwardButton->setEnabled( true );
Thomas Boquet's avatar
Thomas Boquet committed
78

79
    m_ui->progressBar->setHidden( true );
80 81
    m_ui->errorLabelImg->hide();
    m_ui->errorLabel->hide();
82

83 84 85 86 87 88 89
    connect( m_ui->treeView, SIGNAL( clicked( QModelIndex ) ),
             this, SLOT( treeViewClicked( QModelIndex ) ) );
    connect( m_ui->treeView, SIGNAL( doubleClicked( QModelIndex ) ),
             this, SLOT( treeViewDoubleClicked( QModelIndex ) ) );
    connect( m_ui->forwardButton, SIGNAL( clicked() ),
             this, SLOT( forwardButtonClicked() ) );

90
    connect( m_mediaListController, SIGNAL( clipSelected( Clip* ) ),
91
             qobject_cast<const ClipRenderer*>( m_preview->getGenericRenderer() ),
92 93 94 95
             SLOT( setClip( Clip* ) ) );
    connect( m_mediaListController, SIGNAL( clipSelected( Clip* ) ),
             this, SLOT( mediaSelection( Clip* ) ) );
    connect( m_mediaListController, SIGNAL( clipDeleted( const QUuid& ) ),
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
96 97
             qobject_cast<const ClipRenderer*>( m_preview->getGenericRenderer() ),
             SLOT( clipUnloaded( const QUuid& ) ) );
98 99 100

    connect( MetaDataManager::getInstance(), SIGNAL( failedToCompute( Media* ) ),
             this, SLOT( failedToLoad( Media* ) ) );
Thomas Boquet's avatar
Thomas Boquet committed
101 102 103 104
}

ImportController::~ImportController()
{
105
    delete m_preview;
Thomas Boquet's avatar
Thomas Boquet committed
106 107 108 109 110
    delete m_ui;
    delete m_stackNav;
    delete m_tag;
}

111 112
void
ImportController::changeEvent( QEvent *e )
Thomas Boquet's avatar
Thomas Boquet committed
113 114
{
    QDialog::changeEvent( e );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
115 116 117 118 119 120 121
    switch ( e->type() )
    {
        case QEvent::LanguageChange:
            m_ui->retranslateUi( this );
            break;
        default:
            break;
Thomas Boquet's avatar
Thomas Boquet committed
122 123 124
    }
}

125
void
126
ImportController::mediaSelection( Clip* clip )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
127
{
128
    const QUuid& uuid = clip->uuid();
129 130
    if ( m_currentUuid == uuid )
        return ;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
131 132
    Media*  media = clip->rootClip()->getMedia();
    setUIMetaData( clip->rootClip() );
133 134
    m_preview->stop();
    m_currentUuid = uuid;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
135 136
    m_tag->clipSelected( clip );
    emit clipSelected( clip );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
137 138
}

139 140
void
ImportController::clipSelection( const QUuid& uuid )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
141
{
142 143
    if ( uuid == m_currentUuid )
        return ;
144
    Clip*   clip = m_temporaryMedias->clip( uuid );
145 146

    if ( clip == NULL )
147
        return ;
148
    setUIMetaData( clip );
149
    m_preview->stop();
150
    emit clipSelected( clip );
Thomas Boquet's avatar
Thomas Boquet committed
151 152
}

153
void
154
ImportController::setUIMetaData( Clip* clip )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
155
{
156
    if ( clip != NULL )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
157 158 159
    {
        //Duration
        QTime   duration;
160
        duration = duration.addSecs( clip->lengthSecond() );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
161 162
        m_ui->durationValueLabel->setText( duration.toString( "hh:mm:ss" ) );
        //Filename || title
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
163
        m_ui->nameValueLabel->setText( clip->getMedia()->fileInfo()->fileName() );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
164
        m_ui->nameValueLabel->setWordWrap( true );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
165
        setWindowTitle( clip->getMedia()->fileInfo()->fileName() + " " + tr( "properties" ) );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
166
        //Resolution
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
167 168
        m_ui->resolutionValueLabel->setText( QString::number( clip->getMedia()->width() )
                                        + " x " + QString::number( clip->getMedia()->height() ) );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
169
        //FPS
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
170
        m_ui->fpsValueLabel->setText( QString::number( clip->getMedia()->fps() ) );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
171 172 173
    }
    else
    {
174 175 176 177
        m_ui->durationValueLabel->setText( "--:--:--" );
        m_ui->nameValueLabel->setText( "none" );
        m_ui->resolutionValueLabel->setText( "-- x --" );
        m_ui->fpsValueLabel->setText( "--" );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
178
    }
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
179 180
}

181
void
182
ImportController::importMedia( const QString &filePath )
Thomas Boquet's avatar
Thomas Boquet committed
183
{
184
    ++m_nbMediaToLoad;
185
    m_ui->progressBar->setMaximum( m_nbMediaToLoad );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
186

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
187
    m_temporaryMedias->addMedia( filePath );
Thomas Boquet's avatar
Thomas Boquet committed
188 189
}

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
void
ImportController::importDir( const QString &path )
{
    QDir            dir( path );
    QFileInfoList   files = dir.entryInfoList( QDir::NoDotAndDotDot | QDir::Readable
                                               | QDir::AllEntries );

    foreach ( QFileInfo fInfo, files )
    {
        if ( fInfo.isDir() == true )
            importDir( fInfo.absolutePath() );
        else
        {
            QString ext = fInfo.suffix();

            if ( Media::AudioExtensions.contains( ext ) ||
                 Media::VideoExtensions.contains( ext ) ||
                 Media::ImageExtensions.contains( ext ) )
            {
                importMedia( fInfo.absoluteFilePath() );
            }
        }
    }
}

void
ImportController::forwardButtonClicked()
{
    QModelIndex     index = m_ui->treeView->selectionModel()->currentIndex();
    QString         filePath = m_filesModel->fileInfo( index ).filePath();

    if ( !m_filesModel->isDir( index ) )
        importMedia( filePath );
    else
        importDir( filePath );
}

227 228
void
ImportController::treeViewClicked( const QModelIndex& index )
Thomas Boquet's avatar
Thomas Boquet committed
229 230 231 232
{
    if ( m_filesModel->isDir( index ) )
    {
        m_currentlyWatchedDir = m_filesModel->filePath( index );
233
        saveCurrentPath();
Thomas Boquet's avatar
Thomas Boquet committed
234 235 236 237
    }
    m_ui->forwardButton->setEnabled( true );
}

238 239
void
ImportController::treeViewDoubleClicked( const QModelIndex& index )
Thomas Boquet's avatar
Thomas Boquet committed
240
{
241 242
    if ( m_filesModel->isDir( index ) == false )
        forwardButtonClicked();
Thomas Boquet's avatar
Thomas Boquet committed
243
}
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
244

245 246
void
ImportController::reject()
247 248
{
    m_preview->stop();
249
    m_mediaListController->clear();
250
    m_temporaryMedias->clear();
251
    collapseAllButCurrentPath();
252
    done( Rejected );
253 254
}

255 256
void
ImportController::accept()
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
257
{
258
    m_mediaListController->clear();
259
    m_preview->stop();
260
    collapseAllButCurrentPath();
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
261 262
    foreach ( Clip* clip, m_temporaryMedias->clips().values() )
        Library::getInstance()->addMedia( clip->getMedia() );
263
    m_temporaryMedias->removeAll();
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
264 265
    done( Accepted );
}
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
266

267 268 269 270 271 272 273 274 275 276 277 278
void
ImportController::collapseAllButCurrentPath()
{
    m_ui->treeView->collapseAll();
    QStringList paths;
    for ( QDir directory( m_currentlyWatchedDir ); !directory.isRoot(); directory.cdUp() )
        paths.prepend( directory.absolutePath() );
    while ( paths.count() > 0 )
    {
        m_ui->treeView->setCurrentIndex( m_filesModel->index( paths.takeFirst() ) );
        m_ui->treeView->setExpanded( m_ui->treeView->currentIndex() , true );
    }
279
    m_ui->forwardButton->setEnabled( true );
280 281
}

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
void
ImportController::saveCurrentPath()
{
    QSettings s;
    s.setValue( "ImportPreviouslySelectPath", m_currentlyWatchedDir );
    s.sync();
}

void
ImportController::restoreCurrentPath()
{
    QSettings s;
    QVariant path = s.value( "ImportPreviouslySelectPath", QDir::homePath() );
    QFileInfo info = path.toString();
    m_currentlyWatchedDir = info.absoluteFilePath();
}
298 299

void
300
ImportController::mediaLoaded()
301
{
302 303 304 305 306
    ++m_nbMediaLoaded;
    if ( m_nbMediaLoaded == m_nbMediaToLoad )
    {
        m_nbMediaLoaded = 0;
        m_nbMediaToLoad = 0;
307
        m_ui->progressBar->hide();
308 309
    }
    else
310 311 312 313 314
    {
        if ( m_nbMediaToLoad > 3 )
            m_ui->progressBar->show();
        m_ui->progressBar->setValue( m_nbMediaLoaded );
    }
315 316

}
317 318 319 320

void
ImportController::failedToLoad( Media *media )
{
321
    m_ui->errorLabel->setText( tr( "Failed to load %1").arg(
322
            media->fileInfo()->fileName() ) );
323 324 325
    m_ui->errorLabelImg->show();
    m_ui->errorLabel->show();
    QTimer::singleShot( 3000, this, SLOT( hideErrors() ) );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
326 327
    delete m_temporaryMedias->removeClip( media->baseClip() );
    delete media;
328
}
329 330 331 332 333 334 335

void
ImportController::hideErrors()
{
    m_ui->errorLabelImg->hide();
    m_ui->errorLabel->hide();
}