summaryrefslogtreecommitdiffstats
path: root/src/dialogs/dietwizarddialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dialogs/dietwizarddialog.cpp')
-rw-r--r--src/dialogs/dietwizarddialog.cpp748
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"