From 4170df7fc8657a867b202e0aaff5ce2fc6b8b509 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Fri, 30 Mar 2018 20:57:14 +0200 Subject: [PATCH] Added filtering by ingredient to search window. --- gui/openrecipedialog.cpp | 23 +++++++++-------- gui/openrecipedialog.h | 4 +-- model/database/recipedatabase.cpp | 41 +++++++++++++++++++++++++++---- model/database/recipedatabase.h | 2 ++ 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp index 648beb9..4c961cd 100644 --- a/gui/openrecipedialog.cpp +++ b/gui/openrecipedialog.cpp @@ -11,17 +11,17 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) : ui->ingredientsListView->setModel(&this->ingredientsModel); ui->tagsListView->setModel(&this->tagsModel); - connect(ui->ingredientsListView->selectionModel(), - SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + QObject::connect(ui->ingredientsListView->selectionModel(), + SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, - SLOT(on_ingredientsListView_selectionChanged(QItemSelection))); + SLOT(onIngredientsListViewSelectionChanged(QItemSelection))); } OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){ this->recipeDB = recipeDB; this->populateIngredientsList(); this->populateTagsList(); - this->populateRecipesTable(); + this->populateRecipesTable(this->recipeDB->retrieveAllRecipes()); } OpenRecipeDialog::~OpenRecipeDialog() @@ -33,9 +33,8 @@ Recipe OpenRecipeDialog::getSelectedRecipe(){ return this->selectedRecipe; } -void OpenRecipeDialog::populateRecipesTable(){ +void OpenRecipeDialog::populateRecipesTable(vector recipes){ this->recipeTableModel.clear(); - vector recipes = this->recipeDB->retrieveAllRecipes(); this->recipeTableModel.setRecipes(recipes); ui->recipeTableView->resizeColumnsToContents(); ui->recipeTableView->show(); @@ -69,9 +68,10 @@ void OpenRecipeDialog::on_deleteRecipeButton_clicked(){ bool success = this->recipeDB->deleteRecipe(r.getName()); if (!success){ QMessageBox::critical(this, QString::fromStdString("Unable to Delete"), QString::fromStdString("Could not delete recipe "+r.getName())); + } else { + this->populateRecipesTable(this->recipeDB->retrieveAllRecipes()); } } - this->populateRecipesTable(); } } @@ -80,13 +80,12 @@ void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index this->close(); } -void OpenRecipeDialog::on_ingredientsListView_selectionChanged(const QItemSelection &selection){ - printf("Selection changed!\n"); +void OpenRecipeDialog::onIngredientsListViewSelectionChanged(const QItemSelection &selection){ vector ingredients; - for (QModelIndex index : selection.indexes()){ + QModelIndexList indexes = ui->ingredientsListView->selectionModel()->selectedRows(); + for (QModelIndex index : indexes){ Ingredient i = this->ingredientsModel.getIngredients().at(index.row()); ingredients.push_back(i); - printf("Selected: %s\n", i.getName().c_str()); } - + this->populateRecipesTable(this->recipeDB->retrieveRecipesWithIngredients(ingredients)); } diff --git a/gui/openrecipedialog.h b/gui/openrecipedialog.h index 44c56f9..753c206 100644 --- a/gui/openrecipedialog.h +++ b/gui/openrecipedialog.h @@ -30,7 +30,7 @@ class OpenRecipeDialog : public QDialog void on_recipeTableView_doubleClicked(const QModelIndex &index); - void on_ingredientsListView_selectionChanged(const QItemSelection &selection); + void onIngredientsListViewSelectionChanged(const QItemSelection &selection); private: Ui::OpenRecipeDialog *ui; @@ -41,7 +41,7 @@ class OpenRecipeDialog : public QDialog IngredientListModel ingredientsModel; TagListModel tagsModel; - void populateRecipesTable(); + void populateRecipesTable(vector recipes); void populateIngredientsList(); void populateTagsList(); }; diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index 1eeebd3..7e8ab6c 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -158,14 +158,35 @@ Recipe RecipeDatabase::retrieveRandomRecipe(){ } return this->readFromResultTable(t); } - +//TODO: Change this to be more efficient! One query per recipe is not good! vector RecipeDatabase::retrieveAllRecipes(){ - ResultTable t = this->selectFrom("recipe", "name", "ORDER BY name"); + ResultTable t = this->executeSQL("SELECT * FROM recipe ORDER BY name;"); + return this->readRecipesFromTable(t); +} + +vector RecipeDatabase::retrieveRecipesWithIngredients(vector ingredients){ vector recipes; - for (TableRow row : t.rows()){ - recipes.push_back(this->retrieveRecipe(row.at(0))); + if (ingredients.empty()){ + return recipes; } - return recipes; + string filterList = surroundString(ingredients.at(0).getName(), "'"); + for (unsigned int i = 1; i < ingredients.size(); i++){ + filterList += ", " + surroundString(ingredients[i].getName(), "'"); + } + filterList = '(' + filterList + ')'; + ResultTable t = this->executeSQL("SELECT * " + "FROM recipe " + "WHERE recipeId IN (" + " SELECT recipeIngredient.recipeId " + " FROM recipeIngredient " + " INNER JOIN (" + " SELECT ingredientId " + " FROM ingredient " + " WHERE name IN "+filterList+"" + " ) filteredIngredients " + " ON recipeIngredient.ingredientId = filteredIngredients.ingredientId" + ") ORDER BY name;"); + return this->readRecipesFromTable(t); } vector RecipeDatabase::retrieveAllFoodGroups(){ @@ -360,3 +381,13 @@ Recipe RecipeDatabase::readFromResultTable(ResultTable t, int tRow){ r.setTags(this->retrieveTags(id)); return r; } + +//Retrieves recipes from a table with the following format: +// id, name, createdDate, prepTime, cookTime, servings +vector RecipeDatabase::readRecipesFromTable(ResultTable t){ + vector recipes; + for (unsigned int row = 0; row < t.rowCount(); row++){ + recipes.push_back(readFromResultTable(t, row)); + } + return recipes; +} diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index 79ff7bd..f58dd19 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -34,6 +34,7 @@ class RecipeDatabase : public Database Recipe retrieveRecipe(string name); Recipe retrieveRandomRecipe(); vector retrieveAllRecipes(); + vector retrieveRecipesWithIngredients(vector ingredients); vector retrieveAllFoodGroups(); vector retrieveRecipeIngredients(int recipeId); vector retrieveAllIngredients(); @@ -53,6 +54,7 @@ class RecipeDatabase : public Database void ensureTablesExist(); //Read a recipe from a row of a result table. Recipe readFromResultTable(ResultTable t, int row=0); + vector readRecipesFromTable(ResultTable t); }; #endif // RECIPEDATABASE_H