1
/***************************************************************************
2
copyright : (C) 2005, 2006 by Carsten Niehaus
3
email : cniehaus@kde.org
4
***************************************************************************/
5
/***************************************************************************
7
* This program is free software; you can redistribute it and/or modify *
8
* it under the terms of the GNU General Public License as published by *
9
* the Free Software Foundation; either version 2 of the License, or *
10
* (at your option) any later version. *
12
***************************************************************************/
13
#include "elementparser.h"
15
#include "chemicaldataobject.h"
16
#include <kunitconversion/converter.h>
22
class ElementSaxParser::Private
26
: currentUnit(KUnitConversion::NoUnit),
32
inAtomicNumber(false),
35
inElectronAffinity(false),
36
inElectronegativityPauling(false),
37
inRadiusCovalent(false),
39
inBoilingPoint(false),
40
inMeltingPoint(false),
41
inPeriodTableBlock(false),
43
inDiscoveryDate(false),
46
inCrystalstructure( false ),
47
inAcidicbehaviour( false ),
50
inElectronicconfiguration( false ),
51
inDangerSymbol( false ),
60
delete currentElement;
61
//qDeleteAll(elements);
64
ChemicalDataObject currentDataObject;
65
int currentUnit; // KUnitConversion::UnitId
66
Element *currentElement;
68
QList<Element*> elements;
77
bool inElectronAffinity;
78
bool inElectronegativityPauling;
79
bool inRadiusCovalent;
83
bool inPeriodTableBlock;
88
bool inCrystalstructure;
89
bool inAcidicbehaviour;
92
bool inElectronicconfiguration;
100
ElementSaxParser::ElementSaxParser()
101
: QXmlDefaultHandler(), d( new Private )
105
ElementSaxParser::~ElementSaxParser()
110
bool ElementSaxParser::startElement(const QString&, const QString &localName, const QString&, const QXmlAttributes &attrs)
112
if (localName == "atom")
114
d->currentElement = new Element();
116
} else if ( ( d->inElement && localName == "scalar" ) || localName == "array" )
118
for (int i = 0; i < attrs.length(); ++i)
120
if ( attrs.localName( i ) == "units" )
122
// kDebug() << "value of the unit: " << attrs.value(i);
123
d->currentUnit = unit( attrs.value( i ) );
124
// kDebug() << "Took " << d->currentUnit;
128
if (attrs.value(i) == "bo:atomicNumber")
129
d->inAtomicNumber = true;
130
else if (attrs.value(i) == "bo:mass")
132
else if (attrs.value(i) == "bo:exactMass")
133
d->inExactMass = true;
134
else if (attrs.value(i) == "bo:ionization")
135
d->inIonization = true;
136
else if (attrs.value(i) == "bo:electronAffinity")
137
d->inElectronAffinity = true;
138
else if (attrs.value(i) == "bo:electronegativityPauling")
139
d->inElectronegativityPauling = true;
140
else if (attrs.value(i) == "bo:radiusCovalent")
141
d->inRadiusCovalent = true;
142
else if (attrs.value(i) == "bo:radiusVDW")
143
d->inRadiusVDW = true;
144
else if (attrs.value(i) == "bo:meltingpoint")
145
d->inMeltingPoint = true;
146
else if (attrs.value(i) == "bo:boilingpoint")
147
d->inBoilingPoint = true;
148
else if (attrs.value(i) == "bo:periodTableBlock")
149
d->inPeriodTableBlock = true;
150
else if (attrs.value(i) == "bo:nameOrigin")
151
d->inNameOrigin = true;
152
else if (attrs.value(i) == "bo:discoveryDate")
153
d->inDiscoveryDate = true;
154
else if (attrs.value(i) == "bo:discoverers")
155
d->inDiscoverers = true;
156
else if (attrs.value(i) == "bo:discoveryCountry")
158
else if (attrs.value(i) == "bo:period")
160
else if (attrs.value(i) == "bo:crystalstructure")
161
d->inCrystalstructure = true;
162
else if (attrs.value(i) == "bo:acidicbehaviour")
163
d->inAcidicbehaviour = true;
164
else if (attrs.value(i) == "bo:family")
166
else if (attrs.value(i) == "bo:group")
168
else if (attrs.value(i) == "bo:electronicConfiguration")
169
d->inElectronicconfiguration = true;
170
else if (attrs.value(i) == "bo:dangerSymbol")
171
d->inDangerSymbol = true;
172
else if (attrs.value(i) == "bo:RPhrase")
174
else if (attrs.value(i) == "bo:SPhrase")
176
else if (attrs.value(i) == "bo:oxidation")
177
d->inOxidation = true;
179
} else if (d->inElement && localName == "label")
181
for (int i = 0; i < attrs.length(); ++i)
183
if ( attrs.localName( i ) != "dictRef" )
186
if (attrs.value(i) == "bo:symbol") {
187
for (int i = 0; i < attrs.length(); ++i)
189
if (attrs.localName(i) == "value") {
190
d->currentDataObject.setData( attrs.value(i) );
191
d->currentDataObject.setType( ChemicalDataObject::symbol );
193
if ( d->currentElement )
194
d->currentElement->addData( d->currentDataObject );
198
else if ( attrs.value(i) == "bo:name" ) {
199
for (int i = 0; i < attrs.length(); ++i)
201
if (attrs.localName(i) == "value") {
202
d->currentDataObject.setData( i18n( attrs.value(i).toUtf8() ) );
203
d->currentDataObject.setType( ChemicalDataObject::name );
205
if ( d->currentElement )
206
d->currentElement->addData( d->currentDataObject );
215
bool ElementSaxParser::endElement( const QString &, const QString& localName, const QString& )
217
if ( localName == "atom" )
219
if ( d->currentElement->dataAsString( ChemicalDataObject::symbol ) != "Xx" )
220
d->elements.append(d->currentElement);
222
delete d->currentElement;
224
d->currentElement = 0;
225
d->inElement = false;
227
else if ( localName == "scalar" || localName == "label" || localName == "array" )
229
d->currentDataObject.setUnit( d->currentUnit );
234
bool ElementSaxParser::characters(const QString &ch)
236
d->currentDataObject = ChemicalDataObject();
237
ChemicalDataObject::BlueObelisk type;
241
value = ch.toDouble();
242
type = ChemicalDataObject::mass;
245
else if (d->inExactMass) {
246
value = ch.toDouble();
247
type = ChemicalDataObject::exactMass;
248
d->inExactMass = false;
250
else if (d->inAtomicNumber) {
252
type = ChemicalDataObject::atomicNumber;
253
d->inAtomicNumber = false;
255
else if (d->inIonization) {
256
value = ch.toDouble();;
257
type = ChemicalDataObject::ionization;
258
d->inIonization = false;
260
else if (d->inElectronAffinity) {
261
value = ch.toDouble();
262
type = ChemicalDataObject::electronAffinity;
263
d->inElectronAffinity = false;
265
else if (d->inElectronegativityPauling) {
266
value = ch.toDouble();
267
type = ChemicalDataObject::electronegativityPauling;
268
d->inElectronegativityPauling = false;
270
else if (d->inRadiusCovalent) {
271
value = ch.toDouble();
272
type = ChemicalDataObject::radiusCovalent;
273
d->inRadiusCovalent = false;
275
else if (d->inRadiusVDW) {
276
value = ch.toDouble();
277
type = ChemicalDataObject::radiusVDW;
278
d->inRadiusVDW = false;
280
else if (d->inMeltingPoint) {
281
value = ch.toDouble();
282
type = ChemicalDataObject::meltingpoint;
283
d->inMeltingPoint = false;
285
else if (d->inBoilingPoint) {
286
value = ch.toDouble();
287
type = ChemicalDataObject::boilingpoint;
288
d->inBoilingPoint = false;
290
else if (d->inPeriodTableBlock) {
292
type = ChemicalDataObject::periodTableBlock;
293
d->inPeriodTableBlock = false;
295
else if (d->inNameOrigin) {
296
value = i18n( ch.toUtf8() );
297
type = ChemicalDataObject::nameOrigin;
298
d->inNameOrigin = false;
300
else if (d->inDiscoveryDate) {
302
type = ChemicalDataObject::date;
303
d->inDiscoveryDate = false;
305
else if (d->inDiscoverers) {
307
type = ChemicalDataObject::discoverers;
308
d->inDiscoverers = false;
310
else if (d->inPeriod) {
312
type = ChemicalDataObject::period;
315
else if (d->inCrystalstructure) {
317
type = ChemicalDataObject::crystalstructure;
318
d->inCrystalstructure = false;
320
else if (d->inAcidicbehaviour) {
322
type = ChemicalDataObject::acidicbehaviour;
323
d->inAcidicbehaviour = false;
325
else if (d->inFamily) {
327
type = ChemicalDataObject::family;
330
else if (d->inGroup) {
332
type = ChemicalDataObject::group;
335
else if (d->inElectronicconfiguration) {
337
type = ChemicalDataObject::electronicConfiguration;
338
d->inElectronicconfiguration = false;
340
else if (d->inDangerSymbol) {
342
type = ChemicalDataObject::dangerSymbol;
343
d->inDangerSymbol = false;
345
else if (d->inRPhrase) {
347
type = ChemicalDataObject::RPhrase;
348
d->inRPhrase = false;
350
else if (d->inSPhrase) {
352
type = ChemicalDataObject::SPhrase;
353
d->inSPhrase = false;
355
else if (d->inCountry) {
356
if ( ch == "ancient" ) {
358
type = ChemicalDataObject::date;
361
type = ChemicalDataObject::discoveryCountry;
363
d->inCountry = false;
365
else if (d->inOxidation) {
367
type = ChemicalDataObject::oxidation;
368
d->inOxidation = false;
370
else//it is a non known value. Do not create a wrong object but return
373
d->currentDataObject.setData( value );
374
d->currentDataObject.setType( type );
375
d->currentDataObject.setUnit( d->currentUnit );
377
if ( d->currentElement )
378
d->currentElement->addData( d->currentDataObject );
383
int ElementSaxParser::unit( const QString& unit ) const
385
if ( unit == "siUnits:kelvin" )
386
return KUnitConversion::Kelvin;
387
else if ( unit == "units:ev" )
388
return KUnitConversion::Electronvolt;
389
else if ( unit == "units:ang" )
390
return KUnitConversion::Angstrom;
391
else if ( unit == "bo:noUnit" )
392
return KUnitConversion::NoUnit;
394
return KUnitConversion::NoUnit;
397
QList<Element*> ElementSaxParser::getElements()