00001
00002
00003
00004
00005
00006
00007
00014 #include "kmolcalc.h"
00015 #include <qpe/qpeapplication.h>
00016
00017
00021 KMolCalc::KMolCalc() {
00022 elements = new ElementList;
00023 elstable = NULL;
00024 readElstable();
00025 }
00026
00027 KMolCalc::~KMolCalc() {
00028 delete elements;
00029 }
00030
00031 void KMolCalc::readElstable() {
00032 weight = -1;
00033 if (elstable) delete elstable;
00034 elstable = new QDict<SubUnit> (197, TRUE);
00035 elstable->setAutoDelete(TRUE);
00036 mwfile = QPEApplication::qpeDir() +"share/oxygen/kmolweights";
00037 QFile f(mwfile);
00038 if (f.exists()) readMwfile(f);
00039 }
00040
00041
00049 QString KMolCalc::readFormula(const QString& s) {
00050 weight = -1;
00051 if (elements) delete elements;
00052 elements = new ElementList;
00053 return KMolCalc::readGroup(s, elements);
00054 }
00055
00056
00057 QString KMolCalc::readGroup(const QString& s, ElementList* els) {
00058 if (s.isEmpty()) return QString ("Enter a formula.");
00059 int sl = s.length();
00060 int i = 0;
00061 QString errors ("OK");
00062 bool ok = TRUE;
00063 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
00064 double prefix = (i == 0 ? 1 : s.left(i).toDouble(&ok));
00065 if (! ok || i == sl || prefix == 0) return QString ("Bad formula.");
00066 ElementList* elstemp = new ElementList;
00067 while (i < sl) {
00068 int j = i;
00069 if (s[i] == '(') {
00070 ElementList* inner = new ElementList;
00071 int level = 1;
00072 while (1) {
00073 if (i++ == sl) {
00074 delete inner;
00075 delete elstemp;
00076 return QString ("Bad formula.");
00077 }
00078 if (s[i] == '(') level++;
00079 if (s[i] == ')') level--;
00080 if (level == 0) break;
00081 }
00082 errors = KMolCalc::readGroup(s.mid(j+1, i-j-1), inner);
00083 j = ++i;
00084 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
00085 double suffix = (i == j ? 1 : s.mid(j, i-j).toDouble(&ok));
00086 if (! ok || suffix == 0) {
00087 delete inner;
00088 delete elstemp;
00089 return QString ("Bad formula.");
00090 }
00091 inner->addTo(*elstemp, suffix);
00092 delete inner;
00093 inner = NULL;
00094 } else if ((s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z')) {
00095 while (++i < sl && ((s[i] >= 'a' && s[i] <= 'z') || s[i] == '*' ||
00096 s[i] == '\''));
00097 QString elname = s.mid(j, i-j);
00098 j = i;
00099 while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
00100 double suffix = (i == j ? 1 : s.mid(j, i-j).toDouble(&ok));
00101 if (! ok || suffix == 0) {
00102 delete elstemp;
00103 return QString ("Bad formula.");
00104 }
00105 SubUnit* group = elstable->find(elname);
00106 if (group == 0) {
00107 delete elstemp;
00108 return QString ("Undefined symbol: ") + elname;
00109 }
00110 group->addTo(*elstemp, suffix);
00111 } else if (s[i] == '+') {
00112 if (elstemp->isEmpty()) {
00113 delete elstemp;
00114 return QString ("Bad formula.");
00115 }
00116 elstemp->addTo(*els, prefix);
00117 delete elstemp;
00118 errors = KMolCalc::readGroup(s.mid(i+1, sl-i-1), els);
00119 return errors;
00120 } else {
00121 delete elstemp;
00122 return QString ("Bad formula.");
00123 }
00124 }
00125 elstemp->addTo(*els, prefix);
00126 delete elstemp;
00127 return errors;
00128 }
00129
00133 double KMolCalc::getWeight() {
00134 if (weight == -1) weight = elements->getWeight(elstable);
00135 return weight;
00136 }
00137
00142 QString KMolCalc::getEA() {
00143 if (weight == -1) weight = elements->getWeight(elstable);
00144 if (weight == -1) return QString("ERROR: Couldn't get Mw...");
00145 return elements->getEA(elstable, weight);
00146 }
00147
00151 QString KMolCalc::getEmpFormula() {
00152 return elements->getEmpFormula();
00153 }
00154
00155
00156 void KMolCalc::readMwfile(QFile& f) {
00157 if (! f.open(IO_ReadOnly)) return;
00158 QTextStream fs (&f);
00159 QString line;
00160 while (! fs.eof()) {
00161 line = fs.readLine();
00162 SubUnit* s = SubUnit::makeSubUnit(line);
00163 elstable->replace(s->getName(), s);
00164 }
00165 f.close();
00166 }
00167
00171 void KMolCalc::undefineGroup (const QString& name) {
00172 elstable->remove (name);
00173 }
00174
00180 void KMolCalc::defineElement (const QString& name, double weight) {
00181 Element* el = new Element(name, weight);
00182 elstable->replace(name, el);
00183 }
00184
00189 QString KMolCalc::defineGroup (const QString& grpname, const QString& formula) {
00190 ElementList* els = new ElementList(grpname);
00191 QString error = readGroup(formula, els);
00192 if (error != "OK") return error;
00193 if (els->contains(grpname)) return QString("Can't define a group recursively!\n");
00194 elstable->replace(grpname, els);
00195 return QString("OK");
00196 }