/*************************************************************************** * Copyright (C) 2003 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 "baseimporter.h" #include #include #include #include #include #include #include #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::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 ) { // ensures it is detected as RichText m_master_error += TQString( i18n( "Import of recipes from the file \"%1\" failed due to the following error(s):" ) ).arg( file ); m_master_error += "
  • " + m_error_msgs.join( "
  • " ) + "
"; m_error_msgs.clear(); } else if ( m_warning_msgs.count() > 0 ) { m_master_warning += TQString( i18n( "The file %1 generated the following warning(s):" ) ).arg( file ); m_master_warning += "
  • " + m_warning_msgs.join( "
  • " ) + "
"; m_warning_msgs.clear(); } }