File indexing completed on 2024-04-14 15:17:36

0001 /*************************************************************************************
0002     begin                : Thu Jul 17 2003
0003     copyright            : (C) 2003 by Jeroen Wijnhout (Jeroen.Wijnhout@kdemail.net)
0004                                2007-2018 by Michel Ludwig (michel.ludwig@kdemail.net)
0005  *************************************************************************************/
0006 
0007 /***************************************************************************
0008  *                                                                         *
0009  *   This program is free software; you can redistribute it and/or modify  *
0010  *   it under the terms of the GNU General Public License as published by  *
0011  *   the Free Software Foundation; either version 2 of the License, or     *
0012  *   (at your option) any later version.                                   *
0013  *                                                                         *
0014  ***************************************************************************/
0015 
0016 // 2007-03-12 dani
0017 //  - use KileDocument::Extensions
0018 
0019 #include "kileinfo.h"
0020 
0021 #include <qwidget.h>
0022 #include <QFileInfo>
0023 #include <QObject>
0024 
0025 #include <ktexteditor/document.h>
0026 #include <ktexteditor/view.h>
0027 #include <KLocalizedString>
0028 #include <KMessageBox>
0029 
0030 #include "parser/parsermanager.h"
0031 #include "widgets/structurewidget.h"
0032 #include "configurationmanager.h"
0033 #include "editorcommands.h"
0034 #include "kiledocmanager.h"
0035 #include "kileviewmanager.h"
0036 #include "documentinfo.h"
0037 #include "kileproject.h"
0038 #include "scriptmanager.h"
0039 #include "abbreviationmanager.h"
0040 #include "editorkeysequencemanager.h"
0041 #include "templates.h"
0042 #include "utilities.h"
0043 #include "usermenu/usermenu.h"
0044 
0045 #include <QStringList>
0046 #include <QString>
0047 
0048 /*
0049  * Class KileInfo.
0050  */
0051 
0052 KileInfo::KileInfo(KParts::MainWindow *parent)
0053     : m_mainWindow(parent),
0054       m_configurationManager(Q_NULLPTR),
0055       m_docManager(Q_NULLPTR),
0056       m_viewManager(Q_NULLPTR),
0057       m_manager(Q_NULLPTR),
0058       m_templateManager(Q_NULLPTR),
0059       m_jScriptManager(Q_NULLPTR),
0060       m_editorKeySequenceManager(Q_NULLPTR),
0061       m_toolFactory(Q_NULLPTR),
0062       m_texKonsole(Q_NULLPTR),
0063       m_outputWidget(Q_NULLPTR),
0064       m_scriptsManagementWidget(Q_NULLPTR),
0065       m_bottomBar(Q_NULLPTR),
0066       m_previewWidget(Q_NULLPTR),
0067       m_previewScrollArea(Q_NULLPTR),
0068       m_codeCompletionManager(Q_NULLPTR),
0069       m_abbreviationManager(Q_NULLPTR),
0070       m_parserManager(Q_NULLPTR),
0071       m_errorHandler(Q_NULLPTR),
0072       m_editorCommands(Q_NULLPTR),
0073       m_help(Q_NULLPTR),
0074       m_edit(Q_NULLPTR),
0075       m_latexCommands(Q_NULLPTR),
0076       m_extensions(Q_NULLPTR),
0077       m_quickPreview(Q_NULLPTR),
0078       m_userMenu(Q_NULLPTR),
0079       m_livePreviewManager(Q_NULLPTR),
0080       m_kwStructure(Q_NULLPTR),
0081       m_fileBrowserWidget(Q_NULLPTR)
0082 {
0083     m_configurationManager = new KileConfiguration::Manager(this, parent, "KileConfiguration::Manager");
0084     m_docManager = new KileDocument::Manager(this, parent, "KileDocument::Manager");
0085     m_templateManager = new KileTemplate::Manager(this, parent, "KileTemplate::Manager");
0086     m_editorKeySequenceManager = new KileEditorKeySequence::Manager(this, parent, "KileEditorKeySequence::Manager");
0087     m_abbreviationManager = new KileAbbreviation::Manager(this, parent);
0088     m_parserManager = new KileParser::Manager(this, parent);
0089     m_editorCommands = new EditorCommands(this);
0090 }
0091 
0092 KileInfo::~KileInfo()
0093 {
0094     // this has to be deleted before the editor component is destroyed
0095     delete m_editorCommands;
0096 }
0097 
0098 KTextEditor::Document * KileInfo::activeTextDocument() const
0099 {
0100     KTextEditor::View *view = viewManager()->currentTextView();
0101     if (view) return view->document();
0102     else return Q_NULLPTR;
0103 }
0104 
0105 QString KileInfo::getName(KTextEditor::Document *doc, bool shrt) const
0106 {
0107     KILE_DEBUG_MAIN << "===KileInfo::getName(KTextEditor::Document *doc, bool " << shrt << ")===" << Qt::endl;
0108     QString title;
0109 
0110     if (!doc) {
0111         doc = activeTextDocument();
0112     }
0113     if (doc) {
0114         QUrl url = doc->url();
0115         KILE_DEBUG_MAIN << "url " << url << Qt::endl;
0116         if(url.isLocalFile()) {
0117             title = shrt ? doc->url().fileName() : doc->url().toLocalFile();
0118         }
0119         else {
0120             title = url.toDisplayString();
0121         }
0122     }
0123 
0124     return title;
0125 }
0126 
0127 LaTeXOutputHandler* KileInfo::findCurrentLaTeXOutputHandler() const
0128 {
0129     LaTeXOutputHandler *h = Q_NULLPTR;
0130 
0131     getCompileName(false, &h);
0132     return h;
0133 }
0134 
0135 QString KileInfo::getCompileName(bool shrt /* = false */, LaTeXOutputHandler** h /* = Q_NULLPTR */) const
0136 {
0137     KileProject *project = docManager()->activeProject();
0138 
0139     if (m_singlemode) {
0140         if (project) {
0141             if(h) {
0142                 *h = project;
0143             }
0144             return getCompileNameForProject(project, shrt);
0145         }
0146         else {
0147             KTextEditor::Document *doc = activeTextDocument();
0148             if(h) {
0149                 *h = dynamic_cast<KileDocument::LaTeXInfo*>(m_docManager->textInfoFor(doc));
0150             }
0151             return getName(doc, shrt);
0152         }
0153     }
0154     else {
0155         QFileInfo fi(m_masterDocumentFileName);
0156         if(h) {
0157             *h = dynamic_cast<KileDocument::LaTeXInfo*>(m_docManager->textInfoFor(m_masterDocumentFileName));
0158         }
0159         if(shrt) {
0160             return fi.fileName();
0161         }
0162         else {
0163             return m_masterDocumentFileName;
0164         }
0165     }
0166 }
0167 
0168 QString KileInfo::getCompileNameForProject(KileProject *project, bool shrt) const
0169 {
0170     if (!project->masterDocument().isEmpty()) {
0171         QUrl master = QUrl::fromLocalFile(project->masterDocument());
0172         if(shrt) {
0173             return master.fileName();
0174         }
0175         else {
0176             return master.toLocalFile();
0177         }
0178     }
0179     else {
0180         KileProjectItem *item = project->rootItem(docManager()->activeProjectItem());
0181         if (item) {
0182             QUrl url = item->url();
0183             if(shrt) {
0184                 return url.fileName();
0185             }
0186             else {
0187                 return url.toLocalFile();
0188             }
0189         }
0190         else {
0191             return QString();
0192         }
0193     }
0194 }
0195 
0196 QString KileInfo::getFullFromPrettyName(const OutputInfo& info, const QString& name) const
0197 {
0198     if(name.isEmpty()) {
0199         return name;
0200     }
0201 
0202     QString file = name;
0203 
0204     if(file.left(2) == "./") {
0205         file = QFileInfo(info.mainSourceFile()).absolutePath() + '/' + file.mid(2);
0206     }
0207 
0208     if(QDir::isRelativePath(file)) {
0209         file = QFileInfo(info.mainSourceFile()).absolutePath() + '/' + file;
0210     }
0211 
0212     QFileInfo fi(file);
0213     if(file.isEmpty() || fi.isDir() || (! fi.exists()) || (! fi.isReadable())) {
0214         // - call from logwidget or error handling, which
0215         //   tries to determine the LaTeX source file
0216         bool found = false;
0217         QStringList extlist = (m_extensions->latexDocuments()).split(' ');
0218         for(QStringList::Iterator it=extlist.begin(); it!=extlist.end(); ++it) {
0219             QString extName = file + (*it);
0220             if(QFileInfo::exists(extName)) {
0221                 file = extName;
0222                 fi.setFile(extName);
0223                 found = true;
0224                 break;
0225             }
0226         }
0227         if(!found) {
0228             file.clear();
0229         }
0230     }
0231 
0232     if(!fi.isReadable()) {
0233         return QString();
0234     }
0235 
0236     return file;
0237 }
0238 
0239 QList<QUrl> KileInfo::getParentsFor(KileDocument::Info *info)
0240 {
0241     QList<KileProjectItem*> items = docManager()->itemsFor(info);
0242     QList<QUrl> list;
0243     for(QList<KileProjectItem*>::iterator it = items.begin(); it != items.end(); ++it) {
0244         if((*it)->parent()) {
0245             list.append((*it)->parent()->url());
0246         }
0247     }
0248     return list;
0249 }
0250 
0251 QStringList KileInfo::retrieveList(QStringList (KileDocument::Info::*getit)() const, KileDocument::TextInfo *docinfo)
0252 {
0253     if(!docinfo) {
0254         docinfo = docManager()->getInfo();
0255     }
0256     KileProjectItem *item = docManager()->itemFor(docinfo, docManager()->activeProject());
0257 
0258     KILE_DEBUG_MAIN << "Kile::retrieveList()";
0259     if (item) {
0260         KileProject *project = item->project();
0261         KileProjectItem *root = project->rootItem(item);
0262         if (root) {
0263             KILE_DEBUG_MAIN << "\tusing root item " << root->url().fileName();
0264 
0265             QList<KileProjectItem*> children;
0266             children.append(root);
0267             root->allChildren(&children);
0268 
0269             QStringList toReturn;
0270             for(QList<KileProjectItem*>::iterator it = children.begin(); it != children.end(); ++it) {
0271                 const KileProjectItem *childItem = *it;
0272                 KileDocument::TextInfo *textInfo = childItem->getInfo();
0273                 KILE_DEBUG_MAIN << "\t" << childItem->url();
0274 
0275                 if(textInfo) {
0276                     toReturn << (textInfo->*getit)();
0277                 }
0278             }
0279             return toReturn;
0280         }
0281         else {
0282             return QStringList();
0283         }
0284     }
0285     else if (docinfo) {
0286         return (docinfo->*getit)();
0287     }
0288     else {
0289         return QStringList();
0290     }
0291 }
0292 
0293 QStringList KileInfo::allLabels(KileDocument::TextInfo *info)
0294 {
0295     KILE_DEBUG_MAIN << "Kile::allLabels()" << Qt::endl;
0296     return retrieveList(&KileDocument::Info::labels, info);
0297 }
0298 
0299 QStringList KileInfo::allBibItems(KileDocument::TextInfo *info)
0300 {
0301     KILE_DEBUG_MAIN << "Kile::allBibItems()" << Qt::endl;
0302     return retrieveList(&KileDocument::Info::bibItems, info);
0303 }
0304 
0305 QStringList KileInfo::allBibliographies(KileDocument::TextInfo *info)
0306 {
0307     KILE_DEBUG_MAIN << "Kile::bibliographies()" << Qt::endl;
0308     return retrieveList(&KileDocument::Info::bibliographies, info);
0309 }
0310 
0311 QStringList KileInfo::allDependencies(KileDocument::TextInfo *info)
0312 {
0313     KILE_DEBUG_MAIN << "Kile::dependencies()" << Qt::endl;
0314     return retrieveList(&KileDocument::Info::dependencies, info);
0315 }
0316 
0317 QStringList KileInfo::allNewCommands(KileDocument::TextInfo *info)
0318 {
0319     KILE_DEBUG_MAIN << "Kile::newCommands()" << Qt::endl;
0320     return retrieveList(&KileDocument::Info::newCommands, info);
0321 }
0322 
0323 QStringList KileInfo::allAsyFigures(KileDocument::TextInfo *info)
0324 {
0325     KILE_DEBUG_MAIN << "Kile::asyFigures()" << Qt::endl;
0326     return retrieveList(&KileDocument::Info::asyFigures, info);
0327 }
0328 
0329 QStringList KileInfo::allPackages(KileDocument::TextInfo *info)
0330 {
0331     KILE_DEBUG_MAIN << "Kile::allPackages()" << Qt::endl;
0332     return retrieveList(&KileDocument::Info::packages, info);
0333 }
0334 
0335 QString KileInfo::lastModifiedFile(KileDocument::TextInfo* info)
0336 {
0337     if(!info) {
0338         info = docManager()->getInfo();
0339     }
0340     QStringList list = allDependencies(info);
0341     QFileInfo fileinfo(info->url().toLocalFile());
0342     list.append(fileinfo.fileName());
0343 
0344     return KileUtilities::lastModifiedFile(list, fileinfo.absolutePath());
0345 }
0346 
0347 QString KileInfo::documentTypeToString(KileDocument::Type type)
0348 {
0349     switch(type) {
0350     case KileDocument::Undefined:
0351         return i18n("Undefined");
0352     case KileDocument::Text:
0353         return i18n("Text");
0354     case KileDocument::LaTeX:
0355         return i18n("LaTeX");
0356     case KileDocument::BibTeX:
0357         return i18n("BibTeX");
0358     case KileDocument::Script:
0359         return i18n("Script");
0360     }
0361     return QString();
0362 }
0363 
0364 bool KileInfo::similarOrEqualURL(const QUrl &validurl, const QUrl &testurl)
0365 {
0366     if ( testurl.isEmpty() || testurl.path().isEmpty() ) return false;
0367 
0368 
0369     bool absolute = QDir::isAbsolutePath(testurl.toLocalFile());
0370     return (
0371                (validurl == testurl) ||
0372                (!absolute && validurl.path().endsWith(testurl.path()))
0373            );
0374 }
0375 
0376 bool KileInfo::isOpen(const QUrl &url)
0377 {
0378     KILE_DEBUG_MAIN << "==bool KileInfo::isOpen(const QUrl &url)=============" << Qt::endl;
0379 
0380     for (int i = 0; i < viewManager()->textViewCount(); ++i) {
0381         KTextEditor::View *view = viewManager()->textView(i);
0382         if (view->document() && similarOrEqualURL(view->document()->url(), url)) {
0383             return true;
0384         }
0385     }
0386 
0387     return false;
0388 }
0389 
0390 bool KileInfo::projectIsOpen(const QUrl &url)
0391 {
0392     KileProject *project = docManager()->projectFor(url);
0393 
0394     return project != 0 ;
0395 }
0396 
0397 
0398 QString KileInfo::getSelection() const
0399 {
0400     KTextEditor::View *view = viewManager()->currentTextView();
0401 
0402     if (view && view->selection()) {
0403         return view->selectionText();
0404     }
0405 
0406     return QString();
0407 }
0408 
0409 void KileInfo::clearSelection() const
0410 {
0411     KTextEditor::View *view = viewManager()->currentTextView();
0412 
0413     if(view && view->selection()) {
0414         view->removeSelectionText();
0415     }
0416 }
0417 
0418 QString KileInfo::expandEnvironmentVars(const QString &str)
0419 {
0420     static QRegExp reEnvVars("\\$(\\w+)");
0421     QString result = str;
0422     int index = -1;
0423     while ( (index = str.indexOf(reEnvVars, index + 1)) != -1 )
0424         result.replace(reEnvVars.cap(0),qgetenv(reEnvVars.cap(1).toLocal8Bit()));
0425 
0426     return result;
0427 }
0428 
0429 QString KileInfo::checkOtherPaths(const QString &path,const QString &file, int type)
0430 {
0431     KILE_DEBUG_MAIN << "QString KileInfo::checkOtherPaths(const QString &path,const QString &file, int type)" << Qt::endl;
0432     QStringList inputpaths;
0433     QString configpaths;
0434     QFileInfo info;
0435 
0436     switch(type)
0437     {
0438     case bibinputs:
0439         configpaths = KileConfig::bibInputPaths() + LIST_SEPARATOR + "$BIBINPUTS";
0440         break;
0441     case texinputs:
0442         configpaths = KileConfig::teXPaths() + LIST_SEPARATOR + "$TEXINPUTS";
0443         break;
0444     case bstinputs:
0445         configpaths = KileConfig::bstInputPaths() + LIST_SEPARATOR + "$BSTINPUTS";
0446         break;
0447     default:
0448         KILE_DEBUG_MAIN << "Unknown type in checkOtherPaths" << Qt::endl;
0449         return QString();
0450         break;
0451     }
0452 
0453     inputpaths = expandEnvironmentVars(configpaths).split(LIST_SEPARATOR);
0454     inputpaths.prepend(path);
0455 
0456     // the first match is supposed to be the correct one
0457     foreach(const QString &string, inputpaths) {
0458         KILE_DEBUG_MAIN << "path is " << string << "and file is " << file << Qt::endl;
0459         info.setFile(string + '/' + file);
0460         if(info.exists()) {
0461             KILE_DEBUG_MAIN << "filepath after correction is: " << info.path() << Qt::endl;
0462             return info.absoluteFilePath();
0463         }
0464     }
0465     return QString();
0466 }
0467