1 #ifndef Header_Latex_Document 2 #define Header_Latex_Document 3 //#undef QT_NO_DEBUG 4 #include "mostQtHeaders.h" 5 #include "latexstructure.h" 6 #include "qdocument.h" 7 #include "codesnippet.h" 8 #include "bibtexparser.h" 9 #include "latexparser.h" 10 #include "usermacro.h" 11 #include "syntaxcheck.h" 12 #include "grammarcheck.h" 13 #include "latexpackage.h" 14 //#include "latexeditorview.h" 15 16 //class QDocumentLineHandle; 17 class LatexEditorView; 18 class QDocumentCursor; 19 class Macro; 20 21 22 struct FileNamePair { 23 QString relative, absolute; 24 FileNamePair(const QString &rel, const QString &abs); 25 }; 26 27 28 struct ReferencePair { 29 QString name; 30 int start; 31 }; 32 33 struct ReferencePairEx { 34 QDocumentLineHandle *dlh; 35 QVector<int> starts,lengths,formats; 36 QList<int> formatList; 37 }; 38 39 40 struct UserCommandPair { 41 // name of command ("\command") or environment ("environment"), 42 // null string for other user definitions (e.g. newcolumntype, definecolor) 43 QString name; 44 // information for code completion 45 CodeSnippet snippet; 46 UserCommandPair(const QString &name, const CodeSnippet &snippet); 47 }; 48 49 50 /*! \brief extended QDocument 51 * 52 * Extended document for handling latex documents 53 * Extension encompass filename handling, label,bibliography as well as syntax interpreting (Token system) 54 * Also structureview is maintained here 55 * The live-update of syntactical information is performed in \method patchStructure 56 */ 57 class LatexDocument: public QDocument 58 { 59 Q_OBJECT 60 61 public: 62 LatexDocument(QObject *parent = nullptr); 63 ~LatexDocument(); 64 65 enum CookieType { 66 CK_COLS = 0 67 }; 68 static const QSet<QString> LATEX_LIKE_LANGUAGES; 69 70 void setFileName(const QString &fileName); 71 void setEditorView(LatexEditorView *edView);///< set reference to actual GUI element of editor 72 Q_INVOKABLE LatexEditorView *getEditorView() const; 73 QString getFileName() const; 74 QFileInfo getFileInfo() const; 75 //QSet<QString> texFiles; //absolute file names, also contains fileName 76 77 Q_PROPERTY(QString fileName READ getFileName) 78 Q_PROPERTY(QFileInfo fileInfo READ getFileInfo) 79 #if (QT_VERSION<QT_VERSION_CHECK(6,0,0)) 80 Q_PROPERTY(LatexEditorView *editorView READ getEditorView) 81 #endif 82 83 bool isHidden(); ///< true if editor is not displayed 84 85 // References containedLabels,containedReferences; 86 QMultiHash<QDocumentLineHandle *, FileNamePair> &mentionedBibTeXFiles(); 87 const QMultiHash<QDocumentLineHandle *, FileNamePair> &mentionedBibTeXFiles() const; 88 QStringList listOfMentionedBibTeXFiles() const; 89 QSet<QString> lastCompiledBibTeXFiles; 90 91 QList<Macro> localMacros; 92 93 friend class SyntaxCheckTest; 94 friend class LatexEditorViewTest; 95 friend class LatexStructureMerger; 96 friend class LatexStructureMergerMerge; 97 friend class ScriptEngineTest; 98 99 private: 100 static QStringList someItems(const QMultiHash<QDocumentLineHandle *, ReferencePair> &list); 101 void setFileNameInternal(const QString& fileName); 102 void setFileNameInternal(const QString& fileName, const QFileInfo &pairedFileInfo); 103 104 public: 105 Q_INVOKABLE QStringList labelItems() const; ///< all labels in this document 106 Q_INVOKABLE QStringList refItems() const; ///< all references in this document 107 Q_INVOKABLE QStringList bibItems() const; ///< all bibitem defined in this document 108 Q_INVOKABLE QList<CodeSnippet> userCommandList() const; ///< all user commands defined in this document, sorted 109 Q_INVOKABLE CodeSnippetList additionalCommandsList(); 110 void updateRefsLabels(const QString &ref); 111 void recheckRefsLabels(QList<LatexDocument *> listOfDocs=QList<LatexDocument*>(), QStringList items=QStringList()); 112 static void updateRefHighlight(ReferencePairEx p); 113 Q_INVOKABLE int countLabels(const QString &name); 114 Q_INVOKABLE int countRefs(const QString &name); 115 Q_INVOKABLE bool bibIdValid(const QString &name); 116 Q_INVOKABLE bool isBibItem(const QString &name); 117 Q_INVOKABLE QString findFileFromBibId(const QString &name); ///< find bib-file from bibid 118 Q_INVOKABLE QMultiHash<QDocumentLineHandle *, int> getLabels(const QString &name); ///< get line/column from label name 119 Q_INVOKABLE QMultiHash<QDocumentLineHandle *, int> getRefs(const QString &name); ///< get line/column from reference name 120 Q_INVOKABLE QMultiHash<QDocumentLineHandle *, int> getBibItems(const QString &name); 121 Q_INVOKABLE QDocumentLineHandle *findCommandDefinition(const QString &name); ///< get line of definition from command name (may return nullptr) 122 Q_INVOKABLE QDocumentLineHandle *findUsePackage(const QString &name); ///< get line of \usepackage from package name (may return nullptr) 123 Q_INVOKABLE void replaceItems(QMultiHash<QDocumentLineHandle *, ReferencePair> items, const QString &newName, QDocumentCursor *cursor = nullptr); 124 Q_INVOKABLE void replaceLabel(const QString &name, const QString &newName, QDocumentCursor *cursor = nullptr); 125 Q_INVOKABLE void replaceRefs(const QString &name, const QString &newName, QDocumentCursor *cursor = nullptr); 126 Q_INVOKABLE void replaceLabelsAndRefs(const QString &name, const QString &newName); 127 128 void patchLinesContaining(const QStringList cmds); 129 130 StructureEntry *baseStructure; 131 132 QDocumentSelection sectionSelection(StructureEntry *section); clearAppendix()133 void clearAppendix() 134 { 135 mAppendixLine = nullptr; 136 } 137 StructureEntry *findSectionForLine(int currentLine); 138 139 LatexDocuments *parent; 140 141 void setTemporaryFileName(const QString &fileName); 142 Q_INVOKABLE QString getTemporaryFileName() const; 143 Q_INVOKABLE QString getFileNameOrTemporaryFileName() const; 144 Q_INVOKABLE QFileInfo getTemporaryFileInfo() const; 145 Q_INVOKABLE QString getAbsoluteFilePath(const QString &relName, const QString &extension, const QStringList &additionalSearchPaths = QStringList()) const; 146 147 void setMasterDocument(LatexDocument *doc, bool recheck = true); 148 void addChild(LatexDocument *doc); 149 void removeChild(LatexDocument *doc); 150 bool containsChild(LatexDocument *doc) const; getMasterDocument()151 Q_INVOKABLE LatexDocument *getMasterDocument() const 152 { 153 return masterDocument; 154 } 155 const LatexDocument *getRootDocument(QSet<const LatexDocument *> *visitedDocs = nullptr) const; 156 Q_INVOKABLE LatexDocument *getRootDocument(); getTopMasterDocument()157 Q_INVOKABLE LatexDocument *getTopMasterDocument() 158 { 159 return getRootDocument(); // DEPRECATED: only the for backward compatibility of user scripts 160 } 161 162 Q_INVOKABLE QStringList includedFiles(); 163 Q_INVOKABLE QStringList includedFilesAndParent(); 164 Q_INVOKABLE QList<LatexDocument *> getListOfDocs(QSet<LatexDocument *> *visitedDocs = nullptr); 165 166 LatexParser ltxCommands, lp; 167 168 Q_INVOKABLE bool containsPackage(const QString &name); 169 Q_INVOKABLE QStringList containedPackages(); 170 Q_INVOKABLE QSet<QString> usedPackages(); 171 bool updateCompletionFiles(const bool forceUpdate,const bool forceLabelUpdate = false,const bool delayUpdate = false, const bool dontPatch = false ); 172 const QSet<QString> &getCWLFiles() const; 173 spellingDictName()174 Q_INVOKABLE QString spellingDictName() const 175 { 176 return mSpellingDictName; 177 } 178 Q_INVOKABLE QString getMagicComment(const QString &name) const; 179 Q_INVOKABLE StructureEntry *getMagicCommentEntry(const QString &name) const; 180 Q_INVOKABLE void updateMagicComment(const QString &name, const QString &val, bool createIfNonExisting = false, QString prefix="!TeX"); 181 182 void updateMagicCommentScripts(); 183 static bool splitMagicComment(const QString &comment, QString &name, QString &val); 184 185 QString findFileName(QString fname); 186 bool fileExits(QString fname); 187 188 void saveLineSnapshot(); 189 QDocumentLine lineFromLineSnapshot(int lineNumber); 190 int lineToLineSnapshotLineNumber(const QDocumentLine &line); 191 192 bool remeberAutoReload; //remember whether doc is auto reloaded while hidden (and auto reload is always activated). 193 194 bool mayHaveDiffMarkers; 195 196 void emitUpdateCompleter(); 197 198 static int syntaxErrorFormat,spellErrorFormat; 199 200 bool languageIsLatexLike() const; 201 void reCheckSyntax(int lineStart = 0, int lineNum = -1); 202 QString getErrorAt(QDocumentLineHandle *dlh, int pos, StackEnvironment previous, TokenStack stack); 203 204 void getEnv(int lineNumber, StackEnvironment &env); // get Environment for syntax checking, number of cols is now part of env 205 Q_INVOKABLE QString getLastEnvName(int lineNumber); // special function to use with javascript (insert "\item" from menu) 206 enableSyntaxCheck(bool enable)207 void enableSyntaxCheck(bool enable) 208 { 209 syntaxChecking = enable; 210 SynChecker.enableSyntaxCheck(enable); 211 } 212 213 private: 214 QString fileName; //absolute 215 QString temporaryFileName; //absolute, temporary 216 QFileInfo fileInfo; 217 218 LatexEditorView *edView; 219 220 LatexDocument *masterDocument; 221 QSet<LatexDocument *> childDocs; 222 223 StructureEntry *magicCommentList; 224 StructureEntry *labelList; 225 StructureEntry *todoList; 226 StructureEntry *bibTeXList; 227 StructureEntry *blockList; 228 229 QMultiHash<QDocumentLineHandle *, ReferencePair> mLabelItem; 230 QMultiHash<QDocumentLineHandle *, ReferencePair> mBibItem; 231 QMultiHash<QDocumentLineHandle *, ReferencePair> mRefItem; 232 QMultiHash<QDocumentLineHandle *, FileNamePair> mMentionedBibTeXFiles; 233 QMultiHash<QDocumentLineHandle *, UserCommandPair> mUserCommandList; 234 QMultiHash<QDocumentLineHandle *, QString> mUsepackageList; 235 QMultiHash<QDocumentLineHandle *, QString> mIncludedFilesList; 236 237 QList<QDocumentLineHandle *> mLineSnapshot; 238 239 QSet<QString> mCompleterWords; // local list of completer words 240 QSet<QString> mCWLFiles; 241 242 QString mSpellingDictName; 243 244 QString mClassOptions; // store class options, if they are defined in this doc 245 246 QDocumentLineHandle *mAppendixLine, *mBeyondEnd; 247 248 void updateContext(QDocumentLineHandle *oldLine, QDocumentLineHandle *newLine, StructureEntry::Context context); 249 void setContextForLines(StructureEntry *se, int startLine, int endLine, StructureEntry::Context context, bool state); 250 251 int findStructureParentPos(const QList<StructureEntry *> &children, QList<StructureEntry *> &removedElements, int linenr, int count); 252 253 bool IsInTree (StructureEntry *se); updateElementWithSignal(StructureEntry * se)254 void updateElementWithSignal(StructureEntry *se){ emit updateElement(se); } 255 void removeElementWithSignal(StructureEntry *se); 256 void addElementWithSignal(StructureEntry *parent, StructureEntry *se); 257 void insertElementWithSignal(StructureEntry *parent, int pos, StructureEntry *se); 258 void moveElementWithSignal(StructureEntry *se, StructureEntry *parent, int pos); 259 260 void addMagicComment(const QString &text, int lineNr, int posMagicComment); 261 void parseMagicComment(const QString &name, const QString &val, StructureEntry *se); 262 263 void gatherCompletionFiles(QStringList &files, QStringList &loadedFiles, LatexPackage &pck, bool gatherForCompleter = false); 264 265 SyntaxCheck SynChecker; 266 Environment unclosedEnv; 267 268 bool syntaxChecking; 269 270 #ifndef QT_NO_DEBUG 271 public: 272 QSet<StructureEntry *> StructureContent; 273 void checkForLeak(); 274 #endif 275 276 public slots: 277 void updateStructure(); 278 bool patchStructure(int linenr, int count, bool recheck = false); 279 void patchStructureRemoval(QDocumentLineHandle *dlh,int hint=-1); 280 void initClearStructure(); 281 void updateLtxCommands(bool updateAll = false); 282 void setLtxCommands(const LatexParser &cmds); 283 void setSpeller(SpellerUtility *speller); 284 void setReplacementList(QMap<QString,QString> replacementList); 285 void updateSettings(); 286 void checkNextLine(QDocumentLineHandle *dlh, bool clearOverlay, int ticket, int hint=-1); 287 288 signals: 289 void hasBeenIncluded(const LatexDocument &newMasterDocument); 290 void structureUpdated(LatexDocument *document, StructureEntry *highlight = nullptr); 291 void setHighlightedEntry(StructureEntry *highlight); 292 void structureLost(LatexDocument *document); 293 void removeElement(StructureEntry *se, int row); 294 void removeElementFinished(); 295 void addElement(StructureEntry *se, int row); 296 void addElementFinished(); 297 void updateElement(StructureEntry *se); 298 void updateCompleter(); 299 void updateBibTeXFiles(); 300 void toBeChanged(); 301 void importPackage(QString name); 302 void spellingDictChanged(const QString &name); 303 void encodingChanged(); 304 void bookmarkLineUpdated(int lineNr); 305 }; 306 //Q_DECLARE_METATYPE(LatexDocument *) 307 308 309 310 /*! \brief administrate all open documents 311 * organizes all open documents 312 * handles master/slave or root/child relation between documents 313 * documents can be hidden, i.e. they don't have a visible editor 314 * hidden documents are used to keep syntax information present in the editor without the necessesity to make an extra storage architecture for closed elements 315 * documents which are closed/deleted are hidden if they are child documents of still used documents 316 * Furthermore autimatically loaded documents are generally hidden 317 */ 318 class LatexDocuments: public QObject 319 { 320 Q_OBJECT 321 322 public: 323 //LatexDocumentsModel *model; ///< reference to latexmodel which generates the structure information for treeview 324 LatexDocument *masterDocument; ///< master/root document if it is set (in automatic mode ==NULL) 325 LatexDocument *currentDocument; ///< current edited document 326 QList<LatexDocument *> documents; ///< list of open documents 327 QList<LatexDocument *> hiddenDocuments; ///< list of open documents with no visible editor 328 329 LatexDocuments(); 330 331 void addDocument(LatexDocument *document, bool hidden = false); 332 void deleteDocument(LatexDocument *document, bool hidden = false, bool purge = false); 333 void move(int from, int to); 334 Q_INVOKABLE void setMasterDocument(LatexDocument *document); ///< explicitely set master document 335 Q_INVOKABLE LatexDocument *getCurrentDocument() const; 336 Q_INVOKABLE LatexDocument *getMasterDocument() const; ///< get explicit master if set 337 Q_INVOKABLE QList<LatexDocument *> getDocuments() const; ///< get all documents (visible&hidden) 338 339 Q_PROPERTY(LatexDocument *currentDocument READ getCurrentDocument) 340 Q_PROPERTY(LatexDocument *masterDocument READ getMasterDocument) 341 Q_PROPERTY(QList<LatexDocument *> documents READ getDocuments); //<- semicolon necessary due to qt bug 22992 342 343 Q_INVOKABLE LatexDocument *getRootDocumentForDoc(LatexDocument *doc = nullptr) const ; ///< no argument means current doc ... 344 345 Q_INVOKABLE QString getCurrentFileName() const; ///< returns the absolute file name of the current file or "" if none is opened 346 Q_INVOKABLE QString getCompileFileName() const; ///< returns the absolute file name of the file to be compiled (master or current) 347 Q_INVOKABLE QString getTemporaryCompileFileName() const; ///< returns the absolute file name of the file to be compiled (master or current) 348 Q_INVOKABLE QString getLogFileName() const; 349 Q_INVOKABLE QString getAbsoluteFilePath(const QString &relName, const QString &extension = "", const QStringList &additionalSearchPaths = QStringList()) const; 350 351 Q_INVOKABLE LatexDocument *findDocument(const QString &fileName, bool checkTemporaryNames = false) const; 352 Q_INVOKABLE LatexDocument *findDocument(const QDocument *qDoc) const; 353 Q_INVOKABLE LatexDocument *findDocumentFromName(const QString &fileName) const; 354 355 void reorder(const QList<LatexDocument *> &order); 356 357 void settingsRead(); 358 359 Q_INVOKABLE bool singleMode() const; 360 361 //support for included BibTeX-files 362 QMap<QString, BibTeXFileInfo> bibTeXFiles; ///< bibtex files loaded by txs 363 bool bibTeXFilesModified; ///< true if the BibTeX files were changed after the last compilation 364 QStringList mentionedBibTeXFiles; ///< bibtex files imported in the tex file (absolute after updateBibFiles) 365 //QSet<QString> bibItems; // direct defined bibitems 366 //QSet<QString> allBibTeXIds; 367 void updateBibFiles(bool updateFiles = true); 368 369 void updateMasterSlaveRelations(LatexDocument *doc, bool recheckRefs = true, bool updateCompleterNow = false); 370 371 bool showLineNumbersInStructure; 372 int indentationInStructure; 373 bool showCommentedElementsInStructure; 374 bool markStructureElementsBeyondEnd; 375 bool markStructureElementsInAppendix; 376 bool indentIncludesInStructure; //pointer! those above should be changed as well 377 378 379 QHash<QString, LatexPackage> cachedPackages; 380 void addDocToLoad(QString filename); 381 void removeDocs(QStringList removeIncludes); 382 void hideDocInEditor(LatexEditorView *edView); 383 QString findPackageByCommand(const QString command); 384 void enablePatch(const bool enable); 385 bool patchEnabled(); 386 void requestQNFAupdate(); 387 388 signals: 389 void masterDocumentChanged(LatexDocument *masterDocument); 390 void aboutToDeleteDocument(LatexDocument *document); 391 void docToLoad(QString filename); 392 void docToHide(LatexEditorView *edView); 393 void updateQNFA(); 394 395 private slots: 396 void bibTeXFilesNeedUpdate(); 397 398 public slots: 399 void lineGrammarChecked(LatexDocument *doc, QDocumentLineHandle *line, int lineNr, const QList<GrammarError> &errors); 400 void requestedClose(); 401 402 private: 403 bool m_patchEnabled; 404 }; 405 406 #endif // LATEXDOCUMENT_H 407