Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
VideoLAN
VLMC
Commits
d7017b81
Commit
d7017b81
authored
Feb 17, 2010
by
Clement CHAVANCE
Committed by
Hugo Beauzee-Luyssen
Feb 17, 2010
Browse files
Refactored the SettingsManager
Signed-off-by:
Hugo Beauzee-Luyssen
<
beauze.h@gmail.com
>
parent
eb6432c6
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/Configuration/SettingsManager.cpp
View file @
d7017b81
/*****************************************************************************
* SettingsManager.cpp
*
: Backend settings manager
* SettingsManager.cpp: Backend settings manager
*****************************************************************************
* Copyright (C) 2008-20
10 VideoLAN
* Copyright (C) 2008-20
09 the VLMC team
*
* Authors: Clement CHAVANCE <kinder@vlmc.org>
*
...
...
@@ -22,209 +22,222 @@
#include
"SettingsManager.h"
#include
"VLMCSettingsDefault.h"
#include
"ProjectSettingsDefault.h"
#include
"SettingValue.h"
#include
<QHash>
#include
<QDomElement>
#include
<QDomNamedNodeMap>
#include
<QDomNodeList>
#include
<QtDebug>
#include
<QSettings>
#include
<QDomDocument>
#include
<QWriteLocker>
#include
<QReadLocker>
#include
<QTextStream>
#include
<QXmlStreamWriter>
#include
<QtDebug>
bool
SettingsManager
::
m_defaultLoaded
=
false
;
SettingsManager
::
SettingsManager
(
QObject
*
parent
)
:
QObject
(
parent
)
void
SettingsManager
::
setValue
(
const
QString
&
key
,
const
QVariant
&
value
,
SettingsManager
::
Type
type
)
{
if
(
type
==
XML
)
m_tmpXmlSettings
.
insert
(
key
,
new
SettingValue
(
value
)
);
else
if
(
type
==
QSett
)
m_tmpClassicSettings
.
insert
(
key
,
new
SettingValue
(
value
)
);
return
;
}
SettingsManager
::~
SettingsManager
()
void
SettingsManager
::
setImmediateValue
(
const
QString
&
key
,
const
QVariant
&
value
,
SettingsManager
::
Type
type
)
{
QWriteLocker
wlock
(
&
m_rwLock
);
SettingHash
*
settMap
;
if
(
type
==
XML
)
settMap
=
&
m_xmlSettings
;
else
if
(
type
==
QSett
)
{
QSettings
sett
;
sett
.
setValue
(
key
,
value
);
sett
.
sync
();
settMap
=
&
m_classicSettings
;
}
if
(
settMap
->
contains
(
key
)
)
settMap
->
value
(
key
)
->
set
(
value
);
else
settMap
->
insert
(
key
,
new
SettingValue
(
value
)
);
return
;
}
void
SettingsManager
::
setValue
(
const
QString
&
part
,
const
QString
&
key
,
const
QVariant
&
value
)
QVariant
SettingsManager
::
value
(
const
QString
&
key
,
const
QVariant
&
defaultValue
,
SettingsManager
::
Type
type
)
{
m_globalLock
.
lockForRead
();
if
(
!
m_tempData
.
contains
(
part
)
)
qDebug
()
<<
"value :"
<<
key
<<
"default"
<<
defaultValue
;
QReadLocker
rl
(
&
m_rwLock
);
if
(
(
type
==
XML
||
type
==
All
)
&&
m_xmlSettings
.
contains
(
key
)
)
return
m_xmlSettings
.
value
(
key
)
->
get
();
else
if
(
(
type
==
QSett
||
type
==
All
)
)
{
m_globalLock
.
unlock
();
addNewSettingsPart
(
part
);
if
(
m_classicSettings
.
contains
(
key
)
)
return
m_classicSettings
.
value
(
key
)
->
get
();
else
{
QSettings
sett
;
QVariant
val
=
sett
.
value
(
key
,
defaultValue
);
if
(
val
!=
defaultValue
)
m_classicSettings
.
insert
(
key
,
new
SettingValue
(
val
)
);
return
val
;
}
}
else
m_globalLock
.
unlock
();
QWriteLocker
lock
(
&
m_globalLock
);
SettingsPart
*
tmp
=
m_tempData
[
part
];
SettingsPart
::
ConfigPair
::
iterator
it
=
tmp
->
m_data
.
find
(
key
);
if
(
it
==
tmp
->
m_data
.
end
()
)
tmp
->
m_data
[
key
]
=
new
SettingValue
(
value
);
else
it
.
value
()
->
set
(
value
);
return
;
return
defaultValue
;
}
const
SettingValue
*
SettingsManager
::
getValue
(
const
QString
&
part
,
const
QString
&
key
)
const
QHash
<
QString
,
QVariant
>
SettingsManager
::
group
(
const
QString
&
groupName
,
SettingsManager
::
Type
type
)
{
if
(
!
m_data
.
contains
(
part
)
)
return
getValue
(
"default"
,
key
);
QReadLocker
readLock
(
&
m_globalLock
);
QReadLocker
rdLock
(
&
m_data
[
part
]
->
m_lock
);
if
(
m_data
[
part
]
->
m_data
.
contains
(
key
)
==
true
)
return
m_data
[
part
]
->
m_data
[
key
];
return
NULL
;
}
void
SettingsManager
::
saveSettings
(
const
QString
&
part
,
QDomDocument
&
xmlfile
,
QDomElement
&
root
)
bool
SettingsManager
::
watchValue
(
const
QString
&
key
,
QObject
*
receiver
,
const
char
*
method
,
SettingsManager
::
Type
type
)
{
m_globalLock
.
lockForRead
();
if
(
!
m_data
.
contains
(
part
)
)
QReadLocker
rl
(
&
m_rwLock
);
if
(
(
type
==
XML
||
type
==
All
)
&&
m_xmlSettings
.
contains
(
key
)
)
{
m_globalLock
.
unlock
();
return
;
connect
(
m_xmlSettings
[
key
],
SIGNAL
(
changed
(
const
QVariant
&
)
),
receiver
,
method
);
return
true
;
}
SettingsPart
*
sett
=
m_data
[
part
];
m_globalLock
.
unlock
();
//SAVE SETTINGS TO DomDocument
QReadLocker
lock
(
&
sett
->
m_lock
);
SettingsPart
::
ConfigPair
::
const_iterator
it
=
sett
->
m_data
.
begin
();
SettingsPart
::
ConfigPair
::
const_iterator
end
=
sett
->
m_data
.
end
();
QDomElement
settingsNode
=
xmlfile
.
createElement
(
part
);
for
(
;
it
!=
end
;
++
it
)
else
if
(
(
type
==
QSett
||
type
==
All
)
)
{
QDomElement
elem
=
xmlfile
.
createElement
(
it
.
key
()
);
elem
.
setAttribute
(
"value"
,
it
.
value
()
->
get
().
toString
()
);
settingsNode
.
appendChild
(
elem
);
if
(
m_classicSettings
.
contains
(
key
)
)
{
connect
(
m_classicSettings
[
key
],
SIGNAL
(
changed
(
const
QVariant
&
)
),
receiver
,
method
);
return
true
;
}
}
r
oot
.
appendChild
(
settingsNode
)
;
r
eturn
false
;
}
void
SettingsManager
::
loadSettings
(
const
QString
&
part
,
const
QDomElement
&
settings
)
void
SettingsManager
::
save
()
const
{
if
(
settings
.
isNull
()
==
true
||
settings
.
tagName
()
!=
"project"
)
{
qWarning
()
<<
"Invalid settings node"
;
return
;
}
m_globalLock
.
lockForRead
();
if
(
!
m_data
.
contains
(
part
)
)
QReadLocker
rl
(
&
m_rwLock
);
QSettings
sett
;
SettingHash
::
const_iterator
it
=
m_classicSettings
.
begin
();
SettingHash
::
const_iterator
ed
=
m_classicSettings
.
end
();
for
(
;
it
!=
ed
;
++
it
)
sett
.
setValue
(
it
.
key
(),
it
.
value
()
->
get
()
);
sett
.
sync
();
}
void
SettingsManager
::
save
(
QXmlStreamWriter
&
stream
)
const
{
typedef
QPair
<
QString
,
SettingValue
*>
settingPair
;
QMultiHash
<
QString
,
settingPair
>
parts
;
QReadLocker
rl
(
&
m_rwLock
);
SettingHash
::
const_iterator
it
;
SettingHash
::
const_iterator
ed
=
m_xmlSettings
.
end
();
for
(
it
=
m_xmlSettings
.
begin
();
it
!=
ed
;
++
it
)
{
qWarning
()
<<
"These settings Does not exists"
;
return
;
QString
key
=
it
.
key
();
if
(
key
.
count
(
"/"
)
==
1
)
{
int
idx
=
key
.
indexOf
(
"/"
);
QString
part
=
key
.
left
(
idx
);
QString
name
=
key
.
right
(
idx
);
parts
.
insert
(
part
,
settingPair
(
name
,
it
.
value
()
)
);
}
}
SettingsPart
*
sett
=
m_data
[
part
];
m_globalLock
.
unlock
();
//Loading all the settings
m_globalLock
.
lockForWrite
();
sett
->
m_lock
.
lockForWrite
();
QDomNodeList
list
=
settings
.
childNodes
();
int
nbChild
=
list
.
size
();
for
(
int
idx
=
0
;
idx
<
nbChild
;
++
idx
)
QMultiHash
<
QString
,
settingPair
>::
const_iterator
iter
;
QMultiHash
<
QString
,
settingPair
>::
const_iterator
end
=
parts
.
end
();
stream
.
writeStartElement
(
"Settings"
);
for
(
iter
=
parts
.
begin
();
iter
!=
end
;
++
iter
)
{
QDomNamedNodeMap
attrMap
=
list
.
at
(
idx
).
attributes
();
if
(
attrMap
.
count
()
>
1
)
stream
.
writeStartElement
(
iter
.
key
()
);
QList
<
settingPair
>
pairs
=
parts
.
values
(
iter
.
key
()
);
foreach
(
settingPair
pair
,
pairs
)
{
qWarning
()
<<
"Invalid number of attributes for"
<<
list
.
at
(
idx
).
nodeName
();
return
;
stream
.
writeStartElement
(
pair
.
first
);
stream
.
writeAttribute
(
"value"
,
pair
.
second
->
get
().
toString
()
);
stream
.
writeEndElement
();
}
sett
->
m_data
.
insert
(
list
.
at
(
idx
).
toElement
().
tagName
(),
new
SettingValue
(
QVariant
(
attrMap
.
item
(
0
).
nodeValue
()
)
)
);
stream
.
writeEndElement
();
}
sett
->
m_lock
.
unlock
();
m_globalLock
.
unlock
();
emit
settingsLoaded
();
stream
.
writeEndElement
();
}
void
SettingsManager
::
addNewSettingsPart
(
const
QString
&
name
)
bool
SettingsManager
::
load
(
QDomElement
&
element
)
{
QReadLocker
rLock
(
&
m_globalLock
);
if
(
!
m_data
.
contains
(
name
)
)
{
rLock
.
unlock
();
QWriteLocker
lock
(
&
m_globalLock
);
m_data
.
insert
(
name
,
new
SettingsPart
);
m_tempData
.
insert
(
name
,
new
SettingsPart
);
}
}
void
SettingsManager
::
commit
()
bool
SettingsManager
::
commit
(
SettingsManager
::
Type
type
)
{
{
QWriteLocker
lock
(
&
m_globalLock
);
QHash
<
QString
,
SettingsPart
*>::
iterator
it
=
m_tempData
.
begin
();
QHash
<
QString
,
SettingsPart
*>::
iterator
ed
=
m_tempData
.
end
();
for
(
;
it
!=
ed
;
++
it
)
QWriteLocker
wlock
(
&
m_rwLock
);
if
(
type
==
XML
||
type
==
All
)
{
SettingsPart
*
sett
=
it
.
value
();
QString
part
=
it
.
key
();
QReadLocker
rLock
(
&
sett
->
m_lock
);
SettingsPart
::
ConfigPair
::
iterator
iter
=
sett
->
m_data
.
begin
();
SettingsPart
::
ConfigPair
::
iterator
end
=
sett
->
m_data
.
end
();
QWriteLocker
wLock
(
&
m_data
[
part
]
->
m_lock
);
for
(
;
iter
!=
end
;
++
iter
)
SettingHash
::
iterator
it
;
SettingHash
::
iterator
ed
=
m_tmpXmlSettings
.
end
();
for
(
it
=
m_tmpXmlSettings
.
begin
()
;
it
!=
ed
;
++
it
)
{
QString
settingName
=
iter
.
key
();
SettingsPart
::
ConfigPair
::
iterator
insert_it
=
m_data
[
part
]
->
m_data
.
find
(
settingName
);
if
(
insert_it
==
m_data
[
part
]
->
m_data
.
end
()
)
m_data
[
part
]
->
m_data
.
insert
(
settingName
,
new
SettingValue
(
iter
.
value
()
->
get
()
)
);
if
(
m_xmlSettings
.
contains
(
it
.
key
()
)
)
m_xmlSettings
[
it
.
key
()]
->
set
(
it
.
value
()
->
get
()
);
else
m_xmlSettings
.
insert
(
it
.
key
(),
it
.
value
()
);
}
}
if
(
type
==
QSett
||
type
==
All
)
{
QSettings
sett
;
SettingHash
::
iterator
it
;
SettingHash
::
iterator
ed
=
m_classicSettings
.
end
();
for
(
it
=
m_classicSettings
.
begin
();
it
!=
ed
;
++
it
)
{
sett
.
setValue
(
it
.
key
(),
it
.
value
()
->
get
()
);
if
(
m_classicSettings
.
contains
(
it
.
key
()
)
)
m_classicSettings
[
it
.
key
()]
->
set
(
it
.
value
()
->
get
()
);
else
m_
data
[
part
]
->
m_data
[
settingName
]
->
set
(
it
er
.
value
()
->
get
()
);
m_
classicSettings
.
in
se
r
t
(
it
.
key
(),
it
.
value
()
);
}
}
}
flush
();
}
void
SettingsManager
::
flush
()
void
SettingsManager
::
flush
()
{
QWriteLocker
lock
(
&
m_globalLock
);
QHash
<
QString
,
SettingsPart
*>::
iterator
it
=
m_tempData
.
begin
();
QHash
<
QString
,
SettingsPart
*>::
iterator
ed
=
m_tempData
.
end
();
for
(
;
it
!=
ed
;
++
it
)
{
QWriteLocker
wLock
(
&
it
.
value
()
->
m_lock
);
it
.
value
()
->
m_data
.
clear
();
}
}
void
SettingsManager
::
loadDefaultsSettings
()
{
if
(
!
SettingsManager
::
m_defaultLoaded
)
{
SettingsManager
::
m_defaultLoaded
=
true
;
VLMCSettingsDefault
::
load
(
"default"
);
VLMCSettingsDefault
::
load
(
"VLMC"
);
ProjectSettingsDefault
::
load
(
"default"
);
ProjectSettingsDefault
::
load
(
"project"
);
}
QWriteLocker
wl
(
&
m_rwLock
);
m_tmpXmlSettings
.
clear
();
m_tmpClassicSettings
.
clear
();
}
SettingsManager
*
SettingsManager
::
getInstance
()
SettingsManager
::
SettingsManager
()
:
m_classicSettings
(),
m_xmlSettings
(),
m_tmpClassicSettings
(),
m_tmpXmlSettings
(),
m_rwLock
()
{
SettingsManager
*
ret
=
QSingleton
<
SettingsManager
>::
getInstance
();
if
(
!
SettingsManager
::
m_defaultLoaded
)
{
SettingsManager
::
loadDefaultsSettings
();
}
return
ret
;
}
const
Settings
Part
*
SettingsManager
::
getConfigPart
(
const
QString
&
part
)
const
Settings
Manager
::~
SettingsManager
()
{
QHash
<
QString
,
SettingsPart
*>::
const_iterator
it
=
m_data
.
find
(
part
);
if
(
it
==
m_data
.
end
()
)
return
NULL
;
return
it
.
value
();
}
src/Configuration/SettingsManager.h
View file @
d7017b81
/*****************************************************************************
* SettingsManager.h: Backend settings manager
*****************************************************************************
* Copyright (C) 2008-20
10 VideoLAN
* Copyright (C) 2008-20
09 the VLMC team
*
* Authors: Clement CHAVANCE <
kinder@vlmc.org
>
* Authors: Clement CHAVANCE <
chavance.c@gmail.com
>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
...
...
@@ -23,207 +23,67 @@
#ifndef SETTINGSMANAGER_H
#define SETTINGSMANAGER_H
#include
"SettingValue.h"
#include
"QSingleton.hpp"
#include
<Singleton.hpp>
#include
<Q
Object
>
#include
<Q
String
>
#include
<QHash>
#include
<QObject>
#include
<QReadWriteLock>
#include
<QVariant>
class
QDomDocument
;
class
QDomElement
;
class
QString
;
/**
* \struct SettingsPart
* \brief Represent a part of the Settings.
*
* This is used to group different settings, and to be able to easily
* save or load just a part of all the settings used by the application.
*/
class
SettingValue
;
class
QXmlStreamWriter
;
class
QDomElement
;
class
SettingValue
;
struct
SettingsPart
{
typedef
QHash
<
QString
,
SettingValue
*>
ConfigPair
;
SettingsPart
()
{}
/**
* \brief the HashList containing the settings
*/
ConfigPair
m_data
;
/**
* \brief The ReadWriteLock used for when we need to read / write the settingsPart.
*/
QReadWriteLock
m_lock
;
/**
* \brief This flag is used when the SettingsPart is
* a readOnly Part.
*/
bool
m_rdOnly
;
private:
SettingsPart
(
const
SettingsPart
&
);
SettingsPart
&
operator
=
(
const
SettingsPart
&
);
};
/**
* \class SettingsManager
* \brief Will manage everything related to the settings.
*/
class
SettingsManager
:
public
QObject
,
public
QSingleton
<
SettingsManager
>
class
SettingsManager
:
public
QObject
,
public
Singleton
<
SettingsManager
>
{
Q_OBJECT
Q_DISABLE_COPY
(
SettingsManager
)
friend
class
QSingleton
<
SettingsManager
>
;
public:
/**
* \brief Set a value to an existing or a new SettingValue
*
* If the SettingsPart part does not exist, it will be created
* \sa commit()
* \param part the part in wich the value will be set
* \param key the key of the setting
* \param value the value of the setting
*/
void
setValue
(
const
QString
&
part
,
const
QString
&
key
,
const
QVariant
&
value
);
/**
* \brief get a settings value for a given name
*
* if the settings is not in part, return the default value
* for this setting
* \param part the part where the settings is stored
* \param key the setting's name
* \return the settingPart named part
* \warning if part does not exist, return a NULL pointer
*/
const
SettingValue
*
getValue
(
const
QString
&
part
,
const
QString
&
key
)
const
;
/**
* \brief getter for a settingsPart
* \param part the name of the part we wish to get
* \return The settingsPart named part
* \warning returns a NULL pointer if the SettingsPart part does not exist
*/
const
SettingsPart
*
getConfigPart
(
const
QString
&
part
)
const
;
/**
* \brief save a settingPart into a DomDocument
*
* This will only save one part, to save all the preferences, you have to call
* this method with all the name of the existing SettingsPart
* \param part The part to save
* \param xmlfile The QDomDocument used to create new QDomElements
* \param root The root Element of the xml file in wich the project will be saved.
*/
void
saveSettings
(
const
QString
&
part
,
QDomDocument
&
xmlfile
,
QDomElement
&
root
);
/**
* \brief load a Settings part from a QDomElement
*
* after all settings contained in the donElement have been loaded, this method will emit the
* settingsLoaded() signal
* \param part the Settings part to Load. The settings part must exist in order to be loaded
* \param settings the QDomElement containing the settingPart to load.
*/
void
loadSettings
(
const
QString
&
part
,
const
QDomElement
&
settings
);
/**
* \brief add a new SettingsPart
* \param name the name of the SettingPart that need to be created
*
* The SettingsPart is not created if name is already used by another
* SettingsPart
*/
void
addNewSettingsPart
(
const
QString
&
name
);
/**
* \brief commit all change made into the settingManager
*
* This will commit all the settings modified with the SetValue method
* that have been stored in a temporary Hashlist to the settingManager HashList.
* It allow us to discard all the modified settings that have been modified. like when the user
* press the cancel button wile configuring the project settings via the project wizard
* \sa flush()
*/
void
commit
();
/**
* \brief clean the temporary value stored in the SettingsManager
*
* this method allow the user to cancel all the modifications made to the settingsManager
* between two calls of the commit method.
* this method is also called at the end of the commit method
*/
void
flush
();
/**
* \brief Will load the default value of the application and the project settings
*
* the defaults are only loaded once
*/
static
void
loadDefaultsSettings
();
/**
* \brief Return the only available instance of the settingsManager
*/
static
SettingsManager
*
getInstance
();
typedef
QHash
<
QString
,
SettingValue
*>
SettingHash
;
enum
Type
{
XML
,
QSett
,
All
};
void
setValue
(
const
QString
&
key
,
const
QVariant
&
value
,
SettingsManager
::
Type
type
=
QSett
);
void
setImmediateValue
(
const
QString
&
key
,
const
QVariant
&
value
,
SettingsManager
::
Type
=
QSett
);
QVariant
value
(
const
QString
&
key
,
const
QVariant
&
defaultValue
=
QVariant
(),
SettingsManager
::
Type
type
=
QSett
);
QHash
<
QString
,
QVariant
>
group
(
const
QString
&
groupName
,
SettingsManager
::
Type
type
=
QSett
);
bool
watchValue
(
const
QString
&
key
,
QObject
*
receiver
,
const
char
*
method
,
SettingsManager
::
Type
type
);
void
save
()
const
;
void
save
(
QXmlStreamWriter
&
stream
)
const
;
bool
load
(
QDomElement
&
element
);
bool
commit
(
SettingsManager
::
Type
type
);
void
flush
();
private:
SettingsManager
(
QObject
*
parent
=
0
);
friend
class
Singleton
<
SettingsManager
>
;
SettingsManager
();
~
SettingsManager
();