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

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_metadataDisplayer = new ClipMetadataDisplayer( NULL, m_ui->metadataContainer );
63
    m_stackNav->pushViewController( m_mediaListView );
Thomas Boquet's avatar
Thomas Boquet committed
64

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

    restoreCurrentPath();

Thomas Boquet's avatar
Thomas Boquet committed
75
    m_ui->treeView->setModel( m_filesModel );
76
    m_ui->treeView->setHeaderHidden( true );
77
    m_ui->treeView->setCurrentIndex( m_filesModel->index( m_currentlyWatchedDir ) );
Thomas Boquet's avatar
Thomas Boquet committed
78
    m_ui->treeView->setExpanded( m_ui->treeView->currentIndex() , true );
79 80
    m_ui->treeView->header()->setStretchLastSection( false );
    m_ui->treeView->header()->setResizeMode( QHeaderView::ResizeToContents );
Thomas Boquet's avatar
Thomas Boquet committed
81 82 83
    m_ui->treeView->setColumnHidden( 1, true );
    m_ui->treeView->setColumnHidden( 2, true );
    m_ui->treeView->setColumnHidden( 3, true );
84 85 86
    for ( int i = 0; i < m_filesModel->columnCount(); ++i )
        m_ui->treeView->sortByColumn( i );

87
    m_ui->forwardButton->setEnabled( true );
Thomas Boquet's avatar
Thomas Boquet committed
88

89
    m_ui->progressBar->setHidden( true );
90 91
    m_ui->errorLabelImg->hide();
    m_ui->errorLabel->hide();
92

93 94 95 96 97 98 99
    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() ) );

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

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

ImportController::~ImportController()
{
113
    delete m_preview;
Thomas Boquet's avatar
Thomas Boquet committed
114 115 116 117 118
    delete m_ui;
    delete m_stackNav;
    delete m_tag;
}

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

133
void
134
ImportController::clipSelection( Clip* clip )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
135
{
136
    const QUuid& uuid = clip->uuid();
137 138
    if ( m_currentUuid == uuid )
        return ;
139
    m_metadataDisplayer->setWatchedClip( clip );
140 141
    m_preview->stop();
    m_currentUuid = uuid;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
142 143
    m_tag->clipSelected( clip );
    emit clipSelected( clip );
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
144 145
}

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

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

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

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

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

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

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

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

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

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

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

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

}
286 287 288 289

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

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