Improve/redesign ingredients #13

Merged
andrewlalis merged 13 commits from improve/redesignIngredients into development 2018-05-22 21:29:25 +00:00
35 changed files with 111 additions and 1716 deletions

View File

@ -16,10 +16,8 @@ SOURCES += model/recipe/instruction.cpp \
model/recipe/recipe.cpp \
main.cpp \
model/database/database.cpp \
model/recipe/ingredients/unitofmeasure.cpp \
model/recipe/ingredients/ingredient.cpp \
model/recipe/ingredients/ingredientlistmodel.cpp \
model/recipe/ingredients/recipeingredient.cpp \
model/recipe/tags/recipetag.cpp \
SQLite/sqlite3.c \
model/database/resulttable.cpp \
@ -27,24 +25,18 @@ SOURCES += model/recipe/instruction.cpp \
utils/fileutils.cpp \
gui/newrecipedialog.cpp \
model/recipe/tags/taglistmodel.cpp \
gui/newDialogs/newingredientdialog.cpp \
gui/newDialogs/newtagdialog.cpp \
gui/newDialogs/newunitdialog.cpp \
utils/aspectratiopixmaplabel.cpp \
utils/stringutils.cpp \
gui/openrecipedialog.cpp \
model/recipe/recipetablemodel.cpp \
gui/mainwindow.cpp \
gui/newDialogs/newfoodgroupdialog.cpp \
model/recipe/ingredients/recipeingredientlistmodel.cpp
gui/mainwindow.cpp
HEADERS += model/recipe/instruction.h \
model/recipe/recipe.h \
model/database/database.h \
model/recipe/ingredients/unitofmeasure.h \
model/recipe/ingredients/ingredient.h \
model/recipe/ingredients/ingredientlistmodel.h \
model/recipe/ingredients/recipeingredient.h \
model/recipe/tags/recipetag.h \
SQLite/sqlite3.h \
SQLite/sqlite3ext.h \
@ -53,27 +45,20 @@ HEADERS += model/recipe/instruction.h \
utils/fileutils.h \
gui/newrecipedialog.h \
model/recipe/tags/taglistmodel.h \
gui/newDialogs/newingredientdialog.h \
gui/newDialogs/newtagdialog.h \
gui/newDialogs/newunitdialog.h \
utils/aspectratiopixmaplabel.h \
utils/stringutils.h \
gui/openrecipedialog.h \
model/recipe/recipetablemodel.h \
gui/mainwindow.h \
gui/newDialogs/newfoodgroupdialog.h \
model/recipe/ingredients/recipeingredientlistmodel.h
gui/mainwindow.h
LIBS += -ldl \
FORMS += gui/mainwindow.ui \
gui/newrecipedialog.ui \
gui/newDialogs/newingredientdialog.ui \
gui/newDialogs/newtagdialog.ui \
gui/newDialogs/newunitdialog.ui \
gui/openrecipedialog.ui \
gui/mainwindow.ui \
gui/newDialogs/newfoodgroupdialog.ui
gui/mainwindow.ui
DISTFILES += \
.gitignore

View File

@ -48,7 +48,7 @@ void MainWindow::setInstruction(Instruction instruction){
ui->instructionsTextEdit->setHtml(QString::fromStdString(instruction.getHTML()));
}
void MainWindow::setIngredients(vector<RecipeIngredient> ingredients){
void MainWindow::setIngredients(vector<Ingredient> ingredients){
this->ingredientModel.setIngredients(ingredients);
}

View File

@ -6,7 +6,7 @@
#include <QAbstractListModel>
#include "model/recipe/recipe.h"
#include "model/recipe/ingredients/recipeingredientlistmodel.h"
#include "model/recipe/ingredients/ingredientlistmodel.h"
#include "gui/newrecipedialog.h"
#include "gui/openrecipedialog.h"
#include "utils/stringutils.h"
@ -41,14 +41,14 @@ public:
private:
Ui::MainWindow *ui;
RecipeDatabase *recipeDB;
RecipeIngredientListModel ingredientModel;
IngredientListModel ingredientModel;
TagListModel tagsListModel;
Recipe currentRecipe;
//Hidden manipulation methods.
void setRecipeName(string name);
void setInstruction(Instruction instruction);
void setIngredients(vector<RecipeIngredient> ingredients);
void setIngredients(vector<Ingredient> ingredients);
void setImage(QImage img);
void setPrepTime(QTime prepTime);
void setCookTime(QTime cookTime);

View File

@ -1,18 +0,0 @@
#include "newfoodgroupdialog.h"
#include "ui_newfoodgroupdialog.h"
newFoodGroupDialog::newFoodGroupDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::newFoodGroupDialog)
{
ui->setupUi(this);
}
newFoodGroupDialog::~newFoodGroupDialog()
{
delete ui;
}
string newFoodGroupDialog::getFoodGroup() const{
return ui->lineEdit->text().toStdString();
}

View File

@ -1,27 +0,0 @@
#ifndef NEWFOODGROUPDIALOG_H
#define NEWFOODGROUPDIALOG_H
#include <QDialog>
#include <string>
using namespace std;
namespace Ui {
class newFoodGroupDialog;
}
class newFoodGroupDialog : public QDialog
{
Q_OBJECT
public:
explicit newFoodGroupDialog(QWidget *parent = 0);
~newFoodGroupDialog();
string getFoodGroup() const;
private:
Ui::newFoodGroupDialog *ui;
};
#endif // NEWFOODGROUPDIALOG_H

View File

@ -1,102 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>newFoodGroupDialog</class>
<widget class="QDialog" name="newFoodGroupDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>240</width>
<height>114</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="windowTitle">
<string>New Food Group</string>
</property>
<property name="windowIcon">
<iconset resource="../../res.qrc">
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Add New Food Group</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEdit">
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>newFoodGroupDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>newFoodGroupDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,49 +0,0 @@
#include "newingredientdialog.h"
#include "ui_newingredientdialog.h"
NewIngredientDialog::NewIngredientDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::NewIngredientDialog)
{
ui->setupUi(this);
}
NewIngredientDialog::NewIngredientDialog(RecipeDatabase *recipeDB, QWidget *parent) : NewIngredientDialog(parent){
this->recipeDB = recipeDB;
this->populateFoodGroupBox();
}
NewIngredientDialog::~NewIngredientDialog()
{
delete ui;
}
Ingredient NewIngredientDialog::getIngredient(){
return Ingredient(ui->nameEdit->text().toLower().toStdString(), ui->foodGroupBox->currentText().toStdString());
}
void NewIngredientDialog::populateFoodGroupBox(){
vector<string> foodGroups = this->recipeDB->retrieveAllFoodGroups();
ui->foodGroupBox->clear();
for (unsigned int i = 0; i < foodGroups.size(); i++){
QString s = QString::fromStdString(foodGroups[i]);
ui->foodGroupBox->insertItem(i, s);
}
}
void NewIngredientDialog::on_addFoodGroupButton_clicked(){
newFoodGroupDialog d(this);
if (d.exec() == QDialog::Accepted){
string s = d.getFoodGroup();
if (!s.empty()){
ui->foodGroupBox->addItem(QString::fromStdString(s));
ui->foodGroupBox->setCurrentText(QString::fromStdString(s));
} else {
QMessageBox::warning(this, "Empty Food Group", "The food group you entered is empty!");
}
}
}
void NewIngredientDialog::on_deleteFoodGroupButton_clicked(){
ui->foodGroupBox->removeItem(ui->foodGroupBox->currentIndex());
}

View File

@ -1,39 +0,0 @@
#ifndef NEWINGREDIENTDIALOG_H
#define NEWINGREDIENTDIALOG_H
#include <QDialog>
#include <QMessageBox>
#include "model/recipe/ingredients/ingredient.h"
#include "model/database/recipedatabase.h"
#include "gui/newDialogs/newfoodgroupdialog.h"
namespace Ui {
class NewIngredientDialog;
}
class NewIngredientDialog : public QDialog
{
Q_OBJECT
public:
explicit NewIngredientDialog(QWidget *parent = 0);
NewIngredientDialog(RecipeDatabase *recipeDB, QWidget *parent = 0);
~NewIngredientDialog();
//Access values.
Ingredient getIngredient();
private slots:
void on_addFoodGroupButton_clicked();
void on_deleteFoodGroupButton_clicked();
private:
Ui::NewIngredientDialog *ui;
RecipeDatabase *recipeDB;
void populateFoodGroupBox();
};
#endif // NEWINGREDIENTDIALOG_H

View File

@ -1,158 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewIngredientDialog</class>
<widget class="QDialog" name="NewIngredientDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>367</width>
<height>228</height>
</rect>
</property>
<property name="windowTitle">
<string>New Ingredient</string>
</property>
<property name="windowIcon">
<iconset resource="../../res.qrc">
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QWidget" name="mainContentPanel" native="true">
<property name="enabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="namePanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="nameEdit"/>
</item>
</layout>
</widget>
</item>
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="foodGroupPanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="foodGroupLabel">
<property name="text">
<string>Food Group</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="foodGroupSelectionWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="foodGroupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAlphabetically</enum>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QPushButton" name="addFoodGroupButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../res.qrc">
<normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QPushButton" name="deleteFoodGroupButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../res.qrc">
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>NewIngredientDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>NewIngredientDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,31 +0,0 @@
#include "newunitdialog.h"
#include "ui_newunitdialog.h"
NewUnitDialog::NewUnitDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::NewUnitDialog)
{
ui->setupUi(this);
ui->typeComboBox->clear();
QStringList list({"Mass", "Volume", "Length", "Misc"});
ui->typeComboBox->insertItems(0, list);
}
NewUnitDialog::~NewUnitDialog()
{
delete ui;
}
UnitOfMeasure NewUnitDialog::getUnit(){
return UnitOfMeasure(ui->unitNameEdit->text().toLower().toStdString(),
ui->pluralNameEdit->text().toLower().toStdString(),
ui->abbreviationEdit->text().toStdString(),
this->getSelectedType(),
ui->coefficientSpinBox->value());
}
int NewUnitDialog::getSelectedType(){
return ui->typeComboBox->currentIndex();
}

View File

@ -1,27 +0,0 @@
#ifndef NEWUNITDIALOG_H
#define NEWUNITDIALOG_H
#include <QDialog>
#include "model/recipe/ingredients/unitofmeasure.h"
namespace Ui {
class NewUnitDialog;
}
class NewUnitDialog : public QDialog
{
Q_OBJECT
public:
explicit NewUnitDialog(QWidget *parent = 0);
~NewUnitDialog();
UnitOfMeasure getUnit();
private:
Ui::NewUnitDialog *ui;
int getSelectedType();
};
#endif // NEWUNITDIALOG_H

View File

@ -1,228 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewUnitDialog</class>
<widget class="QDialog" name="NewUnitDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>195</width>
<height>340</height>
</rect>
</property>
<property name="windowTitle">
<string>New Unit</string>
</property>
<property name="windowIcon">
<iconset resource="../../res.qrc">
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="contentPanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Unit Name</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="unitNameEdit"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Plural Name</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="pluralNameEdit"/>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Abbreviation</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="abbreviationEdit"/>
</item>
<item>
<widget class="QWidget" name="unitTypePanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item alignment="Qt::AlignLeft">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="typeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="coefficientPanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_5">
<property name="font">
<font>
<pointsize>12</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Metric Coefficient</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="coefficientSpinBox">
<property name="maximum">
<double>1000.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>NewUnitDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>NewUnitDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -15,9 +15,6 @@ NewRecipeDialog::NewRecipeDialog(QWidget *parent) :
NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, QWidget *parent) : NewRecipeDialog(parent){
this->recipeDB = db;
this->populateIngredientsBox();
this->populateUnitsBox();
this->populateTagsBox();
}
@ -55,24 +52,6 @@ bool NewRecipeDialog::isAccepted() const{
return this->accepted;
}
void NewRecipeDialog::populateIngredientsBox(){
this->ingredients = this->recipeDB->retrieveAllIngredients();
ui->ingredientNameBox->clear();
for (unsigned int i = 0; i < this->ingredients.size(); i++){
QString s = QString::fromStdString(this->ingredients[i].getName());
ui->ingredientNameBox->insertItem(i, s);
}
}
void NewRecipeDialog::populateUnitsBox(){
this->units = this->recipeDB->retrieveAllUnitsOfMeasure();
ui->unitComboBox->clear();
for (unsigned int i = 0; i < this->units.size(); i++){
QString s = QString::fromStdString(this->units[i].getName());
ui->unitComboBox->insertItem(i, s);
}
}
void NewRecipeDialog::populateTagsBox(){
this->tags = this->recipeDB->retrieveAllTags();
ui->tagsComboBox->clear();
@ -83,12 +62,9 @@ void NewRecipeDialog::populateTagsBox(){
}
void NewRecipeDialog::on_addIngredientButton_clicked(){
//Construct a recipe ingredient from the supplied data.
Ingredient i = this->ingredients[ui->ingredientNameBox->currentIndex()];
UnitOfMeasure u = this->units[ui->unitComboBox->currentIndex()];
RecipeIngredient ri(i, ui->quantitySpinBox->value(), u, ui->commentsLineEdit->text().toStdString());
this->ingredientListModel.addIngredient(ri);
ui->commentsLineEdit->clear();
Ingredient ing(ui->ingredientLineEdit->text().toStdString());
this->ingredientListModel.addIngredient(ing);
ui->ingredientLineEdit->clear();
}
void NewRecipeDialog::on_italicsButton_clicked(){
@ -113,7 +89,6 @@ void NewRecipeDialog::on_buttonBox_rejected(){
}
void NewRecipeDialog::on_addTagButton_clicked(){
//Add a tag to the list of those prepared to be added.
this->tagsListModel.addTag(this->tags[ui->tagsComboBox->currentIndex()]);
}
@ -140,37 +115,6 @@ void NewRecipeDialog::on_removeIngredientButton_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->recipeDB, this);
d.show();
if (d.exec() == QDialog::Accepted){
Ingredient i = d.getIngredient();
if (!i.getName().empty() && !i.getFoodGroup().empty() && this->recipeDB->storeIngredient(i)){
this->populateIngredientsBox();
ui->ingredientNameBox->setCurrentText(QString::fromStdString(i.getName()));
} else {
QMessageBox::critical(this, "Error", "Unable to add ingredient.");
}
}
}
void NewRecipeDialog::on_newTagButton_clicked(){
NewTagDialog d(this);
d.show();
@ -206,31 +150,6 @@ void NewRecipeDialog::on_removeTagButton_clicked(){
}
}
void NewRecipeDialog::on_newUnitButton_clicked(){
NewUnitDialog d(this);
d.show();
if (d.exec() == QDialog::Accepted){
UnitOfMeasure u = d.getUnit();
if (u.getName().empty() || u.getNamePlural().empty() || u.getAbbreviation().empty() || !this->recipeDB->storeUnitOfMeasure(u)){
QMessageBox::critical(this, "Error", "Unable to store new unit. Make sure all the information is filled in!");
} else {
this->populateUnitsBox();
ui->unitComboBox->setCurrentText(QString::fromStdString(u.getName()));
}
}
}
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();
}
}
void NewRecipeDialog::on_ingredientLineEdit_returnPressed(){
this->on_addIngredientButton_clicked();
}

View File

@ -8,12 +8,10 @@
#include <QMessageBox>
#include "model/database/recipedatabase.h"
#include "model/recipe/ingredients/recipeingredientlistmodel.h"
#include "model/recipe/ingredients/ingredientlistmodel.h"
#include "model/recipe/tags/taglistmodel.h"
#include "gui/newDialogs/newingredientdialog.h"
#include "gui/newDialogs/newtagdialog.h"
#include "gui/newDialogs/newunitdialog.h"
namespace Ui {
class NewRecipeDialog;
@ -29,6 +27,7 @@ class NewRecipeDialog : public QDialog
NewRecipeDialog(RecipeDatabase *db, Recipe recipe, QWidget *parent = 0);
~NewRecipeDialog();
//Extracts a recipe from all the information entered in the ui.
Recipe getRecipe();
bool isAccepted() const;
private slots:
@ -38,8 +37,10 @@ class NewRecipeDialog : public QDialog
void on_boldButton_clicked();
//Sets the dialog as accepted, as in, the user accepts that they want to create the recipe.
void on_buttonBox_accepted();
//The user has rejected the creation of the recipe.
void on_buttonBox_rejected();
void on_addTagButton_clicked();
@ -50,31 +51,22 @@ class NewRecipeDialog : public QDialog
void on_removeIngredientButton_clicked();
void on_deleteIngredientButton_clicked();
void on_newIngredientButton_clicked();
void on_newTagButton_clicked();
void on_removeTagButton_clicked();
void on_newUnitButton_clicked();
void on_deleteUnitButton_clicked();
void on_ingredientLineEdit_returnPressed();
private:
Ui::NewRecipeDialog *ui;
RecipeDatabase *recipeDB;
vector<Ingredient> ingredients;
vector<UnitOfMeasure> units;
vector<RecipeTag> tags;
RecipeIngredientListModel ingredientListModel;
IngredientListModel ingredientListModel;
TagListModel tagsListModel;
bool accepted = false;
//Helper functions to fill fields.
void populateIngredientsBox();
void populateUnitsBox();
void populateTagsBox();
};

View File

@ -175,7 +175,7 @@
<second>0</second>
<year>1999</year>
<month>12</month>
<day>21</day>
<day>20</day>
</datetime>
</property>
<property name="currentSection">
@ -530,176 +530,7 @@ QPushButton#deleteTagButton:pressed{
</widget>
</item>
<item>
<widget class="QWidget" name="ingredientNamePanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="ingredientNameBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(113, 119, 255);</string>
</property>
<property name="editable">
<bool>false</bool>
</property>
<property name="currentText">
<string/>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAlphabetically</enum>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="newIngredientButton">
<property name="toolTip">
<string>Create a new ingredient</string>
</property>
<property name="icon">
<iconset resource="../res.qrc">
<normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteIngredientButton">
<property name="toolTip">
<string>Delete this ingredient</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../res.qrc">
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="quantityPanel" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="amountLabel">
<property name="font">
<font>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Amount</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="quantitySpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="unitComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(113, 119, 255);</string>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAlphabetically</enum>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight">
<widget class="QPushButton" name="newUnitButton">
<property name="toolTip">
<string>Create a new unit of measure</string>
</property>
<property name="icon">
<iconset resource="../res.qrc">
<normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteUnitButton">
<property name="toolTip">
<string>Delete this unit of measure</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../res.qrc">
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLineEdit" name="commentsLineEdit">
<widget class="QLineEdit" name="ingredientLineEdit">
<property name="minimumSize">
<size>
<width>0</width>
@ -710,10 +541,10 @@ QPushButton#deleteTagButton:pressed{
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="placeholderText">
<string>Comments</string>
<string>Write ingredient here...</string>
</property>
<property name="clearButtonEnabled">
<bool>false</bool>
@ -809,11 +640,14 @@ QPushButton#removeIngredientButton:pressed{
<enum>QFrame::NoFrame</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="horizontalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="batchSize">
<number>100</number>
</property>

View File

@ -8,13 +8,8 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) :
ui->setupUi(this);
ui->recipeTableView->setModel(&this->recipeTableModel);
ui->ingredientsListView->setModel(&this->ingredientsModel);
ui->tagsListView->setModel(&this->tagsModel);
QObject::connect(ui->ingredientsListView->selectionModel(),
SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
this,
SLOT(onIngredientsListViewSelectionChanged(QItemSelection)));
QObject::connect(ui->tagsListView->selectionModel(),
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
this,
@ -23,9 +18,7 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) :
OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){
this->recipeDB = recipeDB;
this->populateIngredientsList();
this->populateTagsList();
this->populateFoodGroupsList();
this->populateRecipesTable(this->recipeDB->retrieveAllRecipes());
}
@ -45,21 +38,10 @@ void OpenRecipeDialog::populateRecipesTable(vector<Recipe> recipes){
ui->recipeTableView->show();
}
void OpenRecipeDialog::populateIngredientsList(){
this->ingredientsModel.setIngredients(this->recipeDB->retrieveAllIngredients());
}
void OpenRecipeDialog::populateTagsList(){
this->tagsModel.setTags(this->recipeDB->retrieveAllTags());
}
void OpenRecipeDialog::populateFoodGroupsList(){
for (string s : this->recipeDB->retrieveAllFoodGroups()){
ui->foodGroupsListWidget->addItem(QString::fromStdString(s));
}
//ui->foodGroupsListWidget->show();
}
void OpenRecipeDialog::on_deleteRecipeButton_clicked(){
QItemSelectionModel *selectModel = ui->recipeTableView->selectionModel();
if (!selectModel->hasSelection()){
@ -92,17 +74,6 @@ void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index
this->close();
}
void OpenRecipeDialog::onIngredientsListViewSelectionChanged(const QItemSelection &selection){
Q_UNUSED(selection);
vector<Ingredient> ingredients;
QModelIndexList indexes = ui->ingredientsListView->selectionModel()->selectedRows();
for (QModelIndex index : indexes){
Ingredient i = this->ingredientsModel.getIngredients().at(index.row());
ingredients.push_back(i);
}
this->populateRecipesTable(this->recipeDB->retrieveRecipesWithIngredients(ingredients));
}
void OpenRecipeDialog::onTagsListViewSelectionChanged(const QItemSelection &selection){
Q_UNUSED(selection);
vector<RecipeTag> tags;
@ -119,20 +90,9 @@ void OpenRecipeDialog::on_nameEdit_textChanged(const QString &arg1){
this->populateRecipesTable(this->recipeDB->retrieveRecipesWithSubstring(ui->nameEdit->text().toStdString()));
}
void OpenRecipeDialog::on_foodGroupsListWidget_itemSelectionChanged(){
vector<string> groups;
for (QModelIndex index : ui->foodGroupsListWidget->selectionModel()->selectedRows()){
QListWidgetItem *item = ui->foodGroupsListWidget->item(index.row());
groups.push_back(item->text().toStdString());
}
this->populateRecipesTable(this->recipeDB->retrieveRecipesWithFoodGroups(groups));
}
void OpenRecipeDialog::on_clearSearchButton_clicked(){
ui->nameEdit->clear();
ui->foodGroupsListWidget->selectionModel()->clearSelection();
ui->tagsListView->selectionModel()->clearSelection();
ui->ingredientsListView->selectionModel()->clearSelection();
this->populateRecipesTable(this->recipeDB->retrieveAllRecipes());
}

View File

@ -30,14 +30,10 @@ class OpenRecipeDialog : public QDialog
void on_recipeTableView_doubleClicked(const QModelIndex &index);
void onIngredientsListViewSelectionChanged(const QItemSelection &selection);
void onTagsListViewSelectionChanged(const QItemSelection &selection);
void on_nameEdit_textChanged(const QString &arg1);
void on_foodGroupsListWidget_itemSelectionChanged();
void on_clearSearchButton_clicked();
void on_exitButton_clicked();
@ -48,13 +44,10 @@ class OpenRecipeDialog : public QDialog
RecipeTableModel recipeTableModel;
Recipe selectedRecipe;
IngredientListModel ingredientsModel;
TagListModel tagsModel;
void populateRecipesTable(vector<Recipe> recipes);
void populateIngredientsList();
void populateTagsList();
void populateFoodGroupsList();
};
#endif // OPENRECIPEDIALOG_H

View File

@ -48,7 +48,7 @@
<property name="spacing">
<number>0</number>
</property>
<item alignment="Qt::AlignLeft">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="minimumSize">
<size>
@ -63,7 +63,7 @@
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>2</number>
<number>0</number>
</property>
<widget class="QWidget" name="Tags">
<attribute name="icon">
@ -119,105 +119,6 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="ingredientsTab">
<attribute name="icon">
<iconset resource="../res.qrc">
<normaloff>:/images/images/ingredients.png</normaloff>:/images/images/ingredients.png</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Ingredients</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListView" name="ingredientsListView">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="isWrapping" stdset="0">
<bool>false</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="foodGroups">
<attribute name="icon">
<iconset resource="../res.qrc">
<normaloff>:/images/images/foodPyramid.png</normaloff>:/images/images/foodPyramid.png</iconset>
</attribute>
<attribute name="title">
<string/>
</attribute>
<attribute name="toolTip">
<string>Food Groups</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="foodGroupsListWidget">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>

View File

@ -8,34 +8,11 @@
#include "model/database/recipedatabase.h"
#include "utils/fileutils.h"
void test(RecipeDatabase *recipeDB){
vector<RecipeIngredient> 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",
"Andrew Lalis",
ri,
Instruction("Placeholder Text"),
QImage(),
vector<RecipeTag>({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);
}
Recipe checkForFirstRun(RecipeDatabase *recipeDB){
Recipe r = recipeDB->retrieveRandomRecipe();
if (r.isEmpty()){//There are no recipes in the database.
//Add some basic units to the units, and some basic ingredients.
recipeDB->addBasicUnits();
recipeDB->addBasicIngredients();
}
return r;
}

View File

@ -15,7 +15,10 @@ ResultTable Database::executeSQL(string statement){
this->sql = statement;
this->returnCode = sqlite3_prepare_v2(this->db, statement.c_str(), -1, &stmt, NULL);
if (this->returnCode != SQLITE_OK){
fprintf(stderr, "Unable to successfully prepare SQL statement. Error code: %d\n\tError Message: %s\n", this->returnCode, sqlite3_errmsg(this->db));
fprintf(stderr, "Unable to successfully prepare SQL statement. Error code: %d\n\tError Message: %s\nSQL Statement: %s\n",
this->returnCode,
sqlite3_errmsg(this->db),
statement.c_str());
return ResultTable(this->returnCode);
}
ResultTable t(statement);
@ -39,6 +42,15 @@ bool Database::insertInto(string tableName, vector<string> columnNames, vector<s
return (t.getReturnCode() == SQLITE_DONE);
}
bool Database::insertInto(string tableName, string columnName, string value){
if (columnName.empty() || value.empty() || tableName.empty()){
return false;
}
string query = "INSERT INTO " + tableName + " (" + columnName + ") VALUES (" + value + ");";
ResultTable t = this->executeSQL(query);
return (t.getReturnCode() == SQLITE_DONE);
}
ResultTable Database::selectFrom(string tableName, string columnNames, string conditions){
if (columnNames.size() == 0 || tableName.empty()){
return ResultTable();

View File

@ -24,8 +24,12 @@ public:
//Executes an SQL string statement in a safe way and returns the result.
ResultTable executeSQL(string statement);
//Inserts into a table.
bool insertInto(string tableName, vector<string> columnNames, vector<string> values);
bool insertInto(string tableName, string columnName, string value);
//Selects from a table.
ResultTable selectFrom(string tableName, string columnNames, string conditions);
//Deletes from a table.
bool deleteFrom(string tableName, string conditions);
bool tableExists(string tableName);

View File

@ -57,66 +57,18 @@ bool RecipeDatabase::storeRecipe(Recipe recipe){
return false;
}
bool RecipeDatabase::storeRecipeIngredient(RecipeIngredient ri, int recipeId){
int ingId = this->storeIngredient(ri);
if (ingId < 0) return false;
if (!this->storeUnitOfMeasure(ri.getUnit())) return false;
bool RecipeDatabase::storeRecipeIngredient(Ingredient i, int recipeId){
return this->insertInto("recipeIngredient",
vector<string>({
"ingredientId",
"recipeId",
"quantity",
"unitName",
"comment"
"content",
"recipeId"
}),
vector<string>({
std::to_string(ingId),
std::to_string(recipeId),
std::to_string(ri.getQuantity()),
ri.getUnit().getName(),
ri.getComment()
i.getContent(),
std::to_string(recipeId)
}));
}
int RecipeDatabase::storeIngredient(Ingredient ingredient){
ResultTable t = this->selectFrom("ingredient", "*", "WHERE name="+surroundString(ingredient.getName(), "'"));
if (t.isEmpty()){
bool success = this->insertInto("ingredient", vector<string>({"foodGroup", "name"}), vector<string>({ingredient.getFoodGroup(), ingredient.getName()}));
if (success){
return this->getLastInsertedRowId();
} else {
return -1;
}
} else {
return std::stoi(t.at(0, 0));
}
}
bool RecipeDatabase::storeUnitOfMeasure(UnitOfMeasure u){
ResultTable t = this->selectFrom("unitOfMeasure", "name", "WHERE name="+surroundString(u.getName(), "'"));
if (!t.isEmpty()){
return true;
}
bool success = this->insertInto("unitOfMeasure",
vector<string>({
"name",
"plural",
"abbreviation",
"type",
"metricCoefficient"
}),
vector<string>({
u.getName(),
u.getNamePlural(),
u.getAbbreviation(),
std::to_string(u.getType()),
std::to_string(u.getMetricCoefficient())
}));
return success;
}
bool RecipeDatabase::storeInstruction(Instruction instruction, int recipeId){
return FileUtils::saveInstruction(recipeId, instruction);
}
@ -166,31 +118,6 @@ vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
return this->readRecipesFromTable(t);
}
vector<Recipe> RecipeDatabase::retrieveRecipesWithIngredients(vector<Ingredient> ingredients){
vector<Recipe> recipes;
if (ingredients.empty()){
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<Recipe> RecipeDatabase::retrieveRecipesWithTags(vector<RecipeTag> tags){
vector<Recipe> recipes;
if (tags.empty()){
@ -210,53 +137,15 @@ vector<Recipe> RecipeDatabase::retrieveRecipesWithSubstring(string s){
return this->readRecipesFromTable(t);
}
vector<Recipe> RecipeDatabase::retrieveRecipesWithFoodGroups(vector<string> groups){
vector<Recipe> recipes;
if (groups.empty()){
return recipes;
}
string filterList = surroundString(groups.at(0), "'");
for (unsigned int i = 1; i < groups.size(); i++){
filterList += ", " + surroundString(groups.at(i), "'");
}
filterList = '(' + filterList + ')';
ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE recipeId IN (SELECT recipeId FROM recipeIngredient WHERE ingredientId IN (SELECT ingredientId FROM ingredient WHERE foodGroup IN "+filterList+" ) ) ORDER BY name;");
return this->readRecipesFromTable(t);
}
vector<string> RecipeDatabase::retrieveAllFoodGroups(){
ResultTable t = this->executeSQL("SELECT DISTINCT foodGroup FROM ingredient ORDER BY foodGroup;");
vector<string> foodGroups;
vector<Ingredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
ResultTable t = this->executeSQL("SELECT content "
"FROM recipeIngredient "
"WHERE recipeId = "+std::to_string(recipeId)+";");
vector<Ingredient> ingredients;
for (TableRow row : t.rows()){
foodGroups.push_back(row.at(0));
ingredients.push_back(Ingredient(row.at(0)));
}
return foodGroups;
}
vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
ResultTable t = this->executeSQL("SELECT ingredient.name, ingredient.foodGroup, "//0, 1
"recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment,"//2, 3, 4
"unitOfMeasure.name, unitOfMeasure.plural, unitOfMeasure.abbreviation, unitOfMeasure.type, unitOfMeasure.metricCoefficient "//5, 6, 7, 8, 9
"FROM ingredient "
"INNER JOIN recipeIngredient "
"ON ingredient.ingredientId = recipeIngredient.ingredientId "
"INNER JOIN unitOfMeasure "
"ON recipeIngredient.unitName = unitOfMeasure.name "
"WHERE recipeIngredient.recipeId = "+std::to_string(recipeId)+";");
vector<RecipeIngredient> ings;
for (TableRow row : t.rows()){
RecipeIngredient r(row.at(0),
row.at(1),
std::stof(row.at(2)),
UnitOfMeasure(row.at(5), row.at(6), row.at(7), std::stoi(row.at(8)), std::stod(row.at(9))),
row.at(4));
ings.push_back(r);
}
return ings;
}
int RecipeDatabase::retrieveIngredientId(string ingredientName){
return std::stoi(this->selectFrom("ingredient", "ingredientId", "WHERE name = '"+ingredientName+"'").at(0, 0));
return ingredients;
}
bool RecipeDatabase::deleteRecipeTags(int recipeId){
@ -268,27 +157,14 @@ bool RecipeDatabase::deleteRecipeIngredients(int recipeId){
}
vector<Ingredient> RecipeDatabase::retrieveAllIngredients(){
ResultTable t = this->selectFrom("ingredient", "name, foodGroup", "ORDER BY name");
ResultTable t = this->selectFrom("recipeIngredient", "content", "ORDER BY content");
vector<Ingredient> ings;
for (TableRow row : t.rows()){
Ingredient i(row.at(0), row.at(1));
ings.push_back(i);
ings.push_back(Ingredient(row.at(0)));
}
return ings;
}
vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
ResultTable t = this->selectFrom("unitOfMeasure", "name, plural, abbreviation, type, metricCoefficient", "ORDER BY name");
vector<UnitOfMeasure> units;
if (!t.isEmpty()){
for (TableRow row : t.rows()){
UnitOfMeasure u(row.at(0), row.at(1), row.at(2), std::stoi(row.at(3)), std::stod(row.at(4)));
units.push_back(u);
}
}
return units;
}
vector<RecipeTag> RecipeDatabase::retrieveTags(int recipeId){
ResultTable t = this->selectFrom("recipeTag", "tagName", "WHERE recipeId="+std::to_string(recipeId)+" ORDER BY tagName");
vector<RecipeTag> tags;
@ -358,14 +234,6 @@ bool RecipeDatabase::deleteIngredient(string name){
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()+"'");
}
@ -405,22 +273,16 @@ bool RecipeDatabase::updateRecipe(Recipe recipe, string originalName) {
return false;
}
bool ingredientsSuccess = this->deleteRecipeIngredients(id);
for (RecipeIngredient ri : recipe.getIngredients()){
for (Ingredient i : recipe.getIngredients()){
ingredientsSuccess = ingredientsSuccess && this->insertInto(
"recipeIngredient",
vector<string>({
"recipeId",
"ingredientId",
"unitName",
"quantity",
"comment"
"content"
}),
vector<string>({
idS,
std::to_string(this->retrieveIngredientId(ri.getName())),
ri.getUnit().getName(),
std::to_string(ri.getQuantity()),
ri.getComment()
i.getContent()
}));
}
if (!ingredientsSuccess){
@ -438,67 +300,11 @@ bool RecipeDatabase::updateRecipe(Recipe recipe, string originalName) {
}
}
bool RecipeDatabase::addBasicUnits(){
this->beginTransaction();
//Volume
this->storeUnitOfMeasure(UnitOfMeasure("Teaspoon", "Teaspoons", "tsp", UnitOfMeasure::VOLUME, 5.0));
this->storeUnitOfMeasure(UnitOfMeasure("Tablespoon", "Tablespoons", "tbsp", UnitOfMeasure::VOLUME, 15.0));
this->storeUnitOfMeasure(UnitOfMeasure("Fluid Ounce", "Fluid Ounces", "fl oz", UnitOfMeasure::VOLUME, 30.0));
this->storeUnitOfMeasure(UnitOfMeasure("Cup", "Cups", "c", UnitOfMeasure::VOLUME, 250.0));
this->storeUnitOfMeasure(UnitOfMeasure("Milliliter", "Milliliters", "mL", UnitOfMeasure::VOLUME, 1.0));
this->storeUnitOfMeasure(UnitOfMeasure("Liter", "Liters", "L", UnitOfMeasure::VOLUME, 1000.0));
this->storeUnitOfMeasure(UnitOfMeasure("Gallon", "Gallons", "gal", UnitOfMeasure::VOLUME, 3800.0));
//Mass/Weight
this->storeUnitOfMeasure(UnitOfMeasure("Ounce", "Ounces", "oz", UnitOfMeasure::MASS, 28.0));
this->storeUnitOfMeasure(UnitOfMeasure("Pound", "Pounds", "lb", UnitOfMeasure::MASS, 454.0));
this->storeUnitOfMeasure(UnitOfMeasure("Gram", "Grams", "g", UnitOfMeasure::MASS, 1.0));
this->storeUnitOfMeasure(UnitOfMeasure("Milligram", "Milligrams", "mg", UnitOfMeasure::MASS, 0.001));
this->storeUnitOfMeasure(UnitOfMeasure("Kilogram", "Kilograms", "kg", UnitOfMeasure::MASS, 1000.0));
//Length
this->storeUnitOfMeasure(UnitOfMeasure("Inch", "Inches", "in", UnitOfMeasure::LENGTH, 2.54));
this->storeUnitOfMeasure(UnitOfMeasure("Centimeter", "Centimeters", "cm", UnitOfMeasure::LENGTH, 1.0));
//MISC
this->storeUnitOfMeasure(UnitOfMeasure("Piece", "Pieces", "pc", UnitOfMeasure::MISC, 1.0));
this->storeUnitOfMeasure(UnitOfMeasure("Item", "Items", "", UnitOfMeasure::MISC, 1.0));
this->commitTransaction();
return true;
}
bool RecipeDatabase::addBasicIngredients(){
this->beginTransaction();
this->storeIngredient(Ingredient("Flour", "grains"));
this->storeIngredient(Ingredient("Eggs", "eggs"));
this->storeIngredient(Ingredient("Milk", "dairy"));
this->storeIngredient(Ingredient("Cheese", "dairy"));
this->storeIngredient(Ingredient("Salt", "spices"));
this->storeIngredient(Ingredient("Sugar", "sugars"));
this->storeIngredient(Ingredient("Vegetable Oil", "oils"));
this->storeIngredient(Ingredient("Olive Oil", "oils"));
this->storeIngredient(Ingredient("Water", "water"));
this->storeIngredient(Ingredient("Bell Pepper", "vegetables"));
this->storeIngredient(Ingredient("Onion", "vegetables"));
this->storeIngredient(Ingredient("Garlic", "spices"));
this->commitTransaction();
return true;
}
void RecipeDatabase::ensureTablesExist(){
//Make sure that foreign keys are enabled.
this->executeSQL("PRAGMA foreign_keys = ON;");
this->beginTransaction();
//Ingredients table.
this->executeSQL("CREATE TABLE IF NOT EXISTS ingredient("
"ingredientId INTEGER PRIMARY KEY,"
"foodGroup varchar,"
"name varchar UNIQUE);");
//Unit of Measure table.
this->executeSQL("CREATE TABLE IF NOT EXISTS unitOfMeasure("
"name varchar UNIQUE PRIMARY KEY,"
"plural varchar,"
"abbreviation varchar,"
"type int,"
"metricCoefficient real);");
//Recipe table. Each recipe can have at most one instruction, and one image.
this->executeSQL("CREATE TABLE IF NOT EXISTS recipe("
"recipeId INTEGER PRIMARY KEY,"
@ -515,14 +321,9 @@ void RecipeDatabase::ensureTablesExist(){
"FOREIGN KEY (recipeId) REFERENCES recipe(recipeId));");
//RecipeIngredient table.
this->executeSQL("CREATE TABLE IF NOT EXISTS recipeIngredient("
"ingredientId int,"
"recipeId int,"
"quantity real,"
"unitName varchar,"
"comment varchar,"
"FOREIGN KEY (ingredientId) REFERENCES ingredient(ingredientId),"
"FOREIGN KEY (recipeId) REFERENCES recipe(recipeId),"
"FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name));");
"content,"
"FOREIGN KEY (recipeId) REFERENCES recipe(recipeId));");
this->commitTransaction();
}

View File

@ -23,21 +23,15 @@ class RecipeDatabase : public Database
//SQL Helper methods.
//Storage.
bool storeRecipeIngredient(RecipeIngredient ri, int recipeId);
int storeIngredient(Ingredient ingredient);
bool storeUnitOfMeasure(UnitOfMeasure u);
bool storeRecipeIngredient(Ingredient i, int recipeId);
//Retrieval.
Recipe retrieveRecipe(string name);
Recipe retrieveRandomRecipe();
vector<Recipe> retrieveAllRecipes();
vector<Recipe> retrieveRecipesWithIngredients(vector<Ingredient> ingredients);
vector<Recipe> retrieveRecipesWithTags(vector<RecipeTag> tags);
vector<Recipe> retrieveRecipesWithSubstring(string s);
vector<Recipe> retrieveRecipesWithFoodGroups(vector<string> groups);
vector<string> retrieveAllFoodGroups();
vector<Ingredient> retrieveAllIngredients();
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
vector<RecipeTag> retrieveAllTags();
//Deletion.
@ -50,9 +44,6 @@ class RecipeDatabase : public Database
//Updating.
bool updateRecipe(Recipe recipe, string originalName);
//Adding basic information at start.
bool addBasicUnits();
bool addBasicIngredients();
private:
//Utility methods.
@ -68,8 +59,7 @@ class RecipeDatabase : public Database
//Retrieval
vector<RecipeTag> retrieveTags(int recipeId);
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
int retrieveIngredientId(string ingredientName);
vector<Ingredient> retrieveRecipeIngredients(int recipeId);
//Deletion
bool deleteRecipeTags(int recipeId);

View File

@ -1,31 +1,18 @@
#include "model/recipe/ingredients/ingredient.h"
Ingredient::Ingredient(){
setName("NULL");
setFoodGroup("NULL");
setContent("NULL");
}
Ingredient::Ingredient(string name, string foodGroup){
setName(name);
setFoodGroup(foodGroup);
Ingredient::Ingredient(string content){
setContent(content);
}
string Ingredient::getName() const{
return this->name;
string Ingredient::getContent() const{
return this->content;
}
string Ingredient::getFoodGroup() const{
return this->foodGroup;
void Ingredient::setContent(string newContent){
this->content = newContent;
}
void Ingredient::setName(string newName){
this->name = newName;
}
void Ingredient::setFoodGroup(string newFoodGroup){
this->foodGroup = newFoodGroup;
}
string Ingredient::toString(){
return this->getName();
}

View File

@ -6,28 +6,25 @@
using namespace std;
/**
* @brief The Ingredient class represents an ingredient, which is classified by a food group, and has a name and an ID.
* An ingredient cannot be included on its own in a recipe, and must be paired with a Unit in a RecipeIngredient Object.
* @brief The Ingredient class represents an ingredient, which is a string representing one component of a recipe.
* The user is free to compose a recipe string however they like. However, the program will restrict obviously
* invalid input, and try to be smart about determining if an ingredient is valid.
*/
class Ingredient
{
public:
Ingredient();
Ingredient(string name, string foodGroup);
Ingredient(string content);
//Getters
string getName() const;
string getFoodGroup() const;
string getContent() const;
//Setters
void setName(string newName);
void setFoodGroup(string newFoodGroup);
void setContent(string newContent);
string toString();
protected:
string name;
string foodGroup;
string content;
};
#endif // INGREDIENT_H

View File

@ -13,7 +13,7 @@ QVariant IngredientListModel::data(const QModelIndex &index, int role) const{
int row = index.row();
Ingredient i = this->ingredients[row];
string displayStr = i.toString();
string displayStr = i.getContent();
switch(role){
case Qt::DisplayRole:
@ -30,14 +30,15 @@ void IngredientListModel::setIngredients(vector<Ingredient> ingredients){
emit dataChanged(index, bottomIndex);
}
bool IngredientListModel::addIngredient(Ingredient ri){
bool IngredientListModel::addIngredient(Ingredient i){
//Add only if it doesn't exist already.
for (unsigned int i = 0; i < this->ingredients.size(); i++){
if (!this->ingredients[i].getName().compare(ri.getName())){
for (Ingredient ing : this->ingredients){
if (!ing.getContent().compare(i.getContent())){
return false;
}
}
this->ingredients.push_back(ri);
//The ingredient doesn't exist already, so we'll add it.
this->ingredients.push_back(i);
QModelIndex index = createIndex(this->ingredients.size()-1, 0);
QModelIndex bottomIndex = createIndex(this->ingredients.size()-1, 0);
emit dataChanged(index, bottomIndex);

View File

@ -3,9 +3,16 @@
#include <QAbstractListModel>
#include <QModelIndex>
#include <vector>
#include "model/recipe/ingredients/recipeingredient.h"
#include "model/recipe/ingredients/ingredient.h"
/**
* @brief The IngredientListModel class
*
* The ingredient list model extends the QAbstractListModel and is used for lists of ingredients,
* whether they appear in the NewRecipe dialog or in the main recipe view.
*/
class IngredientListModel : public QAbstractListModel
{
public:
@ -17,15 +24,13 @@ public:
//Custom methods to handle ingredient data.
void setIngredients(vector<Ingredient> ingredients);
bool addIngredient(Ingredient ri);
bool addIngredient(Ingredient i);
void deleteIngredient(int index);
vector<Ingredient> getIngredients();
private:
vector<Ingredient> ingredients;
//Helper for printing.
};
#endif // INGREDIENTLISTMODEL_H

View File

@ -1,60 +0,0 @@
#include "model/recipe/ingredients/recipeingredient.h"
RecipeIngredient::RecipeIngredient(string name, string foodGroup, float quantity, UnitOfMeasure unit, string comment) : Ingredient(name, foodGroup){
setQuantity(quantity);
setUnit(unit);
setComment(comment);
}
RecipeIngredient::RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure unit, string comment){
setName(i.getName());
setFoodGroup(i.getFoodGroup());
setQuantity(quantity);
setUnit(unit);
setComment(comment);
}
RecipeIngredient::RecipeIngredient(Ingredient &i) : RecipeIngredient(i, 0.0f, UnitOfMeasure("bleh"), "Fuck"){
//Constructs recipe ingredient from ingredient which is a hidden recipe ingredient.
}
RecipeIngredient::RecipeIngredient(){
}
float RecipeIngredient::getQuantity() const{
return this->quantity;
}
UnitOfMeasure RecipeIngredient::getUnit() const{
return this->unit;
}
string RecipeIngredient::getComment() const{
return this->comment;
}
void RecipeIngredient::setQuantity(float newQuantity){
this->quantity = newQuantity;
}
void RecipeIngredient::setUnit(UnitOfMeasure newUnit){
this->unit = newUnit;
}
void RecipeIngredient::setComment(string newComment){
this->comment = newComment;
}
string RecipeIngredient::toString(){
string result;
if (std::ceil(this->getQuantity()) == this->getQuantity()){
result += std::to_string((int)this->getQuantity());
} else {
result += StringUtils::toString(this->getQuantity());
}
result += " " + this->getUnit().getAbbreviation() + " " + this->getName();
if (!this->getComment().empty()) result += " (" + this->getComment() + ")";
return result;
}

View File

@ -1,43 +0,0 @@
#ifndef RECIPEINGREDIENT_H
#define RECIPEINGREDIENT_H
#include <string>
#include <cmath>
#include "model/recipe/ingredients/ingredient.h"
#include "model/recipe/ingredients/unitofmeasure.h"
#include "utils/stringutils.h"
using namespace std;
/**
* @brief The RecipeIngredient class represents both an ingredient and a unit of measure, to be used in a recipe object.
*/
class RecipeIngredient : public Ingredient
{
public:
//Constructor for new RecipeIngredient without starting child ingredient.
RecipeIngredient(string name, string foodGroup, float quantity, UnitOfMeasure unit, string comment);
//Constructor using data from a child ingredient.
RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure unit, string comment);
RecipeIngredient(Ingredient &i);
RecipeIngredient();
//Getters
float getQuantity() const;
UnitOfMeasure getUnit() const;
string getComment() const;
//Setters
void setQuantity(float newQuantity);
void setUnit(UnitOfMeasure newUnit);
void setComment(string newComment);
string toString();
private:
float quantity;
UnitOfMeasure unit;
string comment;
};
#endif // RECIPEINGREDIENT_H

View File

@ -1,54 +0,0 @@
#include "recipeingredientlistmodel.h"
RecipeIngredientListModel::RecipeIngredientListModel(){
this->ingredients = vector<RecipeIngredient>();
}
int RecipeIngredientListModel::rowCount(const QModelIndex &parent) const{
Q_UNUSED(parent);
return this->ingredients.size();
}
QVariant RecipeIngredientListModel::data(const QModelIndex &index, int role) const{
int row = index.row();
RecipeIngredient i = this->ingredients[row];
string displayStr = i.toString();
switch(role){
case Qt::DisplayRole:
return QString::fromStdString(displayStr);
}
return QVariant();
}
void RecipeIngredientListModel::setIngredients(vector<RecipeIngredient> ingredients){
this->ingredients = ingredients;
QModelIndex index = createIndex(0, 0);
QModelIndex bottomIndex = createIndex(ingredients.size()-1, 0);
emit dataChanged(index, bottomIndex);
}
bool RecipeIngredientListModel::addIngredient(RecipeIngredient ri){
//Add only if it doesn't exist already.
for (unsigned int i = 0; i < this->ingredients.size(); i++){
if (!this->ingredients[i].getName().compare(ri.getName())){
return false;
}
}
this->ingredients.push_back(ri);
QModelIndex index = createIndex(this->ingredients.size()-1, 0);
QModelIndex bottomIndex = createIndex(this->ingredients.size()-1, 0);
emit dataChanged(index, bottomIndex);
return true;
}
void RecipeIngredientListModel::deleteIngredient(int index){
this->ingredients.erase(this->ingredients.begin() + index);
emit dataChanged(createIndex(0, 0), createIndex(this->ingredients.size()-1, 0));
}
vector<RecipeIngredient> RecipeIngredientListModel::getIngredients(){
return this->ingredients;
}

View File

@ -1,28 +0,0 @@
#ifndef RECIPEINGREDIENTLISTMODEL_H
#define RECIPEINGREDIENTLISTMODEL_H
#include <QAbstractListModel>
#include "model/recipe/ingredients/recipeingredient.h"
class RecipeIngredientListModel : public QAbstractListModel
{
public:
RecipeIngredientListModel();
//Overridden methods.
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
//Custom methods to handle ingredient data.
void setIngredients(vector<RecipeIngredient> ingredients);
bool addIngredient(RecipeIngredient ri);
void deleteIngredient(int index);
vector<RecipeIngredient> getIngredients();
private:
vector<RecipeIngredient> ingredients;
};
#endif // RECIPEINGREDIENTLISTMODEL_H

View File

@ -1,42 +0,0 @@
#include "unitofmeasure.h"
UnitOfMeasure::UnitOfMeasure(string name, string plural, string abbreviation, int type, double coef){
this->name = name;
this->plural = plural;
this->abbreviation = abbreviation;
this->type = type;
this->metricCoefficient = coef;
}
UnitOfMeasure::UnitOfMeasure(string name){
this->name = name;
this->plural = name + "s";
this->abbreviation = "NULL";
this->type = MISC;
this->metricCoefficient = 1;
///TODO: Make actual guessing of this stuff.
}
UnitOfMeasure::UnitOfMeasure() : UnitOfMeasure::UnitOfMeasure("", "", "", MISC, 1.0){
//Default constructor initializes all fields to empty strings.
}
string UnitOfMeasure::getName() const{
return this->name;
}
string UnitOfMeasure::getNamePlural() const{
return this->plural;
}
string UnitOfMeasure::getAbbreviation() const{
return this->abbreviation;
}
int UnitOfMeasure::getType() const{
return this->type;
}
double UnitOfMeasure::getMetricCoefficient() const{
return this->metricCoefficient;
}

View File

@ -1,42 +0,0 @@
#ifndef UNITOFMEASURE_H
#define UNITOFMEASURE_H
#include <string>
using namespace std;
/**
* @brief The UnitOfMeasure class represents a way to measure an ingredient. It contains a name, an abbreviation, plural name, and some information on conversion.
*/
class UnitOfMeasure
{
public:
//Constants Declarations.
static const int MASS = 0;
static const int VOLUME = 1;
static const int LENGTH = 2;
static const int MISC = 3;
//Full constructor.
UnitOfMeasure(string name, string plural, string abbreviation, int type, double coef);
//Attempt to guess unit from just a string.
UnitOfMeasure(string name);
//Constructor with default values.
UnitOfMeasure();
//Getters
string getName() const;
string getNamePlural() const;
string getAbbreviation() const;
int getType() const;
double getMetricCoefficient() const;
private:
string name; //The name of the unit of measure.
string plural; //The plural name.
string abbreviation; //A short version of the unit.
int type; //The type of unit, as one of the constants above.
double metricCoefficient; //The conversion from this unit to the standard metric unit.
};
#endif // UNITOFMEASURE_H

View File

@ -1,6 +1,6 @@
#include "model/recipe/recipe.h"
Recipe::Recipe(string name, string author, vector<RecipeIngredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings){
Recipe::Recipe(string name, string author, vector<Ingredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings){
setName(name);
setAuthor(author);
setIngredients(ingredients);
@ -13,7 +13,7 @@ Recipe::Recipe(string name, string author, vector<RecipeIngredient> ingredients,
setServings(servings);
}
Recipe::Recipe() : Recipe::Recipe("", "", vector<RecipeIngredient>(), Instruction(), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(), QTime(), 1.0f){
Recipe::Recipe() : Recipe::Recipe("", "", vector<Ingredient>(), Instruction(), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(), QTime(), 1.0f){
//Set default values when none are specified.
}
@ -25,20 +25,10 @@ string Recipe::getAuthor() const{
return this->authorName;
}
vector<RecipeIngredient> Recipe::getIngredients() const{
vector<Ingredient> Recipe::getIngredients() const{
return this->ingredients;
}
vector<string> Recipe::getFoodGroups() const{
vector<string> foodGroups;
for (RecipeIngredient ri : this->ingredients){
if (find(foodGroups.begin(), foodGroups.end(), ri.getFoodGroup()) == foodGroups.end()){
foodGroups.push_back(ri.getFoodGroup());
}
}
return foodGroups;
}
Instruction Recipe::getInstruction() const{
return this->instruction;
}
@ -83,7 +73,7 @@ void Recipe::setAuthor(string newName){
this->authorName = newName;
}
void Recipe::setIngredients(vector<RecipeIngredient> ingredients){
void Recipe::setIngredients(vector<Ingredient> ingredients){
this->ingredients = ingredients;
}
@ -91,7 +81,7 @@ void Recipe::setTags(vector<RecipeTag> tags){
this->tags = tags;
}
void Recipe::addIngredient(RecipeIngredient newIngredient){
void Recipe::addIngredient(Ingredient newIngredient){
this->ingredients.push_back(newIngredient);
}
@ -129,17 +119,11 @@ void Recipe::print(){
this->servings);
printf("\tInstruction: %s\n", this->instruction.getHTML().c_str());
printf("\tIngredients:\n");
for (vector<RecipeIngredient>::iterator it = this->ingredients.begin(); it != this->ingredients.end(); ++it){
RecipeIngredient ri = *it;
printf("\t\t%s, Food Group: %s, Quantity: %f, Unit: %s\n",
ri.getName().c_str(),
ri.getFoodGroup().c_str(),
ri.getQuantity(),
ri.getUnit().getName().c_str());
for (Ingredient i : this->ingredients){
printf("\t\t%s\n", i.getContent().c_str());
}
printf("\tTags:\n");
for (vector<RecipeTag>::iterator it = this->tags.begin(); it != this->tags.end(); ++it){
RecipeTag t = *it;
for (RecipeTag t : this->tags){
printf("\t\t%s\n", t.getValue().c_str());
}
}

View File

@ -8,7 +8,7 @@
#include <QImage>
#include <algorithm>
#include "model/recipe/ingredients/recipeingredient.h"
#include "model/recipe/ingredients/ingredient.h"
#include "model/recipe/instruction.h"
#include "model/recipe/tags/recipetag.h"
@ -32,14 +32,14 @@ class Recipe
{
public:
//Full constructor
Recipe(string name, string author, vector<RecipeIngredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings);
Recipe(string name, string author, vector<Ingredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings);
//Constructor with default values.
Recipe();
//Getters
string getName() const;
string getAuthor() const;
vector<RecipeIngredient> getIngredients() const;
vector<Ingredient> getIngredients() const;
vector<string> getFoodGroups() const;
Instruction getInstruction() const;
QImage getImage() const;
@ -54,9 +54,9 @@ public:
//Setters
void setName(string newName);
void setAuthor(string newName);
void setIngredients(vector<RecipeIngredient> ingredients);
void setIngredients(vector<Ingredient> ingredients);
void setTags(vector<RecipeTag> tags);
void addIngredient(RecipeIngredient newIngredient);
void addIngredient(Ingredient newIngredient);
void setInstruction(Instruction newInstruction);
void setImage(QImage newImage);
void setCreatedDate(QDate newDate);
@ -64,12 +64,13 @@ public:
void setCookTime(QTime newTime);
void setServings(float newServingsCount);
//Prints information about the recipe to the console, for debugging.
void print();
private:
//Main information.
string name; //The name of the recipe.
string authorName; //The name of the author of this recipe.
vector<RecipeIngredient> ingredients; //The list of ingredients in the recipe.
vector<Ingredient> ingredients; //The list of ingredients in the recipe.
Instruction instruction; //The instruction HTML document.
QImage image; //An image displayed alongside the recipe.
//Auxiliary Information.