1 /*************************************************************************************
2     Copyright (C) 2003 by Jeroen Wijnhout (Jeroen.Wijnhout@kdemail.net)
3               (C) 2006-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 DOCUMENTINFO_H
16 #define DOCUMENTINFO_H
17 
18 #include <QHash>
19 
20 #include <KTextEditor/Document>
21 #include <QUrl>
22 
23 #include "kiledebug.h"
24 
25 #include <latexcmd.h>
26 
27 #include "kileconstants.h"
28 #include "kileextensions.h"
29 #include "livepreview_utils.h"
30 #include "outputinfo.h"
31 
32 #define TEX_CAT0 '\\'
33 #define TEX_CAT1 '{'
34 #define TEX_CAT2 '}'
35 #define TEX_CAT3 '$'
36 #define TEX_CAT4 '&'
37 #define TEX_CAT6 '#'
38 #define TEX_CAT7 '^'
39 #define TEX_CAT8 '_'
40 #define TEX_CAT13 '~'
41 #define TEX_CAT14 '%'
42 
43 #define SIZE_STAT_ARRAY 6
44 
45 namespace KileDocument {
46 class EditorExtension;
47 }
48 namespace KileConfiguration {
49 class Manager;
50 }
51 namespace KileCodeCompletion {
52 class LaTeXCompletionModel;
53 class AbbreviationCompletionModel;
54 class Manager;
55 }
56 namespace KileAbbreviation {
57 class Manager;
58 }
59 namespace KileTool {
60 class LivePreviewManager;
61 }
62 namespace KileParser {
63 class ParserOutput;
64 class Manager;
65 }
66 namespace KileView {
67 class Manager;
68 }
69 
70 namespace KileStruct
71 {
72 //Different types of elements in the structure view
73 enum
74 {
75     None = 0x1, Label = 0x2, Sect = 0x4, Input = 0x8,
76     BibItem = 0x10, Bibliography = 0x20, Package = 0x40, NewCommand = 0x80,
77     Graphics = 0x100, Reference = 0x200, BeginEnv = 0x400, EndEnv = 0x800,
78     BeginFloat = 0x1000, EndFloat = 0x2000,  Caption = 0x4000, BeamerFrame = 0x8000,
79     BeamerBeginFrame = 0x10000, BeamerEndFrame = 0x20000, BeamerFrametitle = 0x40000, BeamerBeginBlock = 0x80000,
80     ToDo = 0x100000, FixMe = 0x200000, NewEnvironment = 0x400000
81 };
82 
83 //Different levels (in the parent-child hierarchy) in the structure view
84 enum
85 {
86     Hidden = -4, NotSpecified = -3, Object = -2, File = -1
87 };
88 }
89 
90 /**
91  * A convenience class to store info about how LaTeX elements should appear in the
92  * structure view. A QMap<QString, KileStructData> should be created, so that the
93  * actual LaTeX elements can be mapped to this class.
94  **/
95 class KileStructData
96 {
97 public:
level(lvl)98     explicit KileStructData(int lvl = 0, int tp = KileStruct::None, QString px = QString(), QString fldr = "root" )  : level(lvl), type(tp), pix(px), folder(fldr) {}
99     /** At which level the element should be visible **/
100     int				level;
101     /** The type of element (see @ref KileStruct) **/
102     int 			type;
103     /** The name of the icon that goes with this element. The icon is located using SmallIcon(pix). **/
104     QString 	pix, folder;
105 };
106 
107 /**
108  * KileDocument::Info is a decorator class for the Document class. We can't derive a class from an interface
109  * without implementing the interface, a decorator class is a way to add some functionality to the Document class.
110  **/
111 
112 namespace KileDocument
113 {
114 
115 struct BracketResult
116 {
BracketResultBracketResult117     BracketResult() : line(0), col(0) {}
118     QString option, value;
119     int line, col;
120 };
121 
122 struct TodoResult
123 {
124     int type;
125     uint colTag;
126     uint colComment;
127     QString comment;
128 };
129 
130 class Info : public QObject
131 {
132     Q_OBJECT
133 
134 public:
135     static bool containsInvalidCharacters(const QUrl&);
136     static QUrl repairInvalidCharacters(const QUrl&, QWidget *mainWidget, bool checkForFileExistence = true);
137     static QUrl repairExtension(const QUrl &url, QWidget *mainWidget, bool checkForFileExistence = true);
138     static QUrl makeValidTeXURL(const QUrl &url, QWidget *mainWidget, bool istexfile, bool checkForFileExistence = true);
139     static QUrl renameIfExist(const QUrl &url, QWidget *mainWidget);
140 
141 public:
142     Info();
143     ~Info();
144 
labels()145     QStringList labels() const {
146         return m_labels;
147     }
bibItems()148     QStringList bibItems() const {
149         return m_bibItems;
150     }
dependencies()151     QStringList dependencies() const {
152         return m_deps;
153     }
bibliographies()154     QStringList bibliographies() const {
155         return m_bibliography;
156     }
packages()157     QStringList packages() const {
158         return m_packages;
159     }
newCommands()160     QStringList newCommands() const {
161         return m_newCommands;
162     }
asyFigures()163     QStringList asyFigures() const {
164         return m_asyFigures;
165     }
166 
openStructureLabels()167     bool openStructureLabels() {
168         return m_openStructureLabels;
169     }
openStructureReferences()170     bool openStructureReferences() {
171         return m_openStructureReferences;
172     }
openStructureBibitems()173     bool openStructureBibitems() {
174         return m_openStructureBibitems;
175     }
openStructureTodo()176     bool openStructureTodo() {
177         return m_openStructureTodo;
178     }
179 
showStructureLabels()180     bool showStructureLabels() {
181         return m_showStructureLabels;
182     }
183 
dictStructLevel()184     const QMap<QString, KileStructData>& dictStructLevel() {
185         return m_dictStructLevel;
186     }
187 
preamble()188     const QString & preamble() const {
189         return m_preamble;
190     }
191 
isLaTeXRoot()192     virtual bool isLaTeXRoot() {
193         return m_bIsRoot;
194     }
195 
196     virtual QUrl url();
197 
198     virtual void updateStructLevelInfo();
199 
200     void setBaseDirectory(const QUrl &url);
201     const QUrl &getBaseDirectory() const;
202 
203     virtual bool isTextDocument();
204     virtual Type getType();
205 
206     /**
207      * Returns a file filter suitable for loading and saving files of this class' type.
208      **/
209     virtual QLinkedList<Extensions::ExtensionType> getFileFilter() const;
210 
211     virtual bool isDocumentTypePromotionAllowed();
212     void setDocumentTypePromotionAllowed(bool b);
213 
214     /**
215      * Returns true iff new parsing is required.
216      **/
217     bool isDirty() const;
218     void setDirty(bool b);
219 
220     virtual void installParserOutput(KileParser::ParserOutput *parserOutput);
221 
222 public Q_SLOTS:
223     /**
224      * Never call this function directly, use KileWidget::Structure::update(KileDocument::Info *, bool) instead
225      **/
226     virtual void updateStruct();
227     virtual void updateBibItems();
228 
229 Q_SIGNALS:
230     void urlChanged(KileDocument::Info* info, const QUrl &url);
231     void isrootChanged(bool);
232 
233     void foundItem(const QString &title, uint line, uint column, int type, int level, uint startline, uint startcol,
234                    const QString & pix, const QString & folder);
235     void depChanged();
236     void completed(KileDocument::Info* info);
237     void parsingStarted(int maxValue);
238     void parsingComplete();
239     void parsingUpdate(int value);
240 
241 protected Q_SLOTS:
242     void slotCompleted();
243 
244 protected:
245     void count(const QString& line, long *stat);
246 
247     enum State {
248         stStandard = 0, stComment = 1, stControlSequence = 3, stControlSymbol = 4,
249         stCommand = 5, stEnvironment = 6
250     };
251 
252     bool						m_bIsRoot;
253     bool						m_dirty;
254     QStringList					m_labels;
255     QStringList					m_bibItems;
256     QStringList					m_deps, m_depsPrev;
257     QStringList					m_bibliography;
258     QStringList					m_packages;
259     QStringList					m_newCommands;
260     QStringList					m_asyFigures;
261     QString						m_preamble;
262     QMap<QString,KileStructData>			m_dictStructLevel;
263     KConfig						*m_config;
264     bool m_showStructureLabels;
265     bool m_showStructureBibitems;
266     bool m_showStructureGraphics;
267     bool m_showStructureFloats;
268     bool m_showStructureReferences;
269     bool m_showStructureInputFiles;
270     bool m_showStructureTodo;
271     bool m_showSectioningLabels;
272     bool m_openStructureLabels;
273     bool m_openStructureReferences;
274     bool m_openStructureBibitems;
275     bool m_openStructureTodo;
276     QUrl						m_baseDirectory;
277     bool						documentTypePromotionAllowed;
278     Extensions *m_extensions;
279 };
280 
281 
282 /**
283  * The URL of a text document is managed directly by the corresponding KTextEditor::Document.
284  **/
285 class TextInfo : public Info
286 {
287     Q_OBJECT
288 public:
289     /**
290      * @param defaultMode the mode that will be set automatically
291      *                    once a new document is installed
292      **/
293     TextInfo(Extensions *extensions,
294              KileAbbreviation::Manager *abbreviationManager,
295              KileParser::Manager *parserManager,
296              const QString& defaultMode = QString());
297     virtual ~TextInfo();
298 
299     /**
300      * @returns the document for which this class is a decorator
301      **/
302     const KTextEditor::Document* getDoc() const;
303     KTextEditor::Document* getDoc();
304     const KTextEditor::Document* getDocument() const;
305     KTextEditor::Document* getDocument();
306     void setDoc(KTextEditor::Document *doc);
307     void setDocument(KTextEditor::Document *doc);
308     void detach();
309 
310     /**
311      * Used by @ref KileDocInfoDlg to display statistics of the Document.
312      * @returns an array with some statistical data of the document.
313      * The array is filled as follows: [0] = #c in words, [1] = #c in latex commands and environments,
314        [2] = #c whitespace, [3] = #words, [4] = # latex_commands, [5] = latex_environments **/
315 
316     virtual const long* getStatistics(KTextEditor::View *view = Q_NULLPTR);
317 
318     /**
319      * @returns the URL of the KTextEditor::Document if not null, an empty QUrl otherwise
320      **/
321     virtual QUrl url() override;
322 
323     virtual Type getType() override;
324 
325     virtual bool isTextDocument() override;
326 
327     void setHighlightingMode(const QString& highlight = QString());
328 
329     void setMode(const QString& mode = QString());
330 
331     void setDefaultMode(const QString& string);
332 
333     /**
334      * "Overridden" method that installs custom event filters by using the "installEventFilters"
335      * method. It also installs signal connections by using the "installSignalConnections"
336      * method.
337      * @warning Only this method should be used to create new views for text documents !
338      * @return Q_NULLPTR if no document is set (m_doc == NULL)
339      **/
340     KTextEditor::View* createView(QWidget *parent, const char *name = Q_NULLPTR);
341 
342     void startAbbreviationCompletion(KTextEditor::View *view);
343 
344     /**
345      * Returns the contents of the document if a KTextEditor::Document is present. Otherwise,
346      * the contents supplied via @ref setDocumentContents is returned.
347      **/
348     const QStringList documentContents() const;
349     void setDocumentContents(const QStringList& contents);
350 
351 Q_SIGNALS:
352     void documentDetached(KTextEditor::Document*);
353     void aboutToBeDestroyed(KileDocument::TextInfo*);
354 
355 protected Q_SLOTS:
356     void slotFileNameChanged();
357     void slotViewDestroyed(QObject *object);
358     void activateDefaultMode();
359 
360     void makeDirtyIfModified();
361 
362 protected:
363     KTextEditor::Document				*m_doc;
364     bool						m_dirty;
365     long						*m_arStatistics;
366     QString						m_defaultMode;
367     QHash<KTextEditor::View*, QList<QObject*> >	m_eventFilterHash;
368     KileAbbreviation::Manager			*m_abbreviationManager;
369     KileCodeCompletion::AbbreviationCompletionModel *m_abbreviationCodeCompletionModel;
370     KileParser::Manager 			*m_parserManager;
371 
372     QString matchBracket(QChar c, int &, int &);
373     QString getTextline(uint line, TodoResult &todo);
374     void searchTodoComment(const QString &s, uint startpos, TodoResult &todo);
375 
376     /**
377      * Creates the event filters that should be used on a view. Subclasses can override
378      * this method to provide custom event filters. The default implementation does nothing and
379      * returns an empty list. The event filters that are returned by this method are managed by
380      * the "installEventFilters", "removeInstalledEventFilters" methods.
381      * @warning The event filters that are created must be children of the view!
382      * @param view the view that is considered
383      **/
384     virtual QList<QObject*> createEventFilters(KTextEditor::View *view);
385 
386     /**
387      * Installs event filters on a view. The function "createEventFilters(KTextEditor::View *view)
388      * function is used for a specific view.
389      * @param view the view that is considered
390      **/
391     virtual void installEventFilters(KTextEditor::View *view);
392 
393     /**
394      * Removes the event filters that were previously installed by the "installEventFilters"
395      * function.
396      * @param view the view that is considered
397      **/
398     virtual void removeInstalledEventFilters(KTextEditor::View *view);
399 
400     /**
401      * Installs the event filters on all the views that are currently open for the
402      * managed document object. The function "installEventFilters(KTextEditor::View *view)
403      * function is used for a specific view.
404      **/
405     void installEventFilters();
406 
407     /**
408      * Removes the event filters from all the views that are currently open for the
409      * managed document object.
410      **/
411     void removeInstalledEventFilters();
412 
413     /**
414      * Installs signal connections on a view.
415      */
416     virtual void installSignalConnections(KTextEditor::View *view);
417 
418     /**
419      * Disconnects the signals that were previously connected with the
420      * "installSignalConnections" function.
421      */
422     virtual void removeSignalConnections(KTextEditor::View *view);
423 
424     /**
425      * Installs signal connections on all the views that are currently open for the
426      * managed document object. The function "installSignalConnections(KTextEditor::View *view)
427      * function is used for a specific view.
428      **/
429     void installSignalConnections();
430 
431     /**
432      * Removes signal connections from all the views that are currently open for the
433      * managed document object.
434      **/
435     void removeSignalConnections();
436 
437     /**
438      * Register code completion models on a view.
439      */
440     virtual void registerCodeCompletionModels(KTextEditor::View *view);
441 
442     /**
443      * Unregisters the code completion models that were previously registered by the
444      * "registerCodeCompletionModels" method.
445      */
446     virtual void unregisterCodeCompletionModels(KTextEditor::View *view);
447 
448     /**
449      * Register code completion models on all the views that are currently open for the
450      * managed document object. The function "registerCodeCompletionModels(KTextEditor::View *view)
451      * function is used for a specific view.
452      **/
453     void registerCodeCompletionModels();
454 
455     /**
456      * Unregister the code completion models from all the views that are currently open for the
457      * managed document object.
458      **/
459     void unregisterCodeCompletionModels();
460 
461 private:
462     QStringList m_documentContents;
463 };
464 
465 
466 
467 class LaTeXInfo : public TextInfo, public KileTool::LivePreviewUserStatusHandler, public LaTeXOutputHandler
468 {
469     Q_OBJECT
470 
471 public:
472     /**
473      * @param eventFilter the event filter that will be installed on managed documents
474      **/
475     LaTeXInfo(Extensions *extensions,
476               KileAbbreviation::Manager *abbreviationManager,
477               LatexCommands *commands,
478               KileDocument::EditorExtension *editorExtension,
479               KileConfiguration::Manager *manager,
480               KileCodeCompletion::Manager *codeCompletionManager,
481               KileTool::LivePreviewManager *livePreviewManager,
482               KileView::Manager *viewManager,
483               KileParser::Manager *parserManager);
484 
485     virtual ~LaTeXInfo();
486 
487     virtual Type getType() override;
488 
489     virtual QLinkedList<Extensions::ExtensionType> getFileFilter() const override;
490 
491     void startLaTeXCompletion(KTextEditor::View *view);
492 
493     virtual void installParserOutput(KileParser::ParserOutput *parserOutput) override;
494 
495 public Q_SLOTS:
496     virtual void updateStruct() override;
497 
498 protected:
499     LatexCommands *m_commands;
500     EditorExtension *m_editorExtension;
501     KileConfiguration::Manager *m_configurationManager;
502     QObject *m_eventFilter;
503     KileCodeCompletion::LaTeXCompletionModel *m_latexCompletionModel;
504     KileTool::LivePreviewManager *m_livePreviewManager;
505     KileView::Manager *m_viewManager;
506 
507     virtual void updateStructLevelInfo() override;
508     virtual void checkChangedDeps();
509 
510     /**
511      * Creates a custom event filter.
512      */
513     virtual QList<QObject*> createEventFilters(KTextEditor::View *view) override;
514 
515     virtual void installSignalConnections(KTextEditor::View *view) override;
516     virtual void removeSignalConnections(KTextEditor::View *view) override;
517 
518     virtual void registerCodeCompletionModels(KTextEditor::View *view) override;
519     virtual void unregisterCodeCompletionModels(KTextEditor::View *view) override;
520 
521 private:
522     BracketResult matchBracket(int &, int &);
523 };
524 
525 
526 
527 class BibInfo : public TextInfo
528 {
529     Q_OBJECT
530 
531 public:
532     BibInfo (Extensions *extensions,
533              KileAbbreviation::Manager *abbreviationManager,
534              KileParser::Manager *parserManager,
535              LatexCommands* commands);
536     virtual ~BibInfo();
537 
538     virtual bool isLaTeXRoot() override;
539 
540     virtual Type getType() override;
541 
542     virtual QLinkedList<Extensions::ExtensionType> getFileFilter() const override;
543 
544     virtual void installParserOutput(KileParser::ParserOutput *parserOutput) override;
545 
546 public Q_SLOTS:
547     virtual void updateStruct() override;
548 };
549 
550 class ScriptInfo : public TextInfo
551 {
552     Q_OBJECT
553 
554 public:
555     ScriptInfo(Extensions *extensions,
556                KileAbbreviation::Manager *abbreviationManager,
557                KileParser::Manager *parserManager);
558 
559     virtual ~ScriptInfo();
560 
561     virtual bool isLaTeXRoot() override;
562 
563     virtual Type getType() override;
564 
565     virtual QLinkedList<Extensions::ExtensionType> getFileFilter() const override;
566 };
567 
568 }
569 #endif
570