blob: a5baa0c4c81599a057253159b92890126a4c13a5 [file] [log] [blame]
#include "Notebook.h"
#include "CellModel.h"
#include "../PPrint.h"
#include <QJsonObject>
#include <QJsonArray>
#include <QFileDialog>
#include <QDebug>
// TODO: avoid potential race condition if Cell is deleted, pass by value with same UUID instead
Notebook::~Notebook()
{
_rtThread->quit();
_rtThread->wait();
delete _rt;
}
Notebook::Notebook(QObject *parent)
: QObject(parent)
, _cellModel(new CellModel(this))
, _rtThread(new QThread(this))
, _rt(new NbRuntime)
{
connect(_rt, &NbRuntime::cellFailedToParse, this, &Notebook::cellFailedToParse);
connect(_rt, &NbRuntime::cellFinishedRunning, this, &Notebook::cellFinishedRunning);
connect(_rt, &NbRuntime::cellQuit, this, &Notebook::cellQuit);
connect(_rt, &NbRuntime::cellRunning, this, &Notebook::cellRunning);
connect(_rt, &NbRuntime::cellWaiting, this, &Notebook::cellWaiting);
_rt->moveToThread(_rtThread);
_rtThread->start();
}
Notebook::Notebook(const Notebook &other, QObject *parent)
: Notebook(parent)
{
for (const Cell *cell : other._cells)
{
_cells.append(new Cell(*cell, this));
}
}
CellModel *Notebook::cellModel()
{
return _cellModel;
}
void Notebook::runCell(QUuid uuid)
{
qInfo() << "Running cell" << uuid;
_rt->queueCell(Cell::cellFromUuid(uuid));
}
void Notebook::quitCell(QUuid uuid)
{
_rt->unqueueCell(Cell::cellFromUuid(uuid));
_runningAll = false;
}
void Notebook::runAll()
{
if (_cells.size() > 0)
{
_rt->queueCell(_cells.first());
_runningAll = true;
}
}
void Notebook::reset()
{
_rt->reset();
}
void Notebook::fromJson(QJsonDocument doc)
{
QJsonObject nb = doc.object();
QJsonArray cellArray = nb["cells"].toArray();
for (const QJsonValueRef &cell : cellArray)
{
cellModel()->insertCellBefore(cellModel()->rowCount());
_cells.last()->fromJson(cell.toObject());
}
}
void Notebook::open(QString path)
{
QFile file(path);
if (file.exists())
{
file.open(QFile::ReadOnly);
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);
if (error.error == QJsonParseError::NoError)
{
fromJson(doc);
}
else
{
qWarning() << error.errorString();
}
file.close();
setSavePath(path);
}
else
{
qWarning() << "File does not exist" << path;
}
}
QJsonDocument Notebook::toJson() const
{
QJsonObject nb;
QJsonArray cellArray;
for (const Cell *cell : _cells)
{
cellArray.append(cell->toJson());
}
nb["cells"] = cellArray;
return QJsonDocument(nb);
}
void Notebook::save()
{
if (_savePath == "")
{
setSavePath(QFileDialog::getSaveFileName(nullptr, "Open REFAL Notebook", "", "REFAL Notebook (*.refnb)"));
}
QJsonDocument doc = toJson();
QFile save(_savePath);
save.open(QFile::WriteOnly);
if (!save.isOpen())
{
emit saveError(save.errorString());
return;
}
save.write(doc.toJson(QJsonDocument::Indented));
save.close();
emit saved();
}
bool Notebook::savePathSet()
{
return _savePath != "";
}
QString Notebook::savePath()
{
return _savePath;
}
void Notebook::setSavePath(QString savePath)
{
_savePath = savePath;
emit savePathChanged(savePath);
}
void Notebook::cellFinishedRunning(Cell *cell, RuntimeResult result)
{
qInfo() << "cellFinishedRunning" << cell->uuid() << pprint(result);
cell->setResult(pprint(result));
cell->setStatus(Cell::IDLE);
cell->setResultType(Cell::EXPRESSION);
if (_runningAll)
{
int index = _cells.indexOf(cell);
// not last
if (index < _cells.size() - 1)
{
_rt->queueCell(_cells[index + 1]);
}
else
{
_runningAll = false;
}
}
}
void Notebook::cellFailedToParse(Cell *cell, ParseResult result, Parser parser)
{
qInfo() << "cellFailedToParse" << cell->uuid() << pprint(result, parser);
cell->setResult(pprint(result, parser, PPrint::HTML));
cell->setStatus(Cell::IDLE);
cell->setResultType(Cell::DIAGNOSTIC);
_runningAll = false;
}
void Notebook::cellWaiting(Cell *cell)
{
qInfo() << "cellWaiting" << cell->uuid();
cell->setStatus(Cell::WAITING);
}
void Notebook::cellRunning(Cell *cell)
{
qInfo() << "cellRunning" << cell->uuid();
cell->setStatus(Cell::RUNNING);
}
void Notebook::cellQuit(Cell *cell)
{
qInfo() << "cellQuit" << cell->uuid();
cell->setResult("");
cell->setStatus(Cell::IDLE);
_runningAll = false;
}