Commit 1fb13e35 authored by Nikita Sirgienko's avatar Nikita Sirgienko

Add Session::finishRunExpression and move code for variable modele updating...

Add Session::finishRunExpression and move code for variable modele updating (and expressions finishing) to Session
parent a02c4003
......@@ -34,11 +34,9 @@
#include <signal.h>
#endif
RSession::RSession(Cantor::Backend* backend) : Session(backend),
RSession::RSession(Cantor::Backend* backend) : Session(backend, new RVariableModel(this)),
m_process(nullptr),
m_rServer(nullptr),
m_variableModel(new RVariableModel(this)),
m_needUpdate(false)
m_rServer(nullptr)
{
}
......@@ -77,8 +75,9 @@ void RSession::logout()
qDebug()<<"logout";
m_process->terminate();
m_variableModel->clearVariables();
m_variableModel->clearFunctions();
RVariableModel* model = static_cast<RVariableModel*>(variableModel());
model->clearVariables();
model->clearFunctions();
emit symbolsChanged();
changeStatus(Status::Disable);
......@@ -131,10 +130,11 @@ Cantor::CompletionObject* RSession::completionFor(const QString& command, int in
QSyntaxHighlighter* RSession::syntaxHighlighter(QObject* parent)
{
RHighlighter *h=new RHighlighter(parent);
connect(m_variableModel, &Cantor::DefaultVariableModel::variablesAdded, h, &RHighlighter::addUserVariable);
connect(m_variableModel, &Cantor::DefaultVariableModel::variablesRemoved, h, &RHighlighter::removeUserVariable);
connect(m_variableModel, &Cantor::DefaultVariableModel::functionsAdded, h, &RHighlighter::addUserFunction);
connect(m_variableModel, &Cantor::DefaultVariableModel::functionsRemoved, h, &RHighlighter::removeUserFunction);
RVariableModel* model = static_cast<RVariableModel*>(variableModel());
connect(model, &Cantor::DefaultVariableModel::variablesAdded, h, &RHighlighter::addUserVariable);
connect(model, &Cantor::DefaultVariableModel::variablesRemoved, h, &RHighlighter::removeUserVariable);
connect(model, &Cantor::DefaultVariableModel::functionsAdded, h, &RHighlighter::addUserFunction);
connect(model, &Cantor::DefaultVariableModel::functionsRemoved, h, &RHighlighter::removeUserFunction);
return h;
}
......@@ -145,21 +145,11 @@ void RSession::serverChangedStatus(int status)
{
if(!expressionQueue().isEmpty())
{
RExpression* expr = static_cast<RExpression*>(expressionQueue().takeFirst());
m_needUpdate |= !expr->isInternal();
RExpression* expr = static_cast<RExpression*>(expressionQueue().first());
qDebug()<<"done running "<<expr<<" "<<expr->command();
}
if(expressionQueue().isEmpty())
if (m_needUpdate)
{
m_needUpdate = false;
m_variableModel->update();
}
else
changeStatus(Cantor::Session::Done);
else
runFirstExpression();
finishFirstExpression();
}
else
changeStatus(Cantor::Session::Running);
......@@ -193,11 +183,6 @@ void RSession::sendInputToServer(const QString& input)
m_rServer->answerRequest(s);
}
QAbstractItemModel* RSession::variableModel()
{
return m_variableModel;
}
void RSession::updateSymbols(const RVariableModel* model)
{
disconnect(m_rServer, SIGNAL(symbolList(QStringList,QStringList,QStringList)));
......
......@@ -28,8 +28,8 @@
#include "rserver_interface.h"
class RExpression;
class QProcess;
class RVariableModel;
class QProcess;
namespace Cantor {
class DefaultVariableModel;
......@@ -50,7 +50,6 @@ class RSession : public Cantor::Session
Cantor::Expression* evaluateExpression(const QString& command, Cantor::Expression::FinishingBehavior behave = Cantor::Expression::FinishingBehavior::DoNotDelete, bool internal = false) override;
Cantor::CompletionObject* completionFor(const QString& command, int index=-1) override;
QSyntaxHighlighter* syntaxHighlighter(QObject* parent) override;
QAbstractItemModel* variableModel() override;
void runFirstExpression() override;
void sendInputToServer(const QString& input);
......@@ -64,9 +63,6 @@ class RSession : public Cantor::Session
private:
QProcess* m_process;
org::kde::Cantor::R* m_rServer;
RVariableModel* m_variableModel;
bool m_needUpdate;
};
#endif /* _RSESSION_H */
......@@ -47,11 +47,9 @@ const QRegExp MaximaSession::MaximaOutputPrompt=QRegExp(QLatin1String("(\\(\\s*%
const QRegExp MaximaSession::MaximaInputPrompt = QRegExp(QLatin1String("(\\(\\s*%\\s*i\\s*[0-9\\s]*\\))"));
MaximaSession::MaximaSession( Cantor::Backend* backend ) : Session(backend),
MaximaSession::MaximaSession( Cantor::Backend* backend ) : Session(backend, new MaximaVariableModel(this)),
m_process(nullptr),
m_variableModel(new MaximaVariableModel(this)),
m_justRestarted(false),
m_needUpdate(false)
m_justRestarted(false)
{
}
......@@ -90,7 +88,7 @@ void MaximaSession::login()
QString autorunScripts = MaximaSettings::self()->autorunScripts().join(QLatin1String(";"));
autorunScripts.append(QLatin1String(";kill(labels)")); // Reset labels after running autorun scripts
evaluateExpression(autorunScripts, MaximaExpression::DeleteOnFinish, true);
m_needUpdate = true;
forceVariableUpdate();
}
changeStatus(Session::Done);
......@@ -124,8 +122,9 @@ void MaximaSession::logout()
expressionQueue().clear();
delete m_process;
m_process = nullptr;
m_variableModel->clearVariables();
m_variableModel->clearFunctions();
MaximaVariableModel* model = static_cast<MaximaVariableModel*>(variableModel());
model->clearVariables();
model->clearFunctions();
changeStatus(Status::Disable);
......@@ -197,29 +196,21 @@ void MaximaSession::currentExpressionChangedStatus(Cantor::Expression::Status st
{
Cantor::Expression* expression = expressionQueue().first();
const QString& cmd = expression->command();
m_needUpdate |= !expression->isInternal();
qDebug() << "expression status changed: command = " << expression->command() << ", status = " << status;
if(status!=Cantor::Expression::Computing) //The session is ready for the next command
switch (status)
{
case Cantor::Expression::Done:
case Cantor::Expression::Error:
qDebug()<<"################################## EXPRESSION END ###############################################";
disconnect(expression, SIGNAL(statusChanged(Cantor::Expression::Status)),
this, SLOT(currentExpressionChangedStatus(Cantor::Expression::Status)));
this, SLOT(currentExpressionChangedStatus(Cantor::Expression::Status)));
expressionQueue().removeFirst();
if(expressionQueue().isEmpty())
{
if(m_needUpdate)
{
m_variableModel->update();
m_needUpdate = false;
}
else
changeStatus(Cantor::Session::Done);
}else
{
runFirstExpression();
}
finishFirstExpression();
break;
default:
break;
}
}
......@@ -334,11 +325,6 @@ QSyntaxHighlighter* MaximaSession::syntaxHighlighter(QObject* parent)
return new MaximaHighlighter(parent, this);
}
QAbstractItemModel* MaximaSession::variableModel()
{
return m_variableModel;
}
void MaximaSession::write(const QString& exp) {
qDebug()<<"################################## EXPRESSION START ###############################################";
qDebug()<<"sending expression to maxima process: " << exp;
......
......@@ -50,7 +50,6 @@ class MaximaSession : public Cantor::Session
Cantor::CompletionObject* completionFor(const QString& command, int index=-1) override;
Cantor::SyntaxHelpObject* syntaxHelpFor(const QString& command) override;
QSyntaxHighlighter* syntaxHighlighter(QObject*) override;
QAbstractItemModel* variableModel() override;
void runFirstExpression() override;
public Q_SLOTS:
......@@ -68,9 +67,7 @@ class MaximaSession : public Cantor::Session
QProcess* m_process;
QString m_cache;
MaximaVariableModel* m_variableModel;
bool m_justRestarted;
bool m_needUpdate;
};
#endif /* _MAXIMASESSION_H */
......@@ -44,15 +44,13 @@
const QRegExp OctaveSession::PROMPT_UNCHANGEABLE_COMMAND = QRegExp(QLatin1String("(,|;)+"));
OctaveSession::OctaveSession ( Cantor::Backend* backend ) : Session ( backend ),
OctaveSession::OctaveSession ( Cantor::Backend* backend ) : Session ( backend, new OctaveVariableModel(this) ),
m_process(nullptr),
m_prompt(QLatin1String("CANTOR_OCTAVE_BACKEND_PROMPT:([0-9]+)> ")),
m_subprompt(QLatin1String("CANTOR_OCTAVE_BACKEND_SUBPROMPT:([0-9]+)> ")),
m_previousPromptNumber(1),
m_watch(nullptr),
m_syntaxError(false),
m_needUpdate(false),
m_variableModel(new OctaveVariableModel(this))
m_syntaxError(false)
{
qDebug() << octaveScriptInstallDir;
}
......@@ -143,7 +141,7 @@ void OctaveSession::login()
QString autorunScripts = OctaveSettings::self()->autorunScripts().join(QLatin1String("\n"));
evaluateExpression(autorunScripts, OctaveExpression::DeleteOnFinish, true);
m_needUpdate = true;
forceVariableUpdate();
}
changeStatus(Cantor::Session::Done);
......@@ -183,7 +181,7 @@ void OctaveSession::logout()
m_output.clear();
m_previousPromptNumber = 1;
m_variableModel->clearVariables();
static_cast<OctaveVariableModel*>(variableModel())->clearVariables();
changeStatus(Status::Disable);
......@@ -318,19 +316,9 @@ void OctaveSession::currentExpressionStatusChanged(Cantor::Expression::Status st
{
case Cantor::Expression::Done:
case Cantor::Expression::Error:
m_needUpdate |= !expressionQueue().first()->isInternal();
expressionQueue().removeFirst();
if (expressionQueue().isEmpty())
if (m_needUpdate)
{
m_variableModel->update();
m_needUpdate = false;
}
else
changeStatus(Done);
else
runFirstExpression();
finishFirstExpression();
break;
default:
break;
}
......@@ -363,18 +351,13 @@ QSyntaxHighlighter* OctaveSession::syntaxHighlighter ( QObject* parent )
{
OctaveHighlighter* highlighter = new OctaveHighlighter ( parent, this );
connect ( m_variableModel, &Cantor::DefaultVariableModel::variablesAdded, highlighter, &OctaveHighlighter::addUserVariable);
connect ( m_variableModel, &Cantor::DefaultVariableModel::variablesRemoved, highlighter, &OctaveHighlighter::removeUserVariable);
OctaveVariableModel* model = static_cast<OctaveVariableModel*>(variableModel());
connect (model, &Cantor::DefaultVariableModel::variablesAdded, highlighter, &OctaveHighlighter::addUserVariable);
connect (model, &Cantor::DefaultVariableModel::variablesRemoved, highlighter, &OctaveHighlighter::removeUserVariable);
return highlighter;
}
QAbstractItemModel* OctaveSession::variableModel()
{
return m_variableModel;
}
void OctaveSession::runSpecificCommands()
{
m_process->write("figure(1,'visible','off')");
......
......@@ -32,7 +32,6 @@ class DefaultVariableModel;
class KDirWatch;
class OctaveExpression;
class OctaveVariableModel;
class KProcess;
......@@ -49,7 +48,6 @@ class OctaveSession : public Cantor::Session
Cantor::CompletionObject* completionFor(const QString& cmd, int index=-1) override;
Cantor::SyntaxHelpObject* syntaxHelpFor(const QString& cmd) override;
QSyntaxHighlighter* syntaxHighlighter(QObject* parent) override;
QAbstractItemModel* variableModel() override;
void runFirstExpression() override;
private:
......@@ -65,12 +63,9 @@ class OctaveSession : public Cantor::Session
KDirWatch* m_watch;
QString m_tempDir;
bool m_syntaxError;
bool m_needUpdate;
QString m_output;
OctaveVariableModel* m_variableModel;
private:
void readFromOctave(QByteArray data);
bool isDoNothingCommand(const QString& command);
......
......@@ -298,12 +298,8 @@ void SageSession::currentExpressionChangedStatus(Cantor::Expression::Status stat
{
case Cantor::Expression::Done:
case Cantor::Expression::Error:
expressionQueue().removeFirst();
if (expressionQueue().isEmpty())
changeStatus(Done);
else
runFirstExpression();
break;
finishFirstExpression();
default:
break;
}
......
......@@ -22,6 +22,7 @@
using namespace Cantor;
#include "backend.h"
#include "defaultvariablemodel.h"
#include <QTimer>
#include <QQueue>
......@@ -29,7 +30,7 @@ using namespace Cantor;
class Cantor::SessionPrivate
{
public:
SessionPrivate() : backend(nullptr), status(Session::Disable), typesettingEnabled(false), expressionCount(0)
SessionPrivate() : backend(nullptr), status(Session::Disable), typesettingEnabled(false), expressionCount(0), variableModel(nullptr), needUpdate(false)
{
}
......@@ -38,6 +39,8 @@ class Cantor::SessionPrivate
bool typesettingEnabled;
int expressionCount;
QList<Cantor::Expression*> expressionQueue;
DefaultVariableModel* variableModel;
bool needUpdate;
};
Session::Session( Backend* backend ) : QObject(backend), d(new SessionPrivate)
......@@ -45,6 +48,12 @@ Session::Session( Backend* backend ) : QObject(backend), d(new SessionPrivate)
d->backend=backend;
}
Session::Session( Backend* backend, DefaultVariableModel* model) : QObject(backend), d(new SessionPrivate)
{
d->backend=backend;
d->variableModel=model;
}
Session::~Session()
{
delete d;
......@@ -62,8 +71,8 @@ void Session::enqueueExpression(Expression* expr)
//run the newly added expression immediately if it's the only one in the queue
if (d->expressionQueue.size() == 1)
{
changeStatus(Cantor::Session::Running);
runFirstExpression();
changeStatus(Cantor::Session::Running);
runFirstExpression();
}
else
expr->setStatus(Cantor::Expression::Queued);
......@@ -74,6 +83,21 @@ void Session::runFirstExpression()
}
void Session::finishFirstExpression()
{
d->needUpdate |= !d->expressionQueue.takeFirst()->isInternal();
if (d->expressionQueue.isEmpty())
if (d->variableModel && d->needUpdate)
{
d->variableModel->update();
d->needUpdate = false;
}
else
changeStatus(Done);
else
runFirstExpression();
}
Backend* Session::backend()
{
return d->backend;
......@@ -135,10 +159,20 @@ QSyntaxHighlighter* Session::syntaxHighlighter(QObject* parent)
QAbstractItemModel* Session::variableModel()
{
//Return 0 per default, so Backends not offering variable management don't
//Return deafult session model per default
//By default, variableModel is nullptr, so Backends not offering variable management don't
//have to reimplement this. This method should only be called on backends with
//VariableManagement Capability flag
return nullptr;
return d->variableModel;
}
void Session::forceVariableUpdate()
{
if (d->variableModel)
{
d->variableModel->update();
d->needUpdate = false;
}
}
int Session::nextExpressionId()
......
......@@ -40,6 +40,7 @@ class Backend;
class SessionPrivate;
class CompletionObject;
class SyntaxHelpObject;
class DefaultVariableModel;
/**
* The Session object is the main class used to interact with a Backend.
......@@ -53,8 +54,8 @@ class CANTOR_EXPORT Session : public QObject
public:
enum Status {
Running, ///< the session is busy, running some expression
Done, ///< the session has done all the jobs, and is now waiting for more
Disable ///< the session don't login yet, or already logout
Done, ///< the session has done all the jobs, and is now waiting for more
Disable ///< the session don't login yet, or already logout
};
/**
......@@ -63,6 +64,12 @@ class CANTOR_EXPORT Session : public QObject
* @see login()
*/
explicit Session( Backend* backend);
/**
* Similar to Session::Session, but also specify variable model for automatically handles model's updates
*/
explicit Session( Backend* backend, DefaultVariableModel* model);
/**
* Destructor
*/
......@@ -208,6 +215,20 @@ class CANTOR_EXPORT Session : public QObject
*/
virtual void runFirstExpression();
/**
* Opposite action to Session::runFirstExpression()
* This method dequeue the expression and go to next expression, if queue not empty
* Also, this method updates variableModel, if needed
* If queue empty, session change status to Done
*/
virtual void finishFirstExpression();
/**
* Starts variable update immideatly, usefull for subclasses, which run internal command
* which could change variables listen
*/
virtual void forceVariableUpdate();
Q_SIGNALS:
void statusChanged(Cantor::Session::Status newStatus);
void loginStarted();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment