~scottydelicious666/brewtarget/brewtarget

« back to all changes in this revision

Viewing changes to src/water.cpp

  • Committer: Philip Greggory Lee
  • Date: 2009-08-23 16:53:43 UTC
  • Revision ID: git-v1:f8d1a25135bd92f06c46c562293800e4faa42c61
Made a src/ and ui/ directory and moved everything.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * water.cpp is part of Brewtarget, and is Copyright Philip G. Lee
 
3
 * (rocketman768@gmail.com), 2009.
 
4
 *
 
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.
 
9
 
 
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.
 
14
 
 
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/>.
 
17
 */
 
18
 
 
19
#include <iostream>
 
20
#include <string>
 
21
#include <vector>
 
22
#include "stringparsing.h"
 
23
#include "water.h"
 
24
#include "brewtarget.h"
 
25
#include <QDomElement>
 
26
#include <QDomText>
 
27
 
 
28
bool operator<(Water &w1, Water &w2)
 
29
{
 
30
   return w1.name < w2.name;
 
31
}
 
32
 
 
33
bool operator==(Water &w1, Water &w2)
 
34
{
 
35
   return w1.name == w2.name;
 
36
}
 
37
 
 
38
/*
 
39
std::string Water::toXml()
 
40
{
 
41
   std::string ret = "<WATER>\n";
 
42
   
 
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";
 
54
   
 
55
   ret += "</WATER>\n";
 
56
   return ret;
 
57
}
 
58
*/
 
59
 
 
60
void Water::toXml(QDomDocument& doc, QDomNode& parent)
 
61
{
 
62
   QDomElement waterNode;
 
63
   QDomElement tmpNode;
 
64
   QDomText tmpText;
 
65
 
 
66
   waterNode = doc.createElement("WATER");
 
67
 
 
68
   tmpNode = doc.createElement("NAME");
 
69
   tmpText = doc.createTextNode(name.c_str());
 
70
   tmpNode.appendChild(tmpText);
 
71
   waterNode.appendChild(tmpNode);
 
72
 
 
73
   tmpNode = doc.createElement("VERSION");
 
74
   tmpText = doc.createTextNode(text(version));
 
75
   tmpNode.appendChild(tmpText);
 
76
   waterNode.appendChild(tmpNode);
 
77
 
 
78
   tmpNode = doc.createElement("AMOUNT");
 
79
   tmpText = doc.createTextNode(text(amount_l));
 
80
   tmpNode.appendChild(tmpText);
 
81
   waterNode.appendChild(tmpNode);
 
82
 
 
83
   tmpNode = doc.createElement("CALCIUM");
 
84
   tmpText = doc.createTextNode(text(calcium_ppm));
 
85
   tmpNode.appendChild(tmpText);
 
86
   waterNode.appendChild(tmpNode);
 
87
 
 
88
   tmpNode = doc.createElement("BICARBONATE");
 
89
   tmpText = doc.createTextNode(text(bicarbonate_ppm));
 
90
   tmpNode.appendChild(tmpText);
 
91
   waterNode.appendChild(tmpNode);
 
92
 
 
93
   tmpNode = doc.createElement("SULFATE");
 
94
   tmpText = doc.createTextNode(text(sulfate_ppm));
 
95
   tmpNode.appendChild(tmpText);
 
96
   waterNode.appendChild(tmpNode);
 
97
 
 
98
   tmpNode = doc.createElement("CHLORIDE");
 
99
   tmpText = doc.createTextNode(text(chloride_ppm));
 
100
   tmpNode.appendChild(tmpText);
 
101
   waterNode.appendChild(tmpNode);
 
102
 
 
103
   tmpNode = doc.createElement("SODIUM");
 
104
   tmpText = doc.createTextNode(text(sodium_ppm));
 
105
   tmpNode.appendChild(tmpText);
 
106
   waterNode.appendChild(tmpNode);
 
107
 
 
108
   tmpNode = doc.createElement("MAGNESIUM");
 
109
   tmpText = doc.createTextNode(text(magnesium_ppm));
 
110
   tmpNode.appendChild(tmpText);
 
111
   waterNode.appendChild(tmpNode);
 
112
 
 
113
   tmpNode = doc.createElement("PH");
 
114
   tmpText = doc.createTextNode(text(ph));
 
115
   tmpNode.appendChild(tmpText);
 
116
   waterNode.appendChild(tmpNode);
 
117
 
 
118
   tmpNode = doc.createElement("NOTES");
 
119
   tmpText = doc.createTextNode(notes.c_str());
 
120
   tmpNode.appendChild(tmpText);
 
121
   waterNode.appendChild(tmpNode);
 
122
 
 
123
   parent.appendChild(waterNode);
 
124
}
 
125
 
 
126
//================================CONSTRUCTORS==================================
 
127
void Water::setDefaults()
 
128
{
 
129
   name = "";
 
130
   amount_l = 0.0;
 
131
   calcium_ppm = 0.0;
 
132
   bicarbonate_ppm = 0.0;
 
133
   chloride_ppm = 0.0;
 
134
   sodium_ppm = 0.0;
 
135
   magnesium_ppm = 0.0;
 
136
   ph = 7.0;
 
137
   notes = "";
 
138
}
 
139
 
 
140
Water::Water()
 
141
{
 
142
   setDefaults();
 
143
}
 
144
 
 
145
Water::Water( XmlNode *node )
 
146
{
 
147
   std::vector<XmlNode *> children;
 
148
   std::vector<XmlNode *> tmpVec;
 
149
   std::string tag;
 
150
   std::string leafText;
 
151
   XmlNode* leaf;
 
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;
 
155
   
 
156
   setDefaults();
 
157
   
 
158
   if( node->getTag() != "WATER" )
 
159
      throw WaterException("initializer not passed a WATER node.");
 
160
   
 
161
   node->getChildren( children );
 
162
   childrenSize = children.size();
 
163
   
 
164
   for( i = 0; i < childrenSize; ++i )
 
165
   {
 
166
      tag = children[i]->getTag();
 
167
      children[i]->getChildren( tmpVec );
 
168
      
 
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.");
 
172
      
 
173
      leaf = tmpVec[0];
 
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.");
 
177
      
 
178
      leafText = leaf->getLeafText();
 
179
      
 
180
      if( tag == "NAME" )
 
181
      {
 
182
         setName(leafText);
 
183
         hasName = true;
 
184
      }
 
185
      else if( tag == "VERSION" )
 
186
      {
 
187
         if( parseInt(leafText) != version )
 
188
            std::cerr << "Warning: WATER version is not " << version << std::endl;
 
189
         
 
190
         hasVersion = true;
 
191
      }
 
192
      else if( tag == "AMOUNT" )
 
193
      {
 
194
         setAmount_l(parseDouble(leafText));
 
195
         hasAmount = true;
 
196
      }
 
197
      else if( tag == "CALCIUM" )
 
198
      {
 
199
         setCalcium_ppm(parseDouble(leafText));
 
200
         hasCa = true;
 
201
      }
 
202
      else if( tag == "BICARBONATE" )
 
203
      {
 
204
         setBicarbonate_ppm(parseDouble(leafText));
 
205
         hasBic = true;
 
206
      }
 
207
      else if( tag == "SULFATE" )
 
208
      {
 
209
         setSulfate_ppm(parseDouble(leafText));
 
210
         hasSulf = true;
 
211
      }
 
212
      else if( tag == "CHLORIDE" )
 
213
      {
 
214
         setChloride_ppm(parseDouble(leafText));
 
215
         hasChl = true;
 
216
      }
 
217
      else if( tag == "SODIUM" )
 
218
      {
 
219
         setSodium_ppm(parseDouble(leafText));
 
220
         hasSodium = true;
 
221
      }
 
222
      else if( tag == "MAGNESIUM" )
 
223
      {
 
224
         setMagnesium_ppm(parseDouble(leafText));
 
225
         hasMag = true;
 
226
      }
 
227
      else if( tag == "PH" )
 
228
      {
 
229
         setPh(parseDouble(leafText));
 
230
      }
 
231
      else if( tag == "NOTES" )
 
232
      {
 
233
         setNotes(leafText);
 
234
      }
 
235
      else
 
236
         std::cerr << "Warning: \"" << tag << "\" is not a supported WATER tag." << std::endl;
 
237
      
 
238
   } // end for(...)
 
239
   
 
240
   if( !hasName || !hasVersion || !hasAmount || !hasCa || !hasBic ||
 
241
           !hasSulf || !hasChl || !hasSodium || !hasMag )
 
242
      throw WaterException("missing required fields.");
 
243
} // end Water()
 
244
 
 
245
Water::Water(const QDomNode& waterNode)
 
246
{
 
247
   QDomNode node, child;
 
248
   QDomText textNode;
 
249
   QString property, value;
 
250
 
 
251
   setDefaults();
 
252
 
 
253
   for( node = waterNode.firstChild(); ! node.isNull(); node = node.nextSibling() )
 
254
   {
 
255
      if( ! node.isElement() )
 
256
      {
 
257
         Brewtarget::log(Brewtarget::WARNING, QString("Node at line is not an element. Line %1").arg(textNode.lineNumber()) );
 
258
         continue;
 
259
      }
 
260
 
 
261
      child = node.firstChild();
 
262
      if( child.isNull() || ! child.isText() )
 
263
         continue;
 
264
 
 
265
      property = node.nodeName();
 
266
      textNode = child.toText();
 
267
      value = textNode.nodeValue();
 
268
 
 
269
      if( property == "NAME" )
 
270
      {
 
271
         name = value.toStdString();
 
272
      }
 
273
      else if( property == "VERSION" )
 
274
      {
 
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()) );
 
277
      }
 
278
      else if( property == "AMOUNT" )
 
279
      {
 
280
         setAmount_l(getDouble(textNode));
 
281
      }
 
282
      else if( property == "CALCIUM" )
 
283
      {
 
284
         setCalcium_ppm(getDouble(textNode));
 
285
      }
 
286
      else if( property == "BICARBONATE" )
 
287
      {
 
288
         setBicarbonate_ppm(getDouble(textNode));
 
289
      }
 
290
      else if( property == "SULFATE" )
 
291
      {
 
292
         setSulfate_ppm(getDouble(textNode));
 
293
      }
 
294
      else if( property == "CHLORIDE" )
 
295
      {
 
296
         setChloride_ppm(getDouble(textNode));
 
297
      }
 
298
      else if( property == "SODIUM" )
 
299
      {
 
300
         setSodium_ppm(getDouble(textNode));
 
301
      }
 
302
      else if( property == "MAGNESIUM" )
 
303
      {
 
304
         setMagnesium_ppm(getDouble(textNode));
 
305
      }
 
306
      else if( property == "PH" )
 
307
      {
 
308
         setPh(getDouble(textNode));
 
309
      }
 
310
      else if( property == "NOTES" )
 
311
      {
 
312
         setNotes(value.toStdString());
 
313
      }
 
314
      else
 
315
         Brewtarget::log(Brewtarget::WARNING, QString("Unsupported WATER property: %1. Line %2").arg(property).arg(node.lineNumber()) );
 
316
   }
 
317
}
 
318
 
 
319
//================================"SET" METHODS=================================
 
320
void Water::setName( const std::string &var )
 
321
{
 
322
   name = std::string(var);
 
323
   hasChanged();
 
324
}
 
325
 
 
326
void Water::setAmount_l( double var )
 
327
{
 
328
   if( var < 0.0 )
 
329
      throw WaterException("amount cannot be negative: " + doubleToString(var) );
 
330
   else
 
331
   {
 
332
      amount_l = var;
 
333
      hasChanged();
 
334
   }
 
335
}
 
336
 
 
337
void Water::setCalcium_ppm( double var )
 
338
{
 
339
   if( var < 0.0 )
 
340
      throw WaterException("calcium cannot be negative: " + doubleToString(var) );
 
341
   else
 
342
   {
 
343
      calcium_ppm = var;
 
344
      hasChanged();
 
345
   }
 
346
}
 
347
 
 
348
void Water::setBicarbonate_ppm( double var )
 
349
{
 
350
   if( var < 0.0 )
 
351
      throw WaterException("bicarbonate cannot be negative: " + doubleToString(var) );
 
352
   else
 
353
   {
 
354
      bicarbonate_ppm = var;
 
355
      hasChanged();
 
356
   }
 
357
}
 
358
 
 
359
void Water::setChloride_ppm( double var )
 
360
{
 
361
   if( var < 0.0 )
 
362
      throw WaterException("chloride cannot be negative: " + doubleToString(var) );
 
363
   else
 
364
   {
 
365
      chloride_ppm = var;
 
366
      hasChanged();
 
367
   }
 
368
}
 
369
 
 
370
void Water::setSodium_ppm( double var )
 
371
{
 
372
   if( var < 0.0 )
 
373
      throw WaterException("sodium cannot be negative: " + doubleToString(var) );
 
374
   else
 
375
   {
 
376
      sodium_ppm = var;
 
377
      hasChanged();
 
378
   }
 
379
}
 
380
 
 
381
void Water::setMagnesium_ppm( double var )
 
382
{
 
383
   if( var < 0.0 )
 
384
      throw WaterException("magnesium cannot be negative: " + doubleToString(var) );
 
385
   else
 
386
   {
 
387
      magnesium_ppm = var;
 
388
      hasChanged();
 
389
   }
 
390
}
 
391
 
 
392
void Water::setPh( double var )
 
393
{
 
394
   if( var < 0.0 || var > 14.0 )
 
395
      throw WaterException("pH was not in [0,14]: " + doubleToString(var) );
 
396
   else
 
397
   {
 
398
      ph = var;
 
399
      hasChanged();
 
400
   }
 
401
}
 
402
 
 
403
void Water::setSulfate_ppm( double var )
 
404
{
 
405
   if( var < 0.0 )
 
406
      throw WaterException("sulfate cannot be negative: " + doubleToString(var));
 
407
   else
 
408
   {
 
409
      sulfate_ppm = var;
 
410
      hasChanged();
 
411
   }
 
412
}
 
413
 
 
414
void Water::setNotes( const std::string &var )
 
415
{
 
416
   notes = std::string(var);
 
417
   hasChanged();
 
418
}
 
419
 
 
420
//=========================="GET" METHODS=======================================
 
421
std::string Water::getName() const
 
422
{
 
423
   return name;
 
424
}
 
425
 
 
426
double Water::getSulfate_ppm() const
 
427
{
 
428
   return sulfate_ppm;
 
429
}
 
430
 
 
431
double Water::getAmount_l() const
 
432
{
 
433
   return amount_l;
 
434
}
 
435
 
 
436
double Water::getCalcium_ppm() const
 
437
{
 
438
   return calcium_ppm;
 
439
}
 
440
 
 
441
double Water::getBicarbonate_ppm() const
 
442
{
 
443
   return bicarbonate_ppm;
 
444
}
 
445
 
 
446
double Water::getChloride_ppm() const
 
447
{
 
448
   return chloride_ppm;
 
449
}
 
450
 
 
451
double Water::getSodium_ppm() const
 
452
{
 
453
   return sodium_ppm;
 
454
}
 
455
 
 
456
double Water::getMagnesium_ppm() const
 
457
{
 
458
   return magnesium_ppm;
 
459
}
 
460
 
 
461
double Water::getPh() const
 
462
{
 
463
   return ph;
 
464
}
 
465
 
 
466
std::string Water::getNotes() const
 
467
{
 
468
   return notes;
 
469
}