src/ImportXML.cpp

Thu, 18 Aug 2022 20:34:15 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Thu, 18 Aug 2022 20:34:15 +0200
changeset 401
583148eb6e01
parent 389
a98d45793808
child 458
ac216a75ca9b
permissions
-rw-r--r--

Init est_carb field for new products.

/**
 * ImportXML.cpp is part of bmsapp.
 *
 * bmsapp 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 3 of the License, or
 * (at your option) any later version.
 *
 * bmsapp is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "ImportXML.h"
#include "../ui/ui_ImportXML.h"
#include "global.h"
#include "Utils.h"
#include "database/db_recipe.h"
#include "MainWindow.h"


ImportXML::ImportXML(QWidget *parent) : QDialog(parent), ui(new Ui::ImportXML)
{
    qDebug() << "ImportXML start";
    ui->setupUi(this);
    WindowTitle();
    ui->progressBar->setValue(0);
    connect(ui->quitButton, SIGNAL(clicked()), parent, SLOT(fromImportXML()));
}


ImportXML::~ImportXML()
{
    qDebug() << "ImportXML done";
    delete ui;
}


void ImportXML::WindowTitle()
{
    QString txt = QString(tr("BMSapp - Import XML"));
    setWindowTitle(txt);
}


void ImportXML::on_openButton_clicked()
{
    QSqlQuery query;
    QString   log;
    int total = 0, errors = 0;

    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::homePath() + "/*.xml", tr("Files (*.xml)"));
    if (fileName == 0) {
        QMessageBox::warning(this, tr("Open File"), tr("No XML file selected."));
        return;
    }
    ui->fileEdit->setText(fileName);

    QFile file(fileName);
    qint64 fsize = file.size();

    log = "Import XML file `" + fileName + "`\n\n"; 
    qInfo() << "Import XML" << fileName << "length" << fsize << "bytes";

    file.open(QIODevice::ReadOnly);
    QXmlStreamReader *xml = new QXmlStreamReader(&file);

    while (xml->readNext()) {

	if (xml->atEnd())
	    break;

	if (xml->tokenType() == QXmlStreamReader::StartDocument) {
	    qDebug() << xml->documentVersion() << xml->documentEncoding();
	    // Just skip
	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "EQUIPMENTS")) {
	    /*
	     * Equipments
	     */
	    while (xml->readNext()) {
		if (xml->atEnd())
            	    break;
		if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "EQUIPMENTS")) {
		    qDebug() << "0 /EQUIPMENTS";
		    break;
		}
		if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "EQUIPMENT")) {
		    /*
		     * Equipment
		     */
		    total++;
		    Equipment *eq = new Equipment();
		    eq->notes = "";

		    while (xml->readNext()) {
		    	if (xml->atEnd())
                            break;
		    	if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "EQUIPMENT")) {
			    query.prepare("INSERT INTO inventory_equipments SET name=:name, boil_size=:boil_size, "
					"batch_size=:batch_size, tun_volume=:tun_volume, tun_weight=:tun_weight, "
					"tun_specific_heat=:tun_specific_heat, tun_material=:tun_material, tun_height=:tun_height, "
					"top_up_water=:top_up_water, trub_chiller_loss=:chiller_loss, evap_rate=:evap_rate, "
					"boil_time=:boil_time, calc_boil_volume=:calcboil, top_up_kettle=:top_up_kettle, "
					"hop_utilization=:hopfactor, notes=:notes, lauter_volume=:lauter_volume, "
					"lauter_height=:lauter_height, lauter_deadspace=:lauter_deadspace, kettle_volume=:kettle_volume, "
					"kettle_height=:kettle_height, mash_volume=:mash_volume, mash_max=:mash_max, "
					"efficiency=:efficiency, uuid=:uuid");
			    query.bindValue(":name", eq->name);
			    query.bindValue(":boil_size", QString("%1").arg(eq->boil_size, 2, 'f', 1, '0'));
			    query.bindValue(":batch_size", QString("%1").arg(eq->batch_size, 3, 'f', 2, '0'));
			    query.bindValue(":tun_volume", QString("%1").arg(eq->tun_volume, 2, 'f', 1, '0'));
			    query.bindValue(":tun_weight", QString("%1").arg(eq->tun_weight, 2, 'f', 1, '0'));
			    query.bindValue(":tun_specific_heat", QString("%1").arg(eq->tun_specific_heat, 4, 'f', 3, '0'));
			    query.bindValue(":tun_material", eq->tun_material);
			    query.bindValue(":tun_height", QString("%1").arg(eq->tun_height, 4, 'f', 3, '0'));
			    query.bindValue(":top_up_water", QString("%1").arg(eq->top_up_water, 2, 'f', 1, '0'));
			    query.bindValue(":chiller_loss", QString("%1").arg(eq->trub_chiller_loss, 2, 'f', 1, '0'));
			    /* The evaporation in beerxml is percentage, but we use the real volume per hour */
			    query.bindValue(":evap_rate", QString("%1").arg((eq->evap_rate / 100) * eq->boil_size, 3, 'f', 2, '0'));
			    query.bindValue(":boil_time", QString("%1").arg(eq->boil_time, 1, 'f', 0, '0'));
			    query.bindValue(":calcboil", eq->calc_boil_volume ? 1:0);
			    query.bindValue(":top_up_kettle", QString("%1").arg(eq->top_up_kettle, 2, 'f', 1, '0'));
			    query.bindValue(":hopfactor", QString("%1").arg(eq->hop_utilization, 1, 'f', 0, '0'));
			    query.bindValue(":notes", eq->notes);
			    query.bindValue(":lauter_volume", QString("%1").arg(eq->lauter_volume, 2, 'f', 1, '0'));
			    query.bindValue(":lauter_height", QString("%1").arg(eq->lauter_height, 4, 'f', 3, '0'));
			    query.bindValue(":lauter_deadspace", QString("%1").arg(eq->lauter_deadspace, 2, 'f', 1, '0'));
			    query.bindValue(":kettle_volume", QString("%1").arg(eq->kettle_volume, 2, 'f', 1, '0'));
			    query.bindValue(":kettle_height", QString("%1").arg(eq->kettle_height, 4, 'f', 3, '0'));
			    query.bindValue(":mash_volume", QString("%1").arg(eq->mash_volume, 2, 'f', 1, '0'));
			    query.bindValue(":mash_max", QString("%1").arg(eq->mash_max, 2, 'f', 1, '0'));
			    query.bindValue(":efficiency", QString("%1").arg(eq->efficiency, 2, 'f', 1, '0'));
			    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
			    query.exec();
			    if (query.lastError().isValid()) {
				qWarning() << query.lastError();
				errors++;
			    }
			    ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
			    delete eq;
			    break;
		    	}
			if ((xml->tokenType() == QXmlStreamReader::StartElement) &&
			   ((xml->name() == "VERSION") || (xml->name() == "DISPLAY_BOIL_SIZE") ||
			    (xml->name() == "DISPLAY_BATCH_SIZE") || (xml->name() == "DISPLAY_TUN_VOLUME") ||
			    (xml->name() == "DISPLAY_TUN_WEIGHT") || (xml->name() == "DISPLAY_TRUB_CHILLER_LOSS") ||
			    (xml->name() == "DISPLAY_LAUTERDEADSPACE") || (xml->name() == "TUN_MATERIAL") ||
			    (xml->name() == "ATTENUATION_FACTOR_YEAST") || (xml->name() == "ATTENUATION_FACTOR_WATER_TO_GRAIN_RATIO") ||
			    (xml->name() == "ATTENUATION_FACTOR_TOTAL_MASH_TIME") || (xml->name() == "ATTENUATION_FACTOR_PERC_SIMPLE_SUGAR") ||
			    (xml->name() == "ATTENUATION_FACTOR_CONSTANT"))) {
			    // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
			    eq->name = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
			    eq->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BOIL_SIZE")) {
			    eq->boil_size = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BATCH_SIZE")) {
			    eq->batch_size = xml->readElementText().toDouble();
			    qDebug() << eq->batch_size;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TUN_VOLUME")) {
			    eq->tun_volume = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TUN_WEIGHT")) {
			    eq->tun_weight = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TUN_SPECIFIC_HEAT")) {
			    eq->tun_specific_heat = xml->readElementText().toDouble();
			    if (eq->tun_specific_heat == 0.22)
				eq->tun_material = 1;
			    else if (eq->tun_specific_heat == 0.46)
				eq->tun_material = 2;
			    else if (eq->tun_specific_heat == 0.092)
				eq->tun_material = 3;
			    else
				eq->tun_material = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TUN_HEIGHT")) {
			    eq->tun_height = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TRUB_CHILLER_LOSS")) {
			    eq->trub_chiller_loss = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "EVAP_RATE")) {
			    eq->evap_rate = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BOIL_TIME")) {
			    eq->boil_time = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CALC_BOIL_VOLUME")) {
			    eq->calc_boil_volume = (xml->readElementText() == "TRUE") ? true:false;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TOP_UP_KETTLE")) {
			    eq->top_up_kettle = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HOP_UTILIZATION")) {
			    eq->hop_utilization = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "LAUTER_VOLUME")) {
			    eq->lauter_volume = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "LAUTER_HEIGHT")) {
			    eq->lauter_height = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "LAUTER_DEADSPACE")) {
			    eq->lauter_deadspace = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "KETTLE_VOLUME")) {
			    eq->kettle_volume = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "KETTLE_HEIGHT")) {
			    eq->kettle_height = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MASH_VOLUME")) {
			    eq->mash_volume = xml->readElementText().toDouble();
			    eq->mash_max = eq->mash_volume / 3;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "EFFICIENCY")) {
			    eq->efficiency = xml->readElementText().toDouble();
			} else {
			    if (xml->tokenType() == QXmlStreamReader::StartElement)
			    	qDebug() << "2  " << xml->tokenType() << xml->name();
			}
		    }
		}
	    }
	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STYLES")) {
	    /*
             * Styles
             */
            while (xml->readNext()) {
	        if (xml->atEnd())
                    break;
                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "STYLES")) {
                    qDebug() << "0 /STYLES";
                    break;
                }
                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STYLE")) {
                    /*
                     * Style
                     */
		    Style *st = new Style();
		    st->notes = st->category = st->style_letter = st->profile = st->ingredients = st->examples = "";
		    st->style_guide = "BKG 2019";
                    total++;

		    while (xml->readNext()) {
                        if (xml->atEnd())
                            break;
                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "STYLE")) {
			    query.prepare("INSERT INTO profile_styles SET name=:name, category=:category, "
				"category_number=:catnr, style_letter=:group, style_guide=:guide, type=:type, "
				"og_min=:og_min, og_max=:og_max, fg_min=:fg_min, fg_max=:fg_max, ibu_min=:ibu_min, "
				"ibu_max=:ibu_max, color_min=:ebc_min, color_max=:ebc_max, carb_min=:co2_min, "
				"carb_max=:co2_max, abv_min=:abv_min, abv_max=:abv_max, notes=:notes, "
				"profile=:profile, ingredients=:ingredients, examples=:examples, uuid=:uuid");
			    query.bindValue(":name", st->name);
        		    query.bindValue(":category", st->category);
        		    query.bindValue(":catnr", st->category_number);
			    query.bindValue(":group", st->style_letter);
			    query.bindValue(":guide", st->style_guide);
			    query.bindValue(":type", st->type);
			    query.bindValue(":og_min", QString("%1").arg(st->og_min, 4, 'f', 3, '0'));
			    query.bindValue(":og_max", QString("%1").arg(st->og_max, 4, 'f', 3, '0'));
			    query.bindValue(":fg_min", QString("%1").arg(st->fg_min, 4, 'f', 3, '0'));
			    query.bindValue(":fg_max", QString("%1").arg(st->fg_max, 4, 'f', 3, '0'));
			    query.bindValue(":ibu_min", QString("%1").arg(st->ibu_min, 1, 'f', 0, '0'));
			    query.bindValue(":ibu_max", QString("%1").arg(st->ibu_max, 1, 'f', 0, '0'));
			    query.bindValue(":ebc_min", QString("%1").arg(st->color_min, 1, 'f', 0, '0'));
			    query.bindValue(":ebc_max", QString("%1").arg(st->color_max, 1, 'f', 0, '0'));
			    query.bindValue(":co2_min", QString("%1").arg(st->carb_min, 2, 'f', 1, '0'));
			    query.bindValue(":co2_max", QString("%1").arg(st->carb_max, 2, 'f', 1, '0'));
			    query.bindValue(":abv_min", QString("%1").arg(st->abv_min, 2, 'f', 1, '0'));
			    query.bindValue(":abv_max", QString("%1").arg(st->abv_max, 2, 'f', 1, '0'));
			    query.bindValue(":notes", st->notes);
			    query.bindValue(":profile", st->profile);
			    query.bindValue(":ingredients", st->ingredients);
			    query.bindValue(":examples", st->examples);
			    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
                            query.exec();
                            if (query.lastError().isValid()) {
                                qWarning() << query.lastError();
                                errors++;
                            }
                            ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
			    delete st;
                            break;
                        }
                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && ((xml->name() == "VERSION")) ||
			    (xml->name() == "DISPLAY_OG_MIN") || (xml->name() == "DISPLAY_OG_MAX") || (xml->name() == "DISPLAY_FG_MIN") ||
			    (xml->name() == "DISPLAY_FG_MAX") || (xml->name() == "DISPLAY_IBU_MIN") || (xml->name() == "DISPLAY_IBU_MAX") ||
			    (xml->name() == "DISPLAY_COLOR_MIN") || (xml->name() == "DISPLAY_COLOR_MAX") || (xml->name() == "DISPLAY_CARB_MIN") ||
			    (xml->name() == "DISPLAY_CARB_MAX") || (xml->name() == "DISPLAY_ABV_MIN") || (xml->name() == "DISPLAY_ABV_MAX") ||
			    (xml->name() == "OG_RANGE") || (xml->name() == "FG_RANGE") || (xml->name() == "IBU_RANGE") ||
			    (xml->name() == "CARB_RANGE") || (xml->name() == "COLOR_RANGE") || (xml->name() == "ABV_RANGE")) {
                            // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
			    st->name = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CATEGORY")) {
			    st->category = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CATEGORY_NUMBER")) {
			    st->category_number = xml->readElementText().toInt();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STYLE_LETTER")) {
			    st->style_letter = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STYLE_GUIDE")) {
			    st->style_guide = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
			    QString temp = xml->readElementText();
			    if (temp == "Lager")
				st->type = 0;
			    else if (temp == "Ale")
				st->type = 1;
			    else if (temp == "Mead")
				st->type = 2;
                            else if (temp == "Wheat")
				st->type = 3;
                            else if (temp == "Mixed")
				st->type = 4;
                            else if (temp == "Cider")
				st->type = 5;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
			    st->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "OG_MIN")) {
			    st->og_min = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "OG_MAX")) {
			    st->og_max = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FG_MIN")) {
			    st->fg_min = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FG_MAX")) {
			    st->fg_max = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "IBU_MIN")) {
			    st->ibu_min = xml->readElementText().toDouble();
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "IBU_MAX")) {
			    st->ibu_max = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COLOR_MIN")) {
			    st->color_min = xml->readElementText().toDouble();
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COLOR_MAX")) {
			    st->color_max = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CARB_MIN")) {
			    st->carb_min = xml->readElementText().toDouble();
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CARB_MAX")) {
			    st->carb_max = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ABV_MIN")) {
			    st->abv_min = xml->readElementText().toDouble();
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ABV_MAX")) {
			    st->abv_max = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "PROFILE")) {
			    st->profile = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "INGREDIENTS")) {
			    st->ingredients = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "EXAMPLES")) {
			    st->examples = xml->readElementText();
			} else {
                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                qDebug() << "2  " << xml->tokenType() << xml->name();
                        }
                    }
                }
            }
        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FERMENTABLES")) {
            /*
             * Fermentables
             */
            while (xml->readNext()) {
                if (xml->atEnd())
                    break;
                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "FERMENTABLES")) {
                    qDebug() << "0 /FERMENTABLES";
                    break;
                }
                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FERMENTABLE")) {
                    /*
                     * Fermentable
                     */
                    total++;
		    Fermentables *f = new Fermentables();
		    f->supplier = f->origin = f->notes = "";
		    f->yield = 80;
		    f->max_in_batch = 100;
		    f->recommend_mash = true;
		    f->di_ph = 5.7;

                    while (xml->readNext()) {
                        if (xml->atEnd())
                            break;
                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "FERMENTABLE")) {
			    query.prepare("INSERT INTO inventory_fermentables SET name=:name, type=:type, yield=:yield, color=:color, "
				"add_after_boil=:addafter, origin=:origin, supplier=:supplier, notes=:notes, coarse_fine_diff=:coarse, "
				"moisture=:moisture, diastatic_power=:diastatic, protein=:protein, dissolved_protein=:dissolved, "
				"max_in_batch=:maxinbatch, recommend_mash=:mash, added=:added, di_ph=:diph, "
				"acid_to_ph_57=:acidph, graintype=:graintype, uuid = :uuid");
			    query.bindValue(":name", f->name);
			    query.bindValue(":type", f->type);
			    query.bindValue(":yield", QString("%1").arg(f->yield, 2, 'f', 1, '0'));
			    query.bindValue(":color", QString("%1").arg(Utils::srm_to_ebc(f->color), 1, 'f', 0, '0'));
			    query.bindValue(":addafter", f->add_after_boil ? 1:0);
			    query.bindValue(":origin", f->origin);
			    query.bindValue(":supplier", f->supplier);
			    query.bindValue(":notes", f->notes);
			    query.bindValue(":coarse", QString("%1").arg(f->coarse_fine_diff, 4, 'f', 3, '0'));
			    query.bindValue(":moisture", QString("%1").arg(f->moisture, 4, 'f', 3, '0'));
			    query.bindValue(":diastatic", Utils::kolbach_to_lintner(f->diastatic_power));
			    query.bindValue(":protein", QString("%1").arg(f->protein, 4, 'f', 3, '0'));
			    query.bindValue(":dissolved", QString("%1").arg(f->dissolved_protein, 4, 'f', 3, '0'));
			    query.bindValue(":maxinbatch", QString("%1").arg(f->max_in_batch, 2, 'f', 1, '0'));
			    query.bindValue(":mash", f->recommend_mash ? 1:0);
			    query.bindValue(":added", f->added);
			    query.bindValue(":diph", QString("%1").arg(f->di_ph, 6, 'f', 5, '0'));
			    query.bindValue(":acidph", QString("%1").arg(f->acid_to_ph_57, 6, 'f', 5, '0'));
			    query.bindValue(":graintype", f->graintype);
			    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
                            query.exec();
                            if (query.lastError().isValid()) {
				qWarning() << query.lastError();
                                errors++;
                            }
                            ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
                            break;
                        }
                        if ((xml->tokenType() == QXmlStreamReader::StartElement) &&
			   ((xml->name() == "VERSION") || (xml->name() == "DISPLAY_COST") ||
			    (xml->name() == "DISPLAY_COLOR") || (xml->name() == "INVENTORY") ||
			    (xml->name() == "COST") || (xml->name() == "ALWAYS_ON_STOCK") ||
			    (xml->name() == "PERCENTAGE") || (xml->name() == "ADJUST_TO_TOTAL_100") )) {
                            // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
			    f->name = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
			    QString temp = xml->readElementText();
			    if (temp == "Sugar")
				f->type = 1;
			    else if (temp == "Extract")
				f->type = 2;
			    else if (temp == "Dry extract")
				f->type = 3;
			    else if (temp == "Adjunct")
				f->type = 4;
			    else
				f->type = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ORIGIN")) {
			    f->origin = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SUPPLIER")) {
			    f->supplier = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
			    f->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "YIELD")) {
			    f->yield = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COARSE_FINE_DIFF")) {
			    f->coarse_fine_diff = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MOISTURE")) {
			    f->moisture = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "DIASTATIC_POWER")) {
			    f->diastatic_power = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MAX_IN_BATCH")) {
			    f->max_in_batch = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "RECOMMEND_MASH")) {
			    f->recommend_mash = (xml->readElementText() == "TRUE") ? true:false;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "GRAINTYPE")) {
			    QString temp = xml->readElementText();
			    if (temp == "Roast")
				f->graintype = 1;
			    else if (temp == "Crystal")
				f->graintype = 2;
                            else if (temp == "Kilned")
				f->graintype = 3;
                            else if (temp == "Sour Malt")
				f->graintype = 4;
                            else if (temp == "Special")
				f->graintype = 5;
                            else if (temp == "No malt")
				f->graintype = 6;
			    else
				f->graintype = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ADDED")) {
                            QString temp = xml->readElementText();
			    if (temp == "Boil")
				f->added = 1;
                            else if (temp == "Fermentation")
				f->added = 2;
                            else if (temp == "Lagering")
				f->added = 3;
                            else if (temp == "Bottle")
				f->added = 4;
			    else
			        f->added = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ADD_AFTER_BOIL")) {
			    f->add_after_boil = (xml->readElementText() == "TRUE") ? true:false;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COLOR")) {
			    f->color = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "PROTEIN")) {
			    f->protein = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "DISSOLVED_PROTEIN")) {
			    f->dissolved_protein = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "DI_pH")) {
			    f->di_ph = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ACID_TO_pH_5.7")) {
			    f->acid_to_ph_57 = xml->readElementText().toDouble();
                        } else {
                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                qDebug() << "2  " << xml->tokenType() << xml->name();
                        }
                    }
                }
            }
        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HOPS")) {
            /*
             * Hops
             */
            while (xml->readNext()) {
                if (xml->atEnd())
                    break;
                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "HOPS")) {
                    qDebug() << "0 /HOPS";
                    break;
                }
                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HOP")) {
                    /*
                     * Hop
                     */
                    total++;
		    Hops *h = new Hops();
		    h->notes = h->origin = h->substitutes = "";
		    h->bu_factor = 1.0;
		    h->utilisation = my_ut_pellet;

                    while (xml->readNext()) {
                        if (xml->atEnd())
                            break;
                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "HOP")) {
			    query.prepare("INSERT INTO inventory_hops SET name=:name, alpha=:alpha, beta=:beta, "
				"humulene=:humulene, caryophyllene=:cary, cohumulone=:cohumulone, myrcene=:myrcene, "
				"hsi=:hsi, type=:type, form=:form, notes=:notes, origin=:origin, substitutes=:substitutes, "
				"total_oil=:oil, utilisation=:utilisation, bu_factor=:bu_factor, uuid = :uuid");
			    query.bindValue(":name", h->name);
			    query.bindValue(":alpha", QString("%1").arg(h->alpha, 2, 'f', 1, '0'));
			    query.bindValue(":beta", QString("%1").arg(h->beta, 2, 'f', 1, '0'));
			    query.bindValue(":humulene", QString("%1").arg(h->humulene, 2, 'f', 1, '0'));
			    query.bindValue(":cary", QString("%1").arg(h->caryophyllene, 2, 'f', 1, '0'));
			    query.bindValue(":cohumulone", QString("%1").arg(h->cohumulone, 2, 'f', 1, '0'));
			    query.bindValue(":myrcene", QString("%1").arg(h->myrcene, 2, 'f', 1, '0'));
			    query.bindValue(":hsi", QString("%1").arg(h->hsi, 2, 'f', 1, '0'));
			    query.bindValue(":type", h->type);
			    query.bindValue(":form", h->form);
			    query.bindValue(":notes", h->notes);
			    query.bindValue(":origin", h->origin);
			    query.bindValue(":substitutes", h->substitutes);
			    query.bindValue(":oil", QString("%1").arg(h->total_oil, 2, 'f', 1, '0'));
			    query.bindValue(":utilisation", QString("%1").arg(h->utilisation, 2, 'f', 1, '0'));
			    query.bindValue(":bu_factor", QString("%1").arg(h->bu_factor, 2, 'f', 1, '0'));
			    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
			    query.exec();
                            if (query.lastError().isValid()) {
				qWarning() << query.lastError();
                                errors++;
                            }
                            ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
                            break;
                        }
                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
			    (xml->name() == "VERSION") || (xml->name() == "ALWAYS_ON_STOCK") ||
			    (xml->name() == "HARVEST_DATE") || (xml->name() == "DISPLAY_COST") ||
			    (xml->name() == "COST") || (xml->name() == "INVENTORY"))) {
                            // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
			    h->name = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ORIGIN")) {
                            h->origin = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                            h->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) &&
					((xml->name() == "FORM") || (xml->name() == "BMS_FORM"))) {
                            QString temp = xml->readElementText();
                            if (temp == "Plug")
                                h->form = HOP_FORMS_PLUG;
                            else if (temp == "Leaf")
                                h->form = HOP_FORMS_LEAF;
                            else if (temp == "Leaf wet")
                                h->form = HOP_FORMS_LEAF_WET;
                            else if (temp == "Cryo")
                                h->form = HOP_FORMS_CRYO;
			    else if (temp == "CO2 extract")
				h->form = HOP_FORMS_CO2EXTRACT;
			    else if (temp == "Iso extract")
				h->form = HOP_FORMS_ISOEXTRACT;
                            else
                                h->form = HOP_FORMS_PELLET;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ALPHA")) {
			    h->alpha = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
                            QString temp = xml->readElementText();
			    if (temp == "Aroma")
				h->type = HOP_TYPE_AROMA;
			    else if (temp == "Both")
				h->type = HOP_TYPE_BOTH;
			    else
				h->type = HOP_TYPE_BITTERING;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "USE")) {
			    QString temp = xml->readElementText();
			    if (temp == "First wort")
				h->useat = HOP_USEAT_FWH;
			    else if (temp == "Boil")
				h->useat = HOP_USEAT_BOIL;
                            else if (temp == "Aroma")
				h->useat = HOP_USEAT_AROMA;
                            else if (temp == "Whirlpool")
				h->useat = HOP_USEAT_WHIRLPOOL;
                            else if (temp == "Dry hop")
				h->useat = HOP_USEAT_DRY_HOP;
			    else if (temp == "Bottling")
				h->useat = HOP_USEAT_BOTTLING;
			    else
				h->useat = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BETA")) {
                            h->beta = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HSI")) {
                            h->hsi = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SUBSTITUTES")) {
                            h->substitutes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HUMULENE")) {
                            h->humulene = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && 
			    ((xml->name() == "CARYOPHYLLENE") || (xml->name() == "CAROPHYLLENE"))) {
                            h->caryophyllene = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COHUMULONE")) {
                            h->cohumulone = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MYRCENE")) {
                            h->myrcene = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TOTAL_OIL")) {
                            h->total_oil = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BMS_UTILISATION")) {
                            h->utilisation = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BMS_UT_FACTOR")) {
                            h->bu_factor = xml->readElementText().toDouble();
                        } else {
                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                qDebug() << "2  " << xml->tokenType() << xml->name();
                        }
                    }
                }
            }
        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MISCS")) {
            /*
             * Miscs
             */
            while (xml->readNext()) {
                if (xml->atEnd())
                    break;
                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MISCS")) {
                    qDebug() << "0 /MISCS";
                    break;
                }
                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MISC")) {
                    /*
                     * Misc
                     */
                    total++;
		    Miscs *m = new Miscs();
		    m->name = m->use_for = m->notes = "";

                    while (xml->readNext()) {
                        if (xml->atEnd())
                            break;
                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MISC")) {
			    query.prepare("INSERT INTO inventory_miscs SET name=:name, type=:type, use_use=:use, "
					"time=:time, amount_is_weight=:isweight, use_for=:usefor, notes=:notes, "
					"uuid = :uuid");
			    query.bindValue(":name", m->name);
			    query.bindValue(":type", m->type);
			    query.bindValue(":use", m->use_use);
			    query.bindValue(":time", QString("%1").arg(m->time, 1, 'f', 0, '0'));
			    query.bindValue(":isweight", m->amount_is_weight ? 1:0);
			    query.bindValue(":usefor", m->use_for);
			    query.bindValue(":notes", m->notes);
			    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
                            query.exec();
                            if (query.lastError().isValid()) {
				qWarning() << query.lastError();
                                errors++;
                            }
                            ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
                            break;
                        }
                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
			    (xml->name() == "VERSION") || (xml->name() == "DISPLAY_AMOUNT") ||
			    (xml->name() == "AMOUNT") || (xml->name() == "ALWAYS_ON_STOCK") ||
			    (xml->name() == "COST") || (xml->name() == "DISPLAY_COST") ||
			    (xml->name() == "INVENTORY") || (xml->name() == "DISPLAY_TIME") ||
			    (xml->name() == "FREE_FIELD") || (xml->name() == "FREE_FIELD_NAME")
			    )) {
                            // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
			    m->name = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
			    m->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "USE_FOR")) {
                            m->use_for = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
			    QString temp = xml->readElementText();
			    if (temp == "Herb")
				m->type = 1;
			    else if (temp == "Flavor")
				m->type = 2;
                            else if (temp == "Fining")
				m->type = 3;
                            else if (temp == "Water agent")
				m->type = 4;
                            else if (temp == "Yeast nutrient")
				m->type = 5;
                            else if (temp == "Other")
				m->type = 6;
                            else
				m->type = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "USE")) {
                            QString temp = xml->readElementText();
                            if (temp == "Mash")
				m->use_use = 1;
			    else if (temp == "Boil")
				m->use_use = 2;
                            else if (temp == "Primary")
				m->use_use = 3;
                            else if (temp == "Secondary")
				m->use_use = 4;
                            else if (temp == "Bottling")
				m->use_use = 5;
                            else
				m->use_use = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "AMOUNT_IS_WEIGHT")) {
                            m->amount_is_weight = (xml->readElementText() == "TRUE") ? true:false;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TIME")) {
                            m->time = xml->readElementText().toDouble();
                        } else {
                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                qDebug() << "2  " << xml->tokenType() << xml->name();
                        }
                    }
                }
            }
        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "YEASTS")) {
            /*
             * Yeasts
             */
            while (xml->readNext()) {
                if (xml->atEnd())
                    break;
                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "YEASTS")) {
                    qDebug() << "0 /YEASTS";
                    break;
                }
                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "YEAST")) {
                    /*
                     * Yeast
                     */
                    total++;
		    Yeasts *y = new Yeasts();
		    y->laboratory = y->product_id = y->best_for = y->notes = y->short_desc = "";
		    y->max_reuse = 10;
		    y->min_temperature = 18;
		    y->max_temperature = 22;
		    y->attenuation = 77;

                    while (xml->readNext()) {
                        if (xml->atEnd())
                            break;
                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "YEAST")) {
			    query.prepare("INSERT INTO inventory_yeasts SET name=:name, type=:type, form=:form, "
				"laboratory=:laboratory, product_id=:productid, min_temperature=:templo, max_temperature=:temphi, "
				"flocculation=:floc, attenuation=:att, notes=:notes, best_for=:bestfor, "
				"max_reuse=:reuse, short_desc='', uuid = :uuid");
			    query.bindValue(":name", y->name);
			    query.bindValue(":type", y->type);
			    query.bindValue(":form", y->form);
			    query.bindValue(":laboratory", y->laboratory);
			    query.bindValue(":productid", y->product_id);
			    query.bindValue(":templo", QString("%1").arg(y->min_temperature, 2, 'f', 1, '0'));
			    query.bindValue(":temphi", QString("%1").arg(y->max_temperature, 2, 'f', 1, '0'));
			    query.bindValue(":floc", y->flocculation);
			    query.bindValue(":att", QString("%1").arg(y->attenuation, 2, 'f', 1, '0'));
			    query.bindValue(":notes", y->notes);
			    query.bindValue(":bestfor", y->best_for);
			    query.bindValue(":reuse", y->max_reuse);
			    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
			    query.exec();
                            if (query.lastError().isValid()) {
				qWarning() << query.lastError();
                                errors++;
                            }
                            ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
                            break;
                        }
                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
			    (xml->name() == "VERSION") || (xml->name() == "TIMES_CULTURED") ||
			    (xml->name() == "DISP_MIN_TEMP") || (xml->name() == "DISP_MAX_TEMP") ||
			    (xml->name() == "CULTURE_DATE") || (xml->name() == "STARTER_TYPE") ||
			    (xml->name() == "STARTER_MADE") || (xml->name() == "STARTER_VOLUME") ||
			    (xml->name() == "OG_STARTER") || (xml->name() == "TIME_AERATED") ||
			    (xml->name() == "ZINC_ADDED") || (xml->name() == "AMOUNT_ZINC") ||
			    (xml->name() == "AMOUNT_EXTRACT") || (xml->name() == "COST_EXTRACT") ||
			    (xml->name() == "ALWAYS_ON_STOCK") || (xml->name() == "DISPLAY_AMOUNT") ||
			    (xml->name() == "AMOUNT") || (xml->name() == "DISPLAY_AMOUNT") ||
			    (xml->name() == "AMOUNT_IS_WEIGHT") || (xml->name() == "ADD_TO_SECONDARY") ||
			    (xml->name() == "COST") || (xml->name() == "DISPLAY_COST") ||
			    (xml->name() == "TEMP") || (xml->name() == "INVENTORY"))) {
                            // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
			    y->name = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "LABORATORY")) {
                            y->laboratory = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "PRODUCT_ID")) {
                            y->product_id = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                            y->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BEST_FOR")) {
                            y->best_for = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
                            QString temp = xml->readElementText();
			    if (temp == "Ale")
				y->type = 1;
			    else if (temp == "Wheat")
				y->type = 2;
                            else if (temp == "Wine")
				y->type = 3;
                            else if (temp == "Champagne")
				y->type = 4;
                            else if (temp == "Brett")
				y->type = 5;
                            else if (temp == "Kveik")
				y->type = 6;
                            else if (temp == "Hybrid")
				y->type = 7;
			    else
				y->type = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FORM")) {
                            QString temp = xml->readElementText();
                            if (temp == "Dry")
                                y->form = 1;
			    else if (temp == "Slant")
				y->form = 2;
                            else if (temp == "Culture")
				y->form = 3;
                            else if (temp == "Frozen")
				y->form = 4;
                            else if (temp == "Bottle")
				y->form = 5;
                            else if (temp == "Dried")
				y->form = 6;
			    else
				y->form = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FLOCCULATION")) {
                            QString temp = xml->readElementText();
                            if (temp == "Medium")
                                y->flocculation = 1;
			    else if (temp == "High")
	    			y->flocculation = 1;
                            else if (temp == "Very high")
				y->flocculation = 3;
			    else
				y->flocculation = 0;			    
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MIN_TEMPERATURE")) {
			    y->min_temperature = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MAX_TEMPERATURE")) {
                            y->max_temperature = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ATTENUATION")) {
                            y->attenuation = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MAX_REUSE")) {
			    y->max_reuse = xml->readElementText().toInt();
                        } else {
                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                qDebug() << "2  " << xml->tokenType() << xml->name();
                        }
                    }
                }
            }
        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "WATERS")) {
            /*
             * Waters
             */
            while (xml->readNext()) {
                if (xml->atEnd())
                    break;
                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "WATERS")) {
                    qDebug() << "0 /WATERS";
                    break;
                }
                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "WATER")) {
                    /*
                     * Water
                     */
                    total++;
		    Waters *w = new Waters();
		    w->notes = "";
		    w->ph = 7.0;

                    while (xml->readNext()) {
                        if (xml->atEnd())
                            break;
                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "WATER")) {
			    query.prepare("INSERT INTO inventory_waters SET name=:name, unlimited_stock=:unlimited, calcium=:ca, "
				"bicarbonate=:hco, sulfate=:so4, chloride=:cl, sodium=:na, magnesium=:mg, ph=:ph, notes=:notes, "
				"total_alkalinity=:alkalinity, nitrate=:no, uuid = :uuid");
			    query.bindValue(":name", w->name);
			    query.bindValue(":unlimited", w->unlimited_stock ? 1:0);
			    query.bindValue(":ca", QString("%1").arg(w->calcium, 4, 'f', 3, '0'));
			    query.bindValue(":hco", QString("%1").arg(w->bicarbonate, 4, 'f', 3, '0'));
			    query.bindValue(":so4", QString("%1").arg(w->sulfate, 4, 'f', 3, '0'));
			    query.bindValue(":cl", QString("%1").arg(w->chloride, 4, 'f', 3, '0'));
			    query.bindValue(":na", QString("%1").arg(w->sodium, 4, 'f', 3, '0'));
			    query.bindValue(":mg", QString("%1").arg(w->magnesium, 4, 'f', 3, '0'));
			    query.bindValue(":ph", QString("%1").arg(w->ph, 4, 'f', 3, '0'));
			    query.bindValue(":notes", w->notes);
			    query.bindValue(":alkalinity", QString("%1").arg(w->total_alkalinity, 4, 'f', 3, '0'));
			    query.bindValue(":no", QString("%1").arg(w->nitrate, 4, 'f', 3, '0'));
			    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
			    query.exec();
                            if (query.lastError().isValid()) {
				qWarning() << query.lastError();
                                errors++;
                            }
                            ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
                            break;
                        }
                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
			    (xml->name() == "VERSION") || (xml->name() == "DEFAULT_WATER") ||
			    (xml->name() == "ALWAYS_ON_STOCK") || (xml->name() == "AMOUNT") ||
			    (xml->name() == "DISPLAY_AMOUNT"))) {
                            // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
                            w->name = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                            w->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "xUNLIMITED_STOCK")) {
                            w->unlimited_stock = (xml->readElementText() == "TRUE") ? true:false;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CALCIUM")) {
                            w->calcium = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BICARBONATE")) {
                            w->bicarbonate = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TOTAL_ALKALINITY")) {
                            w->total_alkalinity = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SULFATE")) {
                            w->sulfate = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CHLORIDE")) {
                            w->chloride = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SODIUM")) {
                            w->sodium = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MAGNESIUM")) {
                            w->magnesium = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "PH")) {
                            w->ph = xml->readElementText().toDouble();
                        } else {
                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                qDebug() << "2  " << xml->tokenType() << xml->name();
                        }
                    }
                }
            }
        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "RECIPES")) {
            /*
             * Recipes
             */
            while (xml->readNext()) {
                if (xml->atEnd())
                    break;
                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "RECIPES")) {
                    qDebug() << "0 /RECIPES";
                    break;
                }
                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "RECIPE")) {
                    /*
                     * Recipe
                     */
                    total++;
		    Recipe *r = new Recipe();
		    r->record = -1;
		    r->notes = r->st_guide = r->st_name = r->st_letter = r->st_category = "";
		    r->w1_name = r->w2_name = "";
		    r->w1_ph = r->w2_ph = r->wg_ph = r->wb_ph = 7;
		    r->mash_name = "";

                    while (xml->readNext()) {
                        if (xml->atEnd())
                            break;
                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "RECIPE")) {
			    qDebug() << "recipe:" << r->name;
			    for (int i = 0; i < r->fermentables.size(); i++)
                                qDebug() << " fermentable" << i << r->fermentables.at(i).name;
			    for (int i = 0; i < r->hops.size(); i++)
				qDebug() << "         hop" << i << r->hops.at(i).name;
			    for (int i = 0; i < r->miscs.size(); i++)
                                qDebug() << "        misc" << i << r->miscs.at(i).name;
			    for (int i = 0; i < r->yeasts.size(); i++)
                                qDebug() << "       yeast" << i << r->yeasts.at(i).name;
			    for (int i = 0; i < r->mashs.size(); i++)
                                qDebug() << "   mash step" << i << r->mashs.at(i).step_name;
			    qDebug() << "       water" << 0 << r->w1_name << r->w1_amount;
			    qDebug() << "       water" << 1 << r->w2_name << r->w2_amount;
			    if (DB_recipe::save(r, this)) {
				qInfo() << "Inserted recipe" << r->name;
			    } else {
                                errors++;
                            }
			    delete r;
                            ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
                            break;
                        }
                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
			    (xml->name() == "VERSION") || (xml->name() == "AUTONR") ||
			    (xml->name() == "FORCED_CARBONATION") || (xml->name() == "DISPLAY_BATCH_SIZE") ||
			    (xml->name() == "DISPLAY_BOIL_SIZE") || (xml->name() == "SPARGE_WATER_COMP") ||
			    (xml->name() == "OG_BEFORE_BOIL") || (xml->name() == "SG_END_PRIMARY") ||
			    (xml->name() == "FORCED_CARB_KEGS") || (xml->name() == "COOLING_METHOD") ||
			    (xml->name() == "INVENTORY_REDUCED") || (xml->name() == "LOCKED") ||
			    (xml->name() == "PRIMING_SUGAR_BOTTLES") || (xml->name() == "PRIMING_SUGAR_KEGS") ||
			    (xml->name() == "NR_RECIPE") || (xml->name() == "LACTIC_SPARGE") ||
			    (xml->name() == "TARGET_PH") || (xml->name() == "SG_END_MASH") ||
			    (xml->name() == "VOLUME_HLT") || (xml->name() == "OG_FERMENTER") ||
			    (xml->name() == "COOLING_TO") || (xml->name() == "AERATION_TYPE") ||
			    (xml->name() == "BATCH_DIVIDED") || (xml->name() == "BATCH_DIVISION") ||
			    (xml->name() == "DIVIDED_FROM") || (xml->name() == "PARENT") ||
			    (xml->name() == "FERMENTATION_STAGES") || (xml->name() == "DATE") ||
			    (xml->name() == "CALC_ACID") || (xml->name() == "BREWER")
			    )) {
                            // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
                            r->name = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                            r->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BATCH_SIZE")) {
                            r->batch_size = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BOIL_SIZE")) {
                            r->boil_size = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BOIL_TIME")) {
                            r->boil_time = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "EFFICIENCY")) {
                            r->efficiency = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && ((xml->name() == "OG") || (xml->name() == "EST_OG"))) {
                            r->est_og = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && ((xml->name() == "FG") || (xml->name() == "EST_FG"))) {
                            r->est_fg = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && ((xml->name() == "ABV") || (xml->name() == "EST_ABV"))) {
                            r->est_abv = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && ((xml->name() == "IBU") || (xml->name() == "EST_IBU"))) {
                            r->est_ibu = xml->readElementText().toDouble();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "EST_COLOR")) {
                            r->est_color = Utils::srm_to_ebc(xml->readElementText().toDouble());
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ACID_SPARGE_PERC")) {
                            r->sparge_acid_perc = Utils::srm_to_ebc(xml->readElementText().toDouble());
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SPARGE_ACID_TYPE")) {
			    QString temp = xml->readElementText();
			    if (temp == "Hydrochloric")
				r->sparge_acid_type = 1;
			    else if (temp == "Phosphoric")
				r->sparge_acid_type = 2;
			    else if (temp == "Sulfuric")
				r->sparge_acid_type = 3;
			    else
				r->sparge_acid_type = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
			    QString temp = xml->readElementText();
			    if (temp == "Extract")
				r->type = 0;
			    else if (temp == "Partial Mash")
				r->type = 1;
			    else
				r->type = 2;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "IBU_METHOD")) {
			    QString temp = xml->readElementText();
			    /* For the known beerXML names, select Tinseth */
			    r->ibu_method = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COLOR_METHOD")) {
			    QString temp = xml->readElementText();
			    if (temp == "Mosher")
				r->color_method = 1;
			    else if (temp == "Daniels")
				r->color_method = 2;
			    else if (temp == "Halberstadt")
				r->color_method = 3;
			    else if (temp == "Naudts")
				r->color_method = 4;
			    else
				r->color_method = 0;
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STYLE")) {
                            while (xml->readNext()) {
                                if (xml->atEnd())
                                    break;
                                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "STYLE")) {
                                    break;
                                }
                                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
				    (xml->name() == "VERSION") || (xml->name() == "NOTES") ||
				    (xml->name() == "PROFILE") || (xml->name() == "EXAMPLES") ||
				    (xml->name() == "DISPLAY_OG_MIN") || (xml->name() == "DISPLAY_OG_MAX") ||
				    (xml->name() == "DISPLAY_FG_MIN") || (xml->name() == "DISPLAY_FG_MAX") ||
				    (xml->name() == "DISPLAY_IBU_MIN") || (xml->name() == "DISPLAY_IBU_MAX") ||
                            	    (xml->name() == "DISPLAY_COLOR_MIN") || (xml->name() == "DISPLAY_COLOR_MAX") ||
				    (xml->name() == "DISPLAY_CARB_MIN") || (xml->name() == "DISPLAY_CARB_MAX") ||
				    (xml->name() == "DISPLAY_ABV_MIN") || (xml->name() == "DISPLAY_ABV_MAX") ||
                            	    (xml->name() == "OG_RANGE") || (xml->name() == "FG_RANGE") ||
				    (xml->name() == "IBU_RANGE") || (xml->name() == "CARB_RANGE") ||
				    (xml->name() == "COLOR_RANGE") || (xml->name() == "ABV_RANGE"))) {
                                    // Ignore.
                                } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
                                    r->st_name = xml->readElementText();
				} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CATEGORY")) {
                        	    r->st_category = xml->readElementText();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CATEGORY_NUMBER")) {
                        	    r->st_category_number = xml->readElementText().toInt();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STYLE_LETTER")) {
                        	    r->st_letter = xml->readElementText();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STYLE_GUIDE")) {
                        	    r->st_guide = xml->readElementText();
				} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
                        	    QString temp = xml->readElementText();
                        	    if (temp == "Lager")
                        	        r->st_type = 0;
                        	    else if (temp == "Ale")
                        	        r->st_type = 1;
                        	    else if (temp == "Mead")
                        	        r->st_type = 2;
                        	    else if (temp == "Wheat")
                        	        r->st_type = 3;
                        	    else if (temp == "Mixed")
                        	        r->st_type = 4;
                        	    else if (temp == "Cider")
                        	        r->st_type = 5;
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "OG_MIN")) {
                        	    r->st_og_min = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "OG_MAX")) {
                        	    r->st_og_max = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FG_MIN")) {
                        	    r->st_fg_min = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FG_MAX")) {
                        	    r->st_fg_max = xml->readElementText().toDouble();
				} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "IBU_MIN")) {
                        	    r->st_ibu_min = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "IBU_MAX")) {
                        	    r->st_ibu_max = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COLOR_MIN")) {
                        	    r->st_color_min = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COLOR_MAX")) {
                        	    r->st_color_max = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CARB_MIN")) {
                        	    r->st_carb_min = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CARB_MAX")) {
                        	    r->st_carb_max = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ABV_MIN")) {
                        	    r->st_abv_min = xml->readElementText().toDouble();
                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ABV_MAX")) {
                        	    r->st_abv_max = xml->readElementText().toDouble();
				} else {
                                    if (xml->tokenType() == QXmlStreamReader::StartElement)
                                        qDebug() << xml->tokenType() << " STYLE->" << xml->name();
                                }
                            }
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "EQUIPMENT")) {
                            while (xml->readNext()) {
                                if (xml->atEnd())
                                    break;
                                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "EQUIPMENT")) {
                                    break;
                                }
                                /*
				 * Ignore everything about equipment. Not usefull in a recipe, all calculations should
				 * be done after import.
				 */
                            }

			/*
			 * Ingredients
			 */
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HOPS")) {
                            while (xml->readNext()) {
                                if (xml->atEnd())
                                    break;
                                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "HOPS")) {
                                    break;
                                }
                                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HOP")) {
                                    /*
                                     * Process hop
                                     */
				    Hops *newh = new Hops();
				    newh->utilisation = my_ut_pellet;
				    newh->bu_factor = 1.0;
                                    while (xml->readNext()) {
                                        if (xml->atEnd())
                                            break;
                                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "HOP")) {
					    r->hops.append(*newh);
					    delete newh;
                                            break;
                                        }
                                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
                                            newh->name = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ORIGIN")) {
                        		    newh->origin = xml->readElementText();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                        		    newh->notes = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TIME")) {
                                            newh->time = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "AMOUNT")) {
                                            newh->amount = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) &&
							((xml->name() == "FORM") || (xml->name() == "BMS_FORM"))) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Plug")
                        		        newh->form = HOP_FORMS_PLUG;
                        		    else if (temp == "Leaf")
                        		        newh->form = HOP_FORMS_LEAF;
                        		    else if (temp == "Leaf wet")
                        		        newh->form = HOP_FORMS_LEAF_WET;
                        		    else if (temp == "Cryo")
                        		        newh->form = HOP_FORMS_CRYO;
					    else if (temp == "CO2 extract")
						newh->form = HOP_FORMS_CO2EXTRACT;
					    else if (temp == "Iso extract")
						newh->form = HOP_FORMS_ISOEXTRACT;
                        		    else
                        		        newh->form = HOP_FORMS_PELLET;
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ALPHA")) {
                        		    newh->alpha = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Aroma")
                        		        newh->type = HOP_TYPE_AROMA;
                        		    else if (temp == "Both")
                        		        newh->type = HOP_TYPE_BOTH;
                        		    else
                        		        newh->type = HOP_TYPE_BITTERING;
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "USE")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "First wort")
                        		        newh->useat = HOP_USEAT_FWH;
                        		    else if (temp == "Boil")
                        		        newh->useat = HOP_USEAT_BOIL;
                        		    else if (temp == "Aroma")
                        		        newh->useat = HOP_USEAT_AROMA;
                        		    else if (temp == "Whirlpool")
                        		        newh->useat = HOP_USEAT_WHIRLPOOL;
                        		    else if (temp == "Dry hop")
                        		        newh->useat = HOP_USEAT_DRY_HOP;
					    else if (temp == "Bottling")
						newh->useat = HOP_USEAT_BOTTLING;
                        		    else
                        		        newh->useat = HOP_USEAT_MASH;
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BETA")) {
                        		    newh->beta = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HSI")) {
                        		    newh->hsi = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SUBSTITUTES")) {
                        		    newh->substitutes = xml->readElementText();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "HUMULENE")) {
                        		    newh->humulene = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) &&
                        		    ((xml->name() == "CARYOPHYLLENE") || (xml->name() == "CAROPHYLLENE"))) {
                        		    newh->caryophyllene = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COHUMULONE")) {
                        		    newh->cohumulone = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MYRCENE")) {
                        		    newh->myrcene = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TOTAL_OIL")) {
                        		    newh->total_oil = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BMS_UTILISATION")) {
                                            newh->utilisation = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BMS_UT_FACTOR")) {
                                            newh->bu_factor = xml->readElementText().toDouble();
					}
                                    }
                                }
                            }
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FERMENTABLES")) {
                            while (xml->readNext()) {
                                if (xml->atEnd())
                                    break;
                                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "FERMENTABLES")) {
                                    break;
                                }
                                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FERMENTABLE")) {
                                    /*
                                     * Process fermentable
                                     */
				    Fermentables *f = new Fermentables();
                                    while (xml->readNext()) {
                                        if (xml->atEnd())
                                            break;
                                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "FERMENTABLE")) {
					    r->fermentables.append(*f);
					    delete f;
                                            break;
                                        }
                                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
                                            (xml->name() == "VERSION") || (xml->name() == "DISPLAY_STEP_TEMP") ||
					    (xml->name() == "DISPLAY_AMOUNT") || (xml->name() == "COST") ||
					    (xml->name() == "DISPLAY_COST") || (xml->name() == "INVENTORY") ||
					    (xml->name() == "ALWAYS_ON_STOCK") || (xml->name() == "DISPLAY_COLOR") ||
					    (xml->name() == "PERCENTAGE") || (xml->name() == "ADJUST_TO_TOTAL_100"))) {
                                            // Ignore.
                                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
					    f->name = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Sugar")
                        		        f->type = 1;
                        		    else if (temp == "Extract")
                        		        f->type = 2;
                        		    else if (temp == "Dry extract")
                        		        f->type = 3;
                        		    else if (temp == "Adjunct")
                        		        f->type = 4;
                        		    else
                        		        f->type = 0;
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ORIGIN")) {
                        		    f->origin = xml->readElementText();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SUPPLIER")) {
                        		    f->supplier = xml->readElementText();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                        		    f->notes = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "AMOUNT")) {
                                            f->amount = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "YIELD")) {
                        		    f->yield = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COARSE_FINE_DIFF")) {
                        		    f->coarse_fine_diff = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MOISTURE")) {
                        		    f->moisture = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "DIASTATIC_POWER")) {
                        		    f->diastatic_power = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MAX_IN_BATCH")) {
                        		    f->max_in_batch = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "RECOMMEND_MASH")) {
                        		    f->recommend_mash = (xml->readElementText() == "TRUE") ? true:false;
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "GRAINTYPE")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Roast")
                        		        f->graintype = 1;
                        		    else if (temp == "Crystal")
                        		        f->graintype = 2;
                        		    else if (temp == "Kilned")
                        		        f->graintype = 3;
                        		    else if (temp == "Sour Malt")
                        		        f->graintype = 4;
                        		    else if (temp == "Special")
                        		        f->graintype = 5;
                        		    else if (temp == "No malt")
                        		        f->graintype = 6;
                        		    else
                        		        f->graintype = 0;
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ADDED")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Boil")
                        		        f->added = 1;
                        		    else if (temp == "Fermentation")
                        		        f->added = 2;
                        		    else if (temp == "Lagering")
                        		        f->added = 3;
                        		    else if (temp == "Bottle")
                        		        f->added = 4;
                        		    else
                        		        f->added = 0;
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ADD_AFTER_BOIL")) {
                        		    f->add_after_boil = (xml->readElementText() == "TRUE") ? true:false;
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "COLOR")) {
                        		    f->color = Utils::srm_to_ebc(xml->readElementText().toDouble());
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "PROTEIN")) {
                        		    f->protein = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "DISSOLVED_PROTEIN")) {
                        		    f->dissolved_protein = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "DI_pH")) {
                        		    f->di_ph = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ACID_TO_pH_5.7")) {
                        		    f->acid_to_ph_57 = xml->readElementText().toDouble();
                                        } else {
                                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                                qDebug() << xml->tokenType() << "FERMENTABLE->" << xml->name();
                                        }
                                    }
                                }
                            }
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MISCS")) {
                            while (xml->readNext()) {
                                if (xml->atEnd())
                                    break;
                                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MISCS")) {
                                    break;
                                }
                                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MISC")) {
                                    /*
                                     * Process misc
                                     */
				    Miscs *m = new Miscs();
                                    while (xml->readNext()) {
                                        if (xml->atEnd())
                                            break;
                                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MISC")) {
					    r->miscs.append(*m);
					    delete m;
                                            break;
                                        }
                                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
                                            (xml->name() == "VERSION") || (xml->name() == "DISPLAY_AMOUNT") ||
					    (xml->name() == "FREE_FIELD") || (xml->name() == "FREE_FIELD_NAME") ||
					    (xml->name() == "COST") || (xml->name() == "INVENTORY") ||
					    (xml->name() == "DISPLAY_COST") ||
					    (xml->name() == "ALWAYS_ON_STOCK") || (xml->name() == "DISPLAY_TIME"))) {
                                            // Ignore.
                                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
					    m->name = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                        		    m->notes = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "AMOUNT")) {
					    m->amount = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "USE_FOR")) {
                        		    m->use_for = xml->readElementText();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Herb")
                        		        m->type = 1;
                        		    else if (temp == "Flavor")
                        		        m->type = 2;
                        		    else if (temp == "Fining")
                        		        m->type = 3;
                        		    else if (temp == "Water agent")
                        		        m->type = 4;
                        		    else if (temp == "Yeast nutrient")
                        		        m->type = 5;
                        		    else if (temp == "Other")
                        		        m->type = 6;
                        		    else
                        		        m->type = 0;
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "USE")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Mash")
                        		        m->use_use = 1;
                        		    else if (temp == "Boil")
                        		        m->use_use = 2;
                        		    else if (temp == "Primary")
                        		        m->use_use = 3;
                        		    else if (temp == "Secondary")
                        		        m->use_use = 4;
                        		    else if (temp == "Bottling")
                        		        m->use_use = 5;
                        		    else
                        		        m->use_use = 0;
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "AMOUNT_IS_WEIGHT")) {
                        		    m->amount_is_weight = (xml->readElementText() == "TRUE") ? true:false;
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TIME")) {
                        		    m->time = xml->readElementText().toDouble();
                                        } else {
                                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                                qDebug() << xml->tokenType() << " MISC->" << xml->name();
                                        }
                                    }
                                }
                            }
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "YEASTS")) {
                            while (xml->readNext()) {
                                if (xml->atEnd())
                                    break;
                                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "YEASTS")) {
                                    break;
                                }
                                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "YEAST")) {
                                    /*
                                     * Process yeast
                                     */
				    Yeasts *y = new Yeasts();
                                    while (xml->readNext()) {
                                        if (xml->atEnd())
                                            break;
                                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "YEAST")) {
					    r->yeasts.append(*y);
					    delete y;
                                            break;
                                        }
                                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
					    y->name = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "LABORATORY")) {
                        		    y->laboratory = xml->readElementText();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "PRODUCT_ID")) {
                        		    y->product_id = xml->readElementText();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                        		    y->notes = xml->readElementText();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BEST_FOR")) {
                        		    y->best_for = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "AMOUNT")) {
                                            y->amount = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Ale")
                        		        y->type = 1;
                        		    else if (temp == "Wheat")
                        		        y->type = 2;
                        		    else if (temp == "Wine")
                        	        	y->type = 3;
                       			    else if (temp == "Champagne")
                       		        	y->type = 4;
                       			    else if (temp == "Brett")
                        		        y->type = 5;
                        		    else if (temp == "Kveik")
                        		        y->type = 6;
                        		    else if (temp == "Hybrid")
                        		        y->type = 7;
                        		    else
                        		        y->type = 0;
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FORM")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Dry")
                        		        y->form = 1;
                        		    else if (temp == "Slant")
                        		        y->form = 2;
                        		    else if (temp == "Culture")
                        		        y->form = 3;
                        		    else if (temp == "Frozen")
                        		        y->form = 4;
                        		    else if (temp == "Bottle")
                        		        y->form = 5;
                        		    else if (temp == "Dried")
                        		        y->form = 6;
                        		    else
                        		        y->form = 0;
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "FLOCCULATION")) {
                        		    QString temp = xml->readElementText();
                        		    if (temp == "Medium")
                        		        y->flocculation = 1;
                        		    else if (temp == "High")
                        		        y->flocculation = 1;
                        		    else if (temp == "Very high")
                        		        y->flocculation = 3;
                        		    else
                        		        y->flocculation = 0;
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MIN_TEMPERATURE")) {
                        		    y->min_temperature = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MAX_TEMPERATURE")) {
                        		    y->max_temperature = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "ATTENUATION")) {
                        		    y->attenuation = xml->readElementText().toDouble();
                        		} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MAX_REUSE")) {
                        		    y->max_reuse = xml->readElementText().toInt();
                                        }
                                    }
                                }
                            }
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MASH")) {
                            while (xml->readNext()) {
                                if (xml->atEnd())
                                    break;
                                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MASH")) {
                                    break;
                                }
                                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
                                    (xml->name() == "VERSION") || (xml->name() == "NOTES") ||
				    (xml->name() == "GRAIN_TEMP") || (xml->name() == "TUN_TEMP") ||
				    (xml->name() == "SG_LAST_RUNNINGS") || (xml->name() == "PH_LAST_RUNNINGS") ||
				    (xml->name() == "TUN_WEIGHT") || (xml->name() == "TUN_SPECIFIC_HEAT") ||
				    (xml->name() == "EQUIP_ADJUST"))) {
                                    // Ignore.
				} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
                                    r->mash_name = xml->readElementText();
                                } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "PH")) {
                                    r->mash_ph = xml->readElementText().toDouble();
				} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SPARGE_TEMP")) {
                                    r->sparge_temp = xml->readElementText().toDouble();
				} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MASH_STEPS")) {
                            	    while (xml->readNext()) {
                                	if (xml->atEnd())
                                	    break;
                                	if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MASH_STEPS")) {
                                	    break;
                                    	}
                                	if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MASH_STEP")) {
                                	    /*
                                	     * Process mash step
                                	     */
					    MashSteps *ms = new MashSteps();
                                	    while (xml->readNext()) {
                                	        if (xml->atEnd())
                                	            break;
                                	        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MASH_STEP")) {
						    r->mashs.append(*ms);
						    delete ms;
                                	            break;
                                	        }
                                	        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
                                	            (xml->name() == "VERSION") || (xml->name() == "DISPLAY_STEP_TEMP") ||
						    (xml->name() == "PH") || (xml->name() == "WATER_GRAIN_RATIO") ||
                                            	    (xml->name() == "DECOCTION_AMT") || (xml->name() == "INFUSE_TEMP") ||
                                            	    (xml->name() == "INFUSE_AMOUNT") || (xml->name() == "DISPLAY_INFUSE_AMT")
						    )) {
                                	            // Ignore.
                                	        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
						    ms->step_name = xml->readElementText();
						} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
                                            	    QString temp = xml->readElementText();
                                        	    if (temp == "Infusion")
							ms->step_type = 0;
                                        	    else if (temp == "Temperature")
							ms->step_type = 1;
                                       	 	    else if (temp == "Decoction")
							ms->step_type = 2;
						} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STEP_TEMP")) {
                                        	    ms->step_temp = xml->readElementText().toDouble();
                                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "END_TEMP")) {
                                        	    ms->end_temp = xml->readElementText().toDouble();
                                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STEP_TIME")) {
                                        	    ms->step_time = xml->readElementText().toDouble();
                                        	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "RAMP_TIME")) {
                                        	    ms->ramp_time = xml->readElementText().toDouble();
                                	        } else {
                                	            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                	                qDebug() << xml->tokenType() << "  MASH_STEP->" << xml->name();
                                	        }
                                	    }
                                	}
                            	    }
                                } else {
                                    if (xml->tokenType() == QXmlStreamReader::StartElement)
                                        qDebug() << xml->tokenType() << " MASH->" << xml->name();
                                }
                            }
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "WATERS")) {
			    int	waterno = 0;
                            while (xml->readNext()) {
                                if (xml->atEnd())
                                    break;
                                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "WATERS")) {
                                    break;
                                }
                                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "WATER")) {
                                    /*
                                     * Process water
                                     */
                                    while (xml->readNext()) {
                                        if (xml->atEnd())
                                            break;
                                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "WATER")) {
					    waterno++;
                                            break;
                                        }
                                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
                                            (xml->name() == "VERSION") || (xml->name() == "DISPLAY_STEP_TEMP") ||
					    (xml->name() == "NOTES") || (xml->name() == "DISPLAY_AMOUNT") ||
					    (xml->name() == "ALWAYS_ON_STOCK") || (xml->name() == "DEFAULT_WATER")
					    )) {
                                            // Ignore.
                                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
					    if (waterno)
						r->w2_name = xml->readElementText();
					    else
						r->w1_name = xml->readElementText();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "PH")) {
					    if (waterno)
						r->w2_ph = xml->readElementText().toDouble();
					    else
						r->w1_ph = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "AMOUNT")) {
                                            if (waterno)
                                                r->w2_amount = xml->readElementText().toDouble();
                                            else
                                                r->w1_amount = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CALCIUM")) {
                                            if (waterno)
                                                r->w2_calcium = xml->readElementText().toDouble();
                                            else
                                                r->w1_calcium = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "BICARBONATE")) {
                                            if (waterno)
                                                r->w2_total_alkalinity = 1.22 * xml->readElementText().toDouble();
                                            else
                                                r->w1_total_alkalinity = 1.22 * xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SULFATE")) {
                                            if (waterno)
                                                r->w2_sulfate = xml->readElementText().toDouble();
                                            else
                                                r->w1_sulfate = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "CHLORIDE")) {
                                            if (waterno)
                                                r->w2_chloride = xml->readElementText().toDouble();
                                            else
                                                r->w1_chloride = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "SODIUM")) {
                                            if (waterno)
                                                r->w2_sodium = xml->readElementText().toDouble();
                                            else
                                                r->w1_sodium = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MAGNESIUM")) {
                                            if (waterno)
                                                r->w2_magnesium = xml->readElementText().toDouble();
                                            else
                                                r->w1_magnesium = xml->readElementText().toDouble();
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TOTAL_ALKALINITY")) {
                                            if (waterno)
                                                r->w2_total_alkalinity = xml->readElementText().toDouble();
                                            else
                                                r->w1_total_alkalinity = xml->readElementText().toDouble();
                                        } else {
                                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                                qDebug() << xml->tokenType() << " WATER->" << xml->name();
                                        }
                                    }
                                }
                            }
                        } else {
                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                qDebug() << xml->tokenType() << " RECIPE" << xml->name();
                        }
                    }
                }
            }
        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MASHS")) {
            /*
             * Mashes
             */
            while (xml->readNext()) {
                if (xml->atEnd())
                    break;
                if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MASHS")) {
                    break;
                }
                if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MASH")) {
                    /*
                     * Mash
                     */
                    total++;
		    Mashs *m = new Mashs();
		    m->name = m->notes = "";

                    while (xml->readNext()) {
                        if (xml->atEnd())
                            break;
                        if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MASH")) {
			    query.prepare("INSERT INTO profile_mash SET name=:name, notes=:notes, steps=:steps, uuid=:uuid");
			    query.bindValue(":name", m->name);
			    query.bindValue(":notes", m->notes);
			    query.bindValue(":steps", m->steps.toJson(QJsonDocument::Compact));
			    query.bindValue(":uuid", QUuid::createUuid().toString().mid(1, 36));
                            query.exec();
                            if (query.lastError().isValid()) {
				qWarning() << query.lastError();
                                errors++;
                            } else {
				qInfo() << "Inserted mash step" << m->name;
			    }
                            ui->progressBar->setValue(round(100 * xml->characterOffset() / fsize));
                            break;
                        }
                        if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
			    (xml->name() == "VERSION") || (xml->name() == "GRAIN_TEMP") ||
			    (xml->name() == "TUN_TEMP") || (xml->name() == "SPARGE_TEMP") ||
			    (xml->name() == "SG_LAST_RUNNINGS") || (xml->name() == "PH_LAST_RUNNINGS") ||
			    (xml->name() == "PH") || (xml->name() == "TUN_WEIGHT") ||
			    (xml->name() == "TUN_SPECIFIC_HEAT") || (xml->name() == "EQUIP_ADJUST"))) {
                            // Ignore.
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
                            m->name = xml->readElementText();
                        } else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NOTES")) {
                            m->notes = xml->readElementText();
			} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MASH_STEPS")) {
			    QJsonArray array;
			    while (xml->readNext()) {
				if (xml->atEnd())
				    break;
				if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MASH_STEPS")) {
				    m->steps.setArray(array);
				    break;
				}
				if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "MASH_STEP")) {
				    /*
				     * Process mash step
				     */
				    QJsonObject obj;
				    while (xml->readNext()) {
					if (xml->atEnd())
					    break;
				    	if ((xml->tokenType() == QXmlStreamReader::EndElement) && (xml->name() == "MASH_STEP")) {
					    array.append(obj);
					    break;
				    	}
				    	if ((xml->tokenType() == QXmlStreamReader::StartElement) && (
					    (xml->name() == "VERSION") || (xml->name() == "DISPLAY_STEP_TEMP") ||
					    (xml->name() == "PH") || (xml->name() == "WATER_GRAIN_RATIO") ||
					    (xml->name() == "DECOCTION_AMT") || (xml->name() == "INFUSE_TEMP") ||
					    (xml->name() == "INFUSE_AMOUNT") || (xml->name() == "DISPLAY_INFUSE_AMT"))) {
					    // Ignore.
				    	} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "NAME")) {
					    obj.insert("step_name", xml->readElementText());
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "TYPE")) {
					    QString temp = xml->readElementText();
					    if (temp == "Infusion")
						obj.insert("step_type", 0);
					    else if (temp == "Temperature")
						obj.insert("step_type", 1);
					    else if (temp == "Decoction")
						obj.insert("step_type", 2);
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STEP_TEMP")) {
					    obj.insert("step_temp", xml->readElementText().toDouble());
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "END_TEMP")) {
                                            obj.insert("end_temp", xml->readElementText().toDouble());
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "STEP_TIME")) {
                                            obj.insert("step_time", xml->readElementText().toDouble());
					} else if ((xml->tokenType() == QXmlStreamReader::StartElement) && (xml->name() == "RAMP_TIME")) {
                                            obj.insert("ramp_time", xml->readElementText().toDouble());
				    	} else {
					    if (xml->tokenType() == QXmlStreamReader::StartElement)
					    	qDebug() << "4    " << xml->tokenType() << xml->name();
				    	}
				    }
				}
			    }

			} else {
                            if (xml->tokenType() == QXmlStreamReader::StartElement)
                                qDebug() << "2  " << xml->tokenType() << xml->name();
                        }
                    }
                }
            }
	} else {
	    qDebug() << "Unknown level 0" << xml->name();
	}
	if (xml->atEnd())
	    break;
    }

    log.append(QString("             total  errors\n"));
    log.append(QString("             -----  ------\n"));
    log.append(QString("total          %1     %2\n").arg(total, 3).arg(errors, 3));
    ui->logEdit->setPlainText(log);
    qInfo() << "Import" << total << "records, " << total - errors << "ok, " << errors << "errors";

    ui->progressBar->setValue(100);
    if (xml->hasError()) {
	qWarning() << "XML error" << xml->error() << xml->errorString();
    }
    file.close();
}

mercurial