Warning, file /office/kile/src/parser/parsermanager.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /**************************************************************************
0002 *   Copyright (C) 2011-2014 by Michel Ludwig (michel.ludwig@kdemail.net)  *
0003 ***************************************************************************/
0004 
0005 /***************************************************************************
0006  *                                                                         *
0007  *   This program is free software; you can redistribute it and/or modify  *
0008  *   it under the terms of the GNU General Public License as published by  *
0009  *   the Free Software Foundation; either version 2 of the License, or     *
0010  *   (at your option) any later version.                                   *
0011  *                                                                         *
0012  ***************************************************************************/
0013 
0014 #include "parsermanager.h"
0015 
0016 #include "documentinfo.h"
0017 #include "errorhandler.h"
0018 #include "kiledocmanager.h"
0019 #include "kileinfo.h"
0020 #include "kiletool_enums.h"
0021 #include "latexoutputparser.h"
0022 #include "parserthread.h"
0023 #include "widgets/logwidget.h"
0024 
0025 namespace KileParser {
0026 
0027 Manager::Manager(KileInfo *info, QObject *parent) :
0028     QObject(parent),
0029     m_ki(info)
0030 {
0031     qCDebug(LOG_KILE_PARSER);
0032     m_documentParserThread = new DocumentParserThread(m_ki, this);
0033     // we have to make this connection 'blocking' to ensure that when 'ParserThread::isDocumentParsingComplete()'
0034     // returns true, all document info objects have been passed the information obtained from parsing already
0035     connect(m_documentParserThread, SIGNAL(parsingComplete(QUrl,KileParser::ParserOutput*)),
0036             m_ki->docManager(), SLOT(handleParsingComplete(QUrl,KileParser::ParserOutput*)), Qt::BlockingQueuedConnection);
0037     // the next two can't be made 'blocking' as they are emitted when a mutex is held
0038     connect(m_documentParserThread, SIGNAL(parsingQueueEmpty()),
0039             this, SIGNAL(documentParsingComplete()), Qt::QueuedConnection);
0040     connect(m_documentParserThread, SIGNAL(parsingStarted()),
0041             this, SIGNAL(documentParsingStarted()), Qt::QueuedConnection);
0042     m_documentParserThread->start();
0043 
0044     m_outputParserThread = new OutputParserThread(m_ki, this);
0045     connect(m_outputParserThread, SIGNAL(parsingComplete(QUrl,KileParser::ParserOutput*)),
0046             this, SLOT(handleOutputParsingComplete(QUrl,KileParser::ParserOutput*)), Qt::QueuedConnection);
0047     m_outputParserThread->start();
0048 }
0049 
0050 
0051 Manager::~Manager()
0052 {
0053     qCDebug(LOG_KILE_PARSER) << "destroying...";
0054     m_documentParserThread->stopParsing();
0055     m_outputParserThread->stopParsing();
0056 }
0057 
0058 void Manager::parseDocument(KileDocument::TextInfo* textInfo)
0059 {
0060     qCDebug(LOG_KILE_PARSER) << textInfo;
0061     m_documentParserThread->addDocument(textInfo);
0062 }
0063 
0064 void Manager::parseOutput(KileTool::Base *tool, const QString& fileName, const QString& sourceFile,
0065                           const QString& texFileName, int selrow, int docrow)
0066 {
0067     qCDebug(LOG_KILE_PARSER) << fileName << sourceFile;
0068     m_outputParserThread->addLaTeXLogFile(fileName, sourceFile, texFileName, selrow, docrow);
0069     connect(tool, SIGNAL(aboutToBeDestroyed(KileTool::Base*)),
0070             this, SLOT(removeToolFromUrlHash(KileTool::Base*)), Qt::UniqueConnection);
0071 
0072     // using 'fileName' directly is tricky as it might contain occurrences of '//' which are filtered out
0073     // by QUrl (given as argument in 'handleOutputParsingComplete') and the matching won't work anymore;
0074     // so we use QUrl already here
0075     const QUrl url = QUrl::fromLocalFile(fileName);
0076     if(!m_urlToToolHash.contains(url, tool)) {
0077         m_urlToToolHash.insert(url, tool);
0078     }
0079 }
0080 
0081 bool Manager::isDocumentParsingComplete()
0082 {
0083     return m_documentParserThread->isParsingComplete();
0084 }
0085 
0086 void Manager::stopDocumentParsing(const QUrl &url)
0087 {
0088     m_documentParserThread->removeDocument(url);
0089 }
0090 
0091 void Manager::handleOutputParsingComplete(const QUrl &url, KileParser::ParserOutput *output)
0092 {
0093     qCDebug(LOG_KILE_PARSER) << url;
0094     QList<KileTool::Base*> toolList = m_urlToToolHash.values(url);
0095     m_urlToToolHash.remove(url);
0096 
0097     LaTeXOutputParserOutput *latexOutput = dynamic_cast<LaTeXOutputParserOutput*>(output);
0098     if(!latexOutput) {
0099         qCDebug(LOG_KILE_PARSER) << "Q_NULLPTR output given";
0100         return;
0101     }
0102     if(toolList.isEmpty()) { // no tool was found, which means that all the tools for 'url'
0103         return;          // have been killed and we do nothing
0104     }
0105     if(!latexOutput->problem.isEmpty()) {
0106         m_ki->errorHandler()->printProblem(KileTool::Warning, latexOutput->problem);
0107         return;
0108     }
0109     // use the returned list as the new global error information list
0110     m_ki->errorHandler()->setMostRecentLogInformation(latexOutput->logFile, latexOutput->infoList);
0111     // finally, inform the tools waiting for the error information
0112     for(KileTool::Base *tool : toolList) {
0113         tool->installLaTeXOutputParserResult(latexOutput->nErrors, latexOutput->nWarnings,
0114                                              latexOutput->nBadBoxes,
0115                                              latexOutput->infoList,
0116                                              latexOutput->logFile);
0117     }
0118 }
0119 
0120 void Manager::removeToolFromUrlHash(KileTool::Base *tool)
0121 {
0122     QMultiHash<QUrl, KileTool::Base*>::iterator i = m_urlToToolHash.begin();
0123     while(i != m_urlToToolHash.end()) {
0124         const QUrl url = i.key();
0125         if(i.value() == tool) {
0126             i = m_urlToToolHash.erase(i);
0127             // any more mappings for 'url' -> 'tool' left?
0128             if(!m_urlToToolHash.contains(url)) {
0129                 m_outputParserThread->removeFile(url.toLocalFile());
0130             }
0131         }
0132         else {
0133             ++i;
0134         }
0135     }
0136 }
0137 
0138 }
0139