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.

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

mercurial