~scottydelicious666/brewtarget/brewtarget

« back to all changes in this revision

Viewing changes to misc.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
 
 * misc.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 "brewtarget.h"
20
 
#include <iostream>
21
 
#include <string>
22
 
#include <vector>
23
 
#include "misc.h"
24
 
#include "stringparsing.h"
25
 
#include "xmlnode.h"
26
 
#include "brewtarget.h"
27
 
#include <QDomElement>
28
 
#include <QDomText>
29
 
 
30
 
bool operator<(Misc &m1, Misc &m2)
31
 
{
32
 
   return m1.name < m2.name;
33
 
}
34
 
 
35
 
bool operator==(Misc &m1, Misc &m2)
36
 
{
37
 
   return m1.name == m2.name;
38
 
}
39
 
 
40
 
/*
41
 
std::string Misc::toXml()
42
 
{
43
 
   std::string ret = "<MISC>\n";
44
 
   
45
 
   ret += "<NAME>"+name+"</NAME>\n";
46
 
   ret += "<VERSION>"+intToString(version)+"</VERSION>\n";
47
 
   ret += "<TYPE>"+type+"</TYPE>\n";
48
 
   ret += "<USE>"+use+"</USE>\n";
49
 
   ret += "<TIME>"+doubleToString(time)+"</TIME>\n";
50
 
   ret += "<AMOUNT>"+doubleToString(amount)+"</AMOUNT>\n";
51
 
   ret += "<AMOUNT_IS_WEIGHT>"+boolToString(amountIsWeight)+"</AMOUNT_IS_WEIGHT>\n";
52
 
   ret += "<USE_FOR>"+useFor+"</USE_FOR>\n";
53
 
   ret += "<NOTES>"+notes+"</NOTES>\n";
54
 
   
55
 
   ret += "</MISC>\n";
56
 
   return ret;
57
 
}
58
 
*/
59
 
 
60
 
void Misc::toXml(QDomDocument& doc, QDomNode& parent)
61
 
{
62
 
   QDomElement miscNode;
63
 
   QDomElement tmpNode;
64
 
   QDomText tmpText;
65
 
   
66
 
   miscNode = doc.createElement("MISC");
67
 
   
68
 
   tmpNode = doc.createElement("NAME");
69
 
   tmpText = doc.createTextNode(name.c_str());
70
 
   tmpNode.appendChild(tmpText);
71
 
   miscNode.appendChild(tmpNode);
72
 
   
73
 
   tmpNode = doc.createElement("VERSION");
74
 
   tmpText = doc.createTextNode(text(version));
75
 
   tmpNode.appendChild(tmpText);
76
 
   miscNode.appendChild(tmpNode);
77
 
   
78
 
   tmpNode = doc.createElement("TYPE");
79
 
   tmpText = doc.createTextNode(type.c_str());
80
 
   tmpNode.appendChild(tmpText);
81
 
   miscNode.appendChild(tmpNode);
82
 
   
83
 
   tmpNode = doc.createElement("USE");
84
 
   tmpText = doc.createTextNode(use.c_str());
85
 
   tmpNode.appendChild(tmpText);
86
 
   miscNode.appendChild(tmpNode);
87
 
   
88
 
   tmpNode = doc.createElement("TIME");
89
 
   tmpText = doc.createTextNode(text(time));
90
 
   tmpNode.appendChild(tmpText);
91
 
   miscNode.appendChild(tmpNode);
92
 
   
93
 
   tmpNode = doc.createElement("AMOUNT");
94
 
   tmpText = doc.createTextNode(text(amount));
95
 
   tmpNode.appendChild(tmpText);
96
 
   miscNode.appendChild(tmpNode);
97
 
   
98
 
   tmpNode = doc.createElement("AMOUNT_IS_WEIGHT");
99
 
   tmpText = doc.createTextNode(text(amountIsWeight));
100
 
   tmpNode.appendChild(tmpText);
101
 
   miscNode.appendChild(tmpNode);
102
 
   
103
 
   tmpNode = doc.createElement("USE_FOR");
104
 
   tmpText = doc.createTextNode(useFor.c_str());
105
 
   tmpNode.appendChild(tmpText);
106
 
   miscNode.appendChild(tmpNode);
107
 
   
108
 
   tmpNode = doc.createElement("NOTES");
109
 
   tmpText = doc.createTextNode(notes.c_str());
110
 
   tmpNode.appendChild(tmpText);
111
 
   miscNode.appendChild(tmpNode);
112
 
   
113
 
   parent.appendChild(miscNode);
114
 
}
115
 
 
116
 
//============================CONSTRUCTORS======================================
117
 
void Misc::setDefaults()
118
 
{
119
 
   name = "";
120
 
   type = "Other";
121
 
   use = "Boil";
122
 
   amount = 0.0;
123
 
   time = 0.0;
124
 
   
125
 
   amountIsWeight=false;
126
 
   useFor = "";
127
 
   notes = "";
128
 
}
129
 
 
130
 
Misc::Misc() : Observable()
131
 
{
132
 
   setDefaults();
133
 
}
134
 
 
135
 
Misc::Misc(Misc& other)
136
 
        : Observable()
137
 
{
138
 
   name = other.name;
139
 
   type = other.type;
140
 
   use = other.use;
141
 
   time = other.time;
142
 
   amount = other.amount;
143
 
 
144
 
   amountIsWeight = other.amountIsWeight;
145
 
   useFor = other.useFor;
146
 
   notes = other.notes;
147
 
}
148
 
 
149
 
Misc::Misc( const XmlNode * node ) : Observable()
150
 
{
151
 
   std::vector<XmlNode *> children;
152
 
   std::vector<XmlNode *> tmpVec;
153
 
   std::string tag;
154
 
   std::string leafText;
155
 
   XmlNode* leaf;
156
 
   unsigned int i, childrenSize;
157
 
   bool hasName=false, hasVersion=false, hasType=false, hasUse=false, hasAmount=false, hasTime=false;
158
 
   
159
 
   setDefaults();
160
 
   
161
 
   if( node->getTag() != "MISC" )
162
 
      throw MiscException("initializer not passed a MISC node.");
163
 
   
164
 
   node->getChildren( children );
165
 
   childrenSize = children.size();
166
 
   
167
 
   for( i = 0; i < childrenSize; ++i )
168
 
   {
169
 
      tag = children[i]->getTag();
170
 
      children[i]->getChildren( tmpVec );
171
 
      
172
 
      // All valid children of MISC only have zero or one child.
173
 
      if( tmpVec.size() > 1 )
174
 
         throw MiscException("Tag \""+tag+"\" has more than one child.");
175
 
      
176
 
      // Have to deal with the fact that this node might not have
177
 
      // and children at all.
178
 
      if( tmpVec.size() == 1 )
179
 
         leaf = tmpVec[0];
180
 
      else
181
 
         leaf = &XmlNode();
182
 
 
183
 
      // It must be a leaf if it is a valid BeerXML entry.
184
 
      if( ! leaf->isLeaf() )
185
 
         throw MiscException("Should have been a leaf but is not.");
186
 
      
187
 
      leafText = leaf->getLeafText();
188
 
      
189
 
      if( tag == "NAME" )
190
 
      {
191
 
         setName(leafText);
192
 
         hasName = true;
193
 
      }
194
 
      else if( tag == "VERSION" )
195
 
      {
196
 
         hasVersion = true;
197
 
         if( parseInt(leafText) != version )
198
 
            std::cerr << "Warning: XML MISC version is not " << version << std::endl;
199
 
      }
200
 
      else if( tag == "TYPE" )
201
 
      {
202
 
         setType(leafText);
203
 
         hasType = true;
204
 
      }
205
 
      else if( tag == "USE" )
206
 
      {
207
 
         setUse(leafText);
208
 
         hasUse = true;
209
 
      }
210
 
      else if( tag == "TIME" )
211
 
      {
212
 
         setTime(parseDouble(leafText));
213
 
         hasTime = true;
214
 
      }
215
 
      else if( tag == "AMOUNT" )
216
 
      {
217
 
         setAmount(parseDouble(leafText));
218
 
         hasAmount = true;
219
 
      }
220
 
      else if( tag == "AMOUNT_IS_WEIGHT" )
221
 
         setAmountIsWeight(parseBool(leafText));
222
 
      else if( tag == "USE_FOR" )
223
 
         setUseFor(leafText);
224
 
      else if( tag == "NOTES" )
225
 
         setNotes(leafText);
226
 
      else
227
 
         std::cerr << "Warning: MISC tag \"" << tag << "\" is not recognized." << std::endl;
228
 
   } // end for(...)
229
 
   
230
 
   if( !hasName || !hasVersion || !hasType || !hasUse || !hasAmount || !hasTime )
231
 
      throw MiscException("one of the required fields is missing.");
232
 
} //end Misc()
233
 
 
234
 
Misc::Misc(const QDomNode& miscNode)
235
 
{
236
 
   QDomNode node, child;
237
 
   QDomText textNode;
238
 
   QString property, value;
239
 
 
240
 
   setDefaults();
241
 
 
242
 
   for( node = miscNode.firstChild(); ! node.isNull(); node = node.nextSibling() )
243
 
   {
244
 
      if( ! node.isElement() )
245
 
      {
246
 
         Brewtarget::log(Brewtarget::WARNING, QString("Node at line %1 is not an element.").arg(textNode.lineNumber()) );
247
 
         continue;
248
 
      }
249
 
 
250
 
      child = node.firstChild();
251
 
      if( child.isNull() || ! child.isText() )
252
 
         continue;
253
 
 
254
 
      property = node.nodeName();
255
 
      textNode = child.toText();
256
 
      value = textNode.nodeValue();
257
 
 
258
 
      if( property == "NAME" )
259
 
      {
260
 
         name = value.toStdString();
261
 
      }
262
 
      else if( property == "VERSION" )
263
 
      {
264
 
         if( version != getInt(textNode) )
265
 
            Brewtarget::log(Brewtarget::ERROR, QString("MISC says it is not version %1. Line %2").arg(version).arg(textNode.lineNumber()) );
266
 
      }
267
 
      else if( property == "TYPE" )
268
 
      {
269
 
         if( isValidType(value.toStdString()) )
270
 
            type = value.toStdString();
271
 
         else
272
 
            Brewtarget::log(Brewtarget::ERROR, QString("%1 is not a valid type for MISC. Line %2").arg(value).arg(textNode.lineNumber()) );
273
 
      }
274
 
      else if( property == "USE" )
275
 
      {
276
 
         if( isValidUse(value.toStdString()) )
277
 
            use = value.toStdString();
278
 
         else
279
 
            Brewtarget::log(Brewtarget::ERROR, QString("%1 is not a valid use for MISC. Line %2").arg(value).arg(textNode.lineNumber()) );
280
 
      }
281
 
      else if( property == "TIME" )
282
 
      {
283
 
         setTime(getDouble(textNode));
284
 
      }
285
 
      else if( property == "AMOUNT" )
286
 
      {
287
 
         setAmount(getDouble(textNode));
288
 
      }
289
 
      else if( property == "AMOUNT_IS_WEIGHT" )
290
 
      {
291
 
         setAmountIsWeight(getBool(textNode));
292
 
      }
293
 
      else if( property == "USE_FOR" )
294
 
      {
295
 
         setUseFor(value.toStdString());
296
 
      }
297
 
      else if( property == "NOTES" )
298
 
      {
299
 
         setNotes(value.toStdString());
300
 
      }
301
 
      else
302
 
      {
303
 
         Brewtarget::log(Brewtarget::WARNING, QString("Unsupported MISC property: %1. Line %2").arg(property).arg(node.lineNumber()) );
304
 
      }
305
 
   }
306
 
 
307
 
   hasChanged();
308
 
}
309
 
 
310
 
//============================"GET" METHODS=====================================
311
 
std::string Misc::getName() const
312
 
{
313
 
   return name;
314
 
}
315
 
 
316
 
std::string Misc::getType() const
317
 
{
318
 
   return type;
319
 
}
320
 
 
321
 
std::string Misc::getUse() const
322
 
{
323
 
   return use;
324
 
}
325
 
 
326
 
double Misc::getAmount() const
327
 
{
328
 
   return amount;
329
 
}
330
 
 
331
 
double Misc::getTime() const
332
 
{
333
 
   return time;
334
 
}
335
 
 
336
 
bool Misc::getAmountIsWeight() const
337
 
{
338
 
   return amountIsWeight;
339
 
}
340
 
 
341
 
std::string Misc::getUseFor() const
342
 
{
343
 
   return useFor;
344
 
}
345
 
 
346
 
std::string Misc::getNotes() const
347
 
{
348
 
   return notes;
349
 
}
350
 
 
351
 
//============================"SET" METHODS=====================================
352
 
void Misc::setName( const std::string &var )
353
 
{
354
 
   name = std::string(var);
355
 
   hasChanged();
356
 
}
357
 
 
358
 
void Misc::setType( const std::string &var )
359
 
{
360
 
   if( ! isValidType(var) )
361
 
      throw MiscException("\""+var+"\" is not a valid type.");
362
 
   else
363
 
   {
364
 
      type = std::string(var);
365
 
      hasChanged();
366
 
   }
367
 
}
368
 
 
369
 
void Misc::setUse( const std::string &var )
370
 
{
371
 
   if( ! isValidUse(var) )
372
 
      throw MiscException("\""+var+"\" is not a valid use.");
373
 
   else
374
 
   {
375
 
      use = std::string(var);
376
 
      hasChanged();
377
 
   }
378
 
}
379
 
 
380
 
void Misc::setAmount( double var )
381
 
{
382
 
   if( var < 0.0 )
383
 
      throw MiscException("amount cannot be negative: " + doubleToString(var) );
384
 
   else
385
 
   {
386
 
      amount = var;
387
 
      hasChanged();
388
 
   }
389
 
}
390
 
 
391
 
void Misc::setTime( double var )
392
 
{
393
 
   if( var < 0.0 )
394
 
      throw MiscException("time cannot be negative: " + doubleToString(var) );
395
 
   else
396
 
   {
397
 
      time = var;
398
 
      hasChanged();
399
 
   }
400
 
}
401
 
 
402
 
void Misc::setAmountIsWeight( bool var )
403
 
{
404
 
   amountIsWeight = var;
405
 
   hasChanged();
406
 
}
407
 
 
408
 
void Misc::setUseFor( const std::string &var )
409
 
{
410
 
   useFor = std::string(var);
411
 
   hasChanged();
412
 
}
413
 
 
414
 
void Misc::setNotes( const std::string &var )
415
 
{
416
 
   notes = std::string(var);
417
 
   hasChanged();
418
 
}
419
 
 
420
 
//========================OTHER METHODS=========================================
421
 
 
422
 
bool Misc::isValidUse( const std::string &var )
423
 
{
424
 
   static const std::string uses[] = {"Boil", "Mash", "Primary", "Secondary", "Bottling"};
425
 
   static const unsigned int size = 5;
426
 
   unsigned int i;
427
 
   
428
 
   for( i = 0; i < size; ++i )
429
 
      if( var == uses[i] )
430
 
         return true;
431
 
   
432
 
   return false;
433
 
}
434
 
 
435
 
bool Misc::isValidType( const std::string &var )
436
 
{
437
 
   static const std::string types[] = {"Spice", "Fining", "Water Agent", "Herb", "Flavor", "Other"};
438
 
   static const unsigned int size = 6;
439
 
   unsigned int i;
440
 
   
441
 
   for( i = 0; i < size; ++i )
442
 
      if( var == types[i] )
443
 
         return true;
444
 
   
445
 
   return false;
446
 
}