2012-06-05 17:11:29 +04:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Klaas Freitag <freitag@owncloud.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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "logbrowser.h"
|
|
|
|
|
|
|
|
#include "stdio.h"
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
#include <QDialogButtonBox>
|
|
|
|
#include <QTextDocument>
|
|
|
|
#include <QLayout>
|
|
|
|
#include <QPushButton>
|
|
|
|
#include <QLabel>
|
|
|
|
#include <QFileDialog>
|
|
|
|
#include <QDir>
|
|
|
|
#include <QTextStream>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QCoreApplication>
|
2013-11-15 18:45:21 +04:00
|
|
|
#include <QSettings>
|
2013-08-14 19:46:58 +04:00
|
|
|
#include <QAction>
|
2012-06-05 17:11:29 +04:00
|
|
|
|
2014-11-10 01:25:57 +03:00
|
|
|
#include "configfile.h"
|
2014-07-11 02:31:24 +04:00
|
|
|
#include "logger.h"
|
2012-06-05 17:11:29 +04:00
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
namespace OCC {
|
2012-06-05 17:11:29 +04:00
|
|
|
|
|
|
|
// ==============================================================================
|
|
|
|
|
|
|
|
LogWidget::LogWidget(QWidget *parent)
|
2012-08-26 13:46:59 +04:00
|
|
|
: QPlainTextEdit(parent)
|
2012-06-05 17:11:29 +04:00
|
|
|
{
|
|
|
|
setReadOnly(true);
|
|
|
|
QFont font;
|
2012-08-17 19:13:17 +04:00
|
|
|
font.setFamily(QLatin1String("Courier New"));
|
2012-06-05 17:11:29 +04:00
|
|
|
font.setFixedPitch(true);
|
|
|
|
document()->setDefaultFont(font);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ==============================================================================
|
|
|
|
|
|
|
|
LogBrowser::LogBrowser(QWidget *parent)
|
|
|
|
: QDialog(parent)
|
2013-10-02 17:28:33 +04:00
|
|
|
, _logWidget(new LogWidget(parent))
|
2012-06-05 17:11:29 +04:00
|
|
|
{
|
2013-11-13 23:12:56 +04:00
|
|
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
2013-07-22 14:28:43 +04:00
|
|
|
setObjectName("LogBrowser"); // for save/restoreGeometry()
|
2012-06-05 17:11:29 +04:00
|
|
|
setWindowTitle(tr("Log Output"));
|
|
|
|
setMinimumWidth(600);
|
|
|
|
|
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
|
|
|
// mainLayout->setMargin(0);
|
|
|
|
|
|
|
|
mainLayout->addWidget(_logWidget);
|
|
|
|
|
|
|
|
QHBoxLayout *toolLayout = new QHBoxLayout;
|
|
|
|
mainLayout->addLayout(toolLayout);
|
|
|
|
|
|
|
|
// Search input field
|
2015-02-06 00:00:13 +03:00
|
|
|
QLabel *lab = new QLabel(tr("&Search:") + " ");
|
2012-06-05 17:11:29 +04:00
|
|
|
_findTermEdit = new QLineEdit;
|
|
|
|
lab->setBuddy(_findTermEdit);
|
|
|
|
toolLayout->addWidget(lab);
|
|
|
|
toolLayout->addWidget(_findTermEdit);
|
|
|
|
|
|
|
|
// find button
|
|
|
|
QPushButton *findBtn = new QPushButton;
|
|
|
|
findBtn->setText(tr("&Find"));
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(findBtn, &QAbstractButton::clicked, this, &LogBrowser::slotFind);
|
2012-06-05 17:11:29 +04:00
|
|
|
toolLayout->addWidget(findBtn);
|
|
|
|
|
|
|
|
// stretch
|
|
|
|
toolLayout->addStretch(1);
|
|
|
|
_statusLabel = new QLabel;
|
|
|
|
toolLayout->addWidget(_statusLabel);
|
|
|
|
toolLayout->addStretch(5);
|
|
|
|
|
2017-05-09 18:04:04 +03:00
|
|
|
// Debug logging
|
|
|
|
_logDebugCheckBox = new QCheckBox(tr("&Capture debug messages") + " ");
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(_logDebugCheckBox, &QCheckBox::stateChanged, this, &LogBrowser::slotDebugCheckStateChanged);
|
2017-05-09 18:04:04 +03:00
|
|
|
toolLayout->addWidget(_logDebugCheckBox);
|
|
|
|
|
2012-06-05 17:11:29 +04:00
|
|
|
QDialogButtonBox *btnbox = new QDialogButtonBox;
|
|
|
|
QPushButton *closeBtn = btnbox->addButton(QDialogButtonBox::Close);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(closeBtn, &QAbstractButton::clicked, this, &QWidget::close);
|
2012-06-05 17:11:29 +04:00
|
|
|
|
|
|
|
mainLayout->addWidget(btnbox);
|
|
|
|
|
2018-04-10 14:07:20 +03:00
|
|
|
// button to permanently save logs
|
|
|
|
_permanentLogging = new QCheckBox;
|
|
|
|
_permanentLogging->setText(tr("Permanently save logs"));
|
|
|
|
_permanentLogging->setToolTip(
|
|
|
|
tr("When this option is enabled and no other logging is configured, "
|
|
|
|
"logs will be written to a temporary folder and expire after a few hours. "
|
|
|
|
"This setting persists across client restarts.\n"
|
|
|
|
"\n"
|
|
|
|
"Logs will be written to %1")
|
|
|
|
.arg(Logger::instance()->temporaryFolderLogDirPath()));
|
|
|
|
_permanentLogging->setChecked(ConfigFile().automaticLogDir());
|
|
|
|
btnbox->addButton(_permanentLogging, QDialogButtonBox::ActionRole);
|
|
|
|
connect(_permanentLogging, &QCheckBox::toggled, this, &LogBrowser::togglePermanentLogging);
|
|
|
|
|
2012-07-16 23:11:19 +04:00
|
|
|
// clear button
|
|
|
|
_clearBtn = new QPushButton;
|
|
|
|
_clearBtn->setText(tr("Clear"));
|
|
|
|
_clearBtn->setToolTip(tr("Clear the log display."));
|
|
|
|
btnbox->addButton(_clearBtn, QDialogButtonBox::ActionRole);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(_clearBtn, &QAbstractButton::clicked, this, &LogBrowser::slotClearLog);
|
2012-07-16 23:11:19 +04:00
|
|
|
|
2012-06-05 17:11:29 +04:00
|
|
|
// save Button
|
|
|
|
_saveBtn = new QPushButton;
|
|
|
|
_saveBtn->setText(tr("S&ave"));
|
|
|
|
_saveBtn->setToolTip(tr("Save the log file to a file on disk for debugging."));
|
|
|
|
btnbox->addButton(_saveBtn, QDialogButtonBox::ActionRole);
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(_saveBtn, &QAbstractButton::clicked, this, &LogBrowser::slotSave);
|
2012-06-05 17:11:29 +04:00
|
|
|
|
|
|
|
setLayout(mainLayout);
|
|
|
|
|
|
|
|
setModal(false);
|
|
|
|
|
2016-12-08 19:30:41 +03:00
|
|
|
Logger::instance()->setLogWindowActivated(true);
|
2015-10-05 07:21:19 +03:00
|
|
|
// Direct connection for log coming from this thread, and queued for the one in a different thread
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(Logger::instance(), &Logger::logWindowLog, this, &LogBrowser::slotNewLog, Qt::AutoConnection);
|
2013-07-10 11:22:20 +04:00
|
|
|
|
2013-08-14 19:46:58 +04:00
|
|
|
QAction *showLogWindow = new QAction(this);
|
|
|
|
showLogWindow->setShortcut(QKeySequence("F12"));
|
2017-09-20 11:14:48 +03:00
|
|
|
connect(showLogWindow, &QAction::triggered, this, &QWidget::close);
|
2013-08-14 19:46:58 +04:00
|
|
|
addAction(showLogWindow);
|
|
|
|
|
2014-11-10 00:30:29 +03:00
|
|
|
ConfigFile cfg;
|
2013-07-22 14:28:43 +04:00
|
|
|
cfg.restoreGeometry(this);
|
2013-08-15 15:02:27 +04:00
|
|
|
int lines = cfg.maxLogLines();
|
|
|
|
_logWidget->document()->setMaximumBlockCount(lines);
|
2012-06-05 17:11:29 +04:00
|
|
|
}
|
|
|
|
|
2012-06-15 15:04:23 +04:00
|
|
|
LogBrowser::~LogBrowser()
|
2013-09-20 16:18:28 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-05-09 18:04:04 +03:00
|
|
|
void LogBrowser::showEvent(QShowEvent *)
|
|
|
|
{
|
|
|
|
// This could have been changed through the --logdebug argument passed through the single application.
|
|
|
|
_logDebugCheckBox->setCheckState(Logger::instance()->logDebug() ? Qt::Checked : Qt::Unchecked);
|
|
|
|
}
|
|
|
|
|
2013-09-20 16:18:28 +04:00
|
|
|
void LogBrowser::closeEvent(QCloseEvent *)
|
2012-06-15 15:04:23 +04:00
|
|
|
{
|
2014-11-10 00:30:29 +03:00
|
|
|
ConfigFile cfg;
|
2013-08-23 14:41:29 +04:00
|
|
|
cfg.saveGeometry(this);
|
2012-06-15 15:04:23 +04:00
|
|
|
}
|
|
|
|
|
2013-09-20 16:18:28 +04:00
|
|
|
|
2012-06-05 17:11:29 +04:00
|
|
|
void LogBrowser::slotNewLog(const QString &msg)
|
|
|
|
{
|
2013-08-18 15:28:40 +04:00
|
|
|
if (_logWidget->isVisible()) {
|
|
|
|
_logWidget->appendPlainText(msg);
|
|
|
|
}
|
2012-06-15 15:04:23 +04:00
|
|
|
}
|
|
|
|
|
2012-06-05 17:11:29 +04:00
|
|
|
|
|
|
|
void LogBrowser::slotFind()
|
|
|
|
{
|
|
|
|
QString searchText = _findTermEdit->text();
|
|
|
|
|
|
|
|
if (searchText.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
search(searchText);
|
|
|
|
}
|
|
|
|
|
2017-05-09 18:04:04 +03:00
|
|
|
void LogBrowser::slotDebugCheckStateChanged(int checkState)
|
|
|
|
{
|
|
|
|
Logger::instance()->setLogDebug(checkState == Qt::Checked);
|
|
|
|
}
|
|
|
|
|
2012-06-05 17:11:29 +04:00
|
|
|
void LogBrowser::search(const QString &str)
|
|
|
|
{
|
|
|
|
QList<QTextEdit::ExtraSelection> extraSelections;
|
|
|
|
|
|
|
|
_logWidget->moveCursor(QTextCursor::Start);
|
|
|
|
QColor color = QColor(Qt::gray).lighter(130);
|
|
|
|
_statusLabel->clear();
|
|
|
|
|
|
|
|
while (_logWidget->find(str)) {
|
|
|
|
QTextEdit::ExtraSelection extra;
|
|
|
|
extra.format.setBackground(color);
|
|
|
|
|
|
|
|
extra.cursor = _logWidget->textCursor();
|
|
|
|
extraSelections.append(extra);
|
|
|
|
}
|
|
|
|
|
2012-08-17 19:13:17 +04:00
|
|
|
QString stat = QString::fromLatin1("Search term %1 with %2 search results.").arg(str).arg(extraSelections.count());
|
2012-06-05 17:11:29 +04:00
|
|
|
_statusLabel->setText(stat);
|
|
|
|
|
|
|
|
_logWidget->setExtraSelections(extraSelections);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LogBrowser::slotSave()
|
|
|
|
{
|
|
|
|
_saveBtn->setEnabled(false);
|
|
|
|
|
|
|
|
QString saveFile = QFileDialog::getSaveFileName(this, tr("Save log file"), QDir::homePath());
|
|
|
|
|
|
|
|
if (!saveFile.isEmpty()) {
|
|
|
|
QFile file(saveFile);
|
|
|
|
|
2012-06-15 15:04:23 +04:00
|
|
|
if (file.open(QIODevice::WriteOnly)) {
|
2012-06-05 17:11:29 +04:00
|
|
|
QTextStream stream(&file);
|
|
|
|
stream << _logWidget->toPlainText();
|
|
|
|
file.close();
|
|
|
|
} else {
|
2015-02-06 00:00:13 +03:00
|
|
|
QMessageBox::critical(this, tr("Error"), tr("Could not write to log file %1").arg(saveFile));
|
2012-06-05 17:11:29 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
_saveBtn->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
2012-07-16 23:11:19 +04:00
|
|
|
void LogBrowser::slotClearLog()
|
|
|
|
{
|
|
|
|
_logWidget->clear();
|
|
|
|
}
|
|
|
|
|
2018-04-10 14:07:20 +03:00
|
|
|
void LogBrowser::togglePermanentLogging(bool enabled)
|
|
|
|
{
|
|
|
|
ConfigFile().setAutomaticLogDir(enabled);
|
|
|
|
|
|
|
|
auto logger = Logger::instance();
|
|
|
|
if (enabled) {
|
|
|
|
if (!logger->isLoggingToFile()) {
|
|
|
|
logger->setupTemporaryFolderLogDir();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
logger->disableTemporaryFolderLogDir();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-05 17:11:29 +04:00
|
|
|
} // namespace
|