Settings.cpp 5.8 KB
Newer Older
1
/*****************************************************************************
2
 * Settings.cpp: Backend settings manager
3
 *****************************************************************************
4
 * Copyright (C) 2008-2014 VideoLAN
5
 *
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
 *
 * 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
#include "Settings.h"
24
#include "SettingValue.h"
25
#include "Tools/VlmcDebug.h"
26

27 28
#include <QByteArray>
#include <QFile>
29 30
#include <QWriteLocker>
#include <QReadLocker>
31
#include <QStringList>
32
#include <QXmlStreamWriter>
33 34
#include <QFileInfo>
#include <QDir>
35

36
#include <QDomElement>
37 38


39 40
Settings::Settings(const QString &settingsFile)
    : m_settingsFile( NULL )
41
{
42
    setSettingsFile( settingsFile );
43 44
}

45
Settings::~Settings()
46
{
47
    delete m_settingsFile;
48 49
}

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
void
Settings::setSettingsFile(const QString &settingsFile)
{
    delete m_settingsFile;
    if ( settingsFile.isEmpty() == false )
    {
        QFileInfo fInfo( settingsFile );
        if ( fInfo.exists() == false )
        {
            QDir dir = fInfo.dir();
            if ( dir.exists() == false )
                dir.mkpath( fInfo.absolutePath() );
        }
        m_settingsFile = new QFile( settingsFile );
    }
    else
        m_settingsFile = NULL;
}

69 70
bool
Settings::save( QXmlStreamWriter& project )
71
{
72
    QReadLocker lock( &m_rwLock );
73

74 75
    SettingMap::const_iterator     it = m_settings.begin();
    SettingMap::const_iterator     end = m_settings.end();
76

77
    project.writeStartElement( "settings" );
78
    for ( ; it != end; ++it )
79
    {
80
        if ( ( (*it)->flags() & SettingValue::Runtime ) != 0 )
81
            continue ;
82
        project.writeStartElement( "setting" );
83
        project.writeAttribute( "key", (*it)->key() );
84 85
        if ( (*it)->get().canConvert<QString>() == false )
            vlmcWarning() << "Can't serialize" << (*it)->key();
86
        project.writeAttribute( "value", (*it)->get().toString() );
87
        project.writeEndElement();
88
    }
89
    project.writeEndElement();
90
    return true;
91
}
92

93
bool
94
Settings::load( const QDomDocument& document )
95
{
96
    QDomElement     element = document.firstChildElement( "settings" );
97
    if ( element.isNull() == true )
98
    {
99
        vlmcWarning() << "Invalid settings node";
100
        return false;
101
    }
102
    QDomElement s = element.firstChildElement( "setting" );
103
    while ( s.isNull() == false )
104
    {
105 106 107
        QString     key = s.attribute( "key" );
        QString     value = s.attribute( "value" );

108
        if ( key.isEmpty() == true )
109
            vlmcWarning() << "Invalid setting node.";
110
        else
111 112
        {
            vlmcDebug() << "Loading" << key << "=>" << value;
113
            if ( setValue( key, value ) == false )
114
                vlmcWarning() << "Loaded invalid project setting:" << key;
115
        }
116
        s = s.nextSiblingElement();
117
    }
118
    return true;
119 120
}

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
bool
Settings::load()
{
    QDomDocument    doc("root");
    if ( m_settingsFile->open( QFile::ReadOnly ) == false )
    {
        vlmcWarning() << "Failed to open settings file" << m_settingsFile->fileName();
        return false;
    }
    if ( doc.setContent( m_settingsFile ) == false )
    {
        vlmcWarning() << "Failed to load settings file" << m_settingsFile->fileName();
        return false;
    }
    bool res = load( doc );
    m_settingsFile->close();
    return res;
}

bool
Settings::save()
142
{
143
    if ( m_settingsFile == NULL )
144
        return false;
145 146
    QByteArray          settingsContent;
    QXmlStreamWriter    streamWriter( &settingsContent );
147
    streamWriter.setAutoFormatting( true );
148 149 150 151
    save( streamWriter );
    m_settingsFile->open( QFile::WriteOnly );
    m_settingsFile->write( settingsContent );
    m_settingsFile->close();
152
    return true;
153 154 155
}

bool
156
Settings::setValue(const QString &key, const QVariant &value)
157 158 159
{
    SettingMap::iterator   it = m_settings.find( key );
    if ( it != m_settings.end() )
160
    {
161 162
        (*it)->set( value );
        return true;
163
    }
164
    Q_ASSERT_X( false, __FILE__, "setting value without a created variable" );
165 166 167 168
    return false;
}

SettingValue*
169
Settings::value(const QString &key)
170 171 172 173 174 175
{
    QReadLocker lock( &m_rwLock );

    SettingMap::iterator it = m_settings.find( key );
    if ( it != m_settings.end() )
        return *it;
176
    Q_ASSERT_X( false, __FILE__, "fetching value without a created variable" );
177 178 179 180
    return NULL;
}

SettingValue*
181
Settings::createVar(SettingValue::Type type, const QString &key, const QVariant &defaultValue, const char *name, const char *desc, SettingValue::Flags flags)
182 183 184 185 186 187 188 189 190 191
{
    QWriteLocker lock( &m_rwLock );

    if ( m_settings.contains( key ) )
        return NULL;
    SettingValue* val = new SettingValue( key, type, defaultValue, name, desc, flags );
    m_settings.insert( key, val );
    return val;
}

192 193
Settings::SettingList
Settings::group(const QString &groupName) const
194 195 196 197
{
    QReadLocker lock( &m_rwLock );
    SettingMap::const_iterator          it = m_settings.begin();
    SettingMap::const_iterator          ed = m_settings.end();
198
    SettingList        ret;
199 200 201

    QString grp = groupName + '/';
    for ( ; it != ed; ++it )
202
    {
203 204
        if ( (*it)->key().startsWith( grp ) )
            ret.push_back( *it );
205
    }
206 207
    return ret;
}