2013-05-08 01:33:42 +00:00
|
|
|
#include "usersettings.hpp"
|
|
|
|
|
|
|
|
#include <QTextStream>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QString>
|
|
|
|
#include <QRegExp>
|
|
|
|
#include <QMap>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QTextCodec>
|
2013-06-15 11:40:18 +00:00
|
|
|
#include <QFile>
|
2013-05-08 01:33:42 +00:00
|
|
|
|
|
|
|
#include <components/files/configurationmanager.hpp>
|
|
|
|
|
|
|
|
#include "settingcontainer.hpp"
|
|
|
|
|
|
|
|
#include <boost/version.hpp>
|
2013-06-15 11:40:18 +00:00
|
|
|
|
|
|
|
#include <QDebug>
|
2013-05-08 01:33:42 +00:00
|
|
|
/**
|
|
|
|
* Workaround for problems with whitespaces in paths in older versions of Boost library
|
|
|
|
*/
|
|
|
|
#if (BOOST_VERSION <= 104600)
|
|
|
|
namespace boost
|
|
|
|
{
|
|
|
|
|
|
|
|
template<>
|
|
|
|
inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string>(const std::string& arg)
|
|
|
|
{
|
|
|
|
return boost::filesystem::path(arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
} /* namespace boost */
|
|
|
|
#endif /* (BOOST_VERSION <= 104600) */
|
|
|
|
|
2013-05-12 01:55:36 +00:00
|
|
|
CSMSettings::UserSettings::UserSettings()
|
2013-05-08 01:33:42 +00:00
|
|
|
{
|
2013-05-12 01:55:36 +00:00
|
|
|
mUserSettingsInstance = this;
|
2013-06-15 11:40:18 +00:00
|
|
|
|
|
|
|
mReadWriteMessage = QObject::tr("<br><b>Could not open or create file for writing</b><br><br> \
|
|
|
|
Please make sure you have the right permissions and try again.<br>");
|
|
|
|
|
|
|
|
mReadOnlyMessage = QObject::tr("<br><b>Could not open file for reading</b><br><br> \
|
|
|
|
Please make sure you have the right permissions and try again.<br>");
|
2013-05-08 01:33:42 +00:00
|
|
|
}
|
|
|
|
|
2013-05-11 10:55:46 +00:00
|
|
|
CSMSettings::UserSettings::~UserSettings()
|
2013-05-08 01:33:42 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, bool isReadOnly)
|
2013-05-08 01:33:42 +00:00
|
|
|
{
|
2013-06-15 11:40:18 +00:00
|
|
|
QFile *file = new QFile(filePath);
|
|
|
|
|
|
|
|
QIODevice::OpenMode openFlags;
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
if (isReadOnly)
|
|
|
|
openFlags = QIODevice::ReadOnly | QIODevice::Text;
|
|
|
|
else
|
|
|
|
openFlags = QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate;
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
if (!(file->open(openFlags)))
|
2013-05-08 01:33:42 +00:00
|
|
|
{
|
|
|
|
// File cannot be opened or created
|
|
|
|
QMessageBox msgBox;
|
2013-06-15 11:40:18 +00:00
|
|
|
msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error"));
|
2013-05-08 01:33:42 +00:00
|
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
2013-06-15 11:40:18 +00:00
|
|
|
|
|
|
|
QString fileMessage = QObject::tr("<br> File: %0").arg(file->fileName());
|
|
|
|
|
|
|
|
if (!isReadOnly)
|
|
|
|
msgBox.setText (mReadWriteMessage + fileMessage);
|
|
|
|
else
|
|
|
|
msgBox.setText (mReadOnlyMessage + fileMessage);
|
|
|
|
|
2013-05-08 01:33:42 +00:00
|
|
|
msgBox.exec();
|
|
|
|
delete file;
|
|
|
|
file = 0;
|
|
|
|
}
|
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
QTextStream *stream = 0;
|
|
|
|
|
|
|
|
if (file)
|
|
|
|
{
|
|
|
|
stream = new QTextStream(file);
|
|
|
|
stream->setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return stream;
|
|
|
|
|
2013-05-08 01:33:42 +00:00
|
|
|
}
|
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
bool CSMSettings::UserSettings::writeFile(QMap<QString, CSMSettings::SettingList *> &settings)
|
2013-05-08 01:33:42 +00:00
|
|
|
{
|
2013-06-15 11:40:18 +00:00
|
|
|
QTextStream *stream = openFileStream(mPaths.back());
|
2013-05-08 01:33:42 +00:00
|
|
|
|
|
|
|
QList<QString> keyList = settings.keys();
|
|
|
|
|
|
|
|
foreach (QString key, keyList)
|
|
|
|
{
|
|
|
|
SettingList *sectionSettings = settings[key];
|
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
*stream << "[" << key << "]" << '\n';
|
2013-05-08 01:33:42 +00:00
|
|
|
|
|
|
|
foreach (SettingContainer *item, *sectionSettings)
|
2013-06-15 11:40:18 +00:00
|
|
|
*stream << item->objectName() << " = " << item->getValue() << '\n';
|
2013-05-08 01:33:42 +00:00
|
|
|
}
|
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
stream->device()->close();
|
2013-05-08 01:33:42 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
const CSMSettings::SectionMap &CSMSettings::UserSettings::getSettings()
|
2013-05-08 01:33:42 +00:00
|
|
|
{
|
2013-06-15 11:40:18 +00:00
|
|
|
return mSectionSettings;
|
|
|
|
}
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
void CSMSettings::UserSettings::loadFromFile(const QString &filePath)
|
|
|
|
{
|
|
|
|
if (filePath.isEmpty())
|
|
|
|
return;
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
mSectionSettings.clear();
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
QTextStream *stream = openFileStream (filePath, true);
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
if (stream)
|
2013-05-08 01:33:42 +00:00
|
|
|
{
|
2013-06-15 11:40:18 +00:00
|
|
|
//looks for a square bracket, "'\\["
|
|
|
|
//that has one or more "not nothing" in it, "([^]]+)"
|
|
|
|
//and is closed with a square bracket, "\\]"
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
QRegExp sectionRe("^\\[([^]]+)\\]");
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
//Find any character(s) that is/are not equal sign(s), "[^=]+"
|
|
|
|
//followed by an optional whitespace, an equal sign, and another optional whitespace, "\\s*=\\s*"
|
|
|
|
//and one or more periods, "(.+)"
|
|
|
|
|
|
|
|
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
2013-05-08 01:33:42 +00:00
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
CSMSettings::SettingMap *settings = 0;
|
|
|
|
QString section = "none";
|
|
|
|
|
|
|
|
while (!stream->atEnd())
|
2013-05-08 01:33:42 +00:00
|
|
|
{
|
2013-06-15 11:40:18 +00:00
|
|
|
QString line = stream->readLine().simplified();
|
|
|
|
|
|
|
|
if (line.isEmpty() || line.startsWith("#"))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
//if a section is found, push it onto a new QStringList
|
|
|
|
//and push the QStringList onto
|
|
|
|
if (sectionRe.exactMatch(line))
|
|
|
|
{
|
|
|
|
//add the previous section's settings to the member map
|
|
|
|
if (settings)
|
|
|
|
mSectionSettings.insert(section, settings);
|
|
|
|
|
|
|
|
//save new section and create a new list
|
|
|
|
section = sectionRe.cap(1);
|
|
|
|
settings = new SettingMap;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keyRe.indexIn(line) != -1)
|
|
|
|
{
|
|
|
|
SettingContainer *sc = new SettingContainer (keyRe.cap(2).simplified());
|
|
|
|
sc->setObjectName(keyRe.cap(1).simplified());
|
|
|
|
(*settings)[keyRe.cap(1).simplified()] = sc;
|
|
|
|
}
|
|
|
|
|
2013-05-08 01:33:42 +00:00
|
|
|
}
|
|
|
|
|
2013-06-15 11:40:18 +00:00
|
|
|
mSectionSettings.insert(section, settings);
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->device()->close();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
|
|
|
|
{
|
|
|
|
if (mPaths.count() == 0)
|
|
|
|
{
|
|
|
|
mPaths.append(QString::fromStdString(mCfgMgr.getGlobalPath().string()) + fileName);
|
|
|
|
mPaths.append(QString::fromStdString(mCfgMgr.getLocalPath().string()) + fileName);
|
|
|
|
mPaths.append(QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName);
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach (const QString &path, mPaths)
|
|
|
|
{
|
|
|
|
qDebug() << "Loading config file:" << qPrintable(path);
|
|
|
|
loadFromFile(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSMSettings::UserSettings::updateSettings (const QString §ionName, const QString &settingName)
|
|
|
|
{
|
|
|
|
SettingMap *settings = mSectionSettings[sectionName];
|
|
|
|
|
|
|
|
if (!settings)
|
|
|
|
return;
|
|
|
|
|
|
|
|
SettingContainer *setting = 0;
|
|
|
|
|
|
|
|
if (settingName.isEmpty())
|
|
|
|
{
|
|
|
|
foreach (setting, *settings)
|
|
|
|
emit signalUpdateEditorSetting (setting->objectName(), setting->getValue());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setting = (*settings)[settingName];
|
|
|
|
|
|
|
|
if (setting)
|
|
|
|
emit signalUpdateEditorSetting (setting->objectName(), setting->getValue());
|
2013-05-08 01:33:42 +00:00
|
|
|
}
|
|
|
|
}
|