ImportController.cpp 8.95 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.
 *****************************************************************************/

25
#include "ImportController.h"
Thomas Boquet's avatar
Thomas Boquet committed
26
#include "ui_ImportController.h"
27

28
#include "Clip.h"
29
#include "ClipMetadataDisplayer.h"
Thomas Boquet's avatar
Thomas Boquet committed
30
#include "ClipRenderer.h"
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
31
#include "Library.h"
32
#include "Media.h"
33
#include "MediaCellView.h"
34
#include "MediaListView.h"
35 36 37
#include "MetaDataManager.h"
#include "PreviewWidget.h"
#include "TagWidget.h"
38

39
#include <QFileSystemModel>
40
#include <QPalette>
41
#include <QSettings>
42
#include <QTime>
43
#include <QTimer>
Thomas Boquet's avatar
Thomas Boquet committed
44

45 46
#include <QtDebug>

Thomas Boquet's avatar
Thomas Boquet committed
47 48
ImportController::ImportController(QWidget *parent) :
    QDialog(parent),
49
    m_ui(new Ui::ImportController),
50 51
    m_nbMediaToLoad( 0 ),
    m_nbMediaLoaded( 0 )
Thomas Boquet's avatar
Thomas Boquet committed
52 53
{
    m_ui->setupUi(this);
54 55
    //The renderer will be deleted by the PreviewWidget
    m_clipRenderer = new ClipRenderer;
56
    m_ui->previewContainer->setRenderer( m_clipRenderer );
57
    m_stackNav = new StackViewController( m_ui->stackViewContainer );
58
    m_temporaryMedias = new MediaContainer;
59
    m_mediaListView = new MediaListView( m_stackNav, m_temporaryMedias );
Thomas Boquet's avatar
Thomas Boquet committed
60
    m_tag = new TagWidget( m_ui->tagContainer, 6 );
61
    m_filesModel = new QFileSystemModel( this );
62
    m_stackNav->pushViewController( m_mediaListView );
Thomas Boquet's avatar
Thomas Boquet committed
63

64
    m_nameFilters << Media::AudioExtensions.split(' ', QString::SkipEmptyParts)
65 66 67
            << Media::VideoExtensions.split(' ', QString::SkipEmptyParts)
            << Media::ImageExtensions.split(' ', QString::SkipEmptyParts);
    m_filesModel->setFilter( QDir::AllDirs | QDir::AllEntries | QDir::NoDotAndDotDot );
68
    m_filesModel->setNameFilters( m_nameFilters );
69
    m_filesModel->setRootPath( "/" );
70
    m_filesModel->setNameFilterDisables( false );
71
    restoreCurrentPath();
72
    m_filesModel->sort( 0 );
73

Thomas Boquet's avatar
Thomas Boquet committed
74
    m_ui->treeView->setModel( m_filesModel );
75
    m_ui->treeView->setHeaderHidden( true );
76
    m_ui->treeView->setCurrentIndex( m_filesModel->index( m_currentlyWatchedDir ) );
Thomas Boquet's avatar
Thomas Boquet committed
77
    m_ui->treeView->setExpanded( m_ui->treeView->currentIndex() , true );
78 79
    m_ui->treeView->header()->setStretchLastSection( false );
    m_ui->treeView->header()->setResizeMode( QHeaderView::ResizeToContents );
Thomas Boquet's avatar
Thomas Boquet committed
80 81 82
    m_ui->treeView->setColumnHidden( 1, true );
    m_ui->treeView->setColumnHidden( 2, true );
    m_ui->treeView->setColumnHidden( 3, true );
83

84
    m_ui->forwardButton->setEnabled( true );
Thomas Boquet's avatar
Thomas Boquet committed
85

86
    m_ui->progressBar->setHidden( true );
87 88
    m_ui->errorLabelImg->hide();
    m_ui->errorLabel->hide();
89

90 91 92 93 94 95 96
    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() ) );

97
    connect( this, SIGNAL( clipSelected( Clip* ) ),
98
             m_clipRenderer, SLOT( setClip( Clip* ) ) );
99
    connect( m_mediaListView, SIGNAL( clipSelected( Clip* ) ),
100
             this, SLOT( clipSelection( Clip* ) ) );
101 102
    connect( m_mediaListView, SIGNAL( clipRemoved( const QUuid& ) ),
             m_clipRenderer, SLOT( clipUnloaded( const QUuid& ) ) );
103 104 105

    connect( MetaDataManager::getInstance(), SIGNAL( failedToCompute( Media* ) ),
             this, SLOT( failedToLoad( Media* ) ) );
Thomas Boquet's avatar
Thomas Boquet committed
106 107 108 109 110 111 112 113 114
}

ImportController::~ImportController()
{
    delete m_ui;
    delete m_stackNav;
    delete m_tag;
}

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

129
void
130
ImportController::clipSelection( Clip* clip )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
131
{
132
    const QUuid& uuid = clip->uuid();
133 134
    if ( m_currentUuid == uuid )
        return ;
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
135
    m_ui->metadataContainer->setWatchedClip( clip );
136
    m_ui->previewContainer->stop();
137
    m_currentUuid = uuid;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
138 139
    m_tag->clipSelected( clip );
    emit clipSelected( clip );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
140 141
}

142
void
143
ImportController::importMedia( const QString &filePath )
Thomas Boquet's avatar
Thomas Boquet committed
144
{
145 146
    if ( Library::getInstance()->mediaAlreadyLoaded( filePath ) == true ||
         m_temporaryMedias->mediaAlreadyLoaded( filePath ) == true )
147
        return ;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
148

149
    Media*  media = m_temporaryMedias->addMedia( filePath );
150 151
    if ( media == NULL )
    {
Nikoli's avatar
Nikoli committed
152
        qCritical() << "An error occurred while loading media:" << filePath;
153 154
        return ;
    }
155 156 157
    Clip*   clip = new Clip( media );
    media->setBaseClip( clip );
    m_temporaryMedias->addClip( clip );
158 159
    ++m_nbMediaToLoad;
    m_ui->progressBar->setMaximum( m_nbMediaToLoad );
Thomas Boquet's avatar
Thomas Boquet committed
160 161
}

162 163 164 165
void
ImportController::importDir( const QString &path )
{
    QDir            dir( path );
166
    QFileInfoList   files = dir.entryInfoList( m_nameFilters, QDir::NoDotAndDotDot | QDir::Readable
167 168 169 170 171
                                               | QDir::AllEntries );

    foreach ( QFileInfo fInfo, files )
    {
        if ( fInfo.isDir() == true )
172
            importDir( fInfo.absoluteFilePath() );
173
        else
174
            importMedia( fInfo.absoluteFilePath() );
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
    }
}

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 );
}

190 191
void
ImportController::treeViewClicked( const QModelIndex& index )
Thomas Boquet's avatar
Thomas Boquet committed
192 193 194 195
{
    if ( m_filesModel->isDir( index ) )
    {
        m_currentlyWatchedDir = m_filesModel->filePath( index );
196
        saveCurrentPath();
Thomas Boquet's avatar
Thomas Boquet committed
197 198 199 200
    }
    m_ui->forwardButton->setEnabled( true );
}

201 202
void
ImportController::treeViewDoubleClicked( const QModelIndex& index )
Thomas Boquet's avatar
Thomas Boquet committed
203
{
204 205
    if ( m_filesModel->isDir( index ) == false )
        forwardButtonClicked();
Thomas Boquet's avatar
Thomas Boquet committed
206
}
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
207

208 209
void
ImportController::reject()
210
{
211
    m_ui->previewContainer->stop();
212
    m_mediaListView->clear();
213
    m_temporaryMedias->clear();
214
    collapseAllButCurrentPath();
215
    m_clipRenderer->setClip( NULL );
216
    done( Rejected );
217 218
}

219 220
void
ImportController::accept()
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
221
{
222
    m_mediaListView->clear();
223
    m_ui->previewContainer->stop();
224
    collapseAllButCurrentPath();
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
225
    foreach ( Clip* clip, m_temporaryMedias->clips().values() )
226
        Library::getInstance()->addClip( clip );
227
    m_temporaryMedias->removeAll();
228
    m_clipRenderer->setClip( NULL );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
229 230
    done( Accepted );
}
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
231

232 233 234 235 236 237 238 239 240 241 242 243
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 );
    }
244
    m_ui->forwardButton->setEnabled( true );
245 246
}

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
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();
}
263 264

void
265
ImportController::mediaLoaded()
266
{
267 268 269 270 271
    ++m_nbMediaLoaded;
    if ( m_nbMediaLoaded == m_nbMediaToLoad )
    {
        m_nbMediaLoaded = 0;
        m_nbMediaToLoad = 0;
272
        m_ui->progressBar->hide();
273 274
    }
    else
275 276 277 278 279
    {
        if ( m_nbMediaToLoad > 3 )
            m_ui->progressBar->show();
        m_ui->progressBar->setValue( m_nbMediaLoaded );
    }
280 281

}
282 283 284 285

void
ImportController::failedToLoad( Media *media )
{
286
    m_ui->errorLabel->setText( tr( "Failed to load %1").arg(
287
            media->fileInfo()->fileName() ) );
288 289 290
    m_ui->errorLabelImg->show();
    m_ui->errorLabel->show();
    QTimer::singleShot( 3000, this, SLOT( hideErrors() ) );
291
    m_temporaryMedias->deleteClip( media->baseClip()->uuid() );
292
}
293 294 295 296 297 298 299

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