summaryrefslogtreecommitdiffstats
path: root/krecipes/src/exporters/kreexporter.cpp
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2013-07-31 14:57:12 +0200
committerSlávek Banko <slavek.banko@axis.cz>2013-07-31 14:57:12 +0200
commit1a79d6f5bfce52feb71c264d1b63d78a3da584c4 (patch)
tree740b3faa8a9acff0a524733ce5dc5b036bc53969 /krecipes/src/exporters/kreexporter.cpp
downloadkrecipes-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.cpp265
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("\"","&quot;") + "\">\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";
+ }
+}
+