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.
krecipes/krecipes/src/dialogs/dietwizarddialog.cpp

800 lines
24 KiB

/***************************************************************************
* Copyright (C) 2003 by *
* Unai Garro (ugarro@users.sourceforge.net) *
* Cyril Bosselut (bosselut@b1project.com) *
* 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 "dietwizarddialog.h"
#include "backends/recipedb.h"
#include "dietviewdialog.h"
#include <ntqbitmap.h>
#include <ntqheader.h>
#include <ntqlayout.h>
#include <ntqpainter.h>
#include <ntqwmatrix.h>
#include <tdeapplication.h>
#include <kcursor.h>
#include <tdeglobalsettings.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <knuminput.h>
#include <kdebug.h>
#include "propertycalculator.h"
#include "widgets/propertylistview.h"
#include "widgets/categorylistview.h"
#include "profiling.h"
DietWizardDialog::DietWizardDialog( TQWidget *parent, RecipeDB *db ) : TQVBox( parent )
{
// Initialize internal variables
database = db;
mealNumber = 1;
dayNumber = 1;
dietRList = new RecipeList();
//Design the dialog
setSpacing( 5 );
// Options Box
optionsBox = new TQHBox( this );
daysSliderBox = new TQVGroupBox( i18n( "Number of Days" ), optionsBox );
dayNumberLabel = new TQLabel( daysSliderBox );
dayNumberLabel->setText( "- 1 -" );
dayNumberLabel->setAlignment( TQt::AlignHCenter );
dayNumberSelector = new TQSlider( daysSliderBox );
dayNumberSelector->setOrientation( TQt::Horizontal );
dayNumberSelector->setRange( 1, 10 );
dayNumberSelector->setSteps( 1, 1 );
dayNumberSelector->setTickmarks( TQSlider::Below );
dayNumberSelector->setFixedWidth( 100 );
mealsSliderBox = new TQVGroupBox( i18n( "Meals per Day" ), optionsBox );
mealNumberLabel = new TQLabel( mealsSliderBox );
mealNumberLabel->setText( "- 1 -" );
mealNumberLabel->setAlignment( TQt::AlignHCenter );
mealNumberSelector = new TQSlider( mealsSliderBox );
mealNumberSelector->setOrientation( TQt::Horizontal );
mealNumberSelector->setRange( 1, 10 );
mealNumberSelector->setSteps( 1, 1 );
mealNumberSelector->setTickmarks( TQSlider::Below );
mealNumberSelector->setFixedWidth( 100 );
// Tabs
mealTabs = new TQTabWidget( this );
mealTabs->setMargin( 5 );
// Button bar
TDEIconLoader il;
TQHBox *bottom_layout = new TQHBox( this );
//bottom_layout->layout()->addItem( new TQSpacerItem( 10,10, TQSizePolicy::MinimumExpanding, TQSizePolicy::Fixed ) );
okButton = new TQPushButton( bottom_layout );
okButton->setIconSet( il.loadIconSet( "button_ok", TDEIcon::Small ) );
okButton->setText( i18n( "Create the diet" ) );
TQPushButton *clearButton = new TQPushButton( bottom_layout );
clearButton->setIconSet( il.loadIconSet( "edit-clear", TDEIcon::Small ) );
clearButton->setText( i18n( "Clear" ) );
// Create Tabs
//don't use newTab, it'll load data and we don't want it to do that at startup
mealTab = new MealInput( mealTabs, database );
mealTabs->addTab( mealTab,i18n( "Meal 1" ) );
mealTabs->setCurrentPage( mealTabs->indexOf( mealTab ) );
// Signals & Slots
connect( mealNumberSelector, TQ_SIGNAL( valueChanged( int ) ), this, TQ_SLOT( changeMealNumber( int ) ) );
connect( dayNumberSelector, TQ_SIGNAL( valueChanged( int ) ), this, TQ_SLOT( changeDayNumber( int ) ) );
connect( okButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( createDiet() ) );
connect( clearButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( clear() ) );
}
DietWizardDialog::~DietWizardDialog()
{
delete dietRList;
}
void DietWizardDialog::clear()
{
mealNumberSelector->setValue( 1 );
dayNumberSelector->setValue( 1 );
MealInput* mealTab = ( MealInput* ) ( mealTabs->page( 0 ) ); // Get the meal
mealTab->setDishNo( 3 );
mealTab->showDish( 0 );
for ( uint i = 0; i < mealTab->dishInputList.count(); ++i ) {
DishInput* dishInput = mealTab->dishInputList[ i ]; // Get the dish input
dishInput->clear();
}
}
void DietWizardDialog::reload( ReloadFlags flag )
{
for ( int i = 0; i < mealTabs->count(); ++i ) {
MealInput *mealTab = (MealInput*)mealTabs->page(i);
mealTab->reload(flag);
}
}
void DietWizardDialog::newTab( const TQString &name )
{
mealTab = new MealInput( mealTabs, database );
mealTab->reload();
mealTabs->addTab( mealTab, name );
mealTabs->setCurrentPage( mealTabs->indexOf( mealTab ) );
}
void DietWizardDialog::changeMealNumber( int mn )
{
mealNumberLabel->setText( TQString( i18n( "- %1 -" ) ).arg( mn ) );
if ( mn > mealNumber ) {
while ( mealNumber != mn ) {
mealNumber++;
newTab( i18n( "Meal %1" ).arg( mealNumber ) );
}
}
else if ( mn < mealNumber ) {
while ( mealNumber != mn ) {
mealNumber--;
delete mealTabs->page( mealTabs->count() - 1 );
}
}
}
void DietWizardDialog::changeDayNumber( int dn )
{
if ( dn < 7 ) {
dayNumber = dn;
dayNumberLabel->setText( TQString( i18n( "- %1 -" ) ).arg( dn ) );
}
else if ( dn == 7 ) {
dayNumber = 7;
dayNumberLabel->setText( TQString( i18n( "- 1 week -" ) ) );
}
else {
dayNumber = ( dn - 6 ) * 7;
dayNumberLabel->setText( TQString( i18n( "- %1 weeks -" ) ).arg( dn - 6 ) );
}
}
void DietWizardDialog::createDiet( void )
{
TDEApplication::setOverrideCursor( KCursor::waitCursor() );
START_TIMER("Creating the diet");
RecipeList rlist;
dietRList->clear();
// Get the whole list of recipes, detailed
int flags = RecipeDB::Title | getNecessaryFlags();
database->loadRecipes( &rlist, flags );
// temporal iterator list so elements can be removed without reloading them again from the DB
// this list prevents the same meal from showing up in the same day twice
TQValueList <RecipeList::Iterator> tempRList;
bool alert = false;
for ( int day = 0;day < dayNumber;day++ ) // Create the diet for the number of days defined by the user
{
populateIteratorList( rlist, &tempRList ); // temporal iterator list so elements can be removed without reloading them again from the DB
for ( int meal = 0;meal < mealNumber;meal++ )
{
int dishNo = ( ( MealInput* ) ( mealTabs->page( meal ) ) ) ->dishNo();
for ( int dish = 0;dish < dishNo;dish++ ) {
bool found = false;
TQValueList <RecipeList::Iterator> tempDishRList = tempRList;
while ( ( !found ) && !tempDishRList.empty() ) {
int random_index = ( int ) ( ( float ) ( kapp->random() ) / ( float ) RAND_MAX * tempDishRList.count() );
TQValueList<RecipeList::Iterator>::Iterator iit = tempDishRList.at( random_index ); // note that at() retrieves an iterator to the iterator list, so we need to use * in order to get the RecipeList::Iterator
RecipeList::Iterator rit = *iit;
if ( found = ( ( ( !categoryFiltering( meal, dish ) ) || checkCategories( *rit, meal, dish ) ) && checkConstraints( *rit, meal, dish ) ) ) // Check that the recipe is inside the constraint limits and in the categories specified
{
dietRList->append( *rit ); // Add recipe to the diet list
tempRList.remove( tempRList.find(*iit) ); //can't just remove()... the iterator isn't from this list (its an iterator from tempDishRList)
}
else {
tempDishRList.remove( iit ); // Remove this analized recipe from teh list
}
}
if ( !found )
alert = true;
}
}
}
if ( alert ) {
TDEApplication::restoreOverrideCursor();
KMessageBox::sorry( this, i18n( "I could not create a full diet list given the constraints. Either the recipe list is too short or the constraints are too demanding. " ) );
}
else // show the resulting diet
{
// make a list of dishnumbers
TQValueList<int> dishNumbers;
for ( int meal = 0;meal < mealNumber;meal++ ) {
int dishNo = ( ( MealInput* ) ( mealTabs->page( meal ) ) ) ->dishNo();
dishNumbers << dishNo;
}
TDEApplication::restoreOverrideCursor();
// display the list
DietViewDialog dietDisplay( this, *dietRList, dayNumber, mealNumber, dishNumbers );
connect( &dietDisplay, TQ_SIGNAL( signalOk() ), this, TQ_SLOT( createShoppingList() ) );
dietDisplay.exec();
}
END_TIMER();
}
void DietWizardDialog::populateIteratorList( RecipeList &rl, TQValueList <RecipeList::Iterator> *il )
{
il->clear();
RecipeList::Iterator it;
for ( it = rl.begin();it != rl.end(); ++it )
il->append( it );
}
int DietWizardDialog::getNecessaryFlags() const
{
bool need_ingredients = false;
bool need_categories = false;
for ( int meal = 0;meal < mealNumber;meal++ ) {
int dishNo = ( ( MealInput* ) ( mealTabs->page( meal ) ) ) ->dishNo();
for ( int dish = 0;dish < dishNo;dish++ ) {
if ( !need_categories ) {
if ( categoryFiltering( meal, dish ) ) {
need_categories = true;
}
}
if ( !need_ingredients ) {
ConstraintList constraints;
loadConstraints( meal, dish, &constraints );
for ( ConstraintList::const_iterator ct_it = constraints.begin(); ct_it != constraints.end(); ++ct_it ) {
if ( (*ct_it).enabled ) {
need_ingredients = true;
break;
}
}
}
if ( need_ingredients && need_categories )
break;
}
if ( need_ingredients && need_categories )
break;
}
kdDebug()<<"Do we need to load ingredients: "<<need_ingredients<<endl;
kdDebug()<<"Do we need to load categories: "<<need_categories<<endl;
int flags = 0;
if ( need_ingredients ) flags |= RecipeDB::Ingredients;
if ( need_categories ) flags |= RecipeDB::Categories;
return flags;
}
MealInput::MealInput( TQWidget *parent, RecipeDB *db ) : TQWidget( parent ),
database( db )
{
// Design the dialog
TQVBoxLayout *layout = new TQVBoxLayout( this );
layout->setSpacing( 10 );
// Options box
mealOptions = new TQHBox( this );
mealOptions->setSpacing( 10 );
layout->addWidget( mealOptions );
// Number of dishes input
dishNumberBox = new TQHBox( mealOptions );
dishNumberBox->setSpacing( 10 );
dishNumberLabel = new TQLabel( i18n( "No. of dishes: " ), dishNumberBox );
dishNumberInput = new TQSpinBox( dishNumberBox );
dishNumberInput->setMinValue( 1 );
dishNumberInput->setMaxValue( 10 );
dishNumberBox->setSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum ) );
// Toolbar
toolBar = new TQHGroupBox( mealOptions );
toolBar->setFrameStyle ( TQFrame::Panel | TQFrame::Sunken );
toolBar->setSizePolicy( TQSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::Minimum ) );
// Next dish/ Previous dish buttons
TDEIconLoader il;
buttonPrev = new TQToolButton( toolBar );
buttonPrev->setUsesTextLabel( true );
buttonPrev->setTextLabel( i18n( "Previous Dish" ) );
buttonPrev->setIconSet( il.loadIconSet( "back", TDEIcon::Small ) );
buttonPrev->setTextPosition( TQToolButton::Under );
buttonNext = new TQToolButton( toolBar );
buttonNext->setUsesTextLabel( true );
buttonNext->setTextLabel( i18n( "Next Dish" ) );
buttonNext->setIconSet( il.loadIconSet( "forward", TDEIcon::Small ) );
buttonNext->setTextPosition( TQToolButton::Under );
// Dish widgets
dishStack = new TQWidgetStack( this );
layout->addWidget( dishStack );
dishStack->setSizePolicy( TQSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::MinimumExpanding ) );
// Add default dishes
DishInput *newDish = new DishInput( this, database, i18n( "1st Course" ) );
dishStack->addWidget( newDish );
dishInputList.append( newDish );
newDish = new DishInput( this, database, i18n( "2nd Course" ) );
dishStack->addWidget( newDish );
dishInputList.append( newDish );
newDish = new DishInput( this, database, i18n( "Dessert" ) );
dishStack->addWidget( newDish );
dishInputList.append( newDish );
dishNumber = 3;
dishNumberInput->setValue( dishNumber );
// Signals & Slots
connect( dishNumberInput, TQ_SIGNAL( valueChanged( int ) ), this, TQ_SLOT( changeDishNumber( int ) ) );
connect( buttonPrev, TQ_SIGNAL( clicked() ), this, TQ_SLOT( prevDish() ) );
connect( buttonNext, TQ_SIGNAL( clicked() ), this, TQ_SLOT( nextDish() ) );
}
MealInput::~MealInput()
{}
void MealInput::reload( ReloadFlags flag )
{
TQValueList<DishInput*>::iterator it;
for ( it = dishInputList.begin(); it != dishInputList.end(); ++it ) {
DishInput *di = ( *it );
di->reload(flag);
}
}
void MealInput::setDishNo( int dn )
{
dishNumberInput->setValue( dn );
}
void MealInput::changeDishNumber( int dn )
{
if ( dn > dishNumber ) {
while ( dishNumber != dn ) {
DishInput * newDish = new DishInput( this, database, TQString( i18n( "Dish %1" ) ).arg( dishNumber + 1 ) );
newDish->reload();
dishStack->addWidget( newDish );
dishInputList.append( newDish );
dishStack->raiseWidget( newDish );
dishNumber++;
}
}
else if ( dn < dishNumber ) {
TQValueList <DishInput*>::Iterator it;
while ( dishNumber != dn ) {
it = dishInputList.fromLast();
DishInput *lastDish = ( *it );
dishInputList.remove( it );
if ( ( *it ) == ( DishInput* ) dishStack->visibleWidget() ) {
it--;
dishStack->raiseWidget( *it );
}
delete lastDish;
dishNumber--;
}
}
}
void MealInput::nextDish( void )
{
// First get the place of the current dish input in the list
TQValueList <DishInput*>::iterator it = dishInputList.find( ( DishInput* ) ( dishStack->visibleWidget() ) );
//Show the next dish if it exists
it++;
if ( it != dishInputList.end() ) {
dishStack->raiseWidget( *it );
}
}
void MealInput::prevDish( void )
{
// First get the place of the current dish input in the list
TQValueList <DishInput*>::iterator it = dishInputList.find( ( DishInput* ) ( dishStack->visibleWidget() ) );
//Show the previous dish if it exists
it--;
if ( it != dishInputList.end() ) {
dishStack->raiseWidget( *it );
}
}
void MealInput::showDish( int dn )
{
TQValueList <DishInput*>::iterator it = dishInputList.at( dn );
if ( it != dishInputList.end() )
dishStack->raiseWidget( *it );
}
DishInput::DishInput( TQWidget* parent, RecipeDB *db, const TQString &title ) : TQWidget( parent ),
database(db)
{
// Initialize internal variables
categoryFiltering = false;
// Design the widget
TQVBoxLayout *layout = new TQVBoxLayout( this );
layout->setSpacing( 10 );
//Horizontal Box to hold the TDEListView's
listBox = new TQHGroupBox( i18n( "Dish Characteristics" ), this );
layout->addWidget( listBox );
// Dish id
dishTitle = new DishTitle( listBox, title );
//Categories list
categoriesBox = new TQVBox( listBox );
categoriesEnabledBox = new TQCheckBox( categoriesBox );
categoriesEnabledBox->setText( i18n( "Enable Category Filtering" ) );
categoriesView = new CategoryCheckListView( categoriesBox, database, false );
categoriesView->setSizePolicy( TQSizePolicy::Ignored, TQSizePolicy::Ignored );
categoriesView->setEnabled( false ); // Disable it by default
//Constraints list
constraintsView = new PropertyConstraintListView( listBox, database );
constraintsView->setSizePolicy( TQSizePolicy::Ignored, TQSizePolicy::Ignored );
constraintsView->reload();
// KDoubleInput based edit boxes
constraintsEditBox1 = new KDoubleNumInput( constraintsView->viewport() );
constraintsView->addChild( constraintsEditBox1 );
constraintsEditBox1->hide();
constraintsEditBox2 = new KDoubleNumInput( constraintsView->viewport() );
constraintsView->addChild( constraintsEditBox2 );
constraintsEditBox2->hide();
// Connect Signals & Slots
connect( constraintsView, TQ_SIGNAL( executed( TQListViewItem* ) ), this, TQ_SLOT( insertConstraintsEditBoxes( TQListViewItem* ) ) );
connect( constraintsView, TQ_SIGNAL( selectionChanged() ), this, TQ_SLOT( hideConstraintInputs() ) );
connect( constraintsEditBox1, TQ_SIGNAL( valueChanged( double ) ), this, TQ_SLOT( setMinValue( double ) ) );
connect( constraintsEditBox2, TQ_SIGNAL( valueChanged( double ) ), this, TQ_SLOT( setMaxValue( double ) ) );
connect( categoriesEnabledBox, TQ_SIGNAL( toggled( bool ) ), this, TQ_SLOT( enableCategories( bool ) ) );
}
DishInput::~DishInput()
{}
void DishInput::clear()
{
TQListViewItemIterator it( categoriesView );
while ( it.current() ) {
TQCheckListItem * item = ( TQCheckListItem* ) it.current();
item->setOn( false );
++it;
}
constraintsView->reload();
categoriesEnabledBox->setChecked( false );
}
void DishInput::enableCategories( bool enable )
{
categoriesView->setEnabled( enable );
categoryFiltering = enable;
}
bool DishInput::isCategoryFilteringEnabled( void ) const
{
return categoryFiltering;
}
void DishInput::reload( ReloadFlags flag )
{
constraintsView->reload();
categoriesView->reload(flag);
}
void DishInput::insertConstraintsEditBoxes( TQListViewItem* it )
{
TQRect r;
// Constraints Box1
r = constraintsView->header() ->sectionRect( 2 ); //start at the section 2 header
r.moveBy( 0, constraintsView->itemRect( it ).y() ); //Move down to the item, note that its height is same as header's right now.
r.setHeight( it->height() ); // Set the item's height
r.setWidth( constraintsView->header() ->sectionRect( 2 ).width() ); // and width
constraintsEditBox1->setGeometry( r );
//Constraints Box2
r = constraintsView->header() ->sectionRect( 3 ); //start at the section 3 header
r.moveBy( 0, constraintsView->itemRect( it ).y() ); //Move down to the item
r.setHeight( it->height() ); // Set the item's height
r.setWidth( constraintsView->header() ->sectionRect( 3 ).width() ); // and width
constraintsEditBox2->setGeometry( r );
// Set the values from the item
constraintsEditBox1->setValue( ( ( ConstraintsListItem* ) it ) ->minVal() );
constraintsEditBox2->setValue( ( ( ConstraintsListItem* ) it ) ->maxVal() );
// Show Boxes
constraintsEditBox1->show();
constraintsEditBox2->show();
}
void DishInput::hideConstraintInputs()
{
constraintsEditBox1->hide();
constraintsEditBox2->hide();
}
void DishInput::loadConstraints( ConstraintList *constraints ) const
{
constraints->clear();
Constraint constraint;
for ( ConstraintsListItem * it = ( ConstraintsListItem* ) ( constraintsView->firstChild() );it;it = ( ConstraintsListItem* ) ( it->nextSibling() ) ) {
constraint.id = it->propertyId();
constraint.min = it->minVal();
constraint.max = it->maxVal();
constraint.enabled = it->isOn();
constraints->append( constraint );
}
}
void DishInput::loadEnabledCategories( ElementList* categories )
{
categories->clear();
// Only load those that are checked, unless filtering is disabled
if ( !categoriesView->isEnabled() ) {
database->loadCategories(categories);
}
else {
*categories = categoriesView->selections();
}
}
void DishInput::setMinValue( double minValue )
{
ConstraintsListItem *it = ( ConstraintsListItem* ) ( constraintsView->selectedItem() ); // Find selected property
if ( it )
it->setMin( minValue );
}
void DishInput::setMaxValue( double maxValue )
{
ConstraintsListItem *it = ( ConstraintsListItem* ) ( constraintsView->selectedItem() ); // Find selected property
if ( it )
it->setMax( maxValue );
}
DishTitle::DishTitle( TQWidget *parent, const TQString &title ) : TQWidget( parent )
{
titleText = title;
}
DishTitle::~DishTitle()
{}
void DishTitle::paintEvent( TQPaintEvent * )
{
// Now draw the text
if ( TQT_VERSION >= 0x030200 ) {
// Case 1: TQt 3.2+
TQPainter painter( this );
// First draw the decoration
painter.setPen( TDEGlobalSettings::activeTitleColor() );
painter.setBrush( TQBrush( TDEGlobalSettings::activeTitleColor() ) );
painter.drawRoundRect( 0, 20, 30, height() - 40, 50, ( int ) ( 50.0 / ( height() - 40 ) * 35.0 ) );
// Now draw the text
TQFont titleFont = TDEGlobalSettings::windowTitleFont ();
titleFont.setPointSize( 15 );
painter.setFont( titleFont );
painter.rotate( -90 );
painter.setPen( TQColor( 0x00, 0x00, 0x00 ) );
painter.drawText( 0, 0, -height(), 30, AlignCenter, titleText );
painter.setPen( TQColor( 0xFF, 0xFF, 0xFF ) );
painter.drawText( -1, -1, -height() - 1, 29, AlignCenter, titleText );
painter.end();
}
else {
// Case 2: TQt 3.1
// Use a pixmap
TQSize pmSize( height(), width() ); //inverted size so we can rotate later
TQPixmap pm( pmSize );
pm.fill( TQColor( 0xFF, 0xFF, 0xFF ) );
TQPainter painter( &pm );
// First draw the decoration
painter.setPen( TDEGlobalSettings::activeTitleColor() );
painter.setBrush( TQBrush( TDEGlobalSettings::activeTitleColor() ) );
painter.drawRoundRect( 20, 0, height() - 40, 30, ( int ) ( 50.0 / ( height() - 40 ) * 35.0 ), 50 );
// Now draw the text
TQFont titleFont = TDEGlobalSettings::windowTitleFont ();
titleFont.setPointSize( 15 );
painter.setFont( titleFont );
painter.setPen( TQColor( 0x00, 0x00, 0x00 ) );
painter.drawText( 0, 0, height(), 30, AlignCenter, titleText );
painter.setPen( TQColor( 0xFF, 0xFF, 0xFF ) );
painter.drawText( -1, -1, height() - 1, 29, AlignCenter, titleText );
painter.end();
//Set the border transparent using a mask
TQBitmap mask( pm.size() );
mask.fill( TQt::color0 );
painter.begin( &mask );
painter.setPen( TQt::color1 );
painter.setBrush( TQt::color1 );
painter.drawRoundRect( 20, 0, height() - 40, 30, ( int ) ( 50.0 / ( height() - 40 ) * 35.0 ), 50 );
painter.end();
pm.setMask( mask );
//And Rotate
TQWMatrix m ;
m.rotate( -90 );
pm = pm.xForm( m );
bitBlt( this, 0, 0, &pm );
}
}
TQSize DishTitle::sizeHint () const
{
return ( TQSize( 40, 200 ) );
}
TQSize DishTitle::minimumSizeHint() const
{
return ( TQSize( 40, 200 ) );
}
bool DietWizardDialog::checkCategories( Recipe &rec, int meal, int dish )
{
// Check if the recipe is among the categories chosen
ElementList categoryList;
loadEnabledCategories( meal, dish, &categoryList );
for ( ElementList::const_iterator cat_it = rec.categoryList.begin(); cat_it != rec.categoryList.end(); ++cat_it ) {
if ( categoryList.containsId( ( *cat_it ).id ) )
return true;
}
return false;
}
/*
** Calculate the recipe Properties and check if they're within the constraints
*/
bool DietWizardDialog::checkConstraints( Recipe &rec, int meal, int dish )
{
// Check if the properties are within the constraints
ConstraintList constraints;
loadConstraints( meal, dish, &constraints ); //load the constraints
bool any_enabled = false;
for ( ConstraintList::const_iterator ct_it = constraints.begin(); ct_it != constraints.end(); ++ct_it ) {
if ( (*ct_it).enabled ) {
any_enabled = true;
break;
}
}
if ( !any_enabled )
return true;
// Calculate properties of the recipe
calculateProperties( rec, database );
bool withinLimits = checkLimits( rec.properties, constraints );
return ( withinLimits );
}
void DietWizardDialog::loadConstraints( int meal, int dish, ConstraintList *constraints ) const
{
MealInput * mealTab = ( MealInput* ) ( mealTabs->page( meal ) ); // Get the meal
DishInput* dishInput = mealTab->dishInputList[ dish ]; // Get the dish input
dishInput->loadConstraints( constraints ); //Load the constraints form the TDEListView
}
void DietWizardDialog::loadEnabledCategories( int meal, int dish, ElementList *categories )
{
MealInput * mealTab = ( MealInput* ) ( mealTabs->page( meal ) ); // Get the meal
DishInput* dishInput = mealTab->dishInputList[ dish ]; // Get the dish input
dishInput->loadEnabledCategories( categories ); //Load the categories that have been checked in the TDEListView
}
bool DietWizardDialog::categoryFiltering( int meal, int dish ) const
{
MealInput * mealTab = ( MealInput* ) ( mealTabs->page( meal ) ); // Get the meal
DishInput* dishInput = mealTab->dishInputList[ dish ]; // Get the dish input
return ( dishInput->isCategoryFilteringEnabled() ); //Load the categories that have been checked in the TDEListView
}
bool DietWizardDialog::checkLimits( IngredientPropertyList &properties, ConstraintList &constraints )
{
for ( ConstraintList::const_iterator ct_it = constraints.begin(); ct_it != constraints.end(); ++ct_it ) {
if ( (*ct_it).enabled ) {
IngredientPropertyList::const_iterator ip_it = properties.find( (*ct_it).id );
if ( ip_it != properties.end() ) {
if ( ( (*ip_it).amount > (*ct_it).max ) || ( (*ip_it).amount < (*ct_it).min ) )
return false;
}
else
return false;
}
}
return true;
}
void DietWizardDialog::createShoppingList( void )
{
emit dietReady();
}
RecipeList& DietWizardDialog::dietList( void )
{
return *dietRList;
}
#include "dietwizarddialog.moc"