summaryrefslogtreecommitdiff
path: root/noncore/apps/oxygen/kmolcalc.cpp
Unidiff
Diffstat (limited to 'noncore/apps/oxygen/kmolcalc.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/oxygen/kmolcalc.cpp25
1 files changed, 13 insertions, 12 deletions
diff --git a/noncore/apps/oxygen/kmolcalc.cpp b/noncore/apps/oxygen/kmolcalc.cpp
index 0ba52da..33666b1 100644
--- a/noncore/apps/oxygen/kmolcalc.cpp
+++ b/noncore/apps/oxygen/kmolcalc.cpp
@@ -1,127 +1,128 @@
1/* 1/*
2 * kmolcalc.cpp 2 * kmolcalc.cpp
3 * 3 *
4 * Copyright (C) 2000,2001 Tomislav Gountchev <tomi@idiom.com> 4 * Copyright (C) 2000,2001 Tomislav Gountchev <tomi@idiom.com>
5 * Copyright (C) 2002 Carsten Niehaus <cniehaus@handhelds.org> 5 * Copyright (C) 2002 Carsten Niehaus <cniehaus@handhelds.org>
6 */ 6 */
7 7
8/** 8/**
9 * KMOLCALC is the calculation engine. It knows about a hashtable of user defined atomic 9 * KMOLCALC is the calculation engine. It knows about a hashtable of user defined atomic
10 * weights and group definitions ELSTABLE, and the currently processed formula, stored 10 * weights and group definitions ELSTABLE, and the currently processed formula, stored
11 * as a list of elements and their coefficients, ELEMENTS. 11 * as a list of elements and their coefficients, ELEMENTS.
12 */ 12 */
13 13
14#include "kmolcalc.h" 14#include "kmolcalc.h"
15#include <qdict.h> 15#include <qdict.h>
16#include <qdir.h> 16#include <qdir.h>
17#include <qfile.h> 17#include <qfile.h>
18#include <qpe/qpeapplication.h>
18#include <iostream.h> 19#include <iostream.h>
19 20
20 21
21/** 22/**
22 * Construct a new calculator object. 23 * Construct a new calculator object.
23 */ 24 */
24KMolCalc::KMolCalc() { 25KMolCalc::KMolCalc() {
25 elements = new ElementList; 26 elements = new ElementList;
26 elstable = NULL; 27 elstable = NULL;
27 readElstable(); 28 readElstable();
28} 29}
29 30
30KMolCalc::~KMolCalc() { 31KMolCalc::~KMolCalc() {
31 delete elements; 32 delete elements;
32} 33}
33 34
34void KMolCalc::readElstable() { 35void KMolCalc::readElstable() {
35 weight = -1; // not calculated yet 36 weight = -1; // not calculated yet
36 if (elstable) delete elstable; 37 if (elstable) delete elstable;
37 elstable = new QDict<SubUnit> (197, TRUE); 38 elstable = new QDict<SubUnit> (197, TRUE);
38 elstable->setAutoDelete(TRUE); 39 elstable->setAutoDelete(TRUE);
39 mwfile = "/home/opie/opie/noncore/apps/oxygen/kmolweights"; 40 mwfile = QPEApplication::qpeDir() +"share/oxygen/kmolweights";
40 QFile f(mwfile); 41 QFile f(mwfile);
41 if (f.exists()) readMwfile(f); 42 if (f.exists()) readMwfile(f);
42} 43}
43 44
44 45
45/** 46/**
46 * Parse a string S and construct the ElementList this->ELEMENTS, representing the 47 * Parse a string S and construct the ElementList this->ELEMENTS, representing the
47 * composition of S. Returns 0 if successful, or an error code (currently -1) if 48 * composition of S. Returns 0 if successful, or an error code (currently -1) if
48 * parsing failed. 49 * parsing failed.
49 * The elements is S must be valid element or group symbols, as stored in this->ELSTABLE. 50 * The elements is S must be valid element or group symbols, as stored in this->ELSTABLE.
50 * See help files for correct formula syntax. 51 * See help files for correct formula syntax.
51 */ 52 */
52QString KMolCalc::readFormula(const QString& s) { 53QString KMolCalc::readFormula(const QString& s) {
53 weight = -1; 54 weight = -1;
54 if (elements) delete elements; 55 if (elements) delete elements;
55 elements = new ElementList; 56 elements = new ElementList;
56 return KMolCalc::readGroup(s, elements); 57 return KMolCalc::readGroup(s, elements);
57} 58}
58 59
59// read a formula group recursively. Called by readFormula. 60// read a formula group recursively. Called by readFormula.
60QString KMolCalc::readGroup(const QString& s, ElementList* els) { 61QString KMolCalc::readGroup(const QString& s, ElementList* els) {
61 if (s.isEmpty()) return QString ("Enter a formula."); //ERROR 62 if (s.isEmpty()) return QString ("Enter a formula."); //ERROR
62 int sl = s.length(); 63 int sl = s.length();
63 int i = 0; 64 int i = 0;
64 QString errors ("OK"); 65 QString errors ("OK");
65 bool ok = TRUE; 66 bool ok = TRUE;
66 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++; 67 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
67 double prefix = (i == 0 ? 1 : s.left(i).toDouble(&ok)); 68 double prefix = (i == 0 ? 1 : s.left(i).toDouble(&ok));
68 if (! ok || i == sl || prefix == 0) return QString ("Bad formula."); // ERROR 69 if (! ok || i == sl || prefix == 0) return QString ("Bad formula."); // ERROR
69 ElementList* elstemp = new ElementList; 70 ElementList* elstemp = new ElementList;
70 while (i < sl) { 71 while (i < sl) {
71 int j = i; 72 int j = i;
72 if (s[i] == '(') { 73 if (s[i] == '(') {
73 ElementList* inner = new ElementList; 74 ElementList* inner = new ElementList;
74 int level = 1; // count levels of nested ( ). 75 int level = 1; // count levels of nested ( ).
75 while (1) { 76 while (1) {
76 if (i++ == sl) { 77 if (i++ == sl) {
77 delete inner; 78 delete inner;
78 delete elstemp; 79 delete elstemp;
79 return QString ("Bad formula."); //ERROR 80 return QString ("Bad formula."); //ERROR
80 } 81 }
81 if (s[i] == '(') level++; 82 if (s[i] == '(') level++;
82 if (s[i] == ')') level--; 83 if (s[i] == ')') level--;
83 if (level == 0) break; 84 if (level == 0) break;
84 } 85 }
85 errors = KMolCalc::readGroup(s.mid(j+1, i-j-1), inner); 86 errors = KMolCalc::readGroup(s.mid(j+1, i-j-1), inner);
86 j = ++i; 87 j = ++i;
87 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++; 88 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
88 double suffix = (i == j ? 1 : s.mid(j, i-j).toDouble(&ok)); 89 double suffix = (i == j ? 1 : s.mid(j, i-j).toDouble(&ok));
89 if (! ok || suffix == 0) { 90 if (! ok || suffix == 0) {
90 delete inner; 91 delete inner;
91 delete elstemp; 92 delete elstemp;
92 return QString ("Bad formula."); // ERROR 93 return QString ("Bad formula."); // ERROR
93 } 94 }
94 inner->addTo(*elstemp, suffix); 95 inner->addTo(*elstemp, suffix);
95 delete inner; 96 delete inner;
96 inner = NULL; 97 inner = NULL;
97 } else if ((s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z')) { 98 } else if ((s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z')) {
98 while (++i < sl && ((s[i] >= 'a' && s[i] <= 'z') || s[i] == '*' || 99 while (++i < sl && ((s[i] >= 'a' && s[i] <= 'z') || s[i] == '*' ||
99 s[i] == '\'')); 100 s[i] == '\''));
100 QString elname = s.mid(j, i-j); 101 QString elname = s.mid(j, i-j);
101 j = i; 102 j = i;
102 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++; 103 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
103 double suffix = (i == j ? 1 : s.mid(j, i-j).toDouble(&ok)); 104 double suffix = (i == j ? 1 : s.mid(j, i-j).toDouble(&ok));
104 if (! ok || suffix == 0) { 105 if (! ok || suffix == 0) {
105 delete elstemp; 106 delete elstemp;
106 return QString ("Bad formula."); // ERROR 107 return QString ("Bad formula."); // ERROR
107 } 108 }
108 SubUnit* group = elstable->find(elname); 109 SubUnit* group = elstable->find(elname);
109 if (group == 0) { 110 if (group == 0) {
110 delete elstemp; 111 delete elstemp;
111 return QString ("Undefined symbol: ") + elname; //ERROR 112 return QString ("Undefined symbol: ") + elname; //ERROR
112 } 113 }
113 group->addTo(*elstemp, suffix); 114 group->addTo(*elstemp, suffix);
114 } else if (s[i] == '+') { 115 } else if (s[i] == '+') {
115 if (elstemp->isEmpty()) { 116 if (elstemp->isEmpty()) {
116 delete elstemp; 117 delete elstemp;
117 return QString ("Bad formula."); //ERROR 118 return QString ("Bad formula."); //ERROR
118 } 119 }
119 elstemp->addTo(*els, prefix); 120 elstemp->addTo(*els, prefix);
120 delete elstemp; 121 delete elstemp;
121 errors = KMolCalc::readGroup(s.mid(i+1, sl-i-1), els); 122 errors = KMolCalc::readGroup(s.mid(i+1, sl-i-1), els);
122 return errors; 123 return errors;
123 } else { 124 } else {
124 delete elstemp; 125 delete elstemp;
125 return QString ("Bad formula."); //ERROR 126 return QString ("Bad formula."); //ERROR
126 } 127 }
127 } 128 }
@@ -155,45 +156,45 @@ QString KMolCalc::getEmpFormula() {
155 return elements->getEmpFormula(); 156 return elements->getEmpFormula();
156} 157}
157 158
158// Read the element definition file. 159// Read the element definition file.
159void KMolCalc::readMwfile(QFile& f) { 160void KMolCalc::readMwfile(QFile& f) {
160 if (! f.open(IO_ReadOnly)) return; //ERROR 161 if (! f.open(IO_ReadOnly)) return; //ERROR
161 QTextStream fs (&f); 162 QTextStream fs (&f);
162 QString line; 163 QString line;
163 while (! fs.eof()) { 164 while (! fs.eof()) {
164 line = fs.readLine(); 165 line = fs.readLine();
165 SubUnit* s = SubUnit::makeSubUnit(line); 166 SubUnit* s = SubUnit::makeSubUnit(line);
166 elstable->replace(s->getName(), s); 167 elstable->replace(s->getName(), s);
167 } 168 }
168 f.close(); 169 f.close();
169} 170}
170 171
171/** 172/**
172 * Remove a group or element definition from ELSTABLE. 173 * Remove a group or element definition from ELSTABLE.
173 */ 174 */
174void KMolCalc::undefineGroup (const QString& name) { 175void KMolCalc::undefineGroup (const QString& name) {
175 elstable->remove (name); 176 elstable->remove (name);
176} 177}
177 178
178/** 179/**
179 * Add a new element name - atomic weight record to the ELSTABLE hashtable. Assumes 180 * Add a new element name - atomic weight record to the ELSTABLE hashtable. Assumes
180 * NAME has valid syntax. 181 * NAME has valid syntax.
181 182
182 */ 183 */
183void KMolCalc::defineElement (const QString& name, double weight) { 184void KMolCalc::defineElement (const QString& name, double weight) {
184 Element* el = new Element(name, weight); 185 Element* el = new Element(name, weight);
185 elstable->replace(name, el); 186 elstable->replace(name, el);
186} 187}
187 188
188/** 189/**
189 * Add a new group definition to the ELSTABLE. Returns 0 if OK, -1 if parsing FORMULA 190 * Add a new group definition to the ELSTABLE. Returns 0 if OK, -1 if parsing FORMULA
190 * fails. Assumes the syntax of grpname is correct. 191 * fails. Assumes the syntax of grpname is correct.
191 */ 192 */
192QString KMolCalc::defineGroup (const QString& grpname, const QString& formula) { 193QString KMolCalc::defineGroup (const QString& grpname, const QString& formula) {
193 ElementList* els = new ElementList(grpname); 194 ElementList* els = new ElementList(grpname);
194 QString error = readGroup(formula, els); 195 QString error = readGroup(formula, els);
195 if (error != "OK") return error; 196 if (error != "OK") return error;
196 if (els->contains(grpname)) return QString("Can't define a group recursively!\n"); 197 if (els->contains(grpname)) return QString("Can't define a group recursively!\n");
197 elstable->replace(grpname, els); 198 elstable->replace(grpname, els);
198 return QString("OK"); 199 return QString("OK");
199} 200}