diff --git a/src/backends/python/pythonexpression.h b/src/backends/python/pythonexpression.h --- a/src/backends/python/pythonexpression.h +++ b/src/backends/python/pythonexpression.h @@ -22,27 +22,24 @@ #define _PYTHONEXPRESSION_H #include "expression.h" -#include -class QTimer; +class QTemporaryFile; class PythonExpression : public Cantor::Expression { Q_OBJECT public: PythonExpression(Cantor::Session* session, bool internal); - ~PythonExpression() override = default; + ~PythonExpression() override; void evaluate() override; void interrupt() override; void parseOutput(QString output); void parseError(QString error); - void parsePlotFile(const QString& filename); - void setPlotPending(bool plot); private: - bool m_finished; - bool m_plotPending; + void imageChanged(); + QTemporaryFile* m_tempFile; }; #endif /* _PYTHONEXPRESSION_H */ diff --git a/src/backends/python/pythonexpression.cpp b/src/backends/python/pythonexpression.cpp --- a/src/backends/python/pythonexpression.cpp +++ b/src/backends/python/pythonexpression.cpp @@ -32,30 +32,37 @@ #include "settings.h" #include -using PythonPlotResult = Cantor::ImageResult; +#include +#include -PythonExpression::PythonExpression(Cantor::Session* session, bool internal) : Cantor::Expression(session, internal) +PythonExpression::PythonExpression(Cantor::Session* session, bool internal) : Cantor::Expression(session, internal), + m_tempFile(nullptr) { - qDebug() << "PythonExpression constructor"; +} + +PythonExpression::~PythonExpression() { + if(m_tempFile) + delete m_tempFile; } void PythonExpression::evaluate() { - setStatus(Cantor::Expression::Computing); - - PythonSession* pythonSession = dynamic_cast(session()); - - qDebug() << pythonSession->integratePlots() << command().contains(QLatin1String("show()")); + if(m_tempFile) { + delete m_tempFile; + m_tempFile = nullptr; + } + PythonSession* pythonSession = dynamic_cast(session()); if((pythonSession->integratePlots()) && (command().contains(QLatin1String("show()")))){ + m_tempFile = new QTemporaryFile(QDir::tempPath() + QLatin1String("/cantor_python-XXXXXX.png")); + m_tempFile->open(); + QString saveFigCommand = QLatin1String("savefig('%1')"); + setCommand(command().replace(QLatin1String("show()"), saveFigCommand.arg(m_tempFile->fileName()))); - qDebug() << "Preparing export figures property"; - - QString saveFigCommand = QLatin1String("savefig('cantor-export-python-figure-%1.png')"); - - setCommand(command().replace(QLatin1String("show()"), saveFigCommand.arg(qrand()))); - - qDebug() << "New Command " << command(); + QFileSystemWatcher* watcher = fileWatcher(); + watcher->removePaths(watcher->files()); + watcher->addPath(m_tempFile->fileName()); + connect(watcher, &QFileSystemWatcher::fileChanged, this, &PythonExpression::imageChanged, Qt::UniqueConnection); } @@ -84,30 +91,14 @@ setStatus(Cantor::Expression::Error); } -void PythonExpression::parsePlotFile(const QString& filename) +void PythonExpression::imageChanged() { - qDebug() << "parsePlotFile"; - - qDebug() << "PythonExpression::parsePlotFile: " << filename; - - setResult(new PythonPlotResult(QUrl::fromLocalFile(filename))); - - setPlotPending(false); - - if (m_finished) - { - qDebug() << "PythonExpression::parsePlotFile: done"; - setStatus(Done); - } + addResult(new Cantor::ImageResult(QUrl::fromLocalFile(m_tempFile->fileName()))); + setStatus(Done); } void PythonExpression::interrupt() { qDebug()<<"interruptinging command"; setStatus(Cantor::Expression::Interrupted); } - -void PythonExpression::setPlotPending(bool plot) -{ - m_plotPending = plot; -} diff --git a/src/backends/python/pythonsession.h b/src/backends/python/pythonsession.h --- a/src/backends/python/pythonsession.h +++ b/src/backends/python/pythonsession.h @@ -58,8 +58,6 @@ virtual QStringList autorunScripts() const = 0; private: - KDirWatch* m_watch; - QStringList m_listPlotName; Cantor::DefaultVariableModel* m_variableModel; QList m_runningExpressions; @@ -96,7 +94,6 @@ private Q_SLOTS: void readOutput(const QString& commandProcessing); - void plotFileChanged(const QString& filename); void expressionFinished(); Q_SIGNALS: diff --git a/src/backends/python/pythonsession.cpp b/src/backends/python/pythonsession.cpp --- a/src/backends/python/pythonsession.cpp +++ b/src/backends/python/pythonsession.cpp @@ -101,30 +101,6 @@ m_pIface->call(QString::fromLatin1("login")); m_pIface->call(QString::fromLatin1("setFilePath"), worksheetPath); - if(integratePlots()) - { - qDebug() << "integratePlots"; - - QString tempPath = QDir::tempPath(); - - QString pathOperations = tempPath; - pathOperations.prepend(QLatin1String("import os\nos.chdir('")); - pathOperations.append(QLatin1String("')\n")); - - qDebug() << "Processing command to change chdir in Python. Command " << pathOperations.toLocal8Bit(); - - getPythonCommandOutput(pathOperations); - - m_watch = new KDirWatch(this); - m_watch->setObjectName(QLatin1String("PythonDirWatch")); - - m_watch->addDir(tempPath, KDirWatch::WatchFiles); - - qDebug() << "addDir " << tempPath << "? " << m_watch->contains(QLatin1String(tempPath.toLocal8Bit())); - - QObject::connect(m_watch, SIGNAL(created(QString)), SLOT(plotFileChanged(QString))); - } - const QStringList& scripts = autorunScripts(); if(!scripts.isEmpty()){ QString autorunScripts = scripts.join(QLatin1String("\n")); @@ -147,14 +123,6 @@ m_pProcess->terminate(); qDebug()<<"logout"; - - QDir removePlotFigures; - QListIterator i(m_listPlotName); - - while(i.hasNext()){ - removePlotFigures.remove(QLatin1String(i.next().toLocal8Bit().constData())); - } - changeStatus(Status::Disable); } @@ -229,8 +197,6 @@ void PythonSession::getPythonCommandOutput(const QString& commandProcessing) { - qDebug() << "Running python command" << commandProcessing; - runPythonCommand(commandProcessing); m_output = getOutput(); @@ -361,19 +327,6 @@ updateOutput(); } -void PythonSession::plotFileChanged(const QString& filename) -{ - qDebug() << "plotFileChanged filename:" << filename; - - if ((m_currentExpression) && (filename.contains(QLatin1String("cantor-export-python-figure")))) - { - qDebug() << "Calling parsePlotFile"; - m_currentExpression->parsePlotFile(filename); - - m_listPlotName.append(filename); - } -} - void PythonSession::listVariables() { const QString& listVariableCommand = QLatin1String( diff --git a/src/lib/expression.h b/src/lib/expression.h --- a/src/lib/expression.h +++ b/src/lib/expression.h @@ -26,6 +26,7 @@ #include +class QFileSystemWatcher; class KZip; /** @@ -245,10 +246,12 @@ void replaceResult(int index, Result* result); - protected: //returns a string of latex commands, that is inserted into the header. //used for example if special packages are needed virtual QString additionalLatexHeaders(); + + QFileSystemWatcher* fileWatcher(); + private: void renderResultAsLatex(Result* result); void latexRendered(LatexRenderer* renderer, Result* result); diff --git a/src/lib/expression.cpp b/src/lib/expression.cpp --- a/src/lib/expression.cpp +++ b/src/lib/expression.cpp @@ -31,18 +31,19 @@ #include "latexresult.h" #include "settings.h" +#include #include #include +#include #include -#include #include class Cantor::ExpressionPrivate { public: ExpressionPrivate() : status(Expression::Done), session(nullptr), - finishingBehavior(Expression::DoNotDelete), internal(false) + finishingBehavior(Expression::DoNotDelete), internal(false), fileWatcher(nullptr) { } @@ -55,6 +56,7 @@ Session* session; Expression::FinishingBehavior finishingBehavior; bool internal; + QFileSystemWatcher* fileWatcher; }; static const QString tex=QLatin1String("\\documentclass[12pt,fleqn]{article} \n "\ @@ -83,6 +85,9 @@ Expression::~Expression() { qDeleteAll(d->results); + if (d->fileWatcher) + delete d->fileWatcher; + delete d; } @@ -239,6 +244,13 @@ return QString(); } +QFileSystemWatcher* Expression::fileWatcher() { + if (!d->fileWatcher) + d->fileWatcher = new QFileSystemWatcher(); + + return d->fileWatcher; +} + int Expression::id() { return d->id;