summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/oxygen/.cvsignore3
-rw-r--r--noncore/apps/oxygen/TODO1
-rw-r--r--noncore/apps/oxygen/calcdlg.ui243
-rw-r--r--noncore/apps/oxygen/calcdlgui.cpp55
-rw-r--r--noncore/apps/oxygen/calcdlgui.h27
-rw-r--r--noncore/apps/oxygen/kmolcalc.cpp235
-rw-r--r--noncore/apps/oxygen/kmolcalc.h110
-rw-r--r--noncore/apps/oxygen/kmolelements.cpp238
-rw-r--r--noncore/apps/oxygen/kmolelements.h161
-rw-r--r--noncore/apps/oxygen/kmolweights107
-rw-r--r--noncore/apps/oxygen/main.cpp21
-rw-r--r--noncore/apps/oxygen/opie-oxygen.control9
-rw-r--r--noncore/apps/oxygen/oxygen.cpp53
-rw-r--r--noncore/apps/oxygen/oxygen.h22
-rw-r--r--noncore/apps/oxygen/oxygen.pro20
15 files changed, 1305 insertions, 0 deletions
diff --git a/noncore/apps/oxygen/.cvsignore b/noncore/apps/oxygen/.cvsignore
new file mode 100644
index 0000000..2c33e73
--- a/dev/null
+++ b/noncore/apps/oxygen/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile*
diff --git a/noncore/apps/oxygen/TODO b/noncore/apps/oxygen/TODO
new file mode 100644
index 0000000..bc60bf4
--- a/dev/null
+++ b/noncore/apps/oxygen/TODO
@@ -0,0 +1 @@
+TODO:
diff --git a/noncore/apps/oxygen/calcdlg.ui b/noncore/apps/oxygen/calcdlg.ui
new file mode 100644
index 0000000..e0b19f9
--- a/dev/null
+++ b/noncore/apps/oxygen/calcdlg.ui
@@ -0,0 +1,243 @@
+<!DOCTYPE UI><UI>
+<class>CalcDlg</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>CalcDlg</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>218</width>
+ <height>274</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Network Time</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <widget>
+ <class>QTabWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TabWidgetMain</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>10</x>
+ <y>0</y>
+ <width>200</width>
+ <height>260</height>
+ </rect>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tabMain</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Molweight</string>
+ </attribute>
+ <widget>
+ <class>QFrame</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>FrameSystemTime</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>2</x>
+ <y>2</y>
+ <width>180</width>
+ <height>220</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>StyledPanel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Raised</enum>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_4</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>1</x>
+ <y>1</y>
+ <width>298</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Formula:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout7</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>50</y>
+ <width>175</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>calculate</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Calculate</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>clear_fields</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Clear</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>formula</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>20</y>
+ <width>170</width>
+ <height>22</height>
+ </rect>
+ </property>
+ </widget>
+ <widget>
+ <class>QMultiLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>anal_display</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>130</y>
+ <width>170</width>
+ <height>80</height>
+ </rect>
+ </property>
+ </widget>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>result</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>100</y>
+ <width>170</width>
+ <height>22</height>
+ </rect>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2_4</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>1</x>
+ <y>86</y>
+ <width>298</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Result:</string>
+ </property>
+ </widget>
+ </widget>
+ </widget>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tabNtp</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Nernst</string>
+ </attribute>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>1</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>2</number>
+ </property>
+ </grid>
+ </widget>
+ </widget>
+</widget>
+</UI>
diff --git a/noncore/apps/oxygen/calcdlgui.cpp b/noncore/apps/oxygen/calcdlgui.cpp
new file mode 100644
index 0000000..e9b40d3
--- a/dev/null
+++ b/noncore/apps/oxygen/calcdlgui.cpp
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * ( at your option ) any later version. *
+ * *
+ **************************************************************************/
+#include "oxygen.h"
+
+#include "calcdlgui.h"
+#include "kmolcalc.h"
+#include <qlineedit.h>
+#include <qmultilineedit.h>
+#include <qpushbutton.h>
+
+calcDlgUI::calcDlgUI() : CalcDlg()
+{
+ kmolcalc = new KMolCalc;
+ connect( calculate, SIGNAL( clicked() ), this, SLOT( calc() ) );
+ connect( clear_fields, SIGNAL( clicked() ), this, SLOT( clear() ) );
+}
+
+void calcDlgUI::calc()
+{
+ QString compound( formula->text() );
+ if ( compound.isEmpty() ) {
+ clear();
+ return;
+ }
+ QString errors( kmolcalc->readFormula( compound ) );
+ QString mw, ea;
+ double weight = kmolcalc->getWeight();
+ if ( errors == "OK" ) {
+ mw.setNum( weight );
+ ea = kmolcalc->getEmpFormula() + " :\n" + kmolcalc->getEA();
+ } else {
+ mw = "???";
+ ea = tr( "ERROR: \n" ) + errors + "\n";
+ }
+ result->setText( mw );
+ anal_display->setText( ea );
+}
+
+/**
+ * * Clear all text entry / result fields.
+ * */
+void calcDlgUI::clear()
+{
+ formula->clear();
+ result->clear();
+ anal_display->clear();
+}
+
+
diff --git a/noncore/apps/oxygen/calcdlgui.h b/noncore/apps/oxygen/calcdlgui.h
new file mode 100644
index 0000000..33a1ec1
--- a/dev/null
+++ b/noncore/apps/oxygen/calcdlgui.h
@@ -0,0 +1,27 @@
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * ( at your option ) any later version. *
+ * *
+ **************************************************************************/
+#include <qstring.h>
+#include "calcdlg.h"
+
+class QVBox;
+class KMolCalc;
+
+class calcDlgUI : public CalcDlg
+{
+ Q_OBJECT
+
+ public:
+ calcDlgUI();
+ KMolCalc *kmolcalc;
+
+ public slots:
+ void calc();
+ void clear();
+};
diff --git a/noncore/apps/oxygen/kmolcalc.cpp b/noncore/apps/oxygen/kmolcalc.cpp
new file mode 100644
index 0000000..7257c4a
--- a/dev/null
+++ b/noncore/apps/oxygen/kmolcalc.cpp
@@ -0,0 +1,235 @@
+/*
+ * kmolcalc.cpp
+ *
+ * Copyright (C) 2000 Tomislav Gountchev <tomi@idiom.com>
+ * Copyright (C) 2002 Carsten Niehaus <cniehaus@handhelds.org>
+ */
+
+/**
+ * KMOLCALC is the calculation engine. It knows about a hashtable of user defined atomic
+ * weights and group definitions ELSTABLE, and the currently processed formula, stored
+ * as a list of elements and their coefficients, ELEMENTS.
+ */
+
+#include "kmolcalc.h"
+#include <qdict.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <iostream.h>
+
+
+/**
+ * Construct a new calculator object.
+ */
+KMolCalc::KMolCalc() {
+ elements = new ElementList;
+ elstable = NULL;
+ readElstable();
+}
+
+KMolCalc::~KMolCalc() {
+ delete elements;
+}
+
+void KMolCalc::readElstable() {
+ weight = -1; // not calculated yet
+ if (elstable) delete elstable;
+ elstable = new QDict<SubUnit> (197, TRUE);
+ elstable->setAutoDelete(TRUE);
+ QStringList files = "/home/opie/opie/noncore/apps/oxigen/kmolweights";
+ mwfile = "/home/opie/opie/noncore/apps/oxigen/kmolweights";
+ QFile f(mwfile);
+ QString* latest_f = &mwfile;
+ for (uint i=0; i<files.count(); i++) {
+ if (QFileInfo(QFile(files[i])).lastModified() > QFileInfo(QFile(*latest_f)).lastModified()) {
+ latest_f = &files[i];
+ }
+ }
+ QFile lf(*latest_f);
+ if (f.exists()) readMwfile(f);
+ if (!f.exists()) {
+ readMwfile(lf);
+ writeElstable();
+ } else if (QFileInfo(f).lastModified() < QFileInfo(lf).lastModified()) {
+ // announce
+ QMessageBox::information
+ (0, "Warning:", "Found new global Mw file.\nLocal definitions will be updated.", QMessageBox::Ok);
+ readMwfile(lf);
+ writeElstable();
+ }
+
+}
+
+
+/**
+ * Parse a string S and construct the ElementList this->ELEMENTS, representing the
+ * composition of S. Returns 0 if successful, or an error code (currently -1) if
+ * parsing failed.
+ * The elements is S must be valid element or group symbols, as stored in this->ELSTABLE.
+ * See help files for correct formula syntax.
+ */
+QString KMolCalc::readFormula(const QString& s) {
+ weight = -1;
+ if (elements) delete elements;
+ elements = new ElementList;
+ return KMolCalc::readGroup(s, elements);
+}
+
+// read a formula group recursively. Called by readFormula.
+QString KMolCalc::readGroup(const QString& s, ElementList* els) {
+ if (s.isEmpty()) return QString ("Enter a formula."); //ERROR
+ int sl = s.length();
+ int i = 0;
+ QString errors ("OK");
+ bool ok = TRUE;
+ while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
+ double prefix = (i == 0 ? 1 : s.left(i).toDouble(&ok));
+ if (! ok || i == sl || prefix == 0) return QString ("Bad formula."); // ERROR
+ ElementList* elstemp = new ElementList;
+ while (i < sl) {
+ int j = i;
+ if (s[i] == '(') {
+ ElementList* inner = new ElementList;
+ int level = 1; // count levels of nested ( ).
+ while (1) {
+ if (i++ == sl) {
+ delete inner;
+ delete elstemp;
+ return QString ("Bad formula."); //ERROR
+ }
+ if (s[i] == '(') level++;
+ if (s[i] == ')') level--;
+ if (level == 0) break;
+ }
+ errors = KMolCalc::readGroup(s.mid(j+1, i-j-1), inner);
+ j = ++i;
+ while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
+ double suffix = (i == j ? 1 : s.mid(j, i-j).toDouble(&ok));
+ if (! ok || suffix == 0) {
+ delete inner;
+ delete elstemp;
+ return QString ("Bad formula."); // ERROR
+ }
+ inner->addTo(*elstemp, suffix);
+ delete inner;
+ inner = NULL;
+ } else if ((s[i] >= 'A' && s[i] <= 'Z') || (s[i] >= 'a' && s[i] <= 'z')) {
+ while (++i < sl && ((s[i] >= 'a' && s[i] <= 'z') || s[i] == '*' ||
+ s[i] == '\''));
+ QString elname = s.mid(j, i-j);
+ j = i;
+ while (i < sl && ((s[i] <= '9' && s[i] >= '0') || s[i] == '.')) i++;
+ double suffix = (i == j ? 1 : s.mid(j, i-j).toDouble(&ok));
+ if (! ok || suffix == 0) {
+ delete elstemp;
+ return QString ("Bad formula."); // ERROR
+ }
+ SubUnit* group = elstable->find(elname);
+ if (group == 0) {
+ delete elstemp;
+ return QString ("Undefined symbol: ") + elname; //ERROR
+ }
+ group->addTo(*elstemp, suffix);
+ } else if (s[i] == '+') {
+ if (elstemp->isEmpty()) {
+ delete elstemp;
+ return QString ("Bad formula."); //ERROR
+ }
+ elstemp->addTo(*els, prefix);
+ delete elstemp;
+ errors = KMolCalc::readGroup(s.mid(i+1, sl-i-1), els);
+ return errors;
+ } else {
+ delete elstemp;
+ return QString ("Bad formula."); //ERROR
+ }
+ }
+ elstemp->addTo(*els, prefix);
+ delete elstemp;
+ return errors;
+}
+
+/**
+ * Calculate and return the molecular weight of the current chemical formula.
+ */
+double KMolCalc::getWeight() {
+ if (weight == -1) weight = elements->getWeight(elstable);
+ return weight;
+}
+
+/**
+ * Return the elemental composition of the current formula, as a string of tab-separated
+ * element - percentage pairs, separated by newlines.
+ */
+QString KMolCalc::getEA() {
+ if (weight == -1) weight = elements->getWeight(elstable);
+ if (weight == -1) return QString("ERROR: Couldn't get Mw..."); // ERROR
+ return elements->getEA(elstable, weight);
+}
+
+/**
+ * Return the empirical formula of the current compound as a QString.
+ */
+QString KMolCalc::getEmpFormula() {
+ return elements->getEmpFormula();
+}
+
+// Read the element definition file.
+void KMolCalc::readMwfile(QFile& f) {
+ if (! f.open(IO_ReadOnly)) return; //ERROR
+ QTextStream fs (&f);
+ QString line;
+ while (! fs.eof()) {
+ line = fs.readLine();
+ SubUnit* s = SubUnit::makeSubUnit(line);
+ elstable->replace(s->getName(), s);
+ }
+ f.close();
+}
+
+/**
+ * Save the element definitions file.
+ */
+void KMolCalc::writeElstable() {
+ QFile f(mwfile);
+ if (! f.open(IO_WriteOnly)) return; //ERROR
+ QTextStream fs (&f);
+ QString line;
+ QDictIterator<SubUnit> it(*elstable);
+ while (it.current()) {
+ it.current()->writeOut(line);
+ fs << line << endl;
+ ++it;
+ }
+ f.close();
+}
+
+/**
+ * Remove a group or element definition from ELSTABLE.
+ */
+void KMolCalc::undefineGroup (const QString& name) {
+ elstable->remove (name);
+}
+
+/**
+ * Add a new element name - atomic weight record to the ELSTABLE hashtable. Assumes
+ * NAME has valid syntax.
+
+ */
+void KMolCalc::defineElement (const QString& name, double weight) {
+ Element* el = new Element(name, weight);
+ elstable->replace(name, el);
+}
+
+/**
+ * Add a new group definition to the ELSTABLE. Returns 0 if OK, -1 if parsing FORMULA
+ * fails. Assumes the syntax of grpname is correct.
+ */
+QString KMolCalc::defineGroup (const QString& grpname, const QString& formula) {
+ ElementList* els = new ElementList(grpname);
+ QString error = readGroup(formula, els);
+ if (error != "OK") return error;
+ if (els->contains(grpname)) return QString("Can't define a group recursively!\n");
+ elstable->replace(grpname, els);
+ return QString("OK");
+}
diff --git a/noncore/apps/oxygen/kmolcalc.h b/noncore/apps/oxygen/kmolcalc.h
new file mode 100644
index 0000000..c3e02f3
--- a/dev/null
+++ b/noncore/apps/oxygen/kmolcalc.h
@@ -0,0 +1,110 @@
+/*
+ * kmolcalc.h
+ *
+ * Copyright (C) 2000 Tomislav Gountchev <tomi@idiom.com>
+ */
+
+
+#ifndef KMOLCALC_H
+#define KMOLCALC_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include "kmolelements.h"
+#include <qdict.h>
+#include <qlist.h>
+#include <qstring.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qmessagebox.h>
+#include <qtextstream.h>
+
+
+/**
+ * KMOLCALC is the calculation engine. It knows about a hashtable of user defined atomic
+ * weights and group definitions ELSTABLE, and the currently processed formula, stored
+ * as a list of elements and their coefficients, ELEMENTS.
+ */
+class KMolCalc {
+
+public:
+
+ KMolCalc();
+ ~KMolCalc();
+
+ /**
+ * Parse a string S and construct the ElementList ELEMENTS, representing the composition
+ * of S. Returns "OK" if successful, or an error message if parsing failed.
+ * The elements is S must be valid element or group symbols, as stored in ELSTABLE.
+ * See help files for correct formula syntax.
+ */
+ QString readFormula(const QString& s);
+
+ /**
+ * Calculate and return the molecular weight of the current chemical formula.
+ */
+ double getWeight();
+
+ /**
+ * Return the elemental composition of the current formula, as a string of tab-separated
+ * element - percentage pairs, separated by newlines.
+ */
+ QString getEA();
+
+
+ /**
+ * Return the empirical formula of the current compound as a QString.
+ */
+ QString getEmpFormula();
+
+ /**
+ * Add a new element name - atomic weight record to the ELSTABLE hashtable.
+ * Assumes NAME has valid syntax.
+ */
+ void defineElement(const QString& name, double weight);
+
+ /**
+ * Add a new group definition to the ELSTABLE. Returns "OK" if OK, error message
+ * if parsing FORMULA fails. Assumes the syntax of NAME is correct.
+ */
+ QString defineGroup(const QString& name, const QString& formula);
+
+ /**
+ * Remove a group or element definition from ELSTABLE.
+ */
+ void undefineGroup(const QString& name);
+
+ /**
+ * Save the element definitions file.
+ */
+ void writeElstable();
+
+ /**
+ * Read the element definitions file and construct ELSTABLE.
+ */
+ void readElstable();
+
+ /**
+ * The element dictionary.
+ */
+ QDict<SubUnit>* elstable;
+
+ QString mwfile;
+
+ private:
+ double weight;
+
+ QString readGroup(const QString& s, ElementList* els);
+ void readMwfile(QFile& f);
+ ElementList* elements;
+};
+
+#endif
+
+
+
+
+
diff --git a/noncore/apps/oxygen/kmolelements.cpp b/noncore/apps/oxygen/kmolelements.cpp
new file mode 100644
index 0000000..ce8f9c1
--- a/dev/null
+++ b/noncore/apps/oxygen/kmolelements.cpp
@@ -0,0 +1,238 @@
+/*
+ * kmolelements.cpp
+ *
+ * Copyright (C) 2000 Tomislav Gountchev <tomi@idiom.com>
+ */
+
+// classes that store and manipulate chemical formulas represented as
+// lists of elements
+
+#include <stdio.h>
+#include "kmolelements.h"
+
+/**
+ * A generic chemical entity. Can be an element or a group.
+ */
+SubUnit::SubUnit () {}
+
+SubUnit::~SubUnit () {}
+
+/**
+ * Construct a subunit and return a pointer to it. The syntax of LINE is
+ * the one used in the element definition file.
+ */
+SubUnit* SubUnit::makeSubUnit(QString line) {
+ QString name, grpname, weight, coef;
+ QTextStream str (line, IO_ReadOnly);
+ str >> name;
+ if (name != "-group") { // not a group - must be represented as Element
+ str >> weight >> ws;
+ return new Element(name, weight.toDouble());
+ }
+ else {
+ str >> grpname;
+ ElementList* els = new ElementList(grpname); // group - make an ElementList
+ while (!str.eof()) {
+ str >> name >> ws;
+ str >> coef >> ws;
+ els->addElement(name, coef.toDouble());
+ }
+ return els;
+ }
+}
+
+QString SubUnit::getName() const {
+ return QString("None");
+}
+
+/**
+ * Get the molecular weight of THIS, based on the data from ELSTABLE.
+ */
+double SubUnit::getWeight(QDict<SubUnit>* elstable) const {
+ return -1;
+}
+
+/**
+ * A group of elements.
+ */
+ElementList::ElementList () {
+ elements = new QList<ElementCoef>;
+}
+
+ElementList::~ElementList () {
+ delete elements;
+}
+
+
+/**
+ * A group of elements.
+ */
+ElementList::ElementList (QString name) {
+ this->name = name;
+ elements = new QList<ElementCoef>;
+}
+
+/**
+ * Write THIS to LINE, in a format suitable for the element definition file.
+ */
+void ElementList::writeOut(QString& line) {
+ QString coef;
+ line = "-group " + name;
+ ElementCoef* current = elements->first();
+ while (current != 0) {
+ line += " " + current->name + " " + coef.setNum(current->coef, 'g', 10);
+ // precision set to 10 digits
+ current = elements->next();
+ }
+}
+
+/**
+ * Get the molecular weight of THIS, based on the data from ELSTABLE.
+ */
+double ElementList::getWeight(QDict<SubUnit>* elstable) const {
+ double weight = 0;
+ ElementCoef* current = elements->first();
+ while (current != 0) {
+ SubUnit* e = elstable->find(current->name);
+ if (e != 0) {
+ weight += (current->coef) * (e->getWeight(elstable));
+ } else return -1; //ERROR
+ current = elements->next();
+ }
+ return weight;
+}
+
+/**
+ * Return a string representing the elemental composition of THIS, as
+ * a tab-separated element - percentage pairs, separated by newlines.
+ */
+QString ElementList::getEA(QDict<SubUnit>* elstable, double mw) const {
+ if (mw == 0) mw = getWeight(elstable);
+ QString ea;
+ QString temp;
+ ElementCoef* current = elements->first();
+ while (current != 0) {
+ SubUnit* e = elstable->find(current->name);
+ if (e != 0) {
+ double current_percent = 100 * (current->coef) *
+ (e->getWeight(elstable))
+ / mw;
+ ea += current->name + "\t" +
+ temp.setNum(current_percent) + "\n";
+ } else return QString("ERROR!\n"); //ERROR
+ current = elements->next();
+ }
+ return ea;
+}
+
+/**
+ * Return a string representing THIS as an empirical chemical formula.
+ */
+QString ElementList::getEmpFormula() const {
+ QString ef;
+ QString temp;
+ ElementCoef* current = elements->first();
+ while (current != 0) {
+ ef += current->name + temp.setNum(current->coef);
+ current = elements->next();
+ }
+ return ef;
+}
+
+/**
+ * Multiply THIS (i.e. the coefficient of each element) by coef.
+ */
+void ElementList::multiplyBy(double coef) {
+ ElementCoef* current = elements->first();
+ while (current != 0) {
+ (current->coef) *= coef;
+ current = elements->next();
+ }
+}
+
+/**
+ * Add THIS to ELS. THIS is not modified; ELS is.
+ */
+void ElementList::addTo(ElementList& els, double coef) {
+ ElementCoef* current = elements->first();
+ while (current != 0) {
+ els.addElement(current->name, (current->coef) * coef);
+ current = elements->next();
+ }
+}
+
+/**
+ * Add an element to THIS, with a coefficient COEF. If THIS already contains
+ * an element with the same name, adjust its coefficient only; if not, create
+ * a new ElementCoef pair and add to THIS.
+ */
+void ElementList::addElement(const QString& name, double coef) {
+ ElementCoef* current = elements->first();
+ while (current != 0) {
+ if (current->name == name) {
+ current->coef += coef;
+ return;
+ }
+ current = elements->next();
+ }
+ elements->append(new ElementCoef(name, coef));
+}
+
+/**
+ * True iff THIS contains element named NAME.
+ */
+bool ElementList::contains(const QString& name) {
+ ElementCoef* current = elements->first();
+ while (current != 0) {
+ if (current->name == name)
+ return true;
+ current = elements->next();
+ }
+ return false;
+}
+
+bool ElementList::isEmpty() {
+ return elements->isEmpty();
+}
+
+QString ElementList::getName() const {
+ return name;
+}
+
+/**
+ * A chemical element.
+ */
+Element::Element(const QString& n, double w)
+ : weight(w), name(n) { }
+
+
+Element::~Element() {
+}
+
+
+/**
+ * Write THIS to LINE, in a format suitable for the element definition file.
+ */
+void Element::writeOut(QString& line) {
+ line.setNum(weight);
+ line = name + " " + line;
+}
+
+double Element::getWeight(QDict<SubUnit>* elstable) const {
+ return weight;
+}
+
+void Element::addTo(ElementList& els, double coef) {
+ els.addElement(name, coef);
+}
+
+QString Element::getName() const {
+ return name;
+}
+
+/**
+ * An element - coefficient pair. Used to represent elements within an
+ * element list.
+ */
+ElementCoef::ElementCoef(const QString& n, double c) : name(n), coef(c) {}
+
diff --git a/noncore/apps/oxygen/kmolelements.h b/noncore/apps/oxygen/kmolelements.h
new file mode 100644
index 0000000..06d1469
--- a/dev/null
+++ b/noncore/apps/oxygen/kmolelements.h
@@ -0,0 +1,161 @@
+/*
+ * kmolelements.h
+ *
+ * Copyright (C) 2000 Tomislav Gountchev <tomi@idiom.com>
+ */
+
+// classes that store and manipulate chemical formulas represented as
+// lists of elements
+
+#ifndef KMOLELEMENTS_H
+#define KMOLELEMENTS_H
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+
+#include <qlist.h>
+#include <qdict.h>
+#include <qstring.h>
+#include <qtextstream.h>
+
+class ElementCoef;
+class ElementList;
+
+/**
+ * A generic chemical entity. Can be an element or a group.
+ */
+class SubUnit {
+ public:
+
+ SubUnit();
+
+ virtual ~SubUnit();
+
+ /**
+ * Construct a subunit and return a pointer to it. The syntax of LINE is
+ * the one used in the element definition file.
+ */
+ static SubUnit* makeSubUnit(QString line);
+
+ /**
+ * Get the molecular weight of THIS, based on the data from ELSTABLE.
+ */
+ virtual double getWeight(QDict<SubUnit>* elstable) const;
+
+ /**
+ * Add THIS to ELS.
+ */
+ virtual void addTo(ElementList& els, double coef) = 0;
+
+ virtual QString getName() const;
+
+ /**
+ * Write THIS to LINE, in the format used in the definition file.
+ */
+ virtual void writeOut(QString& line) = 0;
+};
+
+
+/**
+ * A group of elements.
+ */
+class ElementList : public SubUnit {
+ public:
+ ElementList ();
+ ElementList (QString name);
+ virtual ~ElementList();
+ double getWeight(QDict<SubUnit>* elstable) const;
+
+ /**
+ * Return a string representing the elemental composition of THIS, as
+ * a tab-separated element - percentage pairs, separated by newlines.
+ */
+ QString getEA(QDict<SubUnit>* elstable, double mw = 0) const;
+
+ /**
+ * Return a string representing THIS as an empirical chemical formula.
+ */
+ QString getEmpFormula() const;
+
+ /**
+ * Multiply THIS (i.e. the coefficient of each element) by coef.
+ */
+ void multiplyBy(double coef);
+
+ /**
+ * Add THIS to ELS. THIS is not modified; ELS is.
+ */
+ void addTo(ElementList& els, double coef);
+
+ /**
+ * Add an element to THIS, with a coefficient COEF.
+ */
+ void addElement(const QString& name, double coef);
+
+ /**
+ * True iff THIS contains element named NAME.
+ */
+ bool contains(const QString& name);
+
+
+ bool isEmpty();
+
+ /**
+ * The name of THIS, as a chemical group.
+ */
+ QString getName() const;
+
+ /**
+ * Write THIS to LINE, in a format suitable for the element definition file.
+ */
+ void writeOut(QString& line);
+
+ private:
+ QString name;
+ QList<ElementCoef>* elements;
+};
+
+/**
+ * A chemical element.
+ */
+class Element : public SubUnit {
+ public:
+ Element(const QString& name, double weight);
+ virtual ~Element();
+ double getWeight(QDict<SubUnit>* elstable) const;
+
+ /**
+ * Add THIS to ELS, with a coefficient COEF.
+ */
+ void addTo(ElementList& els, double coef);
+
+ QString getName() const;
+
+ void writeOut(QString& line);
+
+ private:
+ double weight;
+ QString name;
+};
+
+
+/**
+ * An element - coefficient pair. Used to represent elements within an
+ * element list.
+ */
+class ElementCoef {
+ friend class ElementList;
+ public:
+ ElementCoef(const QString& name, double coef = 1.0);
+ private:
+ QString name;
+ double coef;
+};
+
+
+#endif
+
+
diff --git a/noncore/apps/oxygen/kmolweights b/noncore/apps/oxygen/kmolweights
new file mode 100644
index 0000000..82cbca0
--- a/dev/null
+++ b/noncore/apps/oxygen/kmolweights
@@ -0,0 +1,107 @@
+H 1.00794
+He 4.002602
+Li 6.941
+Be 9.012182
+B 10.811
+C 12.011
+N 14.00674
+O 15.9994
+F 18.9984032
+Ne 20.1797
+Na 22.989768
+Mg 24.3050
+Al 26.981539
+Si 28.0855
+P 30.973762
+S 32.066
+Cl 35.4527
+Ar 39.948
+K 39.0983
+Ca 40.078
+Sc 44.955910
+Ti 47.88
+V 50.9415
+Cr 51.9961
+Mn 54.93805
+Fe 55.847
+Co 58.93320
+Ni 58.6934
+Cu 63.546
+Zn 65.39
+Ga 69.723
+Ge 72.61
+As 74.92159
+Se 78.96
+Br 79.904
+Kr 83.80
+Rb 85.4678
+Sr 87.62
+Y 88.90585
+Zr 91.224
+Nb 92.90638
+Mo 95.94
+Tc 98.9063
+Ru 101.07
+Rh 102.90550
+Pd 106.42
+Ag 107.8682
+Cd 112.411
+In 114.82
+Sn 118.710
+Sb 121.757
+Te 127.60
+I 126.90447
+Xe 131.29
+Cs 132.90543
+Ba 137.327
+La 138.9055
+Ce 140.115
+Pr 140.90765
+Nd 144.24
+Pm 146.9151
+Sm 150.36
+Eu 151.965
+Gd 157.25
+Tb 158.92534
+Dy 162.50
+Ho 164.93032
+Er 167.26
+Tm 168.93421
+Yb 173.04
+Lu 174.967
+Hf 178.49
+Ta 180.9479
+W 183.85
+Re 186.207
+Os 190.2
+Ir 192.22
+Pt 195.08
+Au 196.96654
+Hg 200.59
+Tl 204.3833
+Pb 207.2
+Bi 208.98037
+Po 208.9824
+At 209.9871
+Rn 222.0176
+Fr 223.0197
+Ra 226.0254
+Ac 227.0278
+Th 232.0381
+Pa 231.03588
+U 238.0289
+Np 237.0482
+Pu 244.0642
+Am 243.0614
+Cm 247.0703
+Bk 247.0703
+Cf 251.0796
+Es 252.0829
+Fm 257.0951
+Md 258.0986
+No 259.1009
+Lr 260.1053
+Unq 261.1087
+Unp 262.1138
+Unh 263.1182
+Uns 262.1229
diff --git a/noncore/apps/oxygen/main.cpp b/noncore/apps/oxygen/main.cpp
new file mode 100644
index 0000000..328b61f
--- a/dev/null
+++ b/noncore/apps/oxygen/main.cpp
@@ -0,0 +1,21 @@
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * ( at your option ) any later version. *
+ * *
+ * ***********************************************************************/
+
+
+#include <qpe/qpeapplication.h>
+#include "oxygen.h"
+
+int main(int argc, char **argv)
+{
+ QPEApplication app(argc, argv);
+ Oxygen *oxi = new Oxygen();
+ app.setMainWidget(oxi);
+ oxi->showMaximized();
+ return app.exec();
+}
diff --git a/noncore/apps/oxygen/opie-oxygen.control b/noncore/apps/oxygen/opie-oxygen.control
new file mode 100644
index 0000000..4f84158
--- a/dev/null
+++ b/noncore/apps/oxygen/opie-oxygen.control
@@ -0,0 +1,9 @@
+Files: bin/oxygen apps/Applications/oxygencheckbook.desktop pics/oxygen/oxygen.png
+Priority: optional
+Section: applications
+Maintainer: Carsten Niehaus <cniehaus@handhelds.org>
+Architecture: arm
+Version: $QPE_VERSION-$SUB_VERSION
+Depends: opie-base ($QPE_VERSION)
+Description: Periodic System of the Elements
+ The chemistry application for the Opie-environment
diff --git a/noncore/apps/oxygen/oxygen.cpp b/noncore/apps/oxygen/oxygen.cpp
new file mode 100644
index 0000000..81897e9
--- a/dev/null
+++ b/noncore/apps/oxygen/oxygen.cpp
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * ( at your option ) any later version. *
+ * *
+ * ***********************************************************************/
+#include "oxygen.h"
+
+#include <qmenubar.h>
+#include <qstatusbar.h>
+#include <qpopupmenu.h>
+#include <qlabel.h>
+#include <qapplication.h>
+#include <qpushbutton.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qvbox.h>
+#include "calcdlg.h"
+#include "calcdlgui.h"
+
+Oxygen::Oxygen()
+ : QMainWindow()
+{
+ this->setCaption( "Oxygen" );
+ vbox = new QVBox( this );
+ QPushButton *setButton = new QPushButton( "Settings", vbox );
+ connect ( setButton, SIGNAL( clicked() ), this, SLOT( slotSettings() ) );
+ QPushButton *calcButton = new QPushButton( "Calculations", vbox );
+ connect ( calcButton, SIGNAL( clicked() ), this, SLOT( slotCalculations() ) );
+ QPushButton *pseButton = new QPushButton( "PSE", vbox );
+ connect ( pseButton, SIGNAL( clicked() ), this, SLOT( slotPSE() ) );
+
+ setCentralWidget( vbox );
+}
+
+
+void Oxygen::close()
+{
+ QApplication::exit();
+}
+
+//SLOTS
+
+void Oxygen::slotCalculations(){
+ calcDlgUI *CalcDlgUI = new calcDlgUI();
+ CalcDlgUI->show();
+};
+
+void Oxygen::slotSettings(){ };
+void Oxygen::slotPSE(){ };
+
diff --git a/noncore/apps/oxygen/oxygen.h b/noncore/apps/oxygen/oxygen.h
new file mode 100644
index 0000000..1e923ee
--- a/dev/null
+++ b/noncore/apps/oxygen/oxygen.h
@@ -0,0 +1,22 @@
+
+#include <qpe/resource.h>
+#include <qmainwindow.h>
+#include <qtoolbar.h>
+#include <qstring.h>
+#include <qpopupmenu.h>
+
+class QVBox;
+
+class Oxygen : public QMainWindow
+{
+ Q_OBJECT
+
+ public:
+ Oxygen();
+ QVBox *vbox;
+ private slots:
+ void slotCalculations();
+ void slotSettings();
+ void slotPSE();
+ void close();
+};
diff --git a/noncore/apps/oxygen/oxygen.pro b/noncore/apps/oxygen/oxygen.pro
new file mode 100644
index 0000000..c5448e7
--- a/dev/null
+++ b/noncore/apps/oxygen/oxygen.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+HEADERS = oxygen.h \
+ kmolcalc.h \
+ kmolelements.h \
+ calcdlgui.h
+
+SOURCES = main.cpp \
+ oxygen.cpp \
+ kmolcalc.cpp \
+ calcdlgui.cpp \
+ kmolelements.cpp
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe
+INTERFACES = calcdlg.ui
+TARGET = oxygen
+DESTDIR = $(OPIEDIR)/bin
+
+TRANSLATIONS = ../../../i18n/de/oxygen.ts