2
* water.cpp is part of Brewtarget, and is Copyright Philip G. Lee
3
* (rocketman768@gmail.com), 2009.
5
* Brewtarget is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* Brewtarget is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include "stringparsing.h"
24
#include "brewtarget.h"
25
#include <QDomElement>
28
bool operator<(Water &w1, Water &w2)
30
return w1.name < w2.name;
33
bool operator==(Water &w1, Water &w2)
35
return w1.name == w2.name;
39
std::string Water::toXml()
41
std::string ret = "<WATER>\n";
43
ret += "<NAME>"+name+"</NAME>\n";
44
ret += "<VERSION>"+intToString(version)+"</VERSION>\n";
45
ret += "<AMOUNT>"+doubleToString(amount_l)+"</AMOUNT>\n";
46
ret += "<CALCIUM>"+doubleToString(calcium_ppm)+"</CALCIUM>\n";
47
ret += "<BICARBONATE>"+doubleToString(bicarbonate_ppm)+"</BICARBONATE>\n";
48
ret += "<SULFATE>"+doubleToString(sulfate_ppm)+"</SULFATE>\n";
49
ret += "<CHLORIDE>"+doubleToString(chloride_ppm)+"</CHLORIDE>\n";
50
ret += "<SODIUM>"+doubleToString(sodium_ppm)+"</SODIUM>\n";
51
ret += "<MAGNESIUM>"+doubleToString(magnesium_ppm)+"</MAGNESIUM>\n";
52
ret += "<PH>"+doubleToString(ph)+"</PH>\n";
53
ret += "<NOTES>"+notes+"</NOTES>\n";
60
void Water::toXml(QDomDocument& doc, QDomNode& parent)
62
QDomElement waterNode;
66
waterNode = doc.createElement("WATER");
68
tmpNode = doc.createElement("NAME");
69
tmpText = doc.createTextNode(name.c_str());
70
tmpNode.appendChild(tmpText);
71
waterNode.appendChild(tmpNode);
73
tmpNode = doc.createElement("VERSION");
74
tmpText = doc.createTextNode(text(version));
75
tmpNode.appendChild(tmpText);
76
waterNode.appendChild(tmpNode);
78
tmpNode = doc.createElement("AMOUNT");
79
tmpText = doc.createTextNode(text(amount_l));
80
tmpNode.appendChild(tmpText);
81
waterNode.appendChild(tmpNode);
83
tmpNode = doc.createElement("CALCIUM");
84
tmpText = doc.createTextNode(text(calcium_ppm));
85
tmpNode.appendChild(tmpText);
86
waterNode.appendChild(tmpNode);
88
tmpNode = doc.createElement("BICARBONATE");
89
tmpText = doc.createTextNode(text(bicarbonate_ppm));
90
tmpNode.appendChild(tmpText);
91
waterNode.appendChild(tmpNode);
93
tmpNode = doc.createElement("SULFATE");
94
tmpText = doc.createTextNode(text(sulfate_ppm));
95
tmpNode.appendChild(tmpText);
96
waterNode.appendChild(tmpNode);
98
tmpNode = doc.createElement("CHLORIDE");
99
tmpText = doc.createTextNode(text(chloride_ppm));
100
tmpNode.appendChild(tmpText);
101
waterNode.appendChild(tmpNode);
103
tmpNode = doc.createElement("SODIUM");
104
tmpText = doc.createTextNode(text(sodium_ppm));
105
tmpNode.appendChild(tmpText);
106
waterNode.appendChild(tmpNode);
108
tmpNode = doc.createElement("MAGNESIUM");
109
tmpText = doc.createTextNode(text(magnesium_ppm));
110
tmpNode.appendChild(tmpText);
111
waterNode.appendChild(tmpNode);
113
tmpNode = doc.createElement("PH");
114
tmpText = doc.createTextNode(text(ph));
115
tmpNode.appendChild(tmpText);
116
waterNode.appendChild(tmpNode);
118
tmpNode = doc.createElement("NOTES");
119
tmpText = doc.createTextNode(notes.c_str());
120
tmpNode.appendChild(tmpText);
121
waterNode.appendChild(tmpNode);
123
parent.appendChild(waterNode);
126
//================================CONSTRUCTORS==================================
127
void Water::setDefaults()
132
bicarbonate_ppm = 0.0;
145
Water::Water( XmlNode *node )
147
std::vector<XmlNode *> children;
148
std::vector<XmlNode *> tmpVec;
150
std::string leafText;
152
unsigned int i, childrenSize;
153
bool hasName=false, hasVersion=false, hasAmount=false, hasCa=false, hasBic=false,
154
hasSulf=false, hasChl=false, hasSodium=false, hasMag=false;
158
if( node->getTag() != "WATER" )
159
throw WaterException("initializer not passed a WATER node.");
161
node->getChildren( children );
162
childrenSize = children.size();
164
for( i = 0; i < childrenSize; ++i )
166
tag = children[i]->getTag();
167
children[i]->getChildren( tmpVec );
169
// All valid children of WATER only have one child.
170
if( tmpVec.size() != 1 )
171
throw WaterException("Tag \""+tag+"\" has more than one child.");
174
// It must be a leaf if it is a valid BeerXML entry.
175
if( ! leaf->isLeaf() )
176
throw WaterException("Should have been a leaf but is not.");
178
leafText = leaf->getLeafText();
185
else if( tag == "VERSION" )
187
if( parseInt(leafText) != version )
188
std::cerr << "Warning: WATER version is not " << version << std::endl;
192
else if( tag == "AMOUNT" )
194
setAmount_l(parseDouble(leafText));
197
else if( tag == "CALCIUM" )
199
setCalcium_ppm(parseDouble(leafText));
202
else if( tag == "BICARBONATE" )
204
setBicarbonate_ppm(parseDouble(leafText));
207
else if( tag == "SULFATE" )
209
setSulfate_ppm(parseDouble(leafText));
212
else if( tag == "CHLORIDE" )
214
setChloride_ppm(parseDouble(leafText));
217
else if( tag == "SODIUM" )
219
setSodium_ppm(parseDouble(leafText));
222
else if( tag == "MAGNESIUM" )
224
setMagnesium_ppm(parseDouble(leafText));
227
else if( tag == "PH" )
229
setPh(parseDouble(leafText));
231
else if( tag == "NOTES" )
236
std::cerr << "Warning: \"" << tag << "\" is not a supported WATER tag." << std::endl;
240
if( !hasName || !hasVersion || !hasAmount || !hasCa || !hasBic ||
241
!hasSulf || !hasChl || !hasSodium || !hasMag )
242
throw WaterException("missing required fields.");
245
Water::Water(const QDomNode& waterNode)
247
QDomNode node, child;
249
QString property, value;
253
for( node = waterNode.firstChild(); ! node.isNull(); node = node.nextSibling() )
255
if( ! node.isElement() )
257
Brewtarget::log(Brewtarget::WARNING, QString("Node at line is not an element. Line %1").arg(textNode.lineNumber()) );
261
child = node.firstChild();
262
if( child.isNull() || ! child.isText() )
265
property = node.nodeName();
266
textNode = child.toText();
267
value = textNode.nodeValue();
269
if( property == "NAME" )
271
name = value.toStdString();
273
else if( property == "VERSION" )
275
if( version != getInt(textNode) )
276
Brewtarget::log(Brewtarget::ERROR, QString("WATER says it is not version %1. Line %2").arg(version).arg(textNode.lineNumber()) );
278
else if( property == "AMOUNT" )
280
setAmount_l(getDouble(textNode));
282
else if( property == "CALCIUM" )
284
setCalcium_ppm(getDouble(textNode));
286
else if( property == "BICARBONATE" )
288
setBicarbonate_ppm(getDouble(textNode));
290
else if( property == "SULFATE" )
292
setSulfate_ppm(getDouble(textNode));
294
else if( property == "CHLORIDE" )
296
setChloride_ppm(getDouble(textNode));
298
else if( property == "SODIUM" )
300
setSodium_ppm(getDouble(textNode));
302
else if( property == "MAGNESIUM" )
304
setMagnesium_ppm(getDouble(textNode));
306
else if( property == "PH" )
308
setPh(getDouble(textNode));
310
else if( property == "NOTES" )
312
setNotes(value.toStdString());
315
Brewtarget::log(Brewtarget::WARNING, QString("Unsupported WATER property: %1. Line %2").arg(property).arg(node.lineNumber()) );
319
//================================"SET" METHODS=================================
320
void Water::setName( const std::string &var )
322
name = std::string(var);
326
void Water::setAmount_l( double var )
329
throw WaterException("amount cannot be negative: " + doubleToString(var) );
337
void Water::setCalcium_ppm( double var )
340
throw WaterException("calcium cannot be negative: " + doubleToString(var) );
348
void Water::setBicarbonate_ppm( double var )
351
throw WaterException("bicarbonate cannot be negative: " + doubleToString(var) );
354
bicarbonate_ppm = var;
359
void Water::setChloride_ppm( double var )
362
throw WaterException("chloride cannot be negative: " + doubleToString(var) );
370
void Water::setSodium_ppm( double var )
373
throw WaterException("sodium cannot be negative: " + doubleToString(var) );
381
void Water::setMagnesium_ppm( double var )
384
throw WaterException("magnesium cannot be negative: " + doubleToString(var) );
392
void Water::setPh( double var )
394
if( var < 0.0 || var > 14.0 )
395
throw WaterException("pH was not in [0,14]: " + doubleToString(var) );
403
void Water::setSulfate_ppm( double var )
406
throw WaterException("sulfate cannot be negative: " + doubleToString(var));
414
void Water::setNotes( const std::string &var )
416
notes = std::string(var);
420
//=========================="GET" METHODS=======================================
421
std::string Water::getName() const
426
double Water::getSulfate_ppm() const
431
double Water::getAmount_l() const
436
double Water::getCalcium_ppm() const
441
double Water::getBicarbonate_ppm() const
443
return bicarbonate_ppm;
446
double Water::getChloride_ppm() const
451
double Water::getSodium_ppm() const
456
double Water::getMagnesium_ppm() const
458
return magnesium_ppm;
461
double Water::getPh() const
466
std::string Water::getNotes() const