Periodic update of progress. #4

Merged
andrewlalis merged 5 commits from development into master 2018-03-10 11:38:21 +00:00
19 changed files with 1218 additions and 65 deletions

View File

@ -25,7 +25,9 @@ SOURCES += model/recipe/instruction.cpp \
SQLite/sqlite3.c \
model/database/resulttable.cpp \
model/database/recipedatabase.cpp \
utils/fileutils.cpp
utils/fileutils.cpp \
gui/newrecipedialog.cpp \
model/recipe/tags/taglistmodel.cpp
HEADERS += model/recipe/instruction.h \
model/recipe/recipe.h \
@ -40,11 +42,14 @@ HEADERS += model/recipe/instruction.h \
SQLite/sqlite3ext.h \
model/database/resulttable.h \
model/database/recipedatabase.h \
utils/fileutils.h
utils/fileutils.h \
gui/newrecipedialog.h \
model/recipe/tags/taglistmodel.h
LIBS += -ldl \
FORMS += gui/mainwindow.ui
FORMS += gui/mainwindow.ui \
gui/newrecipedialog.ui
DISTFILES += \
.gitignore

View File

@ -109,12 +109,25 @@
</property>
<property name="font">
<font>
<family>Source Sans Pro Light</family>
<family>Noto Sans CJK KR Light</family>
<pointsize>20</pointsize>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(83, 75, 255);</string>
<string notr="true">QPushButton#newButton {
background-color: rgb(235, 235, 255);
border: 0px;
}
QPushButton#newButton:hover{
background-color: rgb(245, 245, 255);
}
QPushButton#newButton:pressed{
background-color: rgb(255, 255, 255);
}</string>
</property>
<property name="text">
<string>New</string>
@ -134,12 +147,22 @@
</property>
<property name="font">
<font>
<family>Source Sans Pro Light</family>
<family>Noto Sans CJK KR Light</family>
<pointsize>20</pointsize>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(112, 105, 255);</string>
<string notr="true">QPushButton#openButton {
background-color: rgb(222, 226, 255);
border: 0px;
}
QPushButton#openButton:hover{
background-color: rgb(232, 236, 255);
}
QPushButton#openButton:pressed{
background-color: rgb(255, 255, 255);
}</string>
</property>
<property name="text">
<string>Open</string>
@ -156,16 +179,32 @@
</property>
<property name="font">
<font>
<family>Source Sans Pro Light</family>
<family>Noto Sans CJK KR Light</family>
<pointsize>20</pointsize>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(137, 131, 255);</string>
<string notr="true">QPushButton#browseButton {
background-color: rgb(215, 215, 255);
border: 0px;
}
QPushButton#browseButton:hover{
background-color: rgb(225, 225, 255);
}
QPushButton#browseButton:pressed{
background-color: rgb(255, 255, 255);
}</string>
</property>
<property name="text">
<string>Browse</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
@ -214,8 +253,13 @@
</property>
<property name="font">
<font>
<family>Source Sans Pro Light</family>
<family>Noto Sans CJK KR Light</family>
<pointsize>24</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
<stylestrategy>PreferAntialias</stylestrategy>
<kerning>true</kerning>
</font>
</property>
<property name="styleSheet">
@ -299,7 +343,7 @@
</property>
<property name="font">
<font>
<family>Source Sans Pro Light</family>
<family>Noto Sans CJK KR Thin</family>
<pointsize>18</pointsize>
</font>
</property>
@ -324,8 +368,9 @@
</property>
<property name="font">
<font>
<family>Source Sans Pro Light</family>
<pointsize>16</pointsize>
<family>Noto Sans CJK KR Light</family>
<pointsize>12</pointsize>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="styleSheet">
@ -343,6 +388,9 @@
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="isWrapping" stdset="0">
<bool>true</bool>
</property>
@ -397,7 +445,7 @@
</property>
<property name="font">
<font>
<family>Source Sans Pro Light</family>
<family>Noto Sans CJK KR Thin</family>
<pointsize>18</pointsize>
</font>
</property>
@ -414,6 +462,12 @@
</item>
<item>
<widget class="QTextEdit" name="instructionsTextEdit">
<property name="font">
<font>
<family>Noto Sans CJK KR Medium</family>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(244, 244, 244);</string>
</property>
@ -445,11 +499,11 @@
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#00ff40;&quot;&gt;This is some &lt;/span&gt;&lt;span style=&quot; font-size:16pt; color:#a33c3e;&quot;&gt;colored text and &lt;/span&gt;&lt;a href=&quot;https://www.google.com&quot;&gt;&lt;span style=&quot; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;link&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Noto Sans CJK KR Medium'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; color:#00ff40;&quot;&gt;This is some &lt;/span&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:16pt; color:#a33c3e;&quot;&gt;colored text and &lt;/span&gt;&lt;a href=&quot;https://www.google.com&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; text-decoration: underline; color:#0000ff;&quot;&gt;link&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse</set>
<set>Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>

103
gui/newrecipedialog.cpp Normal file
View File

@ -0,0 +1,103 @@
#include "newrecipedialog.h"
#include "ui_newrecipedialog.h"
NewRecipeDialog::NewRecipeDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::NewRecipeDialog){
ui->setupUi(this);
setModal(true);
ui->ingredientsListView->setModel(&this->ingredientListModel);
ui->tagsListView->setModel(&this->tagsListModel);
}
NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, QWidget *parent) : NewRecipeDialog(parent){
this->recipeDB = db;
this->populateIngredientsBox();
this->populateUnitsBox();
this->populateTagsBox();
}
NewRecipeDialog::~NewRecipeDialog(){
delete ui;
}
Recipe NewRecipeDialog::getRecipe(){
Recipe r(ui->recipeNameEdit->text().toStdString(),
this->ingredientListModel.getIngredients(),
ui->instructionsTextEdit->toHtml().toStdString(),
QImage(),//Image
this->tagsListModel.getTags(),//Tags
QDate::currentDate(),
ui->prepTimeEdit->time(),
ui->cookTimeEdit->time(),
(float)ui->servingsSpinBox->value());
}
bool NewRecipeDialog::isAccepted() const{
return this->accepted;
}
void NewRecipeDialog::populateIngredientsBox(){
this->ingredients = this->recipeDB->retrieveAllIngredients();
ui->ingredientNameBox->clear();
for (unsigned int i = 0; i < this->ingredients.size(); i++){
QString s = QString::fromStdString(this->ingredients[i].getName());
ui->ingredientNameBox->insertItem(i, s);
}
}
void NewRecipeDialog::populateUnitsBox(){
this->units = this->recipeDB->retrieveAllUnitsOfMeasure();
ui->unitComboBox->clear();
for (unsigned int i = 0; i < this->units.size(); i++){
QString s = QString::fromStdString(this->units[i].getName());
ui->unitComboBox->insertItem(i, s);
}
}
void NewRecipeDialog::populateTagsBox(){
this->tags = this->recipeDB->retrieveAllTags();
ui->tagsComboBox->clear();
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_addIngredientButton_clicked(){
//Construct a recipe ingredient from the supplied data.
Ingredient i = this->ingredients[ui->ingredientNameBox->currentIndex()];
UnitOfMeasure u = this->units[ui->unitComboBox->currentIndex()];
RecipeIngredient ri(i, ui->quantitySpinBox->value(), u, ui->commentsLineEdit->text().toStdString());
this->ingredientListModel.addIngredient(ri);
}
void NewRecipeDialog::on_italicsButton_clicked(){
ui->instructionsTextEdit->setFontItalic(ui->italicsButton->isChecked());
}
void NewRecipeDialog::on_boldButton_clicked(){
if (ui->boldButton->isChecked()){
ui->instructionsTextEdit->setFontWeight(QFont::Bold);
} else {
ui->instructionsTextEdit->setFontWeight(QFont::Normal);
}
}
void NewRecipeDialog::on_buttonBox_accepted(){
this->accepted = true;
this->close();
}
void NewRecipeDialog::on_buttonBox_rejected(){
this->close();
}
void NewRecipeDialog::on_addTagButton_clicked(){
//Add a tag to the list of those prepared to be added.
this->tagsListModel.addTag(this->tags[ui->tagsComboBox->currentIndex()]);
}

55
gui/newrecipedialog.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef NEWRECIPEDIALOG_H
#define NEWRECIPEDIALOG_H
#include <QDialog>
#include <QTextCharFormat>
#include "model/database/recipedatabase.h"
#include "model/recipe/ingredients/ingredientlistmodel.h"
#include "model/recipe/tags/taglistmodel.h"
namespace Ui {
class NewRecipeDialog;
}
class NewRecipeDialog : public QDialog
{
Q_OBJECT
public:
explicit NewRecipeDialog(QWidget *parent = 0);
NewRecipeDialog(RecipeDatabase *db, QWidget *parent = 0);
~NewRecipeDialog();
Recipe getRecipe();
bool isAccepted() const;
private slots:
void on_addIngredientButton_clicked();
void on_italicsButton_clicked();
void on_boldButton_clicked();
void on_buttonBox_accepted();
void on_buttonBox_rejected();
void on_addTagButton_clicked();
private:
Ui::NewRecipeDialog *ui;
RecipeDatabase *recipeDB;
vector<Ingredient> ingredients;
vector<UnitOfMeasure> units;
vector<RecipeTag> tags;
IngredientListModel ingredientListModel;
TagListModel tagsListModel;
bool accepted = false;
//Helper functions to fill fields.
void populateIngredientsBox();
void populateUnitsBox();
void populateTagsBox();
};
#endif // NEWRECIPEDIALOG_H

685
gui/newrecipedialog.ui Normal file
View File

@ -0,0 +1,685 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewRecipeDialog</class>
<widget class="QDialog" name="NewRecipeDialog">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>689</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>New Recipe</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<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::AlignTop">
<widget class="QWidget" name="mainContentPanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="tagsAndBasicPanel" 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="QWidget" name="basicRecipePanel" native="true">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(234, 235, 255);</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QWidget" name="recipeNamePanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QLabel" name="recipeNameLabel">
<property name="font">
<font>
<family>Noto Sans CJK KR</family>
<pointsize>14</pointsize>
<weight>50</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>
<widget class="QLineEdit" name="recipeNameEdit">
<property name="font">
<font>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>Recipe Name</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="basicInfoPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="prepTimePanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Prep Time</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTimeEdit" name="prepTimeEdit">
<property name="dateTime">
<datetime>
<hour>0</hour>
<minute>0</minute>
<second>0</second>
<year>1999</year>
<month>12</month>
<day>27</day>
</datetime>
</property>
<property name="currentSection">
<enum>QDateTimeEdit::HourSection</enum>
</property>
<property name="displayFormat">
<string>hh:mm:ss</string>
</property>
<property name="timeSpec">
<enum>Qt::UTC</enum>
</property>
<property name="time">
<time>
<hour>0</hour>
<minute>0</minute>
<second>0</second>
</time>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="cookTimePanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Cook Time</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QTimeEdit" name="cookTimeEdit">
<property name="currentSection">
<enum>QDateTimeEdit::HourSection</enum>
</property>
<property name="displayFormat">
<string>hh:mm:ss</string>
</property>
<property name="timeSpec">
<enum>Qt::UTC</enum>
</property>
<property name="time">
<time>
<hour>0</hour>
<minute>0</minute>
<second>0</second>
</time>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="servingsWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Servings</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="servingsSpinBox">
<property name="decimals">
<number>1</number>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="tagsPanel" native="true">
<property name="styleSheet">
<string notr="true">background-color: rgb(222, 226, 255);</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item alignment="Qt::AlignTop">
<widget class="QLabel" name="tagsPanelLabel">
<property name="text">
<string>Tags</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="newTagBoxPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="tagsComboBox"/>
</item>
<item>
<widget class="QPushButton" name="newTagButton">
<property name="text">
<string>New</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="tagsListControlPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<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="QPushButton" name="addTagButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteTagButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QListView" name="tagsListView">
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="ingredientsPanel" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(245, 245, 255);</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</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="ingredientsPanelLabel">
<property name="text">
<string>Ingredients</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="ingredientsSubPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<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">
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>5</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="addIngredientLabel">
<property name="text">
<string>Add Ingredient</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="ingredientNamePanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="ingredientNameBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentText">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="newIngredientButton">
<property name="text">
<string>New</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="quantityPanel" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>36</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>2</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="amountLabel">
<property name="font">
<font>
<family>Noto Sans CJK KR</family>
<pointsize>14</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Amount</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="quantitySpinBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="unitComboBox"/>
</item>
<item>
<widget class="QPushButton" name="newUnitButton">
<property name="text">
<string>New</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLineEdit" name="commentsLineEdit">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="frame">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>Comments</string>
</property>
<property name="clearButtonEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="ingredientsListControlPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<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="QPushButton" name="addIngredientButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteIngredientButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="instructionsPanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="instructionsLabel">
<property name="text">
<string>Instructions</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item alignment="Qt::AlignLeft|Qt::AlignTop">
<widget class="QWidget" name="textControlPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QToolButton" name="italicsButton">
<property name="font">
<font>
<family>Liberation Serif</family>
<pointsize>12</pointsize>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>I</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="boldButton">
<property name="font">
<font>
<family>Liberation Serif</family>
<pointsize>12</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>B</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="autoRaise">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QTextEdit" name="instructionsTextEdit">
<property name="placeholderText">
<string>Enter instructions here.</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,4 +1,5 @@
#include "userInterface/mainwindow.h"
#include "gui/newrecipedialog.h"
#include <QApplication>
#include "model/database/database.h"
@ -13,27 +14,42 @@ int main(int argc, char *argv[])
//TESTING CODE
RecipeDatabase recipeDB("recipes");
// recipeDB.storeIngredient(Ingredient("Apple", "Fruit"));
// recipeDB.storeIngredient(Ingredient("Corn", "Vegetable"));
// recipeDB.storeIngredient(Ingredient("Lettuce", "Vegetable"));
// recipeDB.storeIngredient(Ingredient("Carrot", "Vegetable"));
// recipeDB.executeSQL("SELECT * FROM ingredient;").printData();
//TESTING CODE
vector<RecipeIngredient> ri;
ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c")));
ri.push_back(RecipeIngredient("Baking Powder", "Additives", 1.0f, UnitOfMeasure("Teaspoon", "Teaspoons", "Tsp")));
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", ri, Instruction("<b>BOLD</b><i>iTaLiCs</i>"), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(0, 30), QTime(0, 25), 10.0f);
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);
bool success = recipeDB.storeRecipe(rec);
printf("Storage successful: %d\n", success);
recipeDB.storeUnitOfMeasure(UnitOfMeasure("tablespoon", "tablespoons", "tbsp", UnitOfMeasure::VOLUME, 1.0));
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");
reloadRec.print();
w.loadFromRecipe(reloadRec);
NewRecipeDialog d(&recipeDB);
d.show();
d.exec();
if (d.isAccepted()){
printf("Accepted the dialog.\n");
}
return a.exec();
}

View File

@ -42,7 +42,7 @@ ResultTable Database::selectFrom(string tableName, string columnNames, string co
if (columnNames.size() == 0 || tableName.empty()){
return ResultTable();
}
string query = "SELECT " + columnNames + " FROM " + tableName + " WHERE " + conditions + ";";
string query = "SELECT " + columnNames + " FROM " + tableName + " " + conditions + ";";
return this->executeSQL(query);
}
@ -81,8 +81,7 @@ bool Database::tableExists(string tableName){
if (tableName.empty() || this->db == NULL || !this->dbIsOpen){
return false;
}
ResultTable t = this->selectFrom("sqlite_master", "name", "type='table' AND name='"+tableName+"'");
//ResultTable t = executeSQL("SELECT name FROM sqlite_master WHERE type='table' AND name='"+tableName+"';");
ResultTable t = this->selectFrom("sqlite_master", "name", "WHERE type='table' AND name='"+tableName+"'");
return !t.isEmpty();
}

View File

@ -5,9 +5,9 @@ RecipeDatabase::RecipeDatabase(string filename) : Database(filename){
}
bool RecipeDatabase::storeRecipe(Recipe recipe){
///TODO: Implement this in a smart way using transaction.
//Store a recipe, if it doesn't already exist. This first tries to create the recipe entry, then all subsequent supporting table entries.
this->executeSQL("BEGIN;");
ResultTable t = this->selectFrom("recipe", "*", "name="+surroundString(recipe.getName(), "'"));
ResultTable t = this->selectFrom("recipe", "*", "WHERE name="+surroundString(recipe.getName(), "'"));
if (!t.isEmpty()){
fprintf(stderr, "Error storing recipe: Recipe with name %s already exists.\n", recipe.getName().c_str());
} else {
@ -50,17 +50,11 @@ bool RecipeDatabase::storeRecipe(Recipe recipe){
}
bool RecipeDatabase::storeRecipeIngredient(RecipeIngredient ri, int recipeId){
//First check if the base ingredient has been added to the database. This is done within storeIngredient().
ResultTable t = this->selectFrom("ingredient", "ingredientId", "name="+surroundString(ri.getName(), "'"));
int ingId = 0;
if (t.isEmpty()){
if (!this->insertInto("ingredient", vector<string>({"foodGroup", "name"}), vector<string>({ri.getFoodGroup(), ri.getName()}))){
return false;
}
ingId = this->getLastInsertedRowId();
} else {
ingId = std::stoi(t.valueAt(0, 0));
}
int ingId = this->storeIngredient(ri);
if (ingId < 0) return false;
if (!this->storeUnitOfMeasure(ri.getUnit())) return false;
return this->insertInto("recipeIngredient",
vector<string>({
"ingredientId",
@ -78,11 +72,41 @@ bool RecipeDatabase::storeRecipeIngredient(RecipeIngredient ri, int recipeId){
}));
}
void RecipeDatabase::storeIngredient(Ingredient ingredient){
ResultTable t = this->selectFrom("ingredient", "*", "name="+surroundString(ingredient.getName(), "'"));
int RecipeDatabase::storeIngredient(Ingredient ingredient){
ResultTable t = this->selectFrom("ingredient", "*", "WHERE name="+surroundString(ingredient.getName(), "'"));
if (t.isEmpty()){
this->insertInto("ingredient", vector<string>({"foodGroup", "name"}), vector<string>({ingredient.getFoodGroup(), ingredient.getName()}));
bool success = this->insertInto("ingredient", vector<string>({"foodGroup", "name"}), vector<string>({ingredient.getFoodGroup(), ingredient.getName()}));
if (success){
return this->getLastInsertedRowId();
} else {
return -1;
}
} else {
return std::stoi(t.valueAt(0, 0));
}
}
bool RecipeDatabase::storeUnitOfMeasure(UnitOfMeasure u){
ResultTable t = this->selectFrom("unitOfMeasure", "name", "WHERE name="+surroundString(u.getName(), "'"));
if (!t.isEmpty()){
return true;
}
bool success = this->insertInto("unitOfMeasure",
vector<string>({
"name",
"plural",
"abbreviation",
"type",
"metricCoefficient"
}),
vector<string>({
u.getName(),
u.getNamePlural(),
u.getAbbreviation(),
std::to_string(u.getType()),
std::to_string(u.getMetricCoefficient())
}));
return success;
}
bool RecipeDatabase::storeInstruction(Instruction instruction, int recipeId){
@ -112,12 +136,11 @@ bool RecipeDatabase::storeTags(vector<RecipeTag> tags, int recipeId){
}
Recipe RecipeDatabase::retrieveRecipe(string name){
ResultTable t = this->selectFrom("recipe", "*", "name="+surroundString(name, "'"));
ResultTable t = this->selectFrom("recipe", "*", "WHERE name="+surroundString(name, "'"));
if (t.isEmpty()){
fprintf(stderr, "Error: No recipe with name %s found!\n", name.c_str());
return Recipe();
}
t.printData();
Recipe r;
int id = std::stoi(t.valueAt(0, 0));
r.setName(t.valueAt(0, 1));
@ -128,24 +151,78 @@ Recipe RecipeDatabase::retrieveRecipe(string name){
r.setInstruction(FileUtils::loadInstruction(id));
r.setImage(FileUtils::loadImage(id));
r.setIngredients(this->retrieveRecipeIngredients(id));
r.setTags(this->retrieveTags(id));
return r;
}
vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
ResultTable t = this->executeSQL("SELECT ingredient.name, ingredient.foodGroup, recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment "
ResultTable t = this->executeSQL("SELECT ingredient.name, ingredient.foodGroup, "//0, 1
"recipeIngredient.quantity, recipeIngredient.unitName, recipeIngredient.comment,"//2, 3, 4
"unitOfMeasure.name, unitOfMeasure.plural, unitOfMeasure.abbreviation, unitOfMeasure.type, unitOfMeasure.metricCoefficient "//5, 6, 7, 8, 9
"FROM ingredient "
"INNER JOIN recipeIngredient "
"ON ingredient.ingredientId = recipeIngredient.ingredientId "
"AND recipeIngredient.recipeId = "+std::to_string(recipeId)+";");
t.printData();
"INNER JOIN unitOfMeasure "
"ON recipeIngredient.unitName = unitOfMeasure.name "
"WHERE recipeIngredient.recipeId = "+std::to_string(recipeId)+";");
vector<RecipeIngredient> ings;
for (unsigned int row = 0; row < t.rowCount(); row++){
RecipeIngredient r(t.valueAt(row, 0), t.valueAt(row, 1), std::stof(t.valueAt(row, 2)), UnitOfMeasure(t.valueAt(row, 3)));
RecipeIngredient r(t.valueAt(row, 0),
t.valueAt(row, 1),
std::stof(t.valueAt(row, 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))),
t.valueAt(row, 4));
ings.push_back(r);
}
return ings;
}
vector<Ingredient> RecipeDatabase::retrieveAllIngredients(){
ResultTable t = this->selectFrom("ingredient", "*", "ORDER BY name");
vector<Ingredient> ings;
for (unsigned int row = 0; row < t.rowCount(); row++){
Ingredient i(t.valueAt(row, 2), t.valueAt(row, 1));
ings.push_back(i);
}
return ings;
}
vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
ResultTable t = this->selectFrom("unitOfMeasure", "*", "ORDER BY name");
vector<UnitOfMeasure> units;
if (!t.isEmpty()){
for (unsigned int row = 0; row < t.rowCount(); row++){
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)));
units.push_back(u);
}
}
return units;
}
vector<RecipeTag> RecipeDatabase::retrieveTags(int recipeId){
ResultTable t = this->selectFrom("recipeTag", "tagName", "WHERE recipeId="+std::to_string(recipeId));
vector<RecipeTag> tags;
if (!t.isEmpty()){
for (unsigned int row = 0; row < t.rowCount(); row++){
RecipeTag tag(t.valueAt(row, 0));
tags.push_back(tag);
}
}
return tags;
}
vector<RecipeTag> RecipeDatabase::retrieveAllTags(){
ResultTable t = this->selectFrom("recipeTag", "tagName", "ORDER BY tagName");
vector<RecipeTag> tags;
if (!t.isEmpty()){
for (unsigned int row = 0; row < t.rowCount(); row++){
RecipeTag tag(t.valueAt(row, 0));
tags.push_back(tag);
}
}
return tags;
}
void RecipeDatabase::ensureTablesExist(){
//Make sure that foreign keys are enabled.
this->executeSQL("PRAGMA foreign_keys = ON;");
@ -156,6 +233,13 @@ void RecipeDatabase::ensureTablesExist(){
"ingredientId INTEGER PRIMARY KEY,"
"foodGroup varchar,"
"name varchar UNIQUE);");
//Unit of Measure table.
this->executeSQL("CREATE TABLE IF NOT EXISTS unitOfMeasure("
"name varchar UNIQUE PRIMARY KEY,"
"plural varchar,"
"abbreviation varchar,"
"type int,"
"metricCoefficient real);");
//Recipe table. Each recipe can have at most one instruction, and one image.
this->executeSQL("CREATE TABLE IF NOT EXISTS recipe("
"recipeId INTEGER PRIMARY KEY,"
@ -177,6 +261,7 @@ void RecipeDatabase::ensureTablesExist(){
"unitName varchar,"
"comment varchar,"
"FOREIGN KEY (ingredientId) REFERENCES ingredient(ingredientId),"
"FOREIGN KEY (recipeId) REFERENCES recipe(recipeId));");
"FOREIGN KEY (recipeId) REFERENCES recipe(recipeId),"
"FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name));");
this->executeSQL("COMMIT;");
}

View File

@ -22,14 +22,21 @@ class RecipeDatabase : public Database
bool storeRecipe(Recipe recipe);
//SQL Helper methods.
//Storage.
bool storeRecipeIngredient(RecipeIngredient ri, int recipeId);
void storeIngredient(Ingredient ingredient);
int storeIngredient(Ingredient ingredient);
bool storeUnitOfMeasure(UnitOfMeasure u);
bool storeInstruction(Instruction instruction, int recipeId);
bool storeImage(QImage image, int recipeId);
bool storeTags(vector<RecipeTag> tags, int recipeId);
//Retrieval.
Recipe retrieveRecipe(string name);
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
vector<Ingredient> retrieveAllIngredients();
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
vector<RecipeTag> retrieveTags(int recipeId);
vector<RecipeTag> retrieveAllTags();
private:
//Utility methods.

View File

@ -10,10 +10,23 @@ int IngredientListModel::rowCount(const QModelIndex &parent) const{
QVariant IngredientListModel::data(const QModelIndex &index, int role) const{
int row = index.row();
RecipeIngredient i = this->ingredients[row];
string displayStr;
if (std::ceil(i.getQuantity()) == i.getQuantity()){
//The quantity is an integer and should be casted.
displayStr += std::to_string((int)i.getQuantity());
} else {
float q = i.getQuantity();
displayStr += toString(q);
}
displayStr += " " + i.getUnit().getAbbreviation() + " " + i.getName();
switch(role){
case Qt::DisplayRole:
return QString::fromStdString(ingredients[row].getName());
return QString::fromStdString(displayStr);
}
return QVariant();
@ -25,3 +38,35 @@ void IngredientListModel::setIngredients(vector<RecipeIngredient> ingredients){
QModelIndex bottomIndex = createIndex(ingredients.size()-1, 0);
emit dataChanged(index, bottomIndex);
}
bool IngredientListModel::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;
}
vector<RecipeIngredient> IngredientListModel::getIngredients(){
return this->ingredients;
}
string toString(float val){
float decimal = std::fmod(val, 1.0f);
int places = 1;
while (std::fmod(decimal * 10, 1.0f) > 0){
decimal *= 10;
places++;
}
char buffer[50];
string arg = "%."+std::to_string(places)+"f";
sprintf(buffer, arg.c_str(), val);
string s = buffer;
return s;
}

View File

@ -17,9 +17,16 @@ public:
//Custom methods to handle ingredient data.
void setIngredients(vector<RecipeIngredient> ingredients);
bool addIngredient(RecipeIngredient ri);
vector<RecipeIngredient> getIngredients();
private:
vector<RecipeIngredient> ingredients;
//Helper for printing.
};
string toString(float val);
#endif // INGREDIENTLISTMODEL_H

View File

@ -1,15 +1,17 @@
#include "model/recipe/ingredients/recipeingredient.h"
RecipeIngredient::RecipeIngredient(string name, string foodGroup, float quantity, UnitOfMeasure unit) : Ingredient(name, foodGroup){
RecipeIngredient::RecipeIngredient(string name, string foodGroup, float quantity, UnitOfMeasure unit, string comment) : Ingredient(name, foodGroup){
setQuantity(quantity);
setUnit(unit);
setComment(comment);
}
RecipeIngredient::RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure unit){
RecipeIngredient::RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure unit, string comment){
setName(i.getName());
setFoodGroup(i.getFoodGroup());
setQuantity(quantity);
setUnit(unit);
setComment(comment);
}
RecipeIngredient::RecipeIngredient(){

View File

@ -16,9 +16,9 @@ class RecipeIngredient : public Ingredient
{
public:
//Constructor for new RecipeIngredient without starting child ingredient.
RecipeIngredient(string name, string foodGroup, float quantity, UnitOfMeasure unit);
RecipeIngredient(string name, string foodGroup, float quantity, UnitOfMeasure unit, string comment);
//Constructor using data from a child ingredient.
RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure unit);
RecipeIngredient(Ingredient i, float quantity, UnitOfMeasure unit, string comment);
RecipeIngredient();
//Getters

View File

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

View File

@ -12,8 +12,14 @@ using namespace std;
class UnitOfMeasure
{
public:
//Constants Declarations.
static const int MASS = 1;
static const int VOLUME = 2;
static const int LENGTH = 3;
static const int MISC = 4;
//Full constructor.
UnitOfMeasure(string name, string plural, string abbreviation);
UnitOfMeasure(string name, string plural, string abbreviation, int type, double coef);
//Attempt to guess unit from just a string.
UnitOfMeasure(string name);
//Constructor with default values.
@ -23,10 +29,14 @@ public:
string getName() const;
string getNamePlural() const;
string getAbbreviation() const;
int getType() const;
double getMetricCoefficient() const;
private:
string name; //The name of the unit of measure.
string plural; //The plural name.
string abbreviation; //A short version of the unit.
int type; //The type of unit, as one of the constants above.
double metricCoefficient; //The conversion from this unit to the standard metric unit.
};
#endif // UNITOFMEASURE_H

View File

@ -8,7 +8,7 @@ RecipeTag::RecipeTag(string val){
this->value = val;
}
string RecipeTag::getValue(){
string RecipeTag::getValue() const{
return this->value;
}

View File

@ -16,7 +16,7 @@ public:
RecipeTag(string val);
//Getters
string getValue();
string getValue() const;
//Setters
void setValue(string newValue);
private:

View File

@ -0,0 +1,44 @@
#include "taglistmodel.h"
TagListModel::TagListModel(){
}
int TagListModel::rowCount(const QModelIndex &parent) const{
return this->tags.size();
}
QVariant TagListModel::data(const QModelIndex &index, int role) const{
string displayString = this->tags[index.row()].getValue();
switch(role){
case Qt::DisplayRole:
return QString::fromStdString(displayString);
}
return QVariant();
}
void TagListModel::setTags(vector<RecipeTag> tags){
this->tags = tags;
QModelIndex index = createIndex(0, 0);
QModelIndex bottomIndex = createIndex(this->tags.size()-1, 0);
emit dataChanged(index, bottomIndex);
}
bool TagListModel::addTag(RecipeTag tag){
//Add only if it's different.
for (unsigned int i = 0; i < this->tags.size(); i++){
if (!this->tags[i].getValue().compare(tag.getValue())){
return false;
}
}
this->tags.push_back(tag);
QModelIndex index = createIndex(this->tags.size()-1, 0);
QModelIndex bottomIndex = createIndex(this->tags.size()-1, 0);
emit dataChanged(index, bottomIndex);
return true;
}
vector<RecipeTag> TagListModel::getTags(){
return this->tags;
}

View File

@ -0,0 +1,24 @@
#ifndef TAGLISTMODEL_H
#define TAGLISTMODEL_H
#include <QAbstractListModel>
#include "model/recipe/tags/recipetag.h"
class TagListModel : public QAbstractListModel
{
public:
TagListModel();
//Overridden methods.
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void setTags(vector<RecipeTag> tags);
bool addTag(RecipeTag tag);
vector<RecipeTag> getTags();
private:
vector<RecipeTag> tags;
};
#endif // TAGLISTMODEL_H