File indexing completed on 2024-04-21 05:03:23

0001 /**********************************************************************************************
0002     Copyright (C) 2004-2012 by Holger Danielsson (holger.danielsson@versanet.de)
0003               (C) 2019 by Michel Ludwig (michel.ludwig@kdemail.net)
0004  **********************************************************************************************/
0005 
0006 /***************************************************************************
0007  *                                                                         *
0008  *   This program is free software; you can redistribute it and/or modify  *
0009  *   it under the terms of the GNU General Public License as published by  *
0010  *   the Free Software Foundation; either version 2 of the License, or     *
0011  *   (at your option) any later version.                                   *
0012  *                                                                         *
0013  ***************************************************************************/
0014 
0015 #include "kilehelp.h"
0016 #include <QDir>
0017 #include <QFileInfo>
0018 #include <QTextStream>
0019 
0020 #include "editorextension.h"
0021 #include "errorhandler.h"
0022 #include "kiledebug.h"
0023 #include "kiletool_enums.h"
0024 #include "kiletoolmanager.h"
0025 #include "kileviewmanager.h"
0026 #include "kileinfo.h"
0027 #include "dialogs/texdocumentationdialog.h"
0028 #include "kileconfig.h"
0029 #include "utilities.h"
0030 
0031 namespace KileHelp
0032 {
0033 
0034 Help::Help(KileDocument::EditorExtension *edit, QWidget *mainWindow) : m_mainWindow(mainWindow), m_edit(edit), m_userhelp(Q_NULLPTR)
0035 {
0036     m_helpDir = KileUtilities::locate(QStandardPaths::AppDataLocation, QLatin1String("help/"), QStandardPaths::LocateDirectory); // this must end in '/'
0037     KILE_DEBUG_MAIN << "help dir: " << m_helpDir;
0038 
0039     m_kileReference = m_helpDir + "latexhelp.html";
0040     m_latex2eReference =  m_helpDir + QLatin1String("unofficial-latex2e-reference-manual/");
0041 
0042     m_contextHelpType = contextHelpType();
0043     initContextHelp();
0044 }
0045 
0046 Help::~Help()
0047 {
0048     delete m_userhelp;
0049 }
0050 
0051 void Help::initContextHelp()
0052 {
0053     // read a list with keywords for context help
0054     if(m_contextHelpType == HelpKileRefs) {
0055         readHelpList("latex-kile.lst");
0056     }
0057     else if(m_contextHelpType == HelpLatex2eRefs) {
0058         readHelpList("unofficial-latex2e-reference-manual.index");
0059     }
0060 }
0061 
0062 ////////////////////// update paths and context help of TeX documentation  //////////////////////
0063 
0064 void Help::update()
0065 {
0066     HelpType contextHelp = contextHelpType();
0067     if(m_contextHelpType != contextHelp) {
0068         m_contextHelpType = contextHelp;
0069         initContextHelp();
0070     }
0071 }
0072 
0073 ////////////////////// set parameter/initialize user help //////////////////////
0074 
0075 void Help::setUserhelp(KileTool::Manager *manager, KActionMenu *userHelpActionMenu)
0076 {
0077     m_manager = manager;
0078     m_userhelp = new UserHelp(manager, userHelpActionMenu, m_mainWindow);
0079 }
0080 
0081 void Help::enableUserhelpEntries(bool state)
0082 {
0083     if(m_userhelp) {
0084         m_userhelp->enableUserHelpEntries(state);
0085     }
0086 }
0087 ////////////////////// show help //////////////////////
0088 
0089 void Help::showHelpFile(const QString &parameter)
0090 {
0091     KILE_DEBUG_MAIN << "--------------------------------------------> help file: " << parameter;
0092     KileTool::Base *tool = m_manager->createTool("ViewHTML", QString(), false);
0093     if(!tool) {
0094         return;
0095     }
0096     tool->setFlags(KileTool::NeedSourceExists | KileTool::NeedSourceRead);
0097     //FIXME strip the #label part of the source (not the target),
0098     //somehow this is already done somewhere (by accident),
0099     //bad to rely on it
0100     tool->setMsg(KileTool::NeedSourceExists, ki18n("Could not find the LaTeX documentation at %1; please set the correct path in Settings->Configure Kile->Help."));
0101     tool->setSource(parameter);
0102     tool->setTargetPath(parameter);
0103     tool->prepareToRun();
0104     m_manager->run(tool);
0105 }
0106 
0107 void Help::helpKeyword()
0108 {
0109     //FIXME: we should have a better way to access the current view
0110     helpKeyword(m_manager->info()->viewManager()->currentTextView());
0111 }
0112 
0113 ////////////////////// Help: TexDoc //////////////////////
0114 
0115 void Help::helpDocBrowser()
0116 {
0117     KileDialog::TexDocDialog *dlg = new KileDialog::TexDocDialog();
0118     dlg->exec();
0119     delete dlg;
0120 }
0121 
0122 ////////////////////// Help: LaTeX //////////////////////
0123 
0124 void Help::helpLatex(HelpType type)
0125 {
0126     switch(type) {
0127         case HelpLatexIndex:
0128             showHelpFile(m_latex2eReference + QLatin1String("index.html"));
0129             break;
0130         case HelpLatexCommand:
0131             showHelpFile(m_latex2eReference + QLatin1String("IndexDocument.html#Index_cp_symbol-8"));
0132             break;
0133         case HelpLatexEnvironment:
0134             showHelpFile(m_latex2eReference + QLatin1String("Environments.html#Environments"));
0135             break;
0136         default:
0137             return;
0138     }
0139 }
0140 
0141 ////////////////////// Help: Keyword //////////////////////
0142 
0143 // Context help: user either current TexLive's Latex2e help, TexLive's older tex-refs help or Kile LaTeX help
0144 void Help::helpKeyword(KTextEditor::View *view)
0145 {
0146     QString word = getKeyword(view);
0147     KILE_DEBUG_MAIN << "keyword: " << word;
0148 
0149     if(!m_helpDir.isEmpty() && !word.isEmpty() && m_dictHelpTex.contains(word)) {
0150         KILE_DEBUG_MAIN << "about to show help for '" << word << "' (section " << m_dictHelpTex[word] << " )";
0151 
0152         if(m_contextHelpType == HelpLatex2eRefs) {
0153             showHelpFile(m_latex2eReference + m_dictHelpTex[word]);
0154         }
0155         else if ( m_contextHelpType == HelpKileRefs ) {
0156             showHelpFile(m_kileReference + '#' + m_dictHelpTex[word]);
0157         }
0158     }
0159     else {
0160         noHelpAvailableFor(word);
0161     }
0162 }
0163 
0164 void Help::noHelpAvailableFor(const QString &word)
0165 {
0166     m_manager->info()->errorHandler()->printMessage(KileTool::Error, i18n("No help available for %1.", word), i18n("Help"));
0167 }
0168 
0169 QString Help::getKeyword(KTextEditor::View *view)
0170 {
0171     if(!view) {
0172         return QString();
0173     }
0174 
0175     // get current position
0176     int row, col, col1, col2;
0177     QString word;
0178     KTextEditor::Document *doc = view->document();
0179     KTextEditor::Cursor cursor = view->cursorPosition();
0180     row = cursor.line();
0181     col = cursor.column();
0182 
0183     if (m_edit->getCurrentWord(doc, row, col, KileDocument::EditorExtension::smTex, word, col1, col2)) {
0184         // There is no starred keyword in the references. So if     // dani 04.08.2004
0185         // we find one, we better try the unstarred keyword.
0186         if(word.right(1) == "*") {
0187             return word.left(word.length() - 1);
0188         }
0189         else {
0190             return word;
0191         }
0192     }
0193     else {
0194         return QString();
0195     }
0196 }
0197 
0198 HelpType Help::contextHelpType()
0199 {
0200     if ( KileConfig::latex2erefs() ) {
0201         return HelpLatex2eRefs;
0202     }
0203     else {
0204         return HelpKileRefs;
0205     }
0206 }
0207 
0208 //////////////////// read help lists ////////////////////
0209 
0210 void Help::readHelpList(const QString &filename)
0211 {
0212     // clear old map
0213     m_dictHelpTex.clear();
0214 
0215     QString file = m_helpDir + filename;
0216     if(file.isEmpty()) {
0217         KILE_DEBUG_MAIN << "   file not found: " << filename << Qt::endl;
0218         return;
0219     }
0220 
0221     KILE_DEBUG_MAIN << "read keyword file: " << file;
0222     QRegExp reg("\\s*(\\S+)\\s*\\t\\s*(\\S+)");
0223 
0224     QFile f(file);
0225     if(f.open(QIODevice::ReadOnly)) { // file opened successfully
0226         QTextStream t(&f);         // use a text stream
0227         while(!t.atEnd()) { // until end of file...
0228             QString s = t.readLine().trimmed();       // line of text excluding '\n'
0229             if(!(s.isEmpty() || s.at(0)=='#')) {
0230                 int pos = reg.indexIn(s);
0231                 if(pos != -1) {
0232                     m_dictHelpTex[reg.cap(1)] = reg.cap(2);
0233                 }
0234             }
0235         }
0236         f.close();
0237     }
0238 }
0239 
0240 }
0241