ImportController.cpp 10.1 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>
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
8
 *          Hugo Beauzée-Luyssen <hugo@vlmc.org>
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * 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
25
#include "ui_ImportController.h"
26

Thomas Boquet's avatar
Thomas Boquet committed
27
#include "ClipRenderer.h"
28
#include "ImportController.h"
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
29
#include "Library.h"
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
30
#include "MetaDataManager.h"
31
#include "MediaCellView.h"
32
#include "MediaListView.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
    m_ui(new Ui::ImportController),
42 43
    m_nbMediaToLoad( 0 ),
    m_nbMediaLoaded( 0 )
Thomas Boquet's avatar
Thomas Boquet committed
44 45 46
{
    m_ui->setupUi(this);
    m_preview = new PreviewWidget( new ClipRenderer, m_ui->previewContainer );
47
    m_stackNav = new StackViewController( m_ui->stackViewContainer );
48
    m_temporaryMedias = new MediaContainer;
49
    m_mediaListView = new MediaListView( m_stackNav, m_temporaryMedias );
Thomas Boquet's avatar
Thomas Boquet committed
50
    m_tag = new TagWidget( m_ui->tagContainer, 6 );
51
    m_filesModel = new QFileSystemModel( this );
52
    m_stackNav->pushViewController( m_mediaListView );
Thomas Boquet's avatar
Thomas Boquet committed
53 54

    QStringList filters;
55 56 57 58
    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
59 60 61
    m_filesModel->sort( 2, Qt::AscendingOrder );
    m_filesModel->sort( 0, Qt::AscendingOrder );
    m_filesModel->setNameFilters( filters );
62
    m_filesModel->setRootPath( "/" );
63
    m_filesModel->setNameFilterDisables( false );
64 65 66

    restoreCurrentPath();

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

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

82 83 84 85 86 87 88
    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() ) );

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

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

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

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

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

138
void
139
ImportController::setUIMetaData( const Clip* clip )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
140
{
141
    if ( clip != NULL )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
142 143 144
    {
        //Duration
        QTime   duration;
145
        duration = duration.addSecs( clip->lengthSecond() );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
146 147
        m_ui->durationValueLabel->setText( duration.toString( "hh:mm:ss" ) );
        //Filename || title
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
148
        m_ui->nameValueLabel->setText( clip->getMedia()->fileInfo()->fileName() );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
149
        m_ui->nameValueLabel->setWordWrap( true );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
150
        setWindowTitle( clip->getMedia()->fileInfo()->fileName() + " " + tr( "properties" ) );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
151
        //Resolution
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
152 153
        m_ui->resolutionValueLabel->setText( QString::number( clip->getMedia()->width() )
                                        + " x " + QString::number( clip->getMedia()->height() ) );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
154
        //FPS
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
155
        m_ui->fpsValueLabel->setText( QString::number( clip->getMedia()->fps() ) );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
156 157 158
    }
    else
    {
159 160 161 162
        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
163
    }
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
164 165
}

166
void
167
ImportController::importMedia( const QString &filePath )
Thomas Boquet's avatar
Thomas Boquet committed
168
{
169
    ++m_nbMediaToLoad;
170
    m_ui->progressBar->setMaximum( m_nbMediaToLoad );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
171

172 173 174 175
    Media* media = m_temporaryMedias->addMedia( filePath );
    if ( media )
        connect( media, SIGNAL( metaDataComputed( const Media* ) ),
                 this, SLOT( metaDataComputed( const Media* ) ) );
Thomas Boquet's avatar
Thomas Boquet committed
176 177
}

178 179 180 181 182 183 184 185 186 187 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
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 );
}

215 216
void
ImportController::treeViewClicked( const QModelIndex& index )
Thomas Boquet's avatar
Thomas Boquet committed
217 218 219 220
{
    if ( m_filesModel->isDir( index ) )
    {
        m_currentlyWatchedDir = m_filesModel->filePath( index );
221
        saveCurrentPath();
Thomas Boquet's avatar
Thomas Boquet committed
222 223 224 225
    }
    m_ui->forwardButton->setEnabled( true );
}

226 227
void
ImportController::treeViewDoubleClicked( const QModelIndex& index )
Thomas Boquet's avatar
Thomas Boquet committed
228
{
229 230
    if ( m_filesModel->isDir( index ) == false )
        forwardButtonClicked();
Thomas Boquet's avatar
Thomas Boquet committed
231
}
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
232

233 234
void
ImportController::reject()
235 236
{
    m_preview->stop();
237
    m_mediaListView->clear();
238
    m_temporaryMedias->clear();
239
    collapseAllButCurrentPath();
240
    done( Rejected );
241 242
}

243 244
void
ImportController::accept()
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
245
{
246
    m_mediaListView->clear();
247
    m_preview->stop();
248
    collapseAllButCurrentPath();
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
249 250
    foreach ( Clip* clip, m_temporaryMedias->clips().values() )
        Library::getInstance()->addMedia( clip->getMedia() );
251
    m_temporaryMedias->removeAll();
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
252 253
    done( Accepted );
}
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
254

255 256 257 258 259 260 261 262 263 264 265 266
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 );
    }
267
    m_ui->forwardButton->setEnabled( true );
268 269
}

270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
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();
}
286 287

void
288
ImportController::mediaLoaded()
289
{
290 291 292 293 294
    ++m_nbMediaLoaded;
    if ( m_nbMediaLoaded == m_nbMediaToLoad )
    {
        m_nbMediaLoaded = 0;
        m_nbMediaToLoad = 0;
295
        m_ui->progressBar->hide();
296 297
    }
    else
298 299 300 301 302
    {
        if ( m_nbMediaToLoad > 3 )
            m_ui->progressBar->show();
        m_ui->progressBar->setValue( m_nbMediaLoaded );
    }
303 304

}
305 306 307 308

void
ImportController::failedToLoad( Media *media )
{
309
    m_ui->errorLabel->setText( tr( "Failed to load %1").arg(
310
            media->fileInfo()->fileName() ) );
311 312 313
    m_ui->errorLabelImg->show();
    m_ui->errorLabel->show();
    QTimer::singleShot( 3000, this, SLOT( hideErrors() ) );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
314 315
    delete m_temporaryMedias->removeClip( media->baseClip() );
    delete media;
316
}
317 318 319 320 321 322 323

void
ImportController::hideErrors()
{
    m_ui->errorLabelImg->hide();
    m_ui->errorLabel->hide();
}
324 325 326 327 328 329

void
ImportController::metaDataComputed( const Media *media )
{
    setUIMetaData( media->baseClip() );
}