Commit 84b3c575 authored by Nikita Sirgienko's avatar Nikita Sirgienko

[Julia][GSoC 2020] Move julia hardcoded GR support to new GraphicPackage code

parent 286400db
Pipeline #25586 failed with stage
in 7 minutes and 43 seconds
......@@ -40,3 +40,5 @@ install(
FILES ${scripts}
DESTINATION ${KDE_INSTALL_DATADIR}/cantor/juliabackend/scripts
)
install(FILES graphic_packages.xml DESTINATION ${KDE_INSTALL_DATADIR}/cantor/julia)
<GraphicPackages>
<GraphicPackage>
<Id>gr</Id>
<Name>Julia integrated</Name>
<TestPresenceCommand>
try
import GR
println("1")
catch e
println("0")
end
</TestPresenceCommand>
<EnableCommand>
if (haskey(ENV, "GKS_WSTYPE"))
__cantor_gr_gks_previous__ = ENV["GKS_WSTYPE"]
__cantor_gr_gks_need_restore__ = true
else
__cantor_gr_gks_need_restore__ = false
end
ENV["GKS_WSTYPE"] = "nul"
ENV["GKSwstype"] = ""
GR.emergencyclosegks()
</EnableCommand>
<DisableCommand>
if (__cantor_gr_gks_need_restore__)
ENV["GKS_WSTYPE"] = __cantor_gr_gks_previous__
else
delete!(ENV, "GKS_WSTYPE")
end
ENV["GKSwstype"] = ""
GR.emergencyclosegks()
</DisableCommand>
<ToFileCommandTemplate>
GR.savefig("%1%2.%3")
</ToFileCommandTemplate>
<PlotPrecenseKeywords>
contour
contourf
grid
grid3d
histogram
imshow
plot
plot3
polar
polyline
polyline3d
polymarker
polymarker3d
scatter
scatter3
show
surface
</PlotPrecenseKeywords>
</GraphicPackage>
</GraphicPackages>
......@@ -58,7 +58,7 @@ Cantor::Session *JuliaBackend::createSession()
Cantor::Backend::Capabilities JuliaBackend::capabilities() const
{
Cantor::Backend::Capabilities cap = SyntaxHighlighting | Completion;
Cantor::Backend::Capabilities cap = SyntaxHighlighting | Completion | IntegratedPlots;
if (JuliaSettings::variableManagement())
cap |= VariableManagement;
......
......@@ -49,7 +49,6 @@ void JuliaCompletionObject::fetchCompletions()
allCompletions << JuliaKeywords::instance()->keywords();
allCompletions << JuliaKeywords::instance()->variables();
allCompletions << JuliaKeywords::instance()->functions();
allCompletions << JuliaKeywords::instance()->plotShowingCommands();
setCompletions(allCompletions);
emit fetchingDone();
......
......@@ -28,6 +28,11 @@
#include "textresult.h"
#include "imageresult.h"
const QStringList JuliaExpression::plotExtensions({
QLatin1String("svg"),
QLatin1String("png")
});
JuliaExpression::JuliaExpression(Cantor::Session *session, bool internal)
: Cantor::Expression(session, internal)
{
......@@ -47,24 +52,28 @@ QString JuliaExpression::internalCommand()
// Plots integration
m_plot_filename.clear();
if (juliaSession->integratePlots() && checkPlotShowingCommands()) {
// Simply add plot saving command to the end of execution
QStringList inlinePlotFormats;
inlinePlotFormats << QLatin1String("svg");
inlinePlotFormats << QLatin1String("png");
auto inlinePlotFormat =
inlinePlotFormats[JuliaSettings::inlinePlotFormat()];
m_plot_filename = QDir::tempPath() +
QString::fromLatin1("/cantor-julia-export-%1.%2")
.arg(QUuid::createUuid().toString()).arg(inlinePlotFormat);
QString saveFigCommand =
QString::fromLatin1("\nGR.savefig(\"%1\")\n").arg(m_plot_filename);
cmd = cmd.append(saveFigCommand);
// Not sure about how this code will work with two graphic packages activated in the same time (they both will save to one file?)...
if (!session()->enabledGraphicPackages().isEmpty() && !isInternal())
{
QStringList cmdWords = cmd.split(QRegularExpression(QStringLiteral("\\b")), QString::SkipEmptyParts);
for (const Cantor::GraphicPackage& package : session()->enabledGraphicPackages())
{
for (const QString& plotCmd : package.plotCommandPrecentsKeywords())
if (cmdWords.contains(plotCmd))
{
if (package.isHavePlotCommand())
{
m_plot_filename = juliaSession->plotFilePrefixPath() + QString::number(id()) + QLatin1String(".") + plotExtensions[JuliaSettings::inlinePlotFormat()];
cmd.append(QLatin1String("\n"));
cmd.append(package.savePlotCommand(juliaSession->plotFilePrefixPath(), id(), plotExtensions[JuliaSettings::inlinePlotFormat()]));
}
break;
}
}
}
qDebug() << "expression internal command:" << cmd;
return cmd;
}
......@@ -92,14 +101,3 @@ void JuliaExpression::interrupt()
setStatus(Cantor::Expression::Interrupted);
}
bool JuliaExpression::checkPlotShowingCommands()
{
for (auto showingCommand :
JuliaKeywords::instance()->plotShowingCommands()) {
if (command().contains(showingCommand + QLatin1String("("))) {
return true;
}
}
return false;
}
......@@ -57,15 +57,10 @@ public:
*/
void finalize(const QString& output, const QString& error, bool wasException);
public:
static const QStringList plotExtensions;
private:
/// If not empty, it's a filename of plot image file expression is awaiting
/// to get
/// If not empty, it's a filename of plot image file expression is awaiting to get
QString m_plot_filename;
/**
* @return bool indicator if current expression contains command that
* shows plot
*/
bool checkPlotShowingCommands();
};
......@@ -32,7 +32,6 @@ JuliaHighlighter::JuliaHighlighter(QObject *parent, JuliaSession* session)
addKeywords(JuliaKeywords::instance()->keywords());
addVariables(JuliaKeywords::instance()->variables());
addFunctions(JuliaKeywords::instance()->functions());
addFunctions(JuliaKeywords::instance()->plotShowingCommands());
}
void JuliaHighlighter::highlightBlock(const QString &text)
......
......@@ -40,24 +40,6 @@ JuliaKeywords::JuliaKeywords()
m_variables << QLatin1String("NaN");
m_variables << QLatin1String("nothing");
m_variables << QLatin1String("true");
m_plotShowingCommands << QLatin1String("contour");
m_plotShowingCommands << QLatin1String("contourf");
m_plotShowingCommands << QLatin1String("grid");
m_plotShowingCommands << QLatin1String("grid3d");
m_plotShowingCommands << QLatin1String("histogram");
m_plotShowingCommands << QLatin1String("imshow");
m_plotShowingCommands << QLatin1String("plot");
m_plotShowingCommands << QLatin1String("plot3");
m_plotShowingCommands << QLatin1String("polar");
m_plotShowingCommands << QLatin1String("polyline");
m_plotShowingCommands << QLatin1String("polyline3d");
m_plotShowingCommands << QLatin1String("polymarker");
m_plotShowingCommands << QLatin1String("polymarker3d");
m_plotShowingCommands << QLatin1String("scatter");
m_plotShowingCommands << QLatin1String("scatter3");
m_plotShowingCommands << QLatin1String("show");
m_plotShowingCommands << QLatin1String("surface");
}
JuliaKeywords *JuliaKeywords::instance()
......
......@@ -39,14 +39,6 @@ public:
*/
const QStringList &keywords() const { return m_keywords; }
/**
* @return list of predefined commands, that are capable to show plot
*/
const QStringList &plotShowingCommands() const
{
return m_plotShowingCommands;
}
/**
* @return list of known variable names
*/
......@@ -93,7 +85,6 @@ public:
private:
QStringList m_keywords; //< list of predefined keywords
QStringList m_plotShowingCommands; //< list of predefined plot showing cmds
QStringList m_variables; //< list of variables known at the moment
QStringList m_removedVariables; //< list of variables removed during cleaning
QStringList m_functions; //< list of known function at the moment
......
......@@ -19,12 +19,15 @@
*/
#include "juliasession.h"
#include <random>
#include <KProcess>
#include <KLocalizedString>
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusReply>
#include <QStandardPaths>
#include <QDir>
#include "defaultvariablemodel.h"
......@@ -43,6 +46,8 @@ JuliaSession::JuliaSession(Cantor::Backend *backend)
: Session(backend)
, m_process(nullptr)
, m_interface(nullptr)
, m_isIntegratedPlotsEnabled(false)
, m_isIntegratedPlotsSettingsEnabled(false)
{
setVariableModel(new JuliaVariableModel(this));
}
......@@ -113,13 +118,18 @@ void JuliaSession::login()
static_cast<JuliaVariableModel*>(variableModel())->setJuliaServer(m_interface);
// Plots integration
if (integratePlots()) {
runJuliaCommand(
QLatin1String("import GR; ENV[\"GKS_WSTYPE\"] = \"nul\"")
);
updateVariables();
}
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<int> rand_dist(0, 999999999);
m_plotFilePrefixPath =
QDir::tempPath()
+ QLatin1String("/cantor_octave_")
+ QString::number(m_process->pid())
+ QLatin1String("_")
+ QString::number(rand_dist(mt))
+ QLatin1String("_");
updateVariables();
changeStatus(Session::Done);
emit loginDone();
......@@ -143,6 +153,21 @@ void JuliaSession::logout()
interrupt();
}
if (!m_plotFilePrefixPath.isEmpty())
{
int i = 0;
const QString& extension = JuliaExpression::plotExtensions[JuliaSettings::inlinePlotFormat()];
QString filename = m_plotFilePrefixPath + QString::number(i) + QLatin1String(".") + extension;
while (QFile::exists(filename))
{
QFile::remove(filename);
i++;
filename = m_plotFilePrefixPath + QString::number(i) + QLatin1String(".") + extension;
}
}
m_isIntegratedPlotsEnabled = false;
m_isIntegratedPlotsSettingsEnabled = false;
Session::logout();
}
......@@ -170,6 +195,9 @@ Cantor::Expression *JuliaSession::evaluateExpression(
Cantor::Expression::FinishingBehavior behave,
bool internal)
{
if (!internal)
updateGraphicPackagesFromSettings();
JuliaExpression *expr = new JuliaExpression(this, internal);
expr->setFinishingBehavior(behave);
......@@ -265,9 +293,46 @@ bool JuliaSession::getWasException()
}
bool JuliaSession::integratePlots()
QString JuliaSession::plotFilePrefixPath() const
{
return m_plotFilePrefixPath;
}
void JuliaSession::updateGraphicPackagesFromSettings()
{
if (m_isIntegratedPlotsSettingsEnabled == JuliaSettings::integratePlots())
return;
if (m_isIntegratedPlotsEnabled && JuliaSettings::integratePlots() == false)
{
updateEnabledGraphicPackages(QList<Cantor::GraphicPackage>());
m_isIntegratedPlotsEnabled = false;
m_isIntegratedPlotsSettingsEnabled = JuliaSettings::integratePlots();
return;
}
else if (!m_isIntegratedPlotsEnabled && JuliaSettings::integratePlots() == true)
{
m_isIntegratedPlotsEnabled = true;
m_isIntegratedPlotsSettingsEnabled = true;
updateEnabledGraphicPackages(backend()->availableGraphicPackages());
}
}
QString JuliaSession::graphicPackageErrorMessage(QString packageId) const
{
return JuliaSettings::integratePlots();
QString text;
if (packageId == QLatin1String("gr")) {
return i18n(
"On this moment, integrated graphic can handle only one of Julia packages - GR graphic package. "
"And for using this feature you need to install the package first. "
"For this, run Pkg.install(\"GR\") in Cantor or in julia REPL. Also, it is important "
"to note, that this is a long operation and better use julia REPL, because Cantor don't "
"show intermediate text unlike the julia."
);
}
return text;
}
......@@ -86,10 +86,7 @@ public:
*/
QSyntaxHighlighter *syntaxHighlighter(QObject *parent) override;
/**
* @return indicator if config says to integrate plots into worksheet
*/
bool integratePlots();
QString plotFilePrefixPath() const;
private Q_SLOTS:
/**
......@@ -107,6 +104,11 @@ private:
/// Cache to speedup modules whos calls
QMap<QString, QString> m_whos_cache;
/// Variables for handling plot integration: settings value and real state
QString m_plotFilePrefixPath;
bool m_isIntegratedPlotsEnabled;
bool m_isIntegratedPlotsSettingsEnabled;
void runFirstExpression() override;
/**
......@@ -146,4 +148,8 @@ private:
* @return indicator of exception occurred during the last command execution
*/
bool getWasException();
void updateGraphicPackagesFromSettings();
QString graphicPackageErrorMessage(QString packageId) const override;
};
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