/*************************************************************************** * Copyright (C) 2003 by * * Cyril Bosselut (bosselut@b1project.com) * * * * Copyright (C) 2003-2005 by * * Jason Kivlighn (jkivlighn@gmail.com) * * * * 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. * ***************************************************************************/ #include "kreexporter.h" #include #include #include #include #include #include #include #include #include #include "backends/recipedb.h" KreExporter::KreExporter( CategoryTree *_categories, const TQString& filename, const TQString &format ) : BaseExporter( filename, format ), categories( _categories ) { if ( format == "*.kre" ) { setCompressed(true); } } KreExporter::~KreExporter() { delete categories; } int KreExporter::supportedItems() const { return RecipeDB::All; } int KreExporter::headerFlags() const { return RecipeDB::Categories; } TQString KreExporter::createHeader( const RecipeList& recipes ) { TQString xml; xml += "\n"; xml += "language() + "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"krecipes.xsd\">\n"; createCategoryStructure( xml, recipes ); return xml; } TQString KreExporter::createFooter() { return "\n"; } TQString KreExporter::generateIngredient( const IngredientData &ing ) { TQString xml; xml += "" + TQStyleSheet::escape( ( ing ).name ) + "\n"; xml += ""; if ( ing.amount_offset < 1e-10 ) { xml += TQString::number( ing.amount ); } else { xml += ""+TQString::number( ing.amount )+""; xml += ""+TQString::number( ing.amount + ing.amount_offset )+""; } xml += "\n"; TQString unit_str = ( ing.amount+ing.amount_offset > 1 ) ? ing.units.plural : ing.units.name; xml += "" + TQStyleSheet::escape( unit_str ) + "\n"; if ( ing.prepMethodList.count() > 0 ) xml += "" + TQStyleSheet::escape( ing.prepMethodList.join(",") ) + "\n"; return xml; } //TODO: use TQDOM (see recipemlexporter.cpp)? TQString KreExporter::createContent( const RecipeList& recipes ) { TQString xml; RecipeList::const_iterator recipe_it; for ( recipe_it = recipes.begin(); recipe_it != recipes.end(); ++recipe_it ) { xml += "\n"; xml += "\n"; xml += "" + TQStyleSheet::escape( ( *recipe_it ).title ) + "\n"; for ( ElementList::const_iterator author_it = ( *recipe_it ).authorList.begin(); author_it != ( *recipe_it ).authorList.end(); ++author_it ) xml += "" + TQStyleSheet::escape( ( *author_it ).name ) + "\n"; xml += "\n"; if ( !( *recipe_it ).photo.isNull() ) { xml += "\n"; } xml += "\n"; xml += "\n"; for ( ElementList::const_iterator cat_it = ( *recipe_it ).categoryList.begin(); cat_it != ( *recipe_it ).categoryList.end(); ++cat_it ) xml += "" + TQStyleSheet::escape( ( *cat_it ).name ) + "\n"; xml += "\n"; xml += ""; xml += ""; if ( ( *recipe_it ).yield.amount_offset < 1e-10 ) { xml += TQString::number( ( *recipe_it ).yield.amount ); } else { xml += ""+TQString::number( ( *recipe_it ).yield.amount )+""; xml += ""+TQString::number( ( *recipe_it ).yield.amount + ( *recipe_it ).yield.amount_offset )+""; } xml += ""; xml += ""+( *recipe_it ).yield.type+""; xml += "\n"; xml += ""; xml += ( *recipe_it ).prepTime.toString( "hh:mm" ); xml += "\n"; xml += "\n"; xml += "\n"; IngredientList list_copy = ( *recipe_it ).ingList; for ( IngredientList group_list = list_copy.firstGroup(); group_list.count() != 0; group_list = list_copy.nextGroup() ) { TQString group = group_list[ 0 ].group; //just use the first's name... they're all the same if ( !group.isEmpty() ) xml += "\n"; for ( IngredientList::const_iterator ing_it = group_list.begin(); ing_it != group_list.end(); ++ing_it ) { xml += "\n"; xml += generateIngredient(*ing_it); if ( (*ing_it).substitutes.count() > 0 ) { xml += "\n"; for ( TQValueList::const_iterator sub_it = (*ing_it).substitutes.begin(); sub_it != (*ing_it).substitutes.end(); ++sub_it ) { xml += "\n"; xml += generateIngredient(*sub_it); xml += "\n"; } xml += "\n"; } xml += "\n"; } if ( !group.isEmpty() ) xml += "\n"; } /// @todo add ingredient properties xml += "\n"; xml += "\n"; xml += TQStyleSheet::escape( ( *recipe_it ).instructions ); xml += "\n"; //ratings xml += ""; for ( RatingList::const_iterator rating_it = (*recipe_it).ratingList.begin(); rating_it != (*recipe_it).ratingList.end(); ++rating_it ) { xml += ""; xml += ""+TQStyleSheet::escape( ( *rating_it ).comment )+""; xml += ""+TQStyleSheet::escape( ( *rating_it ).rater )+""; xml += ""; for ( RatingCriteriaList::const_iterator rc_it = (*rating_it).ratingCriteriaList.begin(); rc_it != (*rating_it).ratingCriteriaList.end(); ++rc_it ) { xml += ""; xml += ""+(*rc_it).name+""; xml += ""+TQString::number((*rc_it).stars)+""; xml += ""; } xml += ""; xml += ""; } xml += ""; xml += "\n"; } return xml; } void KreExporter::createCategoryStructure( TQString &xml, const RecipeList &recipes ) { TQValueList categoriesUsed; for ( RecipeList::const_iterator recipe_it = recipes.begin(); recipe_it != recipes.end(); ++recipe_it ) { for ( ElementList::const_iterator cat_it = ( *recipe_it ).categoryList.begin(); cat_it != ( *recipe_it ).categoryList.end(); ++cat_it ) { if ( categoriesUsed.find( ( *cat_it ).id ) == categoriesUsed.end() ) categoriesUsed << ( *cat_it ).id; } } if ( !categoriesUsed.empty() ) { //only keep the relevant category structure removeIfUnused( categoriesUsed, categories ); xml += "\n"; writeCategoryStructure( xml, categories ); xml += "\n"; } } bool KreExporter::removeIfUnused( const TQValueList &cat_ids, CategoryTree *parent, bool parent_should_show ) { for ( CategoryTree * it = parent->firstChild(); it; it = it->nextSibling() ) { if ( cat_ids.find( it->category.id ) != cat_ids.end() ) { parent_should_show = true; removeIfUnused( cat_ids, it, true ); //still recurse, but doesn't affect 'parent' } else { bool result = removeIfUnused( cat_ids, it ); if ( parent_should_show == false ) parent_should_show = result; } } if ( !parent_should_show && parent->category.id != -1 ) { //FIXME: CategoryTree is broken when deleting items //delete parent; parent->category.id = -2; //temporary workaround } return parent_should_show; } void KreExporter::writeCategoryStructure( TQString &xml, const CategoryTree *categoryTree ) { if ( categoryTree->category.id != -2 ) { if ( categoryTree->category.id != -1 ) xml += "category.name ).replace("\"",""") + "\">\n"; for ( CategoryTree * child_it = categoryTree->firstChild(); child_it; child_it = child_it->nextSibling() ) { writeCategoryStructure( xml, child_it ); } if ( categoryTree->category.id != -1 ) xml += "\n"; } }