1 /* 2 SPDX-FileCopyrightText: 2007 Nicolas Ternisien <nicolas.ternisien@gmail.com> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #include "logViewModel.h" 8 9 #include "logLine.h" 10 #include "view.h" 11 12 #include "logModeItemBuilder.h" 13 #include "logViewWidget.h" 14 #include "logViewWidgetItem.h" 15 16 #include "ksystemlog_debug.h" 17 18 #include "ksystemlogConfig.h" 19 LogViewModel(LogViewWidget * logViewWidget)20LogViewModel::LogViewModel(LogViewWidget *logViewWidget) 21 : QObject(logViewWidget) 22 { 23 mLogViewWidget = logViewWidget; 24 } 25 ~LogViewModel()26LogViewModel::~LogViewModel() 27 { 28 } 29 logLineAlreadyExists(LogLine * line) const30bool LogViewModel::logLineAlreadyExists(LogLine *line) const 31 { 32 LogViewWidgetItem *item = mLogViewWidget->findItem(line); 33 if (item) { 34 return true; 35 } 36 37 return false; 38 } 39 logLines() const40QList<LogLine *> LogViewModel::logLines() const 41 { 42 return mLogViewWidget->logLines(); 43 } 44 itemCount() const45int LogViewModel::itemCount() const 46 { 47 return mLogViewWidget->itemCount(); 48 } 49 isEmpty() const50bool LogViewModel::isEmpty() const 51 { 52 if (mLogViewWidget->itemCount() == 0) { 53 return true; 54 } 55 56 return false; 57 } 58 removeRecentStatusOfLogLines()59void LogViewModel::removeRecentStatusOfLogLines() 60 { 61 // The older lines are no longer recent 62 const auto items = mLogViewWidget->items(); 63 for (LogViewWidgetItem *item : items) { 64 item->logLine()->setRecent(false); 65 } 66 } 67 startingMultipleInsertions()68void LogViewModel::startingMultipleInsertions() 69 { 70 bool hasLocked = false; 71 72 // Check the lock before adding this as locker 73 if (lockMultipleInsertions()) { 74 hasLocked = true; 75 } 76 77 // Add a lock 78 mConcurrentMultipleInsertions++; 79 80 if (hasLocked) { 81 qCDebug(KSYSTEMLOG) << "Starting multiple insertions..."; 82 83 Q_EMIT processingMultipleInsertions(true); 84 85 mLogViewWidget->setUpdatesEnabled(false); 86 87 // Remove all recent states of previous log lines 88 removeRecentStatusOfLogLines(); 89 } 90 } 91 endingMultipleInsertions(Analyzer::ReadingMode readingMode,int insertedLogLineCount)92void LogViewModel::endingMultipleInsertions(Analyzer::ReadingMode readingMode, int insertedLogLineCount) 93 { 94 // Remove a lock 95 mConcurrentMultipleInsertions--; 96 97 if (lockMultipleInsertions()) { 98 qCDebug(KSYSTEMLOG) << "Ending multiple insertions..."; 99 100 // Scroll to the newest item if some lines have been added 101 if (insertedLogLineCount > 0) { 102 mLogViewWidget->scrollToNewestItem(); 103 } 104 105 if (readingMode == Analyzer::FullRead) { 106 mLogViewWidget->resizeColumns(); 107 } 108 109 qCDebug(KSYSTEMLOG) << "Enabling log view widget refresh..."; 110 mLogViewWidget->setUpdatesEnabled(true); 111 112 Q_EMIT processingMultipleInsertions(false); 113 } 114 } 115 lockMultipleInsertions()116bool LogViewModel::lockMultipleInsertions() 117 { 118 if (mConcurrentMultipleInsertions == 0) { 119 return true; 120 } 121 122 // Debug messages 123 if (mConcurrentMultipleInsertions > 0) { 124 qCDebug(KSYSTEMLOG) << "Existing multiple insertions request is still active"; 125 } else if (mConcurrentMultipleInsertions < 0) { 126 qCCritical(KSYSTEMLOG) << "Existing multiple insertions forgot to call this method"; 127 } 128 129 return false; 130 } 131 isProcessingMultipleInsertions() const132bool LogViewModel::isProcessingMultipleInsertions() const 133 { 134 if (mConcurrentMultipleInsertions == 0) { 135 return false; 136 } else { 137 return true; 138 } 139 } 140 clear()141void LogViewModel::clear() 142 { 143 mLogViewWidget->clear(); 144 145 // Reinit Oldest item 146 mOldestItem = nullptr; 147 } 148 isNewer(LogLine * newLine) const149bool LogViewModel::isNewer(LogLine *newLine) const 150 { 151 // No element in the list in this case 152 if (!mOldestItem) { 153 return true; 154 } 155 156 if (newLine->isNewerThan(*(mOldestItem->logLine()))) { 157 return true; 158 } 159 160 return false; 161 } 162 removeOldestLogLine()163void LogViewModel::removeOldestLogLine() 164 { 165 // qCDebug(KSYSTEMLOG) << "Removing oldest log line"; 166 167 if (isEmpty()) { 168 return; 169 } 170 171 if (!mOldestItem) { 172 qCWarning(KSYSTEMLOG) << "Oldest item is null"; 173 return; 174 } 175 176 // Remove the oldest item from the list 177 mLogViewWidget->takeTopLevelItem(mLogViewWidget->indexOfTopLevelItem(mOldestItem)); 178 179 delete mOldestItem; 180 mOldestItem = nullptr; 181 182 // Find the next oldest item 183 const auto items{mLogViewWidget->items()}; 184 for (LogViewWidgetItem *item : items) { 185 if (!mOldestItem) { 186 mOldestItem = item; 187 continue; 188 } 189 190 if (mOldestItem->logLine()->isNewerThan(*(item->logLine()))) { 191 mOldestItem = item; 192 } 193 } 194 } 195 insert(LogLine * line)196void LogViewModel::insert(LogLine *line) 197 { 198 // The item is automatically added to the LogViewWidget 199 auto item = new LogViewWidgetItem(mLogViewWidget, line); 200 201 // Update the oldest item 202 if (!mOldestItem) { 203 mOldestItem = item; 204 } else if (mOldestItem->logLine()->isNewerThan(*line)) { 205 mOldestItem = item; 206 } 207 } 208 insertNewLogLine(LogLine * line)209bool LogViewModel::insertNewLogLine(LogLine *line) 210 { 211 // If the Delete Duplicated Line option is checked 212 if (KSystemLogConfig::deleteDuplicatedLines()) { 213 if (logLineAlreadyExists(line)) { 214 delete line; 215 return false; 216 } 217 } 218 219 // If there is still space in the buffer 220 if (itemCount() < KSystemLogConfig::maxLines()) { 221 insert(line); 222 223 return true; 224 } 225 // If the line is newer, it can be inserted 226 else if (isNewer(line)) { 227 removeOldestLogLine(); 228 insert(line); 229 230 return true; 231 } 232 233 // qCDebug(KSYSTEMLOG) << "Do not insert an old line : " << line->logItems(); 234 235 return false; 236 } 237