File indexing completed on 2024-05-05 17:15:08

0001 /*************************************************************************************
0002   Copyright (C) 2004 by Jeroen Wijnhout (Jeroen.Wijnhout@kdemail.net)
0003                 2012-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 "dialogs/configcheckerdialog.h"
0016 
0017 #include <QFileInfo>
0018 #include <QItemDelegate>
0019 #include <QLabel>
0020 #include <QLayout>
0021 #include <QPainter>
0022 #include <QProgressDialog>
0023 #include <QPushButton>
0024 #include <QTextDocument>
0025 
0026 #include <KConfigGroup>
0027 #include <KLocalizedString>
0028 #include <KMessageBox>
0029 
0030 #include <config.h>
0031 #include "kiledebug.h"
0032 #include "kileinfo.h"
0033 
0034 namespace KileDialog
0035 {
0036 
0037 class ResultItemDelegate : public QItemDelegate {
0038 public:
0039     ResultItemDelegate(QListWidget *parent) : QItemDelegate(parent) {}
0040 
0041     virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
0042     {
0043         painter->save();
0044         drawBackground(painter, option, index);
0045 
0046         QTextDocument document;
0047         document.setHtml(index.data(Qt::UserRole).toString());
0048         painter->resetTransform();
0049         painter->translate(option.rect.topLeft());
0050         document.drawContents(painter);
0051         painter->restore();
0052     }
0053 
0054     virtual QSize sizeHint(const QStyleOptionViewItem& /* option */, const QModelIndex &index) const override
0055     {
0056         QTextDocument document;
0057         document.setHtml(index.data(Qt::UserRole).toString());
0058         return document.size().toSize();
0059     }
0060 };
0061 
0062 ResultItem::ResultItem(QListWidget *listWidget, const QString &toolGroup, int status, bool isCritical, const QList<ConfigTest*> &tests)
0063     : QListWidgetItem(listWidget)
0064 {
0065     QString rt = "<hr /><b><font color=\"%1\">%2</font></b> (%3)<br /><ul>";
0066     for (int i = 0; i < tests.count(); ++i) {
0067         QString itemcolor = "black";
0068         if (tests[i]->status() == ConfigTest::Failure) {
0069             if (tests[i]->isCritical()) {
0070                 itemcolor = "#AA0000";
0071             }
0072             else {
0073                 itemcolor = "#FFA201";
0074             }
0075         }
0076         rt += QString("<li><b><font color=\"%1\">%2</font></b>: &nbsp;%3</li>").arg(itemcolor, tests[i]->name(), tests[i]->resultText());
0077     }
0078     rt += "</ul>";
0079 
0080     QString color = "#00AA00", statustr = i18n("Passed");
0081     if(status == ConfigTest::Failure) {
0082         if(isCritical) {
0083             color = "#AA0000";
0084             statustr = i18n("Critical failure, Kile will not function properly");
0085         }
0086         else {
0087             color = "#FFA201";
0088             statustr = i18n("Failed, but not critical");
0089         }
0090     }
0091 
0092     setData(Qt::UserRole, rt.arg(color, toolGroup, statustr));
0093 
0094     //this is for sorting only
0095     setText(QString::number(status) + ':' + toolGroup);
0096 }
0097 
0098 ConfigChecker::ConfigChecker(KileInfo *kileInfo, QWidget* parent)
0099     : KAssistantDialog(parent)
0100     , m_ki(kileInfo)
0101     , m_tester(Q_NULLPTR)
0102 {
0103     // don't show the 'help' button in the title bar
0104     setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
0105     setWindowTitle(i18n("System Check"));
0106     setModal(true);
0107     setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
0108     #ifdef Q_OS_WIN
0109     setContentsMargins(6, 6, 6, 6);
0110     #endif
0111 
0112     QWidget *introWidget = new QWidget(this);
0113     QLabel *label = new QLabel(i18n("<p>This configuration assistant will check whether your system is set up "
0114                                     "correctly to process LaTeX documents. It will also allow to fine-tune the configuration "
0115                                     "of Kile while taking the results of the tests into account.</p>"
0116                                     "<p>It is recommended to run this assistant before using Kile for the first time.</p>"
0117                                     "<p>Please press 'Next' now to start the test procedure.</p>"));
0118     label->setWordWrap(true);
0119     QVBoxLayout *vboxLayout = new QVBoxLayout();
0120     vboxLayout->setSizeConstraint(QLayout::SetMinimumSize);
0121     introWidget->setLayout(vboxLayout);
0122     vboxLayout->addWidget(label);
0123     vboxLayout->addStretch();
0124     m_introPageWidgetItem = addPage(introWidget, i18n("System Check & Configuration Assistant"));
0125 
0126     QWidget *runningTestsWidget = new QWidget(this);
0127     label = new QLabel(i18n("Checking whether the system is set up correctly..."));
0128     vboxLayout = new QVBoxLayout();
0129     vboxLayout->setSizeConstraint(QLayout::SetMinimumSize);
0130     runningTestsWidget->setLayout(vboxLayout);
0131     vboxLayout->addStretch();
0132     vboxLayout->addWidget(label);
0133     m_progressBar = new QProgressBar(this);
0134     vboxLayout->addWidget(m_progressBar);
0135     vboxLayout->addStretch();
0136     m_runningTestsPageWidgetItem = addPage(runningTestsWidget, "");
0137 
0138     QWidget *testResultsWidget = new QWidget(this);
0139     vboxLayout = new QVBoxLayout();
0140     vboxLayout->setSizeConstraint(QLayout::SetMinimumSize);
0141     testResultsWidget->setLayout(vboxLayout);
0142     m_listWidget = new QListWidget(this);
0143     m_listWidget->setMinimumHeight(200);
0144     vboxLayout->addWidget(m_listWidget);
0145     m_overallResultLabel = new QLabel(this);
0146     vboxLayout->addWidget(m_overallResultLabel);
0147     m_useEmbeddedViewerCheckBox = new QCheckBox(i18n("Configure the viewer tools to use the document viewer"));
0148     vboxLayout->addWidget(m_useEmbeddedViewerCheckBox);
0149     m_useModernConfigurationForLaTeXCheckBox = new QCheckBox(i18n("Use the 'modern' configuration for the TeX, PDFTeX, and LaTeX tools"));
0150     vboxLayout->addWidget(m_useModernConfigurationForLaTeXCheckBox);
0151     m_useModernConfigurationForPDFLaTeX = new QCheckBox(i18n("Use the 'modern' configuration for the PDFLaTeX, LuaLaTeX and XeLaTeX tools"));
0152     vboxLayout->addWidget(m_useModernConfigurationForPDFLaTeX);
0153     vboxLayout->addWidget(new QLabel(i18n("<br/>Please press 'Finish' now to accept the recommended configuration changes.")));
0154     vboxLayout->addStretch();
0155 
0156     m_testResultsPageWidgetItem = addPage(testResultsWidget, i18n("Test Results"));
0157 
0158     finishButton()->setVisible(false);
0159     backButton()->setVisible(false);
0160     buttonBox()->button(QDialogButtonBox::Help)->setVisible(false);
0161 
0162     m_listWidget->setAlternatingRowColors(true);
0163     m_listWidget->setSelectionMode(QAbstractItemView::NoSelection);
0164     m_listWidget->setItemDelegate(new ResultItemDelegate(m_listWidget));
0165 }
0166 
0167 ConfigChecker::~ConfigChecker()
0168 {
0169 }
0170 
0171 void ConfigChecker::next()
0172 {
0173     setCurrentPage(m_runningTestsPageWidgetItem);
0174     nextButton()->setEnabled(false);
0175     run();
0176 }
0177 
0178 void ConfigChecker::run()
0179 {
0180     m_tester = new Tester(m_ki, this);
0181 
0182     connect(m_tester, SIGNAL(started()), this, SLOT(started()));
0183     connect(m_tester, SIGNAL(percentageDone(int)), this, SLOT(setPercentageDone(int)));
0184     connect(m_tester, SIGNAL(finished(bool)), this, SLOT(finished(bool)));
0185     connect(finishButton(), SIGNAL(clicked()), this, SLOT(assistantFinished()));
0186 
0187     m_tester->runTests();
0188 }
0189 
0190 void ConfigChecker::slotCancel()
0191 {
0192     finished(false);
0193     reject();
0194 }
0195 
0196 void ConfigChecker::started()
0197 {
0198     setCursor(Qt::BusyCursor);
0199     setPercentageDone(0);
0200 }
0201 
0202 void ConfigChecker::finished(bool ok)
0203 {
0204     setCurrentPage(m_testResultsPageWidgetItem);
0205     setCursor(Qt::ArrowCursor);
0206 
0207     nextButton()->setVisible(false);
0208     finishButton()->setVisible(true);
0209 
0210     QStringList tools = m_tester->testGroups();
0211     QStringList critical, failure;
0212     for (int i = 0; i < tools.count(); ++i) {
0213         bool isCritical = false;
0214         int status = m_tester->statusForGroup(tools[i], &isCritical);
0215         if (status == ConfigTest::Failure) {
0216             if(isCritical) {
0217                 critical.append(tools[i]);
0218             }
0219             else {
0220                 failure.append(tools[i]);
0221             }
0222         }
0223         new ResultItem(m_listWidget, tools[i], status, isCritical, m_tester->resultForGroup(tools[i]));
0224     }
0225 
0226     m_listWidget->sortItems();
0227 
0228     if(ok) {
0229         QString cap = i18n("Test Results");
0230         QString testResultText = "<br/>";
0231         if (critical.count() > 0) {
0232             testResultText += i18n("The following <b>critical</b> tests did not succeed:"
0233                                    "<br/><br/>%1<br/><br/>Kile cannot function correctly on your system. Please consult the "
0234                                    "test results<br/>to determine which programs have to be fixed.", critical.join(", "));
0235         }
0236         else {
0237             if (failure.count() > 0) {
0238                 testResultText += i18n("The following tests did not succeed:<br/><br/>%1<br/><br/>You will still "
0239                                        "be able to use Kile; however, not all features are guaranteed "
0240                                        "to work.", failure.join(", "));
0241             }
0242             else {
0243                 testResultText += i18n("<b>No problems were detected. Kile will work correctly on your system.</b>");
0244             }
0245         }
0246 
0247         testResultText += "<br/><br/>";
0248         m_useModernConfigurationForLaTeXCheckBox->setChecked(m_tester->areSrcSpecialsSupportedForLaTeX());
0249         m_useModernConfigurationForPDFLaTeX->setChecked(m_tester->isSyncTeXSupportedForPDFLaTeX());
0250 
0251 //TODO: simplify this as Okular now always supports viewer mode
0252         if(m_tester->isViewerModeSupportedInOkular()) {
0253             m_useEmbeddedViewerCheckBox->setVisible(true);
0254             m_useEmbeddedViewerCheckBox->setChecked(true);
0255             if(m_tester->isSyncTeXSupportedForPDFLaTeX()) {
0256                 testResultText += i18n("The embedded document viewer is available and live preview is supported.");
0257             }
0258             else {
0259                 testResultText += i18n("The embedded document viewer is available, but the installed version of PDFLaTeX is<br/>"
0260                                        "<b>not compatible</b> with live preview.");
0261             }
0262         }
0263         else {
0264             m_useEmbeddedViewerCheckBox->setVisible(false);
0265             m_useEmbeddedViewerCheckBox->setChecked(false);
0266 
0267             testResultText += i18n("The embedded document viewer is <b>not available</b> (as Okular is either not available or the installed<br/>version is too old). "
0268                                    "Live preview is hence not supported.");
0269         }
0270 
0271         testResultText += "<br/><br/>";
0272 
0273         m_overallResultLabel->setText(testResultText);
0274 
0275         finishButton()->setEnabled(true);
0276         finishButton()->setDefault(true);
0277         finishButton()->setFocus();
0278     }
0279     else {
0280         // start by hiding all the labels
0281         for(QWidget *widget : m_testResultsPageWidgetItem->widget()->findChildren<QLabel*>()) {
0282             widget->setVisible(false);
0283         }
0284         // and then we show those again that we want
0285         m_overallResultLabel->setVisible(true);
0286         m_useEmbeddedViewerCheckBox->setVisible(false);
0287         m_useModernConfigurationForLaTeXCheckBox->setVisible(false);
0288         m_useModernConfigurationForPDFLaTeX->setVisible(false);
0289 
0290         m_overallResultLabel->setText(i18n("<br/><font color=\"#FF0000\"><b>The tests could not be finished correctly. "
0291                                            "Please check the available disk space.</b></font>"));
0292         finishButton()->setEnabled(false);
0293     }
0294 }
0295 
0296 void ConfigChecker::assistantFinished()
0297 {
0298     if(m_useEmbeddedViewerCheckBox->isChecked()) {
0299         m_ki->toolManager()->setConfigName("ViewPS", "Document Viewer");
0300         m_ki->toolManager()->setConfigName("ViewPDF", "Document Viewer");
0301         m_ki->toolManager()->setConfigName("ViewDVI", "Document Viewer");
0302     }
0303     if(m_useModernConfigurationForLaTeXCheckBox->isChecked()) {
0304         m_ki->toolManager()->setConfigName("TeX", "Modern");
0305         m_ki->toolManager()->setConfigName("PDFTeX", "Modern");
0306         m_ki->toolManager()->setConfigName("LaTeX", "Modern");
0307     }
0308     if(m_useModernConfigurationForPDFLaTeX->isChecked()) {
0309         m_ki->toolManager()->setConfigName("PDFLaTeX", "Modern");
0310         m_ki->toolManager()->setConfigName("XeLaTeX", "PDF Modern");
0311         m_ki->toolManager()->setConfigName("LuaLaTeX", "PDF Modern");
0312     }
0313 }
0314 
0315 void ConfigChecker::setPercentageDone(int p)
0316 {
0317     m_progressBar->setValue(p);
0318 }
0319 
0320 }