Actually Usable Version #7
|
@ -58,7 +58,7 @@ void MainWindow::setCookTime(QTime cookTime){
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setServings(float servings){
|
void MainWindow::setServings(float servings){
|
||||||
ui->servingsLabel->setText(QString("Servings: ")+QString::fromStdString(StringUtils::toString(servings)));
|
ui->servingsLabel->setText(QString(QString::fromStdString(StringUtils::toString(servings) + " Serving" + ((servings != 1.0f) ? "s" : ""))));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setTags(vector<RecipeTag> tags){
|
void MainWindow::setTags(vector<RecipeTag> tags){
|
||||||
|
@ -72,9 +72,10 @@ void MainWindow::on_newButton_clicked(){
|
||||||
if (d.isAccepted()){
|
if (d.isAccepted()){
|
||||||
Recipe r = d.getRecipe();
|
Recipe r = d.getRecipe();
|
||||||
if (!this->recipeDB->storeRecipe(r)){
|
if (!this->recipeDB->storeRecipe(r)){
|
||||||
QMessageBox::critical(this, QString("Unable to Save Recipe"), QString("The program was not able to successfully save the recipe."));
|
QMessageBox::critical(this, QString("Unable to Save Recipe"), QString("The program was not able to successfully save the recipe. Make sure to give the recipe a name, instructions, and some ingredients!"));
|
||||||
|
} else {
|
||||||
|
this->loadFromRecipe(r);
|
||||||
}
|
}
|
||||||
this->loadFromRecipe(r);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,4 +83,11 @@ void MainWindow::on_openButton_clicked(){
|
||||||
OpenRecipeDialog d(this->recipeDB, this);
|
OpenRecipeDialog d(this->recipeDB, this);
|
||||||
d.show();
|
d.show();
|
||||||
d.exec();
|
d.exec();
|
||||||
|
if (!d.getSelectedRecipe().isEmpty()){
|
||||||
|
this->loadFromRecipe(d.getSelectedRecipe());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_exitButton_clicked(){
|
||||||
|
this->close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ public:
|
||||||
|
|
||||||
void on_openButton_clicked();
|
void on_openButton_clicked();
|
||||||
|
|
||||||
|
void on_exitButton_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
RecipeDatabase *recipeDB;
|
RecipeDatabase *recipeDB;
|
||||||
|
|
|
@ -143,6 +143,12 @@ QPushButton#newButton:pressed{
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignTop">
|
<item alignment="Qt::AlignTop">
|
||||||
<widget class="QPushButton" name="openButton">
|
<widget class="QPushButton" name="openButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>150</width>
|
<width>150</width>
|
||||||
|
@ -175,6 +181,9 @@ QPushButton#openButton:pressed{
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignTop">
|
<item alignment="Qt::AlignTop">
|
||||||
<widget class="QPushButton" name="browseButton">
|
<widget class="QPushButton" name="browseButton">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>150</width>
|
<width>150</width>
|
||||||
|
@ -211,6 +220,56 @@ QPushButton#browseButton:pressed{
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="exitButton">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
|
<horstretch>150</horstretch>
|
||||||
|
<verstretch>80</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>150</width>
|
||||||
|
<height>80</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Noto Sans CJK KR Light</family>
|
||||||
|
<pointsize>20</pointsize>
|
||||||
|
<stylestrategy>PreferAntialias</stylestrategy>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QPushButton#exitButton {
|
||||||
|
background-color: rgb(255, 216, 216);
|
||||||
|
border: 0px;
|
||||||
|
}
|
||||||
|
QPushButton#exitButton:hover{
|
||||||
|
background-color: rgb(255, 191, 191);
|
||||||
|
}
|
||||||
|
QPushButton#exitButton:pressed{
|
||||||
|
background-color: rgb(255, 147, 147);
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Exit</string>
|
||||||
|
</property>
|
||||||
|
<property name="autoDefault">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="default">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="flat">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -367,6 +426,9 @@ font: "Noto Sans CJK KR";</string>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Prep Time:</string>
|
<string>Prep Time:</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -383,6 +445,9 @@ font: "Noto Sans CJK KR";</string>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Cook Time:</string>
|
<string>Cook Time:</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -396,6 +461,9 @@ font: "Noto Sans CJK KR";</string>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Servings:</string>
|
<string>Servings:</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -119,7 +119,7 @@ void NewRecipeDialog::on_selectImageButton_clicked(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewRecipeDialog::on_deleteIngredientButton_clicked(){
|
void NewRecipeDialog::on_removeIngredientButton_clicked(){
|
||||||
QModelIndexList indexList = ui->ingredientsListView->selectionModel()->selectedIndexes();
|
QModelIndexList indexList = ui->ingredientsListView->selectionModel()->selectedIndexes();
|
||||||
for (QModelIndexList::iterator it = indexList.begin(); it != indexList.end(); ++it){
|
for (QModelIndexList::iterator it = indexList.begin(); it != indexList.end(); ++it){
|
||||||
QModelIndex i = *it;
|
QModelIndex i = *it;
|
||||||
|
@ -127,6 +127,22 @@ void NewRecipeDialog::on_deleteIngredientButton_clicked(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NewRecipeDialog::on_deleteIngredientButton_clicked(){
|
||||||
|
int index = ui->ingredientNameBox->currentIndex();
|
||||||
|
Ingredient ing = this->ingredients.at(index);
|
||||||
|
QMessageBox::StandardButton reply = QMessageBox::question(this,
|
||||||
|
QString::fromStdString("Delete Ingredient"),
|
||||||
|
QString::fromStdString("Are you sure you want to delete the ingredient " + ing.getName() + "?"));
|
||||||
|
if (reply == QMessageBox::Yes){
|
||||||
|
bool success = this->recipeDB->deleteIngredient(ing.getName());
|
||||||
|
if (!success){
|
||||||
|
QMessageBox::critical(this, QString::fromStdString("Error"), QString::fromStdString("Unable to delete ingredient: " + ing.getName() + ", some recipes use it!"));
|
||||||
|
} else {
|
||||||
|
this->populateIngredientsBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NewRecipeDialog::on_newIngredientButton_clicked(){
|
void NewRecipeDialog::on_newIngredientButton_clicked(){
|
||||||
NewIngredientDialog d(this);
|
NewIngredientDialog d(this);
|
||||||
d.show();
|
d.show();
|
||||||
|
@ -155,8 +171,8 @@ void NewRecipeDialog::on_newTagButton_clicked(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewRecipeDialog::on_removeTagButton_clicked(){
|
void NewRecipeDialog::on_removeTagButton_clicked(){
|
||||||
int index = ui->tagsComboBox->currentIndex();
|
unsigned int index = ui->tagsComboBox->currentIndex();
|
||||||
if (index < 0 || index >= this->tags.size()){
|
if (index >= this->tags.size()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()];
|
RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()];
|
||||||
|
@ -180,3 +196,18 @@ void NewRecipeDialog::on_newUnitButton_clicked(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NewRecipeDialog::on_deleteUnitButton_clicked(){
|
||||||
|
int index = ui->unitComboBox->currentIndex();
|
||||||
|
UnitOfMeasure unit = this->units[index];
|
||||||
|
QMessageBox::StandardButton reply = QMessageBox::question(this,
|
||||||
|
QString::fromStdString("Delete Unit Of Measure"),
|
||||||
|
QString::fromStdString("Are you sure you want to delete the unit " + unit.getName() + "?"));
|
||||||
|
if (reply == QMessageBox::Yes){
|
||||||
|
if (!this->recipeDB->deleteUnitOfMeasure(unit.getName())){
|
||||||
|
QMessageBox::critical(this, "Error", "Unable to delete unit. There may be recipes which still use it!");
|
||||||
|
} else {
|
||||||
|
this->populateUnitsBox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@ class NewRecipeDialog : public QDialog
|
||||||
|
|
||||||
void on_selectImageButton_clicked();
|
void on_selectImageButton_clicked();
|
||||||
|
|
||||||
|
void on_removeIngredientButton_clicked();
|
||||||
|
|
||||||
void on_deleteIngredientButton_clicked();
|
void on_deleteIngredientButton_clicked();
|
||||||
|
|
||||||
void on_newIngredientButton_clicked();
|
void on_newIngredientButton_clicked();
|
||||||
|
@ -57,6 +59,8 @@ class NewRecipeDialog : public QDialog
|
||||||
|
|
||||||
void on_newUnitButton_clicked();
|
void on_newUnitButton_clicked();
|
||||||
|
|
||||||
|
void on_deleteUnitButton_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::NewRecipeDialog *ui;
|
Ui::NewRecipeDialog *ui;
|
||||||
RecipeDatabase *recipeDB;
|
RecipeDatabase *recipeDB;
|
||||||
|
|
|
@ -158,7 +158,7 @@
|
||||||
<second>0</second>
|
<second>0</second>
|
||||||
<year>1999</year>
|
<year>1999</year>
|
||||||
<month>12</month>
|
<month>12</month>
|
||||||
<day>26</day>
|
<day>25</day>
|
||||||
</datetime>
|
</datetime>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentSection">
|
<property name="currentSection">
|
||||||
|
@ -504,6 +504,17 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="deleteIngredientButton">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -579,6 +590,17 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="deleteUnitButton">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -627,7 +649,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="deleteIngredientButton">
|
<widget class="QPushButton" name="removeIngredientButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Delete</string>
|
<string>Delete</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -20,13 +20,45 @@ OpenRecipeDialog::~OpenRecipeDialog()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Recipe OpenRecipeDialog::getSelectedRecipe(){
|
||||||
|
return this->selectedRecipe;
|
||||||
|
}
|
||||||
|
|
||||||
void OpenRecipeDialog::populateRecipesTable(){
|
void OpenRecipeDialog::populateRecipesTable(){
|
||||||
|
this->recipeTableModel.clear();
|
||||||
vector<Recipe> recipes = this->recipeDB->retrieveAllRecipes();
|
vector<Recipe> recipes = this->recipeDB->retrieveAllRecipes();
|
||||||
// printf("Found %d recipes:\n", recipes.size());
|
|
||||||
// for (Recipe r : recipes){
|
|
||||||
// r.print();
|
|
||||||
// printf("\n------------------\n");
|
|
||||||
// }
|
|
||||||
this->recipeTableModel.setRecipes(recipes);
|
this->recipeTableModel.setRecipes(recipes);
|
||||||
|
ui->recipeTableView->resizeColumnsToContents();
|
||||||
ui->recipeTableView->show();
|
ui->recipeTableView->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenRecipeDialog::on_deleteRecipeButton_clicked(){
|
||||||
|
QItemSelectionModel *selectModel = ui->recipeTableView->selectionModel();
|
||||||
|
if (!selectModel->hasSelection()){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vector<int> rows;
|
||||||
|
QModelIndexList indexes = selectModel->selectedIndexes();
|
||||||
|
for (int i = 0; i < indexes.count(); i++){
|
||||||
|
rows.push_back(indexes.at(i).row());
|
||||||
|
}
|
||||||
|
string recipePlural = (rows.size() == 1) ? "recipe" : "recipes";
|
||||||
|
QString title = QString::fromStdString("Delete " + recipePlural);
|
||||||
|
QString content = QString::fromStdString("Are you sure you wish to delete the selected "+recipePlural+"?");
|
||||||
|
QMessageBox::StandardButton reply = QMessageBox::question(this, title, content);
|
||||||
|
if (reply == QMessageBox::Yes){
|
||||||
|
for (int row : rows){
|
||||||
|
Recipe r = this->recipeTableModel.getRecipeAt(row);
|
||||||
|
bool success = this->recipeDB->deleteRecipe(r.getName());
|
||||||
|
if (!success){
|
||||||
|
QMessageBox::critical(this, QString::fromStdString("Unable to Delete"), QString::fromStdString("Could not delete recipe "+r.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->populateRecipesTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index){
|
||||||
|
this->selectedRecipe = this->recipeTableModel.getRecipeAt(index.row());
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define OPENRECIPEDIALOG_H
|
#define OPENRECIPEDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include "model/database/recipedatabase.h"
|
#include "model/database/recipedatabase.h"
|
||||||
#include "model/recipe/recipetablemodel.h"
|
#include "model/recipe/recipetablemodel.h"
|
||||||
|
@ -19,10 +20,18 @@ class OpenRecipeDialog : public QDialog
|
||||||
OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent = 0);
|
OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent = 0);
|
||||||
~OpenRecipeDialog();
|
~OpenRecipeDialog();
|
||||||
|
|
||||||
|
Recipe getSelectedRecipe();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_deleteRecipeButton_clicked();
|
||||||
|
|
||||||
|
void on_recipeTableView_doubleClicked(const QModelIndex &index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::OpenRecipeDialog *ui;
|
Ui::OpenRecipeDialog *ui;
|
||||||
RecipeDatabase *recipeDB;
|
RecipeDatabase *recipeDB;
|
||||||
RecipeTableModel recipeTableModel;
|
RecipeTableModel recipeTableModel;
|
||||||
|
Recipe selectedRecipe;
|
||||||
|
|
||||||
void populateRecipesTable();
|
void populateRecipesTable();
|
||||||
};
|
};
|
||||||
|
|
|
@ -86,6 +86,23 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft|Qt::AlignTop">
|
||||||
|
<widget class="QWidget" name="interactionPanel" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="deleteRecipeButton">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../images.qrc">
|
||||||
|
<normaloff>:/images/images/trash.png</normaloff>:/images/images/trash.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="contentPanel" native="true">
|
<widget class="QWidget" name="contentPanel" native="true">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
@ -94,6 +111,9 @@
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
<enum>QFrame::NoFrame</enum>
|
<enum>QFrame::NoFrame</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="selectionBehavior">
|
||||||
|
<enum>QAbstractItemView::SelectRows</enum>
|
||||||
|
</property>
|
||||||
<property name="sortingEnabled">
|
<property name="sortingEnabled">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
<file>images/plus_icon.png</file>
|
<file>images/plus_icon.png</file>
|
||||||
<file>images/minus_icon.png</file>
|
<file>images/minus_icon.png</file>
|
||||||
<file>images/search_icon.png</file>
|
<file>images/search_icon.png</file>
|
||||||
|
<file>images/trash.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
57
main.cpp
57
main.cpp
|
@ -13,45 +13,28 @@ int main(int argc, char *argv[])
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
//TESTING CODE
|
//TESTING CODE
|
||||||
// vector<RecipeIngredient> ri;
|
vector<RecipeIngredient> ri;
|
||||||
// ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), ""));
|
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), ""));
|
ri.push_back(RecipeIngredient("baking powder", "additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), ""));
|
||||||
|
|
||||||
// Recipe rec("Example",
|
Recipe rec("Example",
|
||||||
// ri,
|
ri,
|
||||||
// Instruction("<b>BOLD</b><i>iTaLiCs</i>"),
|
Instruction("<b>BOLD</b><i>iTaLiCs</i>"),
|
||||||
// QImage(),
|
QImage(),
|
||||||
// vector<RecipeTag>({RecipeTag("testing"),
|
vector<RecipeTag>({RecipeTag("testing"),
|
||||||
// RecipeTag("fake")}),
|
RecipeTag("fake")}),
|
||||||
// QDate::currentDate(),
|
QDate::currentDate(),
|
||||||
// QTime(0, 30),
|
QTime(0, 30),
|
||||||
// QTime(0, 25),
|
QTime(0, 25),
|
||||||
// 10.0f);
|
10.0f);
|
||||||
|
|
||||||
// bool success = recipeDB.storeRecipe(rec);
|
bool success = recipeDB.storeRecipe(rec);
|
||||||
// printf("Storage successful: %d\n", success);
|
printf("Storage successful: %d\n", success);
|
||||||
|
|
||||||
// recipeDB.storeUnitOfMeasure(UnitOfMeasure("tablespoon", "tablespoons", "tbsp", UnitOfMeasure::VOLUME, 1.0));
|
//recipeDB.selectFrom("recipe", "recipeId, name", "").printData();
|
||||||
// recipeDB.storeUnitOfMeasure(UnitOfMeasure("pinch", "pinches", "pch", UnitOfMeasure::VOLUME, 1.0));
|
w.loadFromRecipe(recipeDB.retrieveRandomRecipe());
|
||||||
// recipeDB.storeUnitOfMeasure(UnitOfMeasure("gram", "grams", "g", UnitOfMeasure::MASS, 1.0));
|
|
||||||
|
|
||||||
// Recipe reloadRec = recipeDB.retrieveRecipe("Example");
|
a.exec();
|
||||||
// reloadRec.print();
|
recipeDB.closeConnection();
|
||||||
|
return 0;
|
||||||
// w.loadFromRecipe(reloadRec);
|
|
||||||
|
|
||||||
// NewRecipeDialog d(&recipeDB);
|
|
||||||
// d.show();
|
|
||||||
// d.exec();
|
|
||||||
|
|
||||||
// if (d.isAccepted()){
|
|
||||||
// printf("Accepted the dialog.\n");
|
|
||||||
// }
|
|
||||||
|
|
||||||
bool success = recipeDB.deleteRecipe(4);
|
|
||||||
printf("Success: %d\n", success);
|
|
||||||
recipeDB.selectFrom("recipe", "recipeId, name", "").printData();
|
|
||||||
w.loadFromRecipe(recipeDB.retrieveRecipe("Generic Bread"));
|
|
||||||
|
|
||||||
return a.exec();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,8 @@ public:
|
||||||
bool tableExists(string tableName);
|
bool tableExists(string tableName);
|
||||||
int getLastInsertedRowId();
|
int getLastInsertedRowId();
|
||||||
|
|
||||||
|
void closeConnection();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
string surroundString(string s, string surround);
|
string surroundString(string s, string surround);
|
||||||
|
|
||||||
|
@ -44,7 +46,6 @@ private:
|
||||||
char* errorMsg;
|
char* errorMsg;
|
||||||
|
|
||||||
void openConnection();
|
void openConnection();
|
||||||
void closeConnection();
|
|
||||||
std::string combineVector(std::vector<std::string> strings, std::string mid);
|
std::string combineVector(std::vector<std::string> strings, std::string mid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -147,18 +147,16 @@ Recipe RecipeDatabase::retrieveRecipe(string name){
|
||||||
fprintf(stderr, "Error: No recipe with name %s found!\n", name.c_str());
|
fprintf(stderr, "Error: No recipe with name %s found!\n", name.c_str());
|
||||||
return Recipe();
|
return Recipe();
|
||||||
}
|
}
|
||||||
Recipe r;
|
return this->readFromResultTable(t);
|
||||||
int id = std::stoi(t.valueAt(0, 0));
|
}
|
||||||
r.setName(t.valueAt(0, 1));
|
|
||||||
r.setCreatedDate(QDate::fromString(QString::fromStdString(t.valueAt(0, 2))));
|
Recipe RecipeDatabase::retrieveRandomRecipe(){
|
||||||
r.setPrepTime(QTime::fromString(QString::fromStdString(t.valueAt(0, 3))));
|
ResultTable t = this->selectFrom("recipe", "*", "ORDER BY RANDOM() LIMIT 1");
|
||||||
r.setCookTime(QTime::fromString(QString::fromStdString(t.valueAt(0, 4))));
|
if (t.isEmpty()){
|
||||||
r.setServings(std::stof(t.valueAt(0, 5)));
|
fprintf(stderr, "Unable to find a random recipe.\n");
|
||||||
r.setInstruction(FileUtils::loadInstruction(id));
|
return Recipe();
|
||||||
r.setImage(FileUtils::loadImage(id));
|
}
|
||||||
r.setIngredients(this->retrieveRecipeIngredients(id));
|
return this->readFromResultTable(t);
|
||||||
r.setTags(this->retrieveTags(id));
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
|
vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
|
||||||
|
@ -239,7 +237,7 @@ vector<RecipeTag> RecipeDatabase::retrieveAllTags(){
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecipeDatabase::deleteRecipe(string name){
|
bool RecipeDatabase::deleteRecipe(string name){
|
||||||
ResultTable t = this->selectFrom("recipe", "recipeId", "WHERE name="+name);
|
ResultTable t = this->selectFrom("recipe", "recipeId", "WHERE name='"+name+"'");
|
||||||
if (t.rowCount() != 1){
|
if (t.rowCount() != 1){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -250,6 +248,7 @@ bool RecipeDatabase::deleteRecipe(string name){
|
||||||
bool RecipeDatabase::deleteRecipe(int recipeId){
|
bool RecipeDatabase::deleteRecipe(int recipeId){
|
||||||
string idString = std::to_string(recipeId);
|
string idString = std::to_string(recipeId);
|
||||||
if (this->selectFrom("recipe", "recipeId", "WHERE recipeId="+idString).isEmpty()){
|
if (this->selectFrom("recipe", "recipeId", "WHERE recipeId="+idString).isEmpty()){
|
||||||
|
printf("Cannot delete. No recipe with ID %d exists.\n", recipeId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this->executeSQL("BEGIN;");
|
this->executeSQL("BEGIN;");
|
||||||
|
@ -266,27 +265,28 @@ bool RecipeDatabase::deleteRecipe(int recipeId){
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecipeDatabase::deleteIngredient(string name){
|
bool RecipeDatabase::deleteIngredient(string name){
|
||||||
ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE ingredientId=("
|
ResultTable t = this->executeSQL("SELECT recipeId "
|
||||||
"SELECT ingredientId"
|
"FROM recipeIngredient "
|
||||||
"FROM ingredient"
|
"INNER JOIN ingredient "
|
||||||
"WHERE name="+name+")");
|
"ON recipeIngredient.ingredientId = ingredient.ingredientId "
|
||||||
|
"WHERE ingredient.name='"+name+"';");
|
||||||
if (!t.isEmpty()){
|
if (!t.isEmpty()){
|
||||||
//There is at least one recipe dependent on the ingredient.
|
//There is at least one recipe dependent on the ingredient.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this->deleteFrom("ingredient", "WHERE name="+name);
|
return this->deleteFrom("ingredient", "WHERE name='"+name+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecipeDatabase::deleteUnitOfMeasure(string name){
|
bool RecipeDatabase::deleteUnitOfMeasure(string name){
|
||||||
ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE unitName="+name);
|
ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE unitName='"+name+"'");
|
||||||
if (!t.isEmpty()){
|
if (!t.isEmpty()){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this->deleteFrom("unitOfMeasure", "WHERE name="+name);
|
return this->deleteFrom("unitOfMeasure", "WHERE name='"+name+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecipeDatabase::deleteTag(RecipeTag tag){
|
bool RecipeDatabase::deleteTag(RecipeTag tag){
|
||||||
return this->deleteFrom("recipeTag", "WHERE tagName="+tag.getValue());
|
return this->deleteFrom("recipeTag", "WHERE tagName='"+tag.getValue()+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecipeDatabase::ensureTablesExist(){
|
void RecipeDatabase::ensureTablesExist(){
|
||||||
|
@ -331,3 +331,18 @@ void RecipeDatabase::ensureTablesExist(){
|
||||||
"FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name));");
|
"FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name));");
|
||||||
this->executeSQL("COMMIT;");
|
this->executeSQL("COMMIT;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Recipe RecipeDatabase::readFromResultTable(ResultTable t, int row){
|
||||||
|
Recipe r;
|
||||||
|
int id = std::stoi(t.valueAt(row, 0));
|
||||||
|
r.setName(t.valueAt(row, 1));
|
||||||
|
r.setCreatedDate(QDate::fromString(QString::fromStdString(t.valueAt(row, 2))));
|
||||||
|
r.setPrepTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 3))));
|
||||||
|
r.setCookTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 4))));
|
||||||
|
r.setServings(std::stof(t.valueAt(row, 5)));
|
||||||
|
r.setInstruction(FileUtils::loadInstruction(id));
|
||||||
|
r.setImage(FileUtils::loadImage(id));
|
||||||
|
r.setIngredients(this->retrieveRecipeIngredients(id));
|
||||||
|
r.setTags(this->retrieveTags(id));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ class RecipeDatabase : public Database
|
||||||
|
|
||||||
//Retrieval.
|
//Retrieval.
|
||||||
Recipe retrieveRecipe(string name);
|
Recipe retrieveRecipe(string name);
|
||||||
|
Recipe retrieveRandomRecipe();
|
||||||
vector<Recipe> retrieveAllRecipes();
|
vector<Recipe> retrieveAllRecipes();
|
||||||
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
|
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
|
||||||
vector<Ingredient> retrieveAllIngredients();
|
vector<Ingredient> retrieveAllIngredients();
|
||||||
|
@ -49,6 +50,8 @@ class RecipeDatabase : public Database
|
||||||
|
|
||||||
//Utility methods.
|
//Utility methods.
|
||||||
void ensureTablesExist();
|
void ensureTablesExist();
|
||||||
|
//Read a recipe from a row of a result table.
|
||||||
|
Recipe readFromResultTable(ResultTable t, int row=0);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RECIPEDATABASE_H
|
#endif // RECIPEDATABASE_H
|
||||||
|
|
|
@ -50,7 +50,7 @@ string RecipeIngredient::toString(){
|
||||||
result += StringUtils::toString(this->getQuantity());
|
result += StringUtils::toString(this->getQuantity());
|
||||||
}
|
}
|
||||||
result += " " + this->getUnit().getAbbreviation() + " " + this->getName();
|
result += " " + this->getUnit().getAbbreviation() + " " + this->getName();
|
||||||
if (!this->getComment().empty()) result += " ~" + this->getComment();
|
if (!this->getComment().empty()) result += " (" + this->getComment() + ")";
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ Recipe::Recipe(string name, vector<RecipeIngredient> ingredients, Instruction in
|
||||||
setServings(servings);
|
setServings(servings);
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipe::Recipe() : Recipe::Recipe("Unnamed 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(1, 0), QTime(0, 30), 10.0f){
|
||||||
//Set default values when none are specified.
|
//Set default values when none are specified.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,11 @@ QTime Recipe::getTotalTime() const{
|
||||||
}
|
}
|
||||||
|
|
||||||
float Recipe::getServings() const{
|
float Recipe::getServings() const{
|
||||||
return this->servings;
|
return this->servings;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Recipe::isEmpty() const{
|
||||||
|
return this->name.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Recipe::setName(string newName){
|
void Recipe::setName(string newName){
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
QTime getCookTime() const;
|
QTime getCookTime() const;
|
||||||
QTime getTotalTime() const; //Derived method to add prep and cook times.
|
QTime getTotalTime() const; //Derived method to add prep and cook times.
|
||||||
float getServings() const;
|
float getServings() const;
|
||||||
|
bool isEmpty() const;
|
||||||
|
|
||||||
//Setters
|
//Setters
|
||||||
void setName(string newName);
|
void setName(string newName);
|
||||||
|
|
|
@ -16,7 +16,7 @@ int RecipeTableModel::rowCount(const QModelIndex &parent) const{
|
||||||
|
|
||||||
int RecipeTableModel::columnCount(const QModelIndex &parent) const{
|
int RecipeTableModel::columnCount(const QModelIndex &parent) const{
|
||||||
Q_UNUSED(parent);
|
Q_UNUSED(parent);
|
||||||
return 2;//FIX THIS TO BE MORE ADAPTIVE EVENTUALLY.
|
return 5;//FIX THIS TO BE MORE ADAPTIVE EVENTUALLY.
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant RecipeTableModel::data(const QModelIndex &index, int role) const{
|
QVariant RecipeTableModel::data(const QModelIndex &index, int role) const{
|
||||||
|
@ -30,6 +30,12 @@ QVariant RecipeTableModel::data(const QModelIndex &index, int role) const{
|
||||||
return QString::fromStdString(r.getName());
|
return QString::fromStdString(r.getName());
|
||||||
case 1:
|
case 1:
|
||||||
return QString::fromStdString(r.getCreatedDate().toString().toStdString());
|
return QString::fromStdString(r.getCreatedDate().toString().toStdString());
|
||||||
|
case 2:
|
||||||
|
return QString::fromStdString(StringUtils::toString(r.getServings()));
|
||||||
|
case 3:
|
||||||
|
return r.getPrepTime().toString("hh:mm:ss");
|
||||||
|
case 4:
|
||||||
|
return r.getCookTime().toString("hh:mm:ss");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -45,6 +51,12 @@ QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation,
|
||||||
return "Name";
|
return "Name";
|
||||||
case 1:
|
case 1:
|
||||||
return "Created On";
|
return "Created On";
|
||||||
|
case 2:
|
||||||
|
return "Servings";
|
||||||
|
case 3:
|
||||||
|
return "Prep Time";
|
||||||
|
case 4:
|
||||||
|
return "Cook Time";
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
@ -59,3 +71,16 @@ void RecipeTableModel::setRecipes(vector<Recipe> recipes){
|
||||||
this->recipes = recipes;
|
this->recipes = recipes;
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Recipe RecipeTableModel::getRecipeAt(int index){
|
||||||
|
if (index < 0 || index >= this->recipes.size()){
|
||||||
|
return Recipe();
|
||||||
|
}
|
||||||
|
return this->recipes[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecipeTableModel::clear(){
|
||||||
|
beginResetModel();
|
||||||
|
this->recipes.clear();
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <QAbstractTableModel>
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
#include "model/recipe/recipe.h"
|
#include "model/recipe/recipe.h"
|
||||||
|
#include "utils/stringutils.h"
|
||||||
|
|
||||||
class RecipeTableModel : public QAbstractTableModel
|
class RecipeTableModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
|
@ -19,7 +20,8 @@ class RecipeTableModel : public QAbstractTableModel
|
||||||
|
|
||||||
//Normal methods.
|
//Normal methods.
|
||||||
void setRecipes(vector<Recipe> recipes);
|
void setRecipes(vector<Recipe> recipes);
|
||||||
|
Recipe getRecipeAt(int index);
|
||||||
|
void clear();
|
||||||
private:
|
private:
|
||||||
vector<Recipe> recipes;
|
vector<Recipe> recipes;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,6 +2,14 @@
|
||||||
|
|
||||||
namespace StringUtils{
|
namespace StringUtils{
|
||||||
|
|
||||||
|
bool stringEndsWith(std::string const &fullString, std::string const &ending){
|
||||||
|
if (fullString.length() >= ending.length()) {
|
||||||
|
return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string toString(float val){
|
std::string toString(float val){
|
||||||
float decimal = std::fmod(val, 1.0f);
|
float decimal = std::fmod(val, 1.0f);
|
||||||
int places = 1;
|
int places = 1;
|
||||||
|
@ -13,6 +21,11 @@ std::string toString(float val){
|
||||||
std::string arg = "%."+std::to_string(places)+"f";
|
std::string arg = "%."+std::to_string(places)+"f";
|
||||||
sprintf(buffer, arg.c_str(), val);
|
sprintf(buffer, arg.c_str(), val);
|
||||||
std::string s = buffer;
|
std::string s = buffer;
|
||||||
|
if (stringEndsWith(s, ".0")){
|
||||||
|
while (s.find('.') != std::string::npos){
|
||||||
|
s.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue