|
|
|
|
/* -*- C++ -*- */
|
|
|
|
|
#ifndef QCONFIGDB_H
|
|
|
|
|
#define QCONFIGDB_H
|
|
|
|
|
|
|
|
|
|
/* the Configuration Database library, Version II
|
|
|
|
|
|
|
|
|
|
the KDE addressbook
|
|
|
|
|
|
|
|
|
|
$ Author: Mirko Boehm $
|
|
|
|
|
$ Copyright: (C) 1996-2001, Mirko Boehm $
|
|
|
|
|
$ Contact: mirko@kde.org
|
|
|
|
|
http://www.kde.org $
|
|
|
|
|
$ License: GPL with the following explicit clarification:
|
|
|
|
|
This code may be linked against any version of the Qt toolkit
|
|
|
|
|
from Troll Tech, Norway. $
|
|
|
|
|
|
|
|
|
|
$Id$
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace std { }
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
#include <list>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <tqwidget.h>
|
|
|
|
|
#include <tqcstring.h>
|
|
|
|
|
#include <tqstrlist.h>
|
|
|
|
|
|
|
|
|
|
class TQTimer;
|
|
|
|
|
class TQDate;
|
|
|
|
|
class TQString;
|
|
|
|
|
class TQDateTime;
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class TQTextStream;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This is some STL interna, a function object for use with STL
|
|
|
|
|
* container classes. Its only element function is the function
|
|
|
|
|
* operator that returns a comparison value of the both objects
|
|
|
|
|
* it is called with.
|
|
|
|
|
*/
|
|
|
|
|
struct QCStringLess
|
|
|
|
|
: public binary_function<const TQCString&, const TQCString&, bool>
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* The function operator, inline.
|
|
|
|
|
*/
|
|
|
|
|
bool operator()(const TQCString& x, const TQCString& y) const
|
|
|
|
|
{
|
|
|
|
|
return x < (const char*)y; // make one Qt operator fit exactly
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef map<TQCString, TQCString, QCStringLess> StringStringMap;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The class KeyValueMap is used for managing key-value-pairs
|
|
|
|
|
* WITHOUT any hierarchical structure. Objects of it can be
|
|
|
|
|
* used as they are or in conjunction with the configuration
|
|
|
|
|
* database class.
|
|
|
|
|
* While the first version used the string class, this second
|
|
|
|
|
* uses the TQCString class.
|
|
|
|
|
* The class uses pairs of methods for each datatype, they are
|
|
|
|
|
* called ::get and ::insert. Every overloaded version of this
|
|
|
|
|
* methods get the key of the settings and a reference to the
|
|
|
|
|
* value to set or to store it in. A boolean result reports if
|
|
|
|
|
* there where errors or if the key already existed. Keys must
|
|
|
|
|
* of course be unique. Please note that the map does NOT store type
|
|
|
|
|
* information for the keys. You may retrieve a boolean value for a string,
|
|
|
|
|
* it will work if the string is either "true" or "false".
|
|
|
|
|
* See the different get- and insert-methods for details.
|
|
|
|
|
*
|
|
|
|
|
* Capabilities of the class are:
|
|
|
|
|
* <OL>
|
|
|
|
|
* <LI> storing of any key-value-pair that is storable in
|
|
|
|
|
* string values (no binary objects currently), </LI>
|
|
|
|
|
* <LI> key-value-pairs are saved in human-readable text files
|
|
|
|
|
* when saving to disk, </LI>
|
|
|
|
|
* <LI> the values may contain newline and tabulator characters
|
|
|
|
|
* which will still be there after saving and rereading, </LI>
|
|
|
|
|
* <LI> supports the following datatypes: <OL>
|
|
|
|
|
* <LI> strings (of course), </LI>
|
|
|
|
|
* <LI> integers, </LI>
|
|
|
|
|
* <LI> floating point values and </LI>
|
|
|
|
|
* <LI> boolean states </LI> </OL> </LI>
|
|
|
|
|
* <LI> supports storing and retrieving of lists of values of the
|
|
|
|
|
* following datatypes: <OL>
|
|
|
|
|
* <LI> strings, </LI>
|
|
|
|
|
* <LI> integers and </LI>
|
|
|
|
|
* <LI> floating point values </LI> </OL>
|
|
|
|
|
* (boolean lists supported in future when requested) </LI>
|
|
|
|
|
* <LI> easy syntax of files, in general it is supposed to be a
|
|
|
|
|
* kind of guarantee (you know that free software never
|
|
|
|
|
* guarantees anything, don't you?) that every value that
|
|
|
|
|
* has been stored by one of the member functions of the
|
|
|
|
|
* class like <BR>
|
|
|
|
|
* <TT> insert(const TQCString& key, [value&]); </TT> <BR>
|
|
|
|
|
* can also be retrieved using <BR>
|
|
|
|
|
* <TT> get(const TQCString& key, [value&]);</TT> <BR>
|
|
|
|
|
* without being modified. <BR>
|
|
|
|
|
* (Please report anything that does not do so!) </LI> </OL>
|
|
|
|
|
* The class is used to implement the #QConfigDB class.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
class KeyValueMap
|
|
|
|
|
{
|
|
|
|
|
// ############################################################################
|
|
|
|
|
protected:
|
|
|
|
|
/**
|
|
|
|
|
* A map storing the key-value-pairs.
|
|
|
|
|
*/
|
|
|
|
|
StringStringMap* data;
|
|
|
|
|
/**
|
|
|
|
|
* Transform a complex string into a normal string object.
|
|
|
|
|
* The values are not stored as they are, they are coded into
|
|
|
|
|
* complex string where control and non-printable characters get a readable
|
|
|
|
|
* representation.
|
|
|
|
|
* When retrieving, this strings are translated back by this method.
|
|
|
|
|
* \a orig contains the string read from the file, \a index the position from
|
|
|
|
|
* where to start the translation (need not be the beginning of the string),
|
|
|
|
|
* \a result contains the transformed string, \a noOfChars the number of
|
|
|
|
|
* characters used to parse the string.
|
|
|
|
|
* Returns true if there where no errors while parsing.
|
|
|
|
|
* @see makeComplexString
|
|
|
|
|
*/
|
|
|
|
|
bool parseComplexString(const TQCString& orig, int index,
|
|
|
|
|
TQCString& result, int& noOfChars) const;
|
|
|
|
|
/**
|
|
|
|
|
* Codes a normal string into a complex string.
|
|
|
|
|
* @see parseComplexString
|
|
|
|
|
*/
|
|
|
|
|
TQCString makeComplexString(const TQCString& orig);
|
|
|
|
|
/**
|
|
|
|
|
* Inserts a complex string into the map.
|
|
|
|
|
* The string must be coded already, no tests are performed.
|
|
|
|
|
* \a if force is false, an existing value will not be overridden.
|
|
|
|
|
*/
|
|
|
|
|
bool insertRaw(const TQCString& key, const TQCString& value, bool force=false);
|
|
|
|
|
/**
|
|
|
|
|
* Retrieves the undecoded value (a complex string) of the given key.
|
|
|
|
|
*/
|
|
|
|
|
bool getRaw(const TQCString& key, TQCString& value) const;
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* The default constructor.
|
|
|
|
|
*/
|
|
|
|
|
KeyValueMap();
|
|
|
|
|
/**
|
|
|
|
|
* The copy constructor.
|
|
|
|
|
*/
|
|
|
|
|
KeyValueMap(const KeyValueMap&);
|
|
|
|
|
/**
|
|
|
|
|
* The virtual destructor.
|
|
|
|
|
*/
|
|
|
|
|
virtual ~KeyValueMap();
|
|
|
|
|
/**
|
|
|
|
|
* The begin iterator. Use it to iterate over the keys in the map.
|
|
|
|
|
*/
|
|
|
|
|
StringStringMap::iterator begin();
|
|
|
|
|
/**
|
|
|
|
|
* The end iterator.
|
|
|
|
|
*/
|
|
|
|
|
StringStringMap::iterator end();
|
|
|
|
|
/**
|
|
|
|
|
* Debugging aid: returns true if object is OK.
|
|
|
|
|
*/
|
|
|
|
|
bool invariant();
|
|
|
|
|
/**
|
|
|
|
|
* Returns the number of key-value-pairs in the map.
|
|
|
|
|
*/
|
|
|
|
|
unsigned int size() const;
|
|
|
|
|
/**
|
|
|
|
|
* Delete all entries.
|
|
|
|
|
*/
|
|
|
|
|
void clear();
|
|
|
|
|
/**
|
|
|
|
|
* Fills the map with the files contents.
|
|
|
|
|
* If the parameter \a force is true, it overrides keys that are
|
|
|
|
|
* already declared in the database and are declared again in the file.
|
|
|
|
|
* If \a relax is true, the value of a string may be empty.
|
|
|
|
|
*/
|
|
|
|
|
bool fill(const TQString&, bool force=false, bool relax=false);
|
|
|
|
|
/**
|
|
|
|
|
* Saves the database to a file.
|
|
|
|
|
* Only overrides existing files if force is true.
|
|
|
|
|
*/
|
|
|
|
|
bool save(const TQString&, bool force=false);
|
|
|
|
|
/**
|
|
|
|
|
* Saves contents to an already open text stream.
|
|
|
|
|
* \a count spaces are inserted before each line. This method is
|
|
|
|
|
* called when save hierarchical databases.
|
|
|
|
|
* @see ::QConfigDB
|
|
|
|
|
*/
|
|
|
|
|
bool save(TQTextStream& file, int count);
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a string.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString& key, TQCString& value) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a string value for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString& key, const TQCString& value, bool force=false);
|
|
|
|
|
/**
|
|
|
|
|
* Insert a character pointer for the given key.
|
|
|
|
|
* pgcc treats character pointers as boolean objects, not as strings.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
inline bool insert(const TQCString& key, const char* value, bool force=false);
|
|
|
|
|
/**
|
|
|
|
|
* Insert a line like "key_a="Hallo!" into the map as a key-value-pair.
|
|
|
|
|
* If force is true existing keys will be overridden.
|
|
|
|
|
* If relax is true the value may be empty an empty string.
|
|
|
|
|
* If encode is false, the string will not be coded (do not use!).
|
|
|
|
|
*/
|
|
|
|
|
bool insertLine(TQCString, bool force=false, bool relax=false, bool encode=true);
|
|
|
|
|
// ---------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a long integer.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, long&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a long integer value for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const long&, bool force=false);
|
|
|
|
|
// ---------------
|
|
|
|
|
/**
|
|
|
|
|
* For insertion of UNICODE strings, a special method pair is created. The
|
|
|
|
|
* data will be translated to utf8 and inserted in the map as a TQCString.
|
|
|
|
|
* This will probably be not fast, but this methods are not suited to save
|
|
|
|
|
* large amounts of data. For saving anything else than UNICODE strings,
|
|
|
|
|
* no such conversion is needed.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, TQString&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a UNICODE string value for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const TQString&, bool force=false);
|
|
|
|
|
// ---------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a double.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, double&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a double value for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const double&, bool force=false);
|
|
|
|
|
// ---------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a boolean value.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, bool&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a boolean value for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const bool&, bool force=false);
|
|
|
|
|
// ---------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a list of strings.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, list<TQCString>&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a list of strings for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const list<TQCString>&, bool force=false);
|
|
|
|
|
// --------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a TQStrList.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, TQStrList&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a TQStrList for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const TQStrList&, bool force=false);
|
|
|
|
|
// --------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a TQStringList. Beware of the difference -
|
|
|
|
|
* a TQStringList is a list of TQString objects, while TQStrList handles
|
|
|
|
|
* char* like objects.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, TQStringList&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a TQStringList for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const TQStringList&, bool force=false);
|
|
|
|
|
// --------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a list of long integers.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, list<long>&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a list of long integers for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const list<long>&, bool force=false);
|
|
|
|
|
// --------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a list of integers.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, list<int>&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a list of integers for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const list<int>&, bool force=false);
|
|
|
|
|
// -------------- some Qt high-level data types:
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a TQDate.
|
|
|
|
|
* The value will be parsed to a integer list that must be a \e valid
|
|
|
|
|
* date (see TQDate documentation). \c false will be returned if the value
|
|
|
|
|
* is not valid or a null date. This situation might only happen in
|
|
|
|
|
* manually created files, since the insert-method for QDates rejects to
|
|
|
|
|
* insert inalid dates, it inserts null dates instead.
|
|
|
|
|
* @see get(const TQCString&, TQDate &)
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, TQDate &) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a TQDate for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
* \e Attention: If you insert an invalid date a null date will be used.
|
|
|
|
|
* A null date will also be returned when retrieving this value.
|
|
|
|
|
* You will not be able to store an invalid date and retrieve it using
|
|
|
|
|
* ::get!
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const TQDate&, bool force=false);
|
|
|
|
|
// --------------
|
|
|
|
|
/**
|
|
|
|
|
* Get the value for the key as a list of doubles.
|
|
|
|
|
* \a key is the key to search for, \a value is a reference to the object
|
|
|
|
|
* the value for the key is assigned to.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString&, list<double>&) const;
|
|
|
|
|
/**
|
|
|
|
|
* Insert a list of doubles for the given key.
|
|
|
|
|
* If force is true, an existing value for this key will be overridden.
|
|
|
|
|
* The method returns false if the key exists and \a force is false.
|
|
|
|
|
*/
|
|
|
|
|
bool insert(const TQCString&, const list<double>&, bool force=false);
|
|
|
|
|
// --------------
|
|
|
|
|
// end of corresponding get-insert-pairs
|
|
|
|
|
/**
|
|
|
|
|
* Returns true if there are no keys declared in this map.
|
|
|
|
|
*/
|
|
|
|
|
bool empty();
|
|
|
|
|
/**
|
|
|
|
|
* Erases all key-value-pairs in the map.
|
|
|
|
|
*/
|
|
|
|
|
bool erase(const TQCString& key);
|
|
|
|
|
// ############################################################################
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A Section object manages one section of a configuration database.
|
|
|
|
|
* A configuration database consists of sections which in turn
|
|
|
|
|
* consist of other sections (recursive definition) and
|
|
|
|
|
* key-value-pairs. This file declares the Section class. An
|
|
|
|
|
* object of Section manages exactly one section during its
|
|
|
|
|
* lifetime.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
class Section
|
|
|
|
|
{
|
|
|
|
|
// ############################################################################
|
|
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* The StringSectionMap type is defined to make the code more readable.
|
|
|
|
|
*/
|
|
|
|
|
typedef map<TQCString, Section*, QCStringLess> StringSectionMap;
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
protected:
|
|
|
|
|
/**
|
|
|
|
|
* A map containing the subsections of this section.
|
|
|
|
|
*/
|
|
|
|
|
StringSectionMap sections;
|
|
|
|
|
/**
|
|
|
|
|
* The key-value-pairs of this section.
|
|
|
|
|
*/
|
|
|
|
|
KeyValueMap keys;
|
|
|
|
|
/**
|
|
|
|
|
* The number of spaces a subsection is indented in text files.
|
|
|
|
|
*/
|
|
|
|
|
static const int indent_width;
|
|
|
|
|
/**
|
|
|
|
|
* Insert the spaces for indention the lines of this section when saving.
|
|
|
|
|
*/
|
|
|
|
|
void insertIndentSpace(TQTextStream& file, int level);
|
|
|
|
|
/**
|
|
|
|
|
* Check whether the string (one line of the file currently read) marks the
|
|
|
|
|
* beginning of a new subsection (usually [sectionname]).
|
|
|
|
|
*/
|
|
|
|
|
bool isBeginOfSection(TQCString);
|
|
|
|
|
/**
|
|
|
|
|
* Check whether the string (one line of the file currently read) marks the
|
|
|
|
|
* end of a new subsection (usually [END]).
|
|
|
|
|
*/
|
|
|
|
|
bool isEndOfSection(TQCString);
|
|
|
|
|
/**
|
|
|
|
|
* Extract the name of the section from the string.
|
|
|
|
|
* The string must contain the line that starts the section.
|
|
|
|
|
* @see ::isBeginOfSection
|
|
|
|
|
*/
|
|
|
|
|
TQCString nameOfSection(const TQCString&);
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* The default constructor.
|
|
|
|
|
*/
|
|
|
|
|
Section();
|
|
|
|
|
/**
|
|
|
|
|
* Constructor that fills the keys with the given map entries.
|
|
|
|
|
*/
|
|
|
|
|
Section(const KeyValueMap&);
|
|
|
|
|
// handling sections:
|
|
|
|
|
/**
|
|
|
|
|
* Add an empty new section.
|
|
|
|
|
*/
|
|
|
|
|
bool add(const TQCString&);
|
|
|
|
|
/**
|
|
|
|
|
* Add the section.
|
|
|
|
|
*/
|
|
|
|
|
bool add(const TQCString&, Section*);
|
|
|
|
|
/**
|
|
|
|
|
* Search for the section, returning an iterator to it.
|
|
|
|
|
*/
|
|
|
|
|
bool find(const TQCString&, StringSectionMap::iterator&);
|
|
|
|
|
/**
|
|
|
|
|
* Search for the section, returning a pointer to the section object.
|
|
|
|
|
*/
|
|
|
|
|
bool find(const TQCString&, Section*&);
|
|
|
|
|
/**
|
|
|
|
|
* Remove this subsection.
|
|
|
|
|
*/
|
|
|
|
|
bool remove(const TQCString&);
|
|
|
|
|
/**
|
|
|
|
|
* Return the key-value-pairs of this (!) section.
|
|
|
|
|
*/
|
|
|
|
|
KeyValueMap* getKeys();
|
|
|
|
|
/**
|
|
|
|
|
* Save this section to the given output stream.
|
|
|
|
|
* Level is the position in section tree depth (the hierarchy level).
|
|
|
|
|
* It is used for indenting.
|
|
|
|
|
*/
|
|
|
|
|
bool save(TQTextStream& stream, int level=0);
|
|
|
|
|
/**
|
|
|
|
|
* Read one section from the given input stream.
|
|
|
|
|
* The method does not expect the line that marks the begin of the
|
|
|
|
|
* section. If finish is false, the code does also not except the
|
|
|
|
|
* section to be ended with a line like [END].
|
|
|
|
|
*/
|
|
|
|
|
bool readSection(TQTextStream& file, bool finish=true);
|
|
|
|
|
/**
|
|
|
|
|
* Clears both subsections and keys.
|
|
|
|
|
*/
|
|
|
|
|
bool clear();
|
|
|
|
|
/**
|
|
|
|
|
* Returns whether this section is empty. A section is empty if it has no
|
|
|
|
|
* subsections and no key-value-pairs.
|
|
|
|
|
*/
|
|
|
|
|
bool empty();
|
|
|
|
|
// methods to allow iterating through the subsections
|
|
|
|
|
/**
|
|
|
|
|
* Return an iterator to the beginning of the subsections map.
|
|
|
|
|
*/
|
|
|
|
|
StringSectionMap::iterator sectionsBegin();
|
|
|
|
|
/**
|
|
|
|
|
* Return an iterator to the end of the subsections map.
|
|
|
|
|
*/
|
|
|
|
|
StringSectionMap::iterator sectionsEnd();
|
|
|
|
|
/**
|
|
|
|
|
* Return the number of subsections.
|
|
|
|
|
*/
|
|
|
|
|
unsigned int noOfSections();
|
|
|
|
|
// ############################################################################
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The class QConfigDB is used to manage text-based data files
|
|
|
|
|
* with hierarchical structure. <BR>
|
|
|
|
|
* It is derived from ::TQWidget, so it may be derived to display
|
|
|
|
|
* its contents. The basic implementation here does not display
|
|
|
|
|
* anything to make it a lean class. <BR>
|
|
|
|
|
* Some notes about the philosophy of the configuration
|
|
|
|
|
* database library: <OL>
|
|
|
|
|
* <LI> The tasks in managing the structure are shared between the three
|
|
|
|
|
* involved classes ::KeyValueMap, ::Section and QConfigDB. </LI>
|
|
|
|
|
* <LI> \a QConfigDB
|
|
|
|
|
* is used for retrieving sections or key-value-maps from the data
|
|
|
|
|
* hierarchy using keys. This keys are either pathes in UNIX style like
|
|
|
|
|
* "section_A/section_B/section_C", where C is a subsection of B which
|
|
|
|
|
* is in turn a subsection of A, or (STL) lists of strings in equivalent
|
|
|
|
|
* style (the first element of the list is treated as the first part of
|
|
|
|
|
* the path, and so on). </LI>
|
|
|
|
|
* <LI> Section objects are used to manipulate the tree structure below one
|
|
|
|
|
* particular section. </LI>
|
|
|
|
|
* <LI> KeyValueMap objects are used to retrieve and modify the
|
|
|
|
|
* key-value-pairs of one section, but not for its subsections. </LI>
|
|
|
|
|
* </OL>
|
|
|
|
|
* Thus, to use the keys of a specific section in the database, you first
|
|
|
|
|
* retrieve it using the ::get methods, and then manipulate the
|
|
|
|
|
* ::KeyValueMap you got. You may also retrieve a pointer to the whole
|
|
|
|
|
* section, if you need access to its subsections, for example. Although
|
|
|
|
|
* this sounds complex, it is a really easy and comprehensive way to write
|
|
|
|
|
* code using tree-structured text files. <BR>
|
|
|
|
|
* See the code examples provided with the library for details.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
class QConfigDB : public QWidget
|
|
|
|
|
{
|
|
|
|
|
// ############################################################################
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
protected:
|
|
|
|
|
/**
|
|
|
|
|
* The toplevel section.
|
|
|
|
|
*/
|
|
|
|
|
Section top;
|
|
|
|
|
/**
|
|
|
|
|
* A timer pointer for watching the file.
|
|
|
|
|
*/
|
|
|
|
|
TQTimer *timer;
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
public:
|
|
|
|
|
/**
|
|
|
|
|
* The Qt standard constructor.
|
|
|
|
|
*/
|
|
|
|
|
QConfigDB(TQWidget* parent=0, const char* name=0);
|
|
|
|
|
/**
|
|
|
|
|
* The virtual destructor.
|
|
|
|
|
*/
|
|
|
|
|
virtual ~QConfigDB();
|
|
|
|
|
/**
|
|
|
|
|
* Get the key-value-map for the section referenced by \a key.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString& key, KeyValueMap*& map);
|
|
|
|
|
/**
|
|
|
|
|
* Get the key-value-map for the section referenced by \a key as key list.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const list<TQCString>& key, KeyValueMap*& map);
|
|
|
|
|
/**
|
|
|
|
|
* Get the address of the specified Section object by its path.
|
|
|
|
|
* Never delete the section returned to you.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const TQCString& key, Section*&);
|
|
|
|
|
/**
|
|
|
|
|
* Get the address of the specified Section object by a path list.
|
|
|
|
|
* Never delete the section returned to you.
|
|
|
|
|
*/
|
|
|
|
|
bool get(const list<TQCString>& key, Section*&);
|
|
|
|
|
/**
|
|
|
|
|
* Get the keys of the toplevel section.
|
|
|
|
|
*/
|
|
|
|
|
KeyValueMap* get();
|
|
|
|
|
/**
|
|
|
|
|
* Create the section with this path.
|
|
|
|
|
* All elements of the path that do not exist are created.
|
|
|
|
|
*/
|
|
|
|
|
bool createSection(const TQCString& key);
|
|
|
|
|
/**
|
|
|
|
|
* Create the section with a path like the path list.
|
|
|
|
|
* All elements of the path that do not exist are created.
|
|
|
|
|
*/
|
|
|
|
|
bool createSection(const list<TQCString>& key);
|
|
|
|
|
/**
|
|
|
|
|
* Load the file.
|
|
|
|
|
* @see ::setFileName
|
|
|
|
|
*/
|
|
|
|
|
bool load();
|
|
|
|
|
/**
|
|
|
|
|
* Save the file.
|
|
|
|
|
* \a header will be the comment in the first line of the file.
|
|
|
|
|
* If \a force is \c true, a file opened read-only will be switched
|
|
|
|
|
* to read and write mode and back after saving.
|
|
|
|
|
* @see ::setFileName
|
|
|
|
|
*/
|
|
|
|
|
bool save(const char* header=0, bool force=false);
|
|
|
|
|
/**
|
|
|
|
|
* Set the current file name to \a name.
|
|
|
|
|
* Every QConfigDB object requires a file name to be set using
|
|
|
|
|
* this method before the file operations work.
|
|
|
|
|
* setFileName performs checks if the current user may use the file
|
|
|
|
|
* in the requested way. If \a ro is true, she must have
|
|
|
|
|
* permissions to read the file, if it is false, permission must be
|
|
|
|
|
* given to read and write the file. If \a mustexist is true, the file
|
|
|
|
|
* must have existed before, if not, it might be created.
|
|
|
|
|
* If any check failes, false is returned and the objects state is not
|
|
|
|
|
* altered. Subsequent calls may be used to check if a file already
|
|
|
|
|
* exists.
|
|
|
|
|
*/
|
|
|
|
|
bool setFileName(const TQString& name, bool mustexist=true, bool ro=false);
|
|
|
|
|
/**
|
|
|
|
|
* Store the modification time of the file for later check of changes.
|
|
|
|
|
*/
|
|
|
|
|
bool storeFileAge();
|
|
|
|
|
/**
|
|
|
|
|
* Give the current filename.
|
|
|
|
|
*/
|
|
|
|
|
TQString fileName();
|
|
|
|
|
/**
|
|
|
|
|
* Returns if the current file name is set for read only access.
|
|
|
|
|
*/
|
|
|
|
|
bool isRO();
|
|
|
|
|
/**
|
|
|
|
|
* Clear the whole database.
|
|
|
|
|
*/
|
|
|
|
|
bool clear();
|
|
|
|
|
/**
|
|
|
|
|
* Return whether the db is empty (e.g. the toplevel section is).
|
|
|
|
|
*/
|
|
|
|
|
bool empty();
|
|
|
|
|
/**
|
|
|
|
|
* Return a string describing the version.
|
|
|
|
|
*/
|
|
|
|
|
static const char* version() { return "2.0 $Revision$"; }
|
|
|
|
|
/**
|
|
|
|
|
* Check wether the given file is locked.
|
|
|
|
|
* The method returns zero if not, a number > zero is the pid of the process
|
|
|
|
|
* locking the file, a number < zero reports an error and indicates
|
|
|
|
|
* that the file is locked.
|
|
|
|
|
*/
|
|
|
|
|
static int IsLocked(const TQString& fn);
|
|
|
|
|
/**
|
|
|
|
|
* Check an existing lock file for its validity.
|
|
|
|
|
* \a fn is the name of the DATA file that is locked.
|
|
|
|
|
* As lockfiles often remain when a program crashes, this function
|
|
|
|
|
* checks certain conditions that show that a lockfile is not in
|
|
|
|
|
* use anymore, these are:
|
|
|
|
|
* <EFBFBD> there is no process with the pid in the lockfile,
|
|
|
|
|
* <EFBFBD> the systems boot-time is after the creation of the lockfile.
|
|
|
|
|
* The problem is that, if there is a process with the pid we have,
|
|
|
|
|
* this does not need to be the process that created the lockfile
|
|
|
|
|
* the method returns only false if it is shure that no such process
|
|
|
|
|
* exists.
|
|
|
|
|
* Returns false if the lockfile exists and is definitely stale or there
|
|
|
|
|
* is none, returns true if the lockfile seems to be really valid.
|
|
|
|
|
*/
|
|
|
|
|
static bool CheckLockFile(const TQString& filename);
|
|
|
|
|
/**
|
|
|
|
|
* The static method CleanLockFiles removes all files in the list
|
|
|
|
|
* ::LockFiles when called.
|
|
|
|
|
* Thus this function should be installed as a handler for SIGINT,
|
|
|
|
|
* SIGQUIT, SIGKILL, SIGTERM and other program abortion signals or
|
|
|
|
|
* should be called by the respective handlers.
|
|
|
|
|
*/
|
|
|
|
|
static void CleanLockFiles(int);
|
|
|
|
|
/**
|
|
|
|
|
* Lock the current file.
|
|
|
|
|
* Locking is done by creating a file \<filename\> lock.
|
|
|
|
|
* QConfigDB-objects will reject opening a file for reading and
|
|
|
|
|
* writing if a lockfile for the filename exists.
|
|
|
|
|
*/
|
|
|
|
|
bool lock();
|
|
|
|
|
/**
|
|
|
|
|
* Unlock the file.
|
|
|
|
|
*/
|
|
|
|
|
bool unlock();
|
|
|
|
|
/**
|
|
|
|
|
* If \a watch is <TT> true </TT> the object watches its file for changes.
|
|
|
|
|
* A timer is started that checks the file age every second and emits
|
|
|
|
|
* #fileChanged if it has been overridden meanwhile.
|
|
|
|
|
*/
|
|
|
|
|
void watch(bool state);
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
protected:
|
|
|
|
|
/**
|
|
|
|
|
* Transform a given path into a list of strings.
|
|
|
|
|
* All internal path handling is done with lists.
|
|
|
|
|
*/
|
|
|
|
|
list<TQCString> stringToKeylist(const TQCString&);
|
|
|
|
|
/**
|
|
|
|
|
* The current filename.
|
|
|
|
|
*/
|
|
|
|
|
TQString filename;
|
|
|
|
|
/**
|
|
|
|
|
* The current file opening mode.
|
|
|
|
|
*/
|
|
|
|
|
bool readonly;
|
|
|
|
|
/**
|
|
|
|
|
* Whether this object locked the file or not.
|
|
|
|
|
*/
|
|
|
|
|
bool locked;
|
|
|
|
|
/**
|
|
|
|
|
* The modification time of the last file access.
|
|
|
|
|
* Used to recognize file changes, is a null date if the modification time is
|
|
|
|
|
* unknown, what usually means that the current file has not been created and
|
|
|
|
|
* does not exist by now.
|
|
|
|
|
* @see ::storeFileAge
|
|
|
|
|
*/
|
|
|
|
|
TQDateTime *mtime;
|
|
|
|
|
/**
|
|
|
|
|
* Lock the file.
|
|
|
|
|
*/
|
|
|
|
|
bool lock(const TQString& file);
|
|
|
|
|
/**
|
|
|
|
|
* Debugging aid, called from REQUIRE and ENSURE macros when the Nana library
|
|
|
|
|
* is used.
|
|
|
|
|
*/
|
|
|
|
|
bool invariant();
|
|
|
|
|
/**
|
|
|
|
|
* All created lockfiles are notified in this list.
|
|
|
|
|
* The list contains the names of the lockfiles, not of the files itselfes.
|
|
|
|
|
*/
|
|
|
|
|
static list<TQString> LockFiles;
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
public slots:
|
|
|
|
|
/**
|
|
|
|
|
* Check for file changes.
|
|
|
|
|
* This method returns true if the file has been changed on disk
|
|
|
|
|
* after the last reading or saving.
|
|
|
|
|
*/
|
|
|
|
|
bool checkFileChanged();
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
signals:
|
|
|
|
|
/**
|
|
|
|
|
* This signal will be send when the database is cleared or reloaded.
|
|
|
|
|
* The notification might be needed if pointers or iterators are stored
|
|
|
|
|
* outside the database object as they get invalid after reloading.
|
|
|
|
|
* The signal hands over its \a this pointer.
|
|
|
|
|
*/
|
|
|
|
|
virtual void changed(QConfigDB*);
|
|
|
|
|
/**
|
|
|
|
|
* This signal will notify changes of the database <EM> file </EM>. The file
|
|
|
|
|
* will be monitored on disk if #watch has been activated.
|
|
|
|
|
*/
|
|
|
|
|
virtual void fileChanged();
|
|
|
|
|
// ############################################################################
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// ----- inline functions:
|
|
|
|
|
bool KeyValueMap::insert(const TQCString& key, const char* value, bool force)
|
|
|
|
|
{
|
|
|
|
|
return insert(key, (TQCString)value, force);
|
|
|
|
|
}
|
|
|
|
|
// -----
|
|
|
|
|
|
|
|
|
|
#endif // ! defined QCONFIGDB_H
|