From dcfd897f3155f978bea1e94259a2de7bed87534e Mon Sep 17 00:00:00 2001
From: victor <taehoon@falinux.com>
Date: Wed, 24 May 2017 17:03:34 +0900
Subject: [PATCH] =?UTF-8?q?=EC=88=98=EB=8F=99=20=EC=9A=94=EB=A6=AC=20?=
 =?UTF-8?q?=EB=A7=8C=EB=93=A4=EA=B8=B0=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 app/gui/oven_control/cookprogram.cpp               | 714 +++++++++++++++
 app/gui/oven_control/cookprogram.h                 |  20 +
 app/gui/oven_control/oven_control.pro              |  17 +-
 .../programmingmanualcoretemppopup.cpp             |  30 +
 .../oven_control/programmingmanualcoretemppopup.h  |  10 +
 .../oven_control/programmingmanualcoretemppopup.ui | 219 ++++-
 app/gui/oven_control/programmingmanualwindow.cpp   | 229 ++++-
 app/gui/oven_control/programmingmanualwindow.h     |  32 +-
 app/gui/oven_control/programmingmanualwindow.ui    | 990 ++++++++++++++++++++-
 .../oven_control/programmingselectionwindow.cpp    |  93 ++
 app/gui/oven_control/programmingselectionwindow.h  |  25 +
 app/gui/oven_control/programmingselectionwindow.ui | 698 ++++++++++++++-
 app/gui/oven_control/programmingwindow.cpp         | 188 ++++
 app/gui/oven_control/programmingwindow.h           |  25 +
 app/gui/oven_control/programmingwindow.ui          |  96 +-
 15 files changed, 3351 insertions(+), 35 deletions(-)
 create mode 100644 app/gui/oven_control/cookprogram.cpp
 create mode 100644 app/gui/oven_control/cookprogram.h

diff --git a/app/gui/oven_control/cookprogram.cpp b/app/gui/oven_control/cookprogram.cpp
new file mode 100644
index 0000000..1671936
--- /dev/null
+++ b/app/gui/oven_control/cookprogram.cpp
@@ -0,0 +1,714 @@
+#include "cookprogram.h"
+
+#include <QTimer>
+
+#include "cookbook.h"
+
+namespace {
+Define::CookType toCookType(QString type)
+{
+    if (type == "poutry")
+        return Define::Poultry;
+    if (type == "meat")
+        return Define::Meat;
+    if (type == "fish")
+        return Define::Fish;
+    if (type == "desert")
+        return Define::Desert;
+    if (type == "vegetable")
+        return Define::Vegetable;
+    if (type == "bread")
+        return Define::Bread;
+    if (type == "etc")
+        return Define::Etc;
+
+    return Define::InvalidCookType;
+}
+
+QString toString(Define::CookType type)
+{
+    switch (type)
+    {
+    case Define::Poultry:
+        return "poultry";
+    case Define::Meat:
+        return "meat";
+    case Define::Fish:
+        return "fish";
+    case Define::Desert:
+        return "desert";
+    case Define::Vegetable:
+        return "vegetable";
+    case Define::Bread:
+        return "bread";
+    case Define::Etc:
+        return "etc";
+    default:
+        return QString();
+    }
+}
+
+Define::Mode toMode(QString mode)
+{
+    if (mode == "steam")
+        return Define::SteamMode;
+    if (mode == "combi")
+        return Define::CombiMode;
+    if (mode == "dry")
+        return Define::DryMode;
+
+    return Define::InvalidMode;
+}
+
+QString toString(Define::Mode mode)
+{
+    switch (mode)
+    {
+    case Define::SteamMode:
+        return "steam";
+    case Define::CombiMode:
+        return "combi";
+    case Define::DryMode:
+        return "dry";
+    default:
+        return QString();
+    }
+}
+
+QString name(Define::CookType type, QString root)
+{
+    CookBook book(type);
+    return book.name(root);
+}
+}
+
+namespace {
+
+const int maxAuto = 20;
+const int maxManual = 20;
+
+struct AutoEntry
+{
+    int id;
+    QString name;
+    Define::CookType type;
+    QString root;
+    int configs[5];
+
+    bool operator==(const AutoEntry &other)
+    {
+        for (int i = 0; i < 5; i++)
+            if (configs[i] != other.configs[i])
+                return false;
+
+        return id == other.id
+                && name == other.name
+                && type == other.type
+                && root == other.root;
+    }
+};
+
+struct ManualEntry
+{
+    int id;
+    QString name;
+    Define::Mode mode;
+    int humidity;
+    int temp;
+    int time;
+    int fan;
+    int coreTemp;
+
+    bool operator==(const ManualEntry &other)
+    {
+        return id == other.id
+                && name == other.name
+                && mode == other.mode
+                && humidity == other.humidity
+                && temp == other.temp
+                && time == other.time
+                && fan == other.fan
+                && coreTemp == other.coreTemp;
+    }
+};
+
+QList<AutoEntry> savedAutoList;
+QList<ManualEntry> savedManualList;
+QList<AutoEntry> currentAutoList;
+QList<ManualEntry> currentManualList;
+
+void readAuto()
+{
+    QFile file("/prime/program/auto.csv");
+    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+    {
+        qDebug() << "File not found: " + file.fileName();
+        return;
+    }
+
+    QString errorMessage = QString("%3: %1, line %2").arg(file.fileName());
+    int lineCount = 0;
+    while (!file.atEnd())
+    {
+        lineCount++;
+
+        QString line = QString::fromUtf8(file.readLine()).trimmed();
+        if (line.isEmpty())
+            continue;
+
+        QString error = errorMessage.arg(lineCount);
+
+        QString id = line.section(',', 0, 0).trimmed();
+        if (id.isEmpty())
+        {
+            qDebug() << error.arg("Invalid id");
+            continue;
+        }
+
+        QString name = line.section(',', 1, 1).trimmed();
+        if (name.isEmpty())
+        {
+            qDebug() << error.arg("Invalid name");
+            continue;
+        }
+
+        QString type = line.section(',', 2, 2).trimmed();
+        if (type.isEmpty())
+        {
+            qDebug() << error.arg("Invalid type");
+            continue;
+        }
+
+        QString root = line.section(',', 3, 3).trimmed();
+        if (root.isEmpty())
+        {
+            qDebug() << error.arg("Invalid root");
+            continue;
+        }
+
+        QString config1 = line.section(',', 4, 4).trimmed();
+        if (config1.isEmpty())
+        {
+            qDebug() << error.arg("Invalid config1");
+            continue;
+        }
+
+        QString config2 = line.section(',', 5, 5).trimmed();
+        if (config2.isEmpty())
+        {
+            qDebug() << error.arg("Invalid config2");
+            continue;
+        }
+
+        QString config3 = line.section(',', 6, 6).trimmed();
+        if (config3.isEmpty())
+        {
+            qDebug() << error.arg("Invalid config3");
+            continue;
+        }
+
+        QString config4 = line.section(',', 7, 7).trimmed();
+        if (config4.isEmpty())
+        {
+            qDebug() << error.arg("Invalid config4");
+            continue;
+        }
+
+        QString config5 = line.section(',', 8, 8).trimmed();
+        if (config5.isEmpty())
+        {
+            qDebug() << error.arg("Invalid config5");
+            continue;
+        }
+
+        AutoEntry e;
+
+        bool ok;
+        e.id = id.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid id");
+            continue;
+        }
+
+        e.name = name.replace("\\c", ",");
+
+        e.type = toCookType(type);
+        if (e.type == Define::InvalidCookType)
+        {
+            qDebug() << error.arg("Invalid type");
+            continue;
+        }
+
+        e.root = root;
+
+        e.configs[0] = config1.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid config1");
+            continue;
+        }
+
+        e.configs[1] = config2.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid config2");
+            continue;
+        }
+
+        e.configs[2] = config3.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid config3");
+            continue;
+        }
+
+        e.configs[3] = config4.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid config4");
+            continue;
+        }
+
+        e.configs[4] = config5.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid config5");
+            continue;
+        }
+
+        savedAutoList.append(e);
+    }
+
+    currentAutoList = savedAutoList;
+}
+
+void readManual()
+{
+    QFile file("/prime/program/manual.csv");
+    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+    {
+        qDebug() << "File not found: " + file.fileName();
+        return;
+    }
+
+    QString errorMessage = QString("%3: %1, line %2").arg(file.fileName());
+    int lineCount = 0;
+    while (!file.atEnd())
+    {
+        lineCount++;
+
+        QString line = QString::fromUtf8(file.readLine()).trimmed();
+        if (line.isEmpty())
+            continue;
+
+        QString error = errorMessage.arg(lineCount);
+
+        QString id = line.section(',', 0, 0).trimmed();
+        if (id.isEmpty())
+        {
+            qDebug() << error.arg("Invalid id");
+            continue;
+        }
+
+        QString name = line.section(',', 1, 1).trimmed();
+        if (name.isEmpty())
+        {
+            qDebug() << error.arg("Invalid name");
+            continue;
+        }
+
+        QString mode = line.section(',', 2, 2).trimmed();
+        if (mode.isEmpty())
+        {
+            qDebug() << error.arg("Invalid mode");
+            continue;
+        }
+
+        QString humidity = line.section(',', 3, 3).trimmed();
+        if (humidity.isEmpty())
+        {
+            qDebug() << error.arg("Invalid humidity");
+            continue;
+        }
+
+        QString temp = line.section(',', 4, 4).trimmed();
+        if (temp.isEmpty())
+        {
+            qDebug() << error.arg("Invalid temp");
+            continue;
+        }
+
+        QString time = line.section(',', 5, 5).trimmed();
+        if (time.isEmpty())
+        {
+            qDebug() << error.arg("Invalid time");
+            continue;
+        }
+
+        QString fan = line.section(',', 6, 6).trimmed();
+        if (fan.isEmpty())
+        {
+            qDebug() << error.arg("Invalid fan");
+            continue;
+        }
+
+        QString coreTemp = line.section(',', 7, 7).trimmed();
+        if (coreTemp.isEmpty())
+        {
+            qDebug() << error.arg("Invalid coreTemp");
+            continue;
+        }
+
+        ManualEntry e;
+
+        bool ok;
+        e.id = id.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid id");
+            continue;
+        }
+
+        e.name = name.replace("\\c", ",");
+
+        e.mode = toMode(mode);
+        if (e.mode == Define::InvalidMode)
+        {
+            qDebug() << error.arg("Invalid mode");
+            continue;
+        }
+
+        e.humidity = humidity.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid humidity");
+            continue;
+        }
+
+        e.temp = temp.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid temp");
+            continue;
+        }
+
+        e.time = time.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid time");
+            continue;
+        }
+
+        e.fan = fan.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid fan");
+            continue;
+        }
+
+        e.coreTemp = coreTemp.toInt(&ok);
+        if (!ok)
+        {
+            qDebug() << error.arg("Invalid coreTemp");
+            continue;
+        }
+
+        savedManualList.append(e);
+    }
+
+    currentManualList = savedManualList;
+}
+
+void writeAuto()
+{
+    QFile file("/prime/program/auto.csv");
+    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
+    {
+        qDebug() << "File not opened: " + file.fileName();
+        return;
+    }
+
+    QTextStream stream(&file);
+    stream.setCodec("UTF-8");
+    foreach (AutoEntry e, savedAutoList)
+    {
+        stream << e.id << ","
+               << e.name.replace(",", "\\c").toUtf8() << ","
+               << toString(e.type) << ","
+               << e.root;
+        for (int i = 0; i < 5; i++)
+            stream << "," << e.configs[i];
+
+        stream << "\n";
+    }
+}
+
+void writeManual()
+{
+    QFile file("/prime/program/manual.csv");
+    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
+    {
+        qDebug() << "File not opened: " + file.fileName();
+        return;
+    }
+
+    QTextStream stream(&file);
+    stream.setCodec("UTF-8");
+    foreach (ManualEntry e, savedManualList)
+    {
+        stream << e.id << ","
+               << e.name.replace(",", "\\c").toUtf8() << ","
+               << toString(e.mode) << ","
+               << e.humidity << ","
+               << e.temp << ","
+               << e.time << ","
+               << e.fan << ","
+               << e.coreTemp << "\n";
+    }
+}
+
+bool initialized = false;
+void initialize()
+{
+    initialized = true;
+
+    readAuto();
+    readManual();
+}
+
+void checkInitialized()
+{
+    if (!initialized)
+        initialize();
+}
+
+int newAutoId()
+{
+    for (int i = 0; i < 1000; i++)
+    {
+        bool absent = true;
+        foreach (AutoEntry e, currentAutoList)
+            if (e.id == i)
+            {
+                absent = false;
+                break;
+            }
+
+        if (absent)
+            return i;
+    }
+
+    return -1;
+}
+
+int newManualId()
+{
+    for (int i = 0; i < 1000; i++)
+    {
+        bool absent = true;
+        foreach (ManualEntry e, currentManualList)
+            if (e.id == i)
+            {
+                absent = false;
+                break;
+            }
+
+        if (absent)
+            return i;
+    }
+
+    return -1;
+}
+}
+
+void CookProgram::add(AutoCookSetting cook)
+{
+    checkInitialized();
+
+    AutoEntry e;
+    e.id = newAutoId();
+    e.name = cook.name;
+    e.type = cook.type;
+    e.root = cook.root;
+
+    for (int i = 0; i < 5; i++)
+        e.configs[i] = cook.configs[i];
+
+    currentAutoList.append(e);
+}
+
+void CookProgram::add(ManualCookSetting cook)
+{
+    checkInitialized();
+
+    ManualEntry e;
+    e.id = newManualId();
+    e.name = "Manual";
+    e.mode = cook.mode;
+    e.humidity = cook.humidity;
+    e.temp = cook.temp;
+    e.time = cook.time;
+    e.fan = cook.fan;
+    e.coreTemp = cook.coreTempEnabled ? cook.coreTemp : -1;
+
+    currentManualList.append(e);
+}
+
+void CookProgram::remove(CookRecord record)
+{
+    checkInitialized();
+
+    switch (record.type)
+    {
+    case CookRecord::Auto:
+    {
+        AutoEntry e;
+        e.id = record.id;
+        e.name = record.name;
+        e.type = record.autoRecord.setting.type;
+        e.root = record.autoRecord.setting.root;
+        for (int i = 0; i < 5; i++)
+            e.configs[i] = record.autoRecord.setting.configs[i];
+
+        currentAutoList.removeAll(e);
+    }
+        break;
+    case CookRecord::Manual:
+    {
+        ManualEntry e;
+        e.id = record.id;
+        e.name = record.name;
+        e.mode = record.manualRecord.setting.mode;
+        e.humidity = record.manualRecord.setting.humidity;
+        e.temp = record.manualRecord.setting.temp;
+        e.time = record.manualRecord.setting.time;
+        e.fan = record.manualRecord.setting.fan;
+        e.coreTemp = record.manualRecord.setting.coreTempEnabled ? record.manualRecord.setting.coreTemp : -1;
+
+        currentManualList.removeAll(e);
+    }
+        break;
+    }
+}
+
+QList<CookRecord> CookProgram::listAuto()
+{
+    checkInitialized();
+
+    QList<CookRecord> list;
+    foreach (AutoEntry e, currentAutoList)
+    {
+        CookRecord r;
+        r.type = CookRecord::Auto;
+        r.id = e.id;
+        r.name = e.name;
+        r.autoRecord.setting.name = name(e.type, e.root);
+        r.autoRecord.setting.type = e.type;
+        r.autoRecord.setting.root = e.root;
+
+        for (int i = 0; i < 5; i++)
+            r.autoRecord.setting.configs[i] = e.configs[i];
+
+        list.append(r);
+    }
+
+    return list;
+}
+
+QList<CookRecord> CookProgram::listManual()
+{
+    checkInitialized();
+
+    QList<CookRecord> list;
+    foreach (ManualEntry e, currentManualList)
+    {
+        CookRecord r;
+        r.type = CookRecord::Manual;
+        r.id = e.id;
+        r.name = e.name;
+        r.manualRecord.setting.mode = e.mode;
+        r.manualRecord.setting.humidity = e.humidity;
+        r.manualRecord.setting.temp = e.temp;
+        r.manualRecord.setting.time = e.time;
+        r.manualRecord.setting.fan = e.fan;
+        r.manualRecord.setting.coreTempEnabled = e.coreTemp > 0;
+        r.manualRecord.setting.coreTemp = e.coreTemp;
+
+        list.append(r);
+    }
+
+    return list;
+}
+
+void CookProgram::rename(CookRecord record, QString name)
+{
+    checkInitialized();
+
+    switch (record.type)
+    {
+    case CookRecord::Auto:
+    {
+        AutoEntry e;
+        e.id = record.id;
+        e.name = record.name;
+        e.type = record.autoRecord.setting.type;
+        e.root = record.autoRecord.setting.root;
+        for (int i = 0; i < 5; i++)
+            e.configs[i] = record.autoRecord.setting.configs[i];
+
+        int index = currentAutoList.indexOf(e);
+        if (index != -1)
+        {
+            AutoEntry &e = currentAutoList[index];
+            e.name = name;
+        }
+    }
+        break;
+    case CookRecord::Manual:
+    {
+        ManualEntry e;
+        e.id = record.id;
+        e.name = record.name;
+        e.mode = record.manualRecord.setting.mode;
+        e.humidity = record.manualRecord.setting.humidity;
+        e.temp = record.manualRecord.setting.temp;
+        e.time = record.manualRecord.setting.time;
+        e.fan = record.manualRecord.setting.fan;
+        e.coreTemp = record.manualRecord.setting.coreTempEnabled ? record.manualRecord.setting.coreTemp : -1;
+
+        int index = currentManualList.indexOf(e);
+        if (index != -1)
+        {
+            ManualEntry &e = currentManualList[index];
+            e.name = name;
+        }
+    }
+        break;
+    }
+}
+
+void CookProgram::save()
+{
+    checkInitialized();
+
+    if (currentAutoList != savedAutoList)
+    {
+        savedAutoList = currentAutoList;
+        writeAuto();
+    }
+
+    if (currentManualList != savedManualList)
+    {
+        savedManualList = currentManualList;
+        writeManual();
+    }
+}
+
+void CookProgram::discard()
+{
+    checkInitialized();
+
+    currentAutoList = savedAutoList;
+    currentManualList = savedManualList;
+}
diff --git a/app/gui/oven_control/cookprogram.h b/app/gui/oven_control/cookprogram.h
new file mode 100644
index 0000000..a269949
--- /dev/null
+++ b/app/gui/oven_control/cookprogram.h
@@ -0,0 +1,20 @@
+#ifndef COOKPROGRAM_H
+#define COOKPROGRAM_H
+
+
+#include "cookhistory.h"
+
+namespace CookProgram
+{
+void add(AutoCookSetting cook);
+void add(ManualCookSetting cook);
+void remove(CookRecord record);
+void rename(CookRecord record, QString name);
+void save();
+void discard();
+
+QList<CookRecord> listAuto();
+QList<CookRecord> listManual();
+}
+
+#endif // COOKPROGRAM_H
diff --git a/app/gui/oven_control/oven_control.pro b/app/gui/oven_control/oven_control.pro
index e007093..fcdd7e6 100644
--- a/app/gui/oven_control/oven_control.pro
+++ b/app/gui/oven_control/oven_control.pro
@@ -106,7 +106,11 @@ SOURCES += main.cpp\
     coretempsettingpopup.cpp \
     fileprocessor.cpp \
     fileprocessgauge.cpp \
-    fileprocessdlg.cpp
+    fileprocessdlg.cpp \
+    programmingselectionwindow.cpp \
+    programmingmanualwindow.cpp \
+    programmingmanualcoretemppopup.cpp \
+    cookprogram.cpp
 
 HEADERS  += mainwindow.h \
     cook.h \
@@ -202,7 +206,11 @@ HEADERS  += mainwindow.h \
     coretempsettingpopup.h \
     fileprocessor.h \
     fileprocessgauge.h \
-    fileprocessdlg.h
+    fileprocessdlg.h \
+    programmingselectionwindow.h \
+    programmingmanualwindow.h \
+    programmingmanualcoretemppopup.h \
+    cookprogram.h
 
 FORMS    += mainwindow.ui \
     manualcookwindow.ui \
@@ -266,7 +274,10 @@ FORMS    += mainwindow.ui \
     electricmodelsettingwindow.ui \
     servicepassinputdlg.ui \
     coretempsettingpopup.ui \
-    fileprocessdlg.ui
+    fileprocessdlg.ui \
+    programmingselectionwindow.ui \
+    programmingmanualwindow.ui \
+    programmingmanualcoretemppopup.ui
 
 RESOURCES += \
     resources.qrc
diff --git a/app/gui/oven_control/programmingmanualcoretemppopup.cpp b/app/gui/oven_control/programmingmanualcoretemppopup.cpp
index 1264ee8..da03bba 100644
--- a/app/gui/oven_control/programmingmanualcoretemppopup.cpp
+++ b/app/gui/oven_control/programmingmanualcoretemppopup.cpp
@@ -1,14 +1,44 @@
 #include "programmingmanualcoretemppopup.h"
 #include "ui_programmingmanualcoretemppopup.h"
 
+#include "stringer.h"
+
 ProgrammingManualCoreTempPopup::ProgrammingManualCoreTempPopup(QWidget *parent) :
     QWidget(parent),
     ui(new Ui::ProgrammingManualCoreTempPopup)
 {
     ui->setupUi(this);
+
+    setAttribute(Qt::WA_DeleteOnClose);
+
+    connect(ui->coreTempSlider, SIGNAL(valueChanged(int)), SLOT(updateCoreTempLabel()));
+
+    updateCoreTempLabel();
 }
 
 ProgrammingManualCoreTempPopup::~ProgrammingManualCoreTempPopup()
 {
     delete ui;
 }
+
+void ProgrammingManualCoreTempPopup::updateCoreTempLabel()
+{
+    ui->coreTempLabel->setText(Stringer::temperature(ui->coreTempSlider->value(), Stringer::fontSize14));
+}
+
+void ProgrammingManualCoreTempPopup::on_coreTempButton_clicked()
+{
+
+}
+
+void ProgrammingManualCoreTempPopup::on_cancelButton_clicked()
+{
+    close();
+}
+
+void ProgrammingManualCoreTempPopup::on_applyButton_clicked()
+{
+    emit coreTempEnabled(ui->coreTempSlider->value());
+
+    close();
+}
diff --git a/app/gui/oven_control/programmingmanualcoretemppopup.h b/app/gui/oven_control/programmingmanualcoretemppopup.h
index ee5b6a4..8d5f588 100644
--- a/app/gui/oven_control/programmingmanualcoretemppopup.h
+++ b/app/gui/oven_control/programmingmanualcoretemppopup.h
@@ -15,8 +15,18 @@ public:
     explicit ProgrammingManualCoreTempPopup(QWidget *parent = 0);
     ~ProgrammingManualCoreTempPopup();
 
+private slots:
+    void updateCoreTempLabel();
+
+    void on_coreTempButton_clicked();
+    void on_cancelButton_clicked();
+    void on_applyButton_clicked();
+
 private:
     Ui::ProgrammingManualCoreTempPopup *ui;
+
+signals:
+    void coreTempEnabled(int);
 };
 
 #endif // PROGRAMMINGMANUALCORETEMPPOPUP_H
diff --git a/app/gui/oven_control/programmingmanualcoretemppopup.ui b/app/gui/oven_control/programmingmanualcoretemppopup.ui
index 196bf73..5740cbe 100644
--- a/app/gui/oven_control/programmingmanualcoretemppopup.ui
+++ b/app/gui/oven_control/programmingmanualcoretemppopup.ui
@@ -1,21 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <author/>
- <comment/>
- <exportmacro/>
  <class>ProgrammingManualCoreTempPopup</class>
  <widget class="QWidget" name="ProgrammingManualCoreTempPopup">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>400</width>
-    <height>300</height>
+    <width>900</width>
+    <height>1600</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Form</string>
   </property>
+  <property name="styleSheet">
+   <string notr="true">#background {
+background-image: url(:/images/background/manual_core.png);
+margin-top: -720px;
+}
+
+QPushButton[style=&quot;icon&quot;] {
+background-image: url(:/images/slider_icon/background.png);
+background-repeat: no-repeat;
+background-position: center;
+border: none;
+}
+
+QPushButton[style=&quot;interTemp&quot;] {
+background-repeat: no-repeat;
+background-position: center;
+background-clip: border;
+background-origin: border;
+
+border-top: 130px;
+border-style: hidden;
+color: white;
+font-size: 30px;
+}
+
+QSlider::groove {
+background-image: url(:/images/slider/groove_ticks.png);
+background-repeat: no-repeat;
+}
+
+QSlider::sub-page {
+background-repeat: no-repeat;
+margin: 5px;
+}
+
+QSlider::handle {
+background-image: url(:/images/slider/handle_big.png);
+background-repeat: no-repeat;
+width: 23px;
+height: 33px;
+}</string>
+  </property>
+  <widget class="QSlider" name="coreTempSlider">
+   <property name="geometry">
+    <rect>
+     <x>185</x>
+     <y>1012</y>
+     <width>666</width>
+     <height>33</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">QSlider::sub-page { background-image: url(:/images/slider/core.png); }</string>
+   </property>
+   <property name="minimum">
+    <number>30</number>
+   </property>
+   <property name="maximum">
+    <number>99</number>
+   </property>
+   <property name="value">
+    <number>30</number>
+   </property>
+   <property name="tracking">
+    <bool>true</bool>
+   </property>
+   <property name="orientation">
+    <enum>Qt::Horizontal</enum>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="coreTempButton">
+   <property name="geometry">
+    <rect>
+     <x>27</x>
+     <y>954</y>
+     <width>140</width>
+     <height>140</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">QPushButton { image: url(:/images/slider_icon/core_temp_enabled.png); }
+QPushButton:pressed { image: url(:/images/slider_icon/core_temp_ov.png); }</string>
+   </property>
+   <property name="style" stdset="0">
+    <string>icon</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="cancelButton">
+   <property name="geometry">
+    <rect>
+     <x>200</x>
+     <y>1260</y>
+     <width>250</width>
+     <height>190</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">QPushButton { background-image: url(:/images/manual_button/back.png); }
+QPushButton:pressed { background-image: url(:/images/manual_button/back_ov.png); }</string>
+   </property>
+   <property name="text">
+    <string>이전으로</string>
+   </property>
+   <property name="style" stdset="0">
+    <string notr="true">interTemp</string>
+   </property>
+  </widget>
+  <widget class="QPushButton" name="applyButton">
+   <property name="geometry">
+    <rect>
+     <x>450</x>
+     <y>1260</y>
+     <width>250</width>
+     <height>190</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">QPushButton { background-image: url(:/images/manual_button/ok.png); }
+QPushButton:pressed { background-image: url(:/images/manual_button/ok_ov.png); }</string>
+   </property>
+   <property name="text">
+    <string>확인/적용하기</string>
+   </property>
+   <property name="style" stdset="0">
+    <string notr="true">interTemp</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="background">
+   <property name="geometry">
+    <rect>
+     <x>0</x>
+     <y>720</y>
+     <width>900</width>
+     <height>730</height>
+    </rect>
+   </property>
+  </widget>
+  <widget class="QLabel" name="coreTempLabel">
+   <property name="enabled">
+    <bool>true</bool>
+   </property>
+   <property name="geometry">
+    <rect>
+     <x>690</x>
+     <y>1038</y>
+     <width>150</width>
+     <height>50</height>
+    </rect>
+   </property>
+   <property name="palette">
+    <palette>
+     <active>
+      <colorrole role="WindowText">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>255</red>
+         <green>255</green>
+         <blue>255</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </active>
+     <inactive>
+      <colorrole role="WindowText">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>255</red>
+         <green>255</green>
+         <blue>255</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </inactive>
+     <disabled>
+      <colorrole role="WindowText">
+       <brush brushstyle="SolidPattern">
+        <color alpha="255">
+         <red>123</red>
+         <green>123</green>
+         <blue>123</blue>
+        </color>
+       </brush>
+      </colorrole>
+     </disabled>
+    </palette>
+   </property>
+   <property name="font">
+    <font>
+     <family>Roboto</family>
+     <pointsize>16</pointsize>
+     <weight>75</weight>
+     <bold>true</bold>
+    </font>
+   </property>
+   <property name="text">
+    <string>℃</string>
+   </property>
+   <property name="alignment">
+    <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+   </property>
+  </widget>
+  <zorder>background</zorder>
+  <zorder>coreTempSlider</zorder>
+  <zorder>coreTempButton</zorder>
+  <zorder>cancelButton</zorder>
+  <zorder>applyButton</zorder>
+  <zorder>coreTempLabel</zorder>
  </widget>
- <pixmapfunction/>
+ <resources>
+  <include location="resources.qrc"/>
+ </resources>
  <connections/>
 </ui>
diff --git a/app/gui/oven_control/programmingmanualwindow.cpp b/app/gui/oven_control/programmingmanualwindow.cpp
index b722cea..8e8a112 100644
--- a/app/gui/oven_control/programmingmanualwindow.cpp
+++ b/app/gui/oven_control/programmingmanualwindow.cpp
@@ -1,14 +1,241 @@
 #include "programmingmanualwindow.h"
 #include "ui_programmingmanualwindow.h"
 
-ProgrammingManualWindow::ProgrammingManualWindow(QWidget *parent) :
+#include "stringer.h"
+#include "programmingmanualcoretemppopup.h"
+#include "cookprogram.h"
+
+ProgrammingManualWindow::ProgrammingManualWindow(QWidget *parent, Define::Mode mode) :
     QMainWindow(parent),
     ui(new Ui::ProgrammingManualWindow)
 {
     ui->setupUi(this);
+
+    ui->clockContainer->setParent(ui->upperStack);
+    setAttribute(Qt::WA_DeleteOnClose);
+
+    connect(ui->humiditySlider, SIGNAL(valueChanged(int)), SLOT(updateHumidityLabel()));
+    connect(ui->tempSlider, SIGNAL(valueChanged(int)), SLOT(updateTempLabel()));
+    connect(ui->timeSlider, SIGNAL(valueChanged(int)), SLOT(updateTimeLabel()));
+    connect(ui->interTempSlider, SIGNAL(valueChanged(int)), SLOT(updateCoreTempLabel()));
+
+    setDefault(mode);
 }
 
 ProgrammingManualWindow::~ProgrammingManualWindow()
 {
     delete ui;
 }
+
+void ProgrammingManualWindow::setDefault(Define::Mode mode)
+{
+    switch (mode)
+    {
+    case Define::SteamMode:
+        ui->steamButton->setChecked(true);
+        ui->humiditySlider->setEnabled(false);
+        ui->humiditySlider->setValue(100);
+        ui->tempSlider->setRange(30, 130);
+        ui->tempSlider->setValue(100);
+        ui->timeSlider->setValue(0);
+        ui->interTempSlider->setEnabled(false);
+        ui->interTempSlider->setValue(30);
+        setFan(4);
+        updateCoreTempButton();
+        updateCoreTempLabel();
+        this->mode = mode;
+        break;
+    case Define::CombiMode:
+        ui->combiButton->setChecked(true);
+        ui->humiditySlider->setEnabled(true);
+        ui->humiditySlider->setValue(50);
+        ui->tempSlider->setRange(30, 300);
+        ui->tempSlider->setValue(100);
+        ui->timeSlider->setValue(0);
+        ui->interTempSlider->setEnabled(false);
+        ui->interTempSlider->setValue(30);
+        setFan(4);
+        updateCoreTempButton();
+        updateCoreTempLabel();
+        this->mode = mode;
+        break;
+    case Define::DryMode:
+        ui->dryheatButton->setChecked(true);
+        ui->humiditySlider->setEnabled(false);
+        ui->humiditySlider->setValue(0);
+        ui->tempSlider->setRange(30, 300);
+        ui->tempSlider->setValue(160);
+        ui->timeSlider->setValue(0);
+        ui->interTempSlider->setEnabled(false);
+        ui->interTempSlider->setValue(30);
+        setFan(4);
+        updateCoreTempButton();
+        updateCoreTempLabel();
+        this->mode = mode;
+        break;
+    default:
+        return;
+    }
+}
+
+void ProgrammingManualWindow::setFan(int level)
+{
+    fan = level;
+
+    updateFanButton();
+}
+
+void ProgrammingManualWindow::updateHumidityLabel()
+{
+//    ui->humidityLabel->setText(QString::number(ui->humiditySlider->value()));
+    ui->humidityLabel->setText(QString("%1%").arg(ui->humiditySlider->value()));
+}
+
+void ProgrammingManualWindow::updateTempLabel()
+{
+    ui->tempLabel->setText(Stringer::temperature(ui->tempSlider->value(), Stringer::fontSize14));
+}
+
+void ProgrammingManualWindow::updateTimeLabel()
+{
+    ui->timeLabel->setText(Stringer::remainingTime(ui->timeSlider->value() * 1000, Stringer::fontSize14));
+}
+
+void ProgrammingManualWindow::updateCoreTempButton()
+{
+    if (ui->interTempSlider->isEnabled())
+        ui->interTempButton->setStyleSheet("\
+QPushButton {\
+    image: url(:/images/slider_icon/core_temp_enabled.png);\
+}\
+QPushButton:pressed {\
+    image: url(:/images/slider_icon/core_temp_ov.png);\
+}");
+    else
+       ui->interTempButton->setStyleSheet("\
+QPushButton {\
+   image: url(:/images/slider_icon/core_temp.png);\
+}\
+QPushButton:pressed {\
+   image: url(:/images/slider_icon/core_temp_ov.png);\
+}");
+}
+
+void ProgrammingManualWindow::updateCoreTempLabel()
+{
+    if (ui->interTempSlider->isEnabled())
+        ui->interTempLabel->setText(Stringer::temperature(ui->interTempSlider->value(), Stringer::fontSize14));
+    else
+        ui->interTempLabel->setText(Stringer::unusedTemperature(Stringer::fontSize14));
+}
+
+void ProgrammingManualWindow::updateFanButton()
+{
+    switch (fan)
+    {
+    case 1:
+        ui->fanButton->setStyleSheet(
+                    "background-image: url(:/images/manual_button/fan_1.png)");
+        break;
+    case 2:
+        ui->fanButton->setStyleSheet(
+                    "background-image: url(:/images/manual_button/fan_2.png)");
+        break;
+    case 3:
+        ui->fanButton->setStyleSheet(
+                    "background-image: url(:/images/manual_button/fan_3.png)");
+        break;
+    case 4:
+        ui->fanButton->setStyleSheet(
+                    "background-image: url(:/images/manual_button/fan_4.png)");
+        break;
+    case 5:
+        ui->fanButton->setStyleSheet(
+                    "background-image: url(:/images/manual_button/fan_5.png)");
+        break;
+    default:
+        ui->fanButton->setStyleSheet(
+                    "background-image: url(:/images/manual_button/fan_1.png)");
+        break;
+    }
+}
+
+void ProgrammingManualWindow::onCoreTempEnabled(int celsius)
+{
+    ui->interTempSlider->setEnabled(true);
+    ui->interTempSlider->setValue(celsius);
+    updateCoreTempButton();
+    updateCoreTempLabel();
+}
+
+void ProgrammingManualWindow::on_steamButton_clicked()
+{
+    setDefault(Define::SteamMode);
+}
+
+void ProgrammingManualWindow::on_combiButton_clicked()
+{
+    setDefault(Define::CombiMode);
+}
+
+void ProgrammingManualWindow::on_dryheatButton_clicked()
+{
+    setDefault(Define::DryMode);
+}
+
+void ProgrammingManualWindow::on_interTempButton_clicked()
+{
+    if (ui->interTempSlider->isEnabled())
+    {
+        ui->interTempSlider->setEnabled(false);
+        updateCoreTempButton();
+        updateCoreTempLabel();
+    }
+    else
+    {
+        ProgrammingManualCoreTempPopup *p = new ProgrammingManualCoreTempPopup(this);
+        connect(p, SIGNAL(coreTempEnabled(int)), SLOT(onCoreTempEnabled(int)));
+        p->showFullScreen();
+    }
+}
+
+void ProgrammingManualWindow::on_fanButton_clicked()
+{
+    fan++;
+    if (fan > 5)
+        fan = 1;
+
+    updateFanButton();
+}
+
+void ProgrammingManualWindow::on_backButton_clicked()
+{
+    close();
+}
+
+void ProgrammingManualWindow::on_configButton_clicked()
+{
+
+}
+
+void ProgrammingManualWindow::on_helpButton_clicked()
+{
+
+}
+
+void ProgrammingManualWindow::on_okButton_clicked()
+{
+    ManualCookSetting s;
+    s.mode = mode;
+    s.humidity = ui->humiditySlider->value();
+    s.temp = ui->tempSlider->value();
+    s.time = ui->timeSlider->value();
+    s.coreTempEnabled = ui->interTempSlider->isEnabled();
+    s.coreTemp = ui->interTempSlider->value();
+    s.fan = fan;
+
+    CookProgram::add(s);
+
+    emit added();
+    close();
+}
diff --git a/app/gui/oven_control/programmingmanualwindow.h b/app/gui/oven_control/programmingmanualwindow.h
index cf2104d..196a632 100644
--- a/app/gui/oven_control/programmingmanualwindow.h
+++ b/app/gui/oven_control/programmingmanualwindow.h
@@ -3,6 +3,8 @@
 
 #include <QMainWindow>
 
+#include "define.h"
+
 namespace Ui {
 class ProgrammingManualWindow;
 }
@@ -12,11 +14,39 @@ class ProgrammingManualWindow : public QMainWindow
     Q_OBJECT
 
 public:
-    explicit ProgrammingManualWindow(QWidget *parent = 0);
+    explicit ProgrammingManualWindow(QWidget *parent, Define::Mode mode);
     ~ProgrammingManualWindow();
 
 private:
     Ui::ProgrammingManualWindow *ui;
+
+    Define::Mode mode;
+    int fan;
+
+private slots:
+    void setDefault(Define::Mode mode);
+    void setFan(int level);
+    void updateHumidityLabel();
+    void updateTempLabel();
+    void updateTimeLabel();
+    void updateCoreTempButton();
+    void updateCoreTempLabel();
+    void updateFanButton();
+
+    void onCoreTempEnabled(int celsius);
+
+    void on_steamButton_clicked();
+    void on_combiButton_clicked();
+    void on_dryheatButton_clicked();
+    void on_interTempButton_clicked();
+    void on_fanButton_clicked();
+    void on_backButton_clicked();
+    void on_configButton_clicked();
+    void on_helpButton_clicked();
+    void on_okButton_clicked();
+
+signals:
+    void added();
 };
 
 #endif // PROGRAMMINGMANUALWINDOW_H
diff --git a/app/gui/oven_control/programmingmanualwindow.ui b/app/gui/oven_control/programmingmanualwindow.ui
index 48df9fb..83b5e66 100644
--- a/app/gui/oven_control/programmingmanualwindow.ui
+++ b/app/gui/oven_control/programmingmanualwindow.ui
@@ -1,24 +1,996 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <author/>
- <comment/>
- <exportmacro/>
  <class>ProgrammingManualWindow</class>
  <widget class="QMainWindow" name="ProgrammingManualWindow">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>800</width>
-    <height>600</height>
+    <width>900</width>
+    <height>1600</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>MainWindow</string>
   </property>
-  <widget class="QMenuBar" name="menubar"/>
-  <widget class="QWidget" name="centralwidget"/>
-  <widget class="QStatusBar" name="statusbar"/>
+  <property name="styleSheet">
+   <string notr="true">#bottomBar { background-image: url(:/images/bottom_bar/background.png); }
+#centralwidget { background-image: url(:/images/background/manual.png); }
+
+QPushButton {
+background-repeat: no-repeat;
+background-position: center;
+border: none;
+}
+
+QPushButton[style=&quot;mode&quot;] {
+background-clip: border;
+background-origin: border;
+margin-bottom: 50px;
+
+border-top: 200px;
+border-bottom: -50px;
+border-style: hidden;
+color: #7B7B7B;
+font-size: 40px;
+}
+
+QPushButton[style=&quot;mode&quot;]:checked {
+color: white;
+image: url(:/images/cook_mode/indicator.png);
+image-position: bottom;
+}
+
+QPushButton[style=&quot;icon&quot;] {
+background-image: url(:/images/slider_icon/background.png);
+}
+
+QSlider::groove {
+background-image: url(:/images/slider/groove_ticks.png);
+background-repeat: no-repeat;
+}
+
+QSlider::sub-page {
+background-repeat: no-repeat;
+margin: 5px;
+}
+
+QSlider::handle {
+background-image: url(:/images/slider/handle_big.png);
+background-repeat: no-repeat;
+width: 23px;
+height: 33px;
+}</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <widget class="QLabel" name="humidityLabel">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>690</x>
+      <y>810</y>
+      <width>150</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="palette">
+     <palette>
+      <active>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </active>
+      <inactive>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </inactive>
+      <disabled>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>123</red>
+          <green>123</green>
+          <blue>123</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </disabled>
+     </palette>
+    </property>
+    <property name="font">
+     <font>
+      <family>Roboto</family>
+      <pointsize>16</pointsize>
+      <weight>75</weight>
+      <bold>true</bold>
+     </font>
+    </property>
+    <property name="text">
+     <string>0%</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+    </property>
+   </widget>
+   <widget class="QStackedWidget" name="upperStack">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>0</y>
+      <width>900</width>
+      <height>426</height>
+     </rect>
+    </property>
+    <widget class="QWidget" name="clockContainer">
+     <property name="styleSheet">
+      <string notr="true">#clockContainer { background-image: url(:/images/clock/background.png); }</string>
+     </property>
+     <widget class="Clock" name="clock" native="true">
+      <property name="geometry">
+       <rect>
+        <x>272</x>
+        <y>36</y>
+        <width>356</width>
+        <height>355</height>
+       </rect>
+      </property>
+     </widget>
+     <widget class="WashWarnIcon" name="label_6">
+      <property name="geometry">
+       <rect>
+        <x>800</x>
+        <y>320</y>
+        <width>80</width>
+        <height>84</height>
+       </rect>
+      </property>
+     </widget>
+    </widget>
+    <widget class="QWidget" name="closeDoorWidget">
+     <property name="styleSheet">
+      <string notr="true">#closeDoorWidget { background-image: url(:/images/clock/background.png); }</string>
+     </property>
+     <widget class="AnimatedImageBox" name="openDoorAnimation">
+      <property name="geometry">
+       <rect>
+        <x>366</x>
+        <y>20</y>
+        <width>251</width>
+        <height>292</height>
+       </rect>
+      </property>
+     </widget>
+     <widget class="QLabel" name="label_5">
+      <property name="geometry">
+       <rect>
+        <x>430</x>
+        <y>170</y>
+        <width>85</width>
+        <height>24</height>
+       </rect>
+      </property>
+      <property name="pixmap">
+       <pixmap resource="resources.qrc">:/images/animation/close_door_arrow.png</pixmap>
+      </property>
+     </widget>
+    </widget>
+   </widget>
+   <widget class="QPushButton" name="dryheatButton">
+    <property name="geometry">
+     <rect>
+      <x>600</x>
+      <y>426</y>
+      <width>300</width>
+      <height>293</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_mode/big_dryheat_hide.png); }
+QPushButton:pressed { background-image: url(:/images/cook_mode/big_dryheat_ov.png); }
+QPushButton:checked { background-image: url(:/images/cook_mode/big_dryheat.png); }</string>
+    </property>
+    <property name="text">
+     <string>건열</string>
+    </property>
+    <property name="checkable">
+     <bool>true</bool>
+    </property>
+    <property name="autoExclusive">
+     <bool>true</bool>
+    </property>
+    <property name="style" stdset="0">
+     <string notr="true">mode</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="timeButton">
+    <property name="geometry">
+     <rect>
+      <x>27</x>
+      <y>1025</y>
+      <width>140</width>
+      <height>140</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { image: url(:/images/slider_icon/time.png); }
+QPushButton:pressed { image: url(:/images/slider_icon/time_ov.png); }</string>
+    </property>
+    <property name="style" stdset="0">
+     <string notr="true">icon</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="steamLabel_3">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>780</x>
+      <y>740</y>
+      <width>91</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="palette">
+     <palette>
+      <active>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </active>
+      <inactive>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </inactive>
+      <disabled>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>123</red>
+          <green>123</green>
+          <blue>123</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </disabled>
+     </palette>
+    </property>
+    <property name="font">
+     <font>
+      <family>Malgun Gothic</family>
+      <pointsize>9</pointsize>
+     </font>
+    </property>
+    <property name="text">
+     <string>증가</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QSlider" name="timeSlider">
+    <property name="geometry">
+     <rect>
+      <x>185</x>
+      <y>1083</y>
+      <width>666</width>
+      <height>33</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QSlider::sub-page { background-image: url(:/images/slider/time.png); }</string>
+    </property>
+    <property name="maximum">
+     <number>86400</number>
+    </property>
+    <property name="singleStep">
+     <number>60</number>
+    </property>
+    <property name="pageStep">
+     <number>3600</number>
+    </property>
+    <property name="value">
+     <number>0</number>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Horizontal</enum>
+    </property>
+   </widget>
+   <widget class="QSlider" name="interTempSlider">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>185</x>
+      <y>1233</y>
+      <width>666</width>
+      <height>33</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QSlider::sub-page { background-image: url(:/images/slider/core.png); }
+QSlider::sub-page:disabled { background: #00000000; }
+QSlider::handle:disabled { background: #00000000; }</string>
+    </property>
+    <property name="minimum">
+     <number>30</number>
+    </property>
+    <property name="maximum">
+     <number>99</number>
+    </property>
+    <property name="value">
+     <number>30</number>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Horizontal</enum>
+    </property>
+   </widget>
+   <widget class="QLabel" name="interTempLabel">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>690</x>
+      <y>1260</y>
+      <width>150</width>
+      <height>50</height>
+     </rect>
+    </property>
+    <property name="palette">
+     <palette>
+      <active>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </active>
+      <inactive>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </inactive>
+      <disabled>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>123</red>
+          <green>123</green>
+          <blue>123</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </disabled>
+     </palette>
+    </property>
+    <property name="font">
+     <font>
+      <family>Roboto</family>
+      <pointsize>16</pointsize>
+      <weight>75</weight>
+      <bold>true</bold>
+     </font>
+    </property>
+    <property name="text">
+     <string>&lt;span style=&quot;font-size:11pt;&quot;&gt;℃&lt;/span&gt;</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="steamLabel_5">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>780</x>
+      <y>890</y>
+      <width>91</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="palette">
+     <palette>
+      <active>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </active>
+      <inactive>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </inactive>
+      <disabled>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>123</red>
+          <green>123</green>
+          <blue>123</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </disabled>
+     </palette>
+    </property>
+    <property name="font">
+     <font>
+      <family>Malgun Gothic</family>
+      <pointsize>9</pointsize>
+     </font>
+    </property>
+    <property name="text">
+     <string>증가</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="steamLabel_4">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>160</x>
+      <y>890</y>
+      <width>91</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="palette">
+     <palette>
+      <active>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </active>
+      <inactive>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </inactive>
+      <disabled>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>123</red>
+          <green>123</green>
+          <blue>123</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </disabled>
+     </palette>
+    </property>
+    <property name="font">
+     <font>
+      <family>Malgun Gothic</family>
+      <pointsize>9</pointsize>
+     </font>
+    </property>
+    <property name="text">
+     <string>감소</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QWidget" name="bottomBar" native="true">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>1450</y>
+      <width>900</width>
+      <height>150</height>
+     </rect>
+    </property>
+    <widget class="QPushButton" name="backButton">
+     <property name="geometry">
+      <rect>
+       <x>232</x>
+       <y>26</y>
+       <width>97</width>
+       <height>97</height>
+      </rect>
+     </property>
+     <property name="styleSheet">
+      <string notr="true">QPushButton { border-image: url(:/images/bottom_bar/back.png); }
+QPushButton:pressed { border-image: url(:/images/bottom_bar/back_ov.png); }</string>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+    <widget class="QPushButton" name="configButton">
+     <property name="geometry">
+      <rect>
+       <x>345</x>
+       <y>26</y>
+       <width>97</width>
+       <height>97</height>
+      </rect>
+     </property>
+     <property name="styleSheet">
+      <string notr="true">QPushButton { border-image: url(:/images/bottom_bar/config.png); }
+QPushButton:pressed { border-image: url(:/images/bottom_bar/config_ov.png); }</string>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+    <widget class="QPushButton" name="okButton">
+     <property name="geometry">
+      <rect>
+       <x>571</x>
+       <y>26</y>
+       <width>97</width>
+       <height>97</height>
+      </rect>
+     </property>
+     <property name="styleSheet">
+      <string notr="true">QPushButton { border-image: url(:/images/bottom_bar/006_sys_icon_16.png); }
+QPushButton:pressed { border-image: url(:/images/bottom_bar/006_sys_icon_16_ov.png); }</string>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+    <widget class="QPushButton" name="helpButton">
+     <property name="geometry">
+      <rect>
+       <x>458</x>
+       <y>26</y>
+       <width>97</width>
+       <height>97</height>
+      </rect>
+     </property>
+     <property name="styleSheet">
+      <string notr="true">QPushButton { border-image: url(:/images/bottom_bar/help.png); }
+QPushButton:pressed { border-image: url(:/images/bottom_bar/help_ov.png); }</string>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+   </widget>
+   <widget class="QPushButton" name="tempButton">
+    <property name="geometry">
+     <rect>
+      <x>27</x>
+      <y>875</y>
+      <width>140</width>
+      <height>140</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { image: url(:/images/slider_icon/temp.png); }
+QPushButton:pressed { image: url(:/images/slider_icon/temp_ov.png); }</string>
+    </property>
+    <property name="style" stdset="0">
+     <string notr="true">icon</string>
+    </property>
+   </widget>
+   <widget class="QSlider" name="tempSlider">
+    <property name="geometry">
+     <rect>
+      <x>185</x>
+      <y>933</y>
+      <width>666</width>
+      <height>33</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QSlider::sub-page { background-image: url(:/images/slider/temp.png); }</string>
+    </property>
+    <property name="maximum">
+     <number>6</number>
+    </property>
+    <property name="value">
+     <number>0</number>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Horizontal</enum>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="steamButton">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>426</y>
+      <width>300</width>
+      <height>293</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_mode/big_steam_hide.png); }
+QPushButton:pressed { background-image: url(:/images/cook_mode/big_steam_ov.png); }
+QPushButton:checked { background-image: url(:/images/cook_mode/big_steam.png); }</string>
+    </property>
+    <property name="text">
+     <string>스팀</string>
+    </property>
+    <property name="checkable">
+     <bool>true</bool>
+    </property>
+    <property name="autoExclusive">
+     <bool>true</bool>
+    </property>
+    <property name="style" stdset="0">
+     <string notr="true">mode</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="tempLabel">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>690</x>
+      <y>960</y>
+      <width>150</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="palette">
+     <palette>
+      <active>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </active>
+      <inactive>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </inactive>
+      <disabled>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>123</red>
+          <green>123</green>
+          <blue>123</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </disabled>
+     </palette>
+    </property>
+    <property name="font">
+     <font>
+      <family>Roboto</family>
+      <pointsize>16</pointsize>
+      <weight>75</weight>
+      <bold>true</bold>
+     </font>
+    </property>
+    <property name="text">
+     <string>30&lt;span style=&quot;font-size:11pt;&quot;&gt;℃&lt;/span&gt;</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+    </property>
+   </widget>
+   <widget class="QLabel" name="steamLabel_2">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>160</x>
+      <y>740</y>
+      <width>91</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="palette">
+     <palette>
+      <active>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </active>
+      <inactive>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </inactive>
+      <disabled>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>123</red>
+          <green>123</green>
+          <blue>123</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </disabled>
+     </palette>
+    </property>
+    <property name="font">
+     <font>
+      <family>Malgun Gothic</family>
+      <pointsize>9</pointsize>
+     </font>
+    </property>
+    <property name="text">
+     <string>감소</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignCenter</set>
+    </property>
+   </widget>
+   <widget class="QSlider" name="humiditySlider">
+    <property name="geometry">
+     <rect>
+      <x>185</x>
+      <y>783</y>
+      <width>666</width>
+      <height>33</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QSlider::sub-page { background-image: url(:/images/slider/humidity.png); }</string>
+    </property>
+    <property name="maximum">
+     <number>100</number>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Horizontal</enum>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="humidityButton">
+    <property name="geometry">
+     <rect>
+      <x>27</x>
+      <y>725</y>
+      <width>140</width>
+      <height>140</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { image: url(:/images/slider_icon/humidity.png); }
+QPushButton:pressed { image: url(:/images/slider_icon/humidity_ov.png); }</string>
+    </property>
+    <property name="style" stdset="0">
+     <string notr="true">icon</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="interTempButton">
+    <property name="geometry">
+     <rect>
+      <x>27</x>
+      <y>1175</y>
+      <width>140</width>
+      <height>140</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { image: url(:/images/slider_icon/core_temp.png); }
+QPushButton:pressed { image: url(:/images/slider_icon/core_temp_ov.png); }</string>
+    </property>
+    <property name="style" stdset="0">
+     <string notr="true">icon</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="combiButton">
+    <property name="geometry">
+     <rect>
+      <x>300</x>
+      <y>426</y>
+      <width>300</width>
+      <height>293</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_mode/big_combi_hide.png); }
+QPushButton:pressed { background-image: url(:/images/cook_mode/big_combi_ov.png); }
+QPushButton:checked { background-image: url(:/images/cook_mode/big_combi.png); }</string>
+    </property>
+    <property name="text">
+     <string>콤비</string>
+    </property>
+    <property name="checkable">
+     <bool>true</bool>
+    </property>
+    <property name="autoExclusive">
+     <bool>true</bool>
+    </property>
+    <property name="style" stdset="0">
+     <string notr="true">mode</string>
+    </property>
+   </widget>
+   <widget class="QLabel" name="timeLabel">
+    <property name="enabled">
+     <bool>true</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>539</x>
+      <y>1110</y>
+      <width>301</width>
+      <height>51</height>
+     </rect>
+    </property>
+    <property name="palette">
+     <palette>
+      <active>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </active>
+      <inactive>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>255</red>
+          <green>255</green>
+          <blue>255</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </inactive>
+      <disabled>
+       <colorrole role="WindowText">
+        <brush brushstyle="SolidPattern">
+         <color alpha="255">
+          <red>123</red>
+          <green>123</green>
+          <blue>123</blue>
+         </color>
+        </brush>
+       </colorrole>
+      </disabled>
+     </palette>
+    </property>
+    <property name="font">
+     <font>
+      <family>Roboto</family>
+      <pointsize>16</pointsize>
+      <weight>75</weight>
+      <bold>true</bold>
+     </font>
+    </property>
+    <property name="text">
+     <string>0&lt;span style=&quot;font-size:11pt;&quot;&gt;초&lt;/span&gt;</string>
+    </property>
+    <property name="alignment">
+     <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="fanButton">
+    <property name="geometry">
+     <rect>
+      <x>449</x>
+      <y>1319</y>
+      <width>112</width>
+      <height>131</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/manual_button/fan_4.png); }</string>
+    </property>
+   </widget>
+  </widget>
  </widget>
- <pixmapfunction/>
+ <customwidgets>
+  <customwidget>
+   <class>Clock</class>
+   <extends>QWidget</extends>
+   <header>clock.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>WashWarnIcon</class>
+   <extends>QLabel</extends>
+   <header>washwarnicon.h</header>
+  </customwidget>
+  <customwidget>
+   <class>AnimatedImageBox</class>
+   <extends>QLabel</extends>
+   <header>animatedimagebox.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources>
+  <include location="resources.qrc"/>
+ </resources>
  <connections/>
 </ui>
diff --git a/app/gui/oven_control/programmingselectionwindow.cpp b/app/gui/oven_control/programmingselectionwindow.cpp
index e19a6f3..cdb006c 100644
--- a/app/gui/oven_control/programmingselectionwindow.cpp
+++ b/app/gui/oven_control/programmingselectionwindow.cpp
@@ -1,14 +1,107 @@
 #include "programmingselectionwindow.h"
 #include "ui_programmingselectionwindow.h"
 
+#include "programmingmanualwindow.h"
+
 ProgrammingSelectionWindow::ProgrammingSelectionWindow(QWidget *parent) :
     QMainWindow(parent),
     ui(new Ui::ProgrammingSelectionWindow)
 {
     ui->setupUi(this);
+
+//    ui->clockContainer->setParent(ui->upperStack);
+    setAttribute(Qt::WA_DeleteOnClose);
+
+    setFocus();
 }
 
 ProgrammingSelectionWindow::~ProgrammingSelectionWindow()
 {
     delete ui;
 }
+
+void ProgrammingSelectionWindow::setModeEnabled(bool enabled)
+{
+    ui->steamButton->setEnabled(enabled);
+    ui->combiButton->setEnabled(enabled);
+    ui->dryheatButton->setEnabled(enabled);
+}
+
+void ProgrammingSelectionWindow::setCookTypeEnabled(bool enabled)
+{
+    ui->poultryButton->setEnabled(enabled);
+    ui->meatButton->setEnabled(enabled);
+    ui->fishButton->setEnabled(enabled);
+    ui->dessertButton->setEnabled(enabled);
+    ui->grainButton->setEnabled(enabled);
+    ui->breadButton->setEnabled(enabled);
+    ui->etcButton->setEnabled(enabled);
+}
+
+void ProgrammingSelectionWindow::onModeClicked(Define::Mode mode)
+{
+    ProgrammingManualWindow *w = new ProgrammingManualWindow(this, mode);
+    connect(w, SIGNAL(added()), SIGNAL(added()));
+    connect(w, SIGNAL(destroyed(QObject*)), SLOT(deleteLater()));
+    w->setWindowModality(Qt::WindowModal);
+    w->showFullScreen();
+    w->raise();
+
+    hide();
+}
+
+void ProgrammingSelectionWindow::onCookTypeClicked(Define::CookType type)
+{
+    emit cookTypeSelected(type);
+    close();
+}
+
+void ProgrammingSelectionWindow::on_steamButton_clicked()
+{
+    onModeClicked(Define::SteamMode);
+}
+
+void ProgrammingSelectionWindow::on_combiButton_clicked()
+{
+    onModeClicked(Define::CombiMode);
+}
+
+void ProgrammingSelectionWindow::on_dryheatButton_clicked()
+{
+    onModeClicked(Define::DryMode);
+}
+
+void ProgrammingSelectionWindow::on_poultryButton_clicked()
+{
+    onCookTypeClicked(Define::Poultry);
+}
+
+void ProgrammingSelectionWindow::on_meatButton_clicked()
+{
+    onCookTypeClicked(Define::Meat);
+}
+
+void ProgrammingSelectionWindow::on_fishButton_clicked()
+{
+    onCookTypeClicked(Define::Fish);
+}
+
+void ProgrammingSelectionWindow::on_dessertButton_clicked()
+{
+    onCookTypeClicked(Define::Desert);
+}
+
+void ProgrammingSelectionWindow::on_grainButton_clicked()
+{
+    onCookTypeClicked(Define::Vegetable);
+}
+
+void ProgrammingSelectionWindow::on_breadButton_clicked()
+{
+    onCookTypeClicked(Define::Bread);
+}
+
+void ProgrammingSelectionWindow::on_etcButton_clicked()
+{
+    onCookTypeClicked(Define::Etc);
+}
diff --git a/app/gui/oven_control/programmingselectionwindow.h b/app/gui/oven_control/programmingselectionwindow.h
index 7fafca6..23149f8 100644
--- a/app/gui/oven_control/programmingselectionwindow.h
+++ b/app/gui/oven_control/programmingselectionwindow.h
@@ -3,6 +3,8 @@
 
 #include <QMainWindow>
 
+#include "define.h"
+
 namespace Ui {
 class ProgrammingSelectionWindow;
 }
@@ -15,8 +17,31 @@ public:
     explicit ProgrammingSelectionWindow(QWidget *parent = 0);
     ~ProgrammingSelectionWindow();
 
+    void setModeEnabled(bool enabled);
+    void setCookTypeEnabled(bool enabled);
+
 private:
     Ui::ProgrammingSelectionWindow *ui;
+
+signals:
+    void added();
+    void modeSelected(Define::Mode);
+    void cookTypeSelected(Define::CookType);
+
+private slots:
+    void onModeClicked(Define::Mode mode);
+    void onCookTypeClicked(Define::CookType type);
+
+    void on_steamButton_clicked();
+    void on_combiButton_clicked();
+    void on_dryheatButton_clicked();
+    void on_poultryButton_clicked();
+    void on_meatButton_clicked();
+    void on_fishButton_clicked();
+    void on_dessertButton_clicked();
+    void on_grainButton_clicked();
+    void on_breadButton_clicked();
+    void on_etcButton_clicked();
 };
 
 #endif // PROGRAMMINGSELECTIONWINDOW_H
diff --git a/app/gui/oven_control/programmingselectionwindow.ui b/app/gui/oven_control/programmingselectionwindow.ui
index 84534fd..01eae84 100644
--- a/app/gui/oven_control/programmingselectionwindow.ui
+++ b/app/gui/oven_control/programmingselectionwindow.ui
@@ -1,24 +1,704 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
- <author/>
- <comment/>
- <exportmacro/>
  <class>ProgrammingSelectionWindow</class>
  <widget class="QMainWindow" name="ProgrammingSelectionWindow">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>800</width>
-    <height>600</height>
+    <width>900</width>
+    <height>1600</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>MainWindow</string>
   </property>
-  <widget class="QMenuBar" name="menubar"/>
-  <widget class="QWidget" name="centralwidget"/>
-  <widget class="QStatusBar" name="statusbar"/>
+  <property name="styleSheet">
+   <string notr="true">#centralwidget { background-image: url(:/images/background/main.png); }
+#bottomBar { background-image: url(:/images/bottom_bar/background.png); }
+
+QWidget { outline: none; }
+
+QPushButton[style=&quot;mode&quot;] {
+background-repeat: no-repeat;
+background-position: center;
+background-clip: border;
+background-origin: border;
+margin-bottom: 50px;
+
+border-top: 200px;
+border-bottom: -50px;
+border-style: hidden;
+color: white;
+font-size: 40px;
+}
+
+QPushButton[style=&quot;type&quot;] {
+background-repeat: no-repeat;
+background-position: center;
+background-clip: border;
+background-origin: border;
+
+border-top: 165px;
+border-style: hidden;
+color: white;
+font-size: 30px;
+}
+
+QPushButton[style=&quot;function&quot;] {
+background-repeat: no-repeat;
+background-position: center;
+background-clip: border;
+background-origin: border;
+
+border-top: 206px;
+border-style: hidden;
+color: white;
+font-size: 30px;
+}
+
+QPushButton:disabled { color: #7B7B7B; }</string>
+  </property>
+  <widget class="QWidget" name="centralwidget">
+   <widget class="QPushButton" name="dessertButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>675</x>
+      <y>720</y>
+      <width>225</width>
+      <height>222</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_type/desert.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_type/desert_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_type/desert_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>디저트류</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>type</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="fishButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>450</x>
+      <y>720</y>
+      <width>225</width>
+      <height>222</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_type/fish.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_type/fish_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_type/fish_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>생선류</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>type</string>
+    </property>
+   </widget>
+   <widget class="Line" name="line_6">
+    <property name="geometry">
+     <rect>
+      <x>675</x>
+      <y>993</y>
+      <width>1</width>
+      <height>120</height>
+     </rect>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Vertical</enum>
+    </property>
+   </widget>
+   <widget class="Line" name="line_4">
+    <property name="geometry">
+     <rect>
+      <x>225</x>
+      <y>993</y>
+      <width>1</width>
+      <height>120</height>
+     </rect>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Vertical</enum>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="multiButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>1164</y>
+      <width>300</width>
+      <height>286</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/main_button/multi.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/main_button/multi_ov.png); }
+QPushButton:disabled { background-image: url(:/images/main_button/multi_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>다중요리</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>function</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="grainButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>942</y>
+      <width>225</width>
+      <height>222</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_type/vegetable.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_type/vegetable_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_type/vegetable_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>채소및곡류</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>type</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="meatButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>225</x>
+      <y>720</y>
+      <width>225</width>
+      <height>222</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_type/meat.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_type/meat_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_type/meat_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>육류</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>type</string>
+    </property>
+   </widget>
+   <widget class="QWidget" name="bottomBar" native="true">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>1450</y>
+      <width>900</width>
+      <height>150</height>
+     </rect>
+    </property>
+    <property name="minimumSize">
+     <size>
+      <width>900</width>
+      <height>150</height>
+     </size>
+    </property>
+    <property name="maximumSize">
+     <size>
+      <width>900</width>
+      <height>150</height>
+     </size>
+    </property>
+    <widget class="QPushButton" name="configButton">
+     <property name="geometry">
+      <rect>
+       <x>345</x>
+       <y>26</y>
+       <width>97</width>
+       <height>97</height>
+      </rect>
+     </property>
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="minimumSize">
+      <size>
+       <width>62</width>
+       <height>71</height>
+      </size>
+     </property>
+     <property name="styleSheet">
+      <string notr="true">QPushButton { border-image: url(:/images/bottom_bar/config.png); }
+QPushButton:pressed, QPushButton:focus { border-image: url(:/images/bottom_bar/config_ov.png); }</string>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+    <widget class="QPushButton" name="helpButton">
+     <property name="geometry">
+      <rect>
+       <x>458</x>
+       <y>26</y>
+       <width>97</width>
+       <height>97</height>
+      </rect>
+     </property>
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="minimumSize">
+      <size>
+       <width>62</width>
+       <height>71</height>
+      </size>
+     </property>
+     <property name="styleSheet">
+      <string notr="true">QPushButton { border-image: url(:/images/bottom_bar/help.png); }
+QPushButton:pressed, QPushButton:focus { border-image: url(:/images/bottom_bar/help_ov.png); }</string>
+     </property>
+     <property name="text">
+      <string/>
+     </property>
+    </widget>
+   </widget>
+   <widget class="Line" name="line_3">
+    <property name="geometry">
+     <rect>
+      <x>675</x>
+      <y>771</y>
+      <width>1</width>
+      <height>120</height>
+     </rect>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Vertical</enum>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="dryheatButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>600</x>
+      <y>426</y>
+      <width>300</width>
+      <height>293</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_mode/big_dryheat.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_mode/big_dryheat_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_mode/big_dryheat_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>건열</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>mode</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="etcButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>450</x>
+      <y>942</y>
+      <width>225</width>
+      <height>222</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_type/etc.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_type/etc_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_type/etc_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>기타요리</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>type</string>
+    </property>
+   </widget>
+   <widget class="Line" name="line_7">
+    <property name="geometry">
+     <rect>
+      <x>18</x>
+      <y>942</y>
+      <width>863</width>
+      <height>1</height>
+     </rect>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Horizontal</enum>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="washButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>600</x>
+      <y>1164</y>
+      <width>300</width>
+      <height>286</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/main_button/wash.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/main_button/wash_ov.png); }
+QPushButton:disabled { background-image: url(:/images/main_button/wash_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>세척모드</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>function</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="programmingButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>300</x>
+      <y>1164</y>
+      <width>300</width>
+      <height>286</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/main_button/custom.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/main_button/custom_ov.png); }
+QPushButton:disabled { background-image: url(:/images/main_button/custom_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>프로그래밍모드</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>function</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="steamButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>426</y>
+      <width>300</width>
+      <height>293</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_mode/big_steam.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_mode/big_steam_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_mode/big_steam_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>스팀</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>mode</string>
+    </property>
+   </widget>
+   <widget class="Line" name="line">
+    <property name="geometry">
+     <rect>
+      <x>225</x>
+      <y>771</y>
+      <width>1</width>
+      <height>120</height>
+     </rect>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Vertical</enum>
+    </property>
+   </widget>
+   <widget class="Line" name="line_5">
+    <property name="geometry">
+     <rect>
+      <x>450</x>
+      <y>993</y>
+      <width>1</width>
+      <height>120</height>
+     </rect>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Vertical</enum>
+    </property>
+   </widget>
+   <widget class="Line" name="line_2">
+    <property name="geometry">
+     <rect>
+      <x>450</x>
+      <y>771</y>
+      <width>1</width>
+      <height>120</height>
+     </rect>
+    </property>
+    <property name="orientation">
+     <enum>Qt::Vertical</enum>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="poultryButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>720</y>
+      <width>225</width>
+      <height>222</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_type/poultry.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_type/poultry_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_type/poultry_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>가금류</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>type</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="combiButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>300</x>
+      <y>426</y>
+      <width>300</width>
+      <height>293</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_mode/big_combi.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_mode/big_combi_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_mode/big_combi_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>콤비</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>mode</string>
+    </property>
+   </widget>
+   <widget class="QPushButton" name="primeButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>675</x>
+      <y>942</y>
+      <width>225</width>
+      <height>222</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_type/additional.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_type/additional_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_type/additional_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>부가기능</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>type</string>
+    </property>
+   </widget>
+   <widget class="QWidget" name="clockContainer" native="true">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>0</y>
+      <width>900</width>
+      <height>426</height>
+     </rect>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">#clockContainer { background-image: url(:/images/clock/background.png); }</string>
+    </property>
+    <widget class="Clock" name="clock" native="true">
+     <property name="geometry">
+      <rect>
+       <x>272</x>
+       <y>36</y>
+       <width>356</width>
+       <height>355</height>
+      </rect>
+     </property>
+    </widget>
+    <widget class="WashWarnIcon" name="label">
+     <property name="geometry">
+      <rect>
+       <x>800</x>
+       <y>320</y>
+       <width>80</width>
+       <height>84</height>
+      </rect>
+     </property>
+    </widget>
+   </widget>
+   <widget class="QPushButton" name="breadButton">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
+    <property name="geometry">
+     <rect>
+      <x>225</x>
+      <y>942</y>
+      <width>225</width>
+      <height>222</height>
+     </rect>
+    </property>
+    <property name="sizePolicy">
+     <sizepolicy hsizetype="Maximum" vsizetype="Maximum">
+      <horstretch>0</horstretch>
+      <verstretch>0</verstretch>
+     </sizepolicy>
+    </property>
+    <property name="styleSheet">
+     <string notr="true">QPushButton { background-image: url(:/images/cook_type/bread.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/cook_type/bread_ov.png); }
+QPushButton:disabled { background-image: url(:/images/cook_type/bread_hide.png); }</string>
+    </property>
+    <property name="text">
+     <string>제과제빵류</string>
+    </property>
+    <property name="style" stdset="0">
+     <string>type</string>
+    </property>
+   </widget>
+  </widget>
  </widget>
- <pixmapfunction/>
+ <customwidgets>
+  <customwidget>
+   <class>Clock</class>
+   <extends>QWidget</extends>
+   <header>clock.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>WashWarnIcon</class>
+   <extends>QLabel</extends>
+   <header>washwarnicon.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>steamButton</tabstop>
+  <tabstop>combiButton</tabstop>
+  <tabstop>dryheatButton</tabstop>
+  <tabstop>poultryButton</tabstop>
+  <tabstop>meatButton</tabstop>
+  <tabstop>fishButton</tabstop>
+  <tabstop>dessertButton</tabstop>
+  <tabstop>grainButton</tabstop>
+  <tabstop>breadButton</tabstop>
+  <tabstop>etcButton</tabstop>
+  <tabstop>primeButton</tabstop>
+  <tabstop>multiButton</tabstop>
+  <tabstop>programmingButton</tabstop>
+  <tabstop>washButton</tabstop>
+  <tabstop>configButton</tabstop>
+  <tabstop>helpButton</tabstop>
+ </tabstops>
+ <resources/>
  <connections/>
 </ui>
diff --git a/app/gui/oven_control/programmingwindow.cpp b/app/gui/oven_control/programmingwindow.cpp
index 456edcd..6ef92c3 100644
--- a/app/gui/oven_control/programmingwindow.cpp
+++ b/app/gui/oven_control/programmingwindow.cpp
@@ -1,6 +1,13 @@
 #include "programmingwindow.h"
 #include "ui_programmingwindow.h"
 
+#include <QPainter>
+#include <QtDebug>
+
+#include "programmingmanualwindow.h"
+#include "programmingselectionwindow.h"
+#include "cookprogram.h"
+
 ProgrammingWindow::ProgrammingWindow(QWidget *parent) :
     QMainWindow(parent),
     ui(new Ui::ProgrammingWindow)
@@ -9,6 +16,8 @@ ProgrammingWindow::ProgrammingWindow(QWidget *parent) :
 
     ui->clockContainer->setParent(ui->upperStack);
     setAttribute(Qt::WA_DeleteOnClose);
+
+    setupUi();
 }
 
 ProgrammingWindow::~ProgrammingWindow()
@@ -16,7 +25,186 @@ ProgrammingWindow::~ProgrammingWindow()
     delete ui;
 }
 
+void ProgrammingWindow::listAuto()
+{
+    if (!ui->autoButton->isChecked())
+    {
+        ui->autoButton->blockSignals(true);
+        ui->autoButton->setChecked(true);
+        ui->autoButton->blockSignals(false);
+    }
+
+    listButtons(CookProgram::listAuto());
+}
+
+void ProgrammingWindow::listManual()
+{
+    if (!ui->manualButton->isChecked())
+    {
+        ui->manualButton->blockSignals(true);
+        ui->manualButton->setChecked(true);
+        ui->manualButton->blockSignals(false);
+    }
+
+    listButtons(CookProgram::listManual());
+}
+
+void ProgrammingWindow::setupUi()
+{
+    ui->verticalScrollLayout->setAlignment(Qt::AlignTop);
+
+    QFont font = ui->addButton->font();
+    font.setPixelSize(30);
+
+    int textWidth = QFontMetrics(font).width(tr("추가하기"));
+
+    QPixmap iconPix(":/images/etc/bar_icon_03.png");
+
+    QPixmap pixmap(QSize(iconPix.width() + 20 + textWidth, ui->addButton->height()));
+    pixmap.fill(Qt::transparent);
+
+    QRect textRect(iconPix.width() + 20, 0, textWidth, pixmap.height());
+
+    QPainter painter(&pixmap);
+    painter.setFont(font);
+    painter.setPen(Qt::white);
+    painter.drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, tr("추가하기"));
+    painter.drawPixmap(0, (pixmap.height() - iconPix.height()) / 2, iconPix);
+
+    QIcon icon(pixmap);
+    ui->addButton->setIcon(icon);
+    ui->addButton->setIconSize(pixmap.size());
+    ui->addButton->hide();
+}
+
+void ProgrammingWindow::updateView()
+{
+    if (ui->autoButton->isChecked())
+        listAuto();
+    else if (ui->manualButton->isChecked())
+        listManual();
+}
+
+void ProgrammingWindow::listButtons(QList<CookRecord> record)
+{
+    clear();
+
+    ui->addButton->show();
+
+    foreach (CookRecord r, record)
+        newButton(r);
+
+    ui->scrollAreaWidgetContents->adjustSize();
+}
+
+void ProgrammingWindow::clear()
+{
+    lastInfoDisplayed = NULL;
+    while (!list.isEmpty())
+        list.takeFirst()->deleteLater();
+}
+
+CookPanelButton *ProgrammingWindow::newButton(CookRecord record)
+{
+    CookPanelButton *button = new CookPanelButton(record, this);
+    connect(button, SIGNAL(infoClicked(CookPanelButton*)), SLOT(onInfoButtonClicked(CookPanelButton*)));
+    connect(button, SIGNAL(deleteClicked(CookPanelButton*)), SLOT(onDeleteButtonClicked(CookPanelButton*)));
+
+    ui->verticalScrollLayout->addWidget(button);
+    list.append(button);
+
+    return button;
+}
+
+void ProgrammingWindow::onInfoButtonClicked(CookPanelButton *panelButton)
+{
+    if (lastInfoDisplayed)
+    {
+        if (panelButton == lastInfoDisplayed)
+        {
+            lastInfoDisplayed->hideInfo();
+            lastInfoDisplayed = NULL;
+
+            ui->scrollAreaWidgetContents->adjustSize();
+        }
+        else
+        {
+            lastInfoDisplayed->hideInfo();
+            lastInfoDisplayed = panelButton;
+            lastInfoDisplayed->showInfo();
+
+            ui->scrollAreaWidgetContents->adjustSize();
+            ui->scrollArea->ensureWidgetVisible(lastInfoDisplayed);
+        }
+    }
+    else
+    {
+        lastInfoDisplayed = panelButton;
+        lastInfoDisplayed->showInfo();
+
+        ui->scrollAreaWidgetContents->adjustSize();
+        ui->scrollArea->ensureWidgetVisible(lastInfoDisplayed);
+    }
+}
+
+void ProgrammingWindow::onDeleteButtonClicked(CookPanelButton *panelButton)
+{
+    if (panelButton == lastInfoDisplayed)
+        lastInfoDisplayed = NULL;
+
+    CookProgram::remove(panelButton->record);
+
+    list.removeAll(panelButton);
+    panelButton->deleteLater();
+}
+
+void ProgrammingWindow::on_addButton_clicked()
+{
+    ProgrammingSelectionWindow *w = new ProgrammingSelectionWindow(this);
+
+    if (ui->autoButton->isChecked())
+        w->setCookTypeEnabled(true);
+    else if (ui->manualButton->isChecked())
+        w->setModeEnabled(true);
+
+    w->setWindowModality(Qt::WindowModal);
+    w->showFullScreen();
+    w->raise();
+
+    connect(w, SIGNAL(added()), SLOT(updateView()));
+}
+
+void ProgrammingWindow::on_autoButton_toggled(bool checked)
+{
+    if (!checked)
+        return;
+
+    listAuto();
+}
+
+void ProgrammingWindow::on_manualButton_toggled(bool checked)
+{
+    if (!checked)
+        return;
+
+    listManual();
+}
+
 void ProgrammingWindow::on_backButton_clicked()
 {
+    CookProgram::discard();
+
+    close();
+}
+
+void ProgrammingWindow::on_saveButton_clicked()
+{
+    CookProgram::save();
+
     close();
 }
+
+void ProgrammingWindow::on_helpButton_clicked()
+{
+
+}
diff --git a/app/gui/oven_control/programmingwindow.h b/app/gui/oven_control/programmingwindow.h
index ff8d118..b558749 100644
--- a/app/gui/oven_control/programmingwindow.h
+++ b/app/gui/oven_control/programmingwindow.h
@@ -3,6 +3,8 @@
 
 #include <QMainWindow>
 
+#include "cookpanelbutton.h"
+
 namespace Ui {
 class ProgrammingWindow;
 }
@@ -15,11 +17,34 @@ public:
     explicit ProgrammingWindow(QWidget *parent = 0);
     ~ProgrammingWindow();
 
+    void listAuto();
+    void listManual();
+
 private slots:
+    void setupUi();
+    void updateView();
+
+    void listButtons(QList<CookRecord> record);
+    void clear();
+    CookPanelButton *newButton(CookRecord record);
+
+    void onInfoButtonClicked(CookPanelButton *panelButton);
+    void onDeleteButtonClicked(CookPanelButton *panelButton);
+
+    void on_addButton_clicked();
+
+    void on_autoButton_toggled(bool checked);
+    void on_manualButton_toggled(bool checked);
+
     void on_backButton_clicked();
+    void on_saveButton_clicked();
+    void on_helpButton_clicked();
 
 private:
     Ui::ProgrammingWindow *ui;
+
+    QList<CookPanelButton *> list;
+    CookPanelButton *lastInfoDisplayed;
 };
 
 #endif // PROGRAMMINGWINDOW_H
diff --git a/app/gui/oven_control/programmingwindow.ui b/app/gui/oven_control/programmingwindow.ui
index 70e5ee9..3f0d6a0 100644
--- a/app/gui/oven_control/programmingwindow.ui
+++ b/app/gui/oven_control/programmingwindow.ui
@@ -16,11 +16,16 @@
   <property name="styleSheet">
    <string notr="true">#centralwidget { background-image: url(:/images/background/etc.png); }
 #bottomBar { background-image: url(:/images/bottom_bar/background.png); }
+QScrollArea { background: transparent; }
+QScrollArea &gt; QWidget &gt; QWidget { background: transparent; }
 
-
-QPushButton[style=&quot;mode&quot;] {
+QPushButton {
 background-repeat: no-repeat;
 background-position: center;
+border: none;
+color: white;
+}
+QPushButton[style=&quot;mode&quot;] {
 background-clip: border;
 background-origin: border;
 margin-bottom: 50px;
@@ -28,13 +33,35 @@ margin-bottom: 50px;
 border-top: 130px;
 border-bottom: -50px;
 border-style: hidden;
-color: white;
 font-size: 30px;
 }
 
 QPushButton[style=&quot;mode&quot;]:checked {
 image: url(:/images/cook_mode/indicator.png);
 image-position: bottom;
+}
+
+QScrollBar:vertical {
+border: none;
+background: transparent;
+width: 35px;
+margin: 30px 15px 30px 0px;
+}
+QScrollBar::handle:vertical {
+background: #B7B7B7;
+border-radius: 10px;
+min-height: 100px;
+}
+QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
+border: none;
+background: none;
+height: 0px;
+}
+QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
+border: none;
+}
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
+background: none;
 }</string>
   </property>
   <widget class="QWidget" name="centralwidget">
@@ -100,7 +127,7 @@ QPushButton:pressed { border-image: url(:/images/bottom_bar/back_ov.png); }</str
       <string/>
      </property>
     </widget>
-    <widget class="QPushButton" name="washButton">
+    <widget class="QPushButton" name="saveButton">
      <property name="geometry">
       <rect>
        <x>402</x>
@@ -146,7 +173,7 @@ QPushButton:pressed { border-image: url(:/images/bottom_bar/help_ov.png); }</str
     </property>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
-      <widget class="QPushButton" name="steamButton">
+      <widget class="QPushButton" name="autoButton">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
          <horstretch>0</horstretch>
@@ -172,7 +199,7 @@ QPushButton:pressed { background-image: url(:/images/etc/main_btn_01_ov.png); }<
       </widget>
      </item>
      <item>
-      <widget class="QPushButton" name="steamButton_2">
+      <widget class="QPushButton" name="manualButton">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Minimum" vsizetype="Expanding">
          <horstretch>0</horstretch>
@@ -199,6 +226,63 @@ QPushButton:pressed { background-image: url(:/images/etc/main_btn_02_ov.png); }<
      </item>
     </layout>
    </widget>
+   <widget class="QScrollArea" name="scrollArea">
+    <property name="geometry">
+     <rect>
+      <x>0</x>
+      <y>647</y>
+      <width>900</width>
+      <height>803</height>
+     </rect>
+    </property>
+    <property name="widgetResizable">
+     <bool>true</bool>
+    </property>
+    <widget class="QWidget" name="scrollAreaWidgetContents">
+     <property name="geometry">
+      <rect>
+       <x>0</x>
+       <y>0</y>
+       <width>898</width>
+       <height>801</height>
+      </rect>
+     </property>
+     <layout class="QVBoxLayout" name="verticalScrollLayout">
+      <property name="spacing">
+       <number>10</number>
+      </property>
+      <property name="leftMargin">
+       <number>20</number>
+      </property>
+      <property name="topMargin">
+       <number>28</number>
+      </property>
+      <property name="bottomMargin">
+       <number>28</number>
+      </property>
+      <item>
+       <widget class="QPushButton" name="addButton">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize">
+         <size>
+          <width>821</width>
+          <height>65</height>
+         </size>
+        </property>
+        <property name="styleSheet">
+         <string notr="true">QPushButton { background-image: url(:/images/etc/bar_01.png); }
+QPushButton:pressed, QPushButton:focus { background-image: url(:/images/etc/bar_02.png); }</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </widget>
   </widget>
  </widget>
  <customwidgets>
-- 
2.1.4