1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-16 12:49:56 +00:00
openmw-tes3mp/apps/opencs/model/settings/usersettings.cpp

266 lines
7.4 KiB
C++
Raw Normal View History

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>
#include <QFile>
2013-05-08 01:33:42 +00:00
#include <components/files/configurationmanager.hpp>
#include "settingcontainer.hpp"
#include <boost/version.hpp>
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-06-12 10:36:35 +00:00
CSMSettings::UserSettings *CSMSettings::UserSettings::mUserSettingsInstance = 0;
2013-05-08 01:33:42 +00:00
CSMSettings::UserSettings::UserSettings()
2013-05-08 01:33:42 +00:00
{
2013-06-12 10:36:35 +00:00
assert(!mUserSettingsInstance);
mUserSettingsInstance = this;
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
}
CSMSettings::UserSettings::~UserSettings()
2013-05-08 01:33:42 +00:00
{
2013-06-12 10:36:35 +00:00
mUserSettingsInstance = 0;
2013-05-08 01:33:42 +00:00
}
QTextStream *CSMSettings::UserSettings::openFileStream (const QString &filePath, bool isReadOnly) const
2013-05-08 01:33:42 +00:00
{
QIODevice::OpenMode openFlags = QIODevice::Text;
2013-05-08 01:33:42 +00:00
if (isReadOnly)
openFlags = QIODevice::ReadOnly | openFlags;
else
openFlags = QIODevice::ReadWrite | QIODevice::Truncate | openFlags;
2013-05-08 01:33:42 +00:00
QFile *file = new QFile(filePath);
QTextStream *stream = 0;
if (file->open(openFlags))
{
stream = new QTextStream(file);
stream->setCodec(QTextCodec::codecForName("UTF-8"));
}
return stream;
2013-05-08 01:33:42 +00:00
}
bool CSMSettings::UserSettings::writeSettings(QMap<QString, CSMSettings::SettingList *> &settings)
2013-05-08 01:33:42 +00:00
{
QTextStream *stream = openFileStream(mUserFilePath);
2013-05-08 01:33:42 +00:00
bool success = (stream);
2013-05-08 01:33:42 +00:00
if (success)
2013-05-08 01:33:42 +00:00
{
QList<QString> keyList = settings.keys();
2013-05-08 01:33:42 +00:00
foreach (QString key, keyList)
{
SettingList *sectionSettings = settings[key];
2013-05-08 01:33:42 +00:00
*stream << "[" << key << "]" << '\n';
2013-05-08 01:33:42 +00:00
foreach (SettingContainer *item, *sectionSettings)
*stream << item->objectName() << " = " << item->getValue() << '\n';
}
2013-05-08 01:33:42 +00:00
stream->device()->close();
delete stream;
stream = 0;
}
else
{
displayFileErrorMessage(mReadWriteMessage, false);
}
return (success);
2013-05-08 01:33:42 +00:00
}
const CSMSettings::SectionMap &CSMSettings::UserSettings::getSettings() const
2013-05-08 01:33:42 +00:00
{
return mSectionSettings;
}
2013-05-08 01:33:42 +00:00
bool CSMSettings::UserSettings::loadFromFile(const QString &filePath)
{
if (filePath.isEmpty())
return false;
2013-05-08 01:33:42 +00:00
mSectionSettings.clear();
2013-05-08 01:33:42 +00:00
QTextStream *stream = openFileStream (filePath, true);
2013-05-08 01:33:42 +00:00
bool success = (stream);
if (success)
2013-05-08 01:33:42 +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
QRegExp sectionRe("^\\[([^]]+)\\]");
2013-05-08 01:33:42 +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
CSMSettings::SettingMap *settings = 0;
QString section = "none";
while (!stream->atEnd())
2013-05-08 01:33:42 +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
}
mSectionSettings.insert(section, settings);
stream->device()->close();
delete stream;
stream = 0;
}
return success;
}
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
{
//global
QString globalFilePath = QString::fromStdString(mCfgMgr.getGlobalPath().string()) + fileName;
bool globalOk = loadFromFile(globalFilePath);
//local
QString localFilePath = QString::fromStdString(mCfgMgr.getLocalPath().string()) + fileName;
bool localOk = loadFromFile(localFilePath);
//user
mUserFilePath = QString::fromStdString(mCfgMgr.getUserPath().string()) + fileName;
loadFromFile(mUserFilePath);
if (!(localOk || globalOk))
{
QString message = QObject::tr("<br><b>Could not open user settings files for reading</b><br><br> \
Global and local settings files could not be read.\
You may have incorrect file permissions or the OpenCS installation may be corrupted.<br>");
message += QObject::tr("<br>Global filepath: ") + globalFilePath;
message += QObject::tr("<br>Local filepath: ") + localFilePath;
displayFileErrorMessage ( message, true);
}
}
void CSMSettings::UserSettings::updateSettings (const QString &sectionName, const QString &settingName)
{
if (mSectionSettings.find(sectionName) == mSectionSettings.end())
return;
SettingMap *settings = mSectionSettings.value(sectionName);
if (settingName.isEmpty())
{
foreach (const SettingContainer *setting, *settings)
emit signalUpdateEditorSetting (setting->objectName(), setting->getValue());
}
else
{
if (settings->find(settingName) != settings->end())
2013-06-08 22:34:27 +00:00
{
const SettingContainer *setting = settings->value(settingName);
emit signalUpdateEditorSetting (setting->objectName(), setting->getValue());
2013-06-08 22:34:27 +00:00
}
}
2013-06-12 10:36:35 +00:00
}
2013-06-08 22:34:27 +00:00
QString CSMSettings::UserSettings::getSetting (const QString &section, const QString &setting) const
2013-06-12 10:36:35 +00:00
{
QString retVal = "";
2013-06-08 22:34:27 +00:00
if (mSectionSettings.find(section) != mSectionSettings.end())
{
CSMSettings::SettingMap *settings = mSectionSettings.value(section);
2013-06-08 22:34:27 +00:00
if (settings->find(setting) != settings->end())
retVal = settings->value(setting)->getValue();
}
2013-06-08 22:34:27 +00:00
return retVal;
2013-06-08 22:34:27 +00:00
}
CSMSettings::UserSettings& CSMSettings::UserSettings::instance()
2013-06-12 10:36:35 +00:00
{
assert(mUserSettingsInstance);
return *mUserSettingsInstance;
2013-06-12 10:36:35 +00:00
}
void CSMSettings::UserSettings::displayFileErrorMessage(const QString &message, bool isReadOnly)
{
// File cannot be opened or created
QMessageBox msgBox;
msgBox.setWindowTitle(QObject::tr("OpenCS configuration file I/O error"));
msgBox.setIcon(QMessageBox::Critical);
msgBox.setStandardButtons(QMessageBox::Ok);
if (!isReadOnly)
msgBox.setText (mReadWriteMessage + message);
else
msgBox.setText (message);
msgBox.exec();
}