diff --git a/src/generalConfigurationWidget.cpp b/src/generalConfigurationWidget.cpp index 2e015ab..d7dca6d 100644 --- a/src/generalConfigurationWidget.cpp +++ b/src/generalConfigurationWidget.cpp @@ -1,174 +1,176 @@ /*************************************************************************** * KSystemLog, a system log viewer tool * * Copyright (C) 2007 by Nicolas Ternisien * * nicolas.ternisien@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "generalConfigurationWidget.h" #include #include #include #include #include #include #include "logging.h" #include "defaults.h" #include "globals.h" #include "ksystemlogConfig.h" class GeneralConfigurationWidgetPrivate { public: QButtonGroup *dateFormatGroup; KMessageWidget *warningBox; }; GeneralConfigurationWidget::GeneralConfigurationWidget() : QWidget() , d(new GeneralConfigurationWidgetPrivate()) { setupUi(this); d->warningBox = new KMessageWidget(this); d->warningBox->setVisible(false); d->warningBox->setMessageType(KMessageWidget::Warning); d->warningBox->setText(i18n("This mode is unavailable because its log files do not exist.")); d->warningBox->setCloseButtonVisible(false); d->warningBox->setIcon(QIcon::fromTheme(QStringLiteral("dialog-warning"))); startupModeVerticalLayout->addWidget(d->warningBox); startupLogMode->addItem(QIcon::fromTheme(QStringLiteral(NO_MODE_ICON)), i18n("No Log Mode"), QVariant(QLatin1String(""))); foreach (LogMode *logMode, Globals::instance().logModes()) { // Ignore this special case if (logMode->id() == QLatin1String("openLogMode")) continue; startupLogMode->addItem(logMode->icon(), logMode->name(), QVariant(logMode->id())); } - +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) connect(startupLogMode, QOverload::of(&QComboBox::currentIndexChanged), this, &GeneralConfigurationWidget::configurationChanged); - +#else + connect(startupLogMode, QOverload::of(&QComboBox::currentIndexChanged), this, &GeneralConfigurationWidget::configurationChanged); +#endif connect(maxLines, QOverload::of(&QSpinBox::valueChanged), this, &GeneralConfigurationWidget::configurationChanged); connect(deleteDuplicatedLines, &QAbstractButton::clicked, this, &GeneralConfigurationWidget::configurationChanged); connect(deleteProcessId, &QAbstractButton::clicked, this, &GeneralConfigurationWidget::configurationChanged); connect(colorizeLogLines, &QAbstractButton::clicked, this, &GeneralConfigurationWidget::configurationChanged); d->dateFormatGroup = new QButtonGroup(this); d->dateFormatGroup->addButton(formatLongDate, Globals::LongFormat); d->dateFormatGroup->addButton(formatShortDate, Globals::ShortFormat); d->dateFormatGroup->addButton(formatPreciseDate, Globals::PreciseFormat); connect(d->dateFormatGroup, QOverload::of(&QButtonGroup::buttonClicked), this, &GeneralConfigurationWidget::configurationChanged); addDateFormatExample(); } GeneralConfigurationWidget::~GeneralConfigurationWidget() { // dateFormatGroup is automatically deleted by Qt delete d; } void GeneralConfigurationWidget::addDateFormatExample() { foreach (QAbstractButton *button, d->dateFormatGroup->buttons()) { Globals::DateFormat currentButtonFormat = (Globals::DateFormat)d->dateFormatGroup->id(button); QString formattedDate = Globals::instance().formatDate(currentButtonFormat, QDateTime().currentDateTime()); button->setText(i18nc("Date format option (date example)", "%1 (%2)", button->text(), formattedDate)); } } void GeneralConfigurationWidget::readConfig() { for (int i = 0; i < startupLogMode->count(); ++i) { if (KSystemLogConfig::startupLogMode() == startupLogMode->itemData(i)) { startupLogMode->setCurrentIndex(i); break; } } maxLines->setValue(KSystemLogConfig::maxLines()); deleteDuplicatedLines->setChecked(KSystemLogConfig::deleteDuplicatedLines()); deleteProcessId->setChecked(KSystemLogConfig::deleteProcessIdentifier()); colorizeLogLines->setChecked(KSystemLogConfig::colorizeLogLines()); // KLocale::DateFormat dateFormat = (KLocale::DateFormat) KSystemLogConfig::dateFormat(); QLocale::FormatType dateFormat = (QLocale::FormatType)KSystemLogConfig::dateFormat(); QAbstractButton *selectedButton = d->dateFormatGroup->button(dateFormat); selectedButton->setChecked(true); } void GeneralConfigurationWidget::saveConfig() const { logDebug() << "Save config from General preferences"; KSystemLogConfig::setStartupLogMode(startupLogMode->itemData(startupLogMode->currentIndex()).toString()); KSystemLogConfig::setMaxLines(maxLines->value()); KSystemLogConfig::setDeleteDuplicatedLines(deleteDuplicatedLines->isChecked()); KSystemLogConfig::setDeleteProcessIdentifier(deleteProcessId->isChecked()); KSystemLogConfig::setColorizeLogLines(colorizeLogLines->isChecked()); KSystemLogConfig::setDateFormat(d->dateFormatGroup->checkedId()); } void GeneralConfigurationWidget::defaultConfig() { // TODO Find a way to read the configuration per default readConfig(); } bool GeneralConfigurationWidget::isValid() const { if (maxLines->value() > 0) { // Check if log files exist for selected mode. QVariant modeID = startupLogMode->currentData(); if (!modeID.isNull()) { QString modeString = modeID.toString(); LogMode *mode = Globals::instance().findLogMode(modeString); if (mode) { if (!mode->filesExist()) { logDebug() << "Log files are missing for mode" << mode->name(); d->warningBox->setVisible(true); } else { logDebug() << "General configuration is valid"; d->warningBox->setVisible(false); return true; } } else { // Empty log mode is selected. d->warningBox->setVisible(false); return true; } } } logDebug() << "General configuration is not valid"; return false; } diff --git a/src/lib/processOutputLogFileReader.cpp b/src/lib/processOutputLogFileReader.cpp index bd73b67..4c7d63c 100644 --- a/src/lib/processOutputLogFileReader.cpp +++ b/src/lib/processOutputLogFileReader.cpp @@ -1,239 +1,239 @@ /*************************************************************************** * KSystemLog, a system log viewer tool * * Copyright (C) 2007 by Nicolas Ternisien * * nicolas.ternisien@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "processOutputLogFileReader.h" #include #include #include #include #include "logFileReader.h" #include "logFileReaderPrivate.h" #include "logging.h" class ProcessOutputLogFileReaderPrivate : public LogFileReaderPrivate { public: long previousLinesCount; QTimer processUpdater; QProcess *process; QString buffer; QStringList availableStandardOutput; }; ProcessOutputLogFileReader::ProcessOutputLogFileReader(const LogFile &logFile) : LogFileReader(*new ProcessOutputLogFileReaderPrivate(), logFile) { init(); } ProcessOutputLogFileReader::ProcessOutputLogFileReader(ProcessOutputLogFileReaderPrivate &dd, const LogFile &logFile) : LogFileReader(dd, logFile) { init(); } ProcessOutputLogFileReader::~ProcessOutputLogFileReader() { // d pointer is deleted by the parent class } void ProcessOutputLogFileReader::init() { Q_D(ProcessOutputLogFileReader); // Init current file position d->previousLinesCount = 0; d->availableStandardOutput.clear(); d->process = nullptr; d->processUpdater.setInterval(PROCESS_OUTPUT_UPDATER_INTERVAL); connect(&(d->processUpdater), &QTimer::timeout, this, &ProcessOutputLogFileReader::startProcess); logDebug() << "Using process name " << d->logFile.url().path(); } void ProcessOutputLogFileReader::watchFile(bool enable) { Q_D(ProcessOutputLogFileReader); if (enable == true) { logDebug() << "Monitoring process : " << d->logFile.url().path(); // Reinit current file position d->previousLinesCount = 0; // Launch the timer d->processUpdater.start(); // Launch immediately the process updater startProcess(); } else { // Stop regularly start process d->processUpdater.stop(); } } void ProcessOutputLogFileReader::startProcess() { logDebug() << "Starting process..."; Q_D(ProcessOutputLogFileReader); if (d->logFile.url().isValid() == false) { QString message(i18n("This file is not valid. Please adjust it in the settings of KSystemLog.")); emit errorOccured(i18n("File Does Not Exist"), message); emit statusBarChanged(message); } logDebug() << "Starting process..."; d->process = new QProcess(); connect(d->process, &QProcess::readyReadStandardOutput, this, &ProcessOutputLogFileReader::logFileModified); connect(d->process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(emitProcessOutput(int,QProcess::ExitStatus))); - d->process->start(d->logFile.url().path(), QIODevice::ReadOnly | QIODevice::Text); + d->process->start(d->logFile.url().path(), QStringList(), QIODevice::ReadOnly | QIODevice::Text); d->process->waitForStarted(); logDebug() << "Process started"; } void ProcessOutputLogFileReader::closeProcess() { logDebug() << "Closing process..."; Q_D(ProcessOutputLogFileReader); // Get the size file for the next calculation d->previousLinesCount = d->availableStandardOutput.count(); logDebug() << "New lines count : " << d->previousLinesCount << " (" << d->logFile.url().path() << ")"; d->availableStandardOutput.clear(); if (d->process) { d->process->close(); delete d->process; d->process = nullptr; } logDebug() << "Process closed"; } void ProcessOutputLogFileReader::emitProcessOutput(int /*exitCode*/, QProcess::ExitStatus exitStatus) { Q_D(ProcessOutputLogFileReader); // First commit last lines of the buffer to the line list emptyBuffer(); logDebug() << "Process terminated" << d->previousLinesCount << "previously /" << d->availableStandardOutput.count() << "currently"; if (exitStatus == QProcess::CrashExit) { QString message(i18n("The process '%1' crashed.", d->logFile.url().path())); emit errorOccured(i18n("Process Crashed"), message); emit statusBarChanged(message); } // If there is no new lines if (d->previousLinesCount == d->availableStandardOutput.count()) { /* //Emit an empty log lines list emit contentChanged(this, false, QStringList()); */ } // If there are new lines in the file, insert only them or this is the first time we read this file else if (d->previousLinesCount != 0 && d->previousLinesCount <= d->availableStandardOutput.count()) { logDebug() << "Reading from line " << d->previousLinesCount << " (" << d->logFile.url().path() << ")"; QStringList newOutputs; int index = d->previousLinesCount - 1; while (index < d->availableStandardOutput.count()) { newOutputs.append(d->availableStandardOutput.at(index)); ++index; } logDebug() << "Retrieving a part of the file..."; emit contentChanged(this, Analyzer::UpdatingRead, newOutputs); } // Else reread all lines, clear log list else { logDebug() << "New process or process already read. Reading entire content"; emit contentChanged(this, Analyzer::FullRead, d->availableStandardOutput); } closeProcess(); } void ProcessOutputLogFileReader::logFileModified() { Q_D(ProcessOutputLogFileReader); logDebug() << "Content available on process output..."; // New added lines QByteArray bytesOutput = d->process->readAllStandardOutput(); d->buffer.append(QLatin1String(bytesOutput)); // Parse buffer int endLinePos = d->buffer.indexOf(QLatin1String("\n")); forever { if (endLinePos == -1) break; // Add the new found lines and d->availableStandardOutput.append(d->buffer.left(endLinePos)); d->buffer.remove(0, endLinePos + 1); endLinePos = d->buffer.indexOf(QLatin1String("\n")); } logDebug() << "Received a total of" << d->availableStandardOutput.count() << "new lines"; } /** * The buffer could contains some last characters that are added at last * (Normally useless) */ void ProcessOutputLogFileReader::emptyBuffer() { Q_D(ProcessOutputLogFileReader); if (d->buffer.isEmpty() == false) { logWarning() << "Buffer was not empty !!"; d->availableStandardOutput.append(d->buffer); d->buffer.clear(); } } diff --git a/src/statusBar.cpp b/src/statusBar.cpp index 79a2083..3c27e0c 100644 --- a/src/statusBar.cpp +++ b/src/statusBar.cpp @@ -1,145 +1,149 @@ /*************************************************************************** * KSystemLog, a system log viewer tool * * Copyright (C) 2007 by Nicolas Ternisien * * nicolas.ternisien@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "statusBar.h" #include #include #include #include #include #include #include #include #include "logging.h" namespace KSystemLog { class StatusBarPrivate { public: QLabel *lineCountLabel; // KSqueezedTextLabel* messageLabel; KComboBox *messageList; QLabel *lastModificationLabel; QPushButton *toggleHistory; }; StatusBar::StatusBar(QWidget *parent) : QStatusBar(parent) , d(new StatusBarPrivate()) { d->lineCountLabel = new QLabel(this); d->lineCountLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); d->lineCountLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); d->lineCountLabel->setLineWidth(2); d->lineCountLabel->setMidLineWidth(2); addPermanentWidget(d->lineCountLabel, 1); /* d->toggleHistory = new QPushButton(this); d->toggleHistory->setIcon(QIcon::fromTheme( QLatin1String( "view-history" ))); d->toggleHistory->setFlat(true); addPermanentWidget(d->toggleHistory, 0); connect(d->toggleHistory, &QPushButton::clicked, this, &StatusBar::toggleHistory); */ /* d->messageLabel = new KSqueezedTextLabel("", this); d->messageLabel->setAlignment(Qt::AlignLeft); d->messageLabel->setTextElideMode(Qt::ElideRight); addPermanentWidget(d->messageLabel, 4); */ d->messageList = new KComboBox(this); d->messageList->setInsertPolicy(QComboBox::InsertAtTop); d->messageList->setMaxVisibleItems(5); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) connect(d->messageList, QOverload::of(&KComboBox::currentIndexChanged), this, &StatusBar::selectLastHistory); +#else + connect(d->messageList, QOverload::of(&KComboBox::currentIndexChanged), this, &StatusBar::selectLastHistory); +#endif /* //TODO Define a specifical palette (and make it works !) QPalette palette(d->messageList->palette()); palette.setColor(QPalette::HighlightedText, Qt::red); //palette.color(QPalette::Base) palette.setColor(QPalette::Base, Qt::red); //palette.color(QPalette::Base) palette.setColor(QPalette::Text, QColor(212, 140, 95)); //palette.color(QPalette::Base) d->messageList->setPalette(palette); //d->messageList->repaint(); */ addPermanentWidget(d->messageList, 4); d->lastModificationLabel = new QLabel(this); d->lastModificationLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter); d->lastModificationLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); d->lastModificationLabel->setLineWidth(2); d->lastModificationLabel->setMidLineWidth(2); addPermanentWidget(d->lastModificationLabel, 1); } StatusBar::~StatusBar() { // QLabels are automatically deleted by Qt delete d; } void StatusBar::changeLineCountMessage(const QString &lineCountMessage) { d->lineCountLabel->setText(lineCountMessage); } void StatusBar::changeLastModification(const QTime &lastModification) { // d->lastModificationLabel->setText(i18n("Last updated: %1.", // KLocale::global()->formatTime(lastModification, true, false) )); d->lastModificationLabel->setText( i18n("Last updated: %1.", QLocale().toString(lastModification, QStringLiteral("hh:mm:ss")))); } void StatusBar::changeMessage(const QString &message) { // d->messageLabel->setText(message); // d->messageList->insertItem(0, i18n("%1: %2", KLocale::global()->formatTime(QTime::currentTime(), true, // false), message)); d->messageList->insertItem( 0, i18n("%1: %2", QLocale().toString(QTime::currentTime(), QStringLiteral("hh:mm:ss")), message)); // 100 log history message max. if (d->messageList->count() > 100) { d->messageList->removeItem(d->messageList->count() - 1); } } void StatusBar::selectLastHistory() { d->messageList->setCurrentIndex(0); } void StatusBar::toggleHistory() { logDebug() << "Toggling History..."; d->messageList->showPopup(); } }