summaryrefslogtreecommitdiff
path: root/noncore/apps/tableviewer/db/xmlsource.cpp
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (unidiff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /noncore/apps/tableviewer/db/xmlsource.cpp
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'noncore/apps/tableviewer/db/xmlsource.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/tableviewer/db/xmlsource.cpp295
1 files changed, 295 insertions, 0 deletions
diff --git a/noncore/apps/tableviewer/db/xmlsource.cpp b/noncore/apps/tableviewer/db/xmlsource.cpp
new file mode 100644
index 0000000..7418a85
--- a/dev/null
+++ b/noncore/apps/tableviewer/db/xmlsource.cpp
@@ -0,0 +1,295 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20#include "xmlsource.h"
21#include <qdict.h>
22#include <stdlib.h>
23#include <qtextstream.h>
24
25
26DBXml::DBXml(DBStore *d)
27{
28 dstore = d;
29}
30
31QString DBXml::type()
32{
33 return "xml";
34}
35
36bool DBXml::openSource(QIODevice *inDev)
37{
38 bool ok;
39
40 DBXmlHandler h(dstore);
41
42 QTextStream tsIn(inDev);
43 QXmlInputSource source(tsIn);
44 QXmlSimpleReader reader;
45 reader.setContentHandler(&h);
46 reader.setErrorHandler(&h);
47 ok = reader.parse(source);
48
49 return ok;
50}
51
52bool DBXml::saveSource(QIODevice *outDev)
53{
54 int i;
55 DataElem *elem;
56 KeyList *k;
57
58 QTextStream outstream(outDev);
59
60 outstream << "<database name=\"" << dstore->getName() << "\">" << endl;
61 outstream << "<header>" << endl;
62
63 k = dstore->getKeys();
64 KeyListIterator it(*k);
65 while(it.current()) {
66 if (!it.current()->delFlag()) {
67 outstream << "<key name=\"KEYID" << it.currentKey() << "\" ";
68 outstream << "type=\""
69 << TVVariant::typeToName(it.current()->type())
70 << "\">";
71 outstream << it.current()->name() << "</key>" << endl;
72 }
73 ++it;
74 }
75
76 outstream << "</header>" << endl;
77
78 dstore->first();
79
80 do {
81 elem = dstore->getCurrentData();
82 if (!elem)
83 break;
84 outstream << "<record>" << endl;
85 it.toFirst();
86 while (it.current()) {
87 i = it.currentKey();
88 if (elem->hasValidValue(i)) {
89 outstream << "<KEYID" << i << ">";
90 if (dstore->getKeyType(i) == TVVariant::Date) {
91 // dates in files are different from displayed dates
92 QDate date = elem->getField(i).toDate();
93 outstream << date.day() << "/"
94 << date.month() << "/"
95 << date.year();
96 } else {
97 outstream << elem->toQString(i);
98 }
99 outstream << "</KEYID" << i << ">" << endl;
100 }
101 ++it;
102 }
103 outstream << "</record>" << endl;
104 } while(dstore->next());
105
106 outstream << "</database>" << endl;
107 return TRUE;
108}
109
110DBXml::~DBXml() {}
111
112/*!
113 \class DBXmlHandler
114 \brief An Xml parser for flat tables.
115
116 An xml parser for parsing the files used by the table viewer application.
117
118 The format of the xml files can be found at the front of the file
119 dataparser.h
120*/
121
122/*!
123 Constructs a new DBXmlHandler, and sets that the table should be
124 constructed in the DBStore pointed to by ds.
125*/
126DBXmlHandler::DBXmlHandler(DBStore *ds)
127{
128 data_store = ds;
129 current_keyrep = 0;
130}
131
132/*!
133 Destroys the DBXmlHandler
134*/
135DBXmlHandler::~DBXmlHandler()
136{
137}
138
139QString DBXmlHandler::errorProtocol()
140{
141 qWarning("Error reading file");
142 return errorProt;
143}
144
145bool DBXmlHandler::startDocument()
146{
147 errorProt = "";
148 state = StateInit;
149 return TRUE;
150}
151
152bool DBXmlHandler::startElement(const QString&, const QString&,
153 const QString& qName, const QXmlAttributes& atts)
154{
155 if (state == StateInit && qName == "database") {
156 // First thing it expects is a <document name="..."> tag
157 state = StateDocument;
158 data_store->setName(atts.value("name"));
159 return TRUE;
160 }
161 if (state == StateDocument && qName == "header") {
162 state = StateHeader;
163 if (current_keyrep) delete current_keyrep;
164 current_keyrep = new KeyList();
165 return TRUE;
166 }
167 if (state == StateHeader && qName == "key") {
168 /* Ok, adding a new key to our KeyList TODO */
169 state = StateKey;
170 last_key_type = TVVariant::String;
171 key = atts.value("name");
172 if (key.isEmpty()) {
173 qWarning("empty key name");
174 return FALSE;
175 }
176 if(!atts.value("type").isEmpty())
177 last_key_type = TVVariant::nameToType(atts.value("type"));
178 return TRUE;
179 }
180 if (state == StateDocument && qName == "record") {
181 state = StateRecord;
182 current_data = new DataElem(data_store);
183 // Now expecting a <record> tag
184 return TRUE;
185 }
186 if (state == StateRecord) {
187 state = StateField;
188 /* the qName is the name of a key */
189 if (!keyIndexList[qName]) {
190 /* invalid key, we failed */
191 qWarning("Invalid key in record");
192 return FALSE;
193 }
194 keyIndex = *keyIndexList[qName];
195 return TRUE;
196 }
197 qWarning("Unable to determine tag type");
198 return FALSE;
199}
200
201bool DBXmlHandler::endElement(const QString&, const QString&,
202 const QString& qName)
203{
204 switch(state) {
205 case StateField:
206 // TODO checks 'could' be done of the popped value
207 state = StateRecord;
208 break;
209 case StateKey:
210 // TODO checks 'could' be done of the popped value
211 state = StateHeader;
212 break;
213 case StateHeader:
214 data_store->setKeys(current_keyrep);
215 state = StateDocument;
216 break;
217 case StateRecord:
218 data_store->addItem(current_data);
219 state = StateDocument;
220 break;
221 case StateDocument:
222 // we are done...
223 break;
224 default:
225 // should only get a 'endElement' from one of the above states.
226 qWarning("Invalid end tag");
227 return FALSE;
228 break;
229 }
230 return TRUE;
231}
232
233bool DBXmlHandler::characters(const QString& ch)
234{
235 // this is where the 'between tag' stuff happens.
236 // e.g. the stuff between tags.
237 QString ch_simplified = ch.simplifyWhiteSpace();
238
239 if (ch_simplified.isEmpty())
240 return TRUE;
241
242 if (state == StateKey) {
243 int *tmp_val = new int;
244 /* We just grabbed the display name of a key */
245 *tmp_val = current_keyrep->addKey(ch_simplified, last_key_type);
246 keyIndexList.insert(key, tmp_val);
247 return TRUE;
248 }
249 if (state == StateField) {
250 /* Ok, need to add data here */
251 current_data->setField(keyIndex, ch_simplified);
252 return TRUE;
253 }
254
255 qWarning("Junk characters found... ignored");
256 return TRUE;
257}
258
259QString DBXmlHandler::errorString()
260{
261 return "the document is not in the expected file format";
262}
263
264bool DBXmlHandler::warning(const QXmlParseException& exception)
265{
266 errorProt += QString("warning parsing error: %1 in line %2, column %3\n" )
267 .arg(exception.message())
268 .arg(exception.lineNumber())
269 .arg(exception.columnNumber());
270
271 qWarning(errorProt);
272 return QXmlDefaultHandler::fatalError(exception);
273}
274
275bool DBXmlHandler::error(const QXmlParseException& exception)
276{
277 errorProt += QString("error parsing error: %1 in line %2, column %3\n" )
278 .arg(exception.message())
279 .arg(exception.lineNumber())
280 .arg(exception.columnNumber());
281
282 qWarning(errorProt);
283 return QXmlDefaultHandler::fatalError(exception);
284}
285
286bool DBXmlHandler::fatalError(const QXmlParseException& exception)
287{
288 errorProt += QString("fatal parsing error: %1 in line %2, column %3\n" )
289 .arg(exception.message())
290 .arg(exception.lineNumber())
291 .arg(exception.columnNumber());
292
293 qWarning(errorProt);
294 return QXmlDefaultHandler::fatalError(exception);
295}