File indexing completed on 2024-05-05 05:48:57

0001 /*
0002     SPDX-FileCopyrightText: 2007 Nicolas Ternisien <nicolas.ternisien@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "logManager.h"
0008 
0009 #include <KLocalizedString>
0010 #include <KMessageBox>
0011 
0012 #include "analyzer.h"
0013 #include "ksystemlog_debug.h"
0014 #include "view.h"
0015 
0016 #include "logViewWidget.h"
0017 
0018 #include "loadingBar.h"
0019 
0020 class LogManagerPrivate
0021 {
0022     friend class LogManager;
0023 
0024     QTime mLastUpdate;
0025 
0026     LogMode *mLogMode = nullptr;
0027 
0028     Analyzer *mAnalyzer = nullptr;
0029     View *mUsedView = nullptr;
0030     QString mAnalyzerStatus;
0031     QVariant mAnalyzerOptions;
0032 };
0033 
0034 LogManager::LogManager(View *view)
0035     : QObject(view)
0036     , d(new LogManagerPrivate())
0037 {
0038     d->mLastUpdate = QTime::currentTime();
0039 
0040     d->mUsedView = view;
0041     connect(d->mUsedView, &View::droppedUrls, this, &LogManager::loadDroppedUrls);
0042 }
0043 
0044 LogManager::~LogManager()
0045 {
0046     cleanPreviousLogMode();
0047 
0048     // usedView is managed by MainWindow
0049     // logMode is managed by Globals
0050 
0051     delete d;
0052 }
0053 
0054 View *LogManager::usedView() const
0055 {
0056     return d->mUsedView;
0057 }
0058 
0059 void LogManager::reload()
0060 {
0061     if (!d->mLogMode) {
0062         qCWarning(KSYSTEMLOG) << "Log manager is not yet initialized";
0063         return;
0064     }
0065 
0066     qCDebug(KSYSTEMLOG) << "Reloading with log mode " << d->mLogMode->name() << "...";
0067 
0068     Q_EMIT statusBarChanged(i18n("Loading log..."));
0069 
0070     // Change part of the main interface
0071     Q_EMIT tabTitleChanged(d->mUsedView, d->mLogMode->icon(), d->mLogMode->name());
0072     Q_EMIT windowTitleChanged(d->mLogMode->name());
0073 
0074     qCDebug(KSYSTEMLOG) << "Emptying view...";
0075 
0076     // Empty the current list, to better fill it
0077     d->mUsedView->logViewWidget()->model()->clear();
0078 
0079     qCDebug(KSYSTEMLOG) << "Initializing view...";
0080 
0081     // Init the Log View
0082     qCDebug(KSYSTEMLOG) << "Initializing columns view...";
0083 
0084     d->mUsedView->logViewWidget()->setColumns(d->mAnalyzer->initColumns());
0085 
0086     qCDebug(KSYSTEMLOG) << "Reading log...";
0087 
0088     // Read the log files
0089     d->mAnalyzer->watchLogFiles(false);
0090     d->mAnalyzer->watchLogFiles(true);
0091 
0092     Q_EMIT statusBarChanged(i18n("Log successfully loaded."));
0093 
0094     // Log List has been totally reloaded
0095     Q_EMIT reloaded();
0096 
0097     qCDebug(KSYSTEMLOG) << "Log mode " << d->mLogMode->name() << " reloaded";
0098 }
0099 
0100 void LogManager::stopWatching()
0101 {
0102     if (d->mAnalyzer) {
0103         d->mAnalyzer->watchLogFiles(false);
0104     }
0105 }
0106 
0107 const QVariant &LogManager::analyzerOptions() const
0108 {
0109     return d->mAnalyzerOptions;
0110 }
0111 
0112 LogMode *LogManager::logMode()
0113 {
0114     return d->mLogMode;
0115 }
0116 
0117 QString LogManager::title() const
0118 {
0119     if (!d->mAnalyzerStatus.isEmpty()) {
0120         return d->mLogMode->name() + QStringLiteral(" - ") + d->mAnalyzerStatus;
0121     } else {
0122         return d->mLogMode->name();
0123     }
0124 }
0125 
0126 const QTime &LogManager::lastUpdate() const
0127 {
0128     return d->mLastUpdate;
0129 }
0130 
0131 void LogManager::updateLog(int lineCount)
0132 {
0133     qCDebug(KSYSTEMLOG) << "Updating log " << lineCount << " new lines";
0134 
0135     if (lineCount == 0) {
0136         return;
0137     }
0138 
0139     d->mLastUpdate = QTime::currentTime();
0140 
0141     Q_EMIT logUpdated(d->mUsedView, lineCount);
0142 }
0143 
0144 void LogManager::cleanPreviousLogMode()
0145 {
0146     qCDebug(KSYSTEMLOG) << "Cleaning previous LogMode...";
0147 
0148     d->mLogMode = nullptr;
0149 
0150     delete d->mAnalyzer;
0151     d->mAnalyzer = nullptr;
0152 
0153     d->mAnalyzerStatus.clear();
0154 }
0155 
0156 void LogManager::initialize(LogMode *mode, const QVariant &analyzerOptions)
0157 {
0158     if (!mode) {
0159         return;
0160     }
0161     internalInitialize(mode, mode->createLogFiles(), analyzerOptions);
0162 }
0163 
0164 void LogManager::internalInitialize(LogMode *mode, const QVector<LogFile> &logFiles, const QVariant &analyzerOptions)
0165 {
0166     qCDebug(KSYSTEMLOG) << "Initializing LogManager...";
0167 
0168     qCDebug(KSYSTEMLOG) << "Using files" << logFiles;
0169 
0170     cleanPreviousLogMode();
0171 
0172     d->mAnalyzerOptions = analyzerOptions;
0173 
0174     // Use the new mode
0175     d->mLogMode = mode;
0176 
0177     // Find the Analyzer instance used for this new mode
0178     d->mAnalyzer = mode->createAnalyzer(analyzerOptions);
0179     d->mAnalyzer->setLogViewModel(d->mUsedView->logViewWidget()->model());
0180     connect(d->mAnalyzer, &Analyzer::statusChanged, this, [this](const QString &status) {
0181         d->mAnalyzerStatus = status;
0182         Q_EMIT tabTitleChanged(d->mUsedView, d->mLogMode->icon(), title());
0183         Q_EMIT windowTitleChanged(title());
0184     });
0185 
0186     connect(d->mAnalyzer, &Analyzer::statusBarChanged, this, &LogManager::statusBarChanged);
0187     connect(d->mAnalyzer, &Analyzer::errorOccured, this, &LogManager::showErrorMessage);
0188     connect(d->mAnalyzer, &Analyzer::logUpdated, this, &LogManager::updateLog);
0189 
0190     connect(d->mAnalyzer, &Analyzer::readFileStarted, d->mUsedView->loadingBar(), &LoadingBar::startLoading);
0191     connect(d->mAnalyzer, &Analyzer::openingProgressed, d->mUsedView->loadingBar(), &LoadingBar::progressLoading);
0192     connect(d->mAnalyzer, &Analyzer::readEnded, d->mUsedView->loadingBar(), &LoadingBar::endLoading);
0193 
0194     // Find the log files used for this kind of mode, and set them to our log manager
0195     d->mAnalyzer->setLogFiles(logFiles);
0196 
0197     qCDebug(KSYSTEMLOG) << "LogManager initialized";
0198 }
0199 
0200 void LogManager::showErrorMessage(const QString &title, const QString &message)
0201 {
0202     KMessageBox::error(d->mUsedView, message, title, KMessageBox::Notify);
0203 }
0204 
0205 void LogManager::setParsingPaused(bool paused)
0206 {
0207     if (!d->mLogMode) {
0208         qCWarning(KSYSTEMLOG) << "Log manager is not yet initialized";
0209         return;
0210     }
0211 
0212     if (!paused) {
0213         // Current analyzer implementations just perform full reload when resuming.
0214         // Clear the log view to avoid duplicating entries.
0215         d->mUsedView->logViewWidget()->model()->clear();
0216         d->mUsedView->logViewWidget()->setColumns(d->mAnalyzer->initColumns());
0217     }
0218     d->mAnalyzer->setParsingPaused(paused);
0219 }
0220 
0221 bool LogManager::isParsingPaused() const
0222 {
0223     if (!d->mLogMode) {
0224         qCWarning(KSYSTEMLOG) << "Log manager is not yet initialized";
0225         return false;
0226     }
0227 
0228     return d->mAnalyzer->isParsingPaused();
0229 }
0230 
0231 void LogManager::loadDroppedUrls(const QList<QUrl> &urls)
0232 {
0233     qCDebug(KSYSTEMLOG) << "Drop " << urls;
0234 
0235     QVector<LogFile> logFiles;
0236     logFiles.reserve(urls.count());
0237 
0238     for (const QUrl &url : urls) {
0239         logFiles.append(LogFile(url, Globals::instance().informationLogLevel()));
0240     }
0241 
0242     if (!logFiles.isEmpty()) {
0243         internalInitialize(Globals::instance().findLogMode(QStringLiteral("openLogMode")), logFiles);
0244 
0245         reload();
0246     }
0247 }
0248 
0249 #include "moc_logManager.cpp"