File indexing completed on 2023-10-01 07:35:55
0001 /* 0002 SPDX-License-Identifier: GPL-2.0-or-later 0003 SPDX-FileCopyrightText: 2009 Alexander Rieder <alexanderrieder@gmail.com> 0004 SPDX-FileCopyrightText: 2018-2022 Alexander Semke <alexander.semke@web.de> 0005 */ 0006 0007 #include "rexpression.h" 0008 0009 #include "textresult.h" 0010 #include "imageresult.h" 0011 #include "helpresult.h" 0012 #include "epsresult.h" 0013 #include "rsession.h" 0014 0015 #include <QDebug> 0016 #include <KLocalizedString> 0017 #include <QMimeType> 0018 #include <QMimeDatabase> 0019 #include <QFile> 0020 0021 RExpression::RExpression( Cantor::Session* session, bool internal ) : Cantor::Expression(session, internal) 0022 { 0023 0024 } 0025 0026 void RExpression::evaluate() 0027 { 0028 const auto& cmd = command(); 0029 0030 //check whether we need to interpret the current command as a help command. 0031 //see https://www.r-project.org/help.html for the list of different ways to get help in R. 0032 if(cmd.startsWith(QLatin1Char('?')) || cmd.startsWith(QStringLiteral("help(")) 0033 || cmd.startsWith(QStringLiteral("apropos(")) 0034 || cmd.startsWith(QStringLiteral("vignette(")) 0035 || cmd == QStringLiteral("demos()") 0036 || cmd.startsWith(QStringLiteral("help.search(")) ) 0037 setIsHelpRequest(true); 0038 0039 session()->enqueueExpression(this); 0040 } 0041 0042 void RExpression::interrupt() 0043 { 0044 qDebug()<<"interrupting command"; 0045 setStatus(Cantor::Expression::Interrupted); 0046 } 0047 0048 void RExpression::parseOutput(const QString& text) 0049 { 0050 //qDebug() << "output text: " << text; 0051 if (!text.trimmed().isEmpty()) 0052 { 0053 if(isHelpRequest()) 0054 addResult(new Cantor::HelpResult(text)); 0055 else 0056 addResult(new Cantor::TextResult(text)); 0057 } 0058 setStatus(Cantor::Expression::Done); 0059 } 0060 0061 void RExpression::parseError(const QString& text) 0062 { 0063 qDebug() << "error text: " << text; 0064 setErrorMessage(text); 0065 setStatus(Cantor::Expression::Error); 0066 } 0067 0068 void RExpression::addInformation(const QString& information) 0069 { 0070 static_cast<RSession*>(session())->sendInputToServer(information); 0071 } 0072 0073 void RExpression::showFilesAsResult(const QStringList& files) 0074 { 0075 qDebug()<<"showing files: "<<files; 0076 for (const QString& file : files) 0077 { 0078 QMimeDatabase db; 0079 auto type = db.mimeTypeForUrl(QUrl(file)); 0080 qDebug()<<"MimeType: "<<type.name(); 0081 if(type.inherits(QLatin1String("application/postscript"))) 0082 { 0083 qDebug()<<"it's PostScript"; 0084 setResult(new Cantor::EpsResult(QUrl::fromLocalFile(file))); 0085 } 0086 else if (type.name().contains(QLatin1String("image"))) 0087 { 0088 setResult(new Cantor::ImageResult(QUrl::fromLocalFile(file))); 0089 setStatus(Cantor::Expression::Done); 0090 } 0091 else if(type.inherits(QLatin1String("text/plain")) 0092 || type.inherits(QLatin1String("application/x-extension-html")) 0093 ||type.inherits(QLatin1String("application/octet-stream")) ) 0094 { 0095 //Htmls are also plain texts, combining this in one 0096 const bool isHtml = type.inherits(QLatin1String("text/html")) 0097 || type.inherits(QLatin1String("application/x-extension-html")) 0098 || type.inherits(QLatin1String("application/octet-stream")); 0099 if(isHtml) 0100 qDebug()<<"it's a HTML document"; 0101 else 0102 qDebug()<<"it's a plain text"; 0103 0104 QFile f(file); 0105 if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) 0106 { 0107 setResult(new Cantor::TextResult(i18n("Error opening file %1", file))); 0108 setErrorMessage(i18n("Error opening file %1", file)); 0109 setStatus(Cantor::Expression::Error); 0110 } 0111 QString content=QTextStream(&f).readAll(); 0112 if (!isHtml) 0113 { 0114 //Escape whitespace 0115 content.replace( QLatin1Char(' '), QLatin1String(" ")); 0116 //replace appearing backspaces, as they mess the whole output up 0117 content.remove(QRegExp(QLatin1String(".\b"))); 0118 } 0119 else 0120 content.remove(QLatin1String("_\b")); 0121 0122 qDebug()<<"content: "<<content; 0123 if(isHelpRequest()) 0124 setResult(new Cantor::HelpResult(content)); 0125 else 0126 setResult(new Cantor::TextResult(content)); 0127 setStatus(Cantor::Expression::Done); 0128 } 0129 else 0130 { 0131 // File has unsupported mime type, but we suspect, that it is text, so we open the file in the script editor 0132 // Even if it's not text, the script editor can deal with it. 0133 setStatus(Cantor::Expression::Done); 0134 const QString& editor = QStandardPaths::findExecutable(QLatin1String("cantor_scripteditor")); 0135 int code = QProcess::execute(editor, QStringList(file)); 0136 if (code == -2) 0137 qDebug() << "failed to open the file " << file << " with the script editor '" << editor << "'"; 0138 else if (code == -1) 0139 qDebug() << "Cantor script editor crashed"; 0140 } 0141 } 0142 }