Add Notebook
diff --git a/ide/CellModel.cpp b/ide/CellModel.cpp
index 911c9a9..41acbe7 100644
--- a/ide/CellModel.cpp
+++ b/ide/CellModel.cpp
@@ -1,14 +1,14 @@
 #include "CellModel.h"
 
-CellModel::CellModel(QObject *parent)
+CellModel::CellModel(Notebook *parent)
     : QAbstractListModel(parent)
+    , _notebook(parent)
 {
 }
 
-CellModel::CellModel(const CellModel &model, QObject *parent)
-    : CellModel(parent)
+CellModel::CellModel(const CellModel &other)
+    : CellModel(other._notebook)
 {
-    _cells = model._cells;
 }
 
 int CellModel::rowCount(const QModelIndex &parent) const
@@ -18,7 +18,7 @@
     if (parent.isValid())
         return 0;
 
-    return _cells.size();
+    return _notebook->_cells.size();
 }
 
 QVariant CellModel::data(const QModelIndex &index, int role) const
@@ -29,9 +29,9 @@
     switch (role)
     {
     case CodeRole:
-        return _cells[index.row()].code();
+        return _notebook->_cells[index.row()].code();
     case ResultRole:
-        return _cells[index.row()].result();
+        return _notebook->_cells[index.row()].result();
     default:
         return QVariant();
     }
@@ -44,10 +44,10 @@
         switch (role)
         {
         case CodeRole:
-            _cells[index.row()].setCode(value.toString());
+            _notebook->_cells[index.row()].setCode(value.toString());
             break;
         case ResultRole:
-            _cells[index.row()].setResult(value.toString());
+            _notebook->_cells[index.row()].setResult(value.toString());
             break;
         default:
             return false;
@@ -74,7 +74,7 @@
     beginInsertRows(parent, row, row + count - 1);
 
     for (int i = 0; i < count; i++)
-        _cells.insert(row, Cell());
+        _notebook->_cells.insert(row, Cell());
 
     endInsertRows();
 
@@ -86,7 +86,7 @@
     beginRemoveRows(parent, row, row + count - 1);
 
     for (int i = 0; i < count; i++)
-        _cells.removeAt(row);
+        _notebook->_cells.removeAt(row);
 
     endRemoveRows();
 
@@ -103,11 +103,11 @@
 
 void CellModel::addCell(const Cell &cell)
 {
-    int i = _cells.size();
+    int i = _notebook->_cells.size();
 
     insertRows(i, 1, QModelIndex());
 
-    _cells[i] = cell;
+    _notebook->_cells[i] = cell;
     emit dataChanged(index(i), index(i), {CodeRole, ResultRole});
 }
 
diff --git a/ide/CellModel.h b/ide/CellModel.h
index 3920e38..16bfee5 100644
--- a/ide/CellModel.h
+++ b/ide/CellModel.h
@@ -3,16 +3,16 @@
 #include <QAbstractListModel>
 #include <qqml.h>
 
+#include "Notebook.h"
 #include "Cell.h"
 
 class CellModel : public QAbstractListModel
 {
     Q_OBJECT
-    QML_ELEMENT
 
 public:
-    explicit CellModel(QObject *parent = nullptr);
-    CellModel(const CellModel &model, QObject *parent = nullptr);
+    explicit CellModel(Notebook *parent = nullptr);
+    CellModel(const CellModel &other);
 
     enum CellRoles
     {
@@ -43,7 +43,8 @@
     Q_INVOKABLE void addCell(QString code, QString result);
 
 private:
-    QList<Cell> _cells;
+    Notebook *_notebook;
 };
 
 Q_DECLARE_METATYPE(CellModel)
+Q_DECLARE_METATYPE(CellModel *)
diff --git a/ide/IDE.pri b/ide/IDE.pri
index 906b3cb..f656fd1 100644
--- a/ide/IDE.pri
+++ b/ide/IDE.pri
@@ -16,12 +16,14 @@
 SOURCES += \
     $$PWD/Cell.cpp \
     $$PWD/CellModel.cpp \
-    $$PWD/IdeMain.cpp
+    $$PWD/IdeMain.cpp \
+    $$PWD/Notebook.cpp
 
 HEADERS += \
     $$PWD/Cell.h \
     $$PWD/CellModel.h \
-    $$PWD/IdeMain.h
+    $$PWD/IdeMain.h \
+    $$PWD/Notebook.h
 
 RESOURCES += \
     $$PWD/resources.qrc
diff --git a/ide/IdeMain.cpp b/ide/IdeMain.cpp
index a8f918c..d76c955 100644
--- a/ide/IdeMain.cpp
+++ b/ide/IdeMain.cpp
@@ -3,6 +3,8 @@
 #include <QQmlApplicationEngine>
 #include <QQuickStyle>
 
+#include "CellModel.h"
+
 int ideMain(QGuiApplication *app)
 {
     QQmlApplicationEngine engine;
@@ -12,6 +14,9 @@
 
     QQuickStyle::setStyle("Material");
 
+    qRegisterMetaType<CellModel>();
+    qRegisterMetaType<CellModel *>();
+
     const QUrl url(QStringLiteral("qrc:/qml/main.qml"));
     QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                      app, [url](QObject *obj, const QUrl &objUrl)
diff --git a/ide/Notebook.cpp b/ide/Notebook.cpp
new file mode 100644
index 0000000..9beb332
--- /dev/null
+++ b/ide/Notebook.cpp
@@ -0,0 +1,21 @@
+#include "Notebook.h"
+#include "CellModel.h"
+
+Notebook::Notebook(QObject *parent)
+    : QObject(parent)
+    , _cellModel(new CellModel(this))
+{
+
+}
+
+Notebook::Notebook(const Notebook &other, QObject *parent)
+    : QObject(parent)
+    , _cells(other._cells)
+    , _cellModel(new CellModel(this))
+{
+}
+
+CellModel *Notebook::cellModel()
+{
+    return _cellModel;
+}
diff --git a/ide/Notebook.h b/ide/Notebook.h
new file mode 100644
index 0000000..0bd84ec
--- /dev/null
+++ b/ide/Notebook.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <QObject>
+
+#include "Cell.h"
+
+class CellModel;
+
+class Notebook : public QObject
+{
+    Q_OBJECT
+    QML_ELEMENT
+
+    Q_PROPERTY(CellModel *cellModel READ cellModel NOTIFY cellModelChanged)
+
+public:
+    explicit Notebook(QObject *parent = nullptr);
+    Notebook(const Notebook &other, QObject *parent = nullptr);
+
+    CellModel *cellModel();
+
+signals:
+    void cellModelChanged();
+
+protected:
+    friend class CellModel;
+
+    QList<Cell> _cells;
+    CellModel *_cellModel;
+};
+
+Q_DECLARE_METATYPE(Notebook)
diff --git a/ide/icons/trash.svg b/ide/icons/trash.svg
new file mode 100644
index 0000000..d7da9e1
--- /dev/null
+++ b/ide/icons/trash.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M128 405.429C128 428.846 147.198 448 170.667 448h170.667C364.802 448 384 428.846 384 405.429V160H128v245.429zM416 96h-80l-26.785-32H202.786L176 96H96v32h320V96z"/></svg>
\ No newline at end of file
diff --git a/ide/qml/InsertRow.qml b/ide/qml/InsertRow.qml
index 00bad8b..fd7d8b9 100644
--- a/ide/qml/InsertRow.qml
+++ b/ide/qml/InsertRow.qml
@@ -6,6 +6,8 @@
 Rectangle {
     id: root
 
+    signal insertClicked()
+
     color: Material.color(Material.Grey, Material.theme == Material.Dark ? Material.Shade800 : Material.Shade300)
     height: 2
     Layout.fillWidth: true
@@ -51,12 +53,14 @@
         height: 24
         width: 24
 
-        Button {
+        RoundButton {
             id: addButton
             anchors.centerIn: parent
             icon.source: "qrc:///icons/add.svg"
             icon.color: Material.color(Material.Grey, Material.theme == Material.Dark ? Material.Shade400 : Material.Shade600)
             flat: true
+
+            onClicked: root.insertClicked()
         }
     }
 }
diff --git a/ide/qml/NotebookCell.qml b/ide/qml/NotebookCell.qml
index a441b73..3466d05 100644
--- a/ide/qml/NotebookCell.qml
+++ b/ide/qml/NotebookCell.qml
@@ -3,51 +3,89 @@
 import QtQuick.Controls.Material 2.0
 import QtQuick.Layouts 1.0
 
-ColumnLayout {
+Item {
     id: root
 
     required property string code
     required property string result
 
-    RowLayout {
-        Layout.fillWidth: true
+    signal insertBelowClicked()
+    signal codeEditingFinished(string code)
+    signal cellFocused()
 
-        Button {
-            Layout.alignment: Qt.AlignTop
-            icon.source: "qrc:///icons/play-circle.svg"
-            icon.color: Material.color(Material.Grey, Material.Shade600)
-            flat: true
-        }
+    height: column.height
 
-        ColumnLayout {
+    MouseArea {
+        id: selectCell
+
+        anchors.fill: column
+
+        onClicked: root.cellFocused()
+    }
+
+    ColumnLayout {
+        id: column
+
+        width: parent.width
+
+        RowLayout {
+            id: row
             Layout.fillWidth: true
-            Layout.fillHeight: true
 
-            TextArea {
+            RoundButton {
+                Layout.alignment: Qt.AlignTop
+                icon.source: "qrc:///icons/play-circle.svg"
+                icon.color: Material.color(Material.Grey, Material.Shade600)
+                flat: true
+            }
+
+            ColumnLayout {
                 Layout.fillWidth: true
                 Layout.fillHeight: true
-                id: code
-                font.family: "monospace"
-                text: root.code
-                selectByMouse: true
-                wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
 
-                Keys.onTabPressed: {
-                    var pos = cursorPosition + 4
-                    text += "    ";
-                    cursorPosition = pos
+                TextArea {
+                    Layout.fillWidth: true
+                    Layout.fillHeight: true
+                    id: code
+                    font.family: "monospace"
+                    text: root.code
+                    selectByMouse: true
+                    wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
+
+                    Keys.onTabPressed: {
+                        var pos = cursorPosition + 4
+                        text = text.slice(0, cursorPosition) + "    " + text.slice(cursorPosition);
+                        cursorPosition = pos
+                    }
+
+                    Keys.onEscapePressed: {
+                        root.forceActiveFocus()
+                    }
+
+                    onEditingFinished: {
+                        root.codeEditingFinished(text)
+                    }
+
+                    onFocusChanged: if (focus) root.cellFocused()
+                }
+
+                Label {
+                    visible: root.result.length > 0
+                    Layout.fillWidth: true
+                    font.family: "monospace"
+                    text: root.result
                 }
             }
 
-            Label {
-                Layout.fillWidth: true
-                font.family: "monospace"
-                text: root.result
+            RoundButton {
+                icon.source: "qrc:///icons/trash.svg"
+                icon.color: Material.color(Material.Grey, Material.theme == Material.Dark ? Material.Shade400 : Material.Shade600)
+                flat: true
             }
         }
-    }
 
-    InsertRow {
-
+        InsertRow {
+            onInsertClicked: root.insertBelowClicked()
+        }
     }
 }
diff --git a/ide/qml/main.qml b/ide/qml/main.qml
index 73a4581..a28d47d 100644
--- a/ide/qml/main.qml
+++ b/ide/qml/main.qml
@@ -15,14 +15,14 @@
     Material.theme: Material.Light
     Material.accent: Material.Orange
 
-    CellModel {
-        id: model
+    Notebook {
+        id: notebook
     }
 
     Component.onCompleted: {
-        model.addCell("Refal { = Hi!; }", "");
-        model.addCell("<Refal>", "Hi!");
-        model.addCell("Hello there", "Hello there");
+        notebook.cellModel.addCell("Refal { = Hi!; }", "");
+        notebook.cellModel.addCell("<Refal>", "Hi!");
+        notebook.cellModel.addCell("Hello there", "Hello there");
     }
 
     ColumnLayout {
@@ -36,14 +36,17 @@
 
             TabButton {
                 text: "Example Workspace"
+                width: implicitWidth
             }
 
             TabButton {
                 text: "Another Workspace"
+                width: implicitWidth
             }
 
             TabButton {
                 text: "Testing"
+                width: implicitWidth
             }
         }
 
@@ -57,11 +60,26 @@
                 id: codeEditor
                 SplitView.fillWidth: true
                 SplitView.minimumWidth: 400
-                model: model
+                model: notebook.cellModel
                 clip: true
 
                 delegate: NotebookCell {
+                    id: notebookCell
+
+                    required property var model
+                    required property var index
+
                     width: codeEditor.width - 5
+
+                    code: model.code
+                    result: model.result
+
+                    onCodeEditingFinished: model.code = code
+
+                    onInsertBelowClicked: {
+                        console.info(index)
+                        cellModel.insertRows(cellModel.index(0, index), 1)
+                    }
                 }
             }
 
diff --git a/ide/resources.qrc b/ide/resources.qrc
index f48925a..a77a977 100644
--- a/ide/resources.qrc
+++ b/ide/resources.qrc
@@ -5,5 +5,6 @@
         <file>icons/play-circle.svg</file>
         <file>icons/add.svg</file>
         <file>qml/InsertRow.qml</file>
+        <file>icons/trash.svg</file>
     </qresource>
 </RCC>