Add Cell, CellModel
diff --git a/ide/CellModel.cpp b/ide/CellModel.cpp
new file mode 100644
index 0000000..911c9a9
--- /dev/null
+++ b/ide/CellModel.cpp
@@ -0,0 +1,117 @@
+#include "CellModel.h"
+
+CellModel::CellModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+}
+
+CellModel::CellModel(const CellModel &model, QObject *parent)
+ : CellModel(parent)
+{
+ _cells = model._cells;
+}
+
+int CellModel::rowCount(const QModelIndex &parent) const
+{
+ // For list models only the root node (an invalid parent) should return the list's size. For all
+ // other (valid) parents, rowCount() should return 0 so that it does not become a tree model.
+ if (parent.isValid())
+ return 0;
+
+ return _cells.size();
+}
+
+QVariant CellModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ switch (role)
+ {
+ case CodeRole:
+ return _cells[index.row()].code();
+ case ResultRole:
+ return _cells[index.row()].result();
+ default:
+ return QVariant();
+ }
+}
+
+bool CellModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (data(index, role) != value)
+ {
+ switch (role)
+ {
+ case CodeRole:
+ _cells[index.row()].setCode(value.toString());
+ break;
+ case ResultRole:
+ _cells[index.row()].setResult(value.toString());
+ break;
+ default:
+ return false;
+ }
+
+ emit dataChanged(index, index, QVector<int>() << role);
+
+ return true;
+ }
+
+ return false;
+}
+
+Qt::ItemFlags CellModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return Qt::NoItemFlags;
+
+ return Qt::ItemIsEditable; // FIXME: Implement me!
+}
+
+bool CellModel::insertRows(int row, int count, const QModelIndex &parent)
+{
+ beginInsertRows(parent, row, row + count - 1);
+
+ for (int i = 0; i < count; i++)
+ _cells.insert(row, Cell());
+
+ endInsertRows();
+
+ return false;
+}
+
+bool CellModel::removeRows(int row, int count, const QModelIndex &parent)
+{
+ beginRemoveRows(parent, row, row + count - 1);
+
+ for (int i = 0; i < count; i++)
+ _cells.removeAt(row);
+
+ endRemoveRows();
+
+ return true;
+}
+
+QHash<int, QByteArray> CellModel::roleNames() const
+{
+ return {
+ {CodeRole, "code"},
+ {ResultRole, "result"},
+ };
+}
+
+void CellModel::addCell(const Cell &cell)
+{
+ int i = _cells.size();
+
+ insertRows(i, 1, QModelIndex());
+
+ _cells[i] = cell;
+ emit dataChanged(index(i), index(i), {CodeRole, ResultRole});
+}
+
+void CellModel::addCell(QString code, QString result)
+{
+ addCell(Cell(code, result));
+}