as_pref.cpp

Fri, 05 Dec 2008 23:15:28 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 05 Dec 2008 23:15:28 +0100
changeset 4
c920180c879a
parent 1
d64aaa7d146f
child 15
0e0eb7c91312
permissions
-rw-r--r--

Correct version number and date in documentation.

michael@1 1 /***************************************************************************
michael@1 2 preferences.cc
michael@1 3 -------------------
michael@1 4 A class to access persistant preferences for an application. Utilizes XML/DOM.
michael@1 5 Basic format is:
michael@1 6 <!DOCTYPE preferences>
michael@1 7 <preferences version="0.1" application="MyApp" >
michael@1 8 <group name="Default" >
michael@1 9 <option key="alpha" value="true" />
michael@1 10 <option key="beta" value="99" />
michael@1 11 <option key="gamma" value="test" />
michael@1 12 </group>
michael@1 13 </preferences>
michael@1 14 -------------------
michael@1 15 begin Tue Sep 12 2000
michael@1 16 author David Johnson, david@usermode.org
michael@1 17 -------------------
michael@1 18 Copyright 2000, David Johnson
michael@1 19 Please see the header file for copyright and license information
michael@1 20 ***************************************************************************/
michael@1 21
michael@1 22 // version 2
michael@1 23
michael@1 24 // TODO: fix up to account for worst case scenarios:
michael@1 25 // keys without values in file, and
michael@1 26 // checking for a key that doesn't exist puts it into the map
michael@1 27 // then it gets written out if dirty, possibly corrupting the file
michael@1 28
michael@1 29 // TODO: Fix up error reporting
michael@1 30
michael@3 31 #define QT3_SUPPORT
michael@3 32
michael@3 33 #include <Qt/qdom.h>
michael@1 34 #include <qfile.h>
michael@1 35 #include <qtextstream.h>
michael@1 36
michael@1 37 #include "as_pref.h"
michael@1 38
michael@1 39 //////////////////////////////////////////////////////////////////////////////
michael@1 40 // Construction //
michael@1 41 //////////////////////////////////////////////////////////////////////////////
michael@1 42
michael@1 43 //////////////////////////////////////////////////////////////////////////////
michael@1 44 // Preferences()
michael@1 45 // -------------
michael@1 46 // Constructor. Takes the preferences file name as an argument.
michael@1 47
michael@1 48 Preferences::Preferences(const QString& filename,
michael@1 49 const QString& format,
michael@1 50 const QString& version)
michael@1 51 : dirty_(false),
michael@1 52 currentgroup_(),
michael@1 53 file_(filename),
michael@1 54 format_(format),
michael@1 55 version_(version),
michael@1 56 filestate_(false),
michael@1 57 formatstate_(false),
michael@1 58 groups_()
michael@1 59 {
michael@1 60 readData();
michael@1 61 dirty_ = false;
michael@1 62 currentgroup_ = "Default";
michael@1 63 }
michael@1 64
michael@1 65 //////////////////////////////////////////////////////////////////////////////
michael@1 66 // ~Preferences()
michael@1 67 // ---------------
michael@1 68 // Destructor
michael@1 69
michael@1 70 Preferences::~Preferences()
michael@1 71 {
michael@1 72 if (dirty_) writeData();
michael@1 73 }
michael@1 74
michael@1 75 //////////////////////////////////////////////////////////////////////////////
michael@1 76 // Settings
michael@1 77 //////////////////////////////////////////////////////////////////////////////
michael@1 78
michael@1 79 //////////////////////////////////////////////////////////////////////////////
michael@1 80 // getBoolean()
michael@1 81 // ------------
michael@1 82 // Get a boolean value
michael@1 83
michael@1 84 bool Preferences::getBool(const QString& key, bool def)
michael@1 85 {
michael@1 86 buffer_ = getString(key, def ? "true" : "false");
michael@1 87 if (buffer_.isEmpty()) return def;
michael@1 88 if (buffer_.contains("true"))
michael@1 89 return true;
michael@1 90 else
michael@1 91 return false;
michael@1 92 }
michael@1 93
michael@1 94 //////////////////////////////////////////////////////////////////////////////
michael@1 95 // setBoolean()
michael@1 96 // ------------
michael@1 97 // Set a boolean value
michael@1 98
michael@1 99 void Preferences::setBool(const QString& key, bool value)
michael@1 100 {
michael@1 101 groups_[currentgroup_][key] = value ? "true" : "false";
michael@1 102 dirty_ = true;
michael@1 103 }
michael@1 104
michael@1 105 //////////////////////////////////////////////////////////////////////////////
michael@1 106 // getNumber()
michael@1 107 // -----------
michael@1 108 // Get a number value
michael@1 109
michael@1 110 // TODO: this might be a place for templates
michael@1 111
michael@1 112 long Preferences::getNumber(const QString& key, long def)
michael@1 113 {
michael@1 114 buffer_ = getString(key, QString::number(def));
michael@1 115 if (buffer_.isEmpty()) return def;
michael@1 116
michael@1 117 bool ok;
michael@1 118 long num = buffer_.toLong(&ok);
michael@1 119 if (ok) return num;
michael@1 120 else return def;
michael@1 121 }
michael@1 122
michael@1 123 //////////////////////////////////////////////////////////////////////////////
michael@1 124 // setNumber()
michael@1 125 // -----------
michael@1 126 // Set a number value
michael@1 127
michael@1 128 void Preferences::setNumber(const QString& key, long value)
michael@1 129 {
michael@1 130 buffer_.setNum(value);
michael@1 131
michael@1 132 groups_[currentgroup_][key] = buffer_;
michael@1 133 dirty_ = true;
michael@1 134 }
michael@1 135
michael@1 136 //////////////////////////////////////////////////////////////////////////////
michael@1 137 // getDouble()
michael@1 138 // -----------
michael@1 139 // Get a double value
michael@1 140
michael@1 141 double Preferences::getDouble(const QString& key, double def)
michael@1 142 {
michael@1 143 buffer_ = getString(key, QString::number(def));
michael@1 144 if (buffer_.isEmpty()) return def;
michael@1 145
michael@1 146 bool ok;
michael@1 147 double num = buffer_.toDouble(&ok);
michael@1 148 if (ok) return num;
michael@1 149 else return def;
michael@1 150 }
michael@1 151
michael@1 152 //////////////////////////////////////////////////////////////////////////////
michael@1 153 // setDouble()
michael@1 154 // -----------
michael@1 155 // Set a double value
michael@1 156
michael@1 157 void Preferences::setDouble(const QString& key, double value)
michael@1 158 {
michael@1 159 buffer_.setNum(value);
michael@1 160
michael@1 161 groups_[currentgroup_][key] = buffer_;
michael@1 162 dirty_ = true;
michael@1 163 }
michael@1 164
michael@1 165
michael@1 166 //////////////////////////////////////////////////////////////////////////////
michael@1 167 // getString()
michael@1 168 // -----------
michael@1 169 // Get a string value
michael@1 170
michael@1 171 QString Preferences::getString(const QString& key, const QString& def)
michael@1 172 {
michael@1 173 buffer_ = "";
michael@1 174 if (groups_.contains(currentgroup_)) {
michael@1 175 if (groups_[currentgroup_].contains(key)) {
michael@1 176 buffer_ = groups_[currentgroup_][key];
michael@1 177 }
michael@1 178 }
michael@1 179 if (buffer_.isEmpty()) return def;
michael@1 180 return buffer_;
michael@1 181 }
michael@1 182
michael@1 183 //////////////////////////////////////////////////////////////////////////////
michael@1 184 // setString()
michael@1 185 // -----------
michael@1 186 // Set a string value
michael@1 187
michael@1 188 void Preferences::setString(const QString& key, const QString& value)
michael@1 189 {
michael@1 190 groups_[currentgroup_][key] = value;
michael@1 191 dirty_ = true;
michael@1 192 }
michael@1 193
michael@1 194 //////////////////////////////////////////////////////////////////////////////
michael@1 195 // removeValue()
michael@1 196 // -------------
michael@1 197 // Remove a value from the preferences
michael@1 198
michael@1 199 void Preferences::removeKey(const QString& key)
michael@1 200 {
michael@1 201 groups_[currentgroup_].remove(key);
michael@1 202 }
michael@1 203
michael@1 204 //////////////////////////////////////////////////////////////////////////////
michael@1 205 // removeGroup()
michael@1 206 // -------------
michael@1 207 // Remove a group from the preferences, and all its options
michael@1 208
michael@1 209 void Preferences::removeGroup()
michael@1 210 {
michael@1 211 groups_.remove(currentgroup_);
michael@1 212 }
michael@1 213
michael@1 214 //////////////////////////////////////////////////////////////////////////////
michael@1 215 // flush()
michael@1 216 // -------
michael@1 217 // Flush the preferences to file
michael@1 218
michael@1 219 void Preferences::flush()
michael@1 220 {
michael@1 221 if (dirty_) {
michael@1 222 writeData();
michael@1 223 dirty_ = false;
michael@1 224 }
michael@1 225 }
michael@1 226
michael@1 227 //////////////////////////////////////////////////////////////////////////////
michael@1 228 // Serialization //
michael@1 229 //////////////////////////////////////////////////////////////////////////////
michael@1 230
michael@1 231 //////////////////////////////////////////////////////////////////////////////
michael@1 232 // readData()
michael@1 233 // ----------
michael@1 234 // Read data from the file
michael@1 235
michael@1 236 void Preferences::readData()
michael@1 237 {
michael@1 238 // open file
michael@1 239 QFile* datafile = new QFile(file_);
michael@3 240 if (!datafile->open(QIODevice::ReadOnly)) {
michael@1 241 // error opening file
michael@1 242 qWarning("Error: cannot open preferences file " + file_);
michael@1 243 datafile->close();
michael@1 244 delete (datafile);
michael@1 245 filestate_ = false;
michael@1 246 return;
michael@1 247 }
michael@1 248 filestate_ = true;
michael@1 249
michael@1 250 // open dom document
michael@1 251 QDomDocument doc("preferences");
michael@1 252 if (!doc.setContent(datafile)) {
michael@1 253 qWarning("Error: " + file_ + " is not a proper preferences file");
michael@1 254 datafile->close();
michael@1 255 delete (datafile);
michael@1 256 formatstate_ = false;
michael@1 257 return;
michael@1 258 }
michael@1 259 datafile->close();
michael@1 260 delete (datafile);
michael@1 261
michael@1 262 // check the doc type and stuff
michael@1 263 if (doc.doctype().name() != "preferences") {
michael@1 264 // wrong file type
michael@1 265 qWarning("Error: " +file_ + " is not a valid preferences file");
michael@1 266 formatstate_ = false;
michael@1 267 return;
michael@1 268 }
michael@1 269 QDomElement root = doc.documentElement();
michael@1 270 if (root.attribute("application") != format_) {
michael@1 271 // right file type, wrong application
michael@1 272 qWarning("Error: " + file_ + " is not a preferences file for " + format_);
michael@1 273 formatstate_ = false;
michael@1 274 return;
michael@1 275 }
michael@1 276 // We don't care about application version...
michael@1 277
michael@1 278 // get list of groups
michael@1 279 QDomNodeList nodes = root.elementsByTagName("group");
michael@1 280
michael@1 281 // iterate through the groups
michael@1 282 QDomNodeList options;
michael@1 283 for (unsigned n=0; n<nodes.count(); ++n) {
michael@1 284 if (nodes.item(n).isElement()) {
michael@1 285 processGroup(nodes.item(n).toElement());
michael@1 286 }
michael@1 287 }
michael@1 288 formatstate_ = true;
michael@1 289 }
michael@1 290
michael@1 291 void Preferences::processGroup(QDomElement group)
michael@1 292 {
michael@1 293 QDomElement elem;
michael@1 294 QDomNodeList options;
michael@1 295 currentgroup_ = group.attribute("name", "Default");
michael@1 296 options = group.elementsByTagName("option");
michael@1 297 for (unsigned n=0; n<options.count(); ++n) {
michael@1 298 if (options.item(n).isElement()) {
michael@1 299 elem = options.item(n).toElement();
michael@1 300 setString(elem.attribute("key"), elem.attribute("value"));
michael@1 301 }
michael@1 302 }
michael@1 303 }
michael@1 304
michael@1 305 //////////////////////////////////////////////////////////////////////////////
michael@1 306 // writeData()
michael@1 307 // -----------
michael@1 308 // Write data out to the file
michael@1 309
michael@1 310 void Preferences::writeData()
michael@1 311 {
michael@1 312 QDomDocument doc("preferences");
michael@1 313
michael@1 314 // create the root element
michael@1 315 QDomElement root = doc.createElement(doc.doctype().name());
michael@1 316 root.setAttribute("version", version_);
michael@1 317 root.setAttribute("application", format_);
michael@1 318
michael@1 319 // now do our options group by group
michael@1 320 QMap<QString, PrefMap>::Iterator git;
michael@1 321 PrefMap::Iterator pit;
michael@1 322 QDomElement group, option;
michael@1 323 for (git = groups_.begin(); git != groups_.end(); ++git) {
michael@1 324 // create a group element
michael@1 325 group = doc.createElement("group");
michael@1 326 group.setAttribute("name", git.key());
michael@1 327 // add in options
michael@1 328 for (pit = (*git).begin(); pit != (*git).end(); ++pit) {
michael@1 329 option = doc.createElement("option");
michael@1 330 option.setAttribute("key", pit.key());
michael@1 331 option.setAttribute("value", pit.data());
michael@1 332 group.appendChild(option);
michael@1 333 }
michael@1 334 root.appendChild(group);
michael@1 335 }
michael@1 336 doc.appendChild(root);
michael@1 337
michael@1 338 // open file
michael@1 339 QFile* datafile = new QFile(file_);
michael@3 340 if (!datafile->open(QIODevice::WriteOnly)) {
michael@1 341 // error opening file
michael@1 342 qWarning("Error: Cannot open preferences file " + file_);
michael@1 343 datafile->close();
michael@1 344 delete (datafile);
michael@1 345 filestate_ = false;
michael@1 346 return;
michael@1 347 }
michael@1 348 filestate_ = true;
michael@1 349
michael@1 350 // write it out
michael@1 351 QTextStream textstream(datafile);
michael@1 352 doc.save(textstream, 0);
michael@1 353 datafile->close();
michael@1 354 delete (datafile);
michael@1 355 formatstate_ = true;
michael@1 356 }

mercurial