Library.cpp 8.57 KB
Newer Older
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
1 2 3
/*****************************************************************************
 * Library.cpp: Multimedia library
 *****************************************************************************
Ludovic Fauvet's avatar
Ludovic Fauvet committed
4
 * Copyright (C) 2008-2010 VideoLAN
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * Authors: Hugo Beauzee-Luyssen <hugo@vlmc.org>
 *
 * 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.
 *****************************************************************************/

23 24 25
/** \file
  * This file the library contains class implementation.
  * It's the the backend part of the Library widget of vlmc.
26
  * It can load and unload Medias (Medias.h/Media.cpp)
27
  * It can load and unload Clips (Clip.h/Clip.cpp)
28 29
  */

30
#include "Clip.h"
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
31
#include "Library.h"
Ludovic Fauvet's avatar
Ludovic Fauvet committed
32
#include "Media.h"
33
#include "MetaDataManager.h"
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
34

35
#include <QDebug>
36
#include <QDir>
37 38 39
#include <QDomElement>
#include <QHash>
#include <QMessageBox>
40
#include <QProgressDialog>
41 42
#include <QUuid>

Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
43 44 45 46
Library::Library()
{
}

47
Media*
48
Library::media( const QUuid& uuid )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
49
{
50 51 52 53
    QHash<QUuid, Media*>::const_iterator   it = m_medias.find( uuid );
    if ( it == m_medias.end() )
        return NULL;
    return *it;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
54 55
}

56
Clip*
57
Library::clip( const QUuid& uuid )
58
{
59 60 61
    Media*  m = media( uuid );
    if ( m != NULL )
        return m->baseClip();
62

63
    foreach( m, m_medias.values() )
64
    {
65 66
        if ( m != NULL && m->clips().contains( uuid ) )
            return m->clip( uuid );
67 68 69
    }
    return NULL;
}
70

71 72 73
Clip*
Library::clip( const QUuid& mediaUuid, const QUuid& clipUuid )
{
74 75
    if ( m_medias.contains( mediaUuid ) )
    {
76
        if ( m_medias.value( mediaUuid )->clips().contains( clipUuid ) )
77 78
            return m_medias.value( mediaUuid )->clip( clipUuid );
        else
79
            m_medias.value( mediaUuid )->baseClip();
80 81
    }
    return NULL;
82 83
}

84 85
void
Library::removingMediaAsked( const QUuid& uuid )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
86
{
87
    deleteMedia( uuid );
88
    emit mediaRemoved( uuid );
89 90
}

91
void
92
Library::deleteMedia( const QUuid& uuid )
93
{
94
    if ( m_medias.contains( uuid ) )
95
        delete m_medias.take( uuid );
96 97
}

98
bool
99
Library::addMedia( const QFileInfo& fileInfo, const QString& uuid )
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
100
{
101 102
    if ( QFile::exists( fileInfo.absoluteFilePath() ) == false )
        return false;
103
    Media* media = new Media( fileInfo.filePath(), uuid );
104

105 106
    foreach( Media* it, m_medias.values() )
    {
107
        if ( it->fileInfo()->filePath() == media->fileInfo()->filePath() )
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
108
        {
109
            delete media;
110
            return false;
Geoffroy Lacarriere's avatar
Geoffroy Lacarriere committed
111
        }
112
    }
113
    MetaDataManager::getInstance()->computeMediaMetadata( media );
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
114
    addMedia( media );
115
    return true;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
116 117 118 119 120 121
}


void
Library::addMedia( Media *media )
{
122
    m_medias[media->baseClip()->uuid()] = media;
Hugo Beauzee-Luyssen's avatar
Hugo Beauzee-Luyssen committed
123
    emit newMediaLoaded( media );
124 125
}

126 127 128
bool
Library::mediaAlreadyLoaded( const QFileInfo& fileInfo )
{
129
    foreach( Media* media, m_medias.values() )
130
    {
131
        if ( media->fileInfo()->filePath() == fileInfo.filePath() )
132 133
            return true;
    }
134 135 136
    return false;
}

137 138
void
Library::loadProject( const QDomElement& medias )
139 140 141 142 143 144 145 146 147 148
{
    if ( medias.isNull() == true || medias.tagName() != "medias" )
    {
        qWarning() << "Invalid medias node";
        return ;
    }

    QDomElement elem = medias.firstChild().toElement();
    while ( elem.isNull() == false )
    {
149
        QList<QDomElement>  clipList;
150 151 152 153 154 155 156 157 158 159 160
        QDomElement mediaProperty = elem.firstChild().toElement();
        QString     path;
        QString     uuid;

        while ( mediaProperty.isNull() == false )
        {
            QString tagName = mediaProperty.tagName();
            if ( tagName == "path" )
                path = mediaProperty.text();
            else if ( tagName == "uuid" )
                uuid = mediaProperty.text();
161 162 163 164 165 166 167 168 169
            else if ( tagName == "clips" )
            {
                QDomElement clip = mediaProperty.firstChild().toElement();
                while ( clip.isNull() == false )
                {
                    clipList.push_back( clip );
                    clip = clip.nextSibling().toElement();
                }
            }
170 171 172 173
            else
                qWarning() << "Unknown field" << tagName;
            mediaProperty = mediaProperty.nextSibling().toElement();
        }
174 175 176 177 178 179 180 181 182
        //FIXME: This is verry redondant...
        if ( mediaAlreadyLoaded( path ) == true )
        {
            Media*   media;
            QHash<QUuid, Media*>::iterator   it = m_medias.begin();
            QHash<QUuid, Media*>::iterator   end = m_medias.end();

            for ( ; it != end; ++it )
            {
183
                if ( it.value()->fileInfo()->absoluteFilePath() == path )
184 185
                {
                    media = it.value();
186
                    media->baseClip()->setUuid( QUuid( uuid ) );
187
                    m_medias.erase( it );
188
                    m_medias[media->baseClip()->uuid()] = media;
189 190 191 192 193 194
                    break ;
                }
            }
        }
        else
        {
195 196 197 198 199
            if ( addMedia( path, uuid ) == false )
            {
                elem = elem.nextSibling().toElement();
                continue ;
            }
200
        }
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
        if ( clipList.size() != 0 )
        {
            foreach( QDomElement clip, clipList )
            {
                QString parentUuid = clip.attribute( "parentUuid", "");
                if ( parentUuid != "" && parentUuid == uuid )
                {
                    QString beg = clip.attribute( "begin", "" );
                    QString end = clip.attribute( "end", "" );
                    QString clipUuid = clip.attribute( "uuid", "" );
                    if ( beg != "" && end != "" && uuid != "" )
                    {
                        Media* media = m_medias[QUuid( uuid )];
                        if ( media != 0 )
                        {
                            Clip* clip = new Clip( media, beg.toInt(), end.toInt(), QUuid( clipUuid ) );
                            media->addClip( clip );
                        }
                    }
                }
            }
        }
223 224
        elem = elem.nextSibling().toElement();
    }
225
    emit projectLoaded();
226 227
}

228 229
void
Library::saveProject( QDomDocument& doc, QDomElement& rootNode )
230 231 232 233 234 235 236 237 238 239 240 241 242
{
    QHash<QUuid, Media*>::iterator          it = m_medias.begin();
    QHash<QUuid, Media*>::iterator          end = m_medias.end();

    QDomElement medias = doc.createElement( "medias" );

    for ( ; it != end; ++it )
    {
        QDomElement media = doc.createElement( "media" );

        medias.appendChild( media );
        QDomElement mrl = doc.createElement( "path" );

243
        QDomCharacterData text;
244
        text = doc.createTextNode( it.value()->fileInfo()->absoluteFilePath() );
245 246

        QDomElement uuid = doc.createElement( "uuid" );
247
        QDomCharacterData text2 = doc.createTextNode( it.value()->baseClip()->uuid().toString() );
248 249 250 251 252 253

        mrl.appendChild( text );
        uuid.appendChild( text2 );

        media.appendChild( mrl );
        media.appendChild( uuid );
254
        //Creating the clip branch
255
        if ( it.value()->clipsCount() != 0 )
256 257
        {
            QDomElement clips = doc.createElement( "clips" );
258
            foreach( Clip* c, it.value()->clips().values() )
259 260
            {
                QDomElement clip = doc.createElement( "clip" );
261 262 263
                clip.setAttribute( "begin", c->begin() );
                clip.setAttribute( "end", c->end() );
                clip.setAttribute( "uuid", c->uuid() );
264
                clip.setAttribute( "parentUuid", c->getParent()->baseClip()->uuid() );
265 266 267 268
                clips.appendChild( clip );
            }
            media.appendChild( clips );
        }
269
    }
270
    rootNode.appendChild( medias );
271
}
272

273 274
void
Library::clear()
275 276 277 278 279 280 281 282 283 284 285 286
{
    QHash<QUuid, Media*>::iterator  it = m_medias.begin();
    QHash<QUuid, Media*>::iterator  end = m_medias.end();

    while ( it != end )
    {
        emit mediaRemoved( it.key() );
        delete it.value();
        ++it;
    }
    m_medias.clear();
}
287

288 289 290 291 292 293 294 295 296
void
Library::removeClip( const QUuid& mediaId, const QUuid& clipId )
{
    Media*  med = 0;
    if ( m_medias.contains( mediaId ) )
        med = m_medias[mediaId];
    else
        return;

297
    if ( med->clips().contains( clipId ) )
298 299
        med->removeClip( clipId );
}