You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
8.8 KiB
265 lines
8.8 KiB
/***************************************************************************
|
|
* 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 <ntqfile.h>
|
|
#include <ntqstylesheet.h>
|
|
#include <ntqbuffer.h>
|
|
#include <ntqimage.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <tdelocale.h>
|
|
#include <kmdcodec.h>
|
|
#include <tdeglobal.h>
|
|
#include <kstandarddirs.h>
|
|
|
|
#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 += "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
|
|
xml += "<krecipes version=\"" + krecipes_version() + "\" lang=\"" + ( TDEGlobal::locale() )->language() + "\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"krecipes.xsd\">\n";
|
|
|
|
createCategoryStructure( xml, recipes );
|
|
|
|
return xml;
|
|
}
|
|
|
|
TQString KreExporter::createFooter()
|
|
{
|
|
return "</krecipes>\n";
|
|
}
|
|
|
|
TQString KreExporter::generateIngredient( const IngredientData &ing )
|
|
{
|
|
TQString xml;
|
|
|
|
xml += "<name>" + TQStyleSheet::escape( ( ing ).name ) + "</name>\n";
|
|
xml += "<amount>";
|
|
if ( ing.amount_offset < 1e-10 ) {
|
|
xml += TQString::number( ing.amount );
|
|
}
|
|
else {
|
|
xml += "<min>"+TQString::number( ing.amount )+"</min>";
|
|
xml += "<max>"+TQString::number( ing.amount + ing.amount_offset )+"</max>";
|
|
}
|
|
xml += "</amount>\n";
|
|
TQString unit_str = ( ing.amount+ing.amount_offset > 1 ) ? ing.units.plural : ing.units.name;
|
|
xml += "<unit>" + TQStyleSheet::escape( unit_str ) + "</unit>\n";
|
|
if ( ing.prepMethodList.count() > 0 )
|
|
xml += "<prep>" + TQStyleSheet::escape( ing.prepMethodList.join(",") ) + "</prep>\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 += "<krecipes-recipe>\n";
|
|
xml += "<krecipes-description>\n";
|
|
xml += "<title>" + TQStyleSheet::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>" + TQStyleSheet::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
|
|
TQByteArray data;
|
|
TQBuffer buffer( data );
|
|
buffer.open( IO_WriteOnly );
|
|
TQImageIO iio( &buffer, "JPEG" );
|
|
iio.setImage( ( *recipe_it ).photo.convertToImage() );
|
|
iio.write();
|
|
|
|
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>" + TQStyleSheet::escape( ( *cat_it ).name ) + "</cat>\n";
|
|
|
|
xml += "</category>\n";
|
|
xml += "<yield>";
|
|
xml += "<amount>";
|
|
if ( ( *recipe_it ).yield.amount_offset < 1e-10 ) {
|
|
xml += TQString::number( ( *recipe_it ).yield.amount );
|
|
}
|
|
else {
|
|
xml += "<min>"+TQString::number( ( *recipe_it ).yield.amount )+"</min>";
|
|
xml += "<max>"+TQString::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() ) {
|
|
TQString group = group_list[ 0 ].group; //just use the first's name... they're all the same
|
|
if ( !group.isEmpty() )
|
|
xml += "<ingredient-group name=\"" + TQStyleSheet::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 ( TQValueList<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 += TQStyleSheet::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>"+TQStyleSheet::escape( ( *rating_it ).comment )+"</comment>";
|
|
xml += "<rater>"+TQStyleSheet::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>"+TQString::number((*rc_it).stars)+"</stars>";
|
|
xml += "</criteria>";
|
|
}
|
|
xml += "</criterion>";
|
|
xml += "</rating>";
|
|
}
|
|
xml += "</krecipes-ratings>";
|
|
|
|
xml += "</krecipes-recipe>\n";
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
void KreExporter::createCategoryStructure( TQString &xml, const RecipeList &recipes )
|
|
{
|
|
TQValueList<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 TQValueList<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( TQString &xml, const CategoryTree *categoryTree )
|
|
{
|
|
if ( categoryTree->category.id != -2 ) {
|
|
if ( categoryTree->category.id != -1 )
|
|
xml += "<category name=\"" + TQStyleSheet::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";
|
|
}
|
|
}
|
|
|