Merge pull request #8 from andrewlalis/development
More security and less unexpected behaviour.
This commit is contained in:
commit
c971a60666
11
RecipeDB.pro
11
RecipeDB.pro
|
@ -34,7 +34,9 @@ SOURCES += model/recipe/instruction.cpp \
|
||||||
utils/stringutils.cpp \
|
utils/stringutils.cpp \
|
||||||
gui/openrecipedialog.cpp \
|
gui/openrecipedialog.cpp \
|
||||||
model/recipe/recipetablemodel.cpp \
|
model/recipe/recipetablemodel.cpp \
|
||||||
gui/mainwindow.cpp
|
gui/mainwindow.cpp \
|
||||||
|
gui/newDialogs/newfoodgroupdialog.cpp \
|
||||||
|
model/recipe/ingredients/recipeingredientlistmodel.cpp
|
||||||
|
|
||||||
HEADERS += model/recipe/instruction.h \
|
HEADERS += model/recipe/instruction.h \
|
||||||
model/recipe/recipe.h \
|
model/recipe/recipe.h \
|
||||||
|
@ -58,7 +60,9 @@ HEADERS += model/recipe/instruction.h \
|
||||||
utils/stringutils.h \
|
utils/stringutils.h \
|
||||||
gui/openrecipedialog.h \
|
gui/openrecipedialog.h \
|
||||||
model/recipe/recipetablemodel.h \
|
model/recipe/recipetablemodel.h \
|
||||||
gui/mainwindow.h
|
gui/mainwindow.h \
|
||||||
|
gui/newDialogs/newfoodgroupdialog.h \
|
||||||
|
model/recipe/ingredients/recipeingredientlistmodel.h
|
||||||
|
|
||||||
LIBS += -ldl \
|
LIBS += -ldl \
|
||||||
|
|
||||||
|
@ -68,7 +72,8 @@ FORMS += gui/mainwindow.ui \
|
||||||
gui/newDialogs/newtagdialog.ui \
|
gui/newDialogs/newtagdialog.ui \
|
||||||
gui/newDialogs/newunitdialog.ui \
|
gui/newDialogs/newunitdialog.ui \
|
||||||
gui/openrecipedialog.ui \
|
gui/openrecipedialog.ui \
|
||||||
gui/mainwindow.ui
|
gui/mainwindow.ui \
|
||||||
|
gui/newDialogs/newfoodgroupdialog.ui
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
.gitignore
|
.gitignore
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
#include "model/recipe/recipe.h"
|
#include "model/recipe/recipe.h"
|
||||||
#include "model/recipe/ingredients/ingredientlistmodel.h"
|
#include "model/recipe/ingredients/recipeingredientlistmodel.h"
|
||||||
#include "gui/newrecipedialog.h"
|
#include "gui/newrecipedialog.h"
|
||||||
#include "gui/openrecipedialog.h"
|
#include "gui/openrecipedialog.h"
|
||||||
#include "utils/stringutils.h"
|
#include "utils/stringutils.h"
|
||||||
|
@ -39,7 +39,7 @@ public:
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
RecipeDatabase *recipeDB;
|
RecipeDatabase *recipeDB;
|
||||||
IngredientListModel ingredientModel;
|
RecipeIngredientListModel ingredientModel;
|
||||||
TagListModel tagsListModel;
|
TagListModel tagsListModel;
|
||||||
|
|
||||||
//Hidden manipulation methods.
|
//Hidden manipulation methods.
|
||||||
|
|
|
@ -329,10 +329,10 @@ font: "Noto Sans CJK KR";</string>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item alignment="Qt::AlignRight">
|
||||||
<widget class="QLabel" name="recipeNameLabel">
|
<widget class="QLabel" name="recipeNameLabel">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
|
@ -361,6 +361,26 @@ font: "Noto Sans CJK KR";</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft|Qt::AlignBottom">
|
||||||
|
<widget class="QLabel" name="authorLabel">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Noto Sans CJK KR Light</family>
|
||||||
|
<pointsize>14</pointsize>
|
||||||
|
<stylestrategy>PreferAntialias</stylestrategy>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>By Unknown Author</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -584,6 +604,9 @@ font: "Noto Sans CJK KR";</string>
|
||||||
<property name="horizontalScrollBarPolicy">
|
<property name="horizontalScrollBarPolicy">
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="editTriggers">
|
||||||
|
<set>QAbstractItemView::NoEditTriggers</set>
|
||||||
|
</property>
|
||||||
<property name="selectionMode">
|
<property name="selectionMode">
|
||||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include "newfoodgroupdialog.h"
|
||||||
|
#include "ui_newfoodgroupdialog.h"
|
||||||
|
|
||||||
|
newFoodGroupDialog::newFoodGroupDialog(QWidget *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::newFoodGroupDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
newFoodGroupDialog::~newFoodGroupDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
string newFoodGroupDialog::getFoodGroup() const{
|
||||||
|
return ui->lineEdit->text().toStdString();
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef NEWFOODGROUPDIALOG_H
|
||||||
|
#define NEWFOODGROUPDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class newFoodGroupDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class newFoodGroupDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit newFoodGroupDialog(QWidget *parent = 0);
|
||||||
|
~newFoodGroupDialog();
|
||||||
|
|
||||||
|
string getFoodGroup() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::newFoodGroupDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NEWFOODGROUPDIALOG_H
|
|
@ -0,0 +1,101 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>newFoodGroupDialog</class>
|
||||||
|
<widget class="QDialog" name="newFoodGroupDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>240</width>
|
||||||
|
<height>114</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>11</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>New Food Group</string>
|
||||||
|
</property>
|
||||||
|
<property name="windowIcon">
|
||||||
|
<iconset resource="../../images.qrc">
|
||||||
|
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Noto Sans CJK KR Light</family>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add New Food Group</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<family>Noto Sans CJK KR Light</family>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources>
|
||||||
|
<include location="../../images.qrc"/>
|
||||||
|
</resources>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>newFoodGroupDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>newFoodGroupDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -8,11 +8,42 @@ NewIngredientDialog::NewIngredientDialog(QWidget *parent) :
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NewIngredientDialog::NewIngredientDialog(RecipeDatabase *recipeDB, QWidget *parent) : NewIngredientDialog(parent){
|
||||||
|
this->recipeDB = recipeDB;
|
||||||
|
this->populateFoodGroupBox();
|
||||||
|
}
|
||||||
|
|
||||||
NewIngredientDialog::~NewIngredientDialog()
|
NewIngredientDialog::~NewIngredientDialog()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ingredient NewIngredientDialog::getIngredient(){
|
Ingredient NewIngredientDialog::getIngredient(){
|
||||||
return Ingredient(ui->nameEdit->text().toLower().toStdString(), ui->foodGroupEdit->text().toLower().toStdString());
|
return Ingredient(ui->nameEdit->text().toLower().toStdString(), ui->foodGroupBox->currentText().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewIngredientDialog::populateFoodGroupBox(){
|
||||||
|
vector<string> foodGroups = this->recipeDB->retrieveAllFoodGroups();
|
||||||
|
ui->foodGroupBox->clear();
|
||||||
|
for (unsigned int i = 0; i < foodGroups.size(); i++){
|
||||||
|
QString s = QString::fromStdString(foodGroups[i]);
|
||||||
|
ui->foodGroupBox->insertItem(i, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewIngredientDialog::on_addFoodGroupButton_clicked(){
|
||||||
|
newFoodGroupDialog d(this);
|
||||||
|
if (d.exec() == QDialog::Accepted){
|
||||||
|
string s = d.getFoodGroup();
|
||||||
|
if (!s.empty()){
|
||||||
|
ui->foodGroupBox->addItem(QString::fromStdString(s));
|
||||||
|
ui->foodGroupBox->setCurrentText(QString::fromStdString(s));
|
||||||
|
} else {
|
||||||
|
QMessageBox::warning(this, "Empty Food Group", "The food group you entered is empty!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewIngredientDialog::on_deleteFoodGroupButton_clicked(){
|
||||||
|
ui->foodGroupBox->removeItem(ui->foodGroupBox->currentIndex());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,11 @@
|
||||||
#define NEWINGREDIENTDIALOG_H
|
#define NEWINGREDIENTDIALOG_H
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include "model/recipe/ingredients/ingredient.h"
|
#include "model/recipe/ingredients/ingredient.h"
|
||||||
|
#include "model/database/recipedatabase.h"
|
||||||
|
#include "gui/newDialogs/newfoodgroupdialog.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class NewIngredientDialog;
|
class NewIngredientDialog;
|
||||||
|
@ -14,13 +18,22 @@ class NewIngredientDialog : public QDialog
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit NewIngredientDialog(QWidget *parent = 0);
|
explicit NewIngredientDialog(QWidget *parent = 0);
|
||||||
|
NewIngredientDialog(RecipeDatabase *recipeDB, QWidget *parent = 0);
|
||||||
~NewIngredientDialog();
|
~NewIngredientDialog();
|
||||||
|
|
||||||
//Access values.
|
//Access values.
|
||||||
Ingredient getIngredient();
|
Ingredient getIngredient();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_addFoodGroupButton_clicked();
|
||||||
|
|
||||||
|
void on_deleteFoodGroupButton_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::NewIngredientDialog *ui;
|
Ui::NewIngredientDialog *ui;
|
||||||
|
RecipeDatabase *recipeDB;
|
||||||
|
|
||||||
|
void populateFoodGroupBox();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NEWINGREDIENTDIALOG_H
|
#endif // NEWINGREDIENTDIALOG_H
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>240</width>
|
<width>367</width>
|
||||||
<height>320</height>
|
<height>228</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -60,7 +60,45 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="foodGroupEdit"/>
|
<widget class="QWidget" name="foodGroupSelectionWidget" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="foodGroupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="insertPolicy">
|
||||||
|
<enum>QComboBox::InsertAlphabetically</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignRight">
|
||||||
|
<widget class="QPushButton" name="addFoodGroupButton">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../../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="deleteFoodGroupButton">
|
||||||
|
<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>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -7,16 +7,19 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>240</width>
|
<width>240</width>
|
||||||
<height>320</height>
|
<height>121</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>New Tag</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowIcon">
|
<property name="windowIcon">
|
||||||
<iconset resource="../../images.qrc">
|
<iconset resource="../../images.qrc">
|
||||||
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
|
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 25 "Noto Sans CJK KR Light";</string>
|
||||||
|
</property>
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -26,6 +29,14 @@
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="tagLabel">
|
<widget class="QLabel" name="tagLabel">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>13</pointsize>
|
||||||
|
<weight>3</weight>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>New Tag</string>
|
<string>New Tag</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -35,7 +46,16 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="tagEdit"/>
|
<widget class="QLineEdit" name="tagEdit">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
<weight>3</weight>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>240</width>
|
<width>195</width>
|
||||||
<height>350</height>
|
<height>340</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -17,6 +17,9 @@
|
||||||
<iconset resource="../../images.qrc">
|
<iconset resource="../../images.qrc">
|
||||||
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
|
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">font: 25 "Noto Sans CJK KR Light";</string>
|
||||||
|
</property>
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -26,6 +29,14 @@
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
<weight>3</weight>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Unit Name</string>
|
<string>Unit Name</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -39,6 +50,14 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
<weight>3</weight>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Plural Name</string>
|
<string>Plural Name</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -52,6 +71,14 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
<weight>3</weight>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Abbreviation</string>
|
<string>Abbreviation</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -86,6 +113,14 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
<weight>3</weight>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Type:</string>
|
<string>Type:</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -109,6 +144,14 @@
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_5">
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<pointsize>12</pointsize>
|
||||||
|
<weight>3</weight>
|
||||||
|
<italic>false</italic>
|
||||||
|
<bold>false</bold>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Metric Coefficient</string>
|
<string>Metric Coefficient</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -75,6 +75,7 @@ void NewRecipeDialog::on_addIngredientButton_clicked(){
|
||||||
UnitOfMeasure u = this->units[ui->unitComboBox->currentIndex()];
|
UnitOfMeasure u = this->units[ui->unitComboBox->currentIndex()];
|
||||||
RecipeIngredient ri(i, ui->quantitySpinBox->value(), u, ui->commentsLineEdit->text().toStdString());
|
RecipeIngredient ri(i, ui->quantitySpinBox->value(), u, ui->commentsLineEdit->text().toStdString());
|
||||||
this->ingredientListModel.addIngredient(ri);
|
this->ingredientListModel.addIngredient(ri);
|
||||||
|
ui->commentsLineEdit->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewRecipeDialog::on_italicsButton_clicked(){
|
void NewRecipeDialog::on_italicsButton_clicked(){
|
||||||
|
@ -144,12 +145,17 @@ void NewRecipeDialog::on_deleteIngredientButton_clicked(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewRecipeDialog::on_newIngredientButton_clicked(){
|
void NewRecipeDialog::on_newIngredientButton_clicked(){
|
||||||
NewIngredientDialog d(this);
|
NewIngredientDialog d(this->recipeDB, this);
|
||||||
d.show();
|
d.show();
|
||||||
if (d.exec() == QDialog::Accepted){
|
if (d.exec() == QDialog::Accepted){
|
||||||
Ingredient i = d.getIngredient();
|
Ingredient i = d.getIngredient();
|
||||||
this->recipeDB->storeIngredient(i);
|
if (!i.getName().empty() && !i.getFoodGroup().empty() && this->recipeDB->storeIngredient(i)){
|
||||||
this->populateIngredientsBox();
|
this->populateIngredientsBox();
|
||||||
|
ui->ingredientNameBox->setCurrentText(QString::fromStdString(i.getName()));
|
||||||
|
} else {
|
||||||
|
QMessageBox::critical(this, "Error", "Unable to add ingredient.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,12 +165,16 @@ void NewRecipeDialog::on_newTagButton_clicked(){
|
||||||
if (d.exec() == QDialog::Accepted){
|
if (d.exec() == QDialog::Accepted){
|
||||||
RecipeTag tag = d.getTag();
|
RecipeTag tag = d.getTag();
|
||||||
//Temporarily add this to the tags list, and it will be saved if the recipe is saved.
|
//Temporarily add this to the tags list, and it will be saved if the recipe is saved.
|
||||||
this->tags.push_back(tag);
|
if (!tag.getValue().empty()){
|
||||||
this->tagsListModel.addTag(tag);
|
this->tags.push_back(tag);
|
||||||
ui->tagsComboBox->clear();
|
this->tagsListModel.addTag(tag);
|
||||||
for (unsigned int i = 0; i < this->tags.size(); i++){
|
ui->tagsComboBox->clear();
|
||||||
QString s = QString::fromStdString(this->tags[i].getValue());
|
for (unsigned int i = 0; i < this->tags.size(); i++){
|
||||||
ui->tagsComboBox->insertItem(i, s);
|
QString s = QString::fromStdString(this->tags[i].getValue());
|
||||||
|
ui->tagsComboBox->insertItem(i, s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
QMessageBox::warning(this, "Empty Tag", "The tag you entered is blank!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,10 +199,11 @@ void NewRecipeDialog::on_newUnitButton_clicked(){
|
||||||
d.show();
|
d.show();
|
||||||
if (d.exec() == QDialog::Accepted){
|
if (d.exec() == QDialog::Accepted){
|
||||||
UnitOfMeasure u = d.getUnit();
|
UnitOfMeasure u = d.getUnit();
|
||||||
if (!this->recipeDB->storeUnitOfMeasure(u) || u.getName().empty() || u.getNamePlural().empty() || u.getAbbreviation().empty()){
|
if (u.getName().empty() || u.getNamePlural().empty() || u.getAbbreviation().empty() || !this->recipeDB->storeUnitOfMeasure(u)){
|
||||||
QMessageBox::critical(this, "Error", "Unable to store new unit.");
|
QMessageBox::critical(this, "Error", "Unable to store new unit. Make sure all the information is filled in!");
|
||||||
} else {
|
} else {
|
||||||
this->populateUnitsBox();
|
this->populateUnitsBox();
|
||||||
|
ui->unitComboBox->setCurrentText(QString::fromStdString(u.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
#include "model/database/recipedatabase.h"
|
#include "model/database/recipedatabase.h"
|
||||||
#include "model/recipe/ingredients/ingredientlistmodel.h"
|
#include "model/recipe/ingredients/recipeingredientlistmodel.h"
|
||||||
#include "model/recipe/tags/taglistmodel.h"
|
#include "model/recipe/tags/taglistmodel.h"
|
||||||
|
|
||||||
#include "gui/newDialogs/newingredientdialog.h"
|
#include "gui/newDialogs/newingredientdialog.h"
|
||||||
|
@ -67,7 +67,7 @@ class NewRecipeDialog : public QDialog
|
||||||
vector<Ingredient> ingredients;
|
vector<Ingredient> ingredients;
|
||||||
vector<UnitOfMeasure> units;
|
vector<UnitOfMeasure> units;
|
||||||
vector<RecipeTag> tags;
|
vector<RecipeTag> tags;
|
||||||
IngredientListModel ingredientListModel;
|
RecipeIngredientListModel ingredientListModel;
|
||||||
TagListModel tagsListModel;
|
TagListModel tagsListModel;
|
||||||
QImage img;
|
QImage img;
|
||||||
bool accepted = false;
|
bool accepted = false;
|
||||||
|
|
|
@ -96,27 +96,11 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="recipeNamePanel" native="true">
|
<widget class="QWidget" name="recipeNamePanel" native="true">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="recipeNameLabel">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<weight>3</weight>
|
|
||||||
<italic>false</italic>
|
|
||||||
<bold>false</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Edit Recipe</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLineEdit" name="recipeNameEdit">
|
<widget class="QLineEdit" name="recipeNameEdit">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
|
<pointsize>16</pointsize>
|
||||||
<weight>3</weight>
|
<weight>3</weight>
|
||||||
<italic>false</italic>
|
<italic>false</italic>
|
||||||
<bold>false</bold>
|
<bold>false</bold>
|
||||||
|
@ -158,7 +142,7 @@
|
||||||
<second>0</second>
|
<second>0</second>
|
||||||
<year>1999</year>
|
<year>1999</year>
|
||||||
<month>12</month>
|
<month>12</month>
|
||||||
<day>25</day>
|
<day>24</day>
|
||||||
</datetime>
|
</datetime>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentSection">
|
<property name="currentSection">
|
||||||
|
@ -289,6 +273,12 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(113, 119, 255);</string>
|
||||||
|
</property>
|
||||||
|
<property name="insertPolicy">
|
||||||
|
<enum>QComboBox::InsertAlphabetically</enum>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignRight">
|
<item alignment="Qt::AlignRight">
|
||||||
|
@ -418,16 +408,6 @@
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="ingredientsPanelLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Ingredients</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="ingredientsSubPanel" native="true">
|
<widget class="QWidget" name="ingredientsSubPanel" native="true">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||||
|
@ -485,12 +465,21 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(113, 119, 255);</string>
|
||||||
|
</property>
|
||||||
<property name="editable">
|
<property name="editable">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentText">
|
<property name="currentText">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="insertPolicy">
|
||||||
|
<enum>QComboBox::InsertAlphabetically</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frame">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -580,6 +569,12 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(113, 119, 255);</string>
|
||||||
|
</property>
|
||||||
|
<property name="insertPolicy">
|
||||||
|
<enum>QComboBox::InsertAlphabetically</enum>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignRight">
|
<item alignment="Qt::AlignRight">
|
||||||
|
@ -832,7 +827,10 @@
|
||||||
<enum>Qt::LeftToRight</enum>
|
<enum>Qt::LeftToRight</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="autoFillBackground">
|
<property name="autoFillBackground">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">background-color: rgb(255, 255, 255);</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
|
|
@ -8,10 +8,19 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) :
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
ui->recipeTableView->setModel(&this->recipeTableModel);
|
ui->recipeTableView->setModel(&this->recipeTableModel);
|
||||||
|
ui->ingredientsListView->setModel(&this->ingredientsModel);
|
||||||
|
ui->tagsListView->setModel(&this->tagsModel);
|
||||||
|
|
||||||
|
connect(ui->ingredientsListView->selectionModel(),
|
||||||
|
SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
|
||||||
|
this,
|
||||||
|
SLOT(on_ingredientsListView_selectionChanged(QItemSelection)));
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){
|
OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){
|
||||||
this->recipeDB = recipeDB;
|
this->recipeDB = recipeDB;
|
||||||
|
this->populateIngredientsList();
|
||||||
|
this->populateTagsList();
|
||||||
this->populateRecipesTable();
|
this->populateRecipesTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,13 +41,21 @@ void OpenRecipeDialog::populateRecipesTable(){
|
||||||
ui->recipeTableView->show();
|
ui->recipeTableView->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenRecipeDialog::populateIngredientsList(){
|
||||||
|
this->ingredientsModel.setIngredients(this->recipeDB->retrieveAllIngredients());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenRecipeDialog::populateTagsList(){
|
||||||
|
this->tagsModel.setTags(this->recipeDB->retrieveAllTags());
|
||||||
|
}
|
||||||
|
|
||||||
void OpenRecipeDialog::on_deleteRecipeButton_clicked(){
|
void OpenRecipeDialog::on_deleteRecipeButton_clicked(){
|
||||||
QItemSelectionModel *selectModel = ui->recipeTableView->selectionModel();
|
QItemSelectionModel *selectModel = ui->recipeTableView->selectionModel();
|
||||||
if (!selectModel->hasSelection()){
|
if (!selectModel->hasSelection()){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vector<int> rows;
|
vector<int> rows;
|
||||||
QModelIndexList indexes = selectModel->selectedIndexes();
|
QModelIndexList indexes = selectModel->selectedRows();
|
||||||
for (int i = 0; i < indexes.count(); i++){
|
for (int i = 0; i < indexes.count(); i++){
|
||||||
rows.push_back(indexes.at(i).row());
|
rows.push_back(indexes.at(i).row());
|
||||||
}
|
}
|
||||||
|
@ -62,3 +79,14 @@ void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index
|
||||||
this->selectedRecipe = this->recipeTableModel.getRecipeAt(index.row());
|
this->selectedRecipe = this->recipeTableModel.getRecipeAt(index.row());
|
||||||
this->close();
|
this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenRecipeDialog::on_ingredientsListView_selectionChanged(const QItemSelection &selection){
|
||||||
|
printf("Selection changed!\n");
|
||||||
|
vector<Ingredient> ingredients;
|
||||||
|
for (QModelIndex index : selection.indexes()){
|
||||||
|
Ingredient i = this->ingredientsModel.getIngredients().at(index.row());
|
||||||
|
ingredients.push_back(i);
|
||||||
|
printf("Selected: %s\n", i.getName().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -3,9 +3,12 @@
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QItemSelection>
|
||||||
|
|
||||||
#include "model/database/recipedatabase.h"
|
#include "model/database/recipedatabase.h"
|
||||||
#include "model/recipe/recipetablemodel.h"
|
#include "model/recipe/recipetablemodel.h"
|
||||||
|
#include "model/recipe/ingredients/ingredientlistmodel.h"
|
||||||
|
#include "model/recipe/tags/taglistmodel.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class OpenRecipeDialog;
|
class OpenRecipeDialog;
|
||||||
|
@ -27,13 +30,20 @@ class OpenRecipeDialog : public QDialog
|
||||||
|
|
||||||
void on_recipeTableView_doubleClicked(const QModelIndex &index);
|
void on_recipeTableView_doubleClicked(const QModelIndex &index);
|
||||||
|
|
||||||
|
void on_ingredientsListView_selectionChanged(const QItemSelection &selection);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::OpenRecipeDialog *ui;
|
Ui::OpenRecipeDialog *ui;
|
||||||
RecipeDatabase *recipeDB;
|
RecipeDatabase *recipeDB;
|
||||||
RecipeTableModel recipeTableModel;
|
RecipeTableModel recipeTableModel;
|
||||||
Recipe selectedRecipe;
|
Recipe selectedRecipe;
|
||||||
|
|
||||||
|
IngredientListModel ingredientsModel;
|
||||||
|
TagListModel tagsModel;
|
||||||
|
|
||||||
void populateRecipesTable();
|
void populateRecipesTable();
|
||||||
|
void populateIngredientsList();
|
||||||
|
void populateTagsList();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OPENRECIPEDIALOG_H
|
#endif // OPENRECIPEDIALOG_H
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>640</width>
|
<width>1000</width>
|
||||||
<height>480</height>
|
<height>480</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -20,10 +20,80 @@
|
||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
<item alignment="Qt::AlignTop">
|
<item alignment="Qt::AlignLeft|Qt::AlignTop">
|
||||||
<widget class="QWidget" name="searchPanel" native="true">
|
<widget class="QWidget" name="searchPanel" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QWidget" name="tagsSearchpanel" native="true">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="tagLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Tag</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListView" name="tagsListView">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="isWrapping" stdset="0">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignLeft">
|
||||||
|
<widget class="QWidget" name="ingredientSearchPanel" native="true">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="ingredientLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Ingredient</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListView" name="ingredientsListView">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="selectionMode">
|
||||||
|
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||||
|
</property>
|
||||||
|
<property name="isWrapping" stdset="0">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="nameSearchPanel" native="true">
|
<widget class="QWidget" name="nameSearchPanel" native="true">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
@ -40,38 +110,6 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="tagsSearchpanel" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="tagLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Tag</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="tagEdit"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="ingredientSearchPanel" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="ingredientLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Ingredient</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="ingredientEdit"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="searchButton">
|
<widget class="QPushButton" name="searchButton">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -86,26 +124,26 @@
|
||||||
</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">
|
||||||
|
<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="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="QTableView" name="recipeTableView">
|
<widget class="QTableView" name="recipeTableView">
|
||||||
<property name="frameShape">
|
<property name="frameShape">
|
||||||
|
|
41
main.cpp
41
main.cpp
|
@ -4,22 +4,39 @@
|
||||||
|
|
||||||
#include "model/database/database.h"
|
#include "model/database/database.h"
|
||||||
#include "model/database/recipedatabase.h"
|
#include "model/database/recipedatabase.h"
|
||||||
|
#include "utils/fileutils.h"
|
||||||
|
|
||||||
|
void test(RecipeDatabase *recipeDB);
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
RecipeDatabase recipeDB("recipes");
|
RecipeDatabase recipeDB(QString(FileUtils::appDataPath+"recipes.db").toStdString());
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
MainWindow w(&recipeDB);
|
MainWindow w(&recipeDB);
|
||||||
w.show();
|
w.show();
|
||||||
|
|
||||||
//TESTING CODE
|
//TESTING CODE
|
||||||
|
test(&recipeDB);
|
||||||
|
|
||||||
|
//END TESTING CODE.
|
||||||
|
|
||||||
|
w.loadFromRecipe(recipeDB.retrieveRandomRecipe());
|
||||||
|
|
||||||
|
a.exec();
|
||||||
|
recipeDB.closeConnection();
|
||||||
|
printf("Total queries: %lu\n", recipeDB.getQueryCount());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test(RecipeDatabase *recipeDB){
|
||||||
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("Placeholder Text"),
|
||||||
QImage(),
|
QImage(),
|
||||||
vector<RecipeTag>({RecipeTag("testing"),
|
vector<RecipeTag>({RecipeTag("testing"),
|
||||||
RecipeTag("fake")}),
|
RecipeTag("fake")}),
|
||||||
|
@ -28,13 +45,21 @@ int main(int argc, char *argv[])
|
||||||
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.selectFrom("recipe", "recipeId, name", "").printData();
|
vector<string> foodGroups = recipeDB->retrieveAllFoodGroups();
|
||||||
w.loadFromRecipe(recipeDB.retrieveRandomRecipe());
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
a.exec();
|
|
||||||
recipeDB.closeConnection();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
Database::Database(string filename){
|
Database::Database(string filename){
|
||||||
this->filename = filename;
|
this->filename = filename;
|
||||||
|
this->queryCount = 0;
|
||||||
openConnection();
|
openConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@ ResultTable Database::executeSQL(string statement){
|
||||||
t.extractData(stmt);
|
t.extractData(stmt);
|
||||||
|
|
||||||
this->returnCode = sqlite3_finalize(stmt);
|
this->returnCode = sqlite3_finalize(stmt);
|
||||||
|
this->queryCount++;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +101,10 @@ bool Database::tableExists(string tableName){
|
||||||
return !t.isEmpty();
|
return !t.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::getLastInsertedRowId(){
|
int Database::getLastInsertedRowId() const{
|
||||||
return sqlite3_last_insert_rowid(this->db);
|
return sqlite3_last_insert_rowid(this->db);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long Database::getQueryCount() const{
|
||||||
|
return this->queryCount;
|
||||||
|
}
|
||||||
|
|
|
@ -29,7 +29,9 @@ public:
|
||||||
bool deleteFrom(string tableName, string conditions);
|
bool deleteFrom(string tableName, string conditions);
|
||||||
|
|
||||||
bool tableExists(string tableName);
|
bool tableExists(string tableName);
|
||||||
int getLastInsertedRowId();
|
int getLastInsertedRowId() const;
|
||||||
|
|
||||||
|
unsigned long getQueryCount() const;
|
||||||
|
|
||||||
void closeConnection();
|
void closeConnection();
|
||||||
|
|
||||||
|
@ -45,6 +47,9 @@ private:
|
||||||
string sql;
|
string sql;
|
||||||
char* errorMsg;
|
char* errorMsg;
|
||||||
|
|
||||||
|
//Data tracking.
|
||||||
|
unsigned long queryCount;
|
||||||
|
|
||||||
void openConnection();
|
void openConnection();
|
||||||
std::string combineVector(std::vector<std::string> strings, std::string mid);
|
std::string combineVector(std::vector<std::string> strings, std::string mid);
|
||||||
};
|
};
|
||||||
|
|
|
@ -88,7 +88,7 @@ int RecipeDatabase::storeIngredient(Ingredient ingredient){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return std::stoi(t.valueAt(0, 0));
|
return std::stoi(t.at(0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,12 +162,21 @@ Recipe RecipeDatabase::retrieveRandomRecipe(){
|
||||||
vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
|
vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
|
||||||
ResultTable t = this->selectFrom("recipe", "name", "ORDER BY name");
|
ResultTable t = this->selectFrom("recipe", "name", "ORDER BY name");
|
||||||
vector<Recipe> recipes;
|
vector<Recipe> recipes;
|
||||||
for (unsigned int row = 0; row < t.rowCount(); row++){
|
for (TableRow row : t.rows()){
|
||||||
recipes.push_back(this->retrieveRecipe(t.valueAt(row, 0)));
|
recipes.push_back(this->retrieveRecipe(row.at(0)));
|
||||||
}
|
}
|
||||||
return recipes;
|
return recipes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<string> RecipeDatabase::retrieveAllFoodGroups(){
|
||||||
|
ResultTable t = this->executeSQL("SELECT DISTINCT foodGroup FROM ingredient ORDER BY foodGroup;");
|
||||||
|
vector<string> foodGroups;
|
||||||
|
for (TableRow row : t.rows()){
|
||||||
|
foodGroups.push_back(row.at(0));
|
||||||
|
}
|
||||||
|
return foodGroups;
|
||||||
|
}
|
||||||
|
|
||||||
vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
|
vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
|
||||||
ResultTable t = this->executeSQL("SELECT ingredient.name, ingredient.foodGroup, "//0, 1
|
ResultTable t = this->executeSQL("SELECT ingredient.name, ingredient.foodGroup, "//0, 1
|
||||||
"recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment,"//2, 3, 4
|
"recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment,"//2, 3, 4
|
||||||
|
@ -179,33 +188,33 @@ vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId)
|
||||||
"ON recipeIngredient.unitName = unitOfMeasure.name "
|
"ON recipeIngredient.unitName = unitOfMeasure.name "
|
||||||
"WHERE recipeIngredient.recipeId = "+std::to_string(recipeId)+";");
|
"WHERE recipeIngredient.recipeId = "+std::to_string(recipeId)+";");
|
||||||
vector<RecipeIngredient> ings;
|
vector<RecipeIngredient> ings;
|
||||||
for (unsigned int row = 0; row < t.rowCount(); row++){
|
for (TableRow row : t.rows()){
|
||||||
RecipeIngredient r(t.valueAt(row, 0),
|
RecipeIngredient r(row.at(0),
|
||||||
t.valueAt(row, 1),
|
row.at(1),
|
||||||
std::stof(t.valueAt(row, 2)),
|
std::stof(row.at(2)),
|
||||||
UnitOfMeasure(t.valueAt(row, 5), t.valueAt(row, 6), t.valueAt(row, 7), std::stoi(t.valueAt(row, 8)), std::stod(t.valueAt(row, 9))),
|
UnitOfMeasure(row.at(5), row.at(6), row.at(7), std::stoi(row.at(8)), std::stod(row.at(9))),
|
||||||
t.valueAt(row, 4));
|
row.at(4));
|
||||||
ings.push_back(r);
|
ings.push_back(r);
|
||||||
}
|
}
|
||||||
return ings;
|
return ings;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Ingredient> RecipeDatabase::retrieveAllIngredients(){
|
vector<Ingredient> RecipeDatabase::retrieveAllIngredients(){
|
||||||
ResultTable t = this->selectFrom("ingredient", "*", "ORDER BY name");
|
ResultTable t = this->selectFrom("ingredient", "name, foodGroup", "ORDER BY name");
|
||||||
vector<Ingredient> ings;
|
vector<Ingredient> ings;
|
||||||
for (unsigned int row = 0; row < t.rowCount(); row++){
|
for (TableRow row : t.rows()){
|
||||||
Ingredient i(t.valueAt(row, 2), t.valueAt(row, 1));
|
Ingredient i(row.at(0), row.at(1));
|
||||||
ings.push_back(i);
|
ings.push_back(i);
|
||||||
}
|
}
|
||||||
return ings;
|
return ings;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
|
vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
|
||||||
ResultTable t = this->selectFrom("unitOfMeasure", "*", "ORDER BY name");
|
ResultTable t = this->selectFrom("unitOfMeasure", "name, plural, abbreviation, type, metricCoefficient", "ORDER BY name");
|
||||||
vector<UnitOfMeasure> units;
|
vector<UnitOfMeasure> units;
|
||||||
if (!t.isEmpty()){
|
if (!t.isEmpty()){
|
||||||
for (unsigned int row = 0; row < t.rowCount(); row++){
|
for (TableRow row : t.rows()){
|
||||||
UnitOfMeasure u(t.valueAt(row, 0), t.valueAt(row, 1), t.valueAt(row, 2), std::stoi(t.valueAt(row, 3)), std::stod(t.valueAt(row, 4)));
|
UnitOfMeasure u(row.at(0), row.at(1), row.at(2), std::stoi(row.at(3)), std::stod(row.at(4)));
|
||||||
units.push_back(u);
|
units.push_back(u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -213,11 +222,11 @@ vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<RecipeTag> RecipeDatabase::retrieveTags(int recipeId){
|
vector<RecipeTag> RecipeDatabase::retrieveTags(int recipeId){
|
||||||
ResultTable t = this->selectFrom("recipeTag", "tagName", "WHERE recipeId="+std::to_string(recipeId));
|
ResultTable t = this->selectFrom("recipeTag", "tagName", "WHERE recipeId="+std::to_string(recipeId)+" ORDER BY tagName");
|
||||||
vector<RecipeTag> tags;
|
vector<RecipeTag> tags;
|
||||||
if (!t.isEmpty()){
|
if (!t.isEmpty()){
|
||||||
for (unsigned int row = 0; row < t.rowCount(); row++){
|
for (TableRow row : t.rows()){
|
||||||
RecipeTag tag(t.valueAt(row, 0));
|
RecipeTag tag(row.at(0));
|
||||||
tags.push_back(tag);
|
tags.push_back(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,11 +234,11 @@ vector<RecipeTag> RecipeDatabase::retrieveTags(int recipeId){
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<RecipeTag> RecipeDatabase::retrieveAllTags(){
|
vector<RecipeTag> RecipeDatabase::retrieveAllTags(){
|
||||||
ResultTable t = this->selectFrom("recipeTag", "tagName", "ORDER BY tagName");
|
ResultTable t = this->executeSQL("SELECT DISTINCT tagName FROM recipeTag ORDER BY tagName;");
|
||||||
vector<RecipeTag> tags;
|
vector<RecipeTag> tags;
|
||||||
if (!t.isEmpty()){
|
if (!t.isEmpty()){
|
||||||
for (unsigned int row = 0; row < t.rowCount(); row++){
|
for (TableRow row : t.rows()){
|
||||||
RecipeTag tag(t.valueAt(row, 0));
|
RecipeTag tag(row.at(0));
|
||||||
tags.push_back(tag);
|
tags.push_back(tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,7 +250,7 @@ bool RecipeDatabase::deleteRecipe(string name){
|
||||||
if (t.rowCount() != 1){
|
if (t.rowCount() != 1){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
string recipeId = t.valueAt(0, 0);
|
string recipeId = t.at(0, 0);
|
||||||
return this->deleteRecipe(std::stoi(recipeId));
|
return this->deleteRecipe(std::stoi(recipeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,6 +264,10 @@ bool RecipeDatabase::deleteRecipe(int recipeId){
|
||||||
bool tagsDeleted = this->deleteFrom("recipeTag", "WHERE recipeId="+idString);
|
bool tagsDeleted = this->deleteFrom("recipeTag", "WHERE recipeId="+idString);
|
||||||
bool recipeIngredientDeleted = this->deleteFrom("recipeIngredient", "WHERE recipeId="+idString);
|
bool recipeIngredientDeleted = this->deleteFrom("recipeIngredient", "WHERE recipeId="+idString);
|
||||||
bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString);
|
bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString);
|
||||||
|
bool instructionDeleted = FileUtils::deleteInstruction(recipeId);
|
||||||
|
bool imageDeleted = FileUtils::deleteImage(recipeId);
|
||||||
|
Q_UNUSED(instructionDeleted);
|
||||||
|
Q_UNUSED(imageDeleted);
|
||||||
if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){
|
if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){
|
||||||
this->executeSQL("COMMIT;");
|
this->executeSQL("COMMIT;");
|
||||||
return true;
|
return true;
|
||||||
|
@ -332,14 +345,15 @@ void RecipeDatabase::ensureTablesExist(){
|
||||||
this->executeSQL("COMMIT;");
|
this->executeSQL("COMMIT;");
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipe RecipeDatabase::readFromResultTable(ResultTable t, int row){
|
Recipe RecipeDatabase::readFromResultTable(ResultTable t, int tRow){
|
||||||
Recipe r;
|
Recipe r;
|
||||||
int id = std::stoi(t.valueAt(row, 0));
|
TableRow row = t.rows().at(tRow);
|
||||||
r.setName(t.valueAt(row, 1));
|
int id = std::stoi(row.at(0));
|
||||||
r.setCreatedDate(QDate::fromString(QString::fromStdString(t.valueAt(row, 2))));
|
r.setName(row.at(1));
|
||||||
r.setPrepTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 3))));
|
r.setCreatedDate(QDate::fromString(QString::fromStdString(row.at(2))));
|
||||||
r.setCookTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 4))));
|
r.setPrepTime(QTime::fromString(QString::fromStdString(row.at(3))));
|
||||||
r.setServings(std::stof(t.valueAt(row, 5)));
|
r.setCookTime(QTime::fromString(QString::fromStdString(row.at(4))));
|
||||||
|
r.setServings(std::stof(row.at(5)));
|
||||||
r.setInstruction(FileUtils::loadInstruction(id));
|
r.setInstruction(FileUtils::loadInstruction(id));
|
||||||
r.setImage(FileUtils::loadImage(id));
|
r.setImage(FileUtils::loadImage(id));
|
||||||
r.setIngredients(this->retrieveRecipeIngredients(id));
|
r.setIngredients(this->retrieveRecipeIngredients(id));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef RECIPEDATABASE_H
|
#ifndef RECIPEDATABASE_H
|
||||||
#define RECIPEDATABASE_H
|
#define RECIPEDATABASE_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "model/recipe/recipe.h"
|
#include "model/recipe/recipe.h"
|
||||||
|
@ -34,6 +34,7 @@ class RecipeDatabase : public Database
|
||||||
Recipe retrieveRecipe(string name);
|
Recipe retrieveRecipe(string name);
|
||||||
Recipe retrieveRandomRecipe();
|
Recipe retrieveRandomRecipe();
|
||||||
vector<Recipe> retrieveAllRecipes();
|
vector<Recipe> retrieveAllRecipes();
|
||||||
|
vector<string> retrieveAllFoodGroups();
|
||||||
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
|
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
|
||||||
vector<Ingredient> retrieveAllIngredients();
|
vector<Ingredient> retrieveAllIngredients();
|
||||||
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
|
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
|
||||||
|
|
|
@ -47,7 +47,7 @@ bool ResultTable::isEmpty(){
|
||||||
return this->values.empty();
|
return this->values.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
string ResultTable::valueAt(unsigned int row, unsigned int col){
|
string ResultTable::at(unsigned int row, unsigned int col){
|
||||||
if (isIndexValid(row, col)){
|
if (isIndexValid(row, col)){
|
||||||
return this->values[row][col];
|
return this->values[row][col];
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,6 +78,10 @@ unsigned int ResultTable::rowCount(){
|
||||||
return this->values.size();
|
return this->values.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<vector<string> > ResultTable::rows(){
|
||||||
|
return this->values;
|
||||||
|
}
|
||||||
|
|
||||||
string ResultTable::convertToString(sqlite3_value *val){
|
string ResultTable::convertToString(sqlite3_value *val){
|
||||||
const unsigned char* raw_text = sqlite3_value_text(val);
|
const unsigned char* raw_text = sqlite3_value_text(val);
|
||||||
if (raw_text == 0){
|
if (raw_text == 0){
|
||||||
|
|
|
@ -12,6 +12,8 @@ using namespace std;
|
||||||
* @brief The ResultTable class is an object that contains the results of an SQL query, in string form.
|
* @brief The ResultTable class is an object that contains the results of an SQL query, in string form.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef vector<string> TableRow;
|
||||||
|
|
||||||
class ResultTable
|
class ResultTable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -28,11 +30,12 @@ class ResultTable
|
||||||
void printData();
|
void printData();
|
||||||
|
|
||||||
bool isEmpty();
|
bool isEmpty();
|
||||||
string valueAt(unsigned int row, unsigned int col);
|
string at(unsigned int row, unsigned int col);
|
||||||
int getReturnCode();
|
int getReturnCode();
|
||||||
string getOriginalQuery();
|
string getOriginalQuery();
|
||||||
unsigned int columnCount();
|
unsigned int columnCount();
|
||||||
unsigned int rowCount();
|
unsigned int rowCount();
|
||||||
|
vector<vector<string>> rows();
|
||||||
private:
|
private:
|
||||||
vector<vector<string>> values;
|
vector<vector<string>> values;
|
||||||
int queryCode;
|
int queryCode;
|
||||||
|
|
|
@ -23,5 +23,9 @@ void Ingredient::setName(string newName){
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ingredient::setFoodGroup(string newFoodGroup){
|
void Ingredient::setFoodGroup(string newFoodGroup){
|
||||||
this->foodGroup = newFoodGroup;
|
this->foodGroup = newFoodGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
string Ingredient::toString(){
|
||||||
|
return this->getName();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ public:
|
||||||
//Setters
|
//Setters
|
||||||
void setName(string newName);
|
void setName(string newName);
|
||||||
void setFoodGroup(string newFoodGroup);
|
void setFoodGroup(string newFoodGroup);
|
||||||
|
|
||||||
|
string toString();
|
||||||
protected:
|
protected:
|
||||||
string name;
|
string name;
|
||||||
string foodGroup;
|
string foodGroup;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "model/recipe/ingredients/ingredientlistmodel.h"
|
#include "model/recipe/ingredients/ingredientlistmodel.h"
|
||||||
|
|
||||||
IngredientListModel::IngredientListModel(){
|
IngredientListModel::IngredientListModel(){
|
||||||
this->ingredients = vector<RecipeIngredient>();
|
this->ingredients = vector<Ingredient>();
|
||||||
}
|
}
|
||||||
|
|
||||||
int IngredientListModel::rowCount(const QModelIndex &parent) const{
|
int IngredientListModel::rowCount(const QModelIndex &parent) const{
|
||||||
|
@ -10,7 +10,7 @@ int IngredientListModel::rowCount(const QModelIndex &parent) const{
|
||||||
|
|
||||||
QVariant IngredientListModel::data(const QModelIndex &index, int role) const{
|
QVariant IngredientListModel::data(const QModelIndex &index, int role) const{
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
RecipeIngredient i = this->ingredients[row];
|
Ingredient i = this->ingredients[row];
|
||||||
|
|
||||||
string displayStr = i.toString();
|
string displayStr = i.toString();
|
||||||
|
|
||||||
|
@ -22,14 +22,14 @@ QVariant IngredientListModel::data(const QModelIndex &index, int role) const{
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IngredientListModel::setIngredients(vector<RecipeIngredient> ingredients){
|
void IngredientListModel::setIngredients(vector<Ingredient> ingredients){
|
||||||
this->ingredients = ingredients;
|
this->ingredients = ingredients;
|
||||||
QModelIndex index = createIndex(0, 0);
|
QModelIndex index = createIndex(0, 0);
|
||||||
QModelIndex bottomIndex = createIndex(ingredients.size()-1, 0);
|
QModelIndex bottomIndex = createIndex(ingredients.size()-1, 0);
|
||||||
emit dataChanged(index, bottomIndex);
|
emit dataChanged(index, bottomIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IngredientListModel::addIngredient(RecipeIngredient ri){
|
bool IngredientListModel::addIngredient(Ingredient ri){
|
||||||
//Add only if it doesn't exist already.
|
//Add only if it doesn't exist already.
|
||||||
for (unsigned int i = 0; i < this->ingredients.size(); i++){
|
for (unsigned int i = 0; i < this->ingredients.size(); i++){
|
||||||
if (!this->ingredients[i].getName().compare(ri.getName())){
|
if (!this->ingredients[i].getName().compare(ri.getName())){
|
||||||
|
@ -48,6 +48,6 @@ void IngredientListModel::deleteIngredient(int index){
|
||||||
emit dataChanged(createIndex(0, 0), createIndex(this->ingredients.size()-1, 0));
|
emit dataChanged(createIndex(0, 0), createIndex(this->ingredients.size()-1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<RecipeIngredient> IngredientListModel::getIngredients(){
|
vector<Ingredient> IngredientListModel::getIngredients(){
|
||||||
return this->ingredients;
|
return this->ingredients;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,13 @@ public:
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
//Custom methods to handle ingredient data.
|
//Custom methods to handle ingredient data.
|
||||||
void setIngredients(vector<RecipeIngredient> ingredients);
|
void setIngredients(vector<Ingredient> ingredients);
|
||||||
bool addIngredient(RecipeIngredient ri);
|
bool addIngredient(Ingredient ri);
|
||||||
void deleteIngredient(int index);
|
void deleteIngredient(int index);
|
||||||
vector<RecipeIngredient> getIngredients();
|
vector<Ingredient> getIngredients();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vector<RecipeIngredient> ingredients;
|
vector<Ingredient> ingredients;
|
||||||
|
|
||||||
//Helper for printing.
|
//Helper for printing.
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,10 @@ RecipeIngredient::RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure u
|
||||||
setComment(comment);
|
setComment(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RecipeIngredient::RecipeIngredient(Ingredient &i) : RecipeIngredient(i, 0.0f, UnitOfMeasure("bleh"), "Fuck"){
|
||||||
|
//Constructs recipe ingredient from ingredient which is a hidden recipe ingredient.
|
||||||
|
}
|
||||||
|
|
||||||
RecipeIngredient::RecipeIngredient(){
|
RecipeIngredient::RecipeIngredient(){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
RecipeIngredient(string name, string foodGroup, float quantity, UnitOfMeasure unit, string comment);
|
RecipeIngredient(string name, string foodGroup, float quantity, UnitOfMeasure unit, string comment);
|
||||||
//Constructor using data from a child ingredient.
|
//Constructor using data from a child ingredient.
|
||||||
RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure unit, string comment);
|
RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure unit, string comment);
|
||||||
|
RecipeIngredient(Ingredient &i);
|
||||||
RecipeIngredient();
|
RecipeIngredient();
|
||||||
|
|
||||||
//Getters
|
//Getters
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include "recipeingredientlistmodel.h"
|
||||||
|
|
||||||
|
RecipeIngredientListModel::RecipeIngredientListModel(){
|
||||||
|
this->ingredients = vector<RecipeIngredient>();
|
||||||
|
}
|
||||||
|
|
||||||
|
int RecipeIngredientListModel::rowCount(const QModelIndex &parent) const{
|
||||||
|
return this->ingredients.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant RecipeIngredientListModel::data(const QModelIndex &index, int role) const{
|
||||||
|
int row = index.row();
|
||||||
|
RecipeIngredient i = this->ingredients[row];
|
||||||
|
|
||||||
|
string displayStr = i.toString();
|
||||||
|
|
||||||
|
switch(role){
|
||||||
|
case Qt::DisplayRole:
|
||||||
|
return QString::fromStdString(displayStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecipeIngredientListModel::setIngredients(vector<RecipeIngredient> ingredients){
|
||||||
|
this->ingredients = ingredients;
|
||||||
|
QModelIndex index = createIndex(0, 0);
|
||||||
|
QModelIndex bottomIndex = createIndex(ingredients.size()-1, 0);
|
||||||
|
emit dataChanged(index, bottomIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RecipeIngredientListModel::addIngredient(RecipeIngredient ri){
|
||||||
|
//Add only if it doesn't exist already.
|
||||||
|
for (unsigned int i = 0; i < this->ingredients.size(); i++){
|
||||||
|
if (!this->ingredients[i].getName().compare(ri.getName())){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->ingredients.push_back(ri);
|
||||||
|
QModelIndex index = createIndex(this->ingredients.size()-1, 0);
|
||||||
|
QModelIndex bottomIndex = createIndex(this->ingredients.size()-1, 0);
|
||||||
|
emit dataChanged(index, bottomIndex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecipeIngredientListModel::deleteIngredient(int index){
|
||||||
|
this->ingredients.erase(this->ingredients.begin() + index);
|
||||||
|
emit dataChanged(createIndex(0, 0), createIndex(this->ingredients.size()-1, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<RecipeIngredient> RecipeIngredientListModel::getIngredients(){
|
||||||
|
return this->ingredients;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef RECIPEINGREDIENTLISTMODEL_H
|
||||||
|
#define RECIPEINGREDIENTLISTMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
|
||||||
|
#include "model/recipe/ingredients/recipeingredient.h"
|
||||||
|
|
||||||
|
class RecipeIngredientListModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RecipeIngredientListModel();
|
||||||
|
|
||||||
|
//Overridden methods.
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
//Custom methods to handle ingredient data.
|
||||||
|
void setIngredients(vector<RecipeIngredient> ingredients);
|
||||||
|
bool addIngredient(RecipeIngredient ri);
|
||||||
|
void deleteIngredient(int index);
|
||||||
|
vector<RecipeIngredient> getIngredients();
|
||||||
|
|
||||||
|
private:
|
||||||
|
vector<RecipeIngredient> ingredients;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RECIPEINGREDIENTLISTMODEL_H
|
|
@ -21,7 +21,17 @@ string Recipe::getName() const{
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<RecipeIngredient> Recipe::getIngredients() const{
|
vector<RecipeIngredient> Recipe::getIngredients() const{
|
||||||
return this->ingredients;
|
return this->ingredients;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<string> Recipe::getFoodGroups() const{
|
||||||
|
vector<string> foodGroups;
|
||||||
|
for (RecipeIngredient ri : this->ingredients){
|
||||||
|
if (find(foodGroups.begin(), foodGroups.end(), ri.getFoodGroup()) == foodGroups.end()){
|
||||||
|
foodGroups.push_back(ri.getFoodGroup());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foodGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction Recipe::getInstruction() const{
|
Instruction Recipe::getInstruction() const{
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "model/recipe/ingredients/recipeingredient.h"
|
#include "model/recipe/ingredients/recipeingredient.h"
|
||||||
#include "model/recipe/instruction.h"
|
#include "model/recipe/instruction.h"
|
||||||
|
@ -38,6 +39,7 @@ public:
|
||||||
//Getters
|
//Getters
|
||||||
string getName() const;
|
string getName() const;
|
||||||
vector<RecipeIngredient> getIngredients() const;
|
vector<RecipeIngredient> getIngredients() const;
|
||||||
|
vector<string> getFoodGroups() const;
|
||||||
Instruction getInstruction() const;
|
Instruction getInstruction() const;
|
||||||
QImage getImage() const;
|
QImage getImage() const;
|
||||||
vector<RecipeTag> getTags() const;
|
vector<RecipeTag> getTags() const;
|
||||||
|
|
|
@ -72,8 +72,8 @@ void RecipeTableModel::setRecipes(vector<Recipe> recipes){
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipe RecipeTableModel::getRecipeAt(int index){
|
Recipe RecipeTableModel::getRecipeAt(unsigned int index){
|
||||||
if (index < 0 || index >= this->recipes.size()){
|
if (index >= this->recipes.size()){
|
||||||
return Recipe();
|
return Recipe();
|
||||||
}
|
}
|
||||||
return this->recipes[index];
|
return this->recipes[index];
|
||||||
|
|
|
@ -20,7 +20,7 @@ class RecipeTableModel : public QAbstractTableModel
|
||||||
|
|
||||||
//Normal methods.
|
//Normal methods.
|
||||||
void setRecipes(vector<Recipe> recipes);
|
void setRecipes(vector<Recipe> recipes);
|
||||||
Recipe getRecipeAt(int index);
|
Recipe getRecipeAt(unsigned int index);
|
||||||
void clear();
|
void clear();
|
||||||
private:
|
private:
|
||||||
vector<Recipe> recipes;
|
vector<Recipe> recipes;
|
||||||
|
|
|
@ -61,4 +61,18 @@ QImage loadImage(int nr){
|
||||||
return img;
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool deleteInstruction(int nr){
|
||||||
|
ensureAppDataFolderExists();
|
||||||
|
QString filename = appDataPath + QString::fromStdString(std::to_string(nr)) +".html";
|
||||||
|
QFile file(filename);
|
||||||
|
return file.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool deleteImage(int nr){
|
||||||
|
ensureAppDataFolderExists();
|
||||||
|
QString filename = appDataPath + QString::fromStdString(std::to_string(nr)) +".png";
|
||||||
|
QFile file(filename);
|
||||||
|
return file.remove();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "model/recipe/instruction.h"
|
#include "model/recipe/instruction.h"
|
||||||
|
|
||||||
|
@ -19,9 +20,13 @@ namespace FileUtils{
|
||||||
|
|
||||||
Instruction loadInstruction(int nr);
|
Instruction loadInstruction(int nr);
|
||||||
|
|
||||||
|
bool deleteInstruction(int nr);
|
||||||
|
|
||||||
bool saveImage(int nr, QImage image);
|
bool saveImage(int nr, QImage image);
|
||||||
|
|
||||||
QImage loadImage(int nr);
|
QImage loadImage(int nr);
|
||||||
|
|
||||||
|
bool deleteImage(int nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FILEUTILS_H
|
#endif // FILEUTILS_H
|
||||||
|
|
|
@ -29,4 +29,13 @@ std::string toString(float val){
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printVector(std::vector<std::string> &vect){
|
||||||
|
std::printf("Vector of %ld elements:\n", vect.size());
|
||||||
|
int c = 0;
|
||||||
|
for (std::string s : vect){
|
||||||
|
std::printf("\t[%d] = %s\n", c, s.c_str());
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define STRINGUTILS_H
|
#define STRINGUTILS_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace StringUtils{
|
namespace StringUtils{
|
||||||
|
|
Loading…
Reference in New Issue