File indexing completed on 2024-04-21 15:08:24

0001 //
0002 // C++ Implementation: cProfileSettings
0003 //
0004 // Description: profile settings
0005 //
0006 /*
0007 Copyright 2008-2011 Tomas Mecir <kmuddy@kmuddy.com>
0008 
0009 This program is free software; you can redistribute it and/or
0010 modify it under the terms of the GNU General Public License as
0011 published by the Free Software Foundation; either version 2 of 
0012 the License, or (at your option) any later version.
0013 
0014 This program is distributed in the hope that it will be useful,
0015 but WITHOUT ANY WARRANTY; without even the implied warranty of
0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017 GNU General Public License for more details.
0018 
0019 You should have received a copy of the GNU General Public License
0020 along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #include "cprofilesettings.h"
0024 
0025 #include "cprofilemanager.h"
0026 
0027 #include <QDebug>
0028 #include <QDir>
0029 #include <QFile>
0030 #include <QXmlStreamReader>
0031 #include <QXmlStreamWriter>
0032 
0033 #include <map>
0034 
0035 using namespace std;
0036 
0037 struct cProfileSettings::Private {
0038   QString profileId;
0039   map<QString, bool> boolVals;
0040   map<QString, int> intVals;
0041   map<QString, QString> strVals;
0042 };
0043 
0044 cProfileSettings::Private *cProfileSettings::defd = nullptr;
0045 
0046 cProfileSettings::cProfileSettings (QString profileId)
0047 {
0048   d = new Private;
0049   d->profileId = profileId;
0050   initDefaultStorage ();
0051   load ();
0052 }
0053 
0054 cProfileSettings::~cProfileSettings ()
0055 {
0056   // we must NOT save here
0057   delete d;
0058 }
0059 
0060 void cProfileSettings::setBool (const QString &name, bool value)
0061 {
0062   d->boolVals[name] = value;
0063 }
0064 
0065 void cProfileSettings::setInt (const QString &name, int value)
0066 {
0067   d->intVals[name] = value;
0068 }
0069 
0070 void cProfileSettings::setString (const QString &name, const QString &value)
0071 {
0072   d->strVals[name] = value;
0073 }
0074 
0075 bool cProfileSettings::getBool (const QString &name) const
0076 {
0077   if (d->boolVals.count (name))
0078     return d->boolVals[name];
0079   if (defd->boolVals.count (name))
0080     return defd->boolVals[name];
0081   return false;
0082 }
0083 
0084 int cProfileSettings::getInt (const QString &name) const
0085 {
0086   if (d->intVals.count (name))
0087     return d->intVals[name];
0088   if (defd->intVals.count (name))
0089     return defd->intVals[name];
0090   return 0;
0091 }
0092 
0093 QString cProfileSettings::getString (const QString &name) const
0094 {
0095   if (d->strVals.count (name))
0096     return d->strVals[name];
0097   if (defd->strVals.count (name))
0098     return defd->strVals[name];
0099   return QString();
0100 }
0101 
0102 void cProfileSettings::setDefaultBool (const QString &name, bool value)
0103 {
0104   initDefaultStorage ();
0105   defd->boolVals[name] = value;
0106 }
0107 
0108 void cProfileSettings::setDefaultInt (const QString &name, int value)
0109 {
0110   initDefaultStorage ();
0111   defd->intVals[name] = value;
0112 }
0113 
0114 void cProfileSettings::setDefaultString (const QString &name, const QString &value)
0115 {
0116   initDefaultStorage ();
0117   defd->strVals[name] = value;
0118 }
0119 
0120 void cProfileSettings::initDefaultStorage ()
0121 {
0122   if (defd) return;
0123   defd = new Private;
0124   fillDefaultValues ();
0125 }
0126 
0127 void cProfileSettings::fillDefaultValues ()
0128 {
0129   setDefaultBool ("use-ansi", true);
0130   setDefaultBool ("limit-repeater", true);
0131   setDefaultString ("encoding", "ISO 8859-1");
0132   setDefaultBool ("startup-negotiate", true);
0133   setDefaultBool ("lpmud-style", false);
0134   setDefaultBool ("prompt-label", false);
0135   setDefaultBool ("prompt-status", true);
0136   setDefaultBool ("prompt-console", true);
0137   setDefaultBool ("auto-adv-transcript", false);
0138 
0139   QString movecmds[10];
0140   movecmds[0] = "n"; movecmds[1] = "ne";
0141   movecmds[2] = "e"; movecmds[3] = "se";
0142   movecmds[4] = "s"; movecmds[5] = "sw";
0143   movecmds[6] = "w"; movecmds[7] = "nw";
0144   movecmds[8] = "u"; movecmds[9] = "d";
0145   for (int i = 0; i < 10; i++)
0146     setDefaultString ("movement-command-"+QString::number(i), movecmds[i]);
0147   setDefaultString ("transcript-directory", QDir::homePath());
0148 
0149   setDefaultInt ("sound-dir-count", 0);
0150   setDefaultBool ("use-msp", true);
0151   setDefaultBool ("always-msp", false);
0152   setDefaultBool ("midline-msp", false);
0153 
0154   setDefaultInt ("use-mxp", 3);
0155   setDefaultString ("mxp-variable-prefix", QString());
0156 }
0157 
0158 
0159 void cProfileSettings::save ()
0160 {
0161   cProfileManager *pm = cProfileManager::self();
0162 
0163   QString path = pm->profilePath (d->profileId);
0164   QDir dir = QDir (path);
0165   if (!dir.exists()) QDir::root().mkpath (dir.absolutePath());
0166 
0167   dir.remove ("settings.backup");
0168   
0169   if (!QFile(path + "/settings.xml").copy (path + "/settings.backup")) {
0170     qDebug() << "Unable to backup settings.xml.";  // not fatal, may simply not exist
0171   }
0172   
0173   QFile f (path + "/settings.xml");
0174   if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
0175     qDebug() << "Unable to open settings.xml for writing.";
0176     return;  // problem
0177   }
0178   // save the profile file
0179   QXmlStreamWriter *writer = new QXmlStreamWriter (&f);
0180 
0181   writer->setAutoFormatting (true);  // make the generated XML more readable
0182   writer->writeStartDocument ();
0183 
0184   writer->writeStartElement ("profile");
0185   writer->writeAttribute ("version", "1.0");
0186 
0187   // boolean values
0188   map<QString, bool>::iterator itb;
0189   for (itb = d->boolVals.begin(); itb != d->boolVals.end(); ++itb) {
0190     writer->writeStartElement ("setting");
0191     writer->writeAttribute ("type", "bool");
0192     writer->writeAttribute ("name", itb->first);
0193     writer->writeAttribute ("value", itb->second ? "true" : "false");
0194     writer->writeEndElement ();
0195   }
0196 
0197   // integer values
0198   map<QString, int>::iterator it;
0199   for (it = d->intVals.begin(); it != d->intVals.end(); ++it) {
0200     writer->writeStartElement ("setting");
0201     writer->writeAttribute ("type", "integer");
0202     writer->writeAttribute ("name", it->first);
0203     writer->writeAttribute ("value", QString::number (it->second));
0204     writer->writeEndElement ();
0205   }
0206 
0207   // string values
0208   map<QString, QString>::iterator it2;
0209   for (it2 = d->strVals.begin(); it2 != d->strVals.end(); ++it2) {
0210     writer->writeStartElement ("setting");
0211     writer->writeAttribute ("type", "string");
0212     writer->writeAttribute ("name", it2->first);
0213     writer->writeAttribute ("value", it2->second);
0214     writer->writeEndElement ();
0215   }
0216 
0217   writer->writeEndElement ();
0218   writer->writeEndDocument ();
0219 
0220   f.close ();
0221   delete writer;
0222 }
0223 
0224 void cProfileSettings::load ()
0225 {
0226   cProfileManager *pm = cProfileManager::self();
0227   
0228   QString path = pm->profilePath (d->profileId);
0229   QDir dir = QDir (path);
0230   if (!dir.exists()) QDir::root().mkpath (dir.absolutePath());
0231 
0232   QFile f (path + "/settings.xml");
0233   if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) {
0234     qWarning() << "No settings file - nothing to do.";
0235     return;  // no profiles - nothing to do
0236   }
0237   QXmlStreamReader *reader = new QXmlStreamReader (&f);
0238   
0239   reader->readNext ();  // read the document start
0240   reader->readNext ();
0241   if (reader->isStartElement ())
0242     if (reader->name() == "profile")
0243       if (reader->attributes().value ("version") == "1.0") {
0244         // okay, read the list
0245         while (!reader->atEnd()) {
0246           reader->readNext ();
0247           if (reader->isStartElement () && (reader->name() == "setting")) {
0248             QString type = reader->attributes().value ("type").toString();
0249             QString name = reader->attributes().value ("name").toString();
0250             QString value = reader->attributes().value ("value").toString();
0251             if (type == "integer")
0252               setInt (name, value.toInt());
0253             else if (type == "bool")
0254               setBool (name, (value == "true"));
0255             else if (type == "string")
0256               setString (name, value);
0257             else
0258               qDebug() << "Unrecognized setting type " << type;
0259           }
0260         }
0261       } else reader->raiseError ("Unknown profile file version.");
0262     else reader->raiseError ("This is not a valid profile list file.");
0263   else reader->raiseError ("This file is corrupted.");
0264 
0265   if (reader->hasError()) {
0266     qWarning() << ("Error in settings.xml at line " + QString::number (reader->lineNumber()) + ", column " + QString::number (reader->columnNumber()) + QString (": ") + reader->errorString());
0267   }
0268 
0269   // close the file
0270   f.close ();
0271   delete reader;
0272 }
0273 
0274 
0275