File indexing completed on 2024-05-05 11:56:04

0001 /*
0002     SPDX-License-Identifier: GPL-2.0-or-later
0003     SPDX-FileCopyrightText: 2009 Alexander Rieder <alexanderrieder@gmail.com>
0004         SPDX-FileCopyrightText: 2018-2022 by Alexander Semke (alexander.semke@web.de)
0005 */
0006 
0007 #ifndef _EXPRESSION_H
0008 #define _EXPRESSION_H
0009 
0010 #include <QObject>
0011 #include <QDomElement>
0012 
0013 #include "cantor_export.h"
0014 
0015 class QFileSystemWatcher;
0016 class KZip;
0017 
0018 /**
0019  * Namespace collecting all Classes of the Cantor Libraries
0020  */
0021 namespace Cantor
0022 {
0023 class Session;
0024 class Result;
0025 class LatexRenderer;
0026 class ExpressionPrivate;
0027 
0028 /**
0029  * An Expression object is used, to store the information needed when running a command of a Session
0030  * Evaluation of Expression is an asynchronous process in most cases, so most of the members
0031  * of this class are not useful directly after its construction. Therefore there are signals
0032  * indicating, when the Expression goes through the different stages of the Running process.
0033  * An Expression is never constructed directly, but by using Session::evaluateExpression()
0034  *
0035  * @author Alexander Rieder
0036  */
0037 class CANTOR_EXPORT Expression : public QObject
0038 {
0039   Q_OBJECT
0040   public:
0041     enum Status {
0042         Queued,      ///< The Expression is in expression queue, waited for Computing
0043         Computing,   ///< The Expression is still being computed
0044         Done,        ///< The Running of the Expression is finished successfully
0045         Error,       ///< An Error occurred when running the Expression
0046         Interrupted  ///< The Expression was interrupted by the user while running
0047     };
0048 
0049     /**
0050      * Enum indicating how this Expression behaves on finishing
0051      */
0052     enum FinishingBehavior {
0053         DoNotDelete,     ///< This Expression will not be deleted. This is the normal behaviour
0054         DeleteOnFinish   /** < The Object will delete itself when finished. This is used for fire-and-forget commands.
0055                           * All output/results will be dropped
0056                           */
0057     };
0058     /**
0059      * Expression constructor. Should only be called from Session::evaluateExpression
0060      * @param session the session, this Expression belongs to
0061      * @param internal \c true if this expression is internal expression
0062      */
0063     explicit Expression(Session*, bool internal = false);
0064     /**
0065      * destructor
0066      */
0067     ~Expression() override;
0068 
0069     /**
0070      * Evaluate the Expression. before this is called, you should set the Command first
0071      * This method can be implemented asynchronous, thus the Evaluation doesn't need to happen in the method,
0072      * It can also only be scheduled for evaluating.
0073      * @see setCommand()
0074      */
0075     virtual void evaluate() = 0;
0076     /**
0077      * Interrupt the running of the Expression.
0078      * This should set the state to Interrupted.
0079      */
0080     virtual void interrupt();
0081 
0082     virtual void parseOutput(const QString&) = 0;
0083     virtual void parseError(const QString&) = 0;
0084 
0085     /**
0086      * Returns the unique id of the Expression
0087      * or -1 for internal expressions
0088      * @return the unique id of the Expression
0089      */
0090     int id();
0091 
0092     /**
0093      * set the id of the Expression. It should be unique
0094      * @param id the new Id
0095      */
0096     void setId(int id);
0097 
0098     /**
0099      * set the finishing behaviour
0100      * @param behavior the new Finishing Behaviour
0101      */
0102     void setFinishingBehavior(FinishingBehavior);
0103 
0104     /**
0105      * get the Expressions finishing behaviour
0106      * @return the current finishing behaviour
0107      */
0108     FinishingBehavior finishingBehavior();
0109 
0110     /**
0111      * Sets the command, represented by this Expression
0112      * @param cmd the command
0113      */
0114     void setCommand(const QString&);
0115 
0116     /**
0117      * Returns the command, represented by this Expression
0118      * @return the command, represented by this Expression
0119      */
0120     QString command();
0121 
0122     /**
0123      * Returns the command, adapted for using by appropriate Backend
0124      * The return value can be equal or not to @ref command()
0125      * Backend should use this function, instead of @ref command()
0126      */
0127     virtual QString internalCommand();
0128 
0129     /**
0130      * Adds some additional information/input to this expression.
0131      * this is needed, when the Expression has emitted the needsAdditionalInformation signal,
0132      * and the user has answered the question. This is used for e.g. if maxima asks whether
0133      * n+1 is zero or not when running the command "integrate(x^n,x)"
0134      * This method is part of the InteractiveMode feature
0135      */
0136     virtual void addInformation(const QString&);
0137 
0138     /**
0139      * Sets the error message
0140      * @param cmd the error message
0141      * @see errorMessage()
0142      */
0143     void setErrorMessage(const QString&);
0144 
0145     /**
0146      * returns the Error message, if an error occurred during
0147      * the evaluation of the expression.
0148      * @return the error message
0149      */
0150     QString errorMessage();
0151 
0152     /**
0153      * The result of this Expression. It can have different types, represented by various
0154      * subclasses of Result, like text, image, etc.
0155      * The result will be null, until the computation is completed.
0156      * When the result changes, the gotResult() signal is emitted.
0157      * The Result object is owned by the Expression, and will get deleted, as
0158      * soon as the Expression dies, or newer results appear.
0159      * @return the result of the Expression, 0 if it isn't yet set
0160      */
0161     Result* result();
0162 
0163     /*!
0164      * in case the expression has multiple outputs/results, those can be obtained with this functions.
0165      * Everything else said for \sa result() applies here too.
0166      * @return the vector with results, or an empty vector if nor results are available yet.
0167      */
0168     const QVector<Result*>& results() const;
0169 
0170     /**
0171      * Deletes the result of this expression.
0172      *
0173      */
0174     void removeResult(Result* result);
0175 
0176     /**
0177      * Deletes the all results of this expression.
0178      *
0179      */
0180     void clearResults();
0181 
0182     /**
0183      * Returns the status of this Expression
0184      * @return the status of this Expression
0185      */
0186     Status status();
0187 
0188     /**
0189      * Set the status
0190      * statusChanged will be emitted
0191      * @param status the new status
0192      */
0193     void setStatus(Status);
0194 
0195     /**
0196      * Returns the Session, this Expression belongs to
0197      */
0198     Session* session();
0199 
0200     /**
0201      * returns whether or not this expression is internal, or
0202      * comes from the user
0203      */
0204     bool isInternal() const;
0205 
0206     /**
0207      * Sets whether the expression is a help request (available for Maxima and R) where
0208      * additional information/help can be requested and shown.
0209      * Used internally to controll whether the update of the variable model needs to be done.
0210      */
0211     void setIsHelpRequest(bool);
0212     bool isHelpRequest() const;
0213 
0214   Q_SIGNALS:
0215     /**
0216      * the Id of this Expression changed
0217      */
0218     void idChanged();
0219     /**
0220      * A Result of the Expression has arrived
0221      */
0222     void gotResult();
0223     /**
0224      * emitted when the results of the expression were deleted.
0225      * @see clearResults()
0226      */
0227     void resultsCleared();
0228     /**
0229      * emitted when the results of the expression were deleted.
0230      * @see clearResult(Result* result)
0231      */
0232     void resultRemoved(int index);
0233     /**
0234      * emitted when the result at the position @c index was replaced by a new result.
0235      */
0236     void resultReplaced(int index);
0237     /**
0238      * the status of the Expression has changed.
0239      * @param status the new status
0240      */
0241     void statusChanged(Cantor::Expression::Status);
0242 
0243     /**
0244      * the status of the Expression has changed to Done, Error or Interrupt
0245      */
0246     void expressionFinished(Cantor::Expression::Status);
0247 
0248     /**
0249      * the Expression needs more information for the evaluation
0250      * @see addInformation()
0251      * @param question question, the user needs to answer
0252      */
0253     void needsAdditionalInformation(const QString& question);
0254 
0255   //These are protected, because only subclasses will handle results/status changes
0256   protected:
0257     // Protected constructor, useful for derived classes with own id setting strategy
0258     Expression(Session* session, bool internal, int id);
0259 
0260     /**
0261      * Set the result of the Expression.
0262      * this will cause gotResult() to be emitted
0263      * The old result will be deleted, and the Expression
0264      * takes over ownership of the result object, taking
0265      * care of deleting it.
0266      * @param result the new result
0267      */
0268     void setResult(Result*);
0269     void addResult(Result*);
0270     void replaceResult(int index, Result*);
0271 
0272     //returns a string of latex commands, that is inserted into the header.
0273     //used for example if special packages are needed
0274     virtual QString additionalLatexHeaders();
0275 
0276     QFileSystemWatcher* fileWatcher();
0277 
0278   private:
0279     void renderResultAsLatex(Result*);
0280     void latexRendered(LatexRenderer*, Result*);
0281 
0282   private:
0283     ExpressionPrivate* d;
0284 };
0285 
0286 }
0287 #endif /* _EXPRESSION_H */