Merge pull request #13 from andrewlalis/improve/redesignIngredients
Improve/redesign ingredients
This commit is contained in:
		
						commit
						8644cbbd41
					
				
							
								
								
									
										21
									
								
								RecipeDB.pro
								
								
								
								
							
							
						
						
									
										21
									
								
								RecipeDB.pro
								
								
								
								
							| 
						 | 
				
			
			@ -16,10 +16,8 @@ SOURCES += model/recipe/instruction.cpp \
 | 
			
		|||
    model/recipe/recipe.cpp \
 | 
			
		||||
    main.cpp \
 | 
			
		||||
    model/database/database.cpp \
 | 
			
		||||
    model/recipe/ingredients/unitofmeasure.cpp \
 | 
			
		||||
    model/recipe/ingredients/ingredient.cpp \
 | 
			
		||||
    model/recipe/ingredients/ingredientlistmodel.cpp \
 | 
			
		||||
    model/recipe/ingredients/recipeingredient.cpp \
 | 
			
		||||
    model/recipe/tags/recipetag.cpp \
 | 
			
		||||
    SQLite/sqlite3.c \
 | 
			
		||||
    model/database/resulttable.cpp \
 | 
			
		||||
| 
						 | 
				
			
			@ -27,24 +25,18 @@ SOURCES += model/recipe/instruction.cpp \
 | 
			
		|||
    utils/fileutils.cpp \
 | 
			
		||||
    gui/newrecipedialog.cpp \
 | 
			
		||||
    model/recipe/tags/taglistmodel.cpp \
 | 
			
		||||
    gui/newDialogs/newingredientdialog.cpp \
 | 
			
		||||
    gui/newDialogs/newtagdialog.cpp \
 | 
			
		||||
    gui/newDialogs/newunitdialog.cpp \
 | 
			
		||||
    utils/aspectratiopixmaplabel.cpp \
 | 
			
		||||
    utils/stringutils.cpp \
 | 
			
		||||
    gui/openrecipedialog.cpp \
 | 
			
		||||
    model/recipe/recipetablemodel.cpp \
 | 
			
		||||
    gui/mainwindow.cpp \
 | 
			
		||||
    gui/newDialogs/newfoodgroupdialog.cpp \
 | 
			
		||||
    model/recipe/ingredients/recipeingredientlistmodel.cpp
 | 
			
		||||
    gui/mainwindow.cpp
 | 
			
		||||
 | 
			
		||||
HEADERS  += model/recipe/instruction.h \
 | 
			
		||||
    model/recipe/recipe.h \
 | 
			
		||||
    model/database/database.h \
 | 
			
		||||
    model/recipe/ingredients/unitofmeasure.h \
 | 
			
		||||
    model/recipe/ingredients/ingredient.h \
 | 
			
		||||
    model/recipe/ingredients/ingredientlistmodel.h \
 | 
			
		||||
    model/recipe/ingredients/recipeingredient.h \
 | 
			
		||||
    model/recipe/tags/recipetag.h \
 | 
			
		||||
    SQLite/sqlite3.h \
 | 
			
		||||
    SQLite/sqlite3ext.h \
 | 
			
		||||
| 
						 | 
				
			
			@ -53,27 +45,20 @@ HEADERS  += model/recipe/instruction.h \
 | 
			
		|||
    utils/fileutils.h \
 | 
			
		||||
    gui/newrecipedialog.h \
 | 
			
		||||
    model/recipe/tags/taglistmodel.h \
 | 
			
		||||
    gui/newDialogs/newingredientdialog.h \
 | 
			
		||||
    gui/newDialogs/newtagdialog.h \
 | 
			
		||||
    gui/newDialogs/newunitdialog.h \
 | 
			
		||||
    utils/aspectratiopixmaplabel.h \
 | 
			
		||||
    utils/stringutils.h \
 | 
			
		||||
    gui/openrecipedialog.h \
 | 
			
		||||
    model/recipe/recipetablemodel.h \
 | 
			
		||||
    gui/mainwindow.h \
 | 
			
		||||
    gui/newDialogs/newfoodgroupdialog.h \
 | 
			
		||||
    model/recipe/ingredients/recipeingredientlistmodel.h
 | 
			
		||||
    gui/mainwindow.h
 | 
			
		||||
 | 
			
		||||
LIBS += -ldl \
 | 
			
		||||
 | 
			
		||||
FORMS    += gui/mainwindow.ui \
 | 
			
		||||
    gui/newrecipedialog.ui \
 | 
			
		||||
    gui/newDialogs/newingredientdialog.ui \
 | 
			
		||||
    gui/newDialogs/newtagdialog.ui \
 | 
			
		||||
    gui/newDialogs/newunitdialog.ui \
 | 
			
		||||
    gui/openrecipedialog.ui \
 | 
			
		||||
    gui/mainwindow.ui \
 | 
			
		||||
    gui/newDialogs/newfoodgroupdialog.ui
 | 
			
		||||
    gui/mainwindow.ui
 | 
			
		||||
 | 
			
		||||
DISTFILES += \
 | 
			
		||||
    .gitignore
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ void MainWindow::setInstruction(Instruction instruction){
 | 
			
		|||
    ui->instructionsTextEdit->setHtml(QString::fromStdString(instruction.getHTML()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::setIngredients(vector<RecipeIngredient> ingredients){
 | 
			
		||||
void MainWindow::setIngredients(vector<Ingredient> ingredients){
 | 
			
		||||
	this->ingredientModel.setIngredients(ingredients);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
#include <QAbstractListModel>
 | 
			
		||||
 | 
			
		||||
#include "model/recipe/recipe.h"
 | 
			
		||||
#include "model/recipe/ingredients/recipeingredientlistmodel.h"
 | 
			
		||||
#include "model/recipe/ingredients/ingredientlistmodel.h"
 | 
			
		||||
#include "gui/newrecipedialog.h"
 | 
			
		||||
#include "gui/openrecipedialog.h"
 | 
			
		||||
#include "utils/stringutils.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -41,14 +41,14 @@ public:
 | 
			
		|||
	private:
 | 
			
		||||
    Ui::MainWindow *ui;
 | 
			
		||||
	RecipeDatabase *recipeDB;
 | 
			
		||||
	RecipeIngredientListModel ingredientModel;
 | 
			
		||||
	IngredientListModel ingredientModel;
 | 
			
		||||
	TagListModel tagsListModel;
 | 
			
		||||
	Recipe currentRecipe;
 | 
			
		||||
 | 
			
		||||
    //Hidden manipulation methods.
 | 
			
		||||
    void setRecipeName(string name);
 | 
			
		||||
    void setInstruction(Instruction instruction);
 | 
			
		||||
    void setIngredients(vector<RecipeIngredient> ingredients);
 | 
			
		||||
	void setIngredients(vector<Ingredient> ingredients);
 | 
			
		||||
	void setImage(QImage img);
 | 
			
		||||
	void setPrepTime(QTime prepTime);
 | 
			
		||||
	void setCookTime(QTime cookTime);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
#include "newfoodgroupdialog.h"
 | 
			
		||||
#include "ui_newfoodgroupdialog.h"
 | 
			
		||||
 | 
			
		||||
newFoodGroupDialog::newFoodGroupDialog(QWidget *parent) :
 | 
			
		||||
	QDialog(parent),
 | 
			
		||||
	ui(new Ui::newFoodGroupDialog)
 | 
			
		||||
{
 | 
			
		||||
	ui->setupUi(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
newFoodGroupDialog::~newFoodGroupDialog()
 | 
			
		||||
{
 | 
			
		||||
	delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string newFoodGroupDialog::getFoodGroup() const{
 | 
			
		||||
	return ui->lineEdit->text().toStdString();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
#ifndef NEWFOODGROUPDIALOG_H
 | 
			
		||||
#define NEWFOODGROUPDIALOG_H
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class newFoodGroupDialog;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class newFoodGroupDialog : public QDialog
 | 
			
		||||
{
 | 
			
		||||
		Q_OBJECT
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		explicit newFoodGroupDialog(QWidget *parent = 0);
 | 
			
		||||
		~newFoodGroupDialog();
 | 
			
		||||
 | 
			
		||||
		string getFoodGroup() const;
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Ui::newFoodGroupDialog *ui;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // NEWFOODGROUPDIALOG_H
 | 
			
		||||
| 
						 | 
				
			
			@ -1,102 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>newFoodGroupDialog</class>
 | 
			
		||||
 <widget class="QDialog" name="newFoodGroupDialog">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>240</width>
 | 
			
		||||
    <height>114</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="font">
 | 
			
		||||
   <font>
 | 
			
		||||
    <pointsize>11</pointsize>
 | 
			
		||||
   </font>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>New Food Group</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowIcon">
 | 
			
		||||
   <iconset resource="../../res.qrc">
 | 
			
		||||
    <normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="styleSheet">
 | 
			
		||||
   <string notr="true"/>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLabel" name="label">
 | 
			
		||||
     <property name="font">
 | 
			
		||||
      <font>
 | 
			
		||||
       <pointsize>12</pointsize>
 | 
			
		||||
      </font>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string>Add New Food Group</string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="alignment">
 | 
			
		||||
      <set>Qt::AlignCenter</set>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLineEdit" name="lineEdit">
 | 
			
		||||
     <property name="font">
 | 
			
		||||
      <font>
 | 
			
		||||
       <pointsize>12</pointsize>
 | 
			
		||||
      </font>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QDialogButtonBox" name="buttonBox">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Horizontal</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="standardButtons">
 | 
			
		||||
      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources>
 | 
			
		||||
  <include location="../../res.qrc"/>
 | 
			
		||||
 </resources>
 | 
			
		||||
 <connections>
 | 
			
		||||
  <connection>
 | 
			
		||||
   <sender>buttonBox</sender>
 | 
			
		||||
   <signal>accepted()</signal>
 | 
			
		||||
   <receiver>newFoodGroupDialog</receiver>
 | 
			
		||||
   <slot>accept()</slot>
 | 
			
		||||
   <hints>
 | 
			
		||||
    <hint type="sourcelabel">
 | 
			
		||||
     <x>248</x>
 | 
			
		||||
     <y>254</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
    <hint type="destinationlabel">
 | 
			
		||||
     <x>157</x>
 | 
			
		||||
     <y>274</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
   </hints>
 | 
			
		||||
  </connection>
 | 
			
		||||
  <connection>
 | 
			
		||||
   <sender>buttonBox</sender>
 | 
			
		||||
   <signal>rejected()</signal>
 | 
			
		||||
   <receiver>newFoodGroupDialog</receiver>
 | 
			
		||||
   <slot>reject()</slot>
 | 
			
		||||
   <hints>
 | 
			
		||||
    <hint type="sourcelabel">
 | 
			
		||||
     <x>316</x>
 | 
			
		||||
     <y>260</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
    <hint type="destinationlabel">
 | 
			
		||||
     <x>286</x>
 | 
			
		||||
     <y>274</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
   </hints>
 | 
			
		||||
  </connection>
 | 
			
		||||
 </connections>
 | 
			
		||||
</ui>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,49 +0,0 @@
 | 
			
		|||
#include "newingredientdialog.h"
 | 
			
		||||
#include "ui_newingredientdialog.h"
 | 
			
		||||
 | 
			
		||||
NewIngredientDialog::NewIngredientDialog(QWidget *parent) :
 | 
			
		||||
	QDialog(parent),
 | 
			
		||||
	ui(new Ui::NewIngredientDialog)
 | 
			
		||||
{
 | 
			
		||||
	ui->setupUi(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NewIngredientDialog::NewIngredientDialog(RecipeDatabase *recipeDB, QWidget *parent) : NewIngredientDialog(parent){
 | 
			
		||||
	this->recipeDB = recipeDB;
 | 
			
		||||
	this->populateFoodGroupBox();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NewIngredientDialog::~NewIngredientDialog()
 | 
			
		||||
{
 | 
			
		||||
	delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Ingredient NewIngredientDialog::getIngredient(){
 | 
			
		||||
	return Ingredient(ui->nameEdit->text().toLower().toStdString(), ui->foodGroupBox->currentText().toStdString());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NewIngredientDialog::populateFoodGroupBox(){
 | 
			
		||||
	vector<string> foodGroups = this->recipeDB->retrieveAllFoodGroups();
 | 
			
		||||
	ui->foodGroupBox->clear();
 | 
			
		||||
	for (unsigned int i = 0; i < foodGroups.size(); i++){
 | 
			
		||||
		QString s = QString::fromStdString(foodGroups[i]);
 | 
			
		||||
		ui->foodGroupBox->insertItem(i, s);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NewIngredientDialog::on_addFoodGroupButton_clicked(){
 | 
			
		||||
	newFoodGroupDialog d(this);
 | 
			
		||||
	if (d.exec() == QDialog::Accepted){
 | 
			
		||||
		string s = d.getFoodGroup();
 | 
			
		||||
		if (!s.empty()){
 | 
			
		||||
			ui->foodGroupBox->addItem(QString::fromStdString(s));
 | 
			
		||||
			ui->foodGroupBox->setCurrentText(QString::fromStdString(s));
 | 
			
		||||
		} else {
 | 
			
		||||
			QMessageBox::warning(this, "Empty Food Group", "The food group you entered is empty!");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NewIngredientDialog::on_deleteFoodGroupButton_clicked(){
 | 
			
		||||
	ui->foodGroupBox->removeItem(ui->foodGroupBox->currentIndex());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,39 +0,0 @@
 | 
			
		|||
#ifndef NEWINGREDIENTDIALOG_H
 | 
			
		||||
#define NEWINGREDIENTDIALOG_H
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
 | 
			
		||||
#include "model/recipe/ingredients/ingredient.h"
 | 
			
		||||
#include "model/database/recipedatabase.h"
 | 
			
		||||
#include "gui/newDialogs/newfoodgroupdialog.h"
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class NewIngredientDialog;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class NewIngredientDialog : public QDialog
 | 
			
		||||
{
 | 
			
		||||
		Q_OBJECT
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		explicit NewIngredientDialog(QWidget *parent = 0);
 | 
			
		||||
		NewIngredientDialog(RecipeDatabase *recipeDB, QWidget *parent = 0);
 | 
			
		||||
		~NewIngredientDialog();
 | 
			
		||||
 | 
			
		||||
		//Access values.
 | 
			
		||||
		Ingredient getIngredient();
 | 
			
		||||
 | 
			
		||||
	private slots:
 | 
			
		||||
		void on_addFoodGroupButton_clicked();
 | 
			
		||||
 | 
			
		||||
		void on_deleteFoodGroupButton_clicked();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Ui::NewIngredientDialog *ui;
 | 
			
		||||
		RecipeDatabase *recipeDB;
 | 
			
		||||
 | 
			
		||||
		void populateFoodGroupBox();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // NEWINGREDIENTDIALOG_H
 | 
			
		||||
| 
						 | 
				
			
			@ -1,158 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>NewIngredientDialog</class>
 | 
			
		||||
 <widget class="QDialog" name="NewIngredientDialog">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>367</width>
 | 
			
		||||
    <height>228</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>New Ingredient</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowIcon">
 | 
			
		||||
   <iconset resource="../../res.qrc">
 | 
			
		||||
    <normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="modal">
 | 
			
		||||
   <bool>true</bool>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QVBoxLayout" name="verticalLayout_2">
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QWidget" name="mainContentPanel" native="true">
 | 
			
		||||
     <property name="enabled">
 | 
			
		||||
      <bool>true</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
     <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
      <item alignment="Qt::AlignTop">
 | 
			
		||||
       <widget class="QWidget" name="namePanel" native="true">
 | 
			
		||||
        <layout class="QVBoxLayout" name="verticalLayout_3">
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QLabel" name="nameLabel">
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>Name</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="alignment">
 | 
			
		||||
            <set>Qt::AlignCenter</set>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QLineEdit" name="nameEdit"/>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item alignment="Qt::AlignTop">
 | 
			
		||||
       <widget class="QWidget" name="foodGroupPanel" native="true">
 | 
			
		||||
        <layout class="QVBoxLayout" name="verticalLayout_4">
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QLabel" name="foodGroupLabel">
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>Food Group</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="alignment">
 | 
			
		||||
            <set>Qt::AlignCenter</set>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QWidget" name="foodGroupSelectionWidget" native="true">
 | 
			
		||||
           <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
            <item>
 | 
			
		||||
             <widget class="QComboBox" name="foodGroupBox">
 | 
			
		||||
              <property name="sizePolicy">
 | 
			
		||||
               <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
 | 
			
		||||
                <horstretch>0</horstretch>
 | 
			
		||||
                <verstretch>0</verstretch>
 | 
			
		||||
               </sizepolicy>
 | 
			
		||||
              </property>
 | 
			
		||||
              <property name="insertPolicy">
 | 
			
		||||
               <enum>QComboBox::InsertAlphabetically</enum>
 | 
			
		||||
              </property>
 | 
			
		||||
             </widget>
 | 
			
		||||
            </item>
 | 
			
		||||
            <item alignment="Qt::AlignRight">
 | 
			
		||||
             <widget class="QPushButton" name="addFoodGroupButton">
 | 
			
		||||
              <property name="text">
 | 
			
		||||
               <string/>
 | 
			
		||||
              </property>
 | 
			
		||||
              <property name="icon">
 | 
			
		||||
               <iconset resource="../../res.qrc">
 | 
			
		||||
                <normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
 | 
			
		||||
              </property>
 | 
			
		||||
             </widget>
 | 
			
		||||
            </item>
 | 
			
		||||
            <item alignment="Qt::AlignRight">
 | 
			
		||||
             <widget class="QPushButton" name="deleteFoodGroupButton">
 | 
			
		||||
              <property name="text">
 | 
			
		||||
               <string/>
 | 
			
		||||
              </property>
 | 
			
		||||
              <property name="icon">
 | 
			
		||||
               <iconset resource="../../res.qrc">
 | 
			
		||||
                <normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
 | 
			
		||||
              </property>
 | 
			
		||||
             </widget>
 | 
			
		||||
            </item>
 | 
			
		||||
           </layout>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
     </layout>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QDialogButtonBox" name="buttonBox">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Horizontal</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="standardButtons">
 | 
			
		||||
      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources>
 | 
			
		||||
  <include location="../../res.qrc"/>
 | 
			
		||||
 </resources>
 | 
			
		||||
 <connections>
 | 
			
		||||
  <connection>
 | 
			
		||||
   <sender>buttonBox</sender>
 | 
			
		||||
   <signal>accepted()</signal>
 | 
			
		||||
   <receiver>NewIngredientDialog</receiver>
 | 
			
		||||
   <slot>accept()</slot>
 | 
			
		||||
   <hints>
 | 
			
		||||
    <hint type="sourcelabel">
 | 
			
		||||
     <x>248</x>
 | 
			
		||||
     <y>254</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
    <hint type="destinationlabel">
 | 
			
		||||
     <x>157</x>
 | 
			
		||||
     <y>274</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
   </hints>
 | 
			
		||||
  </connection>
 | 
			
		||||
  <connection>
 | 
			
		||||
   <sender>buttonBox</sender>
 | 
			
		||||
   <signal>rejected()</signal>
 | 
			
		||||
   <receiver>NewIngredientDialog</receiver>
 | 
			
		||||
   <slot>reject()</slot>
 | 
			
		||||
   <hints>
 | 
			
		||||
    <hint type="sourcelabel">
 | 
			
		||||
     <x>316</x>
 | 
			
		||||
     <y>260</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
    <hint type="destinationlabel">
 | 
			
		||||
     <x>286</x>
 | 
			
		||||
     <y>274</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
   </hints>
 | 
			
		||||
  </connection>
 | 
			
		||||
 </connections>
 | 
			
		||||
</ui>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,31 +0,0 @@
 | 
			
		|||
#include "newunitdialog.h"
 | 
			
		||||
#include "ui_newunitdialog.h"
 | 
			
		||||
 | 
			
		||||
NewUnitDialog::NewUnitDialog(QWidget *parent) :
 | 
			
		||||
	QDialog(parent),
 | 
			
		||||
	ui(new Ui::NewUnitDialog)
 | 
			
		||||
{
 | 
			
		||||
	ui->setupUi(this);
 | 
			
		||||
 | 
			
		||||
	ui->typeComboBox->clear();
 | 
			
		||||
	QStringList list({"Mass", "Volume", "Length", "Misc"});
 | 
			
		||||
	ui->typeComboBox->insertItems(0, list);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NewUnitDialog::~NewUnitDialog()
 | 
			
		||||
{
 | 
			
		||||
	delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UnitOfMeasure NewUnitDialog::getUnit(){
 | 
			
		||||
	return UnitOfMeasure(ui->unitNameEdit->text().toLower().toStdString(),
 | 
			
		||||
						 ui->pluralNameEdit->text().toLower().toStdString(),
 | 
			
		||||
						 ui->abbreviationEdit->text().toStdString(),
 | 
			
		||||
						 this->getSelectedType(),
 | 
			
		||||
						 ui->coefficientSpinBox->value());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int NewUnitDialog::getSelectedType(){
 | 
			
		||||
	return ui->typeComboBox->currentIndex();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,27 +0,0 @@
 | 
			
		|||
#ifndef NEWUNITDIALOG_H
 | 
			
		||||
#define NEWUNITDIALOG_H
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
 | 
			
		||||
#include "model/recipe/ingredients/unitofmeasure.h"
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class NewUnitDialog;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class NewUnitDialog : public QDialog
 | 
			
		||||
{
 | 
			
		||||
		Q_OBJECT
 | 
			
		||||
 | 
			
		||||
	public:
 | 
			
		||||
		explicit NewUnitDialog(QWidget *parent = 0);
 | 
			
		||||
		~NewUnitDialog();
 | 
			
		||||
 | 
			
		||||
		UnitOfMeasure getUnit();
 | 
			
		||||
	private:
 | 
			
		||||
		Ui::NewUnitDialog *ui;
 | 
			
		||||
 | 
			
		||||
		int getSelectedType();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // NEWUNITDIALOG_H
 | 
			
		||||
| 
						 | 
				
			
			@ -1,228 +0,0 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>NewUnitDialog</class>
 | 
			
		||||
 <widget class="QDialog" name="NewUnitDialog">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>195</width>
 | 
			
		||||
    <height>340</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>New Unit</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowIcon">
 | 
			
		||||
   <iconset resource="../../res.qrc">
 | 
			
		||||
    <normaloff>:/images/images/icon.png</normaloff>:/images/images/icon.png</iconset>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="styleSheet">
 | 
			
		||||
   <string notr="true"/>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="modal">
 | 
			
		||||
   <bool>true</bool>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
   <item alignment="Qt::AlignTop">
 | 
			
		||||
    <widget class="QWidget" name="contentPanel" native="true">
 | 
			
		||||
     <layout class="QVBoxLayout" name="verticalLayout_2">
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QLabel" name="label">
 | 
			
		||||
        <property name="font">
 | 
			
		||||
         <font>
 | 
			
		||||
          <pointsize>12</pointsize>
 | 
			
		||||
          <weight>50</weight>
 | 
			
		||||
          <italic>false</italic>
 | 
			
		||||
          <bold>false</bold>
 | 
			
		||||
         </font>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Unit Name</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="alignment">
 | 
			
		||||
         <set>Qt::AlignCenter</set>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QLineEdit" name="unitNameEdit"/>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QLabel" name="label_2">
 | 
			
		||||
        <property name="font">
 | 
			
		||||
         <font>
 | 
			
		||||
          <pointsize>12</pointsize>
 | 
			
		||||
          <weight>50</weight>
 | 
			
		||||
          <italic>false</italic>
 | 
			
		||||
          <bold>false</bold>
 | 
			
		||||
         </font>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Plural Name</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="alignment">
 | 
			
		||||
         <set>Qt::AlignCenter</set>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QLineEdit" name="pluralNameEdit"/>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QLabel" name="label_3">
 | 
			
		||||
        <property name="font">
 | 
			
		||||
         <font>
 | 
			
		||||
          <pointsize>12</pointsize>
 | 
			
		||||
          <weight>50</weight>
 | 
			
		||||
          <italic>false</italic>
 | 
			
		||||
          <bold>false</bold>
 | 
			
		||||
         </font>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Abbreviation</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="alignment">
 | 
			
		||||
         <set>Qt::AlignCenter</set>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QLineEdit" name="abbreviationEdit"/>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QWidget" name="unitTypePanel" native="true">
 | 
			
		||||
        <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
         <property name="leftMargin">
 | 
			
		||||
          <number>0</number>
 | 
			
		||||
         </property>
 | 
			
		||||
         <property name="topMargin">
 | 
			
		||||
          <number>0</number>
 | 
			
		||||
         </property>
 | 
			
		||||
         <property name="rightMargin">
 | 
			
		||||
          <number>0</number>
 | 
			
		||||
         </property>
 | 
			
		||||
         <property name="bottomMargin">
 | 
			
		||||
          <number>0</number>
 | 
			
		||||
         </property>
 | 
			
		||||
         <item alignment="Qt::AlignLeft">
 | 
			
		||||
          <widget class="QLabel" name="label_4">
 | 
			
		||||
           <property name="sizePolicy">
 | 
			
		||||
            <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
 | 
			
		||||
             <horstretch>0</horstretch>
 | 
			
		||||
             <verstretch>0</verstretch>
 | 
			
		||||
            </sizepolicy>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="font">
 | 
			
		||||
            <font>
 | 
			
		||||
             <pointsize>12</pointsize>
 | 
			
		||||
             <weight>50</weight>
 | 
			
		||||
             <italic>false</italic>
 | 
			
		||||
             <bold>false</bold>
 | 
			
		||||
            </font>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>Type:</string>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QComboBox" name="typeComboBox">
 | 
			
		||||
           <property name="sizePolicy">
 | 
			
		||||
            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
 | 
			
		||||
             <horstretch>0</horstretch>
 | 
			
		||||
             <verstretch>0</verstretch>
 | 
			
		||||
            </sizepolicy>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QWidget" name="coefficientPanel" native="true">
 | 
			
		||||
        <layout class="QVBoxLayout" name="verticalLayout_3">
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QLabel" name="label_5">
 | 
			
		||||
           <property name="font">
 | 
			
		||||
            <font>
 | 
			
		||||
             <pointsize>12</pointsize>
 | 
			
		||||
             <weight>50</weight>
 | 
			
		||||
             <italic>false</italic>
 | 
			
		||||
             <bold>false</bold>
 | 
			
		||||
            </font>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>Metric Coefficient</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="alignment">
 | 
			
		||||
            <set>Qt::AlignCenter</set>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QDoubleSpinBox" name="coefficientSpinBox">
 | 
			
		||||
           <property name="maximum">
 | 
			
		||||
            <double>1000.000000000000000</double>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="value">
 | 
			
		||||
            <double>1.000000000000000</double>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
     </layout>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QDialogButtonBox" name="buttonBox">
 | 
			
		||||
     <property name="orientation">
 | 
			
		||||
      <enum>Qt::Horizontal</enum>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="standardButtons">
 | 
			
		||||
      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources>
 | 
			
		||||
  <include location="../../res.qrc"/>
 | 
			
		||||
 </resources>
 | 
			
		||||
 <connections>
 | 
			
		||||
  <connection>
 | 
			
		||||
   <sender>buttonBox</sender>
 | 
			
		||||
   <signal>accepted()</signal>
 | 
			
		||||
   <receiver>NewUnitDialog</receiver>
 | 
			
		||||
   <slot>accept()</slot>
 | 
			
		||||
   <hints>
 | 
			
		||||
    <hint type="sourcelabel">
 | 
			
		||||
     <x>248</x>
 | 
			
		||||
     <y>254</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
    <hint type="destinationlabel">
 | 
			
		||||
     <x>157</x>
 | 
			
		||||
     <y>274</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
   </hints>
 | 
			
		||||
  </connection>
 | 
			
		||||
  <connection>
 | 
			
		||||
   <sender>buttonBox</sender>
 | 
			
		||||
   <signal>rejected()</signal>
 | 
			
		||||
   <receiver>NewUnitDialog</receiver>
 | 
			
		||||
   <slot>reject()</slot>
 | 
			
		||||
   <hints>
 | 
			
		||||
    <hint type="sourcelabel">
 | 
			
		||||
     <x>316</x>
 | 
			
		||||
     <y>260</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
    <hint type="destinationlabel">
 | 
			
		||||
     <x>286</x>
 | 
			
		||||
     <y>274</y>
 | 
			
		||||
    </hint>
 | 
			
		||||
   </hints>
 | 
			
		||||
  </connection>
 | 
			
		||||
 </connections>
 | 
			
		||||
</ui>
 | 
			
		||||
| 
						 | 
				
			
			@ -15,9 +15,6 @@ NewRecipeDialog::NewRecipeDialog(QWidget *parent) :
 | 
			
		|||
NewRecipeDialog::NewRecipeDialog(RecipeDatabase *db, QWidget *parent) : NewRecipeDialog(parent){
 | 
			
		||||
	this->recipeDB = db;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	this->populateIngredientsBox();
 | 
			
		||||
	this->populateUnitsBox();
 | 
			
		||||
	this->populateTagsBox();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,24 +52,6 @@ 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();
 | 
			
		||||
| 
						 | 
				
			
			@ -83,12 +62,9 @@ void NewRecipeDialog::populateTagsBox(){
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
	ui->commentsLineEdit->clear();
 | 
			
		||||
	Ingredient ing(ui->ingredientLineEdit->text().toStdString());
 | 
			
		||||
	this->ingredientListModel.addIngredient(ing);
 | 
			
		||||
	ui->ingredientLineEdit->clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NewRecipeDialog::on_italicsButton_clicked(){
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +89,6 @@ void NewRecipeDialog::on_buttonBox_rejected(){
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
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()]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -140,37 +115,6 @@ void NewRecipeDialog::on_removeIngredientButton_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->recipeDB, this);
 | 
			
		||||
	d.show();
 | 
			
		||||
	if (d.exec() == QDialog::Accepted){
 | 
			
		||||
		Ingredient i = d.getIngredient();
 | 
			
		||||
		if (!i.getName().empty() && !i.getFoodGroup().empty() && this->recipeDB->storeIngredient(i)){
 | 
			
		||||
			this->populateIngredientsBox();
 | 
			
		||||
			ui->ingredientNameBox->setCurrentText(QString::fromStdString(i.getName()));
 | 
			
		||||
		} else {
 | 
			
		||||
			QMessageBox::critical(this, "Error", "Unable to add ingredient.");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NewRecipeDialog::on_newTagButton_clicked(){
 | 
			
		||||
	NewTagDialog d(this);
 | 
			
		||||
	d.show();
 | 
			
		||||
| 
						 | 
				
			
			@ -206,31 +150,6 @@ void NewRecipeDialog::on_removeTagButton_clicked(){
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NewRecipeDialog::on_newUnitButton_clicked(){
 | 
			
		||||
	NewUnitDialog d(this);
 | 
			
		||||
	d.show();
 | 
			
		||||
	if (d.exec() == QDialog::Accepted){
 | 
			
		||||
		UnitOfMeasure u = d.getUnit();
 | 
			
		||||
		if (u.getName().empty() || u.getNamePlural().empty() || u.getAbbreviation().empty() || !this->recipeDB->storeUnitOfMeasure(u)){
 | 
			
		||||
			QMessageBox::critical(this, "Error", "Unable to store new unit. Make sure all the information is filled in!");
 | 
			
		||||
		} else {
 | 
			
		||||
			this->populateUnitsBox();
 | 
			
		||||
			ui->unitComboBox->setCurrentText(QString::fromStdString(u.getName()));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
void NewRecipeDialog::on_ingredientLineEdit_returnPressed(){
 | 
			
		||||
	this->on_addIngredientButton_clicked();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,12 +8,10 @@
 | 
			
		|||
#include <QMessageBox>
 | 
			
		||||
 | 
			
		||||
#include "model/database/recipedatabase.h"
 | 
			
		||||
#include "model/recipe/ingredients/recipeingredientlistmodel.h"
 | 
			
		||||
#include "model/recipe/ingredients/ingredientlistmodel.h"
 | 
			
		||||
#include "model/recipe/tags/taglistmodel.h"
 | 
			
		||||
 | 
			
		||||
#include "gui/newDialogs/newingredientdialog.h"
 | 
			
		||||
#include "gui/newDialogs/newtagdialog.h"
 | 
			
		||||
#include "gui/newDialogs/newunitdialog.h"
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class NewRecipeDialog;
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +27,7 @@ class NewRecipeDialog : public QDialog
 | 
			
		|||
		NewRecipeDialog(RecipeDatabase *db, Recipe recipe, QWidget *parent = 0);
 | 
			
		||||
		~NewRecipeDialog();
 | 
			
		||||
 | 
			
		||||
		//Extracts a recipe from all the information entered in the ui.
 | 
			
		||||
		Recipe getRecipe();
 | 
			
		||||
		bool isAccepted() const;
 | 
			
		||||
	private slots:
 | 
			
		||||
| 
						 | 
				
			
			@ -38,8 +37,10 @@ class NewRecipeDialog : public QDialog
 | 
			
		|||
 | 
			
		||||
		void on_boldButton_clicked();
 | 
			
		||||
 | 
			
		||||
		//Sets the dialog as accepted, as in, the user accepts that they want to create the recipe.
 | 
			
		||||
		void on_buttonBox_accepted();
 | 
			
		||||
 | 
			
		||||
		//The user has rejected the creation of the recipe.
 | 
			
		||||
		void on_buttonBox_rejected();
 | 
			
		||||
 | 
			
		||||
		void on_addTagButton_clicked();
 | 
			
		||||
| 
						 | 
				
			
			@ -50,31 +51,22 @@ class NewRecipeDialog : public QDialog
 | 
			
		|||
 | 
			
		||||
		void on_removeIngredientButton_clicked();
 | 
			
		||||
 | 
			
		||||
		void on_deleteIngredientButton_clicked();
 | 
			
		||||
 | 
			
		||||
		void on_newIngredientButton_clicked();
 | 
			
		||||
 | 
			
		||||
		void on_newTagButton_clicked();
 | 
			
		||||
 | 
			
		||||
		void on_removeTagButton_clicked();
 | 
			
		||||
 | 
			
		||||
		void on_newUnitButton_clicked();
 | 
			
		||||
 | 
			
		||||
		void on_deleteUnitButton_clicked();
 | 
			
		||||
		void on_ingredientLineEdit_returnPressed();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		Ui::NewRecipeDialog *ui;
 | 
			
		||||
		RecipeDatabase *recipeDB;
 | 
			
		||||
		vector<Ingredient> ingredients;
 | 
			
		||||
		vector<UnitOfMeasure> units;
 | 
			
		||||
		vector<RecipeTag> tags;
 | 
			
		||||
		RecipeIngredientListModel ingredientListModel;
 | 
			
		||||
		IngredientListModel ingredientListModel;
 | 
			
		||||
		TagListModel tagsListModel;
 | 
			
		||||
		bool accepted = false;
 | 
			
		||||
 | 
			
		||||
		//Helper functions to fill fields.
 | 
			
		||||
		void populateIngredientsBox();
 | 
			
		||||
		void populateUnitsBox();
 | 
			
		||||
		void populateTagsBox();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -175,7 +175,7 @@
 | 
			
		|||
                      <second>0</second>
 | 
			
		||||
                      <year>1999</year>
 | 
			
		||||
                      <month>12</month>
 | 
			
		||||
                      <day>21</day>
 | 
			
		||||
                      <day>20</day>
 | 
			
		||||
                     </datetime>
 | 
			
		||||
                    </property>
 | 
			
		||||
                    <property name="currentSection">
 | 
			
		||||
| 
						 | 
				
			
			@ -530,176 +530,7 @@ QPushButton#deleteTagButton:pressed{
 | 
			
		|||
                   </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="styleSheet">
 | 
			
		||||
                        <string notr="true">background-color: rgb(113, 119, 255);</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="editable">
 | 
			
		||||
                        <bool>false</bool>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="currentText">
 | 
			
		||||
                        <string/>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="insertPolicy">
 | 
			
		||||
                        <enum>QComboBox::InsertAlphabetically</enum>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="frame">
 | 
			
		||||
                        <bool>true</bool>
 | 
			
		||||
                       </property>
 | 
			
		||||
                      </widget>
 | 
			
		||||
                     </item>
 | 
			
		||||
                     <item>
 | 
			
		||||
                      <widget class="QPushButton" name="newIngredientButton">
 | 
			
		||||
                       <property name="toolTip">
 | 
			
		||||
                        <string>Create a new ingredient</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="icon">
 | 
			
		||||
                        <iconset resource="../res.qrc">
 | 
			
		||||
                         <normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
 | 
			
		||||
                       </property>
 | 
			
		||||
                      </widget>
 | 
			
		||||
                     </item>
 | 
			
		||||
                     <item>
 | 
			
		||||
                      <widget class="QPushButton" name="deleteIngredientButton">
 | 
			
		||||
                       <property name="toolTip">
 | 
			
		||||
                        <string>Delete this ingredient</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="text">
 | 
			
		||||
                        <string/>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="icon">
 | 
			
		||||
                        <iconset resource="../res.qrc">
 | 
			
		||||
                         <normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
 | 
			
		||||
                       </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>
 | 
			
		||||
                         <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">
 | 
			
		||||
                       <property name="sizePolicy">
 | 
			
		||||
                        <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
 | 
			
		||||
                         <horstretch>0</horstretch>
 | 
			
		||||
                         <verstretch>0</verstretch>
 | 
			
		||||
                        </sizepolicy>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="styleSheet">
 | 
			
		||||
                        <string notr="true">background-color: rgb(113, 119, 255);</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="insertPolicy">
 | 
			
		||||
                        <enum>QComboBox::InsertAlphabetically</enum>
 | 
			
		||||
                       </property>
 | 
			
		||||
                      </widget>
 | 
			
		||||
                     </item>
 | 
			
		||||
                     <item alignment="Qt::AlignRight">
 | 
			
		||||
                      <widget class="QPushButton" name="newUnitButton">
 | 
			
		||||
                       <property name="toolTip">
 | 
			
		||||
                        <string>Create a new unit of measure</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="icon">
 | 
			
		||||
                        <iconset resource="../res.qrc">
 | 
			
		||||
                         <normaloff>:/images/images/plus_icon.png</normaloff>:/images/images/plus_icon.png</iconset>
 | 
			
		||||
                       </property>
 | 
			
		||||
                      </widget>
 | 
			
		||||
                     </item>
 | 
			
		||||
                     <item>
 | 
			
		||||
                      <widget class="QPushButton" name="deleteUnitButton">
 | 
			
		||||
                       <property name="toolTip">
 | 
			
		||||
                        <string>Delete this unit of measure</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="text">
 | 
			
		||||
                        <string/>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="icon">
 | 
			
		||||
                        <iconset resource="../res.qrc">
 | 
			
		||||
                         <normaloff>:/images/images/minus_icon.png</normaloff>:/images/images/minus_icon.png</iconset>
 | 
			
		||||
                       </property>
 | 
			
		||||
                      </widget>
 | 
			
		||||
                     </item>
 | 
			
		||||
                    </layout>
 | 
			
		||||
                   </widget>
 | 
			
		||||
                  </item>
 | 
			
		||||
                  <item>
 | 
			
		||||
                   <widget class="QLineEdit" name="commentsLineEdit">
 | 
			
		||||
                   <widget class="QLineEdit" name="ingredientLineEdit">
 | 
			
		||||
                    <property name="minimumSize">
 | 
			
		||||
                     <size>
 | 
			
		||||
                      <width>0</width>
 | 
			
		||||
| 
						 | 
				
			
			@ -710,10 +541,10 @@ QPushButton#deleteTagButton:pressed{
 | 
			
		|||
                     <bool>false</bool>
 | 
			
		||||
                    </property>
 | 
			
		||||
                    <property name="alignment">
 | 
			
		||||
                     <set>Qt::AlignCenter</set>
 | 
			
		||||
                     <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
 | 
			
		||||
                    </property>
 | 
			
		||||
                    <property name="placeholderText">
 | 
			
		||||
                     <string>Comments</string>
 | 
			
		||||
                     <string>Write ingredient here...</string>
 | 
			
		||||
                    </property>
 | 
			
		||||
                    <property name="clearButtonEnabled">
 | 
			
		||||
                     <bool>false</bool>
 | 
			
		||||
| 
						 | 
				
			
			@ -809,11 +640,14 @@ QPushButton#removeIngredientButton:pressed{
 | 
			
		|||
                  <enum>QFrame::NoFrame</enum>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="selectionMode">
 | 
			
		||||
                  <enum>QAbstractItemView::MultiSelection</enum>
 | 
			
		||||
                  <enum>QAbstractItemView::SingleSelection</enum>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="verticalScrollMode">
 | 
			
		||||
                  <enum>QAbstractItemView::ScrollPerPixel</enum>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="horizontalScrollMode">
 | 
			
		||||
                  <enum>QAbstractItemView::ScrollPerPixel</enum>
 | 
			
		||||
                 </property>
 | 
			
		||||
                 <property name="batchSize">
 | 
			
		||||
                  <number>100</number>
 | 
			
		||||
                 </property>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,13 +8,8 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) :
 | 
			
		|||
	ui->setupUi(this);
 | 
			
		||||
 | 
			
		||||
	ui->recipeTableView->setModel(&this->recipeTableModel);
 | 
			
		||||
	ui->ingredientsListView->setModel(&this->ingredientsModel);
 | 
			
		||||
	ui->tagsListView->setModel(&this->tagsModel);
 | 
			
		||||
 | 
			
		||||
	QObject::connect(ui->ingredientsListView->selectionModel(),
 | 
			
		||||
			SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
 | 
			
		||||
			this,
 | 
			
		||||
			SLOT(onIngredientsListViewSelectionChanged(QItemSelection)));
 | 
			
		||||
	QObject::connect(ui->tagsListView->selectionModel(),
 | 
			
		||||
			SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
 | 
			
		||||
			this,
 | 
			
		||||
| 
						 | 
				
			
			@ -23,9 +18,7 @@ OpenRecipeDialog::OpenRecipeDialog(QWidget *parent) :
 | 
			
		|||
 | 
			
		||||
OpenRecipeDialog::OpenRecipeDialog(RecipeDatabase *recipeDB, QWidget *parent) : OpenRecipeDialog(parent){
 | 
			
		||||
	this->recipeDB = recipeDB;
 | 
			
		||||
	this->populateIngredientsList();
 | 
			
		||||
	this->populateTagsList();
 | 
			
		||||
	this->populateFoodGroupsList();
 | 
			
		||||
	this->populateRecipesTable(this->recipeDB->retrieveAllRecipes());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -45,21 +38,10 @@ void OpenRecipeDialog::populateRecipesTable(vector<Recipe> recipes){
 | 
			
		|||
	ui->recipeTableView->show();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenRecipeDialog::populateIngredientsList(){
 | 
			
		||||
	this->ingredientsModel.setIngredients(this->recipeDB->retrieveAllIngredients());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenRecipeDialog::populateTagsList(){
 | 
			
		||||
	this->tagsModel.setTags(this->recipeDB->retrieveAllTags());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenRecipeDialog::populateFoodGroupsList(){
 | 
			
		||||
	for (string s : this->recipeDB->retrieveAllFoodGroups()){
 | 
			
		||||
		ui->foodGroupsListWidget->addItem(QString::fromStdString(s));
 | 
			
		||||
	}
 | 
			
		||||
	//ui->foodGroupsListWidget->show();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenRecipeDialog::on_deleteRecipeButton_clicked(){
 | 
			
		||||
	QItemSelectionModel *selectModel = ui->recipeTableView->selectionModel();
 | 
			
		||||
	if (!selectModel->hasSelection()){
 | 
			
		||||
| 
						 | 
				
			
			@ -92,17 +74,6 @@ void OpenRecipeDialog::on_recipeTableView_doubleClicked(const QModelIndex &index
 | 
			
		|||
	this->close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenRecipeDialog::onIngredientsListViewSelectionChanged(const QItemSelection &selection){
 | 
			
		||||
	Q_UNUSED(selection);
 | 
			
		||||
	vector<Ingredient> ingredients;
 | 
			
		||||
	QModelIndexList indexes = ui->ingredientsListView->selectionModel()->selectedRows();
 | 
			
		||||
	for (QModelIndex index : indexes){
 | 
			
		||||
		Ingredient i = this->ingredientsModel.getIngredients().at(index.row());
 | 
			
		||||
		ingredients.push_back(i);
 | 
			
		||||
	}
 | 
			
		||||
	this->populateRecipesTable(this->recipeDB->retrieveRecipesWithIngredients(ingredients));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenRecipeDialog::onTagsListViewSelectionChanged(const QItemSelection &selection){
 | 
			
		||||
	Q_UNUSED(selection);
 | 
			
		||||
	vector<RecipeTag> tags;
 | 
			
		||||
| 
						 | 
				
			
			@ -119,20 +90,9 @@ void OpenRecipeDialog::on_nameEdit_textChanged(const QString &arg1){
 | 
			
		|||
	this->populateRecipesTable(this->recipeDB->retrieveRecipesWithSubstring(ui->nameEdit->text().toStdString()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenRecipeDialog::on_foodGroupsListWidget_itemSelectionChanged(){
 | 
			
		||||
	vector<string> groups;
 | 
			
		||||
	for (QModelIndex index : ui->foodGroupsListWidget->selectionModel()->selectedRows()){
 | 
			
		||||
		QListWidgetItem *item = ui->foodGroupsListWidget->item(index.row());
 | 
			
		||||
		groups.push_back(item->text().toStdString());
 | 
			
		||||
	}
 | 
			
		||||
	this->populateRecipesTable(this->recipeDB->retrieveRecipesWithFoodGroups(groups));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void OpenRecipeDialog::on_clearSearchButton_clicked(){
 | 
			
		||||
	ui->nameEdit->clear();
 | 
			
		||||
	ui->foodGroupsListWidget->selectionModel()->clearSelection();
 | 
			
		||||
	ui->tagsListView->selectionModel()->clearSelection();
 | 
			
		||||
	ui->ingredientsListView->selectionModel()->clearSelection();
 | 
			
		||||
	this->populateRecipesTable(this->recipeDB->retrieveAllRecipes());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,14 +30,10 @@ class OpenRecipeDialog : public QDialog
 | 
			
		|||
 | 
			
		||||
		void on_recipeTableView_doubleClicked(const QModelIndex &index);
 | 
			
		||||
 | 
			
		||||
		void onIngredientsListViewSelectionChanged(const QItemSelection &selection);
 | 
			
		||||
 | 
			
		||||
		void onTagsListViewSelectionChanged(const QItemSelection &selection);
 | 
			
		||||
 | 
			
		||||
		void on_nameEdit_textChanged(const QString &arg1);
 | 
			
		||||
 | 
			
		||||
		void on_foodGroupsListWidget_itemSelectionChanged();
 | 
			
		||||
 | 
			
		||||
		void on_clearSearchButton_clicked();
 | 
			
		||||
 | 
			
		||||
		void on_exitButton_clicked();
 | 
			
		||||
| 
						 | 
				
			
			@ -48,13 +44,10 @@ class OpenRecipeDialog : public QDialog
 | 
			
		|||
		RecipeTableModel recipeTableModel;
 | 
			
		||||
		Recipe selectedRecipe;
 | 
			
		||||
 | 
			
		||||
		IngredientListModel ingredientsModel;
 | 
			
		||||
		TagListModel tagsModel;
 | 
			
		||||
 | 
			
		||||
		void populateRecipesTable(vector<Recipe> recipes);
 | 
			
		||||
		void populateIngredientsList();
 | 
			
		||||
		void populateTagsList();
 | 
			
		||||
		void populateFoodGroupsList();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // OPENRECIPEDIALOG_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@
 | 
			
		|||
      <property name="spacing">
 | 
			
		||||
       <number>0</number>
 | 
			
		||||
      </property>
 | 
			
		||||
      <item alignment="Qt::AlignLeft">
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QTabWidget" name="tabWidget">
 | 
			
		||||
        <property name="minimumSize">
 | 
			
		||||
         <size>
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +63,7 @@
 | 
			
		|||
         <enum>QTabWidget::Rounded</enum>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="currentIndex">
 | 
			
		||||
         <number>2</number>
 | 
			
		||||
         <number>0</number>
 | 
			
		||||
        </property>
 | 
			
		||||
        <widget class="QWidget" name="Tags">
 | 
			
		||||
         <attribute name="icon">
 | 
			
		||||
| 
						 | 
				
			
			@ -119,105 +119,6 @@
 | 
			
		|||
          </item>
 | 
			
		||||
         </layout>
 | 
			
		||||
        </widget>
 | 
			
		||||
        <widget class="QWidget" name="ingredientsTab">
 | 
			
		||||
         <attribute name="icon">
 | 
			
		||||
          <iconset resource="../res.qrc">
 | 
			
		||||
           <normaloff>:/images/images/ingredients.png</normaloff>:/images/images/ingredients.png</iconset>
 | 
			
		||||
         </attribute>
 | 
			
		||||
         <attribute name="title">
 | 
			
		||||
          <string/>
 | 
			
		||||
         </attribute>
 | 
			
		||||
         <attribute name="toolTip">
 | 
			
		||||
          <string>Ingredients</string>
 | 
			
		||||
         </attribute>
 | 
			
		||||
         <layout class="QVBoxLayout" name="verticalLayout_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="QListView" name="ingredientsListView">
 | 
			
		||||
            <property name="sizePolicy">
 | 
			
		||||
             <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
 | 
			
		||||
              <horstretch>0</horstretch>
 | 
			
		||||
              <verstretch>0</verstretch>
 | 
			
		||||
             </sizepolicy>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="frameShape">
 | 
			
		||||
             <enum>QFrame::NoFrame</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="selectionMode">
 | 
			
		||||
             <enum>QAbstractItemView::ExtendedSelection</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="verticalScrollMode">
 | 
			
		||||
             <enum>QAbstractItemView::ScrollPerPixel</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="isWrapping" stdset="0">
 | 
			
		||||
             <bool>false</bool>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="wordWrap">
 | 
			
		||||
             <bool>true</bool>
 | 
			
		||||
            </property>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </item>
 | 
			
		||||
         </layout>
 | 
			
		||||
        </widget>
 | 
			
		||||
        <widget class="QWidget" name="foodGroups">
 | 
			
		||||
         <attribute name="icon">
 | 
			
		||||
          <iconset resource="../res.qrc">
 | 
			
		||||
           <normaloff>:/images/images/foodPyramid.png</normaloff>:/images/images/foodPyramid.png</iconset>
 | 
			
		||||
         </attribute>
 | 
			
		||||
         <attribute name="title">
 | 
			
		||||
          <string/>
 | 
			
		||||
         </attribute>
 | 
			
		||||
         <attribute name="toolTip">
 | 
			
		||||
          <string>Food Groups</string>
 | 
			
		||||
         </attribute>
 | 
			
		||||
         <layout class="QVBoxLayout" name="verticalLayout_3">
 | 
			
		||||
          <property name="spacing">
 | 
			
		||||
           <number>0</number>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="leftMargin">
 | 
			
		||||
           <number>0</number>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="topMargin">
 | 
			
		||||
           <number>0</number>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="rightMargin">
 | 
			
		||||
           <number>0</number>
 | 
			
		||||
          </property>
 | 
			
		||||
          <property name="bottomMargin">
 | 
			
		||||
           <number>0</number>
 | 
			
		||||
          </property>
 | 
			
		||||
          <item>
 | 
			
		||||
           <widget class="QListWidget" name="foodGroupsListWidget">
 | 
			
		||||
            <property name="frameShape">
 | 
			
		||||
             <enum>QFrame::NoFrame</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="selectionMode">
 | 
			
		||||
             <enum>QAbstractItemView::ExtendedSelection</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="verticalScrollMode">
 | 
			
		||||
             <enum>QAbstractItemView::ScrollPerPixel</enum>
 | 
			
		||||
            </property>
 | 
			
		||||
            <property name="wordWrap">
 | 
			
		||||
             <bool>true</bool>
 | 
			
		||||
            </property>
 | 
			
		||||
           </widget>
 | 
			
		||||
          </item>
 | 
			
		||||
         </layout>
 | 
			
		||||
        </widget>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										25
									
								
								main.cpp
								
								
								
								
							
							
						
						
									
										25
									
								
								main.cpp
								
								
								
								
							| 
						 | 
				
			
			@ -8,34 +8,11 @@
 | 
			
		|||
#include "model/database/recipedatabase.h"
 | 
			
		||||
#include "utils/fileutils.h"
 | 
			
		||||
 | 
			
		||||
void test(RecipeDatabase *recipeDB){
 | 
			
		||||
	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",
 | 
			
		||||
			   "Andrew Lalis",
 | 
			
		||||
			   ri,
 | 
			
		||||
			   Instruction("Placeholder Text"),
 | 
			
		||||
			   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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Recipe checkForFirstRun(RecipeDatabase *recipeDB){
 | 
			
		||||
	Recipe r = recipeDB->retrieveRandomRecipe();
 | 
			
		||||
	if (r.isEmpty()){//There are no recipes in the database.
 | 
			
		||||
		//Add some basic units to the units, and some basic ingredients.
 | 
			
		||||
		recipeDB->addBasicUnits();
 | 
			
		||||
		recipeDB->addBasicIngredients();
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	return r;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,10 @@ ResultTable Database::executeSQL(string statement){
 | 
			
		|||
	this->sql = statement;
 | 
			
		||||
	this->returnCode = sqlite3_prepare_v2(this->db, statement.c_str(), -1, &stmt, NULL);
 | 
			
		||||
	if (this->returnCode != SQLITE_OK){
 | 
			
		||||
		fprintf(stderr, "Unable to successfully prepare SQL statement. Error code: %d\n\tError Message: %s\n", this->returnCode, sqlite3_errmsg(this->db));
 | 
			
		||||
		fprintf(stderr, "Unable to successfully prepare SQL statement. Error code: %d\n\tError Message: %s\nSQL Statement: %s\n",
 | 
			
		||||
				this->returnCode,
 | 
			
		||||
				sqlite3_errmsg(this->db),
 | 
			
		||||
				statement.c_str());
 | 
			
		||||
		return ResultTable(this->returnCode);
 | 
			
		||||
	}
 | 
			
		||||
	ResultTable t(statement);
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +42,15 @@ bool Database::insertInto(string tableName, vector<string> columnNames, vector<s
 | 
			
		|||
	return (t.getReturnCode() == SQLITE_DONE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Database::insertInto(string tableName, string columnName, string value){
 | 
			
		||||
	if (columnName.empty() || value.empty() || tableName.empty()){
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	string query = "INSERT INTO " + tableName + " (" + columnName + ") VALUES (" + value + ");";
 | 
			
		||||
	ResultTable t = this->executeSQL(query);
 | 
			
		||||
	return (t.getReturnCode() == SQLITE_DONE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultTable Database::selectFrom(string tableName, string columnNames, string conditions){
 | 
			
		||||
	if (columnNames.size() == 0 || tableName.empty()){
 | 
			
		||||
		return ResultTable();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,8 +24,12 @@ public:
 | 
			
		|||
 | 
			
		||||
	//Executes an SQL string statement in a safe way and returns the result.
 | 
			
		||||
	ResultTable executeSQL(string statement);
 | 
			
		||||
	//Inserts into a table.
 | 
			
		||||
	bool insertInto(string tableName, vector<string> columnNames, vector<string> values);
 | 
			
		||||
	bool insertInto(string tableName, string columnName, string value);
 | 
			
		||||
	//Selects from a table.
 | 
			
		||||
	ResultTable selectFrom(string tableName, string columnNames, string conditions);
 | 
			
		||||
	//Deletes from a table.
 | 
			
		||||
	bool deleteFrom(string tableName, string conditions);
 | 
			
		||||
 | 
			
		||||
	bool tableExists(string tableName);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,66 +57,18 @@ bool RecipeDatabase::storeRecipe(Recipe recipe){
 | 
			
		|||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RecipeDatabase::storeRecipeIngredient(RecipeIngredient ri, int recipeId){
 | 
			
		||||
	int ingId = this->storeIngredient(ri);
 | 
			
		||||
	if (ingId < 0) return false;
 | 
			
		||||
 | 
			
		||||
	if (!this->storeUnitOfMeasure(ri.getUnit())) return false;
 | 
			
		||||
 | 
			
		||||
bool RecipeDatabase::storeRecipeIngredient(Ingredient i, int recipeId){
 | 
			
		||||
	return this->insertInto("recipeIngredient",
 | 
			
		||||
					 vector<string>({
 | 
			
		||||
										"ingredientId",
 | 
			
		||||
										"recipeId",
 | 
			
		||||
										"quantity",
 | 
			
		||||
										"unitName",
 | 
			
		||||
										"comment"
 | 
			
		||||
										"content",
 | 
			
		||||
										"recipeId"
 | 
			
		||||
									}),
 | 
			
		||||
					 vector<string>({
 | 
			
		||||
										std::to_string(ingId),
 | 
			
		||||
										std::to_string(recipeId),
 | 
			
		||||
										std::to_string(ri.getQuantity()),
 | 
			
		||||
										ri.getUnit().getName(),
 | 
			
		||||
										ri.getComment()
 | 
			
		||||
										i.getContent(),
 | 
			
		||||
										std::to_string(recipeId)
 | 
			
		||||
									}));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int RecipeDatabase::storeIngredient(Ingredient ingredient){
 | 
			
		||||
	ResultTable t = this->selectFrom("ingredient", "*", "WHERE name="+surroundString(ingredient.getName(), "'"));
 | 
			
		||||
	if (t.isEmpty()){
 | 
			
		||||
		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.at(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){
 | 
			
		||||
	return FileUtils::saveInstruction(recipeId, instruction);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -166,31 +118,6 @@ vector<Recipe> RecipeDatabase::retrieveAllRecipes(){
 | 
			
		|||
	return this->readRecipesFromTable(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<Recipe> RecipeDatabase::retrieveRecipesWithIngredients(vector<Ingredient> ingredients){
 | 
			
		||||
	vector<Recipe> recipes;
 | 
			
		||||
	if (ingredients.empty()){
 | 
			
		||||
		return recipes;
 | 
			
		||||
	}
 | 
			
		||||
	string filterList = surroundString(ingredients.at(0).getName(), "'");
 | 
			
		||||
	for (unsigned int i = 1; i < ingredients.size(); i++){
 | 
			
		||||
		filterList += ", " + surroundString(ingredients[i].getName(), "'");
 | 
			
		||||
	}
 | 
			
		||||
	filterList = '(' + filterList + ')';
 | 
			
		||||
	ResultTable t = this->executeSQL("SELECT * "
 | 
			
		||||
									 "FROM recipe "
 | 
			
		||||
									 "WHERE recipeId IN ("
 | 
			
		||||
									 "	SELECT recipeIngredient.recipeId "
 | 
			
		||||
									 "	FROM recipeIngredient "
 | 
			
		||||
									 "	INNER JOIN ("
 | 
			
		||||
									 "		SELECT ingredientId "
 | 
			
		||||
									 "		FROM ingredient "
 | 
			
		||||
									 "		WHERE name IN "+filterList+""
 | 
			
		||||
									 "	) filteredIngredients "
 | 
			
		||||
									 "	ON recipeIngredient.ingredientId = filteredIngredients.ingredientId"
 | 
			
		||||
									 ") ORDER BY name;");
 | 
			
		||||
	return this->readRecipesFromTable(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<Recipe> RecipeDatabase::retrieveRecipesWithTags(vector<RecipeTag> tags){
 | 
			
		||||
	vector<Recipe> recipes;
 | 
			
		||||
	if (tags.empty()){
 | 
			
		||||
| 
						 | 
				
			
			@ -210,53 +137,15 @@ vector<Recipe> RecipeDatabase::retrieveRecipesWithSubstring(string s){
 | 
			
		|||
	return this->readRecipesFromTable(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<Recipe> RecipeDatabase::retrieveRecipesWithFoodGroups(vector<string> groups){
 | 
			
		||||
	vector<Recipe> recipes;
 | 
			
		||||
	if (groups.empty()){
 | 
			
		||||
		return recipes;
 | 
			
		||||
	}
 | 
			
		||||
	string filterList = surroundString(groups.at(0), "'");
 | 
			
		||||
	for (unsigned int i = 1; i < groups.size(); i++){
 | 
			
		||||
		filterList += ", " + surroundString(groups.at(i), "'");
 | 
			
		||||
	}
 | 
			
		||||
	filterList = '(' + filterList + ')';
 | 
			
		||||
	ResultTable t = this->executeSQL("SELECT * FROM recipe WHERE recipeId IN (SELECT recipeId FROM recipeIngredient WHERE ingredientId IN (SELECT ingredientId FROM ingredient WHERE foodGroup IN "+filterList+" ) ) ORDER BY name;");
 | 
			
		||||
	return this->readRecipesFromTable(t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<string> RecipeDatabase::retrieveAllFoodGroups(){
 | 
			
		||||
	ResultTable t = this->executeSQL("SELECT DISTINCT foodGroup FROM ingredient ORDER BY foodGroup;");
 | 
			
		||||
	vector<string> foodGroups;
 | 
			
		||||
vector<Ingredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
 | 
			
		||||
	ResultTable t = this->executeSQL("SELECT content "
 | 
			
		||||
									 "FROM recipeIngredient "
 | 
			
		||||
									 "WHERE recipeId = "+std::to_string(recipeId)+";");
 | 
			
		||||
	vector<Ingredient> ingredients;
 | 
			
		||||
	for (TableRow row : t.rows()){
 | 
			
		||||
		foodGroups.push_back(row.at(0));
 | 
			
		||||
		ingredients.push_back(Ingredient(row.at(0)));
 | 
			
		||||
	}
 | 
			
		||||
	return foodGroups;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<RecipeIngredient> RecipeDatabase::retrieveRecipeIngredients(int recipeId){
 | 
			
		||||
	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 "
 | 
			
		||||
									 "INNER JOIN unitOfMeasure "
 | 
			
		||||
									 "ON recipeIngredient.unitName = unitOfMeasure.name "
 | 
			
		||||
									 "WHERE recipeIngredient.recipeId = "+std::to_string(recipeId)+";");
 | 
			
		||||
	vector<RecipeIngredient> ings;
 | 
			
		||||
	for (TableRow row : t.rows()){
 | 
			
		||||
		RecipeIngredient r(row.at(0),
 | 
			
		||||
						   row.at(1),
 | 
			
		||||
						   std::stof(row.at(2)),
 | 
			
		||||
						   UnitOfMeasure(row.at(5), row.at(6), row.at(7), std::stoi(row.at(8)), std::stod(row.at(9))),
 | 
			
		||||
						   row.at(4));
 | 
			
		||||
		ings.push_back(r);
 | 
			
		||||
	}
 | 
			
		||||
	return ings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int RecipeDatabase::retrieveIngredientId(string ingredientName){
 | 
			
		||||
	return std::stoi(this->selectFrom("ingredient", "ingredientId", "WHERE name = '"+ingredientName+"'").at(0, 0));
 | 
			
		||||
	return ingredients;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RecipeDatabase::deleteRecipeTags(int recipeId){
 | 
			
		||||
| 
						 | 
				
			
			@ -268,27 +157,14 @@ bool RecipeDatabase::deleteRecipeIngredients(int recipeId){
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
vector<Ingredient> RecipeDatabase::retrieveAllIngredients(){
 | 
			
		||||
	ResultTable t = this->selectFrom("ingredient", "name, foodGroup", "ORDER BY name");
 | 
			
		||||
	ResultTable t = this->selectFrom("recipeIngredient", "content", "ORDER BY content");
 | 
			
		||||
	vector<Ingredient> ings;
 | 
			
		||||
	for (TableRow row : t.rows()){
 | 
			
		||||
		Ingredient i(row.at(0), row.at(1));
 | 
			
		||||
		ings.push_back(i);
 | 
			
		||||
		ings.push_back(Ingredient(row.at(0)));
 | 
			
		||||
	}
 | 
			
		||||
	return ings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<UnitOfMeasure> RecipeDatabase::retrieveAllUnitsOfMeasure(){
 | 
			
		||||
	ResultTable t = this->selectFrom("unitOfMeasure", "name, plural, abbreviation, type, metricCoefficient", "ORDER BY name");
 | 
			
		||||
	vector<UnitOfMeasure> units;
 | 
			
		||||
	if (!t.isEmpty()){
 | 
			
		||||
		for (TableRow row : t.rows()){
 | 
			
		||||
			UnitOfMeasure u(row.at(0), row.at(1), row.at(2), std::stoi(row.at(3)), std::stod(row.at(4)));
 | 
			
		||||
			units.push_back(u);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return units;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<RecipeTag> RecipeDatabase::retrieveTags(int recipeId){
 | 
			
		||||
	ResultTable t = this->selectFrom("recipeTag", "tagName", "WHERE recipeId="+std::to_string(recipeId)+" ORDER BY tagName");
 | 
			
		||||
	vector<RecipeTag> tags;
 | 
			
		||||
| 
						 | 
				
			
			@ -358,14 +234,6 @@ bool RecipeDatabase::deleteIngredient(string name){
 | 
			
		|||
	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()+"'");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -405,22 +273,16 @@ bool RecipeDatabase::updateRecipe(Recipe recipe, string originalName) {
 | 
			
		|||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	bool ingredientsSuccess = this->deleteRecipeIngredients(id);
 | 
			
		||||
	for (RecipeIngredient ri : recipe.getIngredients()){
 | 
			
		||||
	for (Ingredient i : recipe.getIngredients()){
 | 
			
		||||
		ingredientsSuccess = ingredientsSuccess && this->insertInto(
 | 
			
		||||
					"recipeIngredient",
 | 
			
		||||
					vector<string>({
 | 
			
		||||
									   "recipeId",
 | 
			
		||||
									   "ingredientId",
 | 
			
		||||
									   "unitName",
 | 
			
		||||
									   "quantity",
 | 
			
		||||
									   "comment"
 | 
			
		||||
									   "content"
 | 
			
		||||
								   }),
 | 
			
		||||
					vector<string>({
 | 
			
		||||
									   idS,
 | 
			
		||||
									   std::to_string(this->retrieveIngredientId(ri.getName())),
 | 
			
		||||
									   ri.getUnit().getName(),
 | 
			
		||||
									   std::to_string(ri.getQuantity()),
 | 
			
		||||
									   ri.getComment()
 | 
			
		||||
									   i.getContent()
 | 
			
		||||
								   }));
 | 
			
		||||
	}
 | 
			
		||||
	if (!ingredientsSuccess){
 | 
			
		||||
| 
						 | 
				
			
			@ -438,67 +300,11 @@ bool RecipeDatabase::updateRecipe(Recipe recipe, string originalName) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RecipeDatabase::addBasicUnits(){
 | 
			
		||||
	this->beginTransaction();
 | 
			
		||||
	//Volume
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Teaspoon", "Teaspoons", "tsp", UnitOfMeasure::VOLUME, 5.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Tablespoon", "Tablespoons", "tbsp", UnitOfMeasure::VOLUME, 15.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Fluid Ounce", "Fluid Ounces", "fl oz", UnitOfMeasure::VOLUME, 30.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Cup", "Cups", "c", UnitOfMeasure::VOLUME, 250.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Milliliter", "Milliliters", "mL", UnitOfMeasure::VOLUME, 1.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Liter", "Liters", "L", UnitOfMeasure::VOLUME, 1000.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Gallon", "Gallons", "gal", UnitOfMeasure::VOLUME, 3800.0));
 | 
			
		||||
	//Mass/Weight
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Ounce", "Ounces", "oz", UnitOfMeasure::MASS, 28.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Pound", "Pounds", "lb", UnitOfMeasure::MASS, 454.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Gram", "Grams", "g", UnitOfMeasure::MASS, 1.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Milligram", "Milligrams", "mg", UnitOfMeasure::MASS, 0.001));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Kilogram", "Kilograms", "kg", UnitOfMeasure::MASS, 1000.0));
 | 
			
		||||
	//Length
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Inch", "Inches", "in", UnitOfMeasure::LENGTH, 2.54));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Centimeter", "Centimeters", "cm", UnitOfMeasure::LENGTH, 1.0));
 | 
			
		||||
	//MISC
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Piece", "Pieces", "pc", UnitOfMeasure::MISC, 1.0));
 | 
			
		||||
	this->storeUnitOfMeasure(UnitOfMeasure("Item", "Items", "", UnitOfMeasure::MISC, 1.0));
 | 
			
		||||
	this->commitTransaction();
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RecipeDatabase::addBasicIngredients(){
 | 
			
		||||
	this->beginTransaction();
 | 
			
		||||
	this->storeIngredient(Ingredient("Flour", "grains"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Eggs", "eggs"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Milk", "dairy"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Cheese", "dairy"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Salt", "spices"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Sugar", "sugars"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Vegetable Oil", "oils"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Olive Oil", "oils"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Water", "water"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Bell Pepper", "vegetables"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Onion", "vegetables"));
 | 
			
		||||
	this->storeIngredient(Ingredient("Garlic", "spices"));
 | 
			
		||||
	this->commitTransaction();
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecipeDatabase::ensureTablesExist(){
 | 
			
		||||
	//Make sure that foreign keys are enabled.
 | 
			
		||||
	this->executeSQL("PRAGMA foreign_keys = ON;");
 | 
			
		||||
 | 
			
		||||
	this->beginTransaction();
 | 
			
		||||
	//Ingredients table.
 | 
			
		||||
	this->executeSQL("CREATE TABLE IF NOT EXISTS ingredient("
 | 
			
		||||
					 "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,"
 | 
			
		||||
| 
						 | 
				
			
			@ -515,14 +321,9 @@ void RecipeDatabase::ensureTablesExist(){
 | 
			
		|||
					 "FOREIGN KEY (recipeId) REFERENCES recipe(recipeId));");
 | 
			
		||||
	//RecipeIngredient table.
 | 
			
		||||
	this->executeSQL("CREATE TABLE IF NOT EXISTS recipeIngredient("
 | 
			
		||||
					 "ingredientId int,"
 | 
			
		||||
					 "recipeId int,"
 | 
			
		||||
					 "quantity real,"
 | 
			
		||||
					 "unitName varchar,"
 | 
			
		||||
					 "comment varchar,"
 | 
			
		||||
					 "FOREIGN KEY (ingredientId) REFERENCES ingredient(ingredientId),"
 | 
			
		||||
					 "FOREIGN KEY (recipeId) REFERENCES recipe(recipeId),"
 | 
			
		||||
					 "FOREIGN KEY (unitName) REFERENCES unitOfMeasure(name));");
 | 
			
		||||
					 "content,"
 | 
			
		||||
					 "FOREIGN KEY (recipeId) REFERENCES recipe(recipeId));");
 | 
			
		||||
	this->commitTransaction();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,21 +23,15 @@ class RecipeDatabase : public Database
 | 
			
		|||
 | 
			
		||||
		//SQL Helper methods.
 | 
			
		||||
		//Storage.
 | 
			
		||||
		bool storeRecipeIngredient(RecipeIngredient ri, int recipeId);
 | 
			
		||||
		int storeIngredient(Ingredient ingredient);
 | 
			
		||||
		bool storeUnitOfMeasure(UnitOfMeasure u);
 | 
			
		||||
		bool storeRecipeIngredient(Ingredient i, int recipeId);
 | 
			
		||||
 | 
			
		||||
		//Retrieval.
 | 
			
		||||
		Recipe retrieveRecipe(string name);
 | 
			
		||||
		Recipe retrieveRandomRecipe();
 | 
			
		||||
		vector<Recipe> retrieveAllRecipes();
 | 
			
		||||
		vector<Recipe> retrieveRecipesWithIngredients(vector<Ingredient> ingredients);
 | 
			
		||||
		vector<Recipe> retrieveRecipesWithTags(vector<RecipeTag> tags);
 | 
			
		||||
		vector<Recipe> retrieveRecipesWithSubstring(string s);
 | 
			
		||||
		vector<Recipe> retrieveRecipesWithFoodGroups(vector<string> groups);
 | 
			
		||||
		vector<string> retrieveAllFoodGroups();
 | 
			
		||||
		vector<Ingredient> retrieveAllIngredients();
 | 
			
		||||
		vector<UnitOfMeasure> retrieveAllUnitsOfMeasure();
 | 
			
		||||
		vector<RecipeTag> retrieveAllTags();
 | 
			
		||||
 | 
			
		||||
		//Deletion.
 | 
			
		||||
| 
						 | 
				
			
			@ -50,9 +44,6 @@ class RecipeDatabase : public Database
 | 
			
		|||
		//Updating.
 | 
			
		||||
		bool updateRecipe(Recipe recipe, string originalName);
 | 
			
		||||
 | 
			
		||||
		//Adding basic information at start.
 | 
			
		||||
		bool addBasicUnits();
 | 
			
		||||
		bool addBasicIngredients();
 | 
			
		||||
	private:
 | 
			
		||||
 | 
			
		||||
		//Utility methods.
 | 
			
		||||
| 
						 | 
				
			
			@ -68,8 +59,7 @@ class RecipeDatabase : public Database
 | 
			
		|||
 | 
			
		||||
		//Retrieval
 | 
			
		||||
		vector<RecipeTag> retrieveTags(int recipeId);
 | 
			
		||||
		vector<RecipeIngredient> retrieveRecipeIngredients(int recipeId);
 | 
			
		||||
		int retrieveIngredientId(string ingredientName);
 | 
			
		||||
		vector<Ingredient> retrieveRecipeIngredients(int recipeId);
 | 
			
		||||
 | 
			
		||||
		//Deletion
 | 
			
		||||
		bool deleteRecipeTags(int recipeId);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,31 +1,18 @@
 | 
			
		|||
#include "model/recipe/ingredients/ingredient.h"
 | 
			
		||||
 | 
			
		||||
Ingredient::Ingredient(){
 | 
			
		||||
    setName("NULL");
 | 
			
		||||
    setFoodGroup("NULL");
 | 
			
		||||
	setContent("NULL");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Ingredient::Ingredient(string name, string foodGroup){
 | 
			
		||||
    setName(name);
 | 
			
		||||
    setFoodGroup(foodGroup);
 | 
			
		||||
Ingredient::Ingredient(string content){
 | 
			
		||||
	setContent(content);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string Ingredient::getName() const{
 | 
			
		||||
    return this->name;
 | 
			
		||||
string Ingredient::getContent() const{
 | 
			
		||||
	return this->content;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string Ingredient::getFoodGroup() const{
 | 
			
		||||
    return this->foodGroup;
 | 
			
		||||
void Ingredient::setContent(string newContent){
 | 
			
		||||
	this->content = newContent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Ingredient::setName(string newName){
 | 
			
		||||
    this->name = newName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Ingredient::setFoodGroup(string newFoodGroup){
 | 
			
		||||
	this->foodGroup = newFoodGroup;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string Ingredient::toString(){
 | 
			
		||||
	return this->getName();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,28 +6,25 @@
 | 
			
		|||
using namespace std;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The Ingredient class represents an ingredient, which is classified by a food group, and has a name and an ID.
 | 
			
		||||
 * An ingredient cannot be included on its own in a recipe, and must be paired with a Unit in a RecipeIngredient Object.
 | 
			
		||||
 * @brief The Ingredient class represents an ingredient, which is a string representing one component of a recipe.
 | 
			
		||||
 * The user is free to compose a recipe string however they like. However, the program will restrict obviously
 | 
			
		||||
 * invalid input, and try to be smart about determining if an ingredient is valid.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class Ingredient
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    Ingredient();
 | 
			
		||||
    Ingredient(string name, string foodGroup);
 | 
			
		||||
	Ingredient(string content);
 | 
			
		||||
 | 
			
		||||
    //Getters
 | 
			
		||||
    string getName() const;
 | 
			
		||||
    string getFoodGroup() const;
 | 
			
		||||
	string getContent() const;
 | 
			
		||||
 | 
			
		||||
    //Setters
 | 
			
		||||
    void setName(string newName);
 | 
			
		||||
    void setFoodGroup(string newFoodGroup);
 | 
			
		||||
	void setContent(string newContent);
 | 
			
		||||
 | 
			
		||||
	string toString();
 | 
			
		||||
protected:
 | 
			
		||||
    string name;
 | 
			
		||||
    string foodGroup;
 | 
			
		||||
	string content;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // INGREDIENT_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ QVariant IngredientListModel::data(const QModelIndex &index, int role) const{
 | 
			
		|||
    int row = index.row();
 | 
			
		||||
	Ingredient i = this->ingredients[row];
 | 
			
		||||
 | 
			
		||||
	string displayStr = i.toString();
 | 
			
		||||
	string displayStr = i.getContent();
 | 
			
		||||
 | 
			
		||||
    switch(role){
 | 
			
		||||
    case Qt::DisplayRole:
 | 
			
		||||
| 
						 | 
				
			
			@ -30,14 +30,15 @@ void IngredientListModel::setIngredients(vector<Ingredient> ingredients){
 | 
			
		|||
	emit dataChanged(index, bottomIndex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool IngredientListModel::addIngredient(Ingredient ri){
 | 
			
		||||
bool IngredientListModel::addIngredient(Ingredient i){
 | 
			
		||||
	//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())){
 | 
			
		||||
	for (Ingredient ing : this->ingredients){
 | 
			
		||||
		if (!ing.getContent().compare(i.getContent())){
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this->ingredients.push_back(ri);
 | 
			
		||||
	//The ingredient doesn't exist already, so we'll add it.
 | 
			
		||||
	this->ingredients.push_back(i);
 | 
			
		||||
	QModelIndex index = createIndex(this->ingredients.size()-1, 0);
 | 
			
		||||
	QModelIndex bottomIndex = createIndex(this->ingredients.size()-1, 0);
 | 
			
		||||
	emit dataChanged(index, bottomIndex);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,9 +3,16 @@
 | 
			
		|||
 | 
			
		||||
#include <QAbstractListModel>
 | 
			
		||||
#include <QModelIndex>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "model/recipe/ingredients/recipeingredient.h"
 | 
			
		||||
#include "model/recipe/ingredients/ingredient.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The IngredientListModel class
 | 
			
		||||
 *
 | 
			
		||||
 * The ingredient list model extends the QAbstractListModel and is used for lists of ingredients,
 | 
			
		||||
 * whether they appear in the NewRecipe dialog or in the main recipe view.
 | 
			
		||||
 */
 | 
			
		||||
class IngredientListModel : public QAbstractListModel
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
| 
						 | 
				
			
			@ -17,15 +24,13 @@ public:
 | 
			
		|||
 | 
			
		||||
    //Custom methods to handle ingredient data.
 | 
			
		||||
	void setIngredients(vector<Ingredient> ingredients);
 | 
			
		||||
	bool addIngredient(Ingredient ri);
 | 
			
		||||
	bool addIngredient(Ingredient i);
 | 
			
		||||
	void deleteIngredient(int index);
 | 
			
		||||
	vector<Ingredient> getIngredients();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	vector<Ingredient> ingredients;
 | 
			
		||||
 | 
			
		||||
	//Helper for printing.
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // INGREDIENTLISTMODEL_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,60 +0,0 @@
 | 
			
		|||
#include "model/recipe/ingredients/recipeingredient.h"
 | 
			
		||||
 | 
			
		||||
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, string comment){
 | 
			
		||||
    setName(i.getName());
 | 
			
		||||
    setFoodGroup(i.getFoodGroup());
 | 
			
		||||
    setQuantity(quantity);
 | 
			
		||||
	setUnit(unit);
 | 
			
		||||
	setComment(comment);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RecipeIngredient::RecipeIngredient(Ingredient &i) : RecipeIngredient(i, 0.0f, UnitOfMeasure("bleh"), "Fuck"){
 | 
			
		||||
	//Constructs recipe ingredient from ingredient which is a hidden recipe ingredient.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RecipeIngredient::RecipeIngredient(){
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
float RecipeIngredient::getQuantity() const{
 | 
			
		||||
    return this->quantity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
UnitOfMeasure RecipeIngredient::getUnit() const{
 | 
			
		||||
    return this->unit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string RecipeIngredient::getComment() const{
 | 
			
		||||
    return this->comment;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecipeIngredient::setQuantity(float newQuantity){
 | 
			
		||||
    this->quantity = newQuantity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecipeIngredient::setUnit(UnitOfMeasure newUnit){
 | 
			
		||||
    this->unit = newUnit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecipeIngredient::setComment(string newComment){
 | 
			
		||||
	this->comment = newComment;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string RecipeIngredient::toString(){
 | 
			
		||||
	string result;
 | 
			
		||||
	if (std::ceil(this->getQuantity()) == this->getQuantity()){
 | 
			
		||||
		result += std::to_string((int)this->getQuantity());
 | 
			
		||||
	} else {
 | 
			
		||||
		result += StringUtils::toString(this->getQuantity());
 | 
			
		||||
	}
 | 
			
		||||
	result += " " + this->getUnit().getAbbreviation() + " " + this->getName();
 | 
			
		||||
	if (!this->getComment().empty()) result += " (" + this->getComment() + ")";
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,43 +0,0 @@
 | 
			
		|||
#ifndef RECIPEINGREDIENT_H
 | 
			
		||||
#define RECIPEINGREDIENT_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
 | 
			
		||||
#include "model/recipe/ingredients/ingredient.h"
 | 
			
		||||
#include "model/recipe/ingredients/unitofmeasure.h"
 | 
			
		||||
#include "utils/stringutils.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The RecipeIngredient class represents both an ingredient and a unit of measure, to be used in a recipe object.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class RecipeIngredient : public Ingredient
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    //Constructor for new RecipeIngredient without starting child ingredient.
 | 
			
		||||
	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, string comment);
 | 
			
		||||
	RecipeIngredient(Ingredient &i);
 | 
			
		||||
	RecipeIngredient();
 | 
			
		||||
 | 
			
		||||
    //Getters
 | 
			
		||||
    float getQuantity() const;
 | 
			
		||||
    UnitOfMeasure getUnit() const;
 | 
			
		||||
    string getComment() const;
 | 
			
		||||
 | 
			
		||||
    //Setters
 | 
			
		||||
    void setQuantity(float newQuantity);
 | 
			
		||||
    void setUnit(UnitOfMeasure newUnit);
 | 
			
		||||
    void setComment(string newComment);
 | 
			
		||||
	string toString();
 | 
			
		||||
private:
 | 
			
		||||
    float quantity;
 | 
			
		||||
    UnitOfMeasure unit;
 | 
			
		||||
    string comment;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // RECIPEINGREDIENT_H
 | 
			
		||||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
#include "recipeingredientlistmodel.h"
 | 
			
		||||
 | 
			
		||||
RecipeIngredientListModel::RecipeIngredientListModel(){
 | 
			
		||||
	this->ingredients = vector<RecipeIngredient>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int RecipeIngredientListModel::rowCount(const QModelIndex &parent) const{
 | 
			
		||||
	Q_UNUSED(parent);
 | 
			
		||||
	return this->ingredients.size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVariant RecipeIngredientListModel::data(const QModelIndex &index, int role) const{
 | 
			
		||||
	int row = index.row();
 | 
			
		||||
	RecipeIngredient i = this->ingredients[row];
 | 
			
		||||
 | 
			
		||||
	string displayStr = i.toString();
 | 
			
		||||
 | 
			
		||||
	switch(role){
 | 
			
		||||
	case Qt::DisplayRole:
 | 
			
		||||
		return QString::fromStdString(displayStr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return QVariant();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecipeIngredientListModel::setIngredients(vector<RecipeIngredient> ingredients){
 | 
			
		||||
	this->ingredients = ingredients;
 | 
			
		||||
	QModelIndex index = createIndex(0, 0);
 | 
			
		||||
	QModelIndex bottomIndex = createIndex(ingredients.size()-1, 0);
 | 
			
		||||
	emit dataChanged(index, bottomIndex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RecipeIngredientListModel::addIngredient(RecipeIngredient ri){
 | 
			
		||||
	//Add only if it doesn't exist already.
 | 
			
		||||
	for (unsigned int i = 0; i < this->ingredients.size(); i++){
 | 
			
		||||
		if (!this->ingredients[i].getName().compare(ri.getName())){
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	this->ingredients.push_back(ri);
 | 
			
		||||
	QModelIndex index = createIndex(this->ingredients.size()-1, 0);
 | 
			
		||||
	QModelIndex bottomIndex = createIndex(this->ingredients.size()-1, 0);
 | 
			
		||||
	emit dataChanged(index, bottomIndex);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecipeIngredientListModel::deleteIngredient(int index){
 | 
			
		||||
	this->ingredients.erase(this->ingredients.begin() + index);
 | 
			
		||||
	emit dataChanged(createIndex(0, 0), createIndex(this->ingredients.size()-1, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<RecipeIngredient> RecipeIngredientListModel::getIngredients(){
 | 
			
		||||
	return this->ingredients;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,28 +0,0 @@
 | 
			
		|||
#ifndef RECIPEINGREDIENTLISTMODEL_H
 | 
			
		||||
#define RECIPEINGREDIENTLISTMODEL_H
 | 
			
		||||
 | 
			
		||||
#include <QAbstractListModel>
 | 
			
		||||
 | 
			
		||||
#include "model/recipe/ingredients/recipeingredient.h"
 | 
			
		||||
 | 
			
		||||
class RecipeIngredientListModel : public QAbstractListModel
 | 
			
		||||
{
 | 
			
		||||
	public:
 | 
			
		||||
		RecipeIngredientListModel();
 | 
			
		||||
 | 
			
		||||
		//Overridden methods.
 | 
			
		||||
		int rowCount(const QModelIndex &parent = QModelIndex()) const override;
 | 
			
		||||
		QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
 | 
			
		||||
 | 
			
		||||
		//Custom methods to handle ingredient data.
 | 
			
		||||
		void setIngredients(vector<RecipeIngredient> ingredients);
 | 
			
		||||
		bool addIngredient(RecipeIngredient ri);
 | 
			
		||||
		void deleteIngredient(int index);
 | 
			
		||||
		vector<RecipeIngredient> getIngredients();
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		vector<RecipeIngredient> ingredients;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // RECIPEINGREDIENTLISTMODEL_H
 | 
			
		||||
| 
						 | 
				
			
			@ -1,42 +0,0 @@
 | 
			
		|||
#include "unitofmeasure.h"
 | 
			
		||||
 | 
			
		||||
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("", "", "", MISC, 1.0){
 | 
			
		||||
    //Default constructor initializes all fields to empty strings.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string UnitOfMeasure::getName() const{
 | 
			
		||||
    return this->name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string UnitOfMeasure::getNamePlural() const{
 | 
			
		||||
    return this->plural;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
string UnitOfMeasure::getAbbreviation() const{
 | 
			
		||||
	return this->abbreviation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int UnitOfMeasure::getType() const{
 | 
			
		||||
	return this->type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double UnitOfMeasure::getMetricCoefficient() const{
 | 
			
		||||
	return this->metricCoefficient;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,42 +0,0 @@
 | 
			
		|||
#ifndef UNITOFMEASURE_H
 | 
			
		||||
#define UNITOFMEASURE_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The UnitOfMeasure class represents a way to measure an ingredient. It contains a name, an abbreviation, plural name, and some information on conversion.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class UnitOfMeasure
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	//Constants Declarations.
 | 
			
		||||
	static const int MASS = 0;
 | 
			
		||||
	static const int VOLUME = 1;
 | 
			
		||||
	static const int LENGTH = 2;
 | 
			
		||||
	static const int MISC = 3;
 | 
			
		||||
 | 
			
		||||
    //Full constructor.
 | 
			
		||||
	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.
 | 
			
		||||
    UnitOfMeasure();
 | 
			
		||||
 | 
			
		||||
    //Getters
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
#include "model/recipe/recipe.h"
 | 
			
		||||
 | 
			
		||||
Recipe::Recipe(string name, string author, vector<RecipeIngredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings){
 | 
			
		||||
Recipe::Recipe(string name, string author, vector<Ingredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings){
 | 
			
		||||
    setName(name);
 | 
			
		||||
	setAuthor(author);
 | 
			
		||||
    setIngredients(ingredients);
 | 
			
		||||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ Recipe::Recipe(string name, string author, vector<RecipeIngredient> ingredients,
 | 
			
		|||
    setServings(servings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Recipe::Recipe() : Recipe::Recipe("", "", vector<RecipeIngredient>(), Instruction(), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(), QTime(), 1.0f){
 | 
			
		||||
Recipe::Recipe() : Recipe::Recipe("", "", vector<Ingredient>(), Instruction(), QImage(), vector<RecipeTag>(), QDate::currentDate(), QTime(), QTime(), 1.0f){
 | 
			
		||||
    //Set default values when none are specified.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -25,20 +25,10 @@ string Recipe::getAuthor() const{
 | 
			
		|||
	return this->authorName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<RecipeIngredient> Recipe::getIngredients() const{
 | 
			
		||||
vector<Ingredient> Recipe::getIngredients() const{
 | 
			
		||||
	return this->ingredients;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
vector<string> Recipe::getFoodGroups() const{
 | 
			
		||||
	vector<string> foodGroups;
 | 
			
		||||
	for (RecipeIngredient ri : this->ingredients){
 | 
			
		||||
		if (find(foodGroups.begin(), foodGroups.end(), ri.getFoodGroup()) == foodGroups.end()){
 | 
			
		||||
			foodGroups.push_back(ri.getFoodGroup());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return foodGroups;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Instruction Recipe::getInstruction() const{
 | 
			
		||||
    return this->instruction;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +73,7 @@ void Recipe::setAuthor(string newName){
 | 
			
		|||
	this->authorName = newName;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Recipe::setIngredients(vector<RecipeIngredient> ingredients){
 | 
			
		||||
void Recipe::setIngredients(vector<Ingredient> ingredients){
 | 
			
		||||
    this->ingredients = ingredients;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +81,7 @@ void Recipe::setTags(vector<RecipeTag> tags){
 | 
			
		|||
    this->tags = tags;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Recipe::addIngredient(RecipeIngredient newIngredient){
 | 
			
		||||
void Recipe::addIngredient(Ingredient newIngredient){
 | 
			
		||||
    this->ingredients.push_back(newIngredient);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,17 +119,11 @@ void Recipe::print(){
 | 
			
		|||
		   this->servings);
 | 
			
		||||
	printf("\tInstruction: %s\n", this->instruction.getHTML().c_str());
 | 
			
		||||
	printf("\tIngredients:\n");
 | 
			
		||||
	for (vector<RecipeIngredient>::iterator it = this->ingredients.begin(); it != this->ingredients.end(); ++it){
 | 
			
		||||
		RecipeIngredient ri = *it;
 | 
			
		||||
		printf("\t\t%s, Food Group: %s, Quantity: %f, Unit: %s\n",
 | 
			
		||||
			   ri.getName().c_str(),
 | 
			
		||||
			   ri.getFoodGroup().c_str(),
 | 
			
		||||
			   ri.getQuantity(),
 | 
			
		||||
			   ri.getUnit().getName().c_str());
 | 
			
		||||
	for (Ingredient i : this->ingredients){
 | 
			
		||||
		printf("\t\t%s\n", i.getContent().c_str());
 | 
			
		||||
	}
 | 
			
		||||
	printf("\tTags:\n");
 | 
			
		||||
	for (vector<RecipeTag>::iterator it = this->tags.begin(); it != this->tags.end(); ++it){
 | 
			
		||||
		RecipeTag t = *it;
 | 
			
		||||
	for (RecipeTag t : this->tags){
 | 
			
		||||
		printf("\t\t%s\n", t.getValue().c_str());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
#include <QImage>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include "model/recipe/ingredients/recipeingredient.h"
 | 
			
		||||
#include "model/recipe/ingredients/ingredient.h"
 | 
			
		||||
#include "model/recipe/instruction.h"
 | 
			
		||||
#include "model/recipe/tags/recipetag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -32,14 +32,14 @@ class Recipe
 | 
			
		|||
{
 | 
			
		||||
public:
 | 
			
		||||
    //Full constructor
 | 
			
		||||
	Recipe(string name, string author, vector<RecipeIngredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings);
 | 
			
		||||
	Recipe(string name, string author, vector<Ingredient> ingredients, Instruction instruction, QImage image, vector<RecipeTag> tags, QDate createdDate, QTime prepTime, QTime cookTime, float servings);
 | 
			
		||||
    //Constructor with default values.
 | 
			
		||||
    Recipe();
 | 
			
		||||
 | 
			
		||||
    //Getters
 | 
			
		||||
    string getName() const;
 | 
			
		||||
	string getAuthor() const;
 | 
			
		||||
    vector<RecipeIngredient> getIngredients() const;
 | 
			
		||||
	vector<Ingredient> getIngredients() const;
 | 
			
		||||
	vector<string> getFoodGroups() const;
 | 
			
		||||
    Instruction getInstruction() const;
 | 
			
		||||
    QImage getImage() const;
 | 
			
		||||
| 
						 | 
				
			
			@ -54,9 +54,9 @@ public:
 | 
			
		|||
    //Setters
 | 
			
		||||
    void setName(string newName);
 | 
			
		||||
	void setAuthor(string newName);
 | 
			
		||||
    void setIngredients(vector<RecipeIngredient> ingredients);
 | 
			
		||||
	void setIngredients(vector<Ingredient> ingredients);
 | 
			
		||||
    void setTags(vector<RecipeTag> tags);
 | 
			
		||||
    void addIngredient(RecipeIngredient newIngredient);
 | 
			
		||||
	void addIngredient(Ingredient newIngredient);
 | 
			
		||||
    void setInstruction(Instruction newInstruction);
 | 
			
		||||
    void setImage(QImage newImage);
 | 
			
		||||
    void setCreatedDate(QDate newDate);
 | 
			
		||||
| 
						 | 
				
			
			@ -64,12 +64,13 @@ public:
 | 
			
		|||
    void setCookTime(QTime newTime);
 | 
			
		||||
    void setServings(float newServingsCount);
 | 
			
		||||
 | 
			
		||||
	//Prints information about the recipe to the console, for debugging.
 | 
			
		||||
	void print();
 | 
			
		||||
private:
 | 
			
		||||
    //Main information.
 | 
			
		||||
    string name;                                //The name of the recipe.
 | 
			
		||||
	string authorName;							//The name of the author of this recipe.
 | 
			
		||||
    vector<RecipeIngredient> ingredients;       //The list of ingredients in the recipe.
 | 
			
		||||
	vector<Ingredient> ingredients;			    //The list of ingredients in the recipe.
 | 
			
		||||
    Instruction instruction;                    //The instruction HTML document.
 | 
			
		||||
    QImage image;                               //An image displayed alongside the recipe.
 | 
			
		||||
    //Auxiliary Information.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue