1 #ifndef Header_Build_Manager
2 #define Header_Build_Manager
3
4 #include "mostQtHeaders.h"
5
6 class ProcessX;
7
8 struct PreviewSource {
9 QString text;
10 int fromLine, toLine;
11 bool atCursor;
PreviewSourcePreviewSource12 PreviewSource(): fromLine(0), toLine(0), atCursor(false) {}
PreviewSourcePreviewSource13 PreviewSource(const QString &text, int fromLine, int toLine, bool atCursor):
14 text(text), fromLine(fromLine), toLine(toLine), atCursor(atCursor) {}
15 };
16
17 enum LatexCompileResult {
18 LCR_NORMAL = 0,
19 LCR_ERROR,
20 LCR_RERUN,
21 LCR_RERUN_WITH_BIBLIOGRAPHY
22 };
23 Q_DECLARE_METATYPE(LatexCompileResult)
24
25
26 enum RunCommandFlag {
27 RCF_SHOW_STDOUT = 1, //bibliography command (=> show stdout)
28 RCF_COMPILES_TEX = 4, //latex command, show the log
29 RCF_RERUNNABLE = 8, // set if the command provides output information that
30 // tells you when it must be rerun. Usually RCF_RERUNNABLE
31 // is set iff RCF_COMPILES_TEX is set, except for latexmk.
32 RCF_RERUN = 16, // User has allowed program rerun through the command settings
33 RCF_CHANGE_PDF = 32, //pdflatex (=> lock pdf)
34 RCF_SINGLE_INSTANCE = 64,//viewer (=> start only once)
35 RCF_WAITFORFINISHED = 128
36 };
37 Q_DECLARE_FLAGS(RunCommandFlags, RunCommandFlag)
38
39 struct CommandToRun {
40 QString command;
41 QString parentCommand;
42 RunCommandFlags flags;
43 CommandToRun();
44 CommandToRun(const QString &cmd);
45 };
46
47 struct ExpandedCommands {
48 QString primaryCommand;
49 QList<CommandToRun> commands;
50 };
51
52 typedef QString (*GuessCommandLineFunc) ();
53 struct CommandInfo {
54 CommandInfo();
55 QString id;
56 QString commandLine;
57
58 QString defaultArgs;
59 QString displayName;
60 bool user;
61 bool meta;
62 bool rerunCompiler;
63
64 QStringList metaSuggestionList;
65 QStringList simpleDescriptionList;
66
67 QString guessCommandLine(const QString texpath="") const;
68 //sets a command (accepts tr("<unknown>"))
69 void setCommandLine(const QString &newCmd);
70
71 QString getPrettyCommand() const;
getBaseNameCommandInfo72 QString getBaseName() const { return baseName; }
73 QString getProgramName() const;
74 QString getProgramNameUnquoted() const;
75 private:
76 friend class BuildManager;
77 QString baseName;
78 GuessCommandLineFunc guessFunc;
79 QString deprecatedConfigName;
80 public:
81 static QString getProgramName(const QString &commandLine);
82 static QString getProgramNameUnquoted(const QString &commandLine);
83 };
84
85 struct ExpandingOptions {
86 ExpandingOptions(const QFileInfo &mainFile, const QFileInfo ¤tFile = QFileInfo(), const int currentLine = 0);
87 const QFileInfo mainFile;
88 const QFileInfo currentFile;
89 const int currentLine;
90 int nestingDeep;
91 bool canceled;
92 struct ParameterOverride {
93 QList<QPair<QString, QString> > replace;
94 QStringList append;
95 QStringList remove;
96 bool removeAll;
97 };
98 ParameterOverride override;
99 };
100
101 typedef QHash<QString, CommandInfo> CommandMapping;
102
103 class ConfigManagerInterface;
104
105 class BuildManager: public QObject
106 {
107 Q_OBJECT
108
109 public:
110 BuildManager();
111 ~BuildManager();
112
113 static const QString TXS_CMD_PREFIX;
114 static const QString CMD_LATEX, CMD_PDFLATEX, CMD_XELATEX, CMD_LUALATEX, CMD_LATEXMK;
115 static const QString CMD_VIEW_DVI, CMD_VIEW_PS, CMD_VIEW_PDF, CMD_VIEW_LOG;
116 static const QString CMD_DVIPNG, CMD_DVIPS, CMD_DVIPDF, CMD_PS2PDF, CMD_GS, CMD_MAKEINDEX, CMD_TEXINDY, CMD_MAKEGLOSSARIES, CMD_METAPOST, CMD_ASY, CMD_BIBTEX, CMD_BIBTEX8, CMD_BIBER, CMD_SVN, CMD_SVNADMIN, CMD_GIT, CMD_TEXDOC;
117 static const QString CMD_COMPILE, CMD_VIEW, CMD_BIBLIOGRAPHY, CMD_INDEX, CMD_GLOSSARY, CMD_QUICK, CMD_RECOMPILE_BIBLIOGRAPHY;
118 static const QString CMD_VIEW_PDF_INTERNAL, CMD_INTERNAL_PRE_COMPILE, CMD_CONDITIONALLY_RECOMPILE_BIBLIOGRAPHY, CMD_TERMINAL_EXTERNAL;
119
120 static QString chainCommands(const QString &a);
121 static QString chainCommands(const QString &a, const QString &b);
122 static QString chainCommands(const QString &a, const QString &b, const QString &c);
123 static QString chainCommands(const QString &a, const QString &b, const QString &c, const QString &d);
124
125 static QStringList splitOptions(const QString &s);
126 static QString findFileInPath(QString fileName);
127 static QString replaceEnvironmentVariables(const QString &s);
128 static QString replaceEnvironmentVariables(const QString &s, const QHash<QString, QString> &variables, bool compareNamesToUpper);
129 static QString resolvePaths(QString paths);
130 static QStringList parseExtendedCommandLine(QString str, const QFileInfo &mainFile, const QFileInfo ¤tFile = QFileInfo(), int currentLine = 0);
131 static QFileInfo parseExtendedSelectFile(QString &command, const QFileInfo &mainFile, const QFileInfo ¤tFile);
132 static QString extractOutputRedirection(const QString &commandLine, QString &stdOut, QString &stdErr);
133 ExpandedCommands expandCommandLine(const QString &str, ExpandingOptions &expandingOptions);
134 RunCommandFlags getSingleCommandFlags(const QString &command) const;
135 bool hasCommandLine(const QString &program);
136
137 void registerOptions(ConfigManagerInterface &cmi);
138 void readSettings(QSettings &settings);
139 void saveSettings(QSettings &settings);
140 void resetDefaultCommands(const QString texPath);
141
142 void checkLatexConfiguration(bool &noWarnAgain);
143
144
145 public slots:
146 bool runCommand(const QString &unparsedCommandLine, const QFileInfo &mainFile, const QFileInfo ¤tFile = QFileInfo(), int currentLine = 0, QString *buffer = nullptr, QTextCodec *codecForBuffer = nullptr, QString *errorMsg = nullptr);
147 Q_INVOKABLE void killCurrentProcess();
148 private:
149 bool checkExpandedCommands(const ExpandedCommands &expandedCommands);
150 bool runCommandInternal(const ExpandedCommands &expandedCommands, const QFileInfo &mainFile, QString *buffer = nullptr, QTextCodec *codecForBuffer = nullptr, QString *errorMsg = nullptr);
151 public:
152 //creates a process object with the given command line (after it is changed by an implcit call to parseExtendedCommandLine)
153 //ProcessX* newProcess(const QString &unparsedCommandLine, const QString &mainFile, const QString ¤tFile, int currentLine=0, bool singleInstance = false);
154 //QList<ProcessX*> newProcesses(const QString &unparsedCommandLine, const QString &mainFile, const QString ¤tFile, int currentLine=0, bool singleInstance = false);
155 Q_INVOKABLE ProcessX *firstProcessOfDirectExpansion(const QString &command, const QFileInfo &mainfile, const QFileInfo ¤tFile = QFileInfo(), int currentLine = 0, bool nonstop=false);
156
157 Q_INVOKABLE ProcessX *newProcessInternal(const QString &fullCommandLine, const QFileInfo &mainFile, bool singleInstance = false);
158 public:
159 Q_INVOKABLE bool waitForProcess(ProcessX *p);
160 Q_INVOKABLE bool waitingForProcess() const;
161
162 static QString createTemporaryFileName(); //don't forget to remove the file!
163
164 void preview(const QString &preamble, const PreviewSource &source, const QString &masterFile, QTextCodec *outputCodec = nullptr);
165 void clearPreviewPreambleCache();
166
167 Q_INVOKABLE bool isCommandDirectlyDefined(const QString &id) const;
168 CommandInfo getCommandInfo(const QString &id) const;
169 QString editCommandList(const QString &list, const QString &excludeId = "");
170 CommandMapping getAllCommands();
171 QStringList getCommandsOrder();
172 void setAllCommands(const CommandMapping &commands, const QStringList &userOrder);
173 QString guessCompilerFromProgramMagicComment(const QString &program);
174 QString guessViewerFromProgramMagicComment(const QString &program);
175
176 int maxExpandingNestingDeep;
177
178 int previewCompileTimeOut;
179
180 int deprecatedQuickmode;
181 QStringList deprecatedUserToolCommands, deprecatedUserToolNames;
182 QStringList userToolOrder, userToolDisplayNames;
183 enum Dvi2PngMode { DPM_DVIPNG, DPM_DVIPNG_FOLLOW, DPM_DVIPS_GHOSTSCRIPT, DPM_EMBEDDED_PDF};
184 Dvi2PngMode dvi2pngMode;
185 enum SaveFilesBeforeCompiling {SFBC_ALWAYS, SFBC_ONLY_CURRENT_OR_NAMED, SFBC_ONLY_NAMED};
186 SaveFilesBeforeCompiling saveFilesBeforeCompiling;
187 bool previewRemoveBeamer, previewPrecompilePreamble;
188 private slots:
189 void singleInstanceCompleted(int status);
190 void preamblePrecompileCompleted(int status);
191 void latexPreviewCompleted(int status);
192 void dvi2psPreviewCompleted(int status);
193 void conversionPreviewCompleted(int status);
194 void PreviewLatexCompleted(int status);
195 void commandLineRequestedDefault(const QString &cmdId, QString *result, bool *user);
196 void runInternalCommandThroughProcessX();
197 void emitEndRunningSubCommandFromProcessX(int);
198 private:
199 bool testAndRunInternalCommand(const QString &cmd, const QFileInfo &mainFile);
200 signals:
201 void hideSplash();
202 void processNotification(const QString &message);
203 void clearLogs();
204 void previewAvailable(const QString &filename, const PreviewSource &source);
205
206 void commandLineRequested(const QString &cmdId, QString *result, bool *user = nullptr);
207 void runInternalCommand(const QString &cmdId, const QFileInfo &mainfile, const QString &options);
208
209 void latexCompiled(LatexCompileResult *rerun);
210 void beginRunningCommands(const QString &commandMain, bool latex, bool pdf, bool asyncPdf);
211 void beginRunningSubCommand(ProcessX *p, const QString &commandMain, const QString &subCommand, const RunCommandFlags &flags);
212 void endRunningSubCommand(ProcessX *p, const QString &commandMain, const QString &subCommand, const RunCommandFlags &flags);
213 void endRunningCommands(const QString &commandMain, bool latex, bool pdf, bool asyncPdf);
214 void buildRunning(bool c);
215 private:
216
217 void initDefaultCommandNames();
218 static QString guessTerminalExternal(void);
219
220 CommandInfo ®isterCommand(const QString &id, const QString &basename, const QString &displayName, const QString &args, const QString &oldConfig = "", GuessCommandLineFunc guessFunc = nullptr, bool user = false);
221 CommandInfo ®isterCommand(const QString &id, const QString &displayname, const QStringList &alternatives, const QString &oldConfig = "", const bool metaCommand = true, const QStringList simpleDescriptions = QStringList());
222 Q_INVOKABLE QString getCommandLine(const QString &id, bool *user);
223 friend class ProcessX;
224 CommandMapping commands;
225 QStringList internalCommands, commandSortingsOrder;
226 QMap<QString, ProcessX *> runningCommands;
227 QPointer<ProcessX> processWaitedFor;
228
229 QStringList latexCommands, rerunnableCommands, pdfCommands, stdoutCommands, viewerCommands;
230 public:
231 static int autoRerunLatex;
232 static bool showLogInCaseOfCompileError;
233 static bool m_replaceEnvironmentVariables;
234 static bool m_interpetCommandDefinitionInMagicComment;
235 static bool m_supportShellStyleLiteralQuotes;
236 static bool singleViewerInstance;
237 static QString autoRerunCommands;
238 static QString additionalSearchPaths, additionalLogPaths, additionalPdfPaths;
239
240 static QString findCompiledFile(const QString &compiledFilename, const QFileInfo &mainFile);
addPreviewFileName(QString fn)241 void addPreviewFileName(QString fn)
242 {
243 if (!previewFileNames.contains(fn))
244 previewFileNames.append(fn);
245 }
246
247 private:
248 QStringList previewFileNames;
249 QMap<QString, PreviewSource> previewFileNameToSource;
250 QHash<QString, QString> preambleHash;
251 void removePreviewFiles(QString elemName);
252 #ifdef Q_OS_WIN32
253 unsigned long int pidInst;
254 Q_INVOKABLE bool executeDDE(QString ddePseudoURL);
255 #endif
256 };
257
258 //#define PROFILE_PROCESSES
Q_DECLARE_METATYPE(ProcessX *)259 Q_DECLARE_METATYPE(ProcessX *)
260 //this process can handle dde and normal commands
261 class ProcessX: public QProcess
262 {
263 Q_OBJECT
264
265 public:
266 ProcessX(BuildManager *parent = nullptr, const QString &assignedCommand = "", const QString &fileToCompile = "");
267 static QString reformatShellLiteralQuotes(QString cmd);
268 void startCommand();
269 bool waitForStarted(int timeOut = 30000);
270 const QString &getFile();
271 const QString &getCommandLine();
272 bool showStdout() const;
273 void setShowStdout(bool show);
274 QString *getStdoutBuffer();
275 Q_INVOKABLE QString getStdout();
276 void setStdoutBuffer(QString *buffer);
277 void setStderrBuffer(QString *buffer);
278 void setStdoutCodec(QTextCodec *codec);
279 bool showStderr() const;
280 void setShowStderr(bool show);
281 void setOverrideEnvironment(const QStringList &env);
282 const QStringList &overrideEnvironment();
283
284 Q_INVOKABLE int exitStatus() const;
285 Q_INVOKABLE int exitCode() const;
286 Q_INVOKABLE QString readAllStandardOutputStr();
287 Q_INVOKABLE QString readAllStandardErrorStr();
288 Q_INVOKABLE bool waitForFinished ( int msecs = 30000 );
289
290 bool isRunning() const;
291 signals:
292 void startedX();
293
294 void processNotification(const QString &message);
295 void standardOutputRead(const QString &data);
296 void standardErrorRead(const QString &data);
297 void processFinished();
298 private slots:
299 void onStarted();
300 void onError(QProcess::ProcessError error);
301 void onFinished(int error);
302 #ifdef PROFILE_PROCESSES
303 void finished();
304 #endif
305 void readFromStandardOutput();
306 void readFromStandardError(bool force = false);
307 private:
308 friend class BuildManager;
309 QString cmd;
310 QString file;
311 bool isStarted, ended, stderrEnabled, stdoutEnabled, stdoutEnabledOverrideOn;
312 QString *stdoutBuffer,*stderrBuffer;
313 QTextCodec *stdoutCodec;
314 QStringList overriddenEnvironment;
315 QString subCommandName, subCommandPrimary;
316 RunCommandFlags subCommandFlags;
317 #ifdef PROFILE_PROCESSES
318 QTime time;
319 #endif
320 };
321
322
323 #endif // BUILDMANAGER_H
324