diff options
author | Slávek Banko <slavek.banko@axis.cz> | 2013-07-31 14:57:12 +0200 |
---|---|---|
committer | Slávek Banko <slavek.banko@axis.cz> | 2013-07-31 14:57:12 +0200 |
commit | 1a79d6f5bfce52feb71c264d1b63d78a3da584c4 (patch) | |
tree | 740b3faa8a9acff0a524733ce5dc5b036bc53969 /krecipes/src/exporters/kreexporter.cpp | |
download | krecipes-1a79d6f5bfce52feb71c264d1b63d78a3da584c4.tar.gz krecipes-1a79d6f5bfce52feb71c264d1b63d78a3da584c4.zip |
Initial import of krecipes 1.0-beta2
Diffstat (limited to 'krecipes/src/exporters/kreexporter.cpp')
-rw-r--r-- | krecipes/src/exporters/kreexporter.cpp | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/krecipes/src/exporters/kreexporter.cpp b/krecipes/src/exporters/kreexporter.cpp new file mode 100644 index 0000000..5ed1b65 --- /dev/null +++ b/krecipes/src/exporters/kreexporter.cpp @@ -0,0 +1,265 @@ +/*************************************************************************** +* 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 <qfile.h> +#include <qstylesheet.h> +#include <qbuffer.h> +#include <qimage.h> + +#include <kdebug.h> +#include <klocale.h> +#include <kmdcodec.h> +#include <kglobal.h> +#include <kstandarddirs.h> + +#include "backends/recipedb.h" + +KreExporter::KreExporter( CategoryTree *_categories, const QString& filename, const QString &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; +} + +QString KreExporter::createHeader( const RecipeList& recipes ) +{ + QString xml; + + xml += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; + xml += "<krecipes version=\"" + krecipes_version() + "\" lang=\"" + ( KGlobal::locale() )->language() + "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"krecipes.xsd\">\n"; + + createCategoryStructure( xml, recipes ); + + return xml; +} + +QString KreExporter::createFooter() +{ + return "</krecipes>\n"; +} + +QString KreExporter::generateIngredient( const IngredientData &ing ) +{ + QString xml; + + xml += "<name>" + QStyleSheet::escape( ( ing ).name ) + "</name>\n"; + xml += "<amount>"; + if ( ing.amount_offset < 1e-10 ) { + xml += QString::number( ing.amount ); + } + else { + xml += "<min>"+QString::number( ing.amount )+"</min>"; + xml += "<max>"+QString::number( ing.amount + ing.amount_offset )+"</max>"; + } + xml += "</amount>\n"; + QString unit_str = ( ing.amount+ing.amount_offset > 1 ) ? ing.units.plural : ing.units.name; + xml += "<unit>" + QStyleSheet::escape( unit_str ) + "</unit>\n"; + if ( ing.prepMethodList.count() > 0 ) + xml += "<prep>" + QStyleSheet::escape( ing.prepMethodList.join(",") ) + "</prep>\n"; + + return xml; +} + +//TODO: use QDOM (see recipemlexporter.cpp)? +QString KreExporter::createContent( const RecipeList& recipes ) +{ + QString xml; + + RecipeList::const_iterator recipe_it; + for ( recipe_it = recipes.begin(); recipe_it != recipes.end(); ++recipe_it ) { + + xml += "<krecipes-recipe>\n"; + xml += "<krecipes-description>\n"; + xml += "<title>" + QStyleSheet::escape( ( *recipe_it ).title ) + "</title>\n"; + + for ( ElementList::const_iterator author_it = ( *recipe_it ).authorList.begin(); author_it != ( *recipe_it ).authorList.end(); ++author_it ) + xml += "<author>" + QStyleSheet::escape( ( *author_it ).name ) + "</author>\n"; + + xml += "<pictures>\n"; + if ( !( *recipe_it ).photo.isNull() ) { + xml += "<pic format=\"JPEG\" id=\"1\"><![CDATA["; //fixed id until we implement multiple photos ability + QByteArray data; + QBuffer buffer( data ); + buffer.open( IO_WriteOnly ); + QImageIO iio( &buffer, "JPEG" ); + iio.setImage( ( *recipe_it ).photo.convertToImage() ); + iio.write(); + //( *recipe_it ).photo.save( &buffer, "JPEG" ); don't need QImageIO in QT 3.2 + + xml += KCodecs::base64Encode( data, true ); + + xml += "]]></pic>\n"; + } + xml += "</pictures>\n"; + xml += "<category>\n"; + + for ( ElementList::const_iterator cat_it = ( *recipe_it ).categoryList.begin(); cat_it != ( *recipe_it ).categoryList.end(); ++cat_it ) + xml += "<cat>" + QStyleSheet::escape( ( *cat_it ).name ) + "</cat>\n"; + + xml += "</category>\n"; + xml += "<yield>"; + xml += "<amount>"; + if ( ( *recipe_it ).yield.amount_offset < 1e-10 ) { + xml += QString::number( ( *recipe_it ).yield.amount ); + } + else { + xml += "<min>"+QString::number( ( *recipe_it ).yield.amount )+"</min>"; + xml += "<max>"+QString::number( ( *recipe_it ).yield.amount + ( *recipe_it ).yield.amount_offset )+"</max>"; + } + xml += "</amount>"; + xml += "<type>"+( *recipe_it ).yield.type+"</type>"; + xml += "</yield>\n"; + xml += "<preparation-time>"; + xml += ( *recipe_it ).prepTime.toString( "hh:mm" ); + xml += "</preparation-time>\n"; + xml += "</krecipes-description>\n"; + xml += "<krecipes-ingredients>\n"; + + IngredientList list_copy = ( *recipe_it ).ingList; + for ( IngredientList group_list = list_copy.firstGroup(); group_list.count() != 0; group_list = list_copy.nextGroup() ) { + QString group = group_list[ 0 ].group; //just use the first's name... they're all the same + if ( !group.isEmpty() ) + xml += "<ingredient-group name=\"" + QStyleSheet::escape(group) + "\">\n"; + + for ( IngredientList::const_iterator ing_it = group_list.begin(); ing_it != group_list.end(); ++ing_it ) { + xml += "<ingredient>\n"; + + xml += generateIngredient(*ing_it); + + if ( (*ing_it).substitutes.count() > 0 ) { + xml += "<substitutes>\n"; + for ( QValueList<IngredientData>::const_iterator sub_it = (*ing_it).substitutes.begin(); sub_it != (*ing_it).substitutes.end(); ++sub_it ) { + xml += "<ingredient>\n"; + xml += generateIngredient(*sub_it); + xml += "</ingredient>\n"; + } + xml += "</substitutes>\n"; + } + + xml += "</ingredient>\n"; + } + + if ( !group.isEmpty() ) + xml += "</ingredient-group>\n"; + } + + /// @todo add ingredient properties + + xml += "</krecipes-ingredients>\n"; + xml += "<krecipes-instructions>\n"; + xml += QStyleSheet::escape( ( *recipe_it ).instructions ); + xml += "</krecipes-instructions>\n"; + + //ratings + xml += "<krecipes-ratings>"; + for ( RatingList::const_iterator rating_it = (*recipe_it).ratingList.begin(); rating_it != (*recipe_it).ratingList.end(); ++rating_it ) { + xml += "<rating>"; + xml += "<comment>"+QStyleSheet::escape( ( *rating_it ).comment )+"</comment>"; + xml += "<rater>"+QStyleSheet::escape( ( *rating_it ).rater )+"</rater>"; + + xml += "<criterion>"; + for ( RatingCriteriaList::const_iterator rc_it = (*rating_it).ratingCriteriaList.begin(); rc_it != (*rating_it).ratingCriteriaList.end(); ++rc_it ) { + xml += "<criteria>"; + xml += "<name>"+(*rc_it).name+"</name>"; + xml += "<stars>"+QString::number((*rc_it).stars)+"</stars>"; + xml += "</criteria>"; + } + xml += "</criterion>"; + xml += "</rating>"; + } + xml += "</krecipes-ratings>"; + + xml += "</krecipes-recipe>\n"; + } + + return xml; +} + +void KreExporter::createCategoryStructure( QString &xml, const RecipeList &recipes ) +{ + QValueList<int> 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 += "<krecipes-category-structure>\n"; + writeCategoryStructure( xml, categories ); + xml += "</krecipes-category-structure>\n"; + } +} + +bool KreExporter::removeIfUnused( const QValueList<int> &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( QString &xml, const CategoryTree *categoryTree ) +{ + if ( categoryTree->category.id != -2 ) { + if ( categoryTree->category.id != -1 ) + xml += "<category name=\"" + QStyleSheet::escape( categoryTree->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 += "</category>\n"; + } +} + |