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 "logViewModel.h"
0008 
0009 #include "logLine.h"
0010 #include "view.h"
0011 
0012 #include "logModeItemBuilder.h"
0013 #include "logViewWidget.h"
0014 #include "logViewWidgetItem.h"
0015 
0016 #include "ksystemlog_debug.h"
0017 
0018 #include "ksystemlogConfig.h"
0019 
0020 LogViewModel::LogViewModel(LogViewWidget *logViewWidget)
0021     : QObject(logViewWidget)
0022 {
0023     mLogViewWidget = logViewWidget;
0024 }
0025 
0026 LogViewModel::~LogViewModel()
0027 {
0028 }
0029 
0030 bool LogViewModel::logLineAlreadyExists(LogLine *line) const
0031 {
0032     LogViewWidgetItem *item = mLogViewWidget->findItem(line);
0033     if (item) {
0034         return true;
0035     }
0036 
0037     return false;
0038 }
0039 
0040 QList<LogLine *> LogViewModel::logLines() const
0041 {
0042     return mLogViewWidget->logLines();
0043 }
0044 
0045 int LogViewModel::itemCount() const
0046 {
0047     return mLogViewWidget->itemCount();
0048 }
0049 
0050 bool LogViewModel::isEmpty() const
0051 {
0052     if (mLogViewWidget->itemCount() == 0) {
0053         return true;
0054     }
0055 
0056     return false;
0057 }
0058 
0059 void LogViewModel::removeRecentStatusOfLogLines()
0060 {
0061     // The older lines are no longer recent
0062     const auto items = mLogViewWidget->items();
0063     for (LogViewWidgetItem *item : items) {
0064         item->logLine()->setRecent(false);
0065     }
0066 }
0067 
0068 void LogViewModel::startingMultipleInsertions()
0069 {
0070     bool hasLocked = false;
0071 
0072     // Check the lock before adding this as locker
0073     if (lockMultipleInsertions()) {
0074         hasLocked = true;
0075     }
0076 
0077     // Add a lock
0078     mConcurrentMultipleInsertions++;
0079 
0080     if (hasLocked) {
0081         qCDebug(KSYSTEMLOG) << "Starting multiple insertions...";
0082 
0083         Q_EMIT processingMultipleInsertions(true);
0084 
0085         mLogViewWidget->setUpdatesEnabled(false);
0086 
0087         // Remove all recent states of previous log lines
0088         removeRecentStatusOfLogLines();
0089     }
0090 }
0091 
0092 void LogViewModel::endingMultipleInsertions(Analyzer::ReadingMode readingMode, int insertedLogLineCount)
0093 {
0094     // Remove a lock
0095     mConcurrentMultipleInsertions--;
0096 
0097     if (lockMultipleInsertions()) {
0098         qCDebug(KSYSTEMLOG) << "Ending multiple insertions...";
0099 
0100         // Scroll to the newest item if some lines have been added
0101         if (insertedLogLineCount > 0) {
0102             mLogViewWidget->scrollToNewestItem();
0103         }
0104 
0105         if (readingMode == Analyzer::FullRead) {
0106             mLogViewWidget->resizeColumns();
0107         }
0108 
0109         qCDebug(KSYSTEMLOG) << "Enabling log view widget refresh...";
0110         mLogViewWidget->setUpdatesEnabled(true);
0111 
0112         Q_EMIT processingMultipleInsertions(false);
0113     }
0114 }
0115 
0116 bool LogViewModel::lockMultipleInsertions()
0117 {
0118     if (mConcurrentMultipleInsertions == 0) {
0119         return true;
0120     } else if (mConcurrentMultipleInsertions > 0) {
0121         qCDebug(KSYSTEMLOG) << "Existing multiple insertions request is still active";
0122     } else {
0123         qCCritical(KSYSTEMLOG) << "Existing multiple insertions forgot to call this method";
0124     }
0125 
0126     return false;
0127 }
0128 
0129 bool LogViewModel::isProcessingMultipleInsertions() const
0130 {
0131     if (mConcurrentMultipleInsertions == 0) {
0132         return false;
0133     } else {
0134         return true;
0135     }
0136 }
0137 
0138 void LogViewModel::clear()
0139 {
0140     mLogViewWidget->clear();
0141 
0142     // Reinit Oldest item
0143     mOldestItem = nullptr;
0144 }
0145 
0146 bool LogViewModel::isNewer(LogLine *newLine) const
0147 {
0148     // No element in the list in this case
0149     if (!mOldestItem) {
0150         return true;
0151     }
0152 
0153     if (newLine->isNewerThan(*(mOldestItem->logLine()))) {
0154         return true;
0155     }
0156 
0157     return false;
0158 }
0159 
0160 void LogViewModel::removeOldestLogLine()
0161 {
0162     // qCDebug(KSYSTEMLOG) << "Removing oldest log line";
0163 
0164     if (isEmpty()) {
0165         return;
0166     }
0167 
0168     if (!mOldestItem) {
0169         qCWarning(KSYSTEMLOG) << "Oldest item is null";
0170         return;
0171     }
0172 
0173     // Remove the oldest item from the list
0174     mLogViewWidget->takeTopLevelItem(mLogViewWidget->indexOfTopLevelItem(mOldestItem));
0175 
0176     delete mOldestItem;
0177     mOldestItem = nullptr;
0178 
0179     // Find the next oldest item
0180     const auto items{mLogViewWidget->items()};
0181     for (LogViewWidgetItem *item : items) {
0182         if (!mOldestItem) {
0183             mOldestItem = item;
0184             continue;
0185         }
0186 
0187         if (mOldestItem->logLine()->isNewerThan(*(item->logLine()))) {
0188             mOldestItem = item;
0189         }
0190     }
0191 }
0192 
0193 void LogViewModel::insert(LogLine *line)
0194 {
0195     // The item is automatically added to the LogViewWidget
0196     auto item = new LogViewWidgetItem(mLogViewWidget, line);
0197 
0198     // Update the oldest item
0199     if (!mOldestItem) {
0200         mOldestItem = item;
0201     } else if (mOldestItem->logLine()->isNewerThan(*line)) {
0202         mOldestItem = item;
0203     }
0204 }
0205 
0206 bool LogViewModel::insertNewLogLine(LogLine *line)
0207 {
0208     // If the Delete Duplicated Line option is checked
0209     if (KSystemLogConfig::deleteDuplicatedLines()) {
0210         if (logLineAlreadyExists(line)) {
0211             delete line;
0212             return false;
0213         }
0214     }
0215 
0216     // If there is still space in the buffer
0217     if (itemCount() < KSystemLogConfig::maxLines()) {
0218         insert(line);
0219 
0220         return true;
0221     }
0222     // If the line is newer, it can be inserted
0223     else if (isNewer(line)) {
0224         removeOldestLogLine();
0225         insert(line);
0226 
0227         return true;
0228     }
0229 
0230     // qCDebug(KSYSTEMLOG) << "Do not insert an old line : " << line->logItems();
0231 
0232     return false;
0233 }
0234 
0235 #include "moc_logViewModel.cpp"