From cc802e5d0d0cfb8eb15dc930f8a7038683f957f0 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Sun, 11 Mar 2018 09:33:48 +0100 Subject: [PATCH 1/7] Fixed new unit dialog, added open recipe dialog. --- RecipeDB.pro | 6 +- gui/newDialogs/newunitdialog.cpp | 8 +- gui/newrecipedialog.cpp | 2 +- gui/newrecipedialog.ui | 28 ++--- .../openrecipedialog.cpp | 0 openrecipedialog.h => gui/openrecipedialog.h | 0 gui/openrecipedialog.ui | 111 ++++++++++++++++++ images.qrc | 1 + images/search_icon.png | Bin 0 -> 9900 bytes openrecipedialog.ui | 19 --- 10 files changed, 133 insertions(+), 42 deletions(-) rename openrecipedialog.cpp => gui/openrecipedialog.cpp (100%) rename openrecipedialog.h => gui/openrecipedialog.h (100%) create mode 100644 gui/openrecipedialog.ui create mode 100644 images/search_icon.png delete mode 100644 openrecipedialog.ui diff --git a/RecipeDB.pro b/RecipeDB.pro index 791ba66..b170e61 100644 --- a/RecipeDB.pro +++ b/RecipeDB.pro @@ -33,7 +33,7 @@ SOURCES += model/recipe/instruction.cpp \ gui/newDialogs/newunitdialog.cpp \ utils/aspectratiopixmaplabel.cpp \ utils/stringutils.cpp \ - openrecipedialog.cpp + gui/openrecipedialog.cpp HEADERS += model/recipe/instruction.h \ model/recipe/recipe.h \ @@ -56,7 +56,7 @@ HEADERS += model/recipe/instruction.h \ gui/newDialogs/newunitdialog.h \ utils/aspectratiopixmaplabel.h \ utils/stringutils.h \ - openrecipedialog.h + gui/openrecipedialog.h LIBS += -ldl \ @@ -65,7 +65,7 @@ FORMS += gui/mainwindow.ui \ gui/newDialogs/newingredientdialog.ui \ gui/newDialogs/newtagdialog.ui \ gui/newDialogs/newunitdialog.ui \ - openrecipedialog.ui + gui/openrecipedialog.ui DISTFILES += \ .gitignore diff --git a/gui/newDialogs/newunitdialog.cpp b/gui/newDialogs/newunitdialog.cpp index d89acaf..e7be030 100644 --- a/gui/newDialogs/newunitdialog.cpp +++ b/gui/newDialogs/newunitdialog.cpp @@ -8,10 +8,8 @@ NewUnitDialog::NewUnitDialog(QWidget *parent) : ui->setupUi(this); ui->typeComboBox->clear(); - ui->typeComboBox->setItemData(0, "Mass"); - ui->typeComboBox->setItemData(1, "Volume"); - ui->typeComboBox->setItemData(2, "Length"); - ui->typeComboBox->setItemData(3, "Misc"); + QStringList list({"Mass", "Volume", "Length", "Misc"}); + ui->typeComboBox->insertItems(0, list); } @@ -23,7 +21,7 @@ NewUnitDialog::~NewUnitDialog() UnitOfMeasure NewUnitDialog::getUnit(){ return UnitOfMeasure(ui->unitNameEdit->text().toLower().toStdString(), ui->pluralNameEdit->text().toLower().toStdString(), - ui->abbreviationEdit->text().toLower().toStdString(), + ui->abbreviationEdit->text().toStdString(), this->getSelectedType(), ui->coefficientSpinBox->value()); } diff --git a/gui/newrecipedialog.cpp b/gui/newrecipedialog.cpp index 93e3ffa..99459dc 100644 --- a/gui/newrecipedialog.cpp +++ b/gui/newrecipedialog.cpp @@ -173,7 +173,7 @@ void NewRecipeDialog::on_newUnitButton_clicked(){ d.show(); if (d.exec() == QDialog::Accepted){ UnitOfMeasure u = d.getUnit(); - if (!this->recipeDB->storeUnitOfMeasure(u)){ + if (!this->recipeDB->storeUnitOfMeasure(u) || u.getName().empty() || u.getNamePlural().empty() || u.getAbbreviation().empty()){ QMessageBox::critical(this, "Error", "Unable to store new unit."); } else { this->populateUnitsBox(); diff --git a/gui/newrecipedialog.ui b/gui/newrecipedialog.ui index e7ef5e9..a470909 100644 --- a/gui/newrecipedialog.ui +++ b/gui/newrecipedialog.ui @@ -26,6 +26,9 @@ :/images/images/icon.png:/images/images/icon.png + + font: 25 "Noto Sans CJK KR"; + true @@ -97,9 +100,7 @@ - Noto Sans CJK KR - 14 - 50 + 3 false false @@ -116,7 +117,9 @@ - PreferAntialias + 3 + false + false @@ -532,9 +535,7 @@ - Noto Sans CJK KR - 14 - 50 + 3 false false @@ -745,9 +746,9 @@ - Liberation Serif - 12 - true + 3 + false + false @@ -765,10 +766,9 @@ - Liberation Serif - 12 - 75 - true + 3 + false + false diff --git a/openrecipedialog.cpp b/gui/openrecipedialog.cpp similarity index 100% rename from openrecipedialog.cpp rename to gui/openrecipedialog.cpp diff --git a/openrecipedialog.h b/gui/openrecipedialog.h similarity index 100% rename from openrecipedialog.h rename to gui/openrecipedialog.h diff --git a/gui/openrecipedialog.ui b/gui/openrecipedialog.ui new file mode 100644 index 0000000..d0fca63 --- /dev/null +++ b/gui/openrecipedialog.ui @@ -0,0 +1,111 @@ + + + OpenRecipeDialog + + + + 0 + 0 + 640 + 480 + + + + Open Recipe + + + + :/images/images/icon.png:/images/images/icon.png + + + true + + + + + + + + + + + + Name + + + + + + + + + + + + + + + + Tag + + + + + + + + + + + + + + + + Ingredient + + + + + + + + + + + + + + + + + :/images/images/search_icon.png:/images/images/search_icon.png + + + + + + + + + + + + + QFrame::NoFrame + + + true + + + + + + + + + + + + + diff --git a/images.qrc b/images.qrc index 2391914..8b12ebf 100644 --- a/images.qrc +++ b/images.qrc @@ -4,5 +4,6 @@ images/icon.png images/plus_icon.png images/minus_icon.png + images/search_icon.png diff --git a/images/search_icon.png b/images/search_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9cac3e7c3e9d6f4a1c26c8e98b2afdfb4e4830a2 GIT binary patch literal 9900 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 Uv5eURACM0!%BskeNSg%z7oSxj?EnA( literal 0 HcmV?d00001 diff --git a/openrecipedialog.ui b/openrecipedialog.ui deleted file mode 100644 index 31f318f..0000000 --- a/openrecipedialog.ui +++ /dev/null @@ -1,19 +0,0 @@ - - - OpenRecipeDialog - - - - 0 - 0 - 640 - 480 - - - - Dialog - - - - - -- 2.34.1 From 17cbeb0d1c606c81a2b9a649131b83f84e89525a Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Sun, 11 Mar 2018 12:53:30 +0100 Subject: [PATCH 2/7] Added table model, having trouble getting it to work. --- RecipeDB.pro | 6 ++-- gui/openrecipedialog.cpp | 13 +++++++ gui/openrecipedialog.h | 8 +++++ model/database/recipedatabase.cpp | 9 +++++ model/database/recipedatabase.h | 1 + model/recipe/recipetablemodel.cpp | 58 +++++++++++++++++++++++++++++++ model/recipe/recipetablemodel.h | 27 ++++++++++++++ userInterface/mainwindow.cpp | 6 ++++ userInterface/mainwindow.h | 3 ++ 9 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 model/recipe/recipetablemodel.cpp create mode 100644 model/recipe/recipetablemodel.h diff --git a/RecipeDB.pro b/RecipeDB.pro index b170e61..1c8f716 100644 --- a/RecipeDB.pro +++ b/RecipeDB.pro @@ -33,7 +33,8 @@ SOURCES += model/recipe/instruction.cpp \ gui/newDialogs/newunitdialog.cpp \ utils/aspectratiopixmaplabel.cpp \ utils/stringutils.cpp \ - gui/openrecipedialog.cpp + gui/openrecipedialog.cpp \ + model/recipe/recipetablemodel.cpp HEADERS += model/recipe/instruction.h \ model/recipe/recipe.h \ @@ -56,7 +57,8 @@ HEADERS += model/recipe/instruction.h \ gui/newDialogs/newunitdialog.h \ utils/aspectratiopixmaplabel.h \ utils/stringutils.h \ - gui/openrecipedialog.h + gui/openrecipedialog.h \ + model/recipe/recipetablemodel.h LIBS += -ldl \ diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp index 950a06c..67e3add 100644 --- a/gui/openrecipedialog.cpp +++ b/gui/openrecipedialog.cpp @@ -6,9 +6,22 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) : ui(new Ui::OpenRecipeDialog) { ui->setupUi(this); + + ui->recipeTableView->setModel(&this->recipeTableModel); +} + +OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){ + this->recipeDB = recipeDB; + this->populateRecipesTable(); } OpenRecipeDialog::~OpenRecipeDialog() { delete ui; } + +void OpenRecipeDialog::populateRecipesTable(){ + vector recipes = this->recipeDB->retrieveAllRecipes(); + this->recipeTableModel.setRecipes(recipes); + ui->recipeTableView->update(QModelIndex()); +} diff --git a/gui/openrecipedialog.h b/gui/openrecipedialog.h index ad95ad6..51c7a18 100644 --- a/gui/openrecipedialog.h +++ b/gui/openrecipedialog.h @@ -3,6 +3,9 @@ #include +#include "model/database/recipedatabase.h" +#include "model/recipe/recipetablemodel.h" + namespace Ui { class OpenRecipeDialog; } @@ -13,10 +16,15 @@ class OpenRecipeDialog : public QDialog public: explicit OpenRecipeDialog(QWidget *parent = 0); + OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent = 0); ~OpenRecipeDialog(); private: Ui::OpenRecipeDialog *ui; + RecipeDatabase *recipeDB; + RecipeTableModel recipeTableModel; + + void populateRecipesTable(); }; #endif // OPENRECIPEDIALOG_H diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index 5ab05fd..d1a8de0 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -155,6 +155,15 @@ Recipe RecipeDatabase::retrieveRecipe(string name){ return r; } +vector RecipeDatabase::retrieveAllRecipes(){ + ResultTable t = this->selectFrom("recipe", "name", "ORDER BY name"); + vector recipes; + for (unsigned int row = 0; row < t.rowCount(); row++){ + recipes.push_back(this->retrieveRecipe(t.valueAt(row, 0))); + } + return recipes; +} + vector RecipeDatabase::retrieveRecipeIngredients(int recipeId){ ResultTable t = this->executeSQL("SELECT ingredient.name, ingredient.foodGroup, "//0, 1 "recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment,"//2, 3, 4 diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index 099c233..60d382d 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -32,6 +32,7 @@ class RecipeDatabase : public Database //Retrieval. Recipe retrieveRecipe(string name); + vector retrieveAllRecipes(); vector retrieveRecipeIngredients(int recipeId); vector retrieveAllIngredients(); vector retrieveAllUnitsOfMeasure(); diff --git a/model/recipe/recipetablemodel.cpp b/model/recipe/recipetablemodel.cpp new file mode 100644 index 0000000..db58738 --- /dev/null +++ b/model/recipe/recipetablemodel.cpp @@ -0,0 +1,58 @@ +#include "recipetablemodel.h" + +RecipeTableModel::RecipeTableModel() +{ + +} + +RecipeTableModel::RecipeTableModel(vector recipes){ + this->setRecipes(recipes); +} + +int RecipeTableModel::rowCount(const QModelIndex &parent) const{ + Q_UNUSED(parent); + return this->recipes.size(); +} + +int RecipeTableModel::columnCount(const QModelIndex &parent) const{ + Q_UNUSED(parent); + return 2;//FIX THIS TO BE MORE ADAPTIVE EVENTUALLY. +} + +QVariant RecipeTableModel::data(const QModelIndex &index, int role) const{ + int row = index.row(); + int col = index.column(); + Recipe r = this->recipes[row]; + + if (role == Qt::DisplayRole){ + switch(col){ + case 0: + return QString::fromStdString(r.getName()); + case 1: + return QString::fromStdString(r.getCreatedDate().toString().toStdString()); + } + } + return QVariant(); +} + +QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation, int role) const{ + if (role != Qt::DisplayRole){ + return QVariant(); + } + if (orientation == Qt::Horizontal){ + switch (section){ + case 0: + return "Name"; + case 1: + return "Created On"; + } + } else if (orientation == Qt::Vertical){ + return QString::fromStdString(std::to_string(section)); + } + return QVariant(); +} + +void RecipeTableModel::setRecipes(vector recipes){ + this->recipes = recipes; + emit dataChanged(createIndex(0, 0), createIndex(this->recipes.size()-1, 2)); +} diff --git a/model/recipe/recipetablemodel.h b/model/recipe/recipetablemodel.h new file mode 100644 index 0000000..04285f5 --- /dev/null +++ b/model/recipe/recipetablemodel.h @@ -0,0 +1,27 @@ +#ifndef RECIPETABLEMODEL_H +#define RECIPETABLEMODEL_H + +#include + +#include "model/recipe/recipe.h" + +class RecipeTableModel : public QAbstractTableModel +{ + public: + RecipeTableModel(); + RecipeTableModel(vector recipes); + + //Overridden methods. + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + //Normal methods. + void setRecipes(vector recipes); + + private: + vector recipes; +}; + +#endif // RECIPETABLEMODEL_H diff --git a/userInterface/mainwindow.cpp b/userInterface/mainwindow.cpp index d2825d3..e805751 100644 --- a/userInterface/mainwindow.cpp +++ b/userInterface/mainwindow.cpp @@ -77,3 +77,9 @@ void MainWindow::on_newButton_clicked(){ this->loadFromRecipe(r); } } + +void MainWindow::on_openButton_clicked(){ + OpenRecipeDialog d(this->recipeDB, this); + d.show(); + d.exec(); +} diff --git a/userInterface/mainwindow.h b/userInterface/mainwindow.h index b5bcdb5..515fddb 100644 --- a/userInterface/mainwindow.h +++ b/userInterface/mainwindow.h @@ -8,6 +8,7 @@ #include "model/recipe/recipe.h" #include "model/recipe/ingredients/ingredientlistmodel.h" #include "gui/newrecipedialog.h" +#include "gui/openrecipedialog.h" #include "utils/stringutils.h" using namespace std; @@ -30,6 +31,8 @@ public: private slots: void on_newButton_clicked(); + void on_openButton_clicked(); + private: Ui::MainWindow *ui; RecipeDatabase *recipeDB; -- 2.34.1 From aab7a1055359ce919d73d882ed102d4144a594bb Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Thu, 29 Mar 2018 09:17:47 +0200 Subject: [PATCH 3/7] Moved mainWindow to gui directory with other dialogs. --- RecipeDB.pro | 10 ++++++---- {userInterface => gui}/mainwindow.cpp | 0 {userInterface => gui}/mainwindow.h | 0 3 files changed, 6 insertions(+), 4 deletions(-) rename {userInterface => gui}/mainwindow.cpp (100%) rename {userInterface => gui}/mainwindow.h (100%) diff --git a/RecipeDB.pro b/RecipeDB.pro index 1c8f716..580f9c9 100644 --- a/RecipeDB.pro +++ b/RecipeDB.pro @@ -14,7 +14,6 @@ TEMPLATE = app SOURCES += model/recipe/instruction.cpp \ model/recipe/recipe.cpp \ - userInterface/mainwindow.cpp \ main.cpp \ model/database/database.cpp \ model/recipe/ingredients/unitofmeasure.cpp \ @@ -34,7 +33,8 @@ SOURCES += model/recipe/instruction.cpp \ utils/aspectratiopixmaplabel.cpp \ utils/stringutils.cpp \ gui/openrecipedialog.cpp \ - model/recipe/recipetablemodel.cpp + model/recipe/recipetablemodel.cpp \ + gui/mainwindow.cpp HEADERS += model/recipe/instruction.h \ model/recipe/recipe.h \ @@ -58,7 +58,8 @@ HEADERS += model/recipe/instruction.h \ utils/aspectratiopixmaplabel.h \ utils/stringutils.h \ gui/openrecipedialog.h \ - model/recipe/recipetablemodel.h + model/recipe/recipetablemodel.h \ + gui/mainwindow.h LIBS += -ldl \ @@ -67,7 +68,8 @@ FORMS += gui/mainwindow.ui \ gui/newDialogs/newingredientdialog.ui \ gui/newDialogs/newtagdialog.ui \ gui/newDialogs/newunitdialog.ui \ - gui/openrecipedialog.ui + gui/openrecipedialog.ui \ + gui/mainwindow.ui DISTFILES += \ .gitignore diff --git a/userInterface/mainwindow.cpp b/gui/mainwindow.cpp similarity index 100% rename from userInterface/mainwindow.cpp rename to gui/mainwindow.cpp diff --git a/userInterface/mainwindow.h b/gui/mainwindow.h similarity index 100% rename from userInterface/mainwindow.h rename to gui/mainwindow.h -- 2.34.1 From fefa913e94063cc3142d83c22bb0d162861ad125 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Thu, 29 Mar 2018 09:58:25 +0200 Subject: [PATCH 4/7] Able to display recipes in list in openRecipe dialog. --- RecipeDB.pro | 1 - gui/mainwindow.cpp | 2 +- gui/mainwindow.h | 1 + gui/openrecipedialog.cpp | 7 ++++++- main.cpp | 2 +- model/database/recipedatabase.cpp | 4 ++-- model/database/recipedatabase.h | 1 + model/recipe/recipetablemodel.cpp | 7 ++++++- 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/RecipeDB.pro b/RecipeDB.pro index 580f9c9..92ac7d6 100644 --- a/RecipeDB.pro +++ b/RecipeDB.pro @@ -38,7 +38,6 @@ SOURCES += model/recipe/instruction.cpp \ HEADERS += model/recipe/instruction.h \ model/recipe/recipe.h \ - userInterface/mainwindow.h \ model/database/database.h \ model/recipe/ingredients/unitofmeasure.h \ model/recipe/ingredients/ingredient.h \ diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index e805751..78b64db 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -1,4 +1,4 @@ -#include "userInterface/mainwindow.h" +#include "gui/mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 515fddb..0dd91b9 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -28,6 +28,7 @@ public: //Loads all data from a recipe into the GUI components. void loadFromRecipe(Recipe recipe); + private slots: void on_newButton_clicked(); diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp index 67e3add..a910ad5 100644 --- a/gui/openrecipedialog.cpp +++ b/gui/openrecipedialog.cpp @@ -22,6 +22,11 @@ OpenRecipeDialog::~OpenRecipeDialog() void OpenRecipeDialog::populateRecipesTable(){ vector recipes = this->recipeDB->retrieveAllRecipes(); + printf("Found %d recipes:\n", recipes.size()); + for (Recipe r : recipes){ + r.print(); + printf("\n------------------\n"); + } this->recipeTableModel.setRecipes(recipes); - ui->recipeTableView->update(QModelIndex()); + ui->recipeTableView->show(); } diff --git a/main.cpp b/main.cpp index 4e49c1e..c786362 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,4 @@ -#include "userInterface/mainwindow.h" +#include "gui/mainwindow.h" #include "gui/newrecipedialog.h" #include diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index d1a8de0..81dfb14 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -232,8 +232,8 @@ vector RecipeDatabase::retrieveAllTags(){ return tags; } -void RecipeDatabase::deleteTag(RecipeTag tag){ - ResultTable t = this->executeSQL("DELETE FROM recipeTag WHERE tagName="+surroundString(tag.getValue(), "'")); +bool RecipeDatabase::deleteRecipe(string name){ + } void RecipeDatabase::ensureTablesExist(){ diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index 60d382d..c36f061 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -40,6 +40,7 @@ class RecipeDatabase : public Database vector retrieveAllTags(); //Deletion. + bool deleteRecipe(string name); void deleteTag(RecipeTag tag); private: diff --git a/model/recipe/recipetablemodel.cpp b/model/recipe/recipetablemodel.cpp index db58738..1b00a55 100644 --- a/model/recipe/recipetablemodel.cpp +++ b/model/recipe/recipetablemodel.cpp @@ -45,6 +45,10 @@ QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation, return "Name"; case 1: return "Created On"; + case 2: + + default: + return QVariant(); } } else if (orientation == Qt::Vertical){ return QString::fromStdString(std::to_string(section)); @@ -53,6 +57,7 @@ QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation, } void RecipeTableModel::setRecipes(vector recipes){ + beginInsertRows({}, 0, recipes.size()-1); this->recipes = recipes; - emit dataChanged(createIndex(0, 0), createIndex(this->recipes.size()-1, 2)); + endInsertRows(); } -- 2.34.1 From 7fb11b34128d3b888b352340c4cb877c6eb09ad1 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Thu, 29 Mar 2018 11:21:00 +0200 Subject: [PATCH 5/7] Added the ability to delete a recipe by name or id. --- gui/newrecipedialog.cpp | 2 +- gui/openrecipedialog.cpp | 10 +++--- gui/openrecipedialog.ui | 3 ++ main.cpp | 3 ++ model/database/database.cpp | 14 ++++++++ model/database/database.h | 1 + model/database/recipedatabase.cpp | 53 +++++++++++++++++++++++++++++++ model/database/recipedatabase.h | 5 ++- model/recipe/recipetablemodel.cpp | 2 -- 9 files changed, 84 insertions(+), 9 deletions(-) diff --git a/gui/newrecipedialog.cpp b/gui/newrecipedialog.cpp index 99459dc..ac0c89e 100644 --- a/gui/newrecipedialog.cpp +++ b/gui/newrecipedialog.cpp @@ -160,7 +160,7 @@ void NewRecipeDialog::on_removeTagButton_clicked(){ return; } RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()]; - string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue(); + string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue()+"\nThis will delete the tag for all recipes that use it."; QMessageBox::StandardButton reply = QMessageBox::question(this, QString("Delete Tag"), QString(content.c_str())); if (reply == QMessageBox::Yes){ this->recipeDB->deleteTag(tag); diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp index a910ad5..5991297 100644 --- a/gui/openrecipedialog.cpp +++ b/gui/openrecipedialog.cpp @@ -22,11 +22,11 @@ OpenRecipeDialog::~OpenRecipeDialog() void OpenRecipeDialog::populateRecipesTable(){ vector recipes = this->recipeDB->retrieveAllRecipes(); - printf("Found %d recipes:\n", recipes.size()); - for (Recipe r : recipes){ - r.print(); - printf("\n------------------\n"); - } +// printf("Found %d recipes:\n", recipes.size()); +// for (Recipe r : recipes){ +// r.print(); +// printf("\n------------------\n"); +// } this->recipeTableModel.setRecipes(recipes); ui->recipeTableView->show(); } diff --git a/gui/openrecipedialog.ui b/gui/openrecipedialog.ui index d0fca63..be20dd9 100644 --- a/gui/openrecipedialog.ui +++ b/gui/openrecipedialog.ui @@ -97,6 +97,9 @@ true + + false + diff --git a/main.cpp b/main.cpp index c786362..418b03d 100644 --- a/main.cpp +++ b/main.cpp @@ -48,6 +48,9 @@ int main(int argc, char *argv[]) // printf("Accepted the dialog.\n"); // } + bool success = recipeDB.deleteRecipe(4); + printf("Success: %d\n", success); + recipeDB.selectFrom("recipe", "recipeId, name", "").printData(); w.loadFromRecipe(recipeDB.retrieveRecipe("Generic Bread")); return a.exec(); diff --git a/model/database/database.cpp b/model/database/database.cpp index 636a137..0d3b9a4 100644 --- a/model/database/database.cpp +++ b/model/database/database.cpp @@ -46,6 +46,20 @@ ResultTable Database::selectFrom(string tableName, string columnNames, string co return this->executeSQL(query); } +bool Database::deleteFrom(string tableName, string conditions){ + if (tableName.empty()){ + return false; + } + string query = "DELETE FROM " + tableName + " " + conditions + ";"; + ResultTable t = this->executeSQL(query); + if (t.getReturnCode() != SQLITE_DONE){ + fprintf(stderr, "Can't delete from table %s.Return code: %d\n%s\n", tableName.c_str(), t.getReturnCode(), sqlite3_errmsg(this->db)); + exit(EXIT_FAILURE); + } else { + return true; + } +} + void Database::openConnection(){ this->returnCode = sqlite3_open(this->filename.c_str(), &this->db); if (this->returnCode || this->db == NULL){ diff --git a/model/database/database.h b/model/database/database.h index 4a60447..a110db7 100644 --- a/model/database/database.h +++ b/model/database/database.h @@ -26,6 +26,7 @@ public: ResultTable executeSQL(string statement); bool insertInto(string tableName, vector columnNames, vector values); ResultTable selectFrom(string tableName, string columnNames, string conditions); + bool deleteFrom(string tableName, string conditions); bool tableExists(string tableName); int getLastInsertedRowId(); diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index 81dfb14..54f9bcc 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -5,6 +5,12 @@ RecipeDatabase::RecipeDatabase(string filename) : Database(filename){ } bool RecipeDatabase::storeRecipe(Recipe recipe){ + //Some primary checks to avoid garbage in the database. + if (recipe.getName().empty() || + recipe.getInstruction().getHTML().empty() || + recipe.getIngredients().empty()){ + return false; + } //Store a recipe, if it doesn't already exist. This first tries to create the recipe entry, then all subsequent supporting table entries. this->executeSQL("BEGIN;"); ResultTable t = this->selectFrom("recipe", "*", "WHERE name="+surroundString(recipe.getName(), "'")); @@ -233,7 +239,54 @@ vector RecipeDatabase::retrieveAllTags(){ } bool RecipeDatabase::deleteRecipe(string name){ + ResultTable t = this->selectFrom("recipe", "recipeId", "WHERE name="+name); + if (t.rowCount() != 1){ + return false; + } + string recipeId = t.valueAt(0, 0); + return this->deleteRecipe(std::stoi(recipeId)); +} +bool RecipeDatabase::deleteRecipe(int recipeId){ + string idString = std::to_string(recipeId); + if (this->selectFrom("recipe", "recipeId", "WHERE recipeId="+idString).isEmpty()){ + return false; + } + this->executeSQL("BEGIN;"); + bool tagsDeleted = this->deleteFrom("recipeTag", "WHERE recipeId="+idString); + bool recipeIngredientDeleted = this->deleteFrom("recipeIngredient", "WHERE recipeId="+idString); + bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString); + if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){ + this->executeSQL("COMMIT;"); + return true; + } else { + this->executeSQL("ROLLBACK;"); + return false; + } +} + +bool RecipeDatabase::deleteIngredient(string name){ + ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE ingredientId=(" + "SELECT ingredientId" + "FROM ingredient" + "WHERE name="+name+")"); + if (!t.isEmpty()){ + //There is at least one recipe dependent on the ingredient. + return false; + } + return this->deleteFrom("ingredient", "WHERE name="+name); +} + +bool RecipeDatabase::deleteUnitOfMeasure(string name){ + ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE unitName="+name); + if (!t.isEmpty()){ + return false; + } + return this->deleteFrom("unitOfMeasure", "WHERE name="+name); +} + +bool RecipeDatabase::deleteTag(RecipeTag tag){ + return this->deleteFrom("recipeTag", "WHERE tagName="+tag.getValue()); } void RecipeDatabase::ensureTablesExist(){ diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index c36f061..b240166 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -41,7 +41,10 @@ class RecipeDatabase : public Database //Deletion. bool deleteRecipe(string name); - void deleteTag(RecipeTag tag); + bool deleteRecipe(int recipeId); + bool deleteIngredient(string name); + bool deleteUnitOfMeasure(string name); + bool deleteTag(RecipeTag tag); private: //Utility methods. diff --git a/model/recipe/recipetablemodel.cpp b/model/recipe/recipetablemodel.cpp index 1b00a55..a22c7b6 100644 --- a/model/recipe/recipetablemodel.cpp +++ b/model/recipe/recipetablemodel.cpp @@ -45,8 +45,6 @@ QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation, return "Name"; case 1: return "Created On"; - case 2: - default: return QVariant(); } -- 2.34.1 From b8ac72c91a6327aab12e4bdc9aecf8b7576824b0 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Thu, 29 Mar 2018 11:30:38 +0200 Subject: [PATCH 6/7] Added trash icon. --- images/trash.png | Bin 0 -> 724 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/trash.png diff --git a/images/trash.png b/images/trash.png new file mode 100644 index 0000000000000000000000000000000000000000..529896ae21125f61cf80825b544f651d05238db1 GIT binary patch literal 724 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K5893O0R7}x|G$6&6|H(?D8gCb z5n0T@z%2~Ij105pNB{-dOFVsD*&i{>a>~l{+wH&0z`&H~>EaktaqI2vy`l~VA`KUh zq-D)z%}HQA&Skct!7q19I@4Sw`|o}SxbJ&*EnxwgfffAGlXjf@PJPjo^qI%rSg*R0 zz@os=05qL}g8>`E;o+>E$13BV#`G_(J$>hxXofXI0Sf~Qg8+jA$Y)exI570!G^ke2d25dm&5o^mX V-bK@&{x}7a_H^}gS?83{1OQ4kYs~-v literal 0 HcmV?d00001 -- 2.34.1 From 076212e392dc92b5a7135481ea9f24847d0e4bf0 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Thu, 29 Mar 2018 16:09:58 +0200 Subject: [PATCH 7/7] Cleaned up deleting recipes, random recipe on startup, exit button, etc. --- gui/mainwindow.cpp | 14 +++- gui/mainwindow.h | 2 + gui/mainwindow.ui | 68 +++++++++++++++++++ gui/newrecipedialog.cpp | 37 +++++++++- gui/newrecipedialog.h | 4 ++ gui/newrecipedialog.ui | 26 ++++++- gui/openrecipedialog.cpp | 42 ++++++++++-- gui/openrecipedialog.h | 9 +++ gui/openrecipedialog.ui | 20 ++++++ images.qrc | 1 + main.cpp | 57 ++++++---------- model/database/database.h | 3 +- model/database/recipedatabase.cpp | 57 ++++++++++------ model/database/recipedatabase.h | 3 + model/recipe/ingredients/recipeingredient.cpp | 2 +- model/recipe/recipe.cpp | 8 ++- model/recipe/recipe.h | 1 + model/recipe/recipetablemodel.cpp | 27 +++++++- model/recipe/recipetablemodel.h | 4 +- utils/stringutils.cpp | 13 ++++ 20 files changed, 321 insertions(+), 77 deletions(-) diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 78b64db..7db6bbe 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -58,7 +58,7 @@ void MainWindow::setCookTime(QTime cookTime){ } void MainWindow::setServings(float servings){ - ui->servingsLabel->setText(QString("Servings: ")+QString::fromStdString(StringUtils::toString(servings))); + ui->servingsLabel->setText(QString(QString::fromStdString(StringUtils::toString(servings) + " Serving" + ((servings != 1.0f) ? "s" : "")))); } void MainWindow::setTags(vector tags){ @@ -72,9 +72,10 @@ void MainWindow::on_newButton_clicked(){ if (d.isAccepted()){ Recipe r = d.getRecipe(); if (!this->recipeDB->storeRecipe(r)){ - QMessageBox::critical(this, QString("Unable to Save Recipe"), QString("The program was not able to successfully save the recipe.")); + QMessageBox::critical(this, QString("Unable to Save Recipe"), QString("The program was not able to successfully save the recipe. Make sure to give the recipe a name, instructions, and some ingredients!")); + } else { + this->loadFromRecipe(r); } - this->loadFromRecipe(r); } } @@ -82,4 +83,11 @@ void MainWindow::on_openButton_clicked(){ OpenRecipeDialog d(this->recipeDB, this); d.show(); d.exec(); + if (!d.getSelectedRecipe().isEmpty()){ + this->loadFromRecipe(d.getSelectedRecipe()); + } +} + +void MainWindow::on_exitButton_clicked(){ + this->close(); } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 0dd91b9..2b62cc3 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -34,6 +34,8 @@ public: void on_openButton_clicked(); + void on_exitButton_clicked(); + private: Ui::MainWindow *ui; RecipeDatabase *recipeDB; diff --git a/gui/mainwindow.ui b/gui/mainwindow.ui index 430cb1e..0925f75 100644 --- a/gui/mainwindow.ui +++ b/gui/mainwindow.ui @@ -143,6 +143,12 @@ QPushButton#newButton:pressed{ + + + 0 + 0 + + 150 @@ -175,6 +181,9 @@ QPushButton#openButton:pressed{ + + false + 150 @@ -211,6 +220,56 @@ QPushButton#browseButton:pressed{ + + + + + 150 + 80 + + + + + 150 + 80 + + + + + Noto Sans CJK KR Light + 20 + PreferAntialias + + + + false + + + QPushButton#exitButton { + background-color: rgb(255, 216, 216); + border: 0px; +} +QPushButton#exitButton:hover{ + background-color: rgb(255, 191, 191); +} +QPushButton#exitButton:pressed{ + background-color: rgb(255, 147, 147); +} + + + Exit + + + false + + + false + + + false + + + @@ -367,6 +426,9 @@ font: "Noto Sans CJK KR"; Prep Time: + + Qt::AlignCenter + @@ -383,6 +445,9 @@ font: "Noto Sans CJK KR"; Cook Time: + + Qt::AlignCenter + @@ -396,6 +461,9 @@ font: "Noto Sans CJK KR"; Servings: + + Qt::AlignCenter + diff --git a/gui/newrecipedialog.cpp b/gui/newrecipedialog.cpp index ac0c89e..a0681f2 100644 --- a/gui/newrecipedialog.cpp +++ b/gui/newrecipedialog.cpp @@ -119,7 +119,7 @@ void NewRecipeDialog::on_selectImageButton_clicked(){ } } -void NewRecipeDialog::on_deleteIngredientButton_clicked(){ +void NewRecipeDialog::on_removeIngredientButton_clicked(){ QModelIndexList indexList = ui->ingredientsListView->selectionModel()->selectedIndexes(); for (QModelIndexList::iterator it = indexList.begin(); it != indexList.end(); ++it){ QModelIndex i = *it; @@ -127,6 +127,22 @@ void NewRecipeDialog::on_deleteIngredientButton_clicked(){ } } +void NewRecipeDialog::on_deleteIngredientButton_clicked(){ + int index = ui->ingredientNameBox->currentIndex(); + Ingredient ing = this->ingredients.at(index); + QMessageBox::StandardButton reply = QMessageBox::question(this, + QString::fromStdString("Delete Ingredient"), + QString::fromStdString("Are you sure you want to delete the ingredient " + ing.getName() + "?")); + if (reply == QMessageBox::Yes){ + bool success = this->recipeDB->deleteIngredient(ing.getName()); + if (!success){ + QMessageBox::critical(this, QString::fromStdString("Error"), QString::fromStdString("Unable to delete ingredient: " + ing.getName() + ", some recipes use it!")); + } else { + this->populateIngredientsBox(); + } + } +} + void NewRecipeDialog::on_newIngredientButton_clicked(){ NewIngredientDialog d(this); d.show(); @@ -155,8 +171,8 @@ void NewRecipeDialog::on_newTagButton_clicked(){ } void NewRecipeDialog::on_removeTagButton_clicked(){ - int index = ui->tagsComboBox->currentIndex(); - if (index < 0 || index >= this->tags.size()){ + unsigned int index = ui->tagsComboBox->currentIndex(); + if (index >= this->tags.size()){ return; } RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()]; @@ -180,3 +196,18 @@ void NewRecipeDialog::on_newUnitButton_clicked(){ } } } + +void NewRecipeDialog::on_deleteUnitButton_clicked(){ + int index = ui->unitComboBox->currentIndex(); + UnitOfMeasure unit = this->units[index]; + QMessageBox::StandardButton reply = QMessageBox::question(this, + QString::fromStdString("Delete Unit Of Measure"), + QString::fromStdString("Are you sure you want to delete the unit " + unit.getName() + "?")); + if (reply == QMessageBox::Yes){ + if (!this->recipeDB->deleteUnitOfMeasure(unit.getName())){ + QMessageBox::critical(this, "Error", "Unable to delete unit. There may be recipes which still use it!"); + } else { + this->populateUnitsBox(); + } + } +} diff --git a/gui/newrecipedialog.h b/gui/newrecipedialog.h index d272f3e..bfeae1f 100644 --- a/gui/newrecipedialog.h +++ b/gui/newrecipedialog.h @@ -47,6 +47,8 @@ class NewRecipeDialog : public QDialog void on_selectImageButton_clicked(); + void on_removeIngredientButton_clicked(); + void on_deleteIngredientButton_clicked(); void on_newIngredientButton_clicked(); @@ -57,6 +59,8 @@ class NewRecipeDialog : public QDialog void on_newUnitButton_clicked(); + void on_deleteUnitButton_clicked(); + private: Ui::NewRecipeDialog *ui; RecipeDatabase *recipeDB; diff --git a/gui/newrecipedialog.ui b/gui/newrecipedialog.ui index a470909..7a57690 100644 --- a/gui/newrecipedialog.ui +++ b/gui/newrecipedialog.ui @@ -158,7 +158,7 @@ 0 1999 12 - 26 + 25 @@ -504,6 +504,17 @@ + + + + + + + + :/images/images/minus_icon.png:/images/images/minus_icon.png + + + @@ -579,6 +590,17 @@ + + + + + + + + :/images/images/minus_icon.png:/images/images/minus_icon.png + + + @@ -627,7 +649,7 @@ - + Delete diff --git a/gui/openrecipedialog.cpp b/gui/openrecipedialog.cpp index 5991297..fb34703 100644 --- a/gui/openrecipedialog.cpp +++ b/gui/openrecipedialog.cpp @@ -20,13 +20,45 @@ OpenRecipeDialog::~OpenRecipeDialog() delete ui; } +Recipe OpenRecipeDialog::getSelectedRecipe(){ + return this->selectedRecipe; +} + void OpenRecipeDialog::populateRecipesTable(){ + this->recipeTableModel.clear(); vector recipes = this->recipeDB->retrieveAllRecipes(); -// printf("Found %d recipes:\n", recipes.size()); -// for (Recipe r : recipes){ -// r.print(); -// printf("\n------------------\n"); -// } this->recipeTableModel.setRecipes(recipes); + ui->recipeTableView->resizeColumnsToContents(); ui->recipeTableView->show(); } + +void OpenRecipeDialog::on_deleteRecipeButton_clicked(){ + QItemSelectionModel *selectModel = ui->recipeTableView->selectionModel(); + if (!selectModel->hasSelection()){ + return; + } + vector rows; + QModelIndexList indexes = selectModel->selectedIndexes(); + for (int i = 0; i < indexes.count(); i++){ + rows.push_back(indexes.at(i).row()); + } + string recipePlural = (rows.size() == 1) ? "recipe" : "recipes"; + QString title = QString::fromStdString("Delete " + recipePlural); + QString content = QString::fromStdString("Are you sure you wish to delete the selected "+recipePlural+"?"); + QMessageBox::StandardButton reply = QMessageBox::question(this, title, content); + if (reply == QMessageBox::Yes){ + for (int row : rows){ + Recipe r = this->recipeTableModel.getRecipeAt(row); + 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())); + } + } + this->populateRecipesTable(); + } +} + +void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index){ + this->selectedRecipe = this->recipeTableModel.getRecipeAt(index.row()); + this->close(); +} diff --git a/gui/openrecipedialog.h b/gui/openrecipedialog.h index 51c7a18..974b6cf 100644 --- a/gui/openrecipedialog.h +++ b/gui/openrecipedialog.h @@ -2,6 +2,7 @@ #define OPENRECIPEDIALOG_H #include +#include #include "model/database/recipedatabase.h" #include "model/recipe/recipetablemodel.h" @@ -19,10 +20,18 @@ class OpenRecipeDialog : public QDialog OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent = 0); ~OpenRecipeDialog(); + Recipe getSelectedRecipe(); + + private slots: + void on_deleteRecipeButton_clicked(); + + void on_recipeTableView_doubleClicked(const QModelIndex &index); + private: Ui::OpenRecipeDialog *ui; RecipeDatabase *recipeDB; RecipeTableModel recipeTableModel; + Recipe selectedRecipe; void populateRecipesTable(); }; diff --git a/gui/openrecipedialog.ui b/gui/openrecipedialog.ui index be20dd9..d689a16 100644 --- a/gui/openrecipedialog.ui +++ b/gui/openrecipedialog.ui @@ -86,6 +86,23 @@ + + + + + + + + + + + :/images/images/trash.png:/images/images/trash.png + + + + + + @@ -94,6 +111,9 @@ QFrame::NoFrame + + QAbstractItemView::SelectRows + true diff --git a/images.qrc b/images.qrc index 8b12ebf..a5261a4 100644 --- a/images.qrc +++ b/images.qrc @@ -5,5 +5,6 @@ images/plus_icon.png images/minus_icon.png images/search_icon.png + images/trash.png diff --git a/main.cpp b/main.cpp index 418b03d..3d4bfdb 100644 --- a/main.cpp +++ b/main.cpp @@ -13,45 +13,28 @@ int main(int argc, char *argv[]) w.show(); //TESTING CODE -// vector ri; -// ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), "")); -// ri.push_back(RecipeIngredient("baking powder", "additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), "")); + vector ri; + ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), "")); + ri.push_back(RecipeIngredient("baking powder", "additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), "")); -// Recipe rec("Example", -// ri, -// Instruction("BOLDiTaLiCs"), -// QImage(), -// vector({RecipeTag("testing"), -// RecipeTag("fake")}), -// QDate::currentDate(), -// QTime(0, 30), -// QTime(0, 25), -// 10.0f); + Recipe rec("Example", + ri, + Instruction("BOLDiTaLiCs"), + QImage(), + vector({RecipeTag("testing"), + RecipeTag("fake")}), + QDate::currentDate(), + QTime(0, 30), + QTime(0, 25), + 10.0f); -// bool success = recipeDB.storeRecipe(rec); -// printf("Storage successful: %d\n", success); + bool success = recipeDB.storeRecipe(rec); + printf("Storage successful: %d\n", success); -// recipeDB.storeUnitOfMeasure(UnitOfMeasure("tablespoon", "tablespoons", "tbsp", UnitOfMeasure::VOLUME, 1.0)); -// recipeDB.storeUnitOfMeasure(UnitOfMeasure("pinch", "pinches", "pch", UnitOfMeasure::VOLUME, 1.0)); -// recipeDB.storeUnitOfMeasure(UnitOfMeasure("gram", "grams", "g", UnitOfMeasure::MASS, 1.0)); + //recipeDB.selectFrom("recipe", "recipeId, name", "").printData(); + w.loadFromRecipe(recipeDB.retrieveRandomRecipe()); -// Recipe reloadRec = recipeDB.retrieveRecipe("Example"); -// reloadRec.print(); - -// w.loadFromRecipe(reloadRec); - -// NewRecipeDialog d(&recipeDB); -// d.show(); -// d.exec(); - -// if (d.isAccepted()){ -// printf("Accepted the dialog.\n"); -// } - - bool success = recipeDB.deleteRecipe(4); - printf("Success: %d\n", success); - recipeDB.selectFrom("recipe", "recipeId, name", "").printData(); - w.loadFromRecipe(recipeDB.retrieveRecipe("Generic Bread")); - - return a.exec(); + a.exec(); + recipeDB.closeConnection(); + return 0; } diff --git a/model/database/database.h b/model/database/database.h index a110db7..ab149d5 100644 --- a/model/database/database.h +++ b/model/database/database.h @@ -31,6 +31,8 @@ public: bool tableExists(string tableName); int getLastInsertedRowId(); + void closeConnection(); + protected: string surroundString(string s, string surround); @@ -44,7 +46,6 @@ private: char* errorMsg; void openConnection(); - void closeConnection(); std::string combineVector(std::vector strings, std::string mid); }; diff --git a/model/database/recipedatabase.cpp b/model/database/recipedatabase.cpp index 54f9bcc..1650579 100644 --- a/model/database/recipedatabase.cpp +++ b/model/database/recipedatabase.cpp @@ -147,18 +147,16 @@ Recipe RecipeDatabase::retrieveRecipe(string name){ fprintf(stderr, "Error: No recipe with name %s found!\n", name.c_str()); return Recipe(); } - Recipe r; - int id = std::stoi(t.valueAt(0, 0)); - r.setName(t.valueAt(0, 1)); - r.setCreatedDate(QDate::fromString(QString::fromStdString(t.valueAt(0, 2)))); - r.setPrepTime(QTime::fromString(QString::fromStdString(t.valueAt(0, 3)))); - r.setCookTime(QTime::fromString(QString::fromStdString(t.valueAt(0, 4)))); - r.setServings(std::stof(t.valueAt(0, 5))); - r.setInstruction(FileUtils::loadInstruction(id)); - r.setImage(FileUtils::loadImage(id)); - r.setIngredients(this->retrieveRecipeIngredients(id)); - r.setTags(this->retrieveTags(id)); - return r; + return this->readFromResultTable(t); +} + +Recipe RecipeDatabase::retrieveRandomRecipe(){ + ResultTable t = this->selectFrom("recipe", "*", "ORDER BY RANDOM() LIMIT 1"); + if (t.isEmpty()){ + fprintf(stderr, "Unable to find a random recipe.\n"); + return Recipe(); + } + return this->readFromResultTable(t); } vector RecipeDatabase::retrieveAllRecipes(){ @@ -239,7 +237,7 @@ vector RecipeDatabase::retrieveAllTags(){ } bool RecipeDatabase::deleteRecipe(string name){ - ResultTable t = this->selectFrom("recipe", "recipeId", "WHERE name="+name); + ResultTable t = this->selectFrom("recipe", "recipeId", "WHERE name='"+name+"'"); if (t.rowCount() != 1){ return false; } @@ -250,6 +248,7 @@ bool RecipeDatabase::deleteRecipe(string name){ bool RecipeDatabase::deleteRecipe(int recipeId){ string idString = std::to_string(recipeId); if (this->selectFrom("recipe", "recipeId", "WHERE recipeId="+idString).isEmpty()){ + printf("Cannot delete. No recipe with ID %d exists.\n", recipeId); return false; } this->executeSQL("BEGIN;"); @@ -266,27 +265,28 @@ bool RecipeDatabase::deleteRecipe(int recipeId){ } bool RecipeDatabase::deleteIngredient(string name){ - ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE ingredientId=(" - "SELECT ingredientId" - "FROM ingredient" - "WHERE name="+name+")"); + ResultTable t = this->executeSQL("SELECT recipeId " + "FROM recipeIngredient " + "INNER JOIN ingredient " + "ON recipeIngredient.ingredientId = ingredient.ingredientId " + "WHERE ingredient.name='"+name+"';"); if (!t.isEmpty()){ //There is at least one recipe dependent on the ingredient. return false; } - return this->deleteFrom("ingredient", "WHERE name="+name); + return this->deleteFrom("ingredient", "WHERE name='"+name+"'"); } bool RecipeDatabase::deleteUnitOfMeasure(string name){ - ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE unitName="+name); + ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE unitName='"+name+"'"); if (!t.isEmpty()){ return false; } - return this->deleteFrom("unitOfMeasure", "WHERE name="+name); + return this->deleteFrom("unitOfMeasure", "WHERE name='"+name+"'"); } bool RecipeDatabase::deleteTag(RecipeTag tag){ - return this->deleteFrom("recipeTag", "WHERE tagName="+tag.getValue()); + return this->deleteFrom("recipeTag", "WHERE tagName='"+tag.getValue()+"'"); } void RecipeDatabase::ensureTablesExist(){ @@ -331,3 +331,18 @@ void RecipeDatabase::ensureTablesExist(){ "FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name));"); this->executeSQL("COMMIT;"); } + +Recipe RecipeDatabase::readFromResultTable(ResultTable t, int row){ + Recipe r; + int id = std::stoi(t.valueAt(row, 0)); + r.setName(t.valueAt(row, 1)); + r.setCreatedDate(QDate::fromString(QString::fromStdString(t.valueAt(row, 2)))); + r.setPrepTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 3)))); + r.setCookTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 4)))); + r.setServings(std::stof(t.valueAt(row, 5))); + r.setInstruction(FileUtils::loadInstruction(id)); + r.setImage(FileUtils::loadImage(id)); + r.setIngredients(this->retrieveRecipeIngredients(id)); + r.setTags(this->retrieveTags(id)); + return r; +} diff --git a/model/database/recipedatabase.h b/model/database/recipedatabase.h index b240166..c5466b7 100644 --- a/model/database/recipedatabase.h +++ b/model/database/recipedatabase.h @@ -32,6 +32,7 @@ class RecipeDatabase : public Database //Retrieval. Recipe retrieveRecipe(string name); + Recipe retrieveRandomRecipe(); vector retrieveAllRecipes(); vector retrieveRecipeIngredients(int recipeId); vector retrieveAllIngredients(); @@ -49,6 +50,8 @@ class RecipeDatabase : public Database //Utility methods. void ensureTablesExist(); + //Read a recipe from a row of a result table. + Recipe readFromResultTable(ResultTable t, int row=0); }; #endif // RECIPEDATABASE_H diff --git a/model/recipe/ingredients/recipeingredient.cpp b/model/recipe/ingredients/recipeingredient.cpp index d8f115b..34de9d1 100644 --- a/model/recipe/ingredients/recipeingredient.cpp +++ b/model/recipe/ingredients/recipeingredient.cpp @@ -50,7 +50,7 @@ string RecipeIngredient::toString(){ result += StringUtils::toString(this->getQuantity()); } result += " " + this->getUnit().getAbbreviation() + " " + this->getName(); - if (!this->getComment().empty()) result += " ~" + this->getComment(); + if (!this->getComment().empty()) result += " (" + this->getComment() + ")"; return result; } diff --git a/model/recipe/recipe.cpp b/model/recipe/recipe.cpp index f99e1a2..0859bd8 100644 --- a/model/recipe/recipe.cpp +++ b/model/recipe/recipe.cpp @@ -12,7 +12,7 @@ Recipe::Recipe(string name, vector ingredients, Instruction in setServings(servings); } -Recipe::Recipe() : Recipe::Recipe("Unnamed Recipe", vector(), Instruction(), QImage(), vector(), QDate::currentDate(), QTime(1, 0), QTime(0, 30), 10.0f){ +Recipe::Recipe() : Recipe::Recipe("", vector(), Instruction(), QImage(), vector(), QDate::currentDate(), QTime(1, 0), QTime(0, 30), 10.0f){ //Set default values when none are specified. } @@ -53,7 +53,11 @@ QTime Recipe::getTotalTime() const{ } float Recipe::getServings() const{ - return this->servings; + return this->servings; +} + +bool Recipe::isEmpty() const{ + return this->name.empty(); } void Recipe::setName(string newName){ diff --git a/model/recipe/recipe.h b/model/recipe/recipe.h index d013659..048b09a 100644 --- a/model/recipe/recipe.h +++ b/model/recipe/recipe.h @@ -46,6 +46,7 @@ public: QTime getCookTime() const; QTime getTotalTime() const; //Derived method to add prep and cook times. float getServings() const; + bool isEmpty() const; //Setters void setName(string newName); diff --git a/model/recipe/recipetablemodel.cpp b/model/recipe/recipetablemodel.cpp index a22c7b6..521fa51 100644 --- a/model/recipe/recipetablemodel.cpp +++ b/model/recipe/recipetablemodel.cpp @@ -16,7 +16,7 @@ int RecipeTableModel::rowCount(const QModelIndex &parent) const{ int RecipeTableModel::columnCount(const QModelIndex &parent) const{ Q_UNUSED(parent); - return 2;//FIX THIS TO BE MORE ADAPTIVE EVENTUALLY. + return 5;//FIX THIS TO BE MORE ADAPTIVE EVENTUALLY. } QVariant RecipeTableModel::data(const QModelIndex &index, int role) const{ @@ -30,6 +30,12 @@ QVariant RecipeTableModel::data(const QModelIndex &index, int role) const{ return QString::fromStdString(r.getName()); case 1: return QString::fromStdString(r.getCreatedDate().toString().toStdString()); + case 2: + return QString::fromStdString(StringUtils::toString(r.getServings())); + case 3: + return r.getPrepTime().toString("hh:mm:ss"); + case 4: + return r.getCookTime().toString("hh:mm:ss"); } } return QVariant(); @@ -45,6 +51,12 @@ QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation, return "Name"; case 1: return "Created On"; + case 2: + return "Servings"; + case 3: + return "Prep Time"; + case 4: + return "Cook Time"; default: return QVariant(); } @@ -59,3 +71,16 @@ void RecipeTableModel::setRecipes(vector recipes){ this->recipes = recipes; endInsertRows(); } + +Recipe RecipeTableModel::getRecipeAt(int index){ + if (index < 0 || index >= this->recipes.size()){ + return Recipe(); + } + return this->recipes[index]; +} + +void RecipeTableModel::clear(){ + beginResetModel(); + this->recipes.clear(); + endResetModel(); +} diff --git a/model/recipe/recipetablemodel.h b/model/recipe/recipetablemodel.h index 04285f5..7449619 100644 --- a/model/recipe/recipetablemodel.h +++ b/model/recipe/recipetablemodel.h @@ -4,6 +4,7 @@ #include #include "model/recipe/recipe.h" +#include "utils/stringutils.h" class RecipeTableModel : public QAbstractTableModel { @@ -19,7 +20,8 @@ class RecipeTableModel : public QAbstractTableModel //Normal methods. void setRecipes(vector recipes); - + Recipe getRecipeAt(int index); + void clear(); private: vector recipes; }; diff --git a/utils/stringutils.cpp b/utils/stringutils.cpp index 3ed578b..f6115e8 100644 --- a/utils/stringutils.cpp +++ b/utils/stringutils.cpp @@ -2,6 +2,14 @@ namespace StringUtils{ +bool stringEndsWith(std::string const &fullString, std::string const &ending){ + if (fullString.length() >= ending.length()) { + return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending)); + } else { + return false; + } +} + std::string toString(float val){ float decimal = std::fmod(val, 1.0f); int places = 1; @@ -13,6 +21,11 @@ std::string toString(float val){ std::string arg = "%."+std::to_string(places)+"f"; sprintf(buffer, arg.c_str(), val); std::string s = buffer; + if (stringEndsWith(s, ".0")){ + while (s.find('.') != std::string::npos){ + s.pop_back(); + } + } return s; } -- 2.34.1