Add a page to view launcher logs (#3831)
This commit is contained in:
commit
9f9aabcf97
17 changed files with 320 additions and 66 deletions
|
@ -52,6 +52,7 @@
|
|||
#include "tools/GenericProfiler.h"
|
||||
#include "ui/InstanceWindow.h"
|
||||
#include "ui/MainWindow.h"
|
||||
#include "ui/ViewLogWindow.h"
|
||||
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/instanceview/AccessibleInstanceView.h"
|
||||
|
@ -244,8 +245,11 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext& context, const QSt
|
|||
}
|
||||
|
||||
QString out = qFormatLogMessage(type, context, msg);
|
||||
out += QChar::LineFeed;
|
||||
if (APPLICATION->logModel) {
|
||||
APPLICATION->logModel->append(MessageLevel::getLevel(type), out);
|
||||
}
|
||||
|
||||
out += QChar::LineFeed;
|
||||
APPLICATION->logFile->write(out.toUtf8());
|
||||
APPLICATION->logFile->flush();
|
||||
|
||||
|
@ -538,6 +542,8 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
|||
qInstallMessageHandler(appDebugOutput);
|
||||
qSetMessagePattern(defaultLogFormat);
|
||||
|
||||
logModel.reset(new LogModel(this));
|
||||
|
||||
bool foundLoggingRules = false;
|
||||
|
||||
auto logRulesFile = QStringLiteral("qtlogging.ini");
|
||||
|
@ -691,6 +697,10 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
|||
m_settings->registerSetting("ConsoleMaxLines", 100000);
|
||||
m_settings->registerSetting("ConsoleOverflowStop", true);
|
||||
|
||||
logModel->setMaxLines(getConsoleMaxLines(settings()));
|
||||
logModel->setStopOnOverflow(shouldStopOnConsoleOverflow(settings()));
|
||||
logModel->setOverflowMessage(tr("Cannot display this log since the log length surpassed %1 lines.").arg(logModel->getMaxLines()));
|
||||
|
||||
// Folders
|
||||
m_settings->registerSetting("InstanceDir", "instances");
|
||||
m_settings->registerSetting({ "CentralModsDir", "ModsDir" }, "mods");
|
||||
|
@ -1683,6 +1693,20 @@ MainWindow* Application::showMainWindow(bool minimized)
|
|||
return m_mainWindow;
|
||||
}
|
||||
|
||||
ViewLogWindow* Application::showLogWindow()
|
||||
{
|
||||
if (m_viewLogWindow) {
|
||||
m_viewLogWindow->setWindowState(m_viewLogWindow->windowState() & ~Qt::WindowMinimized);
|
||||
m_viewLogWindow->raise();
|
||||
m_viewLogWindow->activateWindow();
|
||||
} else {
|
||||
m_viewLogWindow = new ViewLogWindow();
|
||||
connect(m_viewLogWindow, &ViewLogWindow::isClosing, this, &Application::on_windowClose);
|
||||
m_openWindows++;
|
||||
}
|
||||
return m_viewLogWindow;
|
||||
}
|
||||
|
||||
InstanceWindow* Application::showInstanceWindow(InstancePtr instance, QString page)
|
||||
{
|
||||
if (!instance)
|
||||
|
@ -1737,6 +1761,10 @@ void Application::on_windowClose()
|
|||
if (mainWindow) {
|
||||
m_mainWindow = nullptr;
|
||||
}
|
||||
auto logWindow = qobject_cast<ViewLogWindow*>(sender());
|
||||
if (logWindow) {
|
||||
m_viewLogWindow = nullptr;
|
||||
}
|
||||
// quit when there are no more windows.
|
||||
if (shouldExitNow()) {
|
||||
exit(0);
|
||||
|
|
|
@ -48,12 +48,14 @@
|
|||
|
||||
#include <BaseInstance.h>
|
||||
|
||||
#include "launch/LogModel.h"
|
||||
#include "minecraft/launch/MinecraftTarget.h"
|
||||
|
||||
class LaunchController;
|
||||
class LocalPeer;
|
||||
class InstanceWindow;
|
||||
class MainWindow;
|
||||
class ViewLogWindow;
|
||||
class SetupWizard;
|
||||
class GenericPageProvider;
|
||||
class QFile;
|
||||
|
@ -182,6 +184,7 @@ class Application : public QApplication {
|
|||
|
||||
InstanceWindow* showInstanceWindow(InstancePtr instance, QString page = QString());
|
||||
MainWindow* showMainWindow(bool minimized = false);
|
||||
ViewLogWindow* showLogWindow();
|
||||
|
||||
void updateIsRunning(bool running);
|
||||
bool updatesAreAllowed();
|
||||
|
@ -289,6 +292,9 @@ class Application : public QApplication {
|
|||
// main window, if any
|
||||
MainWindow* m_mainWindow = nullptr;
|
||||
|
||||
// log window, if any
|
||||
ViewLogWindow* m_viewLogWindow = nullptr;
|
||||
|
||||
// peer launcher instance connector - used to implement single instance launcher and signalling
|
||||
LocalPeer* m_peerInstance = nullptr;
|
||||
|
||||
|
@ -307,6 +313,7 @@ class Application : public QApplication {
|
|||
QList<QUrl> m_urlsToImport;
|
||||
QString m_instanceIdToShowWindowOf;
|
||||
std::unique_ptr<QFile> logFile;
|
||||
shared_qobject_ptr<LogModel> logModel;
|
||||
|
||||
public:
|
||||
void addQSavePath(QString);
|
||||
|
|
|
@ -53,6 +53,23 @@
|
|||
#include "Commandline.h"
|
||||
#include "FileSystem.h"
|
||||
|
||||
int getConsoleMaxLines(SettingsObjectPtr settings)
|
||||
{
|
||||
auto lineSetting = settings->getSetting("ConsoleMaxLines");
|
||||
bool conversionOk = false;
|
||||
int maxLines = lineSetting->get().toInt(&conversionOk);
|
||||
if (!conversionOk) {
|
||||
maxLines = lineSetting->defValue().toInt();
|
||||
qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines;
|
||||
}
|
||||
return maxLines;
|
||||
}
|
||||
|
||||
bool shouldStopOnConsoleOverflow(SettingsObjectPtr settings)
|
||||
{
|
||||
return settings->get("ConsoleOverflowStop").toBool();
|
||||
}
|
||||
|
||||
BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) : QObject()
|
||||
{
|
||||
m_settings = settings;
|
||||
|
@ -184,23 +201,6 @@ void BaseInstance::copyManagedPack(BaseInstance& other)
|
|||
}
|
||||
}
|
||||
|
||||
int BaseInstance::getConsoleMaxLines() const
|
||||
{
|
||||
auto lineSetting = m_settings->getSetting("ConsoleMaxLines");
|
||||
bool conversionOk = false;
|
||||
int maxLines = lineSetting->get().toInt(&conversionOk);
|
||||
if (!conversionOk) {
|
||||
maxLines = lineSetting->defValue().toInt();
|
||||
qWarning() << "ConsoleMaxLines has nonsensical value, defaulting to" << maxLines;
|
||||
}
|
||||
return maxLines;
|
||||
}
|
||||
|
||||
bool BaseInstance::shouldStopOnConsoleOverflow() const
|
||||
{
|
||||
return m_settings->get("ConsoleOverflowStop").toBool();
|
||||
}
|
||||
|
||||
QStringList BaseInstance::getLinkedInstances() const
|
||||
{
|
||||
auto setting = m_settings->get("linkedInstances").toString();
|
||||
|
|
|
@ -78,6 +78,10 @@ struct ShortcutData {
|
|||
ShortcutTarget target = ShortcutTarget::Other;
|
||||
};
|
||||
|
||||
/// Console settings
|
||||
int getConsoleMaxLines(SettingsObjectPtr settings);
|
||||
bool shouldStopOnConsoleOverflow(SettingsObjectPtr settings);
|
||||
|
||||
/*!
|
||||
* \brief Base class for instances.
|
||||
* This class implements many functions that are common between instances and
|
||||
|
@ -272,9 +276,6 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
|
|||
|
||||
Status currentStatus() const;
|
||||
|
||||
int getConsoleMaxLines() const;
|
||||
bool shouldStopOnConsoleOverflow() const;
|
||||
|
||||
QStringList getLinkedInstances() const;
|
||||
void setLinkedInstances(const QStringList& list);
|
||||
void addLinkedInstanceId(const QString& id);
|
||||
|
|
|
@ -847,6 +847,8 @@ SET(LAUNCHER_SOURCES
|
|||
ui/MainWindow.cpp
|
||||
ui/InstanceWindow.h
|
||||
ui/InstanceWindow.cpp
|
||||
ui/ViewLogWindow.h
|
||||
ui/ViewLogWindow.cpp
|
||||
|
||||
# FIXME: maybe find a better home for this.
|
||||
FileIgnoreProxy.cpp
|
||||
|
|
|
@ -46,7 +46,7 @@ class InstancePageProvider : protected QObject, public BasePageProvider {
|
|||
// values.append(new GameOptionsPage(onesix.get()));
|
||||
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
|
||||
values.append(new InstanceSettingsPage(onesix));
|
||||
values.append(new OtherLogsPage(inst));
|
||||
values.append(new OtherLogsPage("logs", tr("Other logs"), "Other-Logs", inst));
|
||||
return values;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ MessageLevel::Enum MessageLevel::getLevel(const QString& levelName)
|
|||
return MessageLevel::Message;
|
||||
else if (name == "WARNING" || name == "WARN")
|
||||
return MessageLevel::Warning;
|
||||
else if (name == "ERROR")
|
||||
else if (name == "ERROR" || name == "CRITICAL")
|
||||
return MessageLevel::Error;
|
||||
else if (name == "FATAL")
|
||||
return MessageLevel::Fatal;
|
||||
|
@ -25,6 +25,24 @@ MessageLevel::Enum MessageLevel::getLevel(const QString& levelName)
|
|||
return MessageLevel::Unknown;
|
||||
}
|
||||
|
||||
MessageLevel::Enum MessageLevel::getLevel(QtMsgType type)
|
||||
{
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
return MessageLevel::Debug;
|
||||
case QtInfoMsg:
|
||||
return MessageLevel::Info;
|
||||
case QtWarningMsg:
|
||||
return MessageLevel::Warning;
|
||||
case QtCriticalMsg:
|
||||
return MessageLevel::Error;
|
||||
case QtFatalMsg:
|
||||
return MessageLevel::Fatal;
|
||||
default:
|
||||
return MessageLevel::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
MessageLevel::Enum MessageLevel::fromLine(QString& line)
|
||||
{
|
||||
// Level prefix
|
||||
|
@ -36,3 +54,18 @@ MessageLevel::Enum MessageLevel::fromLine(QString& line)
|
|||
}
|
||||
return MessageLevel::Unknown;
|
||||
}
|
||||
|
||||
MessageLevel::Enum MessageLevel::fromLauncherLine(QString& line)
|
||||
{
|
||||
// Level prefix
|
||||
int startMark = 0;
|
||||
while (startMark < line.size() && (line[startMark].isDigit() || line[startMark].isSpace() || line[startMark] == '.'))
|
||||
++startMark;
|
||||
int endmark = line.indexOf(":");
|
||||
if (startMark < line.size() && endmark != -1) {
|
||||
auto level = MessageLevel::getLevel(line.left(endmark).mid(startMark));
|
||||
line = line.mid(endmark + 2);
|
||||
return level;
|
||||
}
|
||||
return MessageLevel::Unknown;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QtLogging>
|
||||
|
||||
/**
|
||||
* @brief the MessageLevel Enum
|
||||
|
@ -21,7 +22,11 @@ enum Enum {
|
|||
Fatal, /**< Fatal Errors */
|
||||
};
|
||||
MessageLevel::Enum getLevel(const QString& levelName);
|
||||
MessageLevel::Enum getLevel(QtMsgType type);
|
||||
|
||||
/* Get message level from a line. Line is modified if it was successful. */
|
||||
MessageLevel::Enum fromLine(QString& line);
|
||||
|
||||
/* Get message level from a line from the launcher log. Line is modified if it was successful. */
|
||||
MessageLevel::Enum fromLauncherLine(QString& line);
|
||||
} // namespace MessageLevel
|
||||
|
|
|
@ -203,8 +203,8 @@ shared_qobject_ptr<LogModel> LaunchTask::getLogModel()
|
|||
{
|
||||
if (!m_logModel) {
|
||||
m_logModel.reset(new LogModel());
|
||||
m_logModel->setMaxLines(m_instance->getConsoleMaxLines());
|
||||
m_logModel->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow());
|
||||
m_logModel->setMaxLines(getConsoleMaxLines(m_instance->settings()));
|
||||
m_logModel->setStopOnOverflow(shouldStopOnConsoleOverflow(m_instance->settings()));
|
||||
// FIXME: should this really be here?
|
||||
m_logModel->setOverflowMessage(tr("Stopped watching the game log because the log length surpassed %1 lines.\n"
|
||||
"You may have to fix your mods because the game is still logging to files and"
|
||||
|
|
|
@ -24,5 +24,5 @@ class ResourcePack : public DataPack {
|
|||
/** Gets, respectively, the lower and upper versions supported by the set pack format. */
|
||||
[[nodiscard]] std::pair<Version, Version> compatibleVersions() const override;
|
||||
|
||||
virtual QString directory() override { return "/assets"; }
|
||||
QString directory() override { return "/assets"; }
|
||||
};
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
#include "InstanceWindow.h"
|
||||
|
||||
#include "ui/GuiUtil.h"
|
||||
#include "ui/ViewLogWindow.h"
|
||||
#include "ui/dialogs/AboutDialog.h"
|
||||
#include "ui/dialogs/CopyInstanceDialog.h"
|
||||
#include "ui/dialogs/CreateShortcutDialog.h"
|
||||
|
@ -238,14 +239,8 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi
|
|||
ui->actionViewJavaFolder->setEnabled(BuildConfig.JAVA_DOWNLOADER_ENABLED);
|
||||
}
|
||||
|
||||
{ // logs upload
|
||||
|
||||
auto menu = new QMenu(this);
|
||||
for (auto file : QDir("logs").entryInfoList(QDir::Files)) {
|
||||
auto action = menu->addAction(file.fileName());
|
||||
connect(action, &QAction::triggered, this, [this, file] { GuiUtil::uploadPaste(file.fileName(), file, this); });
|
||||
}
|
||||
ui->actionUploadLog->setMenu(menu);
|
||||
{ // logs viewing
|
||||
connect(ui->actionViewLog, &QAction::triggered, this, [] { APPLICATION->showLogWindow(); });
|
||||
}
|
||||
|
||||
// add the toolbar toggles to the view menu
|
||||
|
|
|
@ -215,7 +215,7 @@
|
|||
</property>
|
||||
<addaction name="actionClearMetadata"/>
|
||||
<addaction name="actionReportBug"/>
|
||||
<addaction name="actionUploadLog"/>
|
||||
<addaction name="actionViewLog"/>
|
||||
<addaction name="actionAddToPATH"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionMATRIX"/>
|
||||
|
@ -663,16 +663,16 @@
|
|||
<string>Clear cached metadata</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUploadLog">
|
||||
<action name="actionViewLog">
|
||||
<property name="icon">
|
||||
<iconset theme="log">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Upload logs</string>
|
||||
<string>View logs</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Upload launcher logs to the selected log provider</string>
|
||||
<string>View current and previous launcher logs</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionAddToPATH">
|
||||
|
|
25
launcher/ui/ViewLogWindow.cpp
Normal file
25
launcher/ui/ViewLogWindow.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include <QCloseEvent>
|
||||
|
||||
#include "ViewLogWindow.h"
|
||||
|
||||
#include "ui/pages/instance/OtherLogsPage.h"
|
||||
|
||||
ViewLogWindow::ViewLogWindow(QWidget* parent)
|
||||
: QMainWindow(parent), m_page(new OtherLogsPage("launcher-logs", tr("Launcher Logs"), "Launcher-Logs", nullptr, parent))
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowIcon(APPLICATION->getThemedIcon("log"));
|
||||
setWindowTitle(tr("View Launcher Logs"));
|
||||
setCentralWidget(m_page);
|
||||
setMinimumSize(m_page->size());
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
m_page->opened();
|
||||
show();
|
||||
}
|
||||
|
||||
void ViewLogWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
m_page->closed();
|
||||
emit isClosing();
|
||||
event->accept();
|
||||
}
|
23
launcher/ui/ViewLogWindow.h
Normal file
23
launcher/ui/ViewLogWindow.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
class OtherLogsPage;
|
||||
|
||||
class ViewLogWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ViewLogWindow(QWidget* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void isClosing();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent*) override;
|
||||
|
||||
private:
|
||||
OtherLogsPage* m_page;
|
||||
};
|
|
@ -40,6 +40,7 @@
|
|||
#include <QMessageBox>
|
||||
|
||||
#include "ui/GuiUtil.h"
|
||||
#include "ui/themes/ThemeManager.h"
|
||||
|
||||
#include <FileSystem.h>
|
||||
#include <GZip.h>
|
||||
|
@ -49,18 +50,26 @@
|
|||
#include <QShortcut>
|
||||
#include <QUrl>
|
||||
|
||||
OtherLogsPage::OtherLogsPage(InstancePtr instance, QWidget* parent)
|
||||
OtherLogsPage::OtherLogsPage(QString id, QString displayName, QString helpPage, InstancePtr instance, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_id(id)
|
||||
, m_displayName(displayName)
|
||||
, m_helpPage(helpPage)
|
||||
, ui(new Ui::OtherLogsPage)
|
||||
, m_instance(instance)
|
||||
, m_basePath(instance->gameRoot())
|
||||
, m_logSearchPaths(instance->getLogFileSearchPaths())
|
||||
, m_model(new LogModel(this))
|
||||
, m_basePath(instance ? instance->gameRoot() : APPLICATION->dataRoot())
|
||||
, m_logSearchPaths(instance ? instance->getLogFileSearchPaths() : QStringList{ "logs" })
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->tabWidget->tabBar()->hide();
|
||||
|
||||
m_proxy = new LogFormatProxyModel(this);
|
||||
if (m_instance) {
|
||||
m_model.reset(new LogModel(this));
|
||||
ui->trackLogCheckbox->hide();
|
||||
} else {
|
||||
m_model = APPLICATION->logModel;
|
||||
}
|
||||
|
||||
// set up fonts in the log proxy
|
||||
{
|
||||
|
@ -75,9 +84,13 @@ OtherLogsPage::OtherLogsPage(InstancePtr instance, QWidget* parent)
|
|||
|
||||
ui->text->setModel(m_proxy);
|
||||
|
||||
m_model->setMaxLines(m_instance->getConsoleMaxLines());
|
||||
m_model->setStopOnOverflow(m_instance->shouldStopOnConsoleOverflow());
|
||||
m_model->setOverflowMessage(tr("Cannot display this log since the log length surpassed %1 lines.").arg(m_model->getMaxLines()));
|
||||
if (m_instance) {
|
||||
m_model->setMaxLines(getConsoleMaxLines(m_instance->settings()));
|
||||
m_model->setStopOnOverflow(shouldStopOnConsoleOverflow(m_instance->settings()));
|
||||
m_model->setOverflowMessage(tr("Cannot display this log since the log length surpassed %1 lines.").arg(m_model->getMaxLines()));
|
||||
} else {
|
||||
modelStateToUI();
|
||||
}
|
||||
m_proxy->setSourceModel(m_model.get());
|
||||
|
||||
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &OtherLogsPage::populateSelectLogBox);
|
||||
|
@ -99,6 +112,39 @@ OtherLogsPage::~OtherLogsPage()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void OtherLogsPage::modelStateToUI()
|
||||
{
|
||||
if (m_model->wrapLines()) {
|
||||
ui->text->setWordWrap(true);
|
||||
ui->wrapCheckbox->setCheckState(Qt::Checked);
|
||||
} else {
|
||||
ui->text->setWordWrap(false);
|
||||
ui->wrapCheckbox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
if (m_model->colorLines()) {
|
||||
ui->text->setColorLines(true);
|
||||
ui->colorCheckbox->setCheckState(Qt::Checked);
|
||||
} else {
|
||||
ui->text->setColorLines(false);
|
||||
ui->colorCheckbox->setCheckState(Qt::Unchecked);
|
||||
}
|
||||
if (m_model->suspended()) {
|
||||
ui->trackLogCheckbox->setCheckState(Qt::Unchecked);
|
||||
} else {
|
||||
ui->trackLogCheckbox->setCheckState(Qt::Checked);
|
||||
}
|
||||
}
|
||||
|
||||
void OtherLogsPage::UIToModelState()
|
||||
{
|
||||
if (!m_model) {
|
||||
return;
|
||||
}
|
||||
m_model->setLineWrap(ui->wrapCheckbox->checkState() == Qt::Checked);
|
||||
m_model->setColorLines(ui->colorCheckbox->checkState() == Qt::Checked);
|
||||
m_model->suspend(ui->trackLogCheckbox->checkState() != Qt::Checked);
|
||||
}
|
||||
|
||||
void OtherLogsPage::retranslate()
|
||||
{
|
||||
ui->retranslateUi(this);
|
||||
|
@ -136,6 +182,8 @@ void OtherLogsPage::populateSelectLogBox()
|
|||
|
||||
ui->selectLogBox->blockSignals(true);
|
||||
ui->selectLogBox->clear();
|
||||
if (!m_instance)
|
||||
ui->selectLogBox->addItem("Current logs");
|
||||
ui->selectLogBox->addItems(getPaths());
|
||||
ui->selectLogBox->blockSignals(false);
|
||||
|
||||
|
@ -151,6 +199,9 @@ void OtherLogsPage::populateSelectLogBox()
|
|||
} else {
|
||||
setControlsEnabled(false);
|
||||
}
|
||||
} else if (!m_instance) {
|
||||
ui->selectLogBox->setCurrentIndex(0);
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
|
||||
on_selectLogBox_currentIndexChanged(ui->selectLogBox->currentIndex());
|
||||
|
@ -159,27 +210,50 @@ void OtherLogsPage::populateSelectLogBox()
|
|||
void OtherLogsPage::on_selectLogBox_currentIndexChanged(const int index)
|
||||
{
|
||||
QString file;
|
||||
if (index != -1) {
|
||||
if (index > 0 || (index == 0 && m_instance)) {
|
||||
file = ui->selectLogBox->itemText(index);
|
||||
}
|
||||
|
||||
if (file.isEmpty() || !QFile::exists(FS::PathCombine(m_basePath, file))) {
|
||||
if ((index != 0 || m_instance) && (file.isEmpty() || !QFile::exists(FS::PathCombine(m_basePath, file)))) {
|
||||
m_currentFile = QString();
|
||||
ui->text->clear();
|
||||
setControlsEnabled(false);
|
||||
} else {
|
||||
m_currentFile = file;
|
||||
on_btnReload_clicked();
|
||||
reload();
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_btnReload_clicked()
|
||||
{
|
||||
if (!m_instance && m_currentFile.isEmpty()) {
|
||||
if (!m_model)
|
||||
return;
|
||||
m_model->clear();
|
||||
if (m_container)
|
||||
m_container->refreshContainer();
|
||||
} else {
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
void OtherLogsPage::reload()
|
||||
{
|
||||
if (m_currentFile.isEmpty()) {
|
||||
setControlsEnabled(false);
|
||||
if (m_instance) {
|
||||
setControlsEnabled(false);
|
||||
} else {
|
||||
m_model = APPLICATION->logModel;
|
||||
m_proxy->setSourceModel(m_model.get());
|
||||
ui->text->setModel(m_proxy);
|
||||
ui->text->scrollToBottom();
|
||||
UIToModelState();
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(FS::PathCombine(m_basePath, m_currentFile));
|
||||
if (!file.open(QFile::ReadOnly)) {
|
||||
setControlsEnabled(false);
|
||||
|
@ -210,15 +284,20 @@ void OtherLogsPage::on_btnReload_clicked()
|
|||
line = line.remove(line.size() - 1, 1);
|
||||
MessageLevel::Enum level = MessageLevel::Unknown;
|
||||
|
||||
// if the launcher part set a log level, use it
|
||||
auto innerLevel = MessageLevel::fromLine(line);
|
||||
if (innerLevel != MessageLevel::Unknown) {
|
||||
level = innerLevel;
|
||||
}
|
||||
QString lineTemp = line; // don't edit out the time and level for clarity
|
||||
if (!m_instance) {
|
||||
level = MessageLevel::fromLauncherLine(lineTemp);
|
||||
} else {
|
||||
// if the launcher part set a log level, use it
|
||||
auto innerLevel = MessageLevel::fromLine(lineTemp);
|
||||
if (innerLevel != MessageLevel::Unknown) {
|
||||
level = innerLevel;
|
||||
}
|
||||
|
||||
// If the level is still undetermined, guess level
|
||||
if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) {
|
||||
level = LogParser::guessLevel(line, last);
|
||||
// If the level is still undetermined, guess level
|
||||
if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) {
|
||||
level = LogParser::guessLevel(line, last);
|
||||
}
|
||||
}
|
||||
|
||||
last = level;
|
||||
|
@ -229,6 +308,12 @@ void OtherLogsPage::on_btnReload_clicked()
|
|||
// Try to determine a level for each line
|
||||
ui->text->clear();
|
||||
ui->text->setModel(nullptr);
|
||||
if (!m_instance) {
|
||||
m_model.reset(new LogModel(this));
|
||||
m_model->setMaxLines(getConsoleMaxLines(APPLICATION->settings()));
|
||||
m_model->setStopOnOverflow(shouldStopOnConsoleOverflow(APPLICATION->settings()));
|
||||
m_model->setOverflowMessage(tr("Cannot display this log since the log length surpassed %1 lines.").arg(m_model->getMaxLines()));
|
||||
}
|
||||
m_model->clear();
|
||||
if (file.fileName().endsWith(".gz")) {
|
||||
QString line;
|
||||
|
@ -258,14 +343,24 @@ void OtherLogsPage::on_btnReload_clicked()
|
|||
while (!file.atEnd() && !handleLine(QString::fromUtf8(file.readLine()))) {
|
||||
}
|
||||
}
|
||||
ui->text->setModel(m_proxy);
|
||||
ui->text->scrollToBottom();
|
||||
|
||||
if (m_instance) {
|
||||
ui->text->setModel(m_proxy);
|
||||
ui->text->scrollToBottom();
|
||||
} else {
|
||||
m_proxy->setSourceModel(m_model.get());
|
||||
ui->text->setModel(m_proxy);
|
||||
ui->text->scrollToBottom();
|
||||
UIToModelState();
|
||||
setControlsEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_btnPaste_clicked()
|
||||
{
|
||||
GuiUtil::uploadPaste(m_currentFile, ui->text->toPlainText(), this);
|
||||
QString name = m_currentFile.isEmpty() ? displayName() : m_currentFile;
|
||||
GuiUtil::uploadPaste(name, ui->text->toPlainText(), this);
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_btnCopy_clicked()
|
||||
|
@ -278,6 +373,13 @@ void OtherLogsPage::on_btnBottom_clicked()
|
|||
ui->text->scrollToBottom();
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_trackLogCheckbox_clicked(bool checked)
|
||||
{
|
||||
if (!m_model)
|
||||
return;
|
||||
m_model->suspend(!checked);
|
||||
}
|
||||
|
||||
void OtherLogsPage::on_btnDelete_clicked()
|
||||
{
|
||||
if (m_currentFile.isEmpty()) {
|
||||
|
@ -376,12 +478,27 @@ void OtherLogsPage::on_colorCheckbox_clicked(bool checked)
|
|||
|
||||
void OtherLogsPage::setControlsEnabled(const bool enabled)
|
||||
{
|
||||
if (m_instance) {
|
||||
ui->btnDelete->setEnabled(enabled);
|
||||
ui->btnClean->setEnabled(enabled);
|
||||
} else if (!m_currentFile.isEmpty()) {
|
||||
ui->btnReload->setText("&Reload");
|
||||
ui->btnReload->setToolTip("Reload the contents of the log from the disk");
|
||||
ui->btnDelete->setEnabled(enabled);
|
||||
ui->btnClean->setEnabled(enabled);
|
||||
ui->trackLogCheckbox->setEnabled(false);
|
||||
} else {
|
||||
ui->btnReload->setText("Clear");
|
||||
ui->btnReload->setToolTip("Clear the log");
|
||||
ui->btnDelete->setEnabled(false);
|
||||
ui->btnClean->setEnabled(false);
|
||||
ui->trackLogCheckbox->setEnabled(enabled);
|
||||
}
|
||||
|
||||
ui->btnReload->setEnabled(enabled);
|
||||
ui->btnDelete->setEnabled(enabled);
|
||||
ui->btnCopy->setEnabled(enabled);
|
||||
ui->btnPaste->setEnabled(enabled);
|
||||
ui->text->setEnabled(enabled);
|
||||
ui->btnClean->setEnabled(enabled);
|
||||
}
|
||||
|
||||
QStringList OtherLogsPage::getPaths()
|
||||
|
|
|
@ -53,13 +53,13 @@ class OtherLogsPage : public QWidget, public BasePage {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OtherLogsPage(InstancePtr instance, QWidget* parent = 0);
|
||||
explicit OtherLogsPage(QString id, QString displayName, QString helpPage, InstancePtr instance = nullptr, QWidget* parent = 0);
|
||||
~OtherLogsPage();
|
||||
|
||||
QString id() const override { return "logs"; }
|
||||
QString displayName() const override { return tr("Other logs"); }
|
||||
QString id() const override { return m_id; }
|
||||
QString displayName() const override { return m_displayName; }
|
||||
QIcon icon() const override { return APPLICATION->getThemedIcon("log"); }
|
||||
QString helpPage() const override { return "other-Logs"; }
|
||||
QString helpPage() const override { return m_helpPage; }
|
||||
void retranslate() override;
|
||||
|
||||
void openedImpl() override;
|
||||
|
@ -75,6 +75,7 @@ class OtherLogsPage : public QWidget, public BasePage {
|
|||
void on_btnClean_clicked();
|
||||
void on_btnBottom_clicked();
|
||||
|
||||
void on_trackLogCheckbox_clicked(bool checked);
|
||||
void on_wrapCheckbox_clicked(bool checked);
|
||||
void on_colorCheckbox_clicked(bool checked);
|
||||
|
||||
|
@ -84,11 +85,18 @@ class OtherLogsPage : public QWidget, public BasePage {
|
|||
void findPreviousActivated();
|
||||
|
||||
private:
|
||||
void reload();
|
||||
void modelStateToUI();
|
||||
void UIToModelState();
|
||||
void setControlsEnabled(bool enabled);
|
||||
|
||||
QStringList getPaths();
|
||||
|
||||
private:
|
||||
QString m_id;
|
||||
QString m_displayName;
|
||||
QString m_helpPage;
|
||||
|
||||
Ui::OtherLogsPage* ui;
|
||||
InstancePtr m_instance;
|
||||
/** Path to display log paths relative to. */
|
||||
|
|
|
@ -127,6 +127,16 @@
|
|||
</item>
|
||||
<item row="1" column="0" colspan="5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout1">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="trackLogCheckbox">
|
||||
<property name="text">
|
||||
<string>Keep updating</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="wrapCheckbox">
|
||||
<property name="text">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue