Added tags area to dialog, made it look better, and added tag model.

This commit is contained in:
Andrew Lalis 2018-03-10 12:36:14 +01:00
parent 61711323cc
commit cb3be5e1e2
12 changed files with 516 additions and 130 deletions

View File

@ -26,7 +26,8 @@ SOURCES += model/recipe/instruction.cpp \
model/database/resulttable.cpp \ model/database/resulttable.cpp \
model/database/recipedatabase.cpp \ model/database/recipedatabase.cpp \
utils/fileutils.cpp \ utils/fileutils.cpp \
gui/newrecipedialog.cpp gui/newrecipedialog.cpp \
model/recipe/tags/taglistmodel.cpp
HEADERS += model/recipe/instruction.h \ HEADERS += model/recipe/instruction.h \
model/recipe/recipe.h \ model/recipe/recipe.h \
@ -42,7 +43,8 @@ HEADERS += model/recipe/instruction.h \
model/database/resulttable.h \ model/database/resulttable.h \
model/database/recipedatabase.h \ model/database/recipedatabase.h \
utils/fileutils.h \ utils/fileutils.h \
gui/newrecipedialog.h gui/newrecipedialog.h \
model/recipe/tags/taglistmodel.h
LIBS += -ldl \ LIBS += -ldl \

View File

@ -6,7 +6,10 @@ NewRecipeDialog::NewRecipeDialog(QWidget *parent) :
ui(new Ui::NewRecipeDialog){ ui(new Ui::NewRecipeDialog){
ui->setupUi(this); ui->setupUi(this);
setModal(true);
ui->ingredientsListView->setModel(&this->ingredientListModel); ui->ingredientsListView->setModel(&this->ingredientListModel);
ui->tagsListView->setModel(&this->tagsListModel);
} }
NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, QWidget *parent) : NewRecipeDialog(parent){ NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, QWidget *parent) : NewRecipeDialog(parent){
@ -15,12 +18,29 @@ NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, QWidget *parent) : NewRecip
this->populateIngredientsBox(); this->populateIngredientsBox();
this->populateUnitsBox(); this->populateUnitsBox();
this->populateTagsBox();
} }
NewRecipeDialog::~NewRecipeDialog(){ NewRecipeDialog::~NewRecipeDialog(){
delete ui; 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(){ void NewRecipeDialog::populateIngredientsBox(){
this->ingredients = this->recipeDB->retrieveAllIngredients(); this->ingredients = this->recipeDB->retrieveAllIngredients();
ui->ingredientNameBox->clear(); ui->ingredientNameBox->clear();
@ -39,6 +59,15 @@ void NewRecipeDialog::populateUnitsBox(){
} }
} }
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(){ void NewRecipeDialog::on_addIngredientButton_clicked(){
//Construct a recipe ingredient from the supplied data. //Construct a recipe ingredient from the supplied data.
Ingredient i = this->ingredients[ui->ingredientNameBox->currentIndex()]; Ingredient i = this->ingredients[ui->ingredientNameBox->currentIndex()];
@ -58,3 +87,17 @@ void NewRecipeDialog::on_boldButton_clicked(){
ui->instructionsTextEdit->setFontWeight(QFont::Normal); 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()]);
}

View File

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

View File

@ -23,9 +23,66 @@
<string>New Recipe</string> <string>New Recipe</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <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"> <item alignment="Qt::AlignTop">
<widget class="QWidget" name="mainContentPanel" native="true"> <widget class="QWidget" name="mainContentPanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2"> <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> <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">
@ -50,6 +107,11 @@
</item> </item>
<item> <item>
<widget class="QLineEdit" name="recipeNameEdit"> <widget class="QLineEdit" name="recipeNameEdit">
<property name="font">
<font>
<stylestrategy>PreferAntialias</stylestrategy>
</font>
</property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignCenter</set> <set>Qt::AlignCenter</set>
</property> </property>
@ -175,6 +237,104 @@
</layout> </layout>
</widget> </widget>
</item> </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"> <item alignment="Qt::AlignTop">
<widget class="QWidget" name="ingredientsPanel" native="true"> <widget class="QWidget" name="ingredientsPanel" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
@ -183,10 +343,28 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="styleSheet">
<string notr="true">background-color: rgb(245, 245, 255);</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6"> <layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum> <enum>QLayout::SetMaximumSize</enum>
</property> </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> <item>
<widget class="QLabel" name="ingredientsPanelLabel"> <widget class="QLabel" name="ingredientsPanelLabel">
<property name="text"> <property name="text">
@ -200,14 +378,20 @@
<item> <item>
<widget class="QWidget" name="ingredientsSubPanel" native="true"> <widget class="QWidget" name="ingredientsSubPanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item alignment="Qt::AlignLeft"> <item>
<widget class="QListView" name="ingredientsListView"> <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"> <property name="batchSize">
<number>100</number> <number>100</number>
</property> </property>
</widget> </widget>
</item> </item>
<item alignment="Qt::AlignTop"> <item alignment="Qt::AlignRight|Qt::AlignTop">
<widget class="QWidget" name="addIngredientPanel" native="true"> <widget class="QWidget" name="addIngredientPanel" native="true">
<layout class="QVBoxLayout" name="verticalLayout_7"> <layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing"> <property name="spacing">
@ -239,7 +423,7 @@
<widget class="QWidget" name="ingredientNamePanel" native="true"> <widget class="QWidget" name="ingredientNamePanel" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>2</number>
</property> </property>
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
@ -286,7 +470,7 @@
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing"> <property name="spacing">
<number>0</number> <number>2</number>
</property> </property>
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
@ -367,6 +551,21 @@
</property> </property>
</widget> </widget>
</item> </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> <item>
<widget class="QPushButton" name="addIngredientButton"> <widget class="QPushButton" name="addIngredientButton">
<property name="text"> <property name="text">
@ -374,6 +573,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="deleteIngredientButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>
@ -456,6 +665,16 @@
</layout> </layout>
</widget> </widget>
</item> </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> </layout>
</widget> </widget>
</item> </item>

View File

@ -18,9 +18,18 @@ int main(int argc, char *argv[])
//TESTING CODE //TESTING CODE
vector<RecipeIngredient> ri; vector<RecipeIngredient> ri;
ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), "")); ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), ""));
ri.push_back(RecipeIngredient("baking powder", "Additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), "")); ri.push_back(RecipeIngredient("baking powder", "additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), ""));
Recipe rec("Example", 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); bool success = recipeDB.storeRecipe(rec);
printf("Storage successful: %d\n", success); printf("Storage successful: %d\n", success);
@ -38,5 +47,9 @@ int main(int argc, char *argv[])
d.show(); d.show();
d.exec(); d.exec();
if (d.isAccepted()){
printf("Accepted the dialog.\n");
}
return a.exec(); return a.exec();
} }

View File

@ -151,6 +151,7 @@ Recipe RecipeDatabase::retrieveRecipe(string name){
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));
r.setTags(this->retrieveTags(id));
return r; return r;
} }
@ -198,6 +199,30 @@ vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
return units; 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(){ void RecipeDatabase::ensureTablesExist(){
//Make sure that foreign keys are enabled. //Make sure that foreign keys are enabled.
this->executeSQL("PRAGMA foreign_keys = ON;"); this->executeSQL("PRAGMA foreign_keys = ON;");

View File

@ -35,6 +35,8 @@ class RecipeDatabase : public Database
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId); vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
vector<Ingredient> retrieveAllIngredients(); vector<Ingredient> retrieveAllIngredients();
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure(); vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
vector<RecipeTag> retrieveTags(int recipeId);
vector<RecipeTag> retrieveAllTags();
private: private:
//Utility methods. //Utility methods.

View File

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

View File

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

View File

@ -16,7 +16,7 @@ public:
RecipeTag(string val); RecipeTag(string val);
//Getters //Getters
string getValue(); string getValue() const;
//Setters //Setters
void setValue(string newValue); void setValue(string newValue);
private: 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