1 /****************************************************************************************
2   Copyright (C) 2003 by Jeroen Wijnhout (Jeroen.Wijnhout@kdemail.net)
3             (C) 2011-2019 by Michel Ludwig (michel.ludwig@kdemail.net)
4  ****************************************************************************************/
5 
6 /***************************************************************************
7  *                                                                         *
8  *   This program is free software; you can redistribute it and/or modify  *
9  *   it under the terms of the GNU General Public License as published by  *
10  *   the Free Software Foundation; either version 2 of the License, or     *
11  *   (at your option) any later version.                                   *
12  *                                                                         *
13  ***************************************************************************/
14 
15 #ifndef KILETOOL_H
16 #define KILETOOL_H
17 
18 #include <QHash>
19 #include <QLinkedList>
20 #include <QMap>
21 #include <QObject>
22 #include <QString>
23 #include <QStringList>
24 
25 #include <KLocalizedString>
26 
27 #include "kilelauncher.h"
28 #include "outputinfo.h"
29 
30 class KConfig;
31 class KileInfo;
32 class KileProject;
33 
34 namespace KileTool
35 {
36 typedef QMap<QString, QString> Config;
37 
38 class Factory;
39 class Manager;
40 
41 /**
42 * A class that defines a general tool (latex, dvips etc.) to be launched from
43 * within Kile.
44 *
45 * @author Jeroen Wijnhout
46 **/
47 
48 class Base : public QObject
49 {
50     Q_OBJECT
51     friend class KileTool::Factory;
52 
53     // only the factory can create tools
54 protected:
55     Base(const QString &name, Manager *manager, bool prepare = true);
56 public:
57     ~Base();
58 
59     /**
60      * Sets the KileInfo object, this is already taken care of by the Manager.
61      **/
setInfo(KileInfo * ki)62     void setInfo(KileInfo *ki) {
63         m_ki = ki;
64     }
65 
66     /**
67      * Sets the KConfig object, this is already taken care of by the Manager.
68      **/
setConfig(KConfig * config)69     void setConfig(KConfig *config) {
70         m_config = config;
71     }
72 
73     /**
74      * @returns the Manager object for this tool.
75      **/
manager()76     Manager* manager() const {
77         return m_manager;
78     }
79 
80     /**
81      * @returns a short descriptive name for this tool.
82      **/
name()83     const QString& name() const {
84         return m_name;
85     }
86 
87     /**
88      * Allows you to set the source file and working directory explicitly (absolute path).
89      **/
90     virtual void setSource(const QString& source, const QString& workingDir = "");
91 
92     /**
93      * @returns the source file that is used to run the tool on.
94      **/
95     QString source(bool absolute = true) const;
96 
S()97     QString S() const {
98         return m_S;
99     }
baseDir()100     QString baseDir() const {
101         return m_basedir;
102     }
relativeDir()103     QString relativeDir() const {
104         return m_relativedir;
105     }
targetDir()106     QString targetDir() const {
107         return m_targetdir;
108     }
from()109     inline QString from() const {
110         return readEntry("from");
111     }
to()112     inline QString to() const {
113         return readEntry("to");
114     }
target()115     QString target() const {
116         return m_target;
117     }
options()118     QString options() const {
119         return m_options;
120     }
121 
toolConfig()122     QString toolConfig() const {
123         return m_toolConfig;
124     }
125 
setOptions(const QString & opt)126     void setOptions(const QString& opt) {
127         m_options = opt;
128     }
129 
isViewer()130     virtual bool isViewer() {
131         return false;
132     }
133 
setQuickie()134     void setQuickie() {
135         m_quickie = true;
136     }
isQuickie()137     bool isQuickie() {
138         return m_quickie;
139     }
140 
141     /**
142      * Returns true iff all documents must be saved before the tool can be launched
143      **/
144     virtual bool requestSaveAll();
145 
setPartOfLivePreview()146     void setPartOfLivePreview() {
147         m_isPartOfLivePreview = true;
148     }
isPartOfLivePreview()149     bool isPartOfLivePreview() const {
150         return m_isPartOfLivePreview;
151     }
152 
153     void setTeXInputPaths(const QString& s);
154     QString teXInputPaths() const;
155     void setBibInputPaths(const QString& s);
156     QString bibInputPaths() const;
157     void setBstInputPaths(const QString& s);
158     QString bstInputPaths() const;
159     void copyPaths(Base* tool);
160 
161     /**
162      * Allows you to set the target file explicitly (filename only).
163      **/
164     virtual void setTarget(const QString & target);
165     virtual void setTargetDir(const QString & target);
166     virtual void setTargetPath(const QString & target);
167 
168     /**
169      * Sets the target directory relative to the source directory.
170      **/
setRelativeBaseDir(const QString & dir)171     void setRelativeBaseDir(const QString & dir) {
172         m_relativedir = dir;
173     }
174 
175     /**
176      * Installs a launcher object that will be responsible for actually starting the tool. The
177      * tool can be a command-line tool or a kpart, the KileTool class doesn't need to know
178      * about the specifics of the launcher.
179      **/
180     void installLauncher(Launcher *lr );
181 
182     /**
183      * Installs a launcher as indicated by the tool type. This creates a launcher object.
184      **/
185     bool installLauncher();
186 
187     /**
188      * @returns a pointer to the launcher object, returns 0 if no launcher is installed.
189      **/
launcher()190     Launcher *launcher() {
191         return m_launcher;
192     }
193 
194     /**
195      * @returns the working dir for this tool.
196      **/
workingDir()197     const QString &workingDir() const {
198         return m_workingDir;
199     }
200 
setWorkingDir(const QString & s)201     void setWorkingDir(const QString& s) {
202         m_workingDir = s;
203     }
204 
205     /**
206      * @returns the dictionary that translates the following keys
207     Example docu:
208     Consider a file which is called myBestBook.tex which resides in /home/thomas/latex and you compile it with pdflatex to myBestBook.pdf.
209 
210     The variables have the following meanings:
211     %source ->  filename with suffix but without path <-> myBestBook.tex
212     %S ->  filename without suffix but without path <-> myBestBook
213     %dir_base  -> path of the source file without filename  <-> /home/thomas/latex
214     %dir_target -> path of the target file without filename, same as %dir_base if no relative path has been set <-> /home/thomas/latex
215     %target -> target filename without path <-> without filename
216 
217     And these are special variables:
218     %res <-> resolution of the quickpreview action set in configure kile->tools->preview
219 
220     %AFL <-> List of all files in a project marked for archiving. You can set the archive flag in the "Files and projects" sidebar using the context menu.
221 
222     %absolute_target -> Used in conjunction with Okular to inform it about the cursor position for
223                         the ForwardDVI/PDF feature
224 
225     %sourceFileName <-> Source file name (for synchronizing the cursor location with the viewer)
226     %sourceLine <-> Line in the source file on which the cursor is located (for synchronizing the cursor location with the viewer)
227     */
paramDict()228     QHash<QString,QString>& paramDict() {
229         return m_dictParams;
230     }
231 
232     bool addDict(const QString& key, const QString& value);
233 
234     void translate(QString &str, bool quoteForShell = false);
235 
setFlags(uint flags)236     void setFlags(uint flags) {
237         m_flags = flags;
238     }
flags()239     uint flags() {
240         return m_flags;
241     }
242     void removeFlag(uint flag);
243 
244     void setMsg(long n, const KLocalizedString& msg);
msg(long n)245     KLocalizedString msg(long n) const {
246         return m_messages[n];
247     }
248 
249     virtual void setupAsChildTool(KileTool::Base *child);
250 
251 public Q_SLOTS:
252     void sendMessage(int, const QString &);
253     virtual void filterOutput(const QString &);
254 
255     /**
256      * Starts the tool. First it performs basic checks (checkPrereqs()),
257      * if all is well it launches the tool (launch()). After the process has
258      * exited it calls finish().
259      * @return the exit code of the tool (if available)
260      **/
261     virtual int run();
262 
263     /**
264      * Terminates the running process.
265      **/
266     virtual void stop();
267 
268     /**
269      * Clean up after the process/lib has finished.
270      **/
271     virtual bool finish(int);
272 
273     void installLaTeXOutputParserResult(int nErrors, int nWarnings, int nBadBoxes, const LatexOutputInfoArray& outputList,
274                                         const QString& logFile);
275 
276 Q_SIGNALS:
277     void message(int, const QString &, const QString &);
278     void output(const QString &);
279 
280     void start(KileTool::Base*);
281     void done(KileTool::Base*, int, bool childToolSpawned);
282     void failedToRun(KileTool::Base*, int);
283 
284     void aboutToBeDestroyed(KileTool::Base*);
285 
286 public:
setEntryMap(Config map)287     void setEntryMap(Config map) {
288         m_entryMap = map;
289     }
290     void setEntry(const QString& key, const QString& value);
readEntry(const QString & key)291     const QString readEntry(const QString& key) const {
292         return m_entryMap[key];
293     }
294 
295     virtual void prepareToRun();
isPrepared()296     bool isPrepared() {
297         return m_bPrepared;
298     }
needsToBePrepared()299     bool needsToBePrepared() {
300         return m_bPrepareToRun;
301     }
302 
303 protected:
304     Launcher	*m_launcher;
305     bool		m_quickie;
306     bool		m_isPartOfLivePreview;
307 
308     bool needsUpdate(const QString &target, const QString &source);
309 
310     /**
311      * Checks if the prerequisites are in order.
312      * @returns true if everything is ok, false otherwise.
313      **/
314     virtual bool checkPrereqs();
315 
316     /**
317      * Determines on which file to run the tool.
318      **/
319     virtual bool determineSource();
320 
321     /**
322      * Determines the target of the tool (i.e. a DVI for latex, PS for dvips) and
323      * checks if the target file can be written to the specified location.
324      **/
325     virtual bool determineTarget();
326 
327     /**
328      * Check if the target dir and file have the correct permissions (according to the flags set).
329      **/
330     virtual bool checkTarget();
331 
332     virtual bool checkSource();
333 
334     void runChildNext(Base *tool, bool block = false);
335 
setToolConfig(const QString & config)336     void setToolConfig(const QString& config) {
337         m_toolConfig = config;
338     }
339 
340     virtual void latexOutputParserResultInstalled();
341 
342 protected:
343     Manager			*m_manager;
344     KileInfo		*m_ki;
345     KConfig			*m_config;
346 
347 private:
348     QString			m_name;
349     QString			m_target, m_basedir, m_relativedir, m_targetdir, m_source, m_S, m_workingDir;
350     QString			m_options;
351     QString			m_resolution;
352 
353     QString			m_message;
354 
355     bool			m_buildPrereqs;
356 
357     QHash<QString,QString> m_dictParams;
358     Config			m_entryMap;
359 
360     uint		    	m_flags;
361     int			m_nPreparationResult;
362     bool			m_bPrepared;
363     bool			m_bPrepareToRun;
364     QString			m_toolConfig;
365 
366     QString m_texInputs, m_bibInputs, m_bstInputs;
367 
368     //messages
369     QMap<long, KLocalizedString>	m_messages;
370 
371 protected:
372     int			m_nErrors, m_nWarnings, m_nBadBoxes;
373     LatexOutputInfoArray	m_latexOutputInfoList;
374     QString			m_logFile;
375     bool			m_childToolSpawned;
376     int			m_toolResult;
377 };
378 
379 /**
380  * A class that represents a compile tool (such as latex, pdflatex).
381  **/
382 class Compile : public Base
383 {
384     friend class KileTool::Factory;
385 protected:
386     Compile(const QString &name, Manager * manager, bool prepare = true);
387 public:
388     ~Compile();
389 
390 protected:
391     virtual bool checkSource() override;
392 };
393 
394 /**
395  * A class that represents a view tool (such as KDVI, gv, etc.).
396  **/
397 class View : public Base
398 {
399     friend class KileTool::Factory;
400 protected:
401     View(const QString &name, Manager * manager, bool prepare = true);
402 public:
403     ~View();
404 
isViewer()405     virtual bool isViewer() override {
406         return true;
407     }
408 };
409 
410 /**
411  * A class that represents a conversion tool (such as dvips).
412  **/
413 class Convert : public Base
414 {
415     friend class KileTool::Factory;
416 protected:
417     Convert(const QString &name, Manager * manager, bool prepare = true);
418 public:
419     ~Convert();
420 
421     virtual bool determineSource() override;
422 };
423 
424 /**
425  * A class that represents a tool like tar, from multiple files to one file
426  **/
427 class Archive: public Base
428 {
429     Q_OBJECT
430     friend class KileTool::Factory;
431 
432 protected:
433     Archive(const QString &name, Manager * manager, bool prepare = true);
434 public:
435     ~Archive();
436     virtual bool checkPrereqs() override;
437     virtual void setSource(const QString & source, const QString& workingDir = "") override;
438 private:
439     KileProject *m_project;
440     QString m_fileList;
441 };
442 
443 class Sequence : public Base
444 {
445     Q_OBJECT
446     friend class KileTool::Factory;
447 
448     virtual bool requestSaveAll() override;
449 
450     void setupSequenceTools();
451 
452     LaTeXOutputHandler* latexOutputHandler();
453     void setLaTeXOutputHandler(LaTeXOutputHandler *h);
454 
455 public Q_SLOTS:
456     virtual int run() override;
457 
458 protected:
459     Sequence(const QString &name, Manager *manager, bool prepare = true);
460     ~Sequence();
461 
462     // will also determine the current LaTeXOutputHandler
463     virtual bool determineSource() override;
464 
465     QLinkedList<Base*> m_tools;
466     QString m_unknownToolSpec;
467     LaTeXOutputHandler *m_latexOutputHandler;
468 };
469 }
470 
471 #endif
472