summaryrefslogtreecommitdiffstats
path: root/src/importers/baseimporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/importers/baseimporter.cpp')
-rw-r--r--src/importers/baseimporter.cpp399
1 files changed, 399 insertions, 0 deletions
diff --git a/src/importers/baseimporter.cpp b/src/importers/baseimporter.cpp
new file mode 100644
index 0000000..b0ecd61
--- /dev/null
+++ b/src/importers/baseimporter.cpp
@@ -0,0 +1,399 @@
+/***************************************************************************
+* Copyright (C) 2003 by *
+* Jason Kivlighn ([email protected]) *
+* *
+* 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 "baseimporter.h"
+
+#include <tdeapplication.h>
+#include <tdeconfig.h>
+#include <kdebug.h>
+#include <tdelocale.h>
+#include <kprogress.h>
+#include <tdemessagebox.h>
+
+#include <tqvaluevector.h>
+
+#include "datablocks/recipe.h"
+#include "backends/recipedb.h"
+#include "datablocks/categorytree.h"
+#include "datablocks/unit.h"
+
+BaseImporter::BaseImporter() :
+ m_recipe_list( new RecipeList ),
+ m_cat_structure( 0 ),
+ file_recipe_count( 0 )
+{
+ TDEConfig * config = kapp->config();
+ config->setGroup( "Import" );
+
+ direct = config->readBoolEntry( "DirectImport", false );
+}
+
+BaseImporter::~BaseImporter()
+{
+ delete m_recipe_list;
+ delete m_cat_structure;
+}
+
+void BaseImporter::add( const RecipeList &recipe_list )
+{
+ file_recipe_count += recipe_list.count();
+
+ for ( RecipeList::const_iterator it = recipe_list.begin(); it != recipe_list.end(); ++it ) {
+ Recipe copy = *it;
+ copy.recipeID = -1; //make sure an importer didn't give this a value
+ for ( RatingList::iterator rating_it = copy.ratingList.begin(); rating_it != copy.ratingList.end(); ++rating_it ) {
+ (*rating_it).id = -1;
+ }
+ m_recipe_list->append( copy );
+ }
+
+ if ( direct ) {
+ if ( !m_progress_dialog->wasCancelled() )
+ importRecipes( *m_recipe_list, m_database, m_progress_dialog );
+ }
+}
+
+void BaseImporter::add( const Recipe &recipe )
+{
+ file_recipe_count++;
+ Recipe copy = recipe;
+ copy.recipeID = -1; //make sure an importer didn't give this a value
+
+ if ( direct ) {
+ if ( !m_progress_dialog->wasCancelled() ) {
+ RecipeList list;
+ list.append( recipe );
+ importRecipes( list, m_database, m_progress_dialog );
+ }
+ }
+ else
+ m_recipe_list->append( copy );
+}
+
+void BaseImporter::parseFiles( const TQStringList &filenames )
+{
+ if ( direct )
+ m_filenames = filenames;
+ else {
+ for ( TQStringList::const_iterator file_it = filenames.begin(); file_it != filenames.end(); ++file_it ) {
+ file_recipe_count = 0;
+ parseFile( *file_it );
+ processMessages( *file_it );
+ }
+ }
+}
+
+void BaseImporter::import( RecipeDB *db, bool automatic )
+{
+ if ( direct ) {
+ m_database = db;
+
+ m_progress_dialog = new KProgressDialog( kapp->mainWidget(), 0,
+ i18n( "Importing selected recipes" ), TQString::null, true );
+ KProgress *progress = m_progress_dialog->progressBar();
+ progress->setPercentageVisible(false);
+ progress->setTotalSteps( 0 );
+
+ for ( TQStringList::const_iterator file_it = m_filenames.begin(); file_it != m_filenames.end(); ++file_it ) {
+ file_recipe_count = 0;
+ parseFile( *file_it );
+ processMessages( *file_it );
+
+ if ( m_progress_dialog->wasCancelled() )
+ break;
+ }
+
+ importUnitRatios( db );
+ delete m_progress_dialog;
+ }
+ else {
+ if ( m_recipe_list->count() == 0 )
+ return;
+
+ m_recipe_list->empty();
+ //db->blockSignals(true);
+
+ m_progress_dialog = new KProgressDialog( kapp->mainWidget(), 0,
+ i18n( "Importing selected recipes" ), TQString::null, true );
+ KProgress *progress = m_progress_dialog->progressBar();
+ progress->setTotalSteps( m_recipe_list->count() );
+ progress->setFormat( i18n( "%v/%m Recipes" ) );
+
+ if ( m_cat_structure ) {
+ importCategoryStructure( db, m_cat_structure );
+ delete m_cat_structure;
+ m_cat_structure = 0;
+ }
+ importRecipes( *m_recipe_list, db, m_progress_dialog );
+ importUnitRatios( db );
+
+ //db->blockSignals(false);
+ delete m_progress_dialog; m_progress_dialog = 0;
+ }
+}
+
+void BaseImporter::importIngredient( IngredientData &ing, RecipeDB *db, KProgressDialog *progress_dialog )
+{
+ //cache some data we'll need
+ int max_units_length = db->maxUnitNameLength();
+ int max_group_length = db->maxIngGroupNameLength();
+
+ if ( direct ) {
+ progress_dialog->progressBar()->advance( 1 );
+ kapp->processEvents();
+ }
+
+ //create ingredient groups
+ TQString real_group_name = ing.group.left( max_group_length );
+ int new_group_id = db->findExistingIngredientGroupByName(real_group_name);
+ if ( new_group_id == -1 ) {
+ db->createNewIngGroup( real_group_name );
+ new_group_id = db->lastInsertID();
+ }
+ ing.groupID = new_group_id;
+
+ int new_ing_id = db->findExistingIngredientByName(ing.name);
+ if ( new_ing_id == -1 && !ing.name.isEmpty() )
+ {
+ db->createNewIngredient( ing.name );
+ new_ing_id = db->lastInsertID();
+ }
+
+ if ( direct ) {
+ progress_dialog->progressBar()->advance( 1 );
+ kapp->processEvents();
+ }
+
+ Unit real_unit( ing.units.name.left( max_units_length ), ing.units.plural.left( max_units_length ) );
+ if ( real_unit.name.isEmpty() )
+ real_unit.name = real_unit.plural;
+ else if ( real_unit.plural.isEmpty() )
+ real_unit.plural = real_unit.name;
+
+ int new_unit_id = db->findExistingUnitByName(real_unit.name);
+ if ( new_unit_id == -1 ) {
+ db->createNewUnit( Unit(real_unit.name, real_unit.plural) );
+ new_unit_id = db->lastInsertID();
+ }
+
+ if ( direct ) {
+ progress_dialog->progressBar()->advance( 1 );
+ kapp->processEvents();
+ }
+
+ if ( ing.prepMethodList.count() > 0 ) {
+ for ( ElementList::iterator prep_it = ing.prepMethodList.begin(); prep_it != ing.prepMethodList.end(); ++prep_it ) {
+ int new_prep_id = db->findExistingPrepByName((*prep_it).name);
+ if ( new_prep_id == -1 ) {
+ db->createNewPrepMethod((*prep_it).name);
+ new_prep_id = db->lastInsertID();
+ }
+ (*prep_it).id = new_prep_id;
+ }
+ }
+
+ ing.units.id = new_unit_id;
+ ing.ingredientID = new_ing_id;
+
+ if ( !db->ingredientContainsUnit( new_ing_id, new_unit_id ) )
+ db->addUnitToIngredient( new_ing_id, new_unit_id );
+}
+
+void BaseImporter::importRecipes( RecipeList &selected_recipes, RecipeDB *db, KProgressDialog *progress_dialog )
+{
+ // Load Current Settings
+ TDEConfig *config = kapp->config();
+ config->setGroup( "Import" );
+ bool overwrite = config->readBoolEntry( "OverwriteExisting", false );
+
+ RecipeList::iterator recipe_it; RecipeList::iterator recipe_list_end( selected_recipes.end() );
+ RecipeList::iterator recipe_it_old = selected_recipes.end();
+ for ( recipe_it = selected_recipes.begin(); recipe_it != recipe_list_end; ++recipe_it ) {
+ if ( !direct ) {
+ if ( progress_dialog->wasCancelled() ) {
+ KMessageBox::information( kapp->mainWidget(), i18n( "All recipes up unto this point have been successfully imported." ) );
+ //db->blockSignals(false);
+ return ;
+ }
+ }
+
+ if ( recipe_it_old != selected_recipes.end() )
+ selected_recipes.remove( recipe_it_old );
+
+ progress_dialog->setLabel( TQString( i18n( "Importing recipe: %1" ) ).arg( ( *recipe_it ).title ) );
+ progress_dialog->progressBar()->advance( 1 );
+ kapp->processEvents();
+
+ //add all recipe items (authors, ingredients, etc. to the database if they aren't already
+ IngredientList::iterator ing_list_end( ( *recipe_it ).ingList.end() );
+ for ( IngredientList::iterator ing_it = ( *recipe_it ).ingList.begin(); ing_it != ing_list_end; ++ing_it ) {
+ importIngredient( *ing_it, db, progress_dialog );
+
+ for ( TQValueList<IngredientData>::iterator sub_it = (*ing_it).substitutes.begin(); sub_it != (*ing_it).substitutes.end(); ++sub_it ) {
+ importIngredient( *sub_it, db, progress_dialog );
+ }
+ }
+
+ ElementList::iterator author_list_end( ( *recipe_it ).authorList.end() );
+ for ( ElementList::iterator author_it = ( *recipe_it ).authorList.begin(); author_it != author_list_end; ++author_it ) {
+ if ( direct ) {
+ progress_dialog->progressBar()->advance( 1 );
+ kapp->processEvents();
+ }
+
+ int new_author_id = db->findExistingAuthorByName(( *author_it ).name);
+ if ( new_author_id == -1 && !( *author_it ).name.isEmpty() ) {
+ db->createNewAuthor( ( *author_it ).name );
+ new_author_id = db->lastInsertID();
+ }
+
+ ( *author_it ).id = new_author_id;
+ }
+
+ ElementList::iterator cat_list_end( ( *recipe_it ).categoryList.end() );
+ for ( ElementList::iterator cat_it = ( *recipe_it ).categoryList.begin(); cat_it != cat_list_end; ++cat_it ) {
+ if ( direct ) {
+ progress_dialog->progressBar()->advance( 1 );
+ kapp->processEvents();
+ }
+
+ int new_cat_id = db->findExistingCategoryByName(( *cat_it ).name);
+ if ( new_cat_id == -1 && !( *cat_it ).name.isEmpty() ) {
+ db->createNewCategory( ( *cat_it ).name );
+ new_cat_id = db->lastInsertID();
+ }
+
+ ( *cat_it ).id = new_cat_id;
+ }
+
+ if ( !(*recipe_it).yield.type.isEmpty() ) {
+ int new_id = db->findExistingYieldTypeByName((*recipe_it).yield.type);
+ if ( new_id == -1 ) {
+ db->createNewYieldType( (*recipe_it).yield.type );
+ new_id = db->lastInsertID();
+ }
+ (*recipe_it).yield.type_id = new_id;
+ }
+
+ RatingList::iterator rating_list_end( ( *recipe_it ).ratingList.end() );
+ for ( RatingList::iterator rating_it = ( *recipe_it ).ratingList.begin(); rating_it != rating_list_end; ++rating_it ) {
+ if ( direct ) {
+ progress_dialog->progressBar()->advance( 1 );
+ kapp->processEvents();
+ }
+
+ for ( RatingCriteriaList::iterator rc_it = (*rating_it).ratingCriteriaList.begin(); rc_it != (*rating_it).ratingCriteriaList.end(); ++rc_it ) {
+ int new_criteria_id = db->findExistingRatingByName(( *rc_it ).name);
+ if ( new_criteria_id == -1 && !( *rc_it ).name.isEmpty() ) {
+ db->createNewRating( ( *rc_it ).name );
+ new_criteria_id = db->lastInsertID();
+ }
+
+ ( *rc_it ).id = new_criteria_id;
+ }
+ }
+
+ if ( overwrite ) //overwrite existing
+ ( *recipe_it ).recipeID = db->findExistingRecipeByName( ( *recipe_it ).title );
+ else //rename
+ ( *recipe_it ).title = db->getUniqueRecipeTitle( ( *recipe_it ).title );
+
+ if ( direct ) {
+ progress_dialog->progressBar()->advance( 1 );
+ kapp->processEvents();
+ }
+
+ //save into the database
+ db->saveRecipe( &( *recipe_it ) );
+
+ recipe_it_old = recipe_it; //store to delete once we've got the next recipe
+ }
+}
+
+void BaseImporter::setCategoryStructure( CategoryTree *cat_structure )
+{
+ if ( direct ) {
+ importCategoryStructure( m_database, cat_structure );
+ }
+ else {
+ delete m_cat_structure;
+ m_cat_structure = cat_structure;
+ }
+}
+
+void BaseImporter::importCategoryStructure( RecipeDB *db, const CategoryTree *categoryTree )
+{
+ for ( CategoryTree * child_it = categoryTree->firstChild(); child_it; child_it = child_it->nextSibling() ) {
+ int new_cat_id = db->findExistingCategoryByName( child_it->category.name );
+ if ( new_cat_id == -1 ) {
+ db->createNewCategory( child_it->category.name, categoryTree->category.id );
+ new_cat_id = db->lastInsertID();
+ }
+
+ child_it->category.id = new_cat_id;
+
+ importCategoryStructure( db, child_it );
+ }
+}
+
+void BaseImporter::setUnitRatioInfo( UnitRatioList &ratioList, UnitList &unitList )
+{
+ m_ratioList = ratioList;
+ m_unitList = unitList;
+}
+
+void BaseImporter::importUnitRatios( RecipeDB *db )
+{
+ for ( UnitRatioList::const_iterator it = m_ratioList.begin(); it != m_ratioList.end(); ++it ) {
+ TQString unitName1, unitName2;
+ for ( UnitList::const_iterator unit_it = m_unitList.begin(); unit_it != m_unitList.end(); ++unit_it ) {
+ if ( ( *it ).uID1 == ( *unit_it ).id ) {
+ unitName1 = ( *unit_it ).name;
+ if ( !unitName2.isNull() )
+ break;
+ }
+ else if ( ( *it ).uID2 == ( *unit_it ).id ) {
+ unitName2 = ( *unit_it ).name;
+ if ( !unitName1.isNull() )
+ break;
+ }
+ }
+
+ int unitId1 = db->findExistingUnitByName( unitName1 );
+ int unitId2 = db->findExistingUnitByName( unitName2 );
+
+ //the unit needed for the ratio may not have been added, because the
+ //recipes chosen did not include the unit
+ if ( unitId1 != -1 && unitId2 != -1 ) {
+ UnitRatio ratio;
+ ratio.uID1 = unitId1;
+ ratio.uID2 = unitId2;
+ ratio.ratio = ( *it ).ratio;
+ db->saveUnitRatio( &ratio );
+ }
+ }
+}
+
+void BaseImporter::processMessages( const TQString &file )
+{
+ if ( m_error_msgs.count() > 0 ) {
+ //<!doc> ensures it is detected as RichText
+ m_master_error += TQString( i18n( "<!doc>Import of recipes from the file <b>\"%1\"</b> <b>failed</b> due to the following error(s):" ) ).arg( file );
+ m_master_error += "<ul><li>" + m_error_msgs.join( "</li><li>" ) + "</li></ul>";
+
+ m_error_msgs.clear();
+ }
+ else if ( m_warning_msgs.count() > 0 ) {
+ m_master_warning += TQString( i18n( "The file <b>%1</b> generated the following warning(s):" ) ).arg( file );
+ m_master_warning += "<ul><li>" + m_warning_msgs.join( "</li><li>" ) + "</li></ul>";
+
+ m_warning_msgs.clear();
+ }
+}