diff --git a/src/backends/R/rsession.cpp b/src/backends/R/rsession.cpp index a713a55a..c5cd0f72 100644 --- a/src/backends/R/rsession.cpp +++ b/src/backends/R/rsession.cpp @@ -1,184 +1,183 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder Copyright (C) 2018 Alexander Semke */ #include "rsession.h" #include "rexpression.h" #include "rcompletionobject.h" #include "rhighlighter.h" #include "rvariablemodel.h" #include #include #include #include #ifndef Q_OS_WIN #include #endif RSession::RSession(Cantor::Backend* backend) : Session(backend), m_process(nullptr), m_rServer(nullptr) { setVariableModel(new RVariableModel(this)); } RSession::~RSession() { if (m_process) m_process->terminate(); } void RSession::login() { qDebug()<<"login"; emit loginStarted(); if(m_process) m_process->deleteLater(); m_process = new QProcess(this); m_process->start(QStandardPaths::findExecutable(QLatin1String("cantor_rserver"))); m_process->waitForStarted(); m_process->waitForReadyRead(); qDebug()<readAllStandardOutput(); m_rServer = new org::kde::Cantor::R(QString::fromLatin1("org.kde.Cantor.R-%1").arg(m_process->pid()), QLatin1String("/"), QDBusConnection::sessionBus(), this); - connect(m_rServer, SIGNAL(statusChanged(int)), this, SLOT(serverChangedStatus(int))); + connect(m_rServer, SIGNAL(statusChanged(int)), this, SLOT(serverChangedStatus(int)), Qt::QueuedConnection); + connect(m_rServer, SIGNAL(symbolList(QStringList,QStringList,QStringList)), variableModel(), SLOT(parseResult(QStringList,QStringList,QStringList))); changeStatus(Session::Done); emit loginDone(); qDebug()<<"login done"; } void RSession::logout() { qDebug()<<"logout"; m_process->terminate(); variableModel()->clearVariables(); variableModel()->clearFunctions(); emit symbolsChanged(); changeStatus(Status::Disable); } void RSession::interrupt() { if(!expressionQueue().isEmpty()) { qDebug()<<"interrupting " << expressionQueue().first()->command(); if(m_process->state() != QProcess::NotRunning) { #ifndef Q_OS_WIN const int pid=m_process->pid(); kill(pid, SIGINT); #else ; //TODO: interrupt the process on windows #endif } foreach (Cantor::Expression* expression, expressionQueue()) expression->setStatus(Cantor::Expression::Interrupted); expressionQueue().clear(); qDebug()<<"done interrupting"; } changeStatus(Cantor::Session::Done); } Cantor::Expression* RSession::evaluateExpression(const QString& cmd, Cantor::Expression::FinishingBehavior behave, bool internal) { qDebug()<<"evaluating: "<setFinishingBehavior(behave); expr->setCommand(cmd); expr->evaluate(); return expr; } Cantor::CompletionObject* RSession::completionFor(const QString& command, int index) { RCompletionObject *cmp=new RCompletionObject(command, index, this); connect(m_rServer,SIGNAL(completionFinished(QString,QStringList)),cmp,SLOT(receiveCompletions(QString,QStringList))); connect(cmp,SIGNAL(requestCompletion(QString)),m_rServer,SLOT(completeCommand(QString))); return cmp; } QSyntaxHighlighter* RSession::syntaxHighlighter(QObject* parent) { return new RHighlighter(parent, this); } void RSession::serverChangedStatus(int status) { qDebug()<<"changed status to "<command(); } finishFirstExpression(); } else changeStatus(Cantor::Session::Running); } void RSession::runFirstExpression() { if (expressionQueue().isEmpty()) return; disconnect(m_rServer, SIGNAL(expressionFinished(int,QString)), nullptr, nullptr); disconnect(m_rServer, SIGNAL(inputRequested(QString)), nullptr, nullptr); disconnect(m_rServer, SIGNAL(showFilesNeeded(QStringList)), nullptr, nullptr); qDebug()<<"size: "<(expressionQueue().first()); qDebug()<<"running expression: "<command(); connect(m_rServer, SIGNAL(expressionFinished(int,QString)), expr, SLOT(finished(int,QString))); connect(m_rServer, SIGNAL(inputRequested(QString)), expr, SIGNAL(needsAdditionalInformation(QString))); connect(m_rServer, SIGNAL(showFilesNeeded(QStringList)), expr, SLOT(showFilesAsResult(QStringList))); expr->setStatus(Cantor::Expression::Computing); m_rServer->runCommand(expr->command()); } void RSession::sendInputToServer(const QString& input) { QString s=input; if(!input.endsWith(QLatin1Char('\n'))) s+=QLatin1Char('\n'); m_rServer->answerRequest(s); } -void RSession::updateSymbols(const RVariableModel* model) +void RSession::updateSymbols() { - disconnect(m_rServer, SIGNAL(symbolList(QStringList,QStringList,QStringList))); - connect(m_rServer, SIGNAL(symbolList(QStringList,QStringList,QStringList)), model, SLOT(parseResult(QStringList,QStringList,QStringList))); m_rServer->listSymbols(); } diff --git a/src/backends/R/rsession.h b/src/backends/R/rsession.h index b8e46593..1ef38913 100644 --- a/src/backends/R/rsession.h +++ b/src/backends/R/rsession.h @@ -1,68 +1,68 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2009 Alexander Rieder */ #ifndef _RSESSION_H #define _RSESSION_H #include #include #include "session.h" #include "rserver_interface.h" class RExpression; class RVariableModel; class QProcess; namespace Cantor { class DefaultVariableModel; } class RSession : public Cantor::Session { Q_OBJECT public: explicit RSession( Cantor::Backend* backend); ~RSession() override; void login() override; void logout() override; void interrupt() override; 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; void runFirstExpression() override; void sendInputToServer(const QString& input); - void updateSymbols(const RVariableModel* model); + void updateSymbols(); protected Q_SLOTS: void serverChangedStatus(int status); Q_SIGNALS: void symbolsChanged(); private: QProcess* m_process; org::kde::Cantor::R* m_rServer; }; #endif /* _RSESSION_H */ diff --git a/src/backends/R/rvariablemodel.cpp b/src/backends/R/rvariablemodel.cpp index ce9fed44..d888d9e0 100644 --- a/src/backends/R/rvariablemodel.cpp +++ b/src/backends/R/rvariablemodel.cpp @@ -1,49 +1,49 @@ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. --- Copyright (C) 2018 Nikita Sirgienko */ #include "rvariablemodel.h" #include "rsession.h" using namespace Cantor; RVariableModel::RVariableModel(RSession* session): DefaultVariableModel(session) { } void RVariableModel::update() { - static_cast(session())->updateSymbols(this); + static_cast(session())->updateSymbols(); } void RVariableModel::parseResult(const QStringList& names, const QStringList& values, const QStringList& funcs) { QList vars; if (!values.isEmpty()) // Variables management disabled for (int i = 0; i < names.size(); i++) vars.append(Variable{names[i], values[i]}); else for (int i = 0; i < names.size(); i++) vars.append(Variable{names[i], QString()}); setVariables(vars); setFunctions(funcs); }