EffectsEngine.cpp 5.32 KB
Newer Older
1 2 3 4 5
/*****************************************************************************
 * EffectsEngine.cpp: Manage the effects plugins.
 *****************************************************************************
 * Copyright (C) 2008-2010 VideoLAN
 *
Hugo Beauzée-Luyssen's avatar
Hugo Beauzée-Luyssen committed
6
 * Authors: Hugo Beauzée-Luyssen <hugo@beauzee.fr>
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * 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.
 *****************************************************************************/

#include "EffectsEngine.h"

#include "Effect.h"
26
#include "EffectInstance.h"
27
#include "Types.h"
28

29
#include <QApplication>
30
#include <QDesktopServices>
31
#include <QDir>
32
#include <QProcess>
33
#include <QSettings>
34 35
#include <QXmlStreamWriter>

36
#include <QtDebug>
37

38 39 40 41
#ifdef Q_OS_WIN
#include <windows.h>
#endif

42 43
EffectsEngine::EffectsEngine()
{
44 45 46
    m_cache = new QSettings( QDesktopServices::storageLocation(
                    QDesktopServices::CacheLocation ) + "/effects",
                             QSettings::IniFormat, this );
47 48 49 50 51
    //Create the names entry. A bit ugly but faster (I guess...) afterward.
    m_names.push_back( QStringList() );
    m_names.push_back( QStringList() );
    m_names.push_back( QStringList() );
    m_names.push_back( QStringList() );
52 53 54 55 56 57 58
}

EffectsEngine::~EffectsEngine()
{
}

Effect*
59
EffectsEngine::effect( const QString& name )
60
{
61 62 63 64
    QHash<QString, Effect*>::iterator   it = m_effects.find( name );
    if ( it != m_effects.end() )
        return it.value();
    return NULL;
65
}
66 67 68 69

bool
EffectsEngine::loadEffect( const QString &fileName )
{
70 71 72 73 74 75 76 77 78 79 80 81 82 83
    Effect*         e = new Effect( fileName );
    QString         name;
    Effect::Type    type;

    if ( m_cache->contains( fileName + "/name" ) == true &&
         m_cache->contains( fileName + "/type" ) == true )
    {
        name = m_cache->value( fileName + "/name" ).toString();
        int     typeInt = m_cache->value( fileName + "/type" ).toInt();
        if ( typeInt < Effect::Unknown || typeInt > Effect::Mixer3 )
            qWarning() << "Invalid plugin type.";
        else
        {
            type = static_cast<Effect::Type>( typeInt );
84 85 86 87 88
            if ( m_effects.contains( name ) == true )
            {
                delete e;
                return false;
            }
89
            m_effects[name] = e;
90
            m_names[type].push_back( name );
91
            emit effectAdded( e, name, type );
92 93 94
            return true;
        }
    }
95
    if ( e->load() == false || m_effects.contains( e->name() ) == true )
96 97 98 99
    {
        delete e;
        return false;
    }
100
    m_effects[e->name()] = e;
101 102 103 104
    m_cache->setValue( fileName + "/name", e->name() );
    m_cache->setValue( fileName + "/type", e->type() );
    name = e->name();
    type = e->type();
105
    m_names[type].push_back( name );
106
    emit effectAdded( e, name, type );
107 108
    return true;
}
109 110 111 112 113

void
EffectsEngine::browseDirectory( const QString &path )
{
    QDir    dir( path );
114
    const QFileInfoList& files = dir.entryInfoList( QDir::Files | QDir::NoDotAndDotDot |
115
                                              QDir::Readable ); //| QDir::Executable );
116
    foreach ( const QFileInfo& file, files )
117
    {
118 119 120 121
        if ( file.isDir() )
            browseDirectory( file.absoluteFilePath() );
        else
            loadEffect( file.absoluteFilePath() );
122 123
    }
}
124

125 126 127
void
EffectsEngine::loadEffects()
{
128
    QStringList     pathList;
129
    pathList << qApp->applicationDirPath() + "/effects/";
130 131

#if defined ( Q_OS_UNIX )
132 133 134 135
    const QProcessEnvironment &env = QProcessEnvironment::systemEnvironment();
    if ( env.contains( "FREI0R_PATH" ) == true )
        pathList = env.value( "FREI0R_PATH" ).split( ':' );
    else
136 137 138 139 140 141
    {
        //Refer to http://www.piksel.org/frei0r/1.2/spec/group__pluglocations.html
        pathList << QString( QDir::homePath() + "/.frei0r-1/lib/" ) <<
                    QString("/usr/local/lib/frei0r-1/") <<
                    QString("/usr/lib/frei0r-1/" );
    }
142
#elif defined ( Q_OS_WIN32 )
143 144
    TCHAR       appDir[128];
    if ( GetModuleFileName( NULL, appDir, 128 ) > 0 )
145
    {
146
        TCHAR     *pos = strrchr( appDir, '\\' );
147 148 149 150 151 152
        if ( pos == NULL )
        {
            qWarning() << "Can't use ModuleFileName:" << appDir;
            return ;
        }
        *pos = 0;
153
        pathList << QString( appDir ) + "/effects/";
154
    }
155 156 157
    else
    {
        qWarning() << "Failed to get application directory. Using current path.";
158
        pathList << QDir::currentPath() + "/effects/";
159
    }
160
#endif
161
    qDebug() << "Loading effects from:" << pathList;
162
    foreach ( const QString &path, pathList )
163
    {
164
        if ( QFile::exists( path ) == true )
165
        {
166
            qDebug() << "\tScanning" << path << "for effects";
167
            browseDirectory( path );
168 169 170
        }
    }
}
171 172

const QStringList&
173
EffectsEngine::effects( Effect::Type type ) const
174 175 176
{
    return m_names[type];
}