/****************************************************************************
**
** Copyright (C) 2002-2006 Frank Hemer <frank@hemer.org>,
** Tilo Riemer <riemer@crossvc.com>
**
**
**----------------------------------------------------------------------------
**
**----------------------------------------------------------------------------
**
** CrossVC is available under two different licenses:
**
** If CrossVC is linked against the GPLed version of Qt
** CrossVC is released under the terms of GPL also.
**
** If CrossVC is linked against a nonGPLed version of Qt
** CrossVC is released under the terms of the
** CrossVC License for non-Unix platforms (CLNU)
**
**
** CrossVC License for non-Unix platforms (CLNU):
**
** Redistribution and use in binary form, without modification,
** are permitted provided that the following conditions are met:
**
** 1. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 2. It is not permitted to distribute the binary package under a name
** different than CrossVC.
** 3. The name of the authors may not be used to endorse or promote
** products derived from this software without specific prior written
** permission.
** 4. The source code is the creative property of the authors.
** Extensions and development under the terms of the Gnu Public License
** are limited to the Unix platform. Any distribution or compilation of
** the source code against libraries licensed other than gpl requires
** the written permission of the authors.
**
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
**
**
** CrossVC License for Unix platforms:
**
** 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, version 2 of the License.
** 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 version 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*****************************************************************************/
/**
* Settings of each project.
* SubProjects have a relative path, begining with the toplevel project name
* slashes ('/') are replaced with (':') due to QSettings limitations
* on win, subkey are limited to 255 chars, so unfortunatelly a relative path
* can only safely be stored up to this path length
*/
#include "config.h"
#include "ProjectSettings.h"
// #include "globals.h"//needed for debugging
#include <qmap.h>
#include <qregexp.h>
// helps creating fast hash-tables
static const unsigned int nextPrime( unsigned int i) {
switch( i) {
case 0:
case 2:
case 3:
case 5:
case 7:
case 11:
case 13:
case 17: return 19;
case 19: return 41;
case 41: return 79;
case 79: return 157;
case 157: return 311;
case 311: return 619;
case 619: return 1249;
case 1249: return 2503;
case 2503: return 4999;
case 4999: return 9973;
default: return i*2+1;
}
}
const char ProjectSettings::SUBPROJECTS[] = "SubProjects";
ProjectSettings::ProjectSettings() {
projectMap.setAutoDelete(true);
}
ProjectSettings::~ProjectSettings() {
}
//fails if newProjectKey exists or oldProjectKey not found
bool ProjectSettings::renameProject( QString oldProjectKey, QString newProjectKey) {
oldProjectKey.replace(QRegExp("\\^"),"^0");
newProjectKey.replace(QRegExp("\\^"),"^0");
oldProjectKey.replace(QRegExp("/"),"^e");
newProjectKey.replace(QRegExp("/"),"^e");
if ( !(projectMap.find( newProjectKey))) {//null if not found
if ( projectMap.isEmpty() || (projectMap.size() <= projectMap.count()) ) projectMap.resize( nextPrime(projectMap.size()));
SettingsMap * map = projectMap.find(oldProjectKey);
if (!map) return false;
map = new SettingsMap(*map);
projectMap.remove(oldProjectKey);
projectMap.insert( newProjectKey, map);
return true;
} else {
return false;
}
}
bool ProjectSettings::removeProject( QString project) {
project.replace(QRegExp("\\^"),"^0");
project.replace(QRegExp("/"),"^e");
SettingsMap* settings = projectMap.find(project);
if (settings) {
SettingsMap::iterator it = settings->find( SUBPROJECTS);
if (it != settings->end()) {
const QStringList &list = QStringList::split("^e",it.data());
for (QStringList::ConstIterator lit = list.begin(); lit != list.end(); ++lit) {
QString entry = *lit;
entry.replace(QRegExp("/"),"^e");
projectMap.remove(entry);
}
}
}
return projectMap.remove(project);
}
//removes from subprojectlist and removes project itself
bool ProjectSettings::removeSubProject( QString project, QString subProject) {
SettingsMap* settings = getProjectSettings(project);
if (!settings) return false;
SettingsMap::iterator it = settings->find( SUBPROJECTS);
if (it != settings->end()) {
QStringList list = QStringList::split("^e",it.data());
QString tmp = subProject;
tmp.replace(QRegExp("\\^"),"^0");
QStringList::Iterator lit = list.find(tmp);
if (lit != list.end()) {
list.remove(lit);
removeProject(subProject);
settings->insert(SUBPROJECTS,list.join("^e"));
return true;
}
}
return false;
}
void ProjectSettings::addSubProject( QString project, QString subProject) {
SettingsMap* settings = getAndCreateProjectSettings(project);
SettingsMap::iterator it = settings->find( SUBPROJECTS);
QString tmp;
if (it != settings->end()) {
tmp = it.data()+"^e";
}
tmp += subProject.replace(QRegExp("\\^"),"^0");
settings->insert(SUBPROJECTS,tmp);
}
void ProjectSettings::setSubProjects( QString project, QStringList subProjects) {
set(project,SUBPROJECTS,subProjects);
}
ProjectSettings::SettingsMap* ProjectSettings::getAndCreateProjectSettings( QString projectKey) {
projectKey.replace(QRegExp("\\^"),"^0");
projectKey.replace(QRegExp("/"),"^e");
SettingsMap* map = NULL;
if ( projectMap.isEmpty() || !(map = projectMap.find( projectKey))) {//null if not found
map = new SettingsMap();
if (projectMap.size() <= projectMap.count()) projectMap.resize( nextPrime(projectMap.size()));
projectMap.insert( projectKey, map);
}
return map;
}
ProjectSettings::SettingsMap* ProjectSettings::getProjectSettings( QString projectKey) {
projectKey.replace(QRegExp("\\^"),"^0");
projectKey.replace(QRegExp("/"),"^e");
if (projectKey.isNull()) return NULL;
SettingsMap* map = projectMap.find( projectKey);//null if not found
return map;
}
void ProjectSettings::set( const QString project, const QString key, bool val) {
QString value;
if (val) {
value = "true";
} else {
value = "false";
}
getAndCreateProjectSettings(project)->insert(key,value);
}
void ProjectSettings::set( const QString project, const QString key, int val) {
getAndCreateProjectSettings(project)->insert(key,QString::number(val));
}
void ProjectSettings::set( const QString project, const QString key, QString val) {
getAndCreateProjectSettings(project)->insert(key,val);
}
void ProjectSettings::set( const QString project, const QString key, QStringList val) {
QStringList::Iterator it;
for (it = val.begin(); it != val.end(); ++it) {
(*it).replace(QRegExp("\\^"),"^0");
}
getAndCreateProjectSettings(project)->insert(key,val.join("^e"));
}
void ProjectSettings::set( const QString project, const QString key, StringMap map) {
QString val = "";
StringMap::Iterator it;
for ( it = map.begin(); it != map.end(); ++it ) {
QString tmp = it.key();
tmp.replace(QRegExp("\\^"),"^0");
val += tmp+"^e"+it.data().replace(QRegExp("\\^"),"^0")+"^e";
}
getAndCreateProjectSettings(project)->insert(key,val);
}
void ProjectSettings::set( const QString project, const QString key, IntMap map) {
QString val = "";
IntMap::Iterator it;
for ( it = map.begin(); it != map.end(); ++it ) {
QString tmp = it.key();
tmp.replace(QRegExp("\\^"),"^0");
val += tmp+"^e"+QString::number(it.data())+"^e";
}
getAndCreateProjectSettings(project)->insert(key,val);
}
bool ProjectSettings::getProjects( QStringList& val) {
if (projectMap.isEmpty()) {
return false;
}
val.clear();
QDictIterator<SettingsMap> it(projectMap);
for( ; it.current(); ++it ) {
QString key = it.currentKey();
key.replace(QRegExp("\\^e"),"/");
key.replace(QRegExp("\\^0"),"^");
val.append(key);
}
return true;
}
bool ProjectSettings::getTopLevelProjects( QStringList& val) {
if (projectMap.isEmpty()) {
return false;
}
val.clear();
QDictIterator<SettingsMap> it(projectMap);
for( ; it.current(); ++it ) {
if (it.currentKey().find("^e") == -1) {
QString key = it.currentKey();
key.replace(QRegExp("\\^0"),"^");
val.append(key);
}
}
return true;
}
bool ProjectSettings::getSubProjects( const QString& project, QStringList& subProjectList) {
SettingsMap* settings = getProjectSettings(project);
if (!settings) return false;
SettingsMap::iterator it = settings->find( SUBPROJECTS);
if (it == settings->end()) {
return false;
} else {
subProjectList = QStringList::split("^e",it.data());
QStringList::Iterator it;
for (it = subProjectList.begin(); it != subProjectList.end(); ++it) {
(*it).replace(QRegExp("\\^0"),"^");
}
return true;
}
}
bool ProjectSettings::get( const QString project, const QString key, bool& val) {
SettingsMap* settings = getProjectSettings(project);
if (!settings) return false;
SettingsMap::iterator it = settings->find( key);
if (it == settings->end()) {
return false;
} else {
if ( it.data()=="true") {
val = true;
} else {
val = false;
}
return true;
}
}
bool ProjectSettings::get( const QString project, const QString key, int& val) {
SettingsMap* settings = getProjectSettings(project);
if (!settings) return false;
SettingsMap::iterator it = settings->find( key);
if (it == settings->end()) {
return false;
} else {
bool ok;
val = it.data().toInt(&ok);
if (ok) return true;
else return false;
}
}
bool ProjectSettings::get( const QString project, const QString key, QString& val) {
SettingsMap* settings = getProjectSettings(project);
if (!settings) return false;
SettingsMap::iterator it = settings->find( key);
if (it == settings->end()) {
return false;
} else {
val = it.data();
return true;
}
}
bool ProjectSettings::get( const QString project, const QString key, QStringList& val) {
SettingsMap* settings = getProjectSettings(project);
if (!settings) return false;
SettingsMap::iterator it = settings->find( key);
if (it == settings->end()) {
return false;
} else {
val = QStringList::split("^e",it.data());
QStringList::Iterator it;
for (it = val.begin(); it != val.end(); ++it) {
(*it).replace(QRegExp("\\^0"),"^");
}
return true;
}
}
bool ProjectSettings::get( const QString project, const QString key, StringMap& val) {
SettingsMap* settings = getProjectSettings(project);
if (!settings) return false;
SettingsMap::iterator iterator = settings->find( key);
if (iterator == settings->end()) {
return false;
} else {
QStringList list = QStringList::split("^e",iterator.data());
QStringList::Iterator it;
it = list.begin();
while (it != list.end()) {
QString key = *(it++);
key.replace(QRegExp("\\^0"),"^");
QString value = *(it++);
value.replace(QRegExp("\\^0"),"^");
val.insert(key,value);
}
return true;
}
}
bool ProjectSettings::get( const QString project, const QString key, IntMap& val) {
SettingsMap* settings = getProjectSettings(project);
if (!settings) return false;
SettingsMap::iterator iterator = settings->find( key);
if (iterator == settings->end()) {
return false;
} else {
QStringList list = QStringList::split("^e",iterator.data());
QStringList::Iterator it;
it = list.begin();
while (it != list.end()) {
QString key = *(it++);
key.replace(QRegExp("\\^0"),"^");
QString value = *(it++);
val.insert(key,value.toInt() );
}
return true;
}
}
void ProjectSettings::writeToSettings( QSettings* settings, const QString projectPath) {
QDictIterator<SettingsMap> it(projectMap);
for( ; it.current(); ++it ) {
QString key = projectPath+"/"+it.currentKey()+"/";
SettingsMap *tmp = projectMap.find( it.currentKey());
SettingsMap::iterator it;
for ( it = tmp->begin(); it != tmp->end(); ++it ) {
QString subKey = key+it.key();
settings->writeEntry( subKey, it.data());
}
}
}
void ProjectSettings::readFromSettings( QSettings* settings, const QString projectPath) {
unsigned int i = 0;
QStringList projectList = settings->subkeyList( projectPath);
for( i = 0; i < projectList.count(); i++) {
QString subKey = projectPath+"/"+projectList[i];
QStringList entryList = settings->entryList( subKey);
unsigned int j = 0;
for( j = 0; j < entryList.count(); j++) {
QString entry = settings->readEntry( subKey+"/"+entryList[j], "");
SettingsMap* map = NULL;
if ( projectMap.isEmpty() || !(map = projectMap.find( projectList[i]))) {//null if not found
map = new SettingsMap();
if (projectMap.size() <= projectMap.count()) projectMap.resize( nextPrime(projectMap.size()));
projectMap.insert( projectList[i], map);
}
map->insert(entryList[j],entry);
}
}
}
void ProjectSettings::test() {//debug write ProjectSettings contents to konsole
qDebug("\n*************************** ProjectSettings contents:");
QDictIterator<SettingsMap> it(projectMap);
for( ; it.current(); ++it ) {
QString pName = it.currentKey();
pName.replace(QRegExp("\\^e"),"/");
pName.replace(QRegExp("\\^0"),"^");
qDebug("\nproject: "+pName);
SettingsMap *tmp = projectMap.find(it.currentKey());
SettingsMap::iterator it;
for ( it = tmp->begin(); it != tmp->end(); ++it ) {
qDebug(it.key()+" : "+it.data());
}
}
qDebug("&&&&&&&&&&&&&&&&&&&&&&&&&&&done\n");
}
syntax highlighted by Code2HTML, v. 0.9.1