1 /*
2  * varianttree.h - Tree structure for QVariants and Comments
3  * Copyright (C) 2006  Kevin Smith
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  */
20 
21 #ifndef _VARIANTTREE_H_
22 #define _VARIANTTREE_H_
23 
24 #include <QObject>
25 #include <QVariant>
26 #include <QHash>
27 
28 class QDomDocument;
29 class QDomElement;
30 class QDomDocumentFragment;
31 
32 
33 /**
34  * \class VariantTree
35  * \brief A recursive structure for storing QVariants in trees, with comments
36  *
37  * All the methods in this class are recursive, based on a hierachy delimited
38  * with dots in the node name. As such, the nodes "Paris" and "Benvolio" are
39  * top level elements (members of this layer), while "Capulet.Juliet" is a
40  * member of a deeper node ("Capulet") and "Verona.Montague.Romeo" represents
41  * the node "Romeo" which is a member of "Montague", which is again a member
42  * of "Verona" (which is a member of this layer).
43  *
44  * As such, for each function, if the supplied node contains a dot ("."),
45  * the node name is split at the first (if there are several) dot, with the
46  * remainder passed to the same method of the member of this node with the
47  * name given by the primary component. For the set methods, multiple layers
48  * in the hierachy may be created implicitly if the node is not found.
49  */
50 class VariantTree : public QObject
51 {
52 	Q_OBJECT
53 public:
54 	VariantTree(QObject *parent = 0);
55 	~VariantTree();
56 
57 	void setValue(QString node, QVariant value);
58 	QVariant getValue(const QString& node) const;
59 
60 	bool isInternalNode(QString node) const;
61 
62 	void setComment(QString node, QString comment);
63 	QString getComment(QString node) const;
64 
65 	bool remove(const QString &node, bool internal_nodes = false);
66 
67 	QStringList nodeChildren(const QString& node = "", bool direct = false, bool internal_nodes = false) const;
68 
69 	void toXml(QDomDocument &doc, QDomElement& ele) const;
70 	void fromXml(const QDomElement &ele);
71 
72 	static bool isValidNodeName(const QString &name);
73 
74 	static const QVariant missingValue;
75 	static const QString missingComment;
76 
77 protected:
78 	static QVariant elementToVariant(const QDomElement&);
79 	static void variantToElement(const QVariant&, QDomElement&);
80 
81 	static bool getKeyRest(const QString& node, QString &key, QString &rest);
82 
83 private:
84 	QHash<QString, VariantTree*> trees_;
85 	QHash<QString, QVariant> values_;
86 	QHash<QString, QString> comments_;
87 	QHash<QString, QDomDocumentFragment> unknowns_;		// unknown types preservation
88 	QHash<QString, QString> unknowns2_;		// unknown types preservation
89 
90 	// needed to have a document for the fragments.
91 	static QDomDocument *unknownsDoc;
92 	friend class OptionsTreeReader;
93 	friend class OptionsTreeWriter;
94 };
95 
96 #endif /* _VARIANTTREE_H_ */
97