diff -r 27e940e8e5f3 -r d64aaa7d146f as_pref.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/as_pref.cpp Fri Nov 28 11:21:08 2008 +0100 @@ -0,0 +1,354 @@ +/*************************************************************************** + preferences.cc + ------------------- + A class to access persistant preferences for an application. Utilizes XML/DOM. + Basic format is: + + + + + + ------------------- + begin Tue Sep 12 2000 + author David Johnson, david@usermode.org + ------------------- + Copyright 2000, David Johnson + Please see the header file for copyright and license information +***************************************************************************/ + +// version 2 + +// TODO: fix up to account for worst case scenarios: +// keys without values in file, and +// checking for a key that doesn't exist puts it into the map +// then it gets written out if dirty, possibly corrupting the file + +// TODO: Fix up error reporting + +#include +#include +#include + +#include "as_pref.h" + +////////////////////////////////////////////////////////////////////////////// +// Construction // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// Preferences() +// ------------- +// Constructor. Takes the preferences file name as an argument. + +Preferences::Preferences(const QString& filename, + const QString& format, + const QString& version) + : dirty_(false), + currentgroup_(), + file_(filename), + format_(format), + version_(version), + filestate_(false), + formatstate_(false), + groups_() +{ + readData(); + dirty_ = false; + currentgroup_ = "Default"; +} + +////////////////////////////////////////////////////////////////////////////// +// ~Preferences() +// --------------- +// Destructor + +Preferences::~Preferences() +{ + if (dirty_) writeData(); +} + +////////////////////////////////////////////////////////////////////////////// +// Settings +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// getBoolean() +// ------------ +// Get a boolean value + +bool Preferences::getBool(const QString& key, bool def) +{ + buffer_ = getString(key, def ? "true" : "false"); + if (buffer_.isEmpty()) return def; + if (buffer_.contains("true")) + return true; + else + return false; +} + +////////////////////////////////////////////////////////////////////////////// +// setBoolean() +// ------------ +// Set a boolean value + +void Preferences::setBool(const QString& key, bool value) +{ + groups_[currentgroup_][key] = value ? "true" : "false"; + dirty_ = true; +} + +////////////////////////////////////////////////////////////////////////////// +// getNumber() +// ----------- +// Get a number value + +// TODO: this might be a place for templates + +long Preferences::getNumber(const QString& key, long def) +{ + buffer_ = getString(key, QString::number(def)); + if (buffer_.isEmpty()) return def; + + bool ok; + long num = buffer_.toLong(&ok); + if (ok) return num; + else return def; +} + +////////////////////////////////////////////////////////////////////////////// +// setNumber() +// ----------- +// Set a number value + +void Preferences::setNumber(const QString& key, long value) +{ + buffer_.setNum(value); + + groups_[currentgroup_][key] = buffer_; + dirty_ = true; +} + +////////////////////////////////////////////////////////////////////////////// +// getDouble() +// ----------- +// Get a double value + +double Preferences::getDouble(const QString& key, double def) +{ + buffer_ = getString(key, QString::number(def)); + if (buffer_.isEmpty()) return def; + + bool ok; + double num = buffer_.toDouble(&ok); + if (ok) return num; + else return def; +} + +////////////////////////////////////////////////////////////////////////////// +// setDouble() +// ----------- +// Set a double value + +void Preferences::setDouble(const QString& key, double value) +{ + buffer_.setNum(value); + + groups_[currentgroup_][key] = buffer_; + dirty_ = true; +} + + +////////////////////////////////////////////////////////////////////////////// +// getString() +// ----------- +// Get a string value + +QString Preferences::getString(const QString& key, const QString& def) +{ + buffer_ = ""; + if (groups_.contains(currentgroup_)) { + if (groups_[currentgroup_].contains(key)) { + buffer_ = groups_[currentgroup_][key]; + } + } + if (buffer_.isEmpty()) return def; + return buffer_; +} + +////////////////////////////////////////////////////////////////////////////// +// setString() +// ----------- +// Set a string value + +void Preferences::setString(const QString& key, const QString& value) +{ + groups_[currentgroup_][key] = value; + dirty_ = true; +} + +////////////////////////////////////////////////////////////////////////////// +// removeValue() +// ------------- +// Remove a value from the preferences + +void Preferences::removeKey(const QString& key) +{ + groups_[currentgroup_].remove(key); +} + +////////////////////////////////////////////////////////////////////////////// +// removeGroup() +// ------------- +// Remove a group from the preferences, and all its options + +void Preferences::removeGroup() +{ + groups_.remove(currentgroup_); +} + +////////////////////////////////////////////////////////////////////////////// +// flush() +// ------- +// Flush the preferences to file + +void Preferences::flush() +{ + if (dirty_) { + writeData(); + dirty_ = false; + } +} + +////////////////////////////////////////////////////////////////////////////// +// Serialization // +////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////// +// readData() +// ---------- +// Read data from the file + +void Preferences::readData() +{ + // open file + QFile* datafile = new QFile(file_); + if (!datafile->open(IO_ReadOnly)) { + // error opening file + qWarning("Error: cannot open preferences file " + file_); + datafile->close(); + delete (datafile); + filestate_ = false; + return; + } + filestate_ = true; + + // open dom document + QDomDocument doc("preferences"); + if (!doc.setContent(datafile)) { + qWarning("Error: " + file_ + " is not a proper preferences file"); + datafile->close(); + delete (datafile); + formatstate_ = false; + return; + } + datafile->close(); + delete (datafile); + + // check the doc type and stuff + if (doc.doctype().name() != "preferences") { + // wrong file type + qWarning("Error: " +file_ + " is not a valid preferences file"); + formatstate_ = false; + return; + } + QDomElement root = doc.documentElement(); + if (root.attribute("application") != format_) { + // right file type, wrong application + qWarning("Error: " + file_ + " is not a preferences file for " + format_); + formatstate_ = false; + return; + } + // We don't care about application version... + + // get list of groups + QDomNodeList nodes = root.elementsByTagName("group"); + + // iterate through the groups + QDomNodeList options; + for (unsigned n=0; n::Iterator git; + PrefMap::Iterator pit; + QDomElement group, option; + for (git = groups_.begin(); git != groups_.end(); ++git) { + // create a group element + group = doc.createElement("group"); + group.setAttribute("name", git.key()); + // add in options + for (pit = (*git).begin(); pit != (*git).end(); ++pit) { + option = doc.createElement("option"); + option.setAttribute("key", pit.key()); + option.setAttribute("value", pit.data()); + group.appendChild(option); + } + root.appendChild(group); + } + doc.appendChild(root); + + // open file + QFile* datafile = new QFile(file_); + if (!datafile->open(IO_WriteOnly)) { + // error opening file + qWarning("Error: Cannot open preferences file " + file_); + datafile->close(); + delete (datafile); + filestate_ = false; + return; + } + filestate_ = true; + + // write it out + QTextStream textstream(datafile); + doc.save(textstream, 0); + datafile->close(); + delete (datafile); + formatstate_ = true; +}