Merge pull request #7 from andrewlalis/development
Actually Usable Version
This commit is contained in:
commit
626fe91bb1
13
RecipeDB.pro
13
RecipeDB.pro
|
@ -14,7 +14,6 @@ TEMPLATE = app
|
|||
|
||||
SOURCES += model/recipe/instruction.cpp \
|
||||
model/recipe/recipe.cpp \
|
||||
userInterface/mainwindow.cpp \
|
||||
main.cpp \
|
||||
model/database/database.cpp \
|
||||
model/recipe/ingredients/unitofmeasure.cpp \
|
||||
|
@ -33,11 +32,12 @@ SOURCES += model/recipe/instruction.cpp \
|
|||
gui/newDialogs/newunitdialog.cpp \
|
||||
utils/aspectratiopixmaplabel.cpp \
|
||||
utils/stringutils.cpp \
|
||||
openrecipedialog.cpp
|
||||
gui/openrecipedialog.cpp \
|
||||
model/recipe/recipetablemodel.cpp \
|
||||
gui/mainwindow.cpp
|
||||
|
||||
HEADERS += model/recipe/instruction.h \
|
||||
model/recipe/recipe.h \
|
||||
userInterface/mainwindow.h \
|
||||
model/database/database.h \
|
||||
model/recipe/ingredients/unitofmeasure.h \
|
||||
model/recipe/ingredients/ingredient.h \
|
||||
|
@ -56,7 +56,9 @@ HEADERS += model/recipe/instruction.h \
|
|||
gui/newDialogs/newunitdialog.h \
|
||||
utils/aspectratiopixmaplabel.h \
|
||||
utils/stringutils.h \
|
||||
openrecipedialog.h
|
||||
gui/openrecipedialog.h \
|
||||
model/recipe/recipetablemodel.h \
|
||||
gui/mainwindow.h
|
||||
|
||||
LIBS += -ldl \
|
||||
|
||||
|
@ -65,7 +67,8 @@ FORMS += gui/mainwindow.ui \
|
|||
gui/newDialogs/newingredientdialog.ui \
|
||||
gui/newDialogs/newtagdialog.ui \
|
||||
gui/newDialogs/newunitdialog.ui \
|
||||
openrecipedialog.ui
|
||||
gui/openrecipedialog.ui \
|
||||
gui/mainwindow.ui
|
||||
|
||||
DISTFILES += \
|
||||
.gitignore
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "userInterface/mainwindow.h"
|
||||
#include "gui/mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
|
@ -58,7 +58,7 @@ void MainWindow::setCookTime(QTime cookTime){
|
|||
}
|
||||
|
||||
void MainWindow::setServings(float servings){
|
||||
ui->servingsLabel->setText(QString("Servings: ")+QString::fromStdString(StringUtils::toString(servings)));
|
||||
ui->servingsLabel->setText(QString(QString::fromStdString(StringUtils::toString(servings) + " Serving" + ((servings != 1.0f) ? "s" : ""))));
|
||||
}
|
||||
|
||||
void MainWindow::setTags(vector<RecipeTag> tags){
|
||||
|
@ -72,8 +72,22 @@ void MainWindow::on_newButton_clicked(){
|
|||
if (d.isAccepted()){
|
||||
Recipe r = d.getRecipe();
|
||||
if (!this->recipeDB->storeRecipe(r)){
|
||||
QMessageBox::critical(this, QString("Unable to Save Recipe"), QString("The program was not able to successfully save the recipe."));
|
||||
}
|
||||
QMessageBox::critical(this, QString("Unable to Save Recipe"), QString("The program was not able to successfully save the recipe. Make sure to give the recipe a name, instructions, and some ingredients!"));
|
||||
} else {
|
||||
this->loadFromRecipe(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_openButton_clicked(){
|
||||
OpenRecipeDialog d(this->recipeDB, this);
|
||||
d.show();
|
||||
d.exec();
|
||||
if (!d.getSelectedRecipe().isEmpty()){
|
||||
this->loadFromRecipe(d.getSelectedRecipe());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_exitButton_clicked(){
|
||||
this->close();
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
#include "model/recipe/recipe.h"
|
||||
#include "model/recipe/ingredients/ingredientlistmodel.h"
|
||||
#include "gui/newrecipedialog.h"
|
||||
#include "gui/openrecipedialog.h"
|
||||
#include "utils/stringutils.h"
|
||||
|
||||
using namespace std;
|
||||
|
@ -27,9 +28,14 @@ public:
|
|||
|
||||
//Loads all data from a recipe into the GUI components.
|
||||
void loadFromRecipe(Recipe recipe);
|
||||
|
||||
private slots:
|
||||
void on_newButton_clicked();
|
||||
|
||||
void on_openButton_clicked();
|
||||
|
||||
void on_exitButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
RecipeDatabase *recipeDB;
|
|
@ -143,6 +143,12 @@ QPushButton#newButton:pressed{
|
|||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QPushButton" name="openButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
|
@ -175,6 +181,9 @@ QPushButton#openButton:pressed{
|
|||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QPushButton" name="browseButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
|
@ -211,6 +220,56 @@ QPushButton#browseButton:pressed{
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="exitButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>150</horstretch>
|
||||
<verstretch>80</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Noto Sans CJK KR Light</family>
|
||||
<pointsize>20</pointsize>
|
||||
<stylestrategy>PreferAntialias</stylestrategy>
|
||||
</font>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QPushButton#exitButton {
|
||||
background-color: rgb(255, 216, 216);
|
||||
border: 0px;
|
||||
}
|
||||
QPushButton#exitButton:hover{
|
||||
background-color: rgb(255, 191, 191);
|
||||
}
|
||||
QPushButton#exitButton:pressed{
|
||||
background-color: rgb(255, 147, 147);
|
||||
}</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -367,6 +426,9 @@ font: "Noto Sans CJK KR";</string>
|
|||
<property name="text">
|
||||
<string>Prep Time:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -383,6 +445,9 @@ font: "Noto Sans CJK KR";</string>
|
|||
<property name="text">
|
||||
<string>Cook Time:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -396,6 +461,9 @@ font: "Noto Sans CJK KR";</string>
|
|||
<property name="text">
|
||||
<string>Servings:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -8,10 +8,8 @@ NewUnitDialog::NewUnitDialog(QWidget *parent) :
|
|||
ui->setupUi(this);
|
||||
|
||||
ui->typeComboBox->clear();
|
||||
ui->typeComboBox->setItemData(0, "Mass");
|
||||
ui->typeComboBox->setItemData(1, "Volume");
|
||||
ui->typeComboBox->setItemData(2, "Length");
|
||||
ui->typeComboBox->setItemData(3, "Misc");
|
||||
QStringList list({"Mass", "Volume", "Length", "Misc"});
|
||||
ui->typeComboBox->insertItems(0, list);
|
||||
|
||||
}
|
||||
|
||||
|
@ -23,7 +21,7 @@ NewUnitDialog::~NewUnitDialog()
|
|||
UnitOfMeasure NewUnitDialog::getUnit(){
|
||||
return UnitOfMeasure(ui->unitNameEdit->text().toLower().toStdString(),
|
||||
ui->pluralNameEdit->text().toLower().toStdString(),
|
||||
ui->abbreviationEdit->text().toLower().toStdString(),
|
||||
ui->abbreviationEdit->text().toStdString(),
|
||||
this->getSelectedType(),
|
||||
ui->coefficientSpinBox->value());
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ void NewRecipeDialog::on_selectImageButton_clicked(){
|
|||
}
|
||||
}
|
||||
|
||||
void NewRecipeDialog::on_deleteIngredientButton_clicked(){
|
||||
void NewRecipeDialog::on_removeIngredientButton_clicked(){
|
||||
QModelIndexList indexList = ui->ingredientsListView->selectionModel()->selectedIndexes();
|
||||
for (QModelIndexList::iterator it = indexList.begin(); it != indexList.end(); ++it){
|
||||
QModelIndex i = *it;
|
||||
|
@ -127,6 +127,22 @@ void NewRecipeDialog::on_deleteIngredientButton_clicked(){
|
|||
}
|
||||
}
|
||||
|
||||
void NewRecipeDialog::on_deleteIngredientButton_clicked(){
|
||||
int index = ui->ingredientNameBox->currentIndex();
|
||||
Ingredient ing = this->ingredients.at(index);
|
||||
QMessageBox::StandardButton reply = QMessageBox::question(this,
|
||||
QString::fromStdString("Delete Ingredient"),
|
||||
QString::fromStdString("Are you sure you want to delete the ingredient " + ing.getName() + "?"));
|
||||
if (reply == QMessageBox::Yes){
|
||||
bool success = this->recipeDB->deleteIngredient(ing.getName());
|
||||
if (!success){
|
||||
QMessageBox::critical(this, QString::fromStdString("Error"), QString::fromStdString("Unable to delete ingredient: " + ing.getName() + ", some recipes use it!"));
|
||||
} else {
|
||||
this->populateIngredientsBox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NewRecipeDialog::on_newIngredientButton_clicked(){
|
||||
NewIngredientDialog d(this);
|
||||
d.show();
|
||||
|
@ -155,12 +171,12 @@ void NewRecipeDialog::on_newTagButton_clicked(){
|
|||
}
|
||||
|
||||
void NewRecipeDialog::on_removeTagButton_clicked(){
|
||||
int index = ui->tagsComboBox->currentIndex();
|
||||
if (index < 0 || index >= this->tags.size()){
|
||||
unsigned int index = ui->tagsComboBox->currentIndex();
|
||||
if (index >= this->tags.size()){
|
||||
return;
|
||||
}
|
||||
RecipeTag tag = this->tags[ui->tagsComboBox->currentIndex()];
|
||||
string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue();
|
||||
string content = "Are you sure you wish to delete the following tag:\n"+tag.getValue()+"\nThis will delete the tag for all recipes that use it.";
|
||||
QMessageBox::StandardButton reply = QMessageBox::question(this, QString("Delete Tag"), QString(content.c_str()));
|
||||
if (reply == QMessageBox::Yes){
|
||||
this->recipeDB->deleteTag(tag);
|
||||
|
@ -173,10 +189,25 @@ void NewRecipeDialog::on_newUnitButton_clicked(){
|
|||
d.show();
|
||||
if (d.exec() == QDialog::Accepted){
|
||||
UnitOfMeasure u = d.getUnit();
|
||||
if (!this->recipeDB->storeUnitOfMeasure(u)){
|
||||
if (!this->recipeDB->storeUnitOfMeasure(u) || u.getName().empty() || u.getNamePlural().empty() || u.getAbbreviation().empty()){
|
||||
QMessageBox::critical(this, "Error", "Unable to store new unit.");
|
||||
} else {
|
||||
this->populateUnitsBox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NewRecipeDialog::on_deleteUnitButton_clicked(){
|
||||
int index = ui->unitComboBox->currentIndex();
|
||||
UnitOfMeasure unit = this->units[index];
|
||||
QMessageBox::StandardButton reply = QMessageBox::question(this,
|
||||
QString::fromStdString("Delete Unit Of Measure"),
|
||||
QString::fromStdString("Are you sure you want to delete the unit " + unit.getName() + "?"));
|
||||
if (reply == QMessageBox::Yes){
|
||||
if (!this->recipeDB->deleteUnitOfMeasure(unit.getName())){
|
||||
QMessageBox::critical(this, "Error", "Unable to delete unit. There may be recipes which still use it!");
|
||||
} else {
|
||||
this->populateUnitsBox();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ class NewRecipeDialog : public QDialog
|
|||
|
||||
void on_selectImageButton_clicked();
|
||||
|
||||
void on_removeIngredientButton_clicked();
|
||||
|
||||
void on_deleteIngredientButton_clicked();
|
||||
|
||||
void on_newIngredientButton_clicked();
|
||||
|
@ -57,6 +59,8 @@ class NewRecipeDialog : public QDialog
|
|||
|
||||
void on_newUnitButton_clicked();
|
||||
|
||||
void on_deleteUnitButton_clicked();
|
||||
|
||||
private:
|
||||
Ui::NewRecipeDialog *ui;
|
||||
RecipeDatabase *recipeDB;
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">font: 25 "Noto Sans CJK KR";</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
@ -97,9 +100,7 @@
|
|||
<widget class="QLabel" name="recipeNameLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Noto Sans CJK KR</family>
|
||||
<pointsize>14</pointsize>
|
||||
<weight>50</weight>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
|
@ -116,7 +117,9 @@
|
|||
<widget class="QLineEdit" name="recipeNameEdit">
|
||||
<property name="font">
|
||||
<font>
|
||||
<stylestrategy>PreferAntialias</stylestrategy>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
|
@ -155,7 +158,7 @@
|
|||
<second>0</second>
|
||||
<year>1999</year>
|
||||
<month>12</month>
|
||||
<day>26</day>
|
||||
<day>25</day>
|
||||
</datetime>
|
||||
</property>
|
||||
<property name="currentSection">
|
||||
|
@ -501,6 +504,17 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteIngredientButton">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -532,9 +546,7 @@
|
|||
<widget class="QLabel" name="amountLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Noto Sans CJK KR</family>
|
||||
<pointsize>14</pointsize>
|
||||
<weight>50</weight>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
|
@ -578,6 +590,17 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteUnitButton">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -626,7 +649,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="deleteIngredientButton">
|
||||
<widget class="QPushButton" name="removeIngredientButton">
|
||||
<property name="text">
|
||||
<string>Delete</string>
|
||||
</property>
|
||||
|
@ -745,9 +768,9 @@
|
|||
<widget class="QToolButton" name="italicsButton">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Serif</family>
|
||||
<pointsize>12</pointsize>
|
||||
<italic>true</italic>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
@ -765,10 +788,9 @@
|
|||
<widget class="QToolButton" name="boldButton">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Liberation Serif</family>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
<weight>3</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
#include "openrecipedialog.h"
|
||||
#include "ui_openrecipedialog.h"
|
||||
|
||||
OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::OpenRecipeDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->recipeTableView->setModel(&this->recipeTableModel);
|
||||
}
|
||||
|
||||
OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){
|
||||
this->recipeDB = recipeDB;
|
||||
this->populateRecipesTable();
|
||||
}
|
||||
|
||||
OpenRecipeDialog::~OpenRecipeDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
Recipe OpenRecipeDialog::getSelectedRecipe(){
|
||||
return this->selectedRecipe;
|
||||
}
|
||||
|
||||
void OpenRecipeDialog::populateRecipesTable(){
|
||||
this->recipeTableModel.clear();
|
||||
vector<Recipe> recipes = this->recipeDB->retrieveAllRecipes();
|
||||
this->recipeTableModel.setRecipes(recipes);
|
||||
ui->recipeTableView->resizeColumnsToContents();
|
||||
ui->recipeTableView->show();
|
||||
}
|
||||
|
||||
void OpenRecipeDialog::on_deleteRecipeButton_clicked(){
|
||||
QItemSelectionModel *selectModel = ui->recipeTableView->selectionModel();
|
||||
if (!selectModel->hasSelection()){
|
||||
return;
|
||||
}
|
||||
vector<int> rows;
|
||||
QModelIndexList indexes = selectModel->selectedIndexes();
|
||||
for (int i = 0; i < indexes.count(); i++){
|
||||
rows.push_back(indexes.at(i).row());
|
||||
}
|
||||
string recipePlural = (rows.size() == 1) ? "recipe" : "recipes";
|
||||
QString title = QString::fromStdString("Delete " + recipePlural);
|
||||
QString content = QString::fromStdString("Are you sure you wish to delete the selected "+recipePlural+"?");
|
||||
QMessageBox::StandardButton reply = QMessageBox::question(this, title, content);
|
||||
if (reply == QMessageBox::Yes){
|
||||
for (int row : rows){
|
||||
Recipe r = this->recipeTableModel.getRecipeAt(row);
|
||||
bool success = this->recipeDB->deleteRecipe(r.getName());
|
||||
if (!success){
|
||||
QMessageBox::critical(this, QString::fromStdString("Unable to Delete"), QString::fromStdString("Could not delete recipe "+r.getName()));
|
||||
}
|
||||
}
|
||||
this->populateRecipesTable();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index){
|
||||
this->selectedRecipe = this->recipeTableModel.getRecipeAt(index.row());
|
||||
this->close();
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef OPENRECIPEDIALOG_H
|
||||
#define OPENRECIPEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "model/database/recipedatabase.h"
|
||||
#include "model/recipe/recipetablemodel.h"
|
||||
|
||||
namespace Ui {
|
||||
class OpenRecipeDialog;
|
||||
}
|
||||
|
||||
class OpenRecipeDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OpenRecipeDialog(QWidget *parent = 0);
|
||||
OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent = 0);
|
||||
~OpenRecipeDialog();
|
||||
|
||||
Recipe getSelectedRecipe();
|
||||
|
||||
private slots:
|
||||
void on_deleteRecipeButton_clicked();
|
||||
|
||||
void on_recipeTableView_doubleClicked(const QModelIndex &index);
|
||||
|
||||
private:
|
||||
Ui::OpenRecipeDialog *ui;
|
||||
RecipeDatabase *recipeDB;
|
||||
RecipeTableModel recipeTableModel;
|
||||
Recipe selectedRecipe;
|
||||
|
||||
void populateRecipesTable();
|
||||
};
|
||||
|
||||
#endif // OPENRECIPEDIALOG_H
|
|
@ -0,0 +1,134 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OpenRecipeDialog</class>
|
||||
<widget class="QDialog" name="OpenRecipeDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Open Recipe</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QWidget" name="searchPanel" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="nameSearchPanel" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="nameLabel">
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="nameEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
<widget class="QPushButton" name="searchButton">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../images.qrc">
|
||||
<normaloff>:/images/images/search_icon.png</normaloff>:/images/images/search_icon.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</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>
|
||||
<widget class="QWidget" name="contentPanel" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableView" name="recipeTableView">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../images.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -4,5 +4,7 @@
|
|||
<file>images/icon.png</file>
|
||||
<file>images/plus_icon.png</file>
|
||||
<file>images/minus_icon.png</file>
|
||||
<file>images/search_icon.png</file>
|
||||
<file>images/trash.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 724 B |
56
main.cpp
56
main.cpp
|
@ -1,4 +1,4 @@
|
|||
#include "userInterface/mainwindow.h"
|
||||
#include "gui/mainwindow.h"
|
||||
#include "gui/newrecipedialog.h"
|
||||
#include <QApplication>
|
||||
|
||||
|
@ -13,42 +13,28 @@ int main(int argc, char *argv[])
|
|||
w.show();
|
||||
|
||||
//TESTING CODE
|
||||
// vector<RecipeIngredient> ri;
|
||||
// ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), ""));
|
||||
// ri.push_back(RecipeIngredient("baking powder", "additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), ""));
|
||||
vector<RecipeIngredient> ri;
|
||||
ri.push_back(RecipeIngredient("flour", "grains", 3.0f, UnitOfMeasure("cup", "cups", "c", UnitOfMeasure::VOLUME, 1.0), ""));
|
||||
ri.push_back(RecipeIngredient("baking powder", "additives", 1.0f, UnitOfMeasure("teaspoon", "teaspoons", "tsp", UnitOfMeasure::VOLUME, 1.0), ""));
|
||||
|
||||
// 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);
|
||||
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);
|
||||
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));
|
||||
//recipeDB.selectFrom("recipe", "recipeId, name", "").printData();
|
||||
w.loadFromRecipe(recipeDB.retrieveRandomRecipe());
|
||||
|
||||
// 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");
|
||||
// }
|
||||
|
||||
w.loadFromRecipe(recipeDB.retrieveRecipe("Generic Bread"));
|
||||
|
||||
return a.exec();
|
||||
a.exec();
|
||||
recipeDB.closeConnection();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,20 @@ ResultTable Database::selectFrom(string tableName, string columnNames, string co
|
|||
return this->executeSQL(query);
|
||||
}
|
||||
|
||||
bool Database::deleteFrom(string tableName, string conditions){
|
||||
if (tableName.empty()){
|
||||
return false;
|
||||
}
|
||||
string query = "DELETE FROM " + tableName + " " + conditions + ";";
|
||||
ResultTable t = this->executeSQL(query);
|
||||
if (t.getReturnCode() != SQLITE_DONE){
|
||||
fprintf(stderr, "Can't delete from table %s.Return code: %d\n%s\n", tableName.c_str(), t.getReturnCode(), sqlite3_errmsg(this->db));
|
||||
exit(EXIT_FAILURE);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void Database::openConnection(){
|
||||
this->returnCode = sqlite3_open(this->filename.c_str(), &this->db);
|
||||
if (this->returnCode || this->db == NULL){
|
||||
|
|
|
@ -26,10 +26,13 @@ public:
|
|||
ResultTable executeSQL(string statement);
|
||||
bool insertInto(string tableName, vector<string> columnNames, vector<string> values);
|
||||
ResultTable selectFrom(string tableName, string columnNames, string conditions);
|
||||
bool deleteFrom(string tableName, string conditions);
|
||||
|
||||
bool tableExists(string tableName);
|
||||
int getLastInsertedRowId();
|
||||
|
||||
void closeConnection();
|
||||
|
||||
protected:
|
||||
string surroundString(string s, string surround);
|
||||
|
||||
|
@ -43,7 +46,6 @@ private:
|
|||
char* errorMsg;
|
||||
|
||||
void openConnection();
|
||||
void closeConnection();
|
||||
std::string combineVector(std::vector<std::string> strings, std::string mid);
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,12 @@ RecipeDatabase::RecipeDatabase(string filename) : Database(filename){
|
|||
}
|
||||
|
||||
bool RecipeDatabase::storeRecipe(Recipe recipe){
|
||||
//Some primary checks to avoid garbage in the database.
|
||||
if (recipe.getName().empty() ||
|
||||
recipe.getInstruction().getHTML().empty() ||
|
||||
recipe.getIngredients().empty()){
|
||||
return false;
|
||||
}
|
||||
//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", "*", "WHERE name="+surroundString(recipe.getName(), "'"));
|
||||
|
@ -141,18 +147,25 @@ Recipe RecipeDatabase::retrieveRecipe(string name){
|
|||
fprintf(stderr, "Error: No recipe with name %s found!\n", name.c_str());
|
||||
return Recipe();
|
||||
}
|
||||
Recipe r;
|
||||
int id = std::stoi(t.valueAt(0, 0));
|
||||
r.setName(t.valueAt(0, 1));
|
||||
r.setCreatedDate(QDate::fromString(QString::fromStdString(t.valueAt(0, 2))));
|
||||
r.setPrepTime(QTime::fromString(QString::fromStdString(t.valueAt(0, 3))));
|
||||
r.setCookTime(QTime::fromString(QString::fromStdString(t.valueAt(0, 4))));
|
||||
r.setServings(std::stof(t.valueAt(0, 5)));
|
||||
r.setInstruction(FileUtils::loadInstruction(id));
|
||||
r.setImage(FileUtils::loadImage(id));
|
||||
r.setIngredients(this->retrieveRecipeIngredients(id));
|
||||
r.setTags(this->retrieveTags(id));
|
||||
return r;
|
||||
return this->readFromResultTable(t);
|
||||
}
|
||||
|
||||
Recipe RecipeDatabase::retrieveRandomRecipe(){
|
||||
ResultTable t = this->selectFrom("recipe", "*", "ORDER BY RANDOM() LIMIT 1");
|
||||
if (t.isEmpty()){
|
||||
fprintf(stderr, "Unable to find a random recipe.\n");
|
||||
return Recipe();
|
||||
}
|
||||
return this->readFromResultTable(t);
|
||||
}
|
||||
|
||||
vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
|
||||
ResultTable t = this->selectFrom("recipe", "name", "ORDER BY name");
|
||||
vector<Recipe> recipes;
|
||||
for (unsigned int row = 0; row < t.rowCount(); row++){
|
||||
recipes.push_back(this->retrieveRecipe(t.valueAt(row, 0)));
|
||||
}
|
||||
return recipes;
|
||||
}
|
||||
|
||||
vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
|
||||
|
@ -223,8 +236,57 @@ vector<RecipeTag> RecipeDatabase::retrieveAllTags(){
|
|||
return tags;
|
||||
}
|
||||
|
||||
void RecipeDatabase::deleteTag(RecipeTag tag){
|
||||
ResultTable t = this->executeSQL("DELETE FROM recipeTag WHERE tagName="+surroundString(tag.getValue(), "'"));
|
||||
bool RecipeDatabase::deleteRecipe(string name){
|
||||
ResultTable t = this->selectFrom("recipe", "recipeId", "WHERE name='"+name+"'");
|
||||
if (t.rowCount() != 1){
|
||||
return false;
|
||||
}
|
||||
string recipeId = t.valueAt(0, 0);
|
||||
return this->deleteRecipe(std::stoi(recipeId));
|
||||
}
|
||||
|
||||
bool RecipeDatabase::deleteRecipe(int recipeId){
|
||||
string idString = std::to_string(recipeId);
|
||||
if (this->selectFrom("recipe", "recipeId", "WHERE recipeId="+idString).isEmpty()){
|
||||
printf("Cannot delete. No recipe with ID %d exists.\n", recipeId);
|
||||
return false;
|
||||
}
|
||||
this->executeSQL("BEGIN;");
|
||||
bool tagsDeleted = this->deleteFrom("recipeTag", "WHERE recipeId="+idString);
|
||||
bool recipeIngredientDeleted = this->deleteFrom("recipeIngredient", "WHERE recipeId="+idString);
|
||||
bool recipeDeleted = this->deleteFrom("recipe", "WHERE recipeId="+idString);
|
||||
if (tagsDeleted && recipeIngredientDeleted && recipeDeleted){
|
||||
this->executeSQL("COMMIT;");
|
||||
return true;
|
||||
} else {
|
||||
this->executeSQL("ROLLBACK;");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool RecipeDatabase::deleteIngredient(string name){
|
||||
ResultTable t = this->executeSQL("SELECT recipeId "
|
||||
"FROM recipeIngredient "
|
||||
"INNER JOIN ingredient "
|
||||
"ON recipeIngredient.ingredientId = ingredient.ingredientId "
|
||||
"WHERE ingredient.name='"+name+"';");
|
||||
if (!t.isEmpty()){
|
||||
//There is at least one recipe dependent on the ingredient.
|
||||
return false;
|
||||
}
|
||||
return this->deleteFrom("ingredient", "WHERE name='"+name+"'");
|
||||
}
|
||||
|
||||
bool RecipeDatabase::deleteUnitOfMeasure(string name){
|
||||
ResultTable t = this->selectFrom("recipeIngredient", "recipeId", "WHERE unitName='"+name+"'");
|
||||
if (!t.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
return this->deleteFrom("unitOfMeasure", "WHERE name='"+name+"'");
|
||||
}
|
||||
|
||||
bool RecipeDatabase::deleteTag(RecipeTag tag){
|
||||
return this->deleteFrom("recipeTag", "WHERE tagName='"+tag.getValue()+"'");
|
||||
}
|
||||
|
||||
void RecipeDatabase::ensureTablesExist(){
|
||||
|
@ -269,3 +331,18 @@ void RecipeDatabase::ensureTablesExist(){
|
|||
"FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name));");
|
||||
this->executeSQL("COMMIT;");
|
||||
}
|
||||
|
||||
Recipe RecipeDatabase::readFromResultTable(ResultTable t, int row){
|
||||
Recipe r;
|
||||
int id = std::stoi(t.valueAt(row, 0));
|
||||
r.setName(t.valueAt(row, 1));
|
||||
r.setCreatedDate(QDate::fromString(QString::fromStdString(t.valueAt(row, 2))));
|
||||
r.setPrepTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 3))));
|
||||
r.setCookTime(QTime::fromString(QString::fromStdString(t.valueAt(row, 4))));
|
||||
r.setServings(std::stof(t.valueAt(row, 5)));
|
||||
r.setInstruction(FileUtils::loadInstruction(id));
|
||||
r.setImage(FileUtils::loadImage(id));
|
||||
r.setIngredients(this->retrieveRecipeIngredients(id));
|
||||
r.setTags(this->retrieveTags(id));
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ class RecipeDatabase : public Database
|
|||
|
||||
//Retrieval.
|
||||
Recipe retrieveRecipe(string name);
|
||||
Recipe retrieveRandomRecipe();
|
||||
vector<Recipe> retrieveAllRecipes();
|
||||
vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
|
||||
vector<Ingredient> retrieveAllIngredients();
|
||||
vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
|
||||
|
@ -39,11 +41,17 @@ class RecipeDatabase : public Database
|
|||
vector<RecipeTag> retrieveAllTags();
|
||||
|
||||
//Deletion.
|
||||
void deleteTag(RecipeTag tag);
|
||||
bool deleteRecipe(string name);
|
||||
bool deleteRecipe(int recipeId);
|
||||
bool deleteIngredient(string name);
|
||||
bool deleteUnitOfMeasure(string name);
|
||||
bool deleteTag(RecipeTag tag);
|
||||
private:
|
||||
|
||||
//Utility methods.
|
||||
void ensureTablesExist();
|
||||
//Read a recipe from a row of a result table.
|
||||
Recipe readFromResultTable(ResultTable t, int row=0);
|
||||
};
|
||||
|
||||
#endif // RECIPEDATABASE_H
|
||||
|
|
|
@ -50,7 +50,7 @@ string RecipeIngredient::toString(){
|
|||
result += StringUtils::toString(this->getQuantity());
|
||||
}
|
||||
result += " " + this->getUnit().getAbbreviation() + " " + this->getName();
|
||||
if (!this->getComment().empty()) result += " ~" + this->getComment();
|
||||
if (!this->getComment().empty()) result += " (" + this->getComment() + ")";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ Recipe::Recipe(string name, vector<RecipeIngredient> ingredients, Instruction in
|
|||
setServings(servings);
|
||||
}
|
||||
|
||||
Recipe::Recipe() : Recipe::Recipe("Unnamed Recipe", vector<RecipeIngredient>(), Instruction(), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(1, 0), QTime(0, 30), 10.0f){
|
||||
Recipe::Recipe() : Recipe::Recipe("", vector<RecipeIngredient>(), Instruction(), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(1, 0), QTime(0, 30), 10.0f){
|
||||
//Set default values when none are specified.
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,10 @@ float Recipe::getServings() const{
|
|||
return this->servings;
|
||||
}
|
||||
|
||||
bool Recipe::isEmpty() const{
|
||||
return this->name.empty();
|
||||
}
|
||||
|
||||
void Recipe::setName(string newName){
|
||||
this->name = newName;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ public:
|
|||
QTime getCookTime() const;
|
||||
QTime getTotalTime() const; //Derived method to add prep and cook times.
|
||||
float getServings() const;
|
||||
bool isEmpty() const;
|
||||
|
||||
//Setters
|
||||
void setName(string newName);
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
#include "recipetablemodel.h"
|
||||
|
||||
RecipeTableModel::RecipeTableModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
RecipeTableModel::RecipeTableModel(vector<Recipe> recipes){
|
||||
this->setRecipes(recipes);
|
||||
}
|
||||
|
||||
int RecipeTableModel::rowCount(const QModelIndex &parent) const{
|
||||
Q_UNUSED(parent);
|
||||
return this->recipes.size();
|
||||
}
|
||||
|
||||
int RecipeTableModel::columnCount(const QModelIndex &parent) const{
|
||||
Q_UNUSED(parent);
|
||||
return 5;//FIX THIS TO BE MORE ADAPTIVE EVENTUALLY.
|
||||
}
|
||||
|
||||
QVariant RecipeTableModel::data(const QModelIndex &index, int role) const{
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
Recipe r = this->recipes[row];
|
||||
|
||||
if (role == Qt::DisplayRole){
|
||||
switch(col){
|
||||
case 0:
|
||||
return QString::fromStdString(r.getName());
|
||||
case 1:
|
||||
return QString::fromStdString(r.getCreatedDate().toString().toStdString());
|
||||
case 2:
|
||||
return QString::fromStdString(StringUtils::toString(r.getServings()));
|
||||
case 3:
|
||||
return r.getPrepTime().toString("hh:mm:ss");
|
||||
case 4:
|
||||
return r.getCookTime().toString("hh:mm:ss");
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant RecipeTableModel::headerData(int section, Qt::Orientation orientation, int role) const{
|
||||
if (role != Qt::DisplayRole){
|
||||
return QVariant();
|
||||
}
|
||||
if (orientation == Qt::Horizontal){
|
||||
switch (section){
|
||||
case 0:
|
||||
return "Name";
|
||||
case 1:
|
||||
return "Created On";
|
||||
case 2:
|
||||
return "Servings";
|
||||
case 3:
|
||||
return "Prep Time";
|
||||
case 4:
|
||||
return "Cook Time";
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
} else if (orientation == Qt::Vertical){
|
||||
return QString::fromStdString(std::to_string(section));
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void RecipeTableModel::setRecipes(vector<Recipe> recipes){
|
||||
beginInsertRows({}, 0, recipes.size()-1);
|
||||
this->recipes = recipes;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
Recipe RecipeTableModel::getRecipeAt(int index){
|
||||
if (index < 0 || index >= this->recipes.size()){
|
||||
return Recipe();
|
||||
}
|
||||
return this->recipes[index];
|
||||
}
|
||||
|
||||
void RecipeTableModel::clear(){
|
||||
beginResetModel();
|
||||
this->recipes.clear();
|
||||
endResetModel();
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef RECIPETABLEMODEL_H
|
||||
#define RECIPETABLEMODEL_H
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
|
||||
#include "model/recipe/recipe.h"
|
||||
#include "utils/stringutils.h"
|
||||
|
||||
class RecipeTableModel : public QAbstractTableModel
|
||||
{
|
||||
public:
|
||||
RecipeTableModel();
|
||||
RecipeTableModel(vector<Recipe> recipes);
|
||||
|
||||
//Overridden methods.
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||
|
||||
//Normal methods.
|
||||
void setRecipes(vector<Recipe> recipes);
|
||||
Recipe getRecipeAt(int index);
|
||||
void clear();
|
||||
private:
|
||||
vector<Recipe> recipes;
|
||||
};
|
||||
|
||||
#endif // RECIPETABLEMODEL_H
|
|
@ -1,14 +0,0 @@
|
|||
#include "openrecipedialog.h"
|
||||
#include "ui_openrecipedialog.h"
|
||||
|
||||
OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::OpenRecipeDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
OpenRecipeDialog::~OpenRecipeDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef OPENRECIPEDIALOG_H
|
||||
#define OPENRECIPEDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class OpenRecipeDialog;
|
||||
}
|
||||
|
||||
class OpenRecipeDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OpenRecipeDialog(QWidget *parent = 0);
|
||||
~OpenRecipeDialog();
|
||||
|
||||
private:
|
||||
Ui::OpenRecipeDialog *ui;
|
||||
};
|
||||
|
||||
#endif // OPENRECIPEDIALOG_H
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version='1.0'?>
|
||||
<ui version="4.0">
|
||||
<class>OpenRecipeDialog</class>
|
||||
<widget name="OpenRecipeDialog" class="QDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>640</width>
|
||||
<height>480</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -2,6 +2,14 @@
|
|||
|
||||
namespace StringUtils{
|
||||
|
||||
bool stringEndsWith(std::string const &fullString, std::string const &ending){
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string toString(float val){
|
||||
float decimal = std::fmod(val, 1.0f);
|
||||
int places = 1;
|
||||
|
@ -13,6 +21,11 @@ std::string toString(float val){
|
|||
std::string arg = "%."+std::to_string(places)+"f";
|
||||
sprintf(buffer, arg.c_str(), val);
|
||||
std::string s = buffer;
|
||||
if (stringEndsWith(s, ".0")){
|
||||
while (s.find('.') != std::string::npos){
|
||||
s.pop_back();
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue