Merge pull request #5 from andrewlalis/development

First ability to create recipe in gui
This commit is contained in:
Andrew Lalis 2018-03-10 16:03:09 +01:00 committed by GitHub
commit e2ccde9030
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1028 additions and 260 deletions

View File

@ -27,7 +27,9 @@ SOURCES += model/recipe/instruction.cpp \
model/database/recipedatabase.cpp \ model/database/recipedatabase.cpp \
utils/fileutils.cpp \ utils/fileutils.cpp \
gui/newrecipedialog.cpp \ gui/newrecipedialog.cpp \
model/recipe/tags/taglistmodel.cpp model/recipe/tags/taglistmodel.cpp \
gui/newDialogs/newingredientdialog.cpp \
gui/newDialogs/newtagdialog.cpp
HEADERS += model/recipe/instruction.h \ HEADERS += model/recipe/instruction.h \
model/recipe/recipe.h \ model/recipe/recipe.h \
@ -44,14 +46,19 @@ HEADERS += model/recipe/instruction.h \
model/database/recipedatabase.h \ model/database/recipedatabase.h \
utils/fileutils.h \ utils/fileutils.h \
gui/newrecipedialog.h \ gui/newrecipedialog.h \
model/recipe/tags/taglistmodel.h model/recipe/tags/taglistmodel.h \
gui/newDialogs/newingredientdialog.h \
gui/newDialogs/newtagdialog.h
LIBS += -ldl \ LIBS += -ldl \
FORMS += gui/mainwindow.ui \ FORMS += gui/mainwindow.ui \
gui/newrecipedialog.ui gui/newrecipedialog.ui \
gui/newDialogs/newingredientdialog.ui \
gui/newDialogs/newtagdialog.ui
DISTFILES += \ DISTFILES += \
.gitignore .gitignore
RESOURCES += RESOURCES += \
images.qrc

View File

@ -25,6 +25,10 @@
<property name="windowTitle"> <property name="windowTitle">
<string>RecipeDB</string> <string>RecipeDB</string>
</property> </property>
<property name="windowIcon">
<iconset resource="../images.qrc">
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
</property>
<property name="windowOpacity"> <property name="windowOpacity">
<double>1.000000000000000</double> <double>1.000000000000000</double>
</property> </property>
@ -237,10 +241,152 @@ QPushButton#browseButton:pressed{
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item alignment="Qt::AlignTop"> <item>
<widget class="QWidget" name="basicInfoPanel" native="true">
<property name="font">
<font>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(219, 216, 216);
font: &quot;Noto Sans CJK KR&quot;;</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_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 alignment="Qt::AlignLeft">
<widget class="QWidget" name="basicInfoSubPanel" native="true">
<property name="font">
<font>
<family>Noto Sans CJK KR Light</family>
</font>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QWidget" name="prepTimePanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<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="QLabel" name="prepTimeLabel">
<property name="font">
<font>
<family>Noto Sans CJK KR Light</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Prep Time:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="cookTimePanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_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="QLabel" name="cookTimeLabel">
<property name="font">
<font>
<family>Noto Sans CJK KR Light</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Cook Time:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="servingsPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_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="QLabel" name="servingsLabel">
<property name="font">
<font>
<family>Noto Sans CJK KR Light</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Servings:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="recipeNameLabel"> <widget class="QLabel" name="recipeNameLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -254,17 +400,13 @@ QPushButton#browseButton:pressed{
<property name="font"> <property name="font">
<font> <font>
<family>Noto Sans CJK KR Light</family> <family>Noto Sans CJK KR Light</family>
<pointsize>24</pointsize> <pointsize>30</pointsize>
<weight>50</weight> <weight>50</weight>
<italic>false</italic> <italic>false</italic>
<bold>false</bold> <bold>false</bold>
<stylestrategy>PreferAntialias</stylestrategy> <stylestrategy>PreferAntialias</stylestrategy>
<kerning>true</kerning>
</font> </font>
</property> </property>
<property name="styleSheet">
<string notr="true">background-color: rgb(219, 216, 216);</string>
</property>
<property name="text"> <property name="text">
<string>Recipe Name</string> <string>Recipe Name</string>
</property> </property>
@ -273,6 +415,9 @@ QPushButton#browseButton:pressed{
</property> </property>
</widget> </widget>
</item> </item>
</layout>
</widget>
</item>
<item> <item>
<widget class="QWidget" name="displayPanelContent" native="true"> <widget class="QWidget" name="displayPanelContent" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
@ -413,6 +558,12 @@ QPushButton#browseButton:pressed{
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="minimumSize">
<size>
<width>400</width>
<height>0</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3"> <layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
@ -510,7 +661,7 @@ p, li { white-space: pre-wrap; }
</layout> </layout>
</widget> </widget>
</item> </item>
<item alignment="Qt::AlignRight"> <item>
<widget class="QWidget" name="imagePanelWidget" native="true"> <widget class="QWidget" name="imagePanelWidget" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding"> <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
@ -543,6 +694,19 @@ p, li { white-space: pre-wrap; }
<property name="bottomMargin"> <property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<widget class="QLabel" name="imageLabel">
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/images/no_image.png</pixmap>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -556,6 +720,8 @@ p, li { white-space: pre-wrap; }
</widget> </widget>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources/> <resources>
<include location="../images.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

View File

@ -0,0 +1,18 @@
#include "newingredientdialog.h"
#include "ui_newingredientdialog.h"
NewIngredientDialog::NewIngredientDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::NewIngredientDialog)
{
ui->setupUi(this);
}
NewIngredientDialog::~NewIngredientDialog()
{
delete ui;
}
Ingredient NewIngredientDialog::getIngredient(){
return Ingredient(ui->nameEdit->text().toLower().toStdString(), ui->foodGroupEdit->text().toLower().toStdString());
}

View File

@ -0,0 +1,26 @@
#ifndef NEWINGREDIENTDIALOG_H
#define NEWINGREDIENTDIALOG_H
#include <QDialog>
#include "model/recipe/ingredients/ingredient.h"
namespace Ui {
class NewIngredientDialog;
}
class NewIngredientDialog : public QDialog
{
Q_OBJECT
public:
explicit NewIngredientDialog(QWidget *parent = 0);
~NewIngredientDialog();
//Access values.
Ingredient getIngredient();
private:
Ui::NewIngredientDialog *ui;
};
#endif // NEWINGREDIENTDIALOG_H

View File

@ -0,0 +1,120 @@
<?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>240</width>
<height>320</height>
</rect>
</property>
<property name="windowTitle">
<string>New Ingredient</string>
</property>
<property name="windowIcon">
<iconset resource="../../images.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="QLineEdit" name="foodGroupEdit"/>
</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="../../images.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

@ -0,0 +1,18 @@
#include "newtagdialog.h"
#include "ui_newtagdialog.h"
NewTagDialog::NewTagDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::newTagDialog)
{
ui->setupUi(this);
}
NewTagDialog::~NewTagDialog()
{
delete ui;
}
RecipeTag NewTagDialog::getTag(){
return RecipeTag(ui->tagEdit->text().toLower().toStdString());
}

View File

@ -0,0 +1,26 @@
#ifndef NEWTAGDIALOG_H
#define NEWTAGDIALOG_H
#include <QDialog>
#include "model/recipe/tags/recipetag.h"
namespace Ui {
class newTagDialog;
}
class NewTagDialog : public QDialog
{
Q_OBJECT
public:
explicit NewTagDialog(QWidget *parent = 0);
~NewTagDialog();
//Access values
RecipeTag getTag();
private:
Ui::newTagDialog *ui;
};
#endif // NEWTAGDIALOG_H

View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>newTagDialog</class>
<widget class="QDialog" name="newTagDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>240</width>
<height>320</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="windowIcon">
<iconset resource="../../images.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">
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="tagEditWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="tagLabel">
<property name="text">
<string>New Tag</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="tagEdit"/>
</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="../../images.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>newTagDialog</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>newTagDialog</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

@ -29,12 +29,13 @@ Recipe NewRecipeDialog::getRecipe(){
Recipe r(ui->recipeNameEdit->text().toStdString(), Recipe r(ui->recipeNameEdit->text().toStdString(),
this->ingredientListModel.getIngredients(), this->ingredientListModel.getIngredients(),
ui->instructionsTextEdit->toHtml().toStdString(), ui->instructionsTextEdit->toHtml().toStdString(),
QImage(),//Image this->img,//Image
this->tagsListModel.getTags(),//Tags this->tagsListModel.getTags(),//Tags
QDate::currentDate(), QDate::currentDate(),
ui->prepTimeEdit->time(), ui->prepTimeEdit->time(),
ui->cookTimeEdit->time(), ui->cookTimeEdit->time(),
(float)ui->servingsSpinBox->value()); (float)ui->servingsSpinBox->value());
return r;
} }
bool NewRecipeDialog::isAccepted() const{ bool NewRecipeDialog::isAccepted() const{
@ -101,3 +102,67 @@ void NewRecipeDialog::on_addTagButton_clicked(){
//Add a tag to the list of those prepared to be added. //Add a tag to the list of those prepared to be added.
this->tagsListModel.addTag(this->tags[ui->tagsComboBox->currentIndex()]); this->tagsListModel.addTag(this->tags[ui->tagsComboBox->currentIndex()]);
} }
void NewRecipeDialog::on_deleteTagButton_clicked(){
QModelIndexList indexList = ui->tagsListView->selectionModel()->selectedIndexes();
for (QModelIndexList::iterator it = indexList.begin(); it != indexList.end(); ++it){
QModelIndex i = *it;
this->tagsListModel.deleteTag(i.row());
}
}
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));
}
}
void NewRecipeDialog::on_deleteIngredientButton_clicked(){
QModelIndexList indexList = ui->ingredientsListView->selectionModel()->selectedIndexes();
for (QModelIndexList::iterator it = indexList.begin(); it != indexList.end(); ++it){
QModelIndex i = *it;
this->ingredientListModel.deleteIngredient(i.row());
}
}
void NewRecipeDialog::on_newIngredientButton_clicked(){
NewIngredientDialog d(this);
d.show();
if (d.exec() == QDialog::Accepted){
Ingredient i = d.getIngredient();
this->recipeDB->storeIngredient(i);
this->populateIngredientsBox();
}
}
void NewRecipeDialog::on_newTagButton_clicked(){
NewTagDialog d(this);
d.show();
if (d.exec() == QDialog::Accepted){
RecipeTag tag = d.getTag();
//Temporarily add this to the tags list, and it will be saved if the recipe is saved.
this->tags.push_back(tag);
ui->tagsComboBox->clear();
for (unsigned int i = 0; i < this->tags.size(); i++){
QString s = QString::fromStdString(this->tags[i].getValue());
ui->tagsComboBox->insertItem(i, s);
}
}
}
void NewRecipeDialog::on_removeTagButton_clicked(){
int index = ui->tagsComboBox->currentIndex();
if (index < 0 || index >= this->tags.size()){
return;
}
RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()];
string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue();
QMessageBox::StandardButton reply = QMessageBox::question(this, QString("Delete Tag"), QString(content.c_str()));
if (reply == QMessageBox::Yes){
this->recipeDB->deleteTag(tag);
this->populateTagsBox();
}
}

View File

@ -3,11 +3,17 @@
#include <QDialog> #include <QDialog>
#include <QTextCharFormat> #include <QTextCharFormat>
#include <QFileDialog>
#include <QPixmap>
#include <QMessageBox>
#include "model/database/recipedatabase.h" #include "model/database/recipedatabase.h"
#include "model/recipe/ingredients/ingredientlistmodel.h" #include "model/recipe/ingredients/ingredientlistmodel.h"
#include "model/recipe/tags/taglistmodel.h" #include "model/recipe/tags/taglistmodel.h"
#include "gui/newDialogs/newingredientdialog.h"
#include "gui/newDialogs/newtagdialog.h"
namespace Ui { namespace Ui {
class NewRecipeDialog; class NewRecipeDialog;
} }
@ -36,6 +42,18 @@ class NewRecipeDialog : public QDialog
void on_addTagButton_clicked(); void on_addTagButton_clicked();
void on_deleteTagButton_clicked();
void on_selectImageButton_clicked();
void on_deleteIngredientButton_clicked();
void on_newIngredientButton_clicked();
void on_newTagButton_clicked();
void on_removeTagButton_clicked();
private: private:
Ui::NewRecipeDialog *ui; Ui::NewRecipeDialog *ui;
RecipeDatabase *recipeDB; RecipeDatabase *recipeDB;
@ -44,6 +62,7 @@ class NewRecipeDialog : public QDialog
vector<RecipeTag> tags; vector<RecipeTag> tags;
IngredientListModel ingredientListModel; IngredientListModel ingredientListModel;
TagListModel tagsListModel; TagListModel tagsListModel;
QImage img;
bool accepted = false; bool accepted = false;
//Helper functions to fill fields. //Helper functions to fill fields.

View File

@ -22,6 +22,13 @@
<property name="windowTitle"> <property name="windowTitle">
<string>New Recipe</string> <string>New Recipe</string>
</property> </property>
<property name="windowIcon">
<iconset resource="../images.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"> <layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>0</number>
@ -272,12 +279,34 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<widget class="QComboBox" name="tagsComboBox"/> <widget class="QComboBox" name="tagsComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item> </item>
<item> <item alignment="Qt::AlignRight">
<widget class="QPushButton" name="newTagButton"> <widget class="QPushButton" name="newTagButton">
<property name="text"> <property name="toolTip">
<string>New</string> <string>Create a new tag</string>
</property>
<property name="icon">
<iconset resource="../images.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="removeTagButton">
<property name="toolTip">
<string>Permanently delete this tag</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
@ -327,6 +356,9 @@
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::NoFrame</enum> <enum>QFrame::NoFrame</enum>
</property> </property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -336,6 +368,24 @@
</widget> </widget>
</item> </item>
<item alignment="Qt::AlignTop"> <item alignment="Qt::AlignTop">
<widget class="QWidget" name="ingredientsAndImagePanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_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="QWidget" name="ingredientsPanel" native="true"> <widget class="QWidget" name="ingredientsPanel" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -377,21 +427,8 @@
</item> </item>
<item> <item>
<widget class="QWidget" name="ingredientsSubPanel" native="true"> <widget class="QWidget" name="ingredientsSubPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_12">
<item> <item>
<widget class="QListView" name="ingredientsListView">
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="batchSize">
<number>100</number>
</property>
</widget>
</item>
<item alignment="Qt::AlignRight|Qt::AlignTop">
<widget class="QWidget" name="addIngredientPanel" native="true"> <widget class="QWidget" name="addIngredientPanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_7"> <layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing"> <property name="spacing">
@ -445,6 +482,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="editable">
<bool>false</bool>
</property>
<property name="currentText"> <property name="currentText">
<string/> <string/>
</property> </property>
@ -452,8 +492,12 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="newIngredientButton"> <widget class="QPushButton" name="newIngredientButton">
<property name="text"> <property name="toolTip">
<string>New</string> <string>Create a new ingredient</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
@ -517,12 +561,20 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="unitComboBox"/> <widget class="QComboBox" name="unitComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item> </item>
<item> <item alignment="Qt::AlignRight">
<widget class="QPushButton" name="newUnitButton"> <widget class="QPushButton" name="newUnitButton">
<property name="text"> <property name="icon">
<string>New</string> <iconset resource="../images.qrc">
<normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
</property> </property>
</widget> </widget>
</item> </item>
@ -586,6 +638,75 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="QListView" name="ingredientsListView">
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::MultiSelection</enum>
</property>
<property name="batchSize">
<number>100</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="imagePanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_13">
<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="QLabel" name="imageDisplayLabel">
<property name="maximumSize">
<size>
<width>500</width>
<height>500</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../images.qrc">:/images/images/no_image.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="selectImageButton">
<property name="text">
<string>Select Image...</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -594,6 +715,9 @@
</item> </item>
<item> <item>
<widget class="QWidget" name="instructionsPanel" native="true"> <widget class="QWidget" name="instructionsPanel" native="true">
<property name="styleSheet">
<string notr="true">background-color: rgb(250, 250, 255);</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QVBoxLayout" name="verticalLayout_8">
<item> <item>
<widget class="QLabel" name="instructionsLabel"> <widget class="QLabel" name="instructionsLabel">
@ -657,6 +781,12 @@
</item> </item>
<item> <item>
<widget class="QTextEdit" name="instructionsTextEdit"> <widget class="QTextEdit" name="instructionsTextEdit">
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="placeholderText"> <property name="placeholderText">
<string>Enter instructions here.</string> <string>Enter instructions here.</string>
</property> </property>
@ -670,9 +800,15 @@
<property name="layoutDirection"> <property name="layoutDirection">
<enum>Qt::LeftToRight</enum> <enum>Qt::LeftToRight</enum>
</property> </property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="standardButtons"> <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property> </property>
<property name="centerButtons">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -680,6 +816,8 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<resources/> <resources>
<include location="../images.qrc"/>
</resources>
<connections/> <connections/>
</ui> </ui>

8
images.qrc Normal file
View File

@ -0,0 +1,8 @@
<RCC>
<qresource prefix="/images">
<file>images/no_image.png</file>
<file>images/icon.png</file>
<file>images/plus_icon.png</file>
<file>images/minus_icon.png</file>
</qresource>
</RCC>

BIN
images/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

BIN
images/minus_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 B

BIN
images/no_image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
images/plus_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

View File

@ -7,49 +7,48 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
RecipeDatabase recipeDB("recipes");
QApplication a(argc, argv); QApplication a(argc, argv);
MainWindow w; MainWindow w(&recipeDB);
w.show(); w.show();
//TESTING CODE //TESTING CODE
// 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), ""));
RecipeDatabase recipeDB("recipes"); // Recipe rec("Example",
// ri,
// Instruction("<b>BOLD</b><i>iTaLiCs</i>"),
// QImage(),
// vector<RecipeTag>({RecipeTag("testing"),
// RecipeTag("fake")}),
// QDate::currentDate(),
// QTime(0, 30),
// QTime(0, 25),
// 10.0f);
//TESTING CODE // bool success = recipeDB.storeRecipe(rec);
vector<RecipeIngredient> ri; // printf("Storage successful: %d\n", success);
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", // recipeDB.storeUnitOfMeasure(UnitOfMeasure("tablespoon", "tablespoons", "tbsp", UnitOfMeasure::VOLUME, 1.0));
ri, // recipeDB.storeUnitOfMeasure(UnitOfMeasure("pinch", "pinches", "pch", UnitOfMeasure::VOLUME, 1.0));
Instruction("<b>BOLD</b><i>iTaLiCs</i>"), // recipeDB.storeUnitOfMeasure(UnitOfMeasure("gram", "grams", "g", UnitOfMeasure::MASS, 1.0));
QImage(),
vector<RecipeTag>({RecipeTag("testing"),
RecipeTag("fake")}),
QDate::currentDate(),
QTime(0, 30),
QTime(0, 25),
10.0f);
bool success = recipeDB.storeRecipe(rec); // Recipe reloadRec = recipeDB.retrieveRecipe("Example");
printf("Storage successful: %d\n", success); // reloadRec.print();
recipeDB.storeUnitOfMeasure(UnitOfMeasure("tablespoon", "tablespoons", "tbsp", UnitOfMeasure::VOLUME, 1.0)); // w.loadFromRecipe(reloadRec);
recipeDB.storeUnitOfMeasure(UnitOfMeasure("pinch", "pinches", "pch", UnitOfMeasure::VOLUME, 1.0));
recipeDB.storeUnitOfMeasure(UnitOfMeasure("gram", "grams", "g", UnitOfMeasure::MASS, 1.0));
Recipe reloadRec = recipeDB.retrieveRecipe("Example"); // NewRecipeDialog d(&recipeDB);
reloadRec.print(); // d.show();
// d.exec();
w.loadFromRecipe(reloadRec); // if (d.isAccepted()){
// printf("Accepted the dialog.\n");
// }
NewRecipeDialog d(&recipeDB); w.loadFromRecipe(recipeDB.retrieveRecipe("Generic Bread"));
d.show();
d.exec();
if (d.isAccepted()){
printf("Accepted the dialog.\n");
}
return a.exec(); return a.exec();
} }

View File

@ -223,6 +223,10 @@ vector<RecipeTag> RecipeDatabase::retrieveAllTags(){
return tags; return tags;
} }
void RecipeDatabase::deleteTag(RecipeTag tag){
ResultTable t = this->executeSQL("DELETE FROM recipeTag WHERE tagName="+surroundString(tag.getValue(), "'"));
}
void RecipeDatabase::ensureTablesExist(){ void RecipeDatabase::ensureTablesExist(){
//Make sure that foreign keys are enabled. //Make sure that foreign keys are enabled.
this->executeSQL("PRAGMA foreign_keys = ON;"); this->executeSQL("PRAGMA foreign_keys = ON;");

View File

@ -37,6 +37,9 @@ class RecipeDatabase : public Database
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure(); vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
vector<RecipeTag> retrieveTags(int recipeId); vector<RecipeTag> retrieveTags(int recipeId);
vector<RecipeTag> retrieveAllTags(); vector<RecipeTag> retrieveAllTags();
//Deletion.
void deleteTag(RecipeTag tag);
private: private:
//Utility methods. //Utility methods.

View File

@ -53,6 +53,11 @@ bool IngredientListModel::addIngredient(RecipeIngredient ri){
return true; return true;
} }
void IngredientListModel::deleteIngredient(int index){
this->ingredients.erase(this->ingredients.begin() + index);
emit dataChanged(createIndex(0, 0), createIndex(this->ingredients.size()-1, 0));
}
vector<RecipeIngredient> IngredientListModel::getIngredients(){ vector<RecipeIngredient> IngredientListModel::getIngredients(){
return this->ingredients; return this->ingredients;
} }

View File

@ -18,6 +18,7 @@ public:
//Custom methods to handle ingredient data. //Custom methods to handle ingredient data.
void setIngredients(vector<RecipeIngredient> ingredients); void setIngredients(vector<RecipeIngredient> ingredients);
bool addIngredient(RecipeIngredient ri); bool addIngredient(RecipeIngredient ri);
void deleteIngredient(int index);
vector<RecipeIngredient> getIngredients(); vector<RecipeIngredient> getIngredients();
private: private:

View File

@ -39,6 +39,11 @@ bool TagListModel::addTag(RecipeTag tag){
return true; return true;
} }
void TagListModel::deleteTag(int index){
this->tags.erase(this->tags.begin() + index);
emit dataChanged(createIndex(0, 0), createIndex(this->tags.size()-1, 0));
}
vector<RecipeTag> TagListModel::getTags(){ vector<RecipeTag> TagListModel::getTags(){
return this->tags; return this->tags;
} }

View File

@ -16,6 +16,7 @@ class TagListModel : public QAbstractListModel
void setTags(vector<RecipeTag> tags); void setTags(vector<RecipeTag> tags);
bool addTag(RecipeTag tag); bool addTag(RecipeTag tag);
void deleteTag(int index);
vector<RecipeTag> getTags(); vector<RecipeTag> getTags();
private: private:
vector<RecipeTag> tags; vector<RecipeTag> tags;

View File

@ -9,6 +9,10 @@ MainWindow::MainWindow(QWidget *parent) :
ui->ingredientsListView->setModel(&this->ingredientModel); ui->ingredientsListView->setModel(&this->ingredientModel);
} }
MainWindow::MainWindow(RecipeDatabase *db, QWidget *parent) : MainWindow(parent){
this->recipeDB = db;
}
MainWindow::~MainWindow(){ MainWindow::~MainWindow(){
delete ui; delete ui;
} }
@ -17,6 +21,10 @@ void MainWindow::loadFromRecipe(Recipe recipe){
setRecipeName(recipe.getName()); setRecipeName(recipe.getName());
setInstruction(recipe.getInstruction()); setInstruction(recipe.getInstruction());
setIngredients(recipe.getIngredients()); setIngredients(recipe.getIngredients());
setImage(recipe.getImage());
setPrepTime(recipe.getPrepTime());
setCookTime(recipe.getCookTime());
setServings(recipe.getServings());
} }
void MainWindow::setRecipeName(string name){ void MainWindow::setRecipeName(string name){
@ -30,3 +38,32 @@ void MainWindow::setInstruction(Instruction instruction){
void MainWindow::setIngredients(vector<RecipeIngredient> ingredients){ void MainWindow::setIngredients(vector<RecipeIngredient> ingredients){
this->ingredientModel.setIngredients(ingredients); this->ingredientModel.setIngredients(ingredients);
} }
void MainWindow::setImage(QImage img){
ui->imageLabel->setPixmap(QPixmap::fromImage(img));
}
void MainWindow::setPrepTime(QTime prepTime){
ui->prepTimeLabel->setText(QString("Prep Time: ")+prepTime.toString("hh:mm:ss"));
}
void MainWindow::setCookTime(QTime cookTime){
ui->cookTimeLabel->setText(QString("Cook Time: ")+cookTime.toString("hh:mm:ss"));
}
void MainWindow::setServings(float servings){
ui->servingsLabel->setText(QString("Servings: ")+QString::fromStdString(toString(servings)));
}
void MainWindow::on_newButton_clicked(){
NewRecipeDialog d(this->recipeDB, this);
d.show();
d.exec();
if (d.isAccepted()){
Recipe r = d.getRecipe();
if (!this->recipeDB->storeRecipe(r)){
QMessageBox::critical(this, QString("Unable to Save Recipe"), QString("The program was not able to successfully save the recipe."));
}
this->loadFromRecipe(r);
}
}

View File

@ -7,6 +7,7 @@
#include "model/recipe/recipe.h" #include "model/recipe/recipe.h"
#include "model/recipe/ingredients/ingredientlistmodel.h" #include "model/recipe/ingredients/ingredientlistmodel.h"
#include "gui/newrecipedialog.h"
using namespace std; using namespace std;
@ -20,18 +21,27 @@ class MainWindow : public QMainWindow
public: public:
explicit MainWindow(QWidget *parent = 0); explicit MainWindow(QWidget *parent = 0);
MainWindow(RecipeDatabase *db, QWidget *parent = 0);
~MainWindow(); ~MainWindow();
//Loads all data from a recipe into the GUI components. //Loads all data from a recipe into the GUI components.
void loadFromRecipe(Recipe recipe); void loadFromRecipe(Recipe recipe);
private slots:
void on_newButton_clicked();
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
RecipeDatabase *recipeDB;
IngredientListModel ingredientModel; IngredientListModel ingredientModel;
//Hidden manipulation methods. //Hidden manipulation methods.
void setRecipeName(string name); void setRecipeName(string name);
void setInstruction(Instruction instruction); void setInstruction(Instruction instruction);
void setIngredients(vector<RecipeIngredient> ingredients); void setIngredients(vector<RecipeIngredient> ingredients);
void setImage(QImage img);
void setPrepTime(QTime prepTime);
void setCookTime(QTime cookTime);
void setServings(float servings);
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H