Merge pull request #10 from andrewlalis/development
Stable first release
This commit is contained in:
commit
ce6effff91
|
@ -19,6 +19,10 @@ MainWindow::~MainWindow(){
|
|||
}
|
||||
|
||||
void MainWindow::loadFromRecipe(Recipe recipe){
|
||||
if (recipe.isEmpty()){
|
||||
setRecipeName("No recipes found.");
|
||||
setAuthorName("Click 'New' to get started.");
|
||||
} else {
|
||||
setRecipeName(recipe.getName());
|
||||
setInstruction(recipe.getInstruction());
|
||||
setIngredients(recipe.getIngredients());
|
||||
|
@ -32,6 +36,7 @@ void MainWindow::loadFromRecipe(Recipe recipe){
|
|||
setServings(recipe.getServings());
|
||||
setTags(recipe.getTags());
|
||||
this->currentRecipe = recipe;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setRecipeName(string name){
|
||||
|
@ -66,6 +71,10 @@ void MainWindow::setTags(vector<RecipeTag> tags){
|
|||
this->tagsListModel.setTags(tags);
|
||||
}
|
||||
|
||||
void MainWindow::setAuthorName(string name){
|
||||
ui->authorLabel->setText(QString::fromStdString(name));
|
||||
}
|
||||
|
||||
void MainWindow::on_newButton_clicked(){
|
||||
NewRecipeDialog d(this->recipeDB, this);
|
||||
d.show();
|
||||
|
@ -95,11 +104,12 @@ void MainWindow::on_exitButton_clicked(){
|
|||
|
||||
void MainWindow::on_editButton_clicked(){
|
||||
NewRecipeDialog d(this->recipeDB, this->currentRecipe, this);
|
||||
string originalName = this->currentRecipe.getName();
|
||||
d.show();
|
||||
d.exec();
|
||||
if (d.isAccepted()){
|
||||
Recipe r = d.getRecipe();
|
||||
if (!this->recipeDB->storeRecipe(r)){
|
||||
if (!this->recipeDB->updateRecipe(r, originalName)){
|
||||
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);
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
void setCookTime(QTime cookTime);
|
||||
void setServings(float servings);
|
||||
void setTags(vector<RecipeTag> tags);
|
||||
void setAuthorName(string name);
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
|
|
@ -364,7 +364,7 @@ font: "Noto Sans CJK KR";</string>
|
|||
<item alignment="Qt::AlignLeft|Qt::AlignBottom">
|
||||
<widget class="QLabel" name="authorLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
|
|
|
@ -23,6 +23,7 @@ NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, QWidget *parent) : NewRecip
|
|||
|
||||
NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, Recipe recipe, QWidget *parent) : NewRecipeDialog(db, parent){
|
||||
ui->recipeNameEdit->setText(QString::fromStdString(recipe.getName()));
|
||||
ui->authorNameEdit->setText(QString::fromStdString(recipe.getAuthor()));
|
||||
ui->prepTimeEdit->setTime(recipe.getPrepTime());
|
||||
ui->cookTimeEdit->setTime(recipe.getCookTime());
|
||||
ui->servingsSpinBox->setValue((double)recipe.getServings());
|
||||
|
@ -38,9 +39,10 @@ NewRecipeDialog::~NewRecipeDialog(){
|
|||
|
||||
Recipe NewRecipeDialog::getRecipe(){
|
||||
Recipe r(ui->recipeNameEdit->text().toStdString(),
|
||||
ui->authorNameEdit->text().toStdString(),
|
||||
this->ingredientListModel.getIngredients(),
|
||||
ui->instructionsTextEdit->toHtml().toStdString(),
|
||||
this->img,//Image
|
||||
ui->imageDisplayLabel->pixmap()->toImage(),//Image
|
||||
this->tagsListModel.getTags(),//Tags
|
||||
QDate::currentDate(),
|
||||
ui->prepTimeEdit->time(),
|
||||
|
@ -126,7 +128,6 @@ void NewRecipeDialog::on_deleteTagButton_clicked(){
|
|||
void NewRecipeDialog::on_selectImageButton_clicked(){
|
||||
QString filename = QFileDialog::getOpenFileName(this, "Open Image", QString(), "Image Files (*.png *.jpg *.bmp)");
|
||||
if (!filename.isEmpty()){
|
||||
this->img = QImage(filename);
|
||||
ui->imageDisplayLabel->setPixmap(QPixmap(filename));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,7 +70,6 @@ class NewRecipeDialog : public QDialog
|
|||
vector<RecipeTag> tags;
|
||||
RecipeIngredientListModel ingredientListModel;
|
||||
TagListModel tagsListModel;
|
||||
QImage img;
|
||||
bool accepted = false;
|
||||
|
||||
//Helper functions to fill fields.
|
||||
|
|
|
@ -96,16 +96,25 @@
|
|||
<item>
|
||||
<widget class="QWidget" name="recipeNamePanel" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="recipeNameEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
<pointsize>14</pointsize>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
|
@ -114,6 +123,30 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="authorNameEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(245, 245, 255);</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Author</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -142,7 +175,7 @@
|
|||
<second>0</second>
|
||||
<year>1999</year>
|
||||
<month>12</month>
|
||||
<day>24</day>
|
||||
<day>22</day>
|
||||
</datetime>
|
||||
</property>
|
||||
<property name="currentSection">
|
||||
|
@ -253,6 +286,9 @@
|
|||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="newTagBoxPanel" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -286,6 +322,9 @@
|
|||
<property name="toolTip">
|
||||
<string>Create a new tag</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
|
||||
|
@ -297,6 +336,9 @@
|
|||
<property name="toolTip">
|
||||
<string>Permanently delete this tag</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
|
||||
|
@ -309,6 +351,9 @@
|
|||
<item>
|
||||
<widget class="QWidget" name="tagsListControlPanel" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -323,6 +368,27 @@
|
|||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addTagButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Add the above tag to the recipe</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#addTagButton {
|
||||
background-color: rgb(235, 235, 255);
|
||||
border: 0px;
|
||||
}
|
||||
QPushButton#addTagButton:hover{
|
||||
background-color: rgb(245, 245, 255);
|
||||
}
|
||||
QPushButton#addTagButton:pressed{
|
||||
background-color: rgb(255, 255, 255);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
|
@ -330,8 +396,29 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteTagButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Remove this tag from the recipe</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#deleteTagButton {
|
||||
background-color: rgb(225, 225, 255);
|
||||
border: 0px;
|
||||
}
|
||||
QPushButton#deleteTagButton:hover{
|
||||
background-color: rgb(235, 235, 255);
|
||||
}
|
||||
QPushButton#deleteTagButton:pressed{
|
||||
background-color: rgb(245, 245, 255);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -352,6 +439,9 @@
|
|||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -432,7 +522,7 @@
|
|||
<item>
|
||||
<widget class="QLabel" name="addIngredientLabel">
|
||||
<property name="text">
|
||||
<string>Add Ingredient</string>
|
||||
<string>Ingredients</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
@ -495,6 +585,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteIngredientButton">
|
||||
<property name="toolTip">
|
||||
<string>Delete this ingredient</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
@ -579,6 +672,9 @@
|
|||
</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="../images.qrc">
|
||||
<normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
|
||||
|
@ -587,6 +683,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteUnitButton">
|
||||
<property name="toolTip">
|
||||
<string>Delete this unit of measure</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
@ -624,6 +723,9 @@
|
|||
<item>
|
||||
<widget class="QWidget" name="ingredientsListControlPanel" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -638,6 +740,27 @@
|
|||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addIngredientButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Add the above ingredient to the recipe</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#addIngredientButton {
|
||||
background-color: rgb(235, 235, 255);
|
||||
border: 0px;
|
||||
}
|
||||
QPushButton#addIngredientButton:hover{
|
||||
background-color: rgb(245, 245, 255);
|
||||
}
|
||||
QPushButton#addIngredientButton:pressed{
|
||||
background-color: rgb(255, 255, 255);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
|
@ -645,8 +768,29 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="removeIngredientButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Remove this ingredient from the recipe</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#removeIngredientButton {
|
||||
background-color: rgb(225, 225, 255);
|
||||
border: 0px;
|
||||
}
|
||||
QPushButton#removeIngredientButton:hover{
|
||||
background-color: rgb(235, 235, 255);
|
||||
}
|
||||
QPushButton#removeIngredientButton:pressed{
|
||||
background-color: rgb(245, 245, 255);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -667,6 +811,9 @@
|
|||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::MultiSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="batchSize">
|
||||
<number>100</number>
|
||||
</property>
|
||||
|
@ -746,16 +893,6 @@
|
|||
<string notr="true">background-color: rgb(250, 250, 255);</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="instructionsLabel">
|
||||
<property name="text">
|
||||
<string>Instructions</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignLeft|Qt::AlignTop">
|
||||
<widget class="QWidget" name="textControlPanel" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
|
@ -769,7 +906,7 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>I</string>
|
||||
<string>Italic</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
@ -789,7 +926,7 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>B</string>
|
||||
<string>Bold</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
@ -827,7 +964,7 @@
|
|||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||
|
|
|
@ -72,7 +72,7 @@ void OpenRecipeDialog::on_deleteRecipeButton_clicked(){
|
|||
}
|
||||
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+"?");
|
||||
QString content = QString::fromStdString("Are you sure you wish to delete the selected "+recipePlural+"?\nAll deleted recipes are permanently deleted.");
|
||||
QMessageBox::StandardButton reply = QMessageBox::question(this, title, content);
|
||||
if (reply == QMessageBox::Yes){
|
||||
for (int row : rows){
|
||||
|
@ -127,3 +127,15 @@ void OpenRecipeDialog::on_foodGroupsListWidget_itemSelectionChanged(){
|
|||
}
|
||||
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());
|
||||
}
|
||||
|
||||
void OpenRecipeDialog::on_exitButton_clicked(){
|
||||
this->close();
|
||||
}
|
||||
|
|
|
@ -38,6 +38,10 @@ class OpenRecipeDialog : public QDialog
|
|||
|
||||
void on_foodGroupsListWidget_itemSelectionChanged();
|
||||
|
||||
void on_clearSearchButton_clicked();
|
||||
|
||||
void on_exitButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::OpenRecipeDialog *ui;
|
||||
RecipeDatabase *recipeDB;
|
||||
|
|
|
@ -17,13 +17,37 @@
|
|||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font: 25 "Noto Sans CJK KR Light";</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item alignment="Qt::AlignLeft|Qt::AlignTop">
|
||||
<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 alignment="Qt::AlignLeft">
|
||||
<widget class="QWidget" name="searchPanel" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(245, 245, 255);</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item alignment="Qt::AlignLeft">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="minimumSize">
|
||||
|
@ -39,13 +63,35 @@
|
|||
<enum>QTabWidget::Rounded</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tagsTab">
|
||||
<widget class="QWidget" name="Tags">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/tag.png</normaloff>:/images/images/tag.png</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string/>
|
||||
</attribute>
|
||||
<attribute name="toolTip">
|
||||
<string>Tags</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<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="tagsListView">
|
||||
<property name="sizePolicy">
|
||||
|
@ -74,10 +120,32 @@
|
|||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="ingredientsTab">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../images.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">
|
||||
|
@ -105,11 +173,33 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab">
|
||||
<widget class="QWidget" name="foodGroups">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../images.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">
|
||||
|
@ -132,6 +222,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="nameSearchPanel" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(240, 240, 255);</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
|
@ -141,33 +234,83 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="nameEdit"/>
|
||||
<widget class="QLineEdit" name="nameEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="placeholderText">
|
||||
<string>Recipe Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="searchButton">
|
||||
<widget class="QPushButton" name="clearSearchButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#clearSearchButton {
|
||||
background-color: rgb(235, 235, 255);
|
||||
border: 0px;
|
||||
}
|
||||
QPushButton#clearSearchButton:hover{
|
||||
background-color: rgb(245, 245, 255);
|
||||
}
|
||||
QPushButton#clearSearchButton:pressed{
|
||||
background-color: rgb(255, 255, 255);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>Clear search criteria</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/search_icon.png</normaloff>:/images/images/search_icon.png</iconset>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="contentPanel" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item alignment="Qt::AlignLeft">
|
||||
<widget class="QWidget" name="interactionPanel" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteRecipeButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#deleteRecipeButton {
|
||||
background-color: rgb(225, 225, 255);
|
||||
border: 0px;
|
||||
}
|
||||
QPushButton#deleteRecipeButton:hover{
|
||||
background-color: rgb(235, 235, 255);
|
||||
}
|
||||
QPushButton#deleteRecipeButton:pressed{
|
||||
background-color: rgb(245, 245, 255);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
@ -177,20 +320,86 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="exitButton">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#exitButton {
|
||||
background-color: rgb(215, 215, 255);
|
||||
border: 0px;
|
||||
}
|
||||
QPushButton#exitButton:hover{
|
||||
background-color: rgb(225, 225, 255);
|
||||
}
|
||||
QPushButton#exitButton:pressed{
|
||||
background-color: rgb(235, 235, 255);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="contentPanel" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<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="QTableView" name="recipeTableView">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: rgb(250, 250, 255);</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="gridStyle">
|
||||
<enum>Qt::NoPen</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderShowSortIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
|
|
|
@ -6,5 +6,8 @@
|
|||
<file>images/minus_icon.png</file>
|
||||
<file>images/search_icon.png</file>
|
||||
<file>images/trash.png</file>
|
||||
<file>images/tag.png</file>
|
||||
<file>images/foodPyramid.png</file>
|
||||
<file>images/ingredients.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
35
main.cpp
35
main.cpp
|
@ -8,23 +8,27 @@
|
|||
|
||||
void test(RecipeDatabase *recipeDB);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
RecipeDatabase recipeDB(QString(FileUtils::appDataPath+"recipes.db").toStdString());
|
||||
|
||||
QApplication a(argc, argv);
|
||||
MainWindow w(&recipeDB);
|
||||
w.loadFromRecipe(checkForFirstRun(&recipeDB));
|
||||
w.show();
|
||||
|
||||
//TESTING CODE
|
||||
test(&recipeDB);
|
||||
|
||||
//END TESTING CODE.
|
||||
|
||||
w.loadFromRecipe(recipeDB.retrieveRandomRecipe());
|
||||
|
||||
a.exec();
|
||||
recipeDB.closeConnection();
|
||||
printf("Total queries: %lu\n", recipeDB.getQueryCount());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,6 +39,7 @@ void test(RecipeDatabase *recipeDB){
|
|||
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(),
|
||||
|
@ -48,18 +53,4 @@ void test(RecipeDatabase *recipeDB){
|
|||
bool success = recipeDB->storeRecipe(rec);
|
||||
printf("Storage successful: %d\n", success);
|
||||
|
||||
// vector<string> foodGroups = recipeDB->retrieveAllFoodGroups();
|
||||
// printf("Food Groups:\n");
|
||||
// for (string s : foodGroups){
|
||||
// printf("\t%s\n", s.c_str());
|
||||
// }
|
||||
|
||||
//Get food groups from recipe.
|
||||
// Recipe r = recipeDB->retrieveRecipe("Pannenkoeken");
|
||||
// vector<string> foodGroupsR = r.getFoodGroups();
|
||||
// printf("Pannenkoeken Food Groups:\n");
|
||||
// for (string s : foodGroupsR){
|
||||
// printf("\t%s\n", s.c_str());
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -14,12 +14,11 @@ ResultTable Database::executeSQL(string statement){
|
|||
sqlite3_stmt* stmt;
|
||||
this->sql = statement;
|
||||
this->returnCode = sqlite3_prepare_v2(this->db, statement.c_str(), -1, &stmt, NULL);
|
||||
ResultTable t(statement);
|
||||
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));
|
||||
return t;
|
||||
return ResultTable(this->returnCode);
|
||||
}
|
||||
|
||||
ResultTable t(statement);
|
||||
t.extractData(stmt);
|
||||
|
||||
this->returnCode = sqlite3_finalize(stmt);
|
||||
|
@ -78,6 +77,18 @@ void Database::closeConnection(){
|
|||
this->dbIsOpen = false;
|
||||
}
|
||||
|
||||
void Database::beginTransaction(){
|
||||
this->executeSQL("BEGIN;");
|
||||
}
|
||||
|
||||
void Database::commitTransaction(){
|
||||
this->executeSQL("COMMIT;");
|
||||
}
|
||||
|
||||
void Database::rollbackTransaction(){
|
||||
this->executeSQL("ROLLBACK;");
|
||||
}
|
||||
|
||||
string Database::combineVector(std::vector<string> strings, string mid){
|
||||
if (strings.empty()){
|
||||
return "";
|
||||
|
|
|
@ -35,6 +35,10 @@ public:
|
|||
|
||||
void closeConnection();
|
||||
|
||||
void beginTransaction();
|
||||
void commitTransaction();
|
||||
void rollbackTransaction();
|
||||
|
||||
protected:
|
||||
string surroundString(string s, string surround);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ bool RecipeDatabase::storeRecipe(Recipe recipe){
|
|||
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;");
|
||||
this->beginTransaction();
|
||||
ResultTable t = this->selectFrom("recipe", "*", "WHERE name="+surroundString(recipe.getName(), "'"));
|
||||
if (!t.isEmpty()){
|
||||
fprintf(stderr, "Error storing recipe: Recipe with name %s already exists.\n", recipe.getName().c_str());
|
||||
|
@ -20,6 +20,7 @@ bool RecipeDatabase::storeRecipe(Recipe recipe){
|
|||
bool success = this->insertInto("recipe",
|
||||
vector<string>({
|
||||
"name",
|
||||
"authorName",
|
||||
"createdDate",
|
||||
"cookTime",
|
||||
"prepTime",
|
||||
|
@ -27,6 +28,7 @@ bool RecipeDatabase::storeRecipe(Recipe recipe){
|
|||
}),
|
||||
vector<string>({
|
||||
recipe.getName(),
|
||||
recipe.getAuthor(),
|
||||
recipe.getCreatedDate().toString().toStdString(),
|
||||
recipe.getCookTime().toString().toStdString(),
|
||||
recipe.getPrepTime().toString().toStdString(),
|
||||
|
@ -46,12 +48,12 @@ bool RecipeDatabase::storeRecipe(Recipe recipe){
|
|||
this->storeInstruction(recipe.getInstruction(), recipeId) &&
|
||||
this->storeImage(recipe.getImage(), recipeId) &&
|
||||
this->storeTags(recipe.getTags(), recipeId)){
|
||||
this->executeSQL("COMMIT;");
|
||||
this->commitTransaction();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
this->executeSQL("ROLLBACK;");
|
||||
this->rollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -158,7 +160,7 @@ Recipe RecipeDatabase::retrieveRandomRecipe(){
|
|||
}
|
||||
return this->readFromResultTable(t);
|
||||
}
|
||||
//TODO: Change this to be more efficient! One query per recipe is not good!
|
||||
|
||||
vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
|
||||
ResultTable t = this->executeSQL("SELECT * FROM recipe ORDER BY name;");
|
||||
return this->readRecipesFromTable(t);
|
||||
|
@ -204,7 +206,7 @@ vector<Recipe> RecipeDatabase::retrieveRecipesWithTags(vector<RecipeTag> tags){
|
|||
}
|
||||
|
||||
vector<Recipe> RecipeDatabase::retrieveRecipesWithSubstring(string s){
|
||||
ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE name LIKE '%"+s+"%' COLLATE NOCASE;");
|
||||
ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE name LIKE '%"+s+"%' COLLATE NOCASE ORDER BY name;");
|
||||
return this->readRecipesFromTable(t);
|
||||
}
|
||||
|
||||
|
@ -253,6 +255,18 @@ vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId)
|
|||
return ings;
|
||||
}
|
||||
|
||||
int RecipeDatabase::retrieveIngredientId(string ingredientName){
|
||||
return std::stoi(this->selectFrom("ingredient", "ingredientId", "WHERE name = '"+ingredientName+"'").at(0, 0));
|
||||
}
|
||||
|
||||
bool RecipeDatabase::deleteRecipeTags(int recipeId){
|
||||
return this->deleteFrom("recipeTag", "WHERE recipeId = "+std::to_string(recipeId));
|
||||
}
|
||||
|
||||
bool RecipeDatabase::deleteRecipeIngredients(int recipeId){
|
||||
return this->deleteFrom("recipeIngredient", "WHERE recipeId = "+std::to_string(recipeId));
|
||||
}
|
||||
|
||||
vector<Ingredient> RecipeDatabase::retrieveAllIngredients(){
|
||||
ResultTable t = this->selectFrom("ingredient", "name, foodGroup", "ORDER BY name");
|
||||
vector<Ingredient> ings;
|
||||
|
@ -314,7 +328,7 @@ bool RecipeDatabase::deleteRecipe(int recipeId){
|
|||
printf("Cannot delete. No recipe with ID %d exists.\n", recipeId);
|
||||
return false;
|
||||
}
|
||||
this->executeSQL("BEGIN;");
|
||||
this->beginTransaction();
|
||||
bool tagsDeleted = this->deleteFrom("recipeTag", "WHERE recipeId="+idString);
|
||||
bool recipeIngredientDeleted = this->deleteFrom("recipeIngredient", "WHERE recipeId="+idString);
|
||||
bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString);
|
||||
|
@ -323,10 +337,10 @@ bool RecipeDatabase::deleteRecipe(int recipeId){
|
|||
Q_UNUSED(instructionDeleted);
|
||||
Q_UNUSED(imageDeleted);
|
||||
if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){
|
||||
this->executeSQL("COMMIT;");
|
||||
this->commitTransaction();
|
||||
return true;
|
||||
} else {
|
||||
this->executeSQL("ROLLBACK;");
|
||||
this->rollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -356,15 +370,123 @@ bool RecipeDatabase::deleteTag(RecipeTag tag){
|
|||
return this->deleteFrom("recipeTag", "WHERE tagName='"+tag.getValue()+"'");
|
||||
}
|
||||
|
||||
bool RecipeDatabase::updateRecipe(Recipe recipe){
|
||||
bool RecipeDatabase::updateRecipe(Recipe recipe, string originalName) {
|
||||
string idS = this->selectFrom("recipe", "recipeId", "WHERE name="+surroundString(originalName, "'")).at(0, 0);
|
||||
int id = std::stoi(idS);
|
||||
this->beginTransaction();
|
||||
ResultTable t = this->executeSQL("UPDATE recipe "
|
||||
"SET name = '"+recipe.getName()+"', "
|
||||
"authorName = '"+recipe.getAuthor()+"', "
|
||||
"createdDate = '"+recipe.getCreatedDate().toString().toStdString()+"', "
|
||||
"prepTime = '"+recipe.getPrepTime().toString().toStdString()+"', "
|
||||
"cookTime = '"+recipe.getCookTime().toString().toStdString()+"', "
|
||||
"servingCount = "+std::to_string(recipe.getServings())+" "
|
||||
"WHERE recipeId = "+idS+";");
|
||||
bool recipeSuccess = t.getReturnCode() == SQLITE_DONE;
|
||||
if (!recipeSuccess){
|
||||
this->rollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
bool tagsSuccess = this->deleteRecipeTags(id);
|
||||
for (RecipeTag tag : recipe.getTags()){
|
||||
tagsSuccess = tagsSuccess && this->insertInto(
|
||||
"recipeTag",
|
||||
vector<string>({
|
||||
"recipeId",
|
||||
"tagName"
|
||||
}),
|
||||
vector<string>({
|
||||
idS,
|
||||
tag.getValue()
|
||||
}));
|
||||
}
|
||||
if (!tagsSuccess){
|
||||
this->rollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
bool ingredientsSuccess = this->deleteRecipeIngredients(id);
|
||||
for (RecipeIngredient ri : recipe.getIngredients()){
|
||||
ingredientsSuccess = ingredientsSuccess && this->insertInto(
|
||||
"recipeIngredient",
|
||||
vector<string>({
|
||||
"recipeId",
|
||||
"ingredientId",
|
||||
"unitName",
|
||||
"quantity",
|
||||
"comment"
|
||||
}),
|
||||
vector<string>({
|
||||
idS,
|
||||
std::to_string(this->retrieveIngredientId(ri.getName())),
|
||||
ri.getUnit().getName(),
|
||||
std::to_string(ri.getQuantity()),
|
||||
ri.getComment()
|
||||
}));
|
||||
}
|
||||
if (!ingredientsSuccess){
|
||||
this->rollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
bool instructionSuccess = FileUtils::saveInstruction(id, recipe.getInstruction());
|
||||
bool imageSuccess = FileUtils::saveImage(id, recipe.getImage());
|
||||
if (!(instructionSuccess && imageSuccess)){
|
||||
this->rollbackTransaction();
|
||||
return false;
|
||||
} else {
|
||||
this->commitTransaction();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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->executeSQL("BEGIN;");
|
||||
this->beginTransaction();
|
||||
//Ingredients table.
|
||||
this->executeSQL("CREATE TABLE IF NOT EXISTS ingredient("
|
||||
"ingredientId INTEGER PRIMARY KEY,"
|
||||
|
@ -381,6 +503,7 @@ void RecipeDatabase::ensureTablesExist(){
|
|||
this->executeSQL("CREATE TABLE IF NOT EXISTS recipe("
|
||||
"recipeId INTEGER PRIMARY KEY,"
|
||||
"name varchar UNIQUE,"
|
||||
"authorName varchar,"
|
||||
"createdDate date,"
|
||||
"prepTime time,"
|
||||
"cookTime time,"
|
||||
|
@ -400,18 +523,19 @@ void RecipeDatabase::ensureTablesExist(){
|
|||
"FOREIGN KEY (ingredientId) REFERENCES ingredient(ingredientId),"
|
||||
"FOREIGN KEY (recipeId) REFERENCES recipe(recipeId),"
|
||||
"FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name));");
|
||||
this->executeSQL("COMMIT;");
|
||||
this->commitTransaction();
|
||||
}
|
||||
|
||||
Recipe RecipeDatabase::readFromResultTable(ResultTable t, int tRow){
|
||||
Recipe r;
|
||||
TableRow row = t.rows().at(tRow);
|
||||
int id = std::stoi(row.at(0));
|
||||
r.setName(row.at(1));
|
||||
r.setCreatedDate(QDate::fromString(QString::fromStdString(row.at(2))));
|
||||
r.setPrepTime(QTime::fromString(QString::fromStdString(row.at(3))));
|
||||
r.setCookTime(QTime::fromString(QString::fromStdString(row.at(4))));
|
||||
r.setServings(std::stof(row.at(5)));
|
||||
int id = std::stoi(row.at(0)); //id
|
||||
r.setName(row.at(1)); //Name
|
||||
r.setAuthor(row.at(2)); //author
|
||||
r.setCreatedDate(QDate::fromString(QString::fromStdString(row.at(3)))); //createdDate
|
||||
r.setPrepTime(QTime::fromString(QString::fromStdString(row.at(4)))); //prepTime
|
||||
r.setCookTime(QTime::fromString(QString::fromStdString(row.at(5)))); //cookTime
|
||||
r.setServings(std::stof(row.at(6))); //servings
|
||||
r.setInstruction(FileUtils::loadInstruction(id));
|
||||
r.setImage(FileUtils::loadImage(id));
|
||||
r.setIngredients(this->retrieveRecipeIngredients(id));
|
||||
|
|
|
@ -26,9 +26,6 @@ class RecipeDatabase : public Database
|
|||
bool storeRecipeIngredient(RecipeIngredient ri, int recipeId);
|
||||
int storeIngredient(Ingredient ingredient);
|
||||
bool storeUnitOfMeasure(UnitOfMeasure u);
|
||||
bool storeInstruction(Instruction instruction, int recipeId);
|
||||
bool storeImage(QImage image, int recipeId);
|
||||
bool storeTags(vector<RecipeTag> tags, int recipeId);
|
||||
|
||||
//Retrieval.
|
||||
Recipe retrieveRecipe(string name);
|
||||
|
@ -39,10 +36,8 @@ class RecipeDatabase : public Database
|
|||
vector<Recipe> retrieveRecipesWithSubstring(string s);
|
||||
vector<Recipe> retrieveRecipesWithFoodGroups(vector<string> groups);
|
||||
vector<string> retrieveAllFoodGroups();
|
||||
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
|
||||
vector<Ingredient> retrieveAllIngredients();
|
||||
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
|
||||
vector<RecipeTag> retrieveTags(int recipeId);
|
||||
vector<RecipeTag> retrieveAllTags();
|
||||
|
||||
//Deletion.
|
||||
|
@ -53,7 +48,11 @@ class RecipeDatabase : public Database
|
|||
bool deleteTag(RecipeTag tag);
|
||||
|
||||
//Updating.
|
||||
bool updateRecipe(Recipe recipe);
|
||||
bool updateRecipe(Recipe recipe, string originalName);
|
||||
|
||||
//Adding basic information at start.
|
||||
bool addBasicUnits();
|
||||
bool addBasicIngredients();
|
||||
private:
|
||||
|
||||
//Utility methods.
|
||||
|
@ -61,6 +60,20 @@ class RecipeDatabase : public Database
|
|||
//Read a recipe from a row of a result table.
|
||||
Recipe readFromResultTable(ResultTable t, int row=0);
|
||||
vector<Recipe> readRecipesFromTable(ResultTable t);
|
||||
|
||||
//Storage
|
||||
bool storeInstruction(Instruction instruction, int recipeId);
|
||||
bool storeImage(QImage image, int recipeId);
|
||||
bool storeTags(vector<RecipeTag> tags, int recipeId);
|
||||
|
||||
//Retrieval
|
||||
vector<RecipeTag> retrieveTags(int recipeId);
|
||||
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
|
||||
int retrieveIngredientId(string ingredientName);
|
||||
|
||||
//Deletion
|
||||
bool deleteRecipeTags(int recipeId);
|
||||
bool deleteRecipeIngredients(int recipeId);
|
||||
};
|
||||
|
||||
#endif // RECIPEDATABASE_H
|
||||
|
|
|
@ -8,6 +8,10 @@ ResultTable::ResultTable(string query){
|
|||
this->originalQuery = query;
|
||||
}
|
||||
|
||||
ResultTable::ResultTable(int resultCode){
|
||||
this->queryCode = resultCode;
|
||||
}
|
||||
|
||||
void ResultTable::extractData(sqlite3_stmt *stmt){
|
||||
this->values.clear();
|
||||
int res = sqlite3_step(stmt);
|
||||
|
@ -30,6 +34,7 @@ void ResultTable::processRow(sqlite3_stmt *stmt){
|
|||
}
|
||||
|
||||
void ResultTable::printData(){
|
||||
printf("--> Result Code: [%d] <--\n", this->getReturnCode());
|
||||
if (this->isEmpty()){
|
||||
printf("Result table is empty.\n");
|
||||
return;
|
||||
|
|
|
@ -21,6 +21,8 @@ class ResultTable
|
|||
ResultTable();
|
||||
//Constructs a table with the original query saved.
|
||||
ResultTable(string query);
|
||||
//Constructs an empty table with a result code.
|
||||
ResultTable(int resultCode);
|
||||
|
||||
//Gets all the data from the result set and stores it internally as strings.
|
||||
void extractData(sqlite3_stmt* stmt);
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "model/recipe/recipe.h"
|
||||
|
||||
Recipe::Recipe(string name, 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<RecipeIngredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings){
|
||||
setName(name);
|
||||
setAuthor(author);
|
||||
setIngredients(ingredients);
|
||||
setInstruction(instruction);
|
||||
setImage(image);
|
||||
|
@ -12,7 +13,7 @@ Recipe::Recipe(string name, vector<RecipeIngredient> ingredients, Instruction in
|
|||
setServings(servings);
|
||||
}
|
||||
|
||||
Recipe::Recipe() : Recipe::Recipe("", vector<RecipeIngredient>(), Instruction(), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(1, 0), QTime(0, 30), 10.0f){
|
||||
Recipe::Recipe() : Recipe::Recipe("", "", vector<RecipeIngredient>(), Instruction(), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(), QTime(), 1.0f){
|
||||
//Set default values when none are specified.
|
||||
}
|
||||
|
||||
|
@ -20,6 +21,10 @@ string Recipe::getName() const{
|
|||
return this->name;
|
||||
}
|
||||
|
||||
string Recipe::getAuthor() const{
|
||||
return this->authorName;
|
||||
}
|
||||
|
||||
vector<RecipeIngredient> Recipe::getIngredients() const{
|
||||
return this->ingredients;
|
||||
}
|
||||
|
@ -74,6 +79,10 @@ void Recipe::setName(string newName){
|
|||
this->name = newName;
|
||||
}
|
||||
|
||||
void Recipe::setAuthor(string newName){
|
||||
this->authorName = newName;
|
||||
}
|
||||
|
||||
void Recipe::setIngredients(vector<RecipeIngredient> ingredients){
|
||||
this->ingredients = ingredients;
|
||||
}
|
||||
|
@ -111,8 +120,9 @@ void Recipe::setServings(float newServingsCount){
|
|||
}
|
||||
|
||||
void Recipe::print(){
|
||||
printf("Recipe: %s, Created on: %s, Prep time: %s, Cook time: %s, Serves: %f\n",
|
||||
printf("Recipe: %s, Created on: %s, by %s, Prep time: %s, Cook time: %s, Serves: %f\n",
|
||||
this->name.c_str(),
|
||||
this->authorName.c_str(),
|
||||
this->createdDate.toString().toStdString().c_str(),
|
||||
this->prepTime.toString().toStdString().c_str(),
|
||||
this->cookTime.toString().toStdString().c_str(),
|
||||
|
|
|
@ -32,12 +32,13 @@ class Recipe
|
|||
{
|
||||
public:
|
||||
//Full constructor
|
||||
Recipe(string name, vector<RecipeIngredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings);
|
||||
Recipe(string name, string author, vector<RecipeIngredient> 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<string> getFoodGroups() const;
|
||||
Instruction getInstruction() const;
|
||||
|
@ -52,6 +53,7 @@ public:
|
|||
|
||||
//Setters
|
||||
void setName(string newName);
|
||||
void setAuthor(string newName);
|
||||
void setIngredients(vector<RecipeIngredient> ingredients);
|
||||
void setTags(vector<RecipeTag> tags);
|
||||
void addIngredient(RecipeIngredient newIngredient);
|
||||
|
@ -66,6 +68,7 @@ public:
|
|||
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.
|
||||
Instruction instruction; //The instruction HTML document.
|
||||
QImage image; //An image displayed alongside the recipe.
|
||||
|
|
Loading…
Reference in New Issue