/* Copyright (C) 2003 Richard Lärkäng Copyright (C) 2003 Jason Kivlighn This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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, write to the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston, MA 02111-1307 USA */ #include "mx2importer.h" #include #include #include #include #include #include #include "datablocks/recipe.h" MX2Importer::MX2Importer() {} void MX2Importer::parseFile( const TQString& filename ) { TQFile file( filename ); kdDebug() << "loading file: " << filename << endl; if ( file.open( IO_ReadOnly ) ) { kdDebug() << "file opened" << endl; TQDomDocument doc; //hopefully a temporary hack, since MasterCook creates invalid xml declarations TQTextStream stream( &file ); TQString all_data = stream.read(); if ( all_data.startsWith( "" ) + 2 ); TQString error; int line; int column; if ( !doc.setContent( all_data, &error, &line, &column ) ) { kdDebug() << TQString( "error: \"%1\" at line %2, column %3" ).arg( error ).arg( line ).arg( column ) << endl; setErrorMsg( TQString( i18n( "\"%1\" at line %2, column %3. This may not be a *.mx2 file." ) ).arg( error ).arg( line ).arg( column ) ); return ; } TQDomElement mx2 = doc.documentElement(); // TODO Check if there are changes between versions if ( mx2.tagName() != "mx2" /*|| mx2.attribute("source") != "MasterCook 5.0"*/ ) { setErrorMsg( i18n( "This file does not appear to be a *.mx2 file" ) ); return ; } TQDomNodeList l = mx2.childNodes(); for ( unsigned i = 0; i < l.count(); i++ ) { TQDomElement el = l.item( i ).toElement(); if ( el.tagName() == "RcpE" ) { Recipe recipe; recipe.title = el.attribute( "name" ); Element author( el.attribute( "author" ) ); recipe.authorList.append( author ); readRecipe( el.childNodes(), &recipe ); add ( recipe ); } } } else setErrorMsg( i18n( "Unable to open file." ) ); } MX2Importer::~MX2Importer() { } void MX2Importer::readRecipe( const TQDomNodeList& l, Recipe *recipe ) { for ( unsigned i = 0; i < l.count(); i++ ) { TQDomElement el = l.item( i ).toElement(); TQString tagName = el.tagName(); if ( tagName == "Serv" ) { recipe->yield.amount = el.attribute( "qty" ).toInt(); recipe->yield.type = i18n("servings"); } else if ( tagName == "PrpT" ) recipe->prepTime = TQTime::fromString( el.attribute( "elapsed" ) ); else if ( tagName == "CatS" ) { TQDomNodeList categories = el.childNodes(); for ( unsigned j = 0; j < categories.count(); j++ ) { TQDomElement c = categories.item( j ).toElement(); if ( c.tagName() == "CatT" ) { if ( c.text().length() > 0 ) { Element cat( c.text().stripWhiteSpace() ); recipe->categoryList.append( cat ); } } } } else if ( tagName == "IngR" ) { Ingredient new_ing( el.attribute( "name" ), el.attribute( "qty" ).toDouble(), Unit( el.attribute( "unit" ), el.attribute( "qty" ).toDouble() ) ); if ( el.hasChildNodes() ) { TQDomNodeList iChilds = el.childNodes(); for ( unsigned j = 0; j < iChilds.count(); j++ ) { TQDomElement iChild = iChilds.item( j ).toElement(); if ( iChild.tagName() == "IPrp" ) new_ing.prepMethodList.append( Element(iChild.text().stripWhiteSpace()) ); else if ( iChild.tagName() == "INtI" ) ; // TODO: What does it mean?... ingredient nutrient info? } } recipe->ingList.append( new_ing ); } else if ( tagName == "DirS" ) { TQStringList directions; TQDomNodeList dirs = el.childNodes(); for ( unsigned j = 0; j < dirs.count(); j++ ) { TQDomElement dir = dirs.item( j ).toElement(); if ( dir.tagName() == "DirT" ) directions.append( dir.text().stripWhiteSpace() ); } TQString directionsText; // TODO This is copied from RecipeML, maybe a TQStringList // for directions in Recipe instead? if ( directions.count() > 1 ) { for ( unsigned i = 1; i <= directions.count(); i++ ) { if ( i != 1 ) { directionsText += "\n\n"; } TQString sWith = TQString( "%1. " ).arg( i ); TQString text = directions[ i - 1 ]; if ( !text.stripWhiteSpace().startsWith( sWith ) ) directionsText += sWith; directionsText += text; } } else directionsText = directions[ 0 ]; recipe->instructions = directionsText; } else if ( tagName == "SrvI" ) { // Don't know what to do with it, for now add it to directions // btw lets hope this is read after the directions recipe->instructions += "\n\n" + el.text().stripWhiteSpace(); } else if ( tagName == "Note" ) { // Don't know what to do with it, for now add it to directions // btw lets hope this is read after the directions recipe->instructions += "\n\n" + el.text().stripWhiteSpace(); } else if ( tagName == "Nutr" ) { //example: Per Serving (excluding unknown items): 51 Calories; 6g Fat (99.5% calories from fat); trace Protein; trace Carbohydrate; 0g Dietary Fiber; 16mg Cholesterol; 137mg Sodium. Exchanges: 1 Fat. // Don't know what to do with it, for now add it to directions // btw lets hope this is read after the directions recipe->instructions += "\n\n" + el.text().stripWhiteSpace(); } /* tags to check for (example follows: SARA'S SECRETS with Sara Moulton - (Show # SS-1B43) - from the TV FOOD NETWORK */ // TODO Have i missed some tag? } }