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 56
    //The renderer will be deleted by the PreviewWidget
    m_clipRenderer = new ClipRenderer;
    m_preview = new PreviewWidget( m_clipRenderer, m_ui->previewContainer );
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
}

ImportController::~ImportController()
{
110
    delete m_preview;
Thomas Boquet's avatar
Thomas Boquet committed
111 112 113 114 115
    delete m_ui;
    delete m_stackNav;
    delete m_tag;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

}
283 284 285 286

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

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