diff options
Diffstat (limited to 'src/dialogs/dietwizarddialog.cpp')
-rw-r--r-- | src/dialogs/dietwizarddialog.cpp | 748 |
1 files changed, 748 insertions, 0 deletions
diff --git a/src/dialogs/dietwizarddialog.cpp b/src/dialogs/dietwizarddialog.cpp new file mode 100644 index 0000000..30414cf --- /dev/null +++ b/src/dialogs/dietwizarddialog.cpp @@ -0,0 +1,748 @@ +/*************************************************************************** +* Copyright (C) 2003 by * +* Unai Garro ([email protected]) * +* Cyril Bosselut ([email protected]) * +* 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 "dietwizarddialog.h" +#include "backends/recipedb.h" +#include "dietviewdialog.h" + +#include <tqbitmap.h> +#include <tqheader.h> +#include <tqlayout.h> +#include <tqpainter.h> +#include <tqwmatrix.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 + 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(); +} + +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" |