diff options
Diffstat (limited to 'src/dialogs/advancedsearchdialog.cpp')
-rw-r--r-- | src/dialogs/advancedsearchdialog.cpp | 932 |
1 files changed, 932 insertions, 0 deletions
diff --git a/src/dialogs/advancedsearchdialog.cpp b/src/dialogs/advancedsearchdialog.cpp new file mode 100644 index 0000000..9f4864d --- /dev/null +++ b/src/dialogs/advancedsearchdialog.cpp @@ -0,0 +1,932 @@ +/*************************************************************************** +* Copyright (C) 2003-2004 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 "advancedsearchdialog.h" + +#include <tqvariant.h> +#include <tqpushbutton.h> +#include <tqtabwidget.h> +#include <tqwidget.h> +#include <tqcheckbox.h> +#include <tqframe.h> +#include <tqcombobox.h> +#include <tqheader.h> +#include <tqlistview.h> +#include <tqgroupbox.h> +#include <tqspinbox.h> +#include <tqdatetimeedit.h> +#include <kpushbutton.h> +#include <tqlayout.h> +#include <tqtooltip.h> +#include <tqwhatsthis.h> +#include <tqlabel.h> +#include <tqlineedit.h> +#include <tqscrollview.h> +#include <tqhbox.h> +#include <tqradiobutton.h> +#include <tqbuttongroup.h> + +#include <tdeapplication.h> +#include <kcursor.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <tdelistview.h> +#include <tdelocale.h> +#include <tdeconfig.h> +#include <tdeglobal.h> +#include <tdepopupmenu.h> + +#include "backends/recipedb.h" +#include "backends/searchparameters.h" +#include "recipeactionshandler.h" +#include "widgets/recipelistview.h" +#include "widgets/kdateedit.h" +#include "widgets/ratingwidget.h" +#include "widgets/fractioninput.h" +#include "widgets/criteriacombobox.h" + +#include "profiling.h" + +AdvancedSearchDialog::AdvancedSearchDialog( TQWidget *parent, RecipeDB *db ) : TQWidget( parent ), + database( db ) +{ + /// + ///BEGIN OF AUTOMATICALLY GENERATED GUI CODE/// + /// + AdvancedSearchDialogLayout = new TQHBoxLayout( this, 5, 3, "AdvancedSearchDialogLayout"); + + layout7 = new TQVBoxLayout( 0, 0, 3, "layout7"); + + textLabel1_4 = new TQLabel( this, "textLabel1_4" ); + layout7->addWidget( textLabel1_4 ); + + scrollView1 = new TQScrollView( this, "scrollView1" ); + scrollView1->enableClipper(true); + + parametersFrame = new TQFrame( scrollView1, "parametersFrame" ); + parametersFrame->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)3, (TQSizePolicy::SizeType)3, 0, 0, parametersFrame->sizePolicy().hasHeightForWidth() ) ); + parametersFrame->setFrameShape( TQFrame::NoFrame ); + parametersFrame->setFrameShadow( TQFrame::Plain ); + parametersFrame->setLineWidth( 0 ); + parametersFrameLayout = new TQVBoxLayout( parametersFrame, 0, 0, "parametersFrameLayout"); + + titleButton = new TQPushButton( parametersFrame, "titleButton" ); + titleButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( titleButton ); + + titleFrame = new TQFrame( parametersFrame, "titleFrame" ); + titleFrame->setFrameShape( TQFrame::StyledPanel ); + titleFrame->setFrameShadow( TQFrame::Raised ); + titleFrameLayout = new TQVBoxLayout( titleFrame, 5, 3, "titleFrameLayout"); + + requireAllTitle = new TQCheckBox( i18n("Require All Words"), titleFrame ); + titleFrameLayout->addWidget( requireAllTitle ); + + TQHBox *titleHBox = new TQHBox( titleFrame ); + /*TQLabel *titleInfoLabel = */new TQLabel(i18n("Keywords:"),titleHBox); + titleEdit = new TQLineEdit( titleHBox, "titleEdit" ); + titleFrameLayout->addWidget( titleHBox ); + + parametersFrameLayout->addWidget( titleFrame ); + titleFrameSpacer = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Preferred ); + parametersFrameLayout->addItem( titleFrameSpacer ); + + + ingredientButton = new TQPushButton( parametersFrame, "ingredientButton" ); + ingredientButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( ingredientButton ); + + ingredientFrame = new TQFrame( parametersFrame, "ingredientFrame" ); + ingredientFrame->setFrameShape( TQFrame::StyledPanel ); + ingredientFrame->setFrameShadow( TQFrame::Raised ); + ingredientFrameLayout = new TQGridLayout( ingredientFrame, 1, 1, 3, 3, "ingredientFrameLayout"); + + TQLabel *ingredientInfoLabel = new TQLabel(i18n("Enter ingredients: (e.g. chicken pasta \"white wine\")"),ingredientFrame); + ingredientInfoLabel->setTextFormat( TQt::RichText ); + ingredientFrameLayout->addMultiCellWidget( ingredientInfoLabel, 0, 0, 0, 1 ); + + ingredientsAllEdit = new TQLineEdit( ingredientFrame, "ingredientsAllEdit" ); + + ingredientFrameLayout->addWidget( ingredientsAllEdit, 1, 1 ); + + ingredientsAnyEdit = new TQLineEdit( ingredientFrame, "ingredientsAnyEdit" ); + + ingredientFrameLayout->addWidget( ingredientsAnyEdit, 2, 1 ); + + textLabel1_2 = new TQLabel( ingredientFrame, "textLabel1_2" ); + + ingredientFrameLayout->addWidget( textLabel1_2, 2, 0 ); + + textLabel1 = new TQLabel( ingredientFrame, "textLabel1" ); + + ingredientFrameLayout->addWidget( textLabel1, 1, 0 ); + + ingredientsWithoutEdit = new TQLineEdit( ingredientFrame, "ingredientsWithoutEdit" ); + + ingredientFrameLayout->addWidget( ingredientsWithoutEdit, 3, 1 ); + + textLabel1_3 = new TQLabel( ingredientFrame, "textLabel1_3" ); + + ingredientFrameLayout->addWidget( textLabel1_3, 3, 0 ); + parametersFrameLayout->addWidget( ingredientFrame ); + spacer3_2_3_2_2 = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Preferred ); + parametersFrameLayout->addItem( spacer3_2_3_2_2 ); + + + categoriesButton = new TQPushButton( parametersFrame, "categoriesButton" ); + categoriesButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( categoriesButton ); + + categoryFrame = new TQFrame( parametersFrame, "categoryFrame" ); + categoryFrame->setFrameShape( TQFrame::StyledPanel ); + categoryFrame->setFrameShadow( TQFrame::Raised ); + categoryFrameLayout = new TQGridLayout( categoryFrame, 1, 1, 3, 3, "categoryFrameLayout"); + + TQLabel *categoryInfoLabel = new TQLabel(i18n("Enter categories: (e.g. Desserts Pastas \"Main Dishes\")"),categoryFrame); + categoryInfoLabel->setTextFormat( TQt::RichText ); + categoryFrameLayout->addMultiCellWidget( categoryInfoLabel, 0, 0, 0, 1 ); + + categoriesAllEdit = new TQLineEdit( categoryFrame, "categoriesAllEdit" ); + + categoryFrameLayout->addWidget( categoriesAllEdit, 1, 1 ); + + textLabel1_5 = new TQLabel( categoryFrame, "textLabel1_5" ); + + categoryFrameLayout->addWidget( textLabel1_5, 1, 0 ); + + textLabel1_3_3 = new TQLabel( categoryFrame, "textLabel1_3_3" ); + + categoryFrameLayout->addWidget( textLabel1_3_3, 3, 0 ); + + categoriesAnyEdit = new TQLineEdit( categoryFrame, "categoriesAnyEdit" ); + + categoryFrameLayout->addWidget( categoriesAnyEdit, 2, 1 ); + + textLabel1_2_3 = new TQLabel( categoryFrame, "textLabel1_2_3" ); + + categoryFrameLayout->addWidget( textLabel1_2_3, 2, 0 ); + + categoriesNotEdit = new TQLineEdit( categoryFrame, "categoriesNotEdit" ); + + categoryFrameLayout->addWidget( categoriesNotEdit, 3, 1 ); + parametersFrameLayout->addWidget( categoryFrame ); + spacer3_2_3_2 = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Preferred ); + parametersFrameLayout->addItem( spacer3_2_3_2 ); + + + authorsButton = new TQPushButton( parametersFrame, "authorsButton" ); + authorsButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( authorsButton ); + + authorsFrame = new TQFrame( parametersFrame, "authorsFrame" ); + authorsFrame->setFrameShape( TQFrame::StyledPanel ); + authorsFrame->setFrameShadow( TQFrame::Raised ); + authorsFrameLayout = new TQGridLayout( authorsFrame, 1, 1, 3, 3, "authorsFrameLayout"); + + TQLabel *authorsInfoLabel = new TQLabel(i18n("Enter author name (e.g. Smith or \"Jane Doe\")"),authorsFrame); + authorsInfoLabel->setTextFormat( TQt::RichText ); + authorsFrameLayout->addMultiCellWidget( authorsInfoLabel, 0, 0, 0, 1 ); + + textLabel1_2_4 = new TQLabel( authorsFrame, "textLabel1_2_4" ); + + authorsFrameLayout->addWidget( textLabel1_2_4, 1, 0 ); + + textLabel1_6 = new TQLabel( authorsFrame, "textLabel1_6" ); + + authorsFrameLayout->addWidget( textLabel1_6, 2, 0 ); + + textLabel1_3_4 = new TQLabel( authorsFrame, "textLabel1_3_4" ); + + authorsFrameLayout->addWidget( textLabel1_3_4, 3, 0 ); + + authorsAnyEdit = new TQLineEdit( authorsFrame, "authorsAnyEdit" ); + + authorsFrameLayout->addWidget( authorsAnyEdit, 1, 1 ); + + authorsAllEdit = new TQLineEdit( authorsFrame, "authorsAllEdit" ); + + authorsFrameLayout->addWidget( authorsAllEdit, 2, 1 ); + + authorsWithoutEdit = new TQLineEdit( authorsFrame, "authorsWithoutEdit" ); + + authorsFrameLayout->addWidget( authorsWithoutEdit, 3, 1 ); + parametersFrameLayout->addWidget( authorsFrame ); + spacer3_2_3 = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Preferred ); + parametersFrameLayout->addItem( spacer3_2_3 ); + + + servingsButton = new TQPushButton( parametersFrame, "servingsButton" ); + servingsButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( servingsButton ); + + servingsFrame = new TQFrame( parametersFrame, "servingsFrame" ); + servingsFrame->setFrameShape( TQFrame::StyledPanel ); + servingsFrame->setFrameShadow( TQFrame::Raised ); + servingsFrameLayout = new TQVBoxLayout( servingsFrame, 3, 3, "servingsFrameLayout"); + + enableServingsCheckBox = new TQCheckBox( servingsFrame, "enableServingsCheckBox" ); + servingsFrameLayout->addWidget( enableServingsCheckBox ); + + layout5 = new TQHBoxLayout( 0, 0, 3, "layout5"); + + servingsComboBox = new TQComboBox( FALSE, servingsFrame, "servingsComboBox" ); + servingsComboBox->setEnabled( FALSE ); + servingsComboBox->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)0, 1, 0, servingsComboBox->sizePolicy().hasHeightForWidth() ) ); + layout5->addWidget( servingsComboBox ); + + servingsSpinBox = new TQSpinBox( servingsFrame, "servingsSpinBox" ); + servingsSpinBox->setEnabled( FALSE ); + servingsSpinBox->setMinValue( 1 ); + servingsSpinBox->setMaxValue( 9999 ); + layout5->addWidget( servingsSpinBox ); + servingsFrameLayout->addLayout( layout5 ); + parametersFrameLayout->addWidget( servingsFrame ); + spacer3_2_2 = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Preferred ); + parametersFrameLayout->addItem( spacer3_2_2 ); + + + prepTimeButton = new TQPushButton( parametersFrame, "prepTimeButton" ); + prepTimeButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( prepTimeButton ); + + prepTimeFrame = new TQFrame( parametersFrame, "prepTimeFrame" ); + prepTimeFrame->setFrameShape( TQFrame::StyledPanel ); + prepTimeFrame->setFrameShadow( TQFrame::Raised ); + prepTimeFrameLayout = new TQVBoxLayout( prepTimeFrame, 3, 3, "prepTimeFrameLayout"); + + enablePrepTimeCheckBox = new TQCheckBox( prepTimeFrame, "enablePrepTimeCheckBox" ); + prepTimeFrameLayout->addWidget( enablePrepTimeCheckBox ); + + layout6 = new TQHBoxLayout( 0, 0, 3, "layout6"); + + prepTimeComboBox = new TQComboBox( FALSE, prepTimeFrame, "prepTimeComboBox" ); + prepTimeComboBox->setEnabled( FALSE ); + prepTimeComboBox->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)0, 1, 0, prepTimeComboBox->sizePolicy().hasHeightForWidth() ) ); + layout6->addWidget( prepTimeComboBox ); + + prepTimeEdit = new TQTimeEdit( prepTimeFrame, "prepTimeEdit" ); + prepTimeEdit->setEnabled( FALSE ); + prepTimeEdit->setDisplay( int( TQTimeEdit::Minutes | TQTimeEdit::Hours ) ); + layout6->addWidget( prepTimeEdit ); + prepTimeFrameLayout->addLayout( layout6 ); + parametersFrameLayout->addWidget( prepTimeFrame ); + spacer15 = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Preferred ); + parametersFrameLayout->addItem( spacer15 ); + + + instructionsButton = new TQPushButton( parametersFrame, "instructionsButton" ); + instructionsButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( instructionsButton ); + + instructionsFrame = new TQFrame( parametersFrame, "instructionsFrame" ); + instructionsFrame->setFrameShape( TQFrame::StyledPanel ); + instructionsFrame->setFrameShadow( TQFrame::Raised ); + instructionsFrameLayout = new TQVBoxLayout( instructionsFrame, 5, 3, "instructionsFrameLayout"); + + requireAllInstructions = new TQCheckBox( i18n("Require All Words"), instructionsFrame ); + instructionsFrameLayout->addWidget( requireAllInstructions ); + + TQHBox *instructionsHBox = new TQHBox(instructionsFrame); + /*TQLabel *instructionsInfoLabel = */new TQLabel(i18n("Keywords:"),instructionsHBox); + + instructionsEdit = new TQLineEdit( instructionsHBox, "instructionsEdit" ); + instructionsFrameLayout->addWidget( instructionsHBox ); + + parametersFrameLayout->addWidget( instructionsFrame ); + instructionsFrameSpacer = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Preferred ); + parametersFrameLayout->addItem( instructionsFrameSpacer ); + + + metaDataButton = new TQPushButton( parametersFrame, "metaDataButton" ); + metaDataButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( metaDataButton ); + + metaDataFrame = new TQFrame( parametersFrame, "metaDataFrame" ); + metaDataFrame->setFrameShape( TQFrame::StyledPanel ); + metaDataFrame->setFrameShadow( TQFrame::Raised ); + metaDataFrameLayout = new TQVBoxLayout( metaDataFrame, 5, 3, "metaDataFrameLayout"); + + TQLabel *createdLabel = new TQLabel( i18n("Created:"), metaDataFrame ); + metaDataFrameLayout->addWidget( createdLabel ); + + TQHBox *createdHBox = new TQHBox(metaDataFrame); + createdStartDateEdit = new KDateEdit(createdHBox,"createdStartEdit"); + createdStartDateEdit->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::Preferred ); + (void)new TQLabel(" - ",createdHBox); + createdEndDateEdit = new KDateEdit(createdHBox,"createdEndEdit"); + createdEndDateEdit->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::Preferred ); + metaDataFrameLayout->addWidget( createdHBox ); + + TQLabel *modifiedLabel = new TQLabel( i18n("Modified:"), metaDataFrame ); + metaDataFrameLayout->addWidget( modifiedLabel ); + + TQHBox *modifiedHBox = new TQHBox(metaDataFrame); + modifiedStartDateEdit = new KDateEdit(modifiedHBox,"modifiedStartEdit"); + modifiedStartDateEdit->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::Preferred ); + (void)new TQLabel(" - ",modifiedHBox); + modifiedEndDateEdit = new KDateEdit(modifiedHBox,"modifiedEndEdit"); + modifiedEndDateEdit->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::Preferred ); + metaDataFrameLayout->addWidget( modifiedHBox ); + + TQLabel *accessedLabel = new TQLabel( i18n("Last Accessed:"), metaDataFrame ); + metaDataFrameLayout->addWidget( accessedLabel ); + + TQHBox *accessedHBox = new TQHBox(metaDataFrame); + accessedStartDateEdit = new KDateEdit(accessedHBox,"accessedStartEdit"); + accessedStartDateEdit->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::Preferred ); + (void)new TQLabel(" - ",accessedHBox); + accessedEndDateEdit = new KDateEdit(accessedHBox,"accessedEndEdit"); + accessedEndDateEdit->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::Preferred ); + metaDataFrameLayout->addWidget( accessedHBox ); + + parametersFrameLayout->addWidget( metaDataFrame ); + metaDataFrameSpacer = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Preferred ); + parametersFrameLayout->addItem( metaDataFrameSpacer ); + + //=============RATINGS FRAME===========// + ratingsButton = new TQPushButton( parametersFrame, "ratingsButton" ); + ratingsButton->setToggleButton( TRUE ); + parametersFrameLayout->addWidget( ratingsButton ); + + ratingButtonGroup = new TQButtonGroup( parametersFrame, "ratingButtonGroup" ); + ratingButtonGroup->setLineWidth( 0 ); + ratingButtonGroup->setColumnLayout(0, TQt::Vertical ); + ratingButtonGroup->layout()->setSpacing( 5 ); + ratingButtonGroup->layout()->setMargin( 3 ); + ratingButtonGroupLayout = new TQVBoxLayout( ratingButtonGroup->layout() ); + ratingButtonGroupLayout->setAlignment( TQt::AlignTop ); + + ratingAvgRadioButton = new TQRadioButton( ratingButtonGroup, "ratingAvgRadioButton" ); + ratingAvgRadioButton->setChecked( TRUE ); + ratingButtonGroupLayout->addWidget( ratingAvgRadioButton ); + + ratingAvgFrame = new TQFrame( ratingButtonGroup, "ratingAvgFrame" ); + ratingAvgFrame->setLineWidth( 0 ); + ratingAvgFrameLayout = new TQHBoxLayout( ratingAvgFrame, 2, 2, "ratingAvgFrameLayout"); + + avgStarsEdit = new FractionInput( ratingAvgFrame ); + avgStarsEdit->setAllowRange(true); + ratingAvgFrameLayout->addWidget( avgStarsEdit ); + + avgStarsLabel = new TQLabel( ratingAvgFrame, "avgStarsLabel" ); + ratingAvgFrameLayout->addWidget( avgStarsLabel ); + ratingButtonGroupLayout->addWidget( ratingAvgFrame ); + + criterionRadioButton = new TQRadioButton( ratingButtonGroup, "criterionRadioButton" ); + ratingButtonGroupLayout->addWidget( criterionRadioButton ); + + criterionFrame = new TQFrame( ratingButtonGroup, "criterionFrame" ); + criterionFrame->setEnabled( FALSE ); + criterionFrame->setLineWidth( 0 ); + criterionFrameLayout = new TQVBoxLayout( criterionFrame, 2, 2, "criterionFrameLayout"); + + layout12 = new TQHBoxLayout( 0, 0, 6, "layout12"); + + criteriaComboBox = new CriteriaComboBox( FALSE, criterionFrame, database ); + criteriaComboBox->setEditable( false ); + criteriaComboBox->reload(); + layout12->addWidget( criteriaComboBox ); + + starsWidget = new FractionInput( criterionFrame ); + starsWidget->setAllowRange(true); + starsWidget->setSizePolicy( TQSizePolicy::Ignored, TQSizePolicy::Preferred ); + layout12->addWidget( starsWidget ); + + + addCriteriaButton = new TQPushButton( criterionFrame, "addCriteriaButton" ); + addCriteriaButton->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)0, (TQSizePolicy::SizeType)0, 0, 0, addCriteriaButton->sizePolicy().hasHeightForWidth() ) ); + addCriteriaButton->setMaximumSize( TQSize( 30, 30 ) ); + layout12->addWidget( addCriteriaButton ); +#if 0 + removeCriteriaButton = new TQPushButton( criterionFrame, "removeCriteriaButton" ); + removeCriteriaButton->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)0, (TQSizePolicy::SizeType)0, 0, 0, removeCriteriaButton->sizePolicy().hasHeightForWidth() ) ); + removeCriteriaButton->setMaximumSize( TQSize( 30, 30 ) ); + layout12->addWidget( removeCriteriaButton ); +#endif + criterionFrameLayout->addLayout( layout12 ); + + criteriaListView = new TDEListView( criterionFrame, "criteriaListView" ); + criteriaListView->setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Minimum ); + criteriaListView->addColumn( i18n( "Criterion" ) ); + criteriaListView->addColumn( i18n( "Stars" ) ); + criterionFrameLayout->addWidget( criteriaListView ); + ratingButtonGroupLayout->addWidget( criterionFrame ); + + parametersFrameLayout->addWidget( ratingButtonGroup ); + ratingsFrameSpacer = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum, TQSizePolicy::Expanding ); + parametersFrameLayout->addItem( ratingsFrameSpacer ); + + + scrollView1->addChild( parametersFrame ); + layout7->addWidget( scrollView1 ); + + layout9 = new TQHBoxLayout( 0, 0, 3, "layout9"); + + clearButton = new KPushButton( this, "clearButton" ); + clearButton->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)0, 0, 0, clearButton->sizePolicy().hasHeightForWidth() ) ); + layout9->addWidget( clearButton ); + spacer3 = new TQSpacerItem( 110, 0, TQSizePolicy::Expanding, TQSizePolicy::Minimum ); + layout9->addItem( spacer3 ); + + findButton = new KPushButton( this, "findButton" ); + findButton->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)1, (TQSizePolicy::SizeType)0, 0, 0, findButton->sizePolicy().hasHeightForWidth() ) ); + layout9->addWidget( findButton ); + layout7->addLayout( layout9 ); + AdvancedSearchDialogLayout->addLayout( layout7 ); + + resultsListView = new TDEListView( this, "resultsListView" ); + resultsListView->setSelectionMode( TQListView::Extended ); + resultsListView->setSizePolicy( TQSizePolicy( (TQSizePolicy::SizeType)7, (TQSizePolicy::SizeType)7, 0, 1, resultsListView->sizePolicy().hasHeightForWidth() ) ); + AdvancedSearchDialogLayout->addWidget( resultsListView ); + languageChange(); + clearWState( WState_Polished ); + /// + ///END OF AUTOMATICALLY GENERATED GUI CODE/// + /// + + resultsListView->setSizePolicy( TQSizePolicy::MinimumExpanding, TQSizePolicy::Preferred ); + scrollView1->setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored ); + + AdvancedSearchDialogLayout->setStretchFactor( resultsListView, 2 ); + + scrollView1->setHScrollBarMode( TQScrollView::AlwaysOff ); + scrollView1->setResizePolicy( TQScrollView::AutoOneFit ); + + TDEConfig *config = TDEGlobal::config(); + config->setGroup( "Advanced" ); + bool show_id = config->readBoolEntry( "ShowID", false ); + resultsListView->addColumn( i18n( "Title" ) ); + resultsListView->addColumn( i18n( "Id" ), show_id ? -1 : 0 ); + + actionHandler = new RecipeActionsHandler( resultsListView, database, RecipeActionsHandler::Open | RecipeActionsHandler::Edit | RecipeActionsHandler::Export | RecipeActionsHandler::CopyToClipboard | RecipeActionsHandler::Remove ); + + connect( titleEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( ingredientsAllEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( ingredientsAnyEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( ingredientsWithoutEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( authorsAnyEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( authorsAllEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( authorsWithoutEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( categoriesNotEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( categoriesAnyEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( categoriesAllEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( ingredientsWithoutEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + connect( instructionsEdit, TQ_SIGNAL( returnPressed() ), TQ_SLOT( search() ) ); + + connect( findButton, TQ_SIGNAL( clicked() ), TQ_SLOT( search() ) ); + connect( clearButton, TQ_SIGNAL( clicked() ), TQ_SLOT( clear() ) ); + + connect( enableServingsCheckBox, TQ_SIGNAL( toggled( bool ) ), servingsSpinBox, TQ_SLOT( setEnabled( bool ) ) ); + connect( enableServingsCheckBox, TQ_SIGNAL( toggled( bool ) ), servingsComboBox, TQ_SLOT( setEnabled( bool ) ) ); + connect( enablePrepTimeCheckBox, TQ_SIGNAL( toggled( bool ) ), prepTimeEdit, TQ_SLOT( setEnabled( bool ) ) ); + connect( enablePrepTimeCheckBox, TQ_SIGNAL( toggled( bool ) ), prepTimeComboBox, TQ_SLOT( setEnabled( bool ) ) ); + + connect( titleButton, TQ_SIGNAL( toggled( bool ) ), titleFrame, TQ_SLOT( setShown( bool ) ) ); + connect( ingredientButton, TQ_SIGNAL( toggled( bool ) ), ingredientFrame, TQ_SLOT( setShown( bool ) ) ); + connect( authorsButton, TQ_SIGNAL( toggled( bool ) ), authorsFrame, TQ_SLOT( setShown( bool ) ) ); + connect( categoriesButton, TQ_SIGNAL( toggled( bool ) ), categoryFrame, TQ_SLOT( setShown( bool ) ) ); + connect( servingsButton, TQ_SIGNAL( toggled( bool ) ), servingsFrame, TQ_SLOT( setShown( bool ) ) ); + connect( prepTimeButton, TQ_SIGNAL( toggled( bool ) ), prepTimeFrame, TQ_SLOT( setShown( bool ) ) ); + connect( instructionsButton, TQ_SIGNAL( toggled( bool ) ), instructionsFrame, TQ_SLOT( setShown( bool ) ) ); + connect( metaDataButton, TQ_SIGNAL( toggled( bool ) ), metaDataFrame, TQ_SLOT( setShown( bool ) ) ); + connect( ratingsButton, TQ_SIGNAL( toggled( bool ) ), ratingButtonGroup, TQ_SLOT( setShown( bool ) ) ); + + connect( titleButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + connect( ingredientButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + connect( authorsButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + connect( categoriesButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + connect( servingsButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + connect( prepTimeButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + connect( instructionsButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + connect( metaDataButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + connect( ratingsButton, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( buttonSwitched() ) ); + + connect( ratingButtonGroup, TQ_SIGNAL( clicked( int ) ), this, TQ_SLOT( activateRatingOption( int ) ) ); + + connect( addCriteriaButton, TQ_SIGNAL( clicked() ), this, TQ_SLOT( slotAddRatingCriteria() ) ); + + titleFrame->setShown(false); + ingredientFrame->setShown(false); + authorsFrame->setShown(false); + categoryFrame->setShown(false); + servingsFrame->setShown(false); + prepTimeFrame->setShown(false); + instructionsFrame->setShown(false); + metaDataFrame->setShown(false); + ratingButtonGroup->setShown(false); + + connect( actionHandler, TQ_SIGNAL( recipeSelected( int, int ) ), TQ_SIGNAL( recipeSelected( int, int ) ) ); + connect( actionHandler, TQ_SIGNAL( recipesSelected( const TQValueList<int> &, int ) ), TQ_SIGNAL( recipesSelected( const TQValueList<int> &, int ) ) ); + + connect( database, TQ_SIGNAL( recipeRemoved( int ) ), TQ_SLOT( removeRecipe( int ) ) ); + + clear(); + + TDEPopupMenu *kpop = new TDEPopupMenu( criteriaListView ); + kpop->insertItem( i18n( "&Delete" ), this, TQ_SLOT( slotRemoveRatingCriteria() ), Key_Delete ); +} + +AdvancedSearchDialog::~AdvancedSearchDialog() +{} + +void AdvancedSearchDialog::languageChange() +{ + titleButton->setText( TQString("%1 >>").arg(i18n("Title")) ); + textLabel1_4->setText( i18n( "Search using the following criteria:" ) ); + ingredientButton->setText( TQString("%1 >>").arg(i18n("Ingredients")) ); + textLabel1_2->setText( i18n( "Uses any of:" ) ); + textLabel1->setText( i18n( "Uses all:" ) ); + textLabel1_3->setText( i18n( "Without:" ) ); + categoriesButton->setText( i18n( "Categories >>" ) ); + textLabel1_5->setText( i18n( "In all:" ) ); + textLabel1_3_3->setText( i18n( "Not in:" ) ); + textLabel1_2_3->setText( i18n( "In any of:" ) ); + authorsButton->setText( TQString("%1 >>").arg(i18n("Authors")) ); + textLabel1_2_4->setText( i18n( "By any of:" ) ); + textLabel1_6->setText( i18n( "By all:" ) ); + textLabel1_3_4->setText( i18n( "Not by:" ) ); + servingsButton->setText( TQString("%1 >>").arg(i18n("Yield")) ); + enableServingsCheckBox->setText( i18n( "Enabled" ) ); + servingsComboBox->clear(); + servingsComboBox->insertItem( i18n( "Yields at least:" ) ); + servingsComboBox->insertItem( i18n( "Yields at most:" ) ); + servingsComboBox->insertItem( i18n( "Yields about:" ) ); + prepTimeButton->setText( TQString("%1 >>").arg(i18n("Preparation Time")) ); + enablePrepTimeCheckBox->setText( i18n( "Enabled" ) ); + prepTimeComboBox->clear(); + prepTimeComboBox->insertItem( i18n( "Ready in at most:" ) ); + prepTimeComboBox->insertItem( i18n( "Ready in about:" ) ); + instructionsButton->setText( TQString("%1 >>").arg(i18n("Instructions")) ); + metaDataButton->setText( TQString("%1 >>").arg(i18n("Meta Data")) ); + clearButton->setText( i18n( "C&lear" ) ); + findButton->setText( i18n( "&Search" ) ); + ratingAvgRadioButton->setText( i18n( "By average:" ) ); + avgStarsLabel->setText( i18n( "stars" ) ); + criterionRadioButton->setText( i18n( "By criteria:" ) ); + addCriteriaButton->setText( i18n( "+" ) ); + //removeCriteriaButton->setText( i18n( "-" ) ); + criteriaListView->header()->setLabel( 0, i18n( "Criteria" ) ); + criteriaListView->header()->setLabel( 1, i18n( "Stars" ) ); + ratingsButton->setText( TQString("%1 >>").arg(i18n("Ratings")) ); +} + +void AdvancedSearchDialog::removeRecipe( int id ) +{ + TQListViewItemIterator iterator( resultsListView ); + while ( iterator.current() ) { + if ( iterator.current()->rtti() == 1000 ) { + RecipeListItem * recipe_it = ( RecipeListItem* ) iterator.current(); + if ( recipe_it->recipeID() == id ) + delete recipe_it; + } + ++iterator; + } +} + +void AdvancedSearchDialog::clear() +{ + resultsListView->clear(); + authorsAllEdit->clear(); + authorsWithoutEdit->clear(); + authorsAnyEdit->clear(); + categoriesAllEdit->clear(); + categoriesNotEdit->clear(); + categoriesAnyEdit->clear(); + ingredientsAllEdit->clear(); + ingredientsWithoutEdit->clear(); + ingredientsAnyEdit->clear(); + titleEdit->clear(); + instructionsEdit->clear(); + + createdStartDateEdit->setDate( TQDate() ); + createdEndDateEdit->setDate( TQDate() ); + modifiedStartDateEdit->setDate( TQDate() ); + modifiedEndDateEdit->setDate( TQDate() ); + accessedStartDateEdit->setDate( TQDate() ); + accessedEndDateEdit->setDate( TQDate() ); + + servingsSpinBox->setValue( 1 ); + prepTimeEdit->setTime( TQTime(0,0) ); + + enablePrepTimeCheckBox->setChecked(false); + enableServingsCheckBox->setChecked(false); + + requireAllTitle->setChecked(false); + requireAllInstructions->setChecked(false); + + ratingAvgRadioButton->setChecked(true); + activateRatingOption(0); + avgStarsEdit->clear(); + criteriaListView->clear(); + starsWidget->clear(); +} + +void AdvancedSearchDialog::activateRatingOption( int button_id ) +{ + switch ( button_id ) { + case 0: + criterionFrame->setEnabled( false ); + ratingAvgFrame->setEnabled( true ); + break; + case 1: + criterionFrame->setEnabled( true ); + ratingAvgFrame->setEnabled( false ); + break; + default: + break; + } +} + +void AdvancedSearchDialog::buttonSwitched() +{ + const TQObject *sent = sender(); + + if ( sent->inherits("TQPushButton") ) { + TQPushButton *pushed = (TQPushButton*) sent; + + TQString suffix = ( pushed->state() == TQButton::On ) ? " <<" : " >>"; + pushed->setText( pushed->text().left( pushed->text().length() - 3 ) + suffix ); + } +} + +void AdvancedSearchDialog::search() +{ + TDEApplication::setOverrideCursor( KCursor::waitCursor() ); + + //we need to load more than just the title because we'll be doing further refining of the search + int load_items = RecipeDB::Title | RecipeDB::NamesOnly | RecipeDB::Noatime; + if ( !authorsAllEdit->text().isEmpty() || !authorsWithoutEdit->text().isEmpty() ) + load_items |= RecipeDB::Authors; + if ( !ingredientsAllEdit->text().isEmpty() || !ingredientsWithoutEdit->text().isEmpty() ) + load_items |= RecipeDB::Ingredients; + if ( !categoriesAllEdit->text().isEmpty() || !categoriesNotEdit->text().isEmpty() ) + load_items |= RecipeDB::Categories; + if ( (ratingAvgRadioButton->isChecked() && !avgStarsEdit->isEmpty()) || (criterionRadioButton->isChecked() && criteriaListView->firstChild()) ) + load_items |= RecipeDB::Ratings; + + RecipeSearchParameters parameters; + + parameters.titleKeywords = split(titleEdit->text(),true); + parameters.requireAllTitleWords = requireAllTitle->isChecked(); + + parameters.instructionsKeywords = split(instructionsEdit->text(),true); + parameters.requireAllInstructionsWords = requireAllInstructions->isChecked(); + + parameters.ingsOr = split(ingredientsAnyEdit->text(),true); + parameters.catsOr = split(categoriesAnyEdit->text(),true); + parameters.authorsOr = split(authorsAnyEdit->text(),true); + + if ( enablePrepTimeCheckBox->isChecked() ) + parameters.prep_time = prepTimeEdit->time(); + parameters.prep_param = prepTimeComboBox->currentItem(); + + if ( enableServingsCheckBox->isChecked() ) + parameters.servings = servingsSpinBox->value(); + parameters.servings_param = servingsComboBox->currentItem(); + + parameters.createdDateBegin = createdStartDateEdit->date(); + parameters.createdDateEnd = createdEndDateEdit->date(); + if ( parameters.createdDateEnd.date().isValid() ) + parameters.createdDateEnd = parameters.createdDateEnd.addDays(1); //we want to include the given day in the search + + parameters.modifiedDateBegin = modifiedStartDateEdit->date(); + parameters.modifiedDateEnd = modifiedEndDateEdit->date(); + if ( parameters.modifiedDateEnd.date().isValid() ) + parameters.modifiedDateEnd = parameters.modifiedDateEnd.addDays(1); //we want to include the given day in the search + + parameters.accessedDateBegin = accessedStartDateEdit->date(); + parameters.accessedDateEnd = accessedEndDateEdit->date(); + if ( parameters.accessedDateEnd.date().isValid() ) + parameters.accessedDateEnd = parameters.accessedDateEnd.addDays(1); //we want to include the given day in the search + + START_TIMER("Doing database SQL search"); + RecipeList allRecipes; + database->search( &allRecipes, load_items, parameters ); + END_TIMER(); + + /* + * Ideally, would be done by the above SQL query, but I have no idea how to accomplish this. + */ + + START_TIMER("Further narrowing the search (no SQL)"); + TQStringList items = split(authorsAllEdit->text()); + for ( TQStringList::const_iterator author_it = items.begin(); author_it != items.end(); ++author_it ) { + for ( RecipeList::iterator it = allRecipes.begin(); it != allRecipes.end(); ++it ) { + if ( ( *it ).authorList.findByName( TQRegExp(*author_it,false, true) ).id == -1 ) { + it = allRecipes.remove( it ); + it--; + } + } + } + items = split(authorsWithoutEdit->text()); + for ( TQStringList::const_iterator author_it = items.begin(); author_it != items.end(); ++author_it ) { + for ( RecipeList::iterator it = allRecipes.begin(); it != allRecipes.end(); ++it ) { + if ( ( *it ).authorList.findByName( TQRegExp(*author_it,false,true) ).id != -1 ) { + it = allRecipes.remove( it ); + it--; + } + } + } + + //narrow down by categories + items = split(categoriesAllEdit->text()); + for ( TQStringList::const_iterator cat_it = items.begin(); cat_it != items.end(); ++cat_it ) { + for ( RecipeList::iterator it = allRecipes.begin(); it != allRecipes.end(); ++it ) { + if ( ( *it ).categoryList.findByName( TQRegExp(*cat_it,false,true) ).id == -1 ) { + it = allRecipes.remove( it ); + it--; + } + } + } + items = split(categoriesNotEdit->text()); + for ( TQStringList::const_iterator cat_it = items.begin(); cat_it != items.end(); ++cat_it ) { + for ( RecipeList::iterator it = allRecipes.begin(); it != allRecipes.end(); ++it ) { + if ( ( *it ).categoryList.findByName( TQRegExp(*cat_it,false,true) ).id != -1 ) { + it = allRecipes.remove( it ); + it--; + } + } + } + + //narrow down by ingredients + items = split(ingredientsAllEdit->text()); + for ( TQStringList::const_iterator ing_it = items.begin(); ing_it != items.end(); ++ing_it ) { + for ( RecipeList::iterator it = allRecipes.begin(); it != allRecipes.end(); ++it ) { + if ( ( *it ).ingList.findByName( TQRegExp(*ing_it,false,true) ).ingredientID == -1 ) { + it = allRecipes.remove( it ); + it--; + } + } + } + items = split(ingredientsWithoutEdit->text()); + for ( TQStringList::const_iterator ing_it = items.begin(); ing_it != items.end(); ++ing_it ) { + for ( RecipeList::iterator it = allRecipes.begin(); it != allRecipes.end(); ++it ) { + if ( ( *it ).ingList.findByName( TQRegExp(*ing_it,false,true) ).ingredientID != -1 ) { + it = allRecipes.remove( it ); + it--; + } + } + } + + if ( ratingAvgRadioButton->isChecked() && !avgStarsEdit->isEmpty() ) { + for ( RecipeList::iterator recipe_it = allRecipes.begin(); recipe_it != allRecipes.end(); ++recipe_it ) { + double sum = 0; + int count = 0; + + for ( RatingList::iterator rating_it = (*recipe_it).ratingList.begin(); rating_it != (*recipe_it).ratingList.end(); ++rating_it ) { + sum += (*rating_it).average(); + ++count; + } + + if ( count != 0 ) { + double average = sum/count; + + double stars; + double stars_offset; + avgStarsEdit->value(stars,stars_offset); + if ( stars_offset < 1e-10 ) { //if an exact amount is given, search for an amount within 0.5 of what is given + //we can get negatives here, but it really doesn't matter + stars = stars-0.5; + stars_offset = 1.0; + } + + + kdDebug()<<"average for "<<(*recipe_it).title<<" "<<average<<endl; + if ( average < stars || average > stars + stars_offset ) { + recipe_it = allRecipes.remove( recipe_it ); + recipe_it--; + } + } + else { + recipe_it = allRecipes.remove( recipe_it ); + recipe_it--; + } + } + } + + //TODO: Clean this up and/or do it more efficiently + if ( criterionRadioButton->isChecked() && criteriaListView->firstChild() ) { + for ( RecipeList::iterator recipe_it = allRecipes.begin(); recipe_it != allRecipes.end(); ++recipe_it ) { + TQMap< int, double > idSumMap; + TQMap< int, int > idCountMap; + + for ( RatingList::const_iterator rating_it = (*recipe_it).ratingList.begin(); rating_it != (*recipe_it).ratingList.end(); ++rating_it ) { + for ( RatingCriteriaList::const_iterator rc_it = (*rating_it).ratingCriteriaList.begin(); rc_it != (*rating_it).ratingCriteriaList.end(); ++rc_it ) { + TQMap< int, double >::iterator sum_it = idSumMap.find((*rc_it).id); + if ( sum_it == idSumMap.end() ) + sum_it = idSumMap.insert((*rc_it).id,0); + (*sum_it) += (*rc_it).stars; + + TQMap< int, int >::iterator count_it = idCountMap.find((*rc_it).id); + if ( count_it == idCountMap.end() ) + count_it = idCountMap.insert((*rc_it).id,0); + (*count_it)++; + } + } + + for ( TQListViewItem *item = criteriaListView->firstChild(); item; item = item->nextSibling() ) { + Ingredient i; i.setAmount( item->text(1) ); + double stars = i.amount; + double stars_offset = i.amount_offset; + + if ( stars_offset < 1e-10 ) { //if an exact amount is given, search for an amount within 0.5 of what is given + //we can get negatives here, but it really doesn't matter + stars = stars-0.5; + stars_offset = 1.0; + } + + int id = item->text(2).toInt(); + + TQMap< int, double >::iterator sum_it = idSumMap.find(id); + if ( sum_it != idSumMap.end() ) { + TQMap< int, int >::iterator count_it = idCountMap.find(id); + double average = (*sum_it)/(*count_it); + + if ( average < stars || average > stars + stars_offset ) { + recipe_it = allRecipes.remove( recipe_it ); + recipe_it--; + break; + } + } + else { + recipe_it = allRecipes.remove( recipe_it ); + recipe_it--; + break; + } + } + } + } + END_TIMER(); + + + //now display the recipes left + resultsListView->clear(); + for ( RecipeList::const_iterator it = allRecipes.begin(); it != allRecipes.end(); ++it ) { + ( void ) new RecipeListItem( resultsListView, *it ); + } + + if ( !resultsListView->firstChild() ) { + ( void ) new TQListViewItem( resultsListView, "--- "+i18n("No matching recipes found")+" ---"); + } + + TDEApplication::restoreOverrideCursor(); +} + +TQStringList AdvancedSearchDialog::split( const TQString &text, bool sql_wildcards ) const +{ + TQStringList result; + + // To keep quoted words together, first split on quotes, + // and then split again on the even numbered items + + TQStringList temp = TQStringList::split('"',text,true); + for ( uint i = 0; i < temp.count(); ++i ) { + if ( i & 1 ) //odd + result += temp[i].stripWhiteSpace(); + else //even + result += TQStringList::split(' ',temp[i]); + } + + if ( sql_wildcards ) { + for ( TQStringList::iterator it = result.begin(); it != result.end(); ++it ) { + (*it).replace("%","\\%"); + (*it).replace("_","\\_"); + + (*it).replace("*","%"); + (*it).replace("?","_"); + } + } + + return result; +} + +void AdvancedSearchDialog::slotAddRatingCriteria() +{ + TQListViewItem * it = new TQListViewItem(criteriaListView,criteriaComboBox->currentText()); + + MixedNumber stars; + double stars_offset; + starsWidget->value(stars,stars_offset); + TQString stars_str = stars.toString(); + if ( stars_offset > 0 ) + stars_str += "-"+MixedNumber( stars + stars_offset ).toString(); + else if ( stars.toDouble() <= 1e-10 ) + stars_str = ""; + + it->setText(1,stars_str); + it->setText(2,TQString::number(criteriaComboBox->criteriaID(criteriaComboBox->currentItem()))); +} + +void AdvancedSearchDialog::slotRemoveRatingCriteria() +{ + delete criteriaListView->selectedItem(); +} + +#include "advancedsearchdialog.moc" |