mirror of
https://github.com/obhq/obliteration.git
synced 2024-11-23 03:09:52 +00:00
Removes Qt log viewer (#1122)
This commit is contained in:
parent
c25bf3e09d
commit
89dfe18453
@ -24,7 +24,6 @@ We use icons from https://materialdesignicons.com for UI.
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
- `src/ansi_escape.hpp`, `src/ansi_escape.cpp`, `src/log_formatter.hpp` and `src/log_formatter.cpp` are licensed under GPL-3.0 only.
|
|
||||||
- `src/param`, `src/pfs` and `src/pkg` are licensed under LGPL-3.0.
|
- `src/param`, `src/pfs` and `src/pkg` are licensed under LGPL-3.0.
|
||||||
- All other source code are licensed under either MIT License or Apache License, Version 2.0; or both.
|
- All other source code are licensed under either MIT License or Apache License, Version 2.0; or both.
|
||||||
- All release binaries are under GPL-3.0.
|
- All release binaries are under GPL-3.0.
|
||||||
|
@ -12,7 +12,6 @@ endif()
|
|||||||
|
|
||||||
# Setup GUI.
|
# Setup GUI.
|
||||||
add_executable(obliteration WIN32 MACOSX_BUNDLE
|
add_executable(obliteration WIN32 MACOSX_BUNDLE
|
||||||
ansi_escape.cpp
|
|
||||||
app_data.cpp
|
app_data.cpp
|
||||||
core.cpp
|
core.cpp
|
||||||
cpu_settings.cpp
|
cpu_settings.cpp
|
||||||
@ -20,8 +19,6 @@ add_executable(obliteration WIN32 MACOSX_BUNDLE
|
|||||||
game_models.cpp
|
game_models.cpp
|
||||||
initialize_wizard.cpp
|
initialize_wizard.cpp
|
||||||
launch_settings.cpp
|
launch_settings.cpp
|
||||||
log_formatter.cpp
|
|
||||||
logs_viewer.cpp
|
|
||||||
main.cpp
|
main.cpp
|
||||||
main_window.cpp
|
main_window.cpp
|
||||||
path.cpp
|
path.cpp
|
||||||
|
@ -1,257 +0,0 @@
|
|||||||
// This file is a derived works from Qt Creator.
|
|
||||||
// Licensed under GPL-3.0-only.
|
|
||||||
#include "ansi_escape.hpp"
|
|
||||||
|
|
||||||
static QColor ansiColor(uint code)
|
|
||||||
{
|
|
||||||
// QTC_ASSERT(code < 8, return QColor());
|
|
||||||
if (!(code < 8)) {
|
|
||||||
return QColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
const int red = code & 1 ? 170 : 0;
|
|
||||||
const int green = code & 2 ? 170 : 0;
|
|
||||||
const int blue = code & 4 ? 170 : 0;
|
|
||||||
|
|
||||||
return QColor(red, green, blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<FormattedText> AnsiEscape::parseText(const FormattedText &input)
|
|
||||||
{
|
|
||||||
enum AnsiEscapeCodes {
|
|
||||||
ResetFormat = 0,
|
|
||||||
BoldText = 1,
|
|
||||||
TextColorStart = 30,
|
|
||||||
TextColorEnd = 37,
|
|
||||||
RgbTextColor = 38,
|
|
||||||
DefaultTextColor = 39,
|
|
||||||
BackgroundColorStart = 40,
|
|
||||||
BackgroundColorEnd = 47,
|
|
||||||
RgbBackgroundColor = 48,
|
|
||||||
DefaultBackgroundColor = 49
|
|
||||||
};
|
|
||||||
|
|
||||||
const QString escape = "\x1b[";
|
|
||||||
const QChar semicolon = ';';
|
|
||||||
const QChar colorTerminator = 'm';
|
|
||||||
const QChar eraseToEol = 'K';
|
|
||||||
|
|
||||||
QList<FormattedText> outputData;
|
|
||||||
QTextCharFormat charFormat = m_previousFormatClosed ? input.format : m_previousFormat;
|
|
||||||
QString strippedText;
|
|
||||||
if (m_pendingText.isEmpty()) {
|
|
||||||
strippedText = input.text;
|
|
||||||
} else {
|
|
||||||
strippedText = m_pendingText.append(input.text);
|
|
||||||
m_pendingText.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!strippedText.isEmpty()) {
|
|
||||||
// QTC_ASSERT(m_pendingText.isEmpty(), break);
|
|
||||||
if (!m_pendingText.isEmpty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_waitingForTerminator) {
|
|
||||||
// We ignore all escape codes taking string arguments.
|
|
||||||
QString terminator = "\x1b\\";
|
|
||||||
int terminatorPos = strippedText.indexOf(terminator);
|
|
||||||
if (terminatorPos == -1 && !m_alternateTerminator.isEmpty()) {
|
|
||||||
terminator = m_alternateTerminator;
|
|
||||||
terminatorPos = strippedText.indexOf(terminator);
|
|
||||||
}
|
|
||||||
if (terminatorPos == -1) {
|
|
||||||
m_pendingText = strippedText;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
m_waitingForTerminator = false;
|
|
||||||
m_alternateTerminator.clear();
|
|
||||||
strippedText.remove(0, terminatorPos + terminator.length());
|
|
||||||
if (strippedText.isEmpty())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const int escapePos = strippedText.indexOf(escape.at(0));
|
|
||||||
if (escapePos < 0) {
|
|
||||||
outputData << FormattedText(strippedText, charFormat);
|
|
||||||
break;
|
|
||||||
} else if (escapePos != 0) {
|
|
||||||
outputData << FormattedText(strippedText.left(escapePos), charFormat);
|
|
||||||
strippedText.remove(0, escapePos);
|
|
||||||
}
|
|
||||||
|
|
||||||
// QTC_ASSERT(strippedText.at(0) == escape.at(0), break);
|
|
||||||
if (!(strippedText.at(0) == escape.at(0))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!strippedText.isEmpty() && escape.at(0) == strippedText.at(0)) {
|
|
||||||
if (escape.startsWith(strippedText)) {
|
|
||||||
// control secquence is not complete
|
|
||||||
m_pendingText += strippedText;
|
|
||||||
strippedText.clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strippedText.startsWith(escape)) {
|
|
||||||
switch (strippedText.at(1).toLatin1()) {
|
|
||||||
case '\\': // Unexpected terminator sequence.
|
|
||||||
Q_FALLTHROUGH();
|
|
||||||
case 'N': case 'O': // Ignore unsupported single-character sequences.
|
|
||||||
strippedText.remove(0, 2);
|
|
||||||
break;
|
|
||||||
case ']':
|
|
||||||
m_alternateTerminator = QChar(7);
|
|
||||||
Q_FALLTHROUGH();
|
|
||||||
case 'P': case 'X': case '^': case '_':
|
|
||||||
strippedText.remove(0, 2);
|
|
||||||
m_waitingForTerminator = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// not a control sequence
|
|
||||||
m_pendingText.clear();
|
|
||||||
outputData << FormattedText(strippedText.left(1), charFormat);
|
|
||||||
strippedText.remove(0, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
m_pendingText += strippedText.mid(0, escape.length());
|
|
||||||
strippedText.remove(0, escape.length());
|
|
||||||
|
|
||||||
// \e[K is not supported. Just strip it.
|
|
||||||
if (strippedText.startsWith(eraseToEol)) {
|
|
||||||
m_pendingText.clear();
|
|
||||||
strippedText.remove(0, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// get the number
|
|
||||||
QString strNumber;
|
|
||||||
QStringList numbers;
|
|
||||||
while (!strippedText.isEmpty()) {
|
|
||||||
if (strippedText.at(0).isDigit()) {
|
|
||||||
strNumber += strippedText.at(0);
|
|
||||||
} else {
|
|
||||||
if (!strNumber.isEmpty())
|
|
||||||
numbers << strNumber;
|
|
||||||
if (strNumber.isEmpty() || strippedText.at(0) != semicolon)
|
|
||||||
break;
|
|
||||||
strNumber.clear();
|
|
||||||
}
|
|
||||||
m_pendingText += strippedText.mid(0, 1);
|
|
||||||
strippedText.remove(0, 1);
|
|
||||||
}
|
|
||||||
if (strippedText.isEmpty())
|
|
||||||
break;
|
|
||||||
|
|
||||||
// remove terminating char
|
|
||||||
if (!strippedText.startsWith(colorTerminator)) {
|
|
||||||
m_pendingText.clear();
|
|
||||||
strippedText.remove(0, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// got consistent control sequence, ok to clear pending text
|
|
||||||
m_pendingText.clear();
|
|
||||||
strippedText.remove(0, 1);
|
|
||||||
|
|
||||||
if (numbers.isEmpty()) {
|
|
||||||
charFormat = input.format;
|
|
||||||
endFormatScope();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < numbers.size(); ++i) {
|
|
||||||
const uint code = numbers.at(i).toUInt();
|
|
||||||
|
|
||||||
if (code >= TextColorStart && code <= TextColorEnd) {
|
|
||||||
charFormat.setForeground(ansiColor(code - TextColorStart));
|
|
||||||
setFormatScope(charFormat);
|
|
||||||
} else if (code >= BackgroundColorStart && code <= BackgroundColorEnd) {
|
|
||||||
charFormat.setBackground(ansiColor(code - BackgroundColorStart));
|
|
||||||
setFormatScope(charFormat);
|
|
||||||
} else {
|
|
||||||
switch (code) {
|
|
||||||
case ResetFormat:
|
|
||||||
charFormat = input.format;
|
|
||||||
endFormatScope();
|
|
||||||
break;
|
|
||||||
case BoldText:
|
|
||||||
charFormat.setFontWeight(QFont::Bold);
|
|
||||||
setFormatScope(charFormat);
|
|
||||||
break;
|
|
||||||
case DefaultTextColor:
|
|
||||||
charFormat.setForeground(input.format.foreground());
|
|
||||||
setFormatScope(charFormat);
|
|
||||||
break;
|
|
||||||
case DefaultBackgroundColor:
|
|
||||||
charFormat.setBackground(input.format.background());
|
|
||||||
setFormatScope(charFormat);
|
|
||||||
break;
|
|
||||||
case RgbTextColor:
|
|
||||||
case RgbBackgroundColor:
|
|
||||||
// See http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
|
||||||
if (++i >= numbers.size())
|
|
||||||
break;
|
|
||||||
switch (numbers.at(i).toInt()) {
|
|
||||||
case 2:
|
|
||||||
// RGB set with format: 38;2;<r>;<g>;<b>
|
|
||||||
if ((i + 3) < numbers.size()) {
|
|
||||||
(code == RgbTextColor) ?
|
|
||||||
charFormat.setForeground(QColor(numbers.at(i + 1).toInt(),
|
|
||||||
numbers.at(i + 2).toInt(),
|
|
||||||
numbers.at(i + 3).toInt())) :
|
|
||||||
charFormat.setBackground(QColor(numbers.at(i + 1).toInt(),
|
|
||||||
numbers.at(i + 2).toInt(),
|
|
||||||
numbers.at(i + 3).toInt()));
|
|
||||||
setFormatScope(charFormat);
|
|
||||||
}
|
|
||||||
i += 3;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// 256 color mode with format: 38;5;<i>
|
|
||||||
uint index = numbers.at(i + 1).toUInt();
|
|
||||||
|
|
||||||
QColor color;
|
|
||||||
if (index < 8) {
|
|
||||||
// The first 8 colors are standard low-intensity ANSI colors.
|
|
||||||
color = ansiColor(index);
|
|
||||||
} else if (index < 16) {
|
|
||||||
// The next 8 colors are standard high-intensity ANSI colors.
|
|
||||||
color = ansiColor(index - 8).lighter(150);
|
|
||||||
} else if (index < 232) {
|
|
||||||
// The next 216 colors are a 6x6x6 RGB cube.
|
|
||||||
uint o = index - 16;
|
|
||||||
color = QColor((o / 36) * 51, ((o / 6) % 6) * 51, (o % 6) * 51);
|
|
||||||
} else {
|
|
||||||
// The last 24 colors are a greyscale gradient.
|
|
||||||
int grey = int((index - 232) * 11);
|
|
||||||
color = QColor(grey, grey, grey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (code == RgbTextColor)
|
|
||||||
charFormat.setForeground(color);
|
|
||||||
else
|
|
||||||
charFormat.setBackground(color);
|
|
||||||
|
|
||||||
setFormatScope(charFormat);
|
|
||||||
++i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return outputData;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnsiEscape::endFormatScope()
|
|
||||||
{
|
|
||||||
m_previousFormatClosed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AnsiEscape::setFormatScope(const QTextCharFormat &charFormat)
|
|
||||||
{
|
|
||||||
m_previousFormat = charFormat;
|
|
||||||
m_previousFormatClosed = false;
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
// This file is a derived works from Qt Creator.
|
|
||||||
// Licensed under GPL-3.0-only.
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QString>
|
|
||||||
#include <QTextCharFormat>
|
|
||||||
|
|
||||||
class FormattedText {
|
|
||||||
public:
|
|
||||||
FormattedText() = default;
|
|
||||||
FormattedText(const QString &txt, const QTextCharFormat &fmt = QTextCharFormat()) :
|
|
||||||
text(txt),
|
|
||||||
format(fmt)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QString text;
|
|
||||||
QTextCharFormat format;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AnsiEscape {
|
|
||||||
public:
|
|
||||||
QList<FormattedText> parseText(const FormattedText &input);
|
|
||||||
void endFormatScope();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setFormatScope(const QTextCharFormat &charFormat);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_previousFormatClosed = true;
|
|
||||||
bool m_waitingForTerminator = false;
|
|
||||||
QString m_alternateTerminator;
|
|
||||||
QTextCharFormat m_previousFormat;
|
|
||||||
QString m_pendingText;
|
|
||||||
};
|
|
@ -1,135 +0,0 @@
|
|||||||
// This file is a derived works from Qt Creator.
|
|
||||||
// Licensed under GPL-3.0-only.
|
|
||||||
#include "log_formatter.hpp"
|
|
||||||
|
|
||||||
#include <QBrush>
|
|
||||||
#include <QPlainTextEdit>
|
|
||||||
#include <QScrollBar>
|
|
||||||
|
|
||||||
static QString normalizeNewlines(const QString &text)
|
|
||||||
{
|
|
||||||
QString res = text;
|
|
||||||
const auto newEnd = std::unique(res.begin(), res.end(), [](const QChar c1, const QChar c2) {
|
|
||||||
return c1 == '\r' && c2 == '\r'; // QTCREATORBUG-24556
|
|
||||||
});
|
|
||||||
res.chop(std::distance(newEnd, res.end()));
|
|
||||||
res.replace("\r\n", "\n");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogFormatter::LogFormatter(QPlainTextEdit *output, QObject *parent) :
|
|
||||||
QObject(parent),
|
|
||||||
m_output(output),
|
|
||||||
m_cursor(output->textCursor()),
|
|
||||||
m_prependLineFeed(false),
|
|
||||||
m_prependCarriageReturn(false)
|
|
||||||
{
|
|
||||||
m_cursor.movePosition(QTextCursor::End);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogFormatter::~LogFormatter()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogFormatter::appendMessage(const QString &text)
|
|
||||||
{
|
|
||||||
if (text.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString out = text;
|
|
||||||
|
|
||||||
if (m_prependCarriageReturn) {
|
|
||||||
m_prependCarriageReturn = false;
|
|
||||||
out.prepend('\r');
|
|
||||||
}
|
|
||||||
|
|
||||||
out = normalizeNewlines(out);
|
|
||||||
|
|
||||||
if (out.endsWith('\r')) {
|
|
||||||
m_prependCarriageReturn = true;
|
|
||||||
out.chop(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward all complete lines to the specialized formatting code, and handle a
|
|
||||||
// potential trailing incomplete line the same way as above.
|
|
||||||
for (qsizetype startPos = 0; startPos < out.size();) {
|
|
||||||
auto eolPos = out.indexOf('\n', startPos);
|
|
||||||
|
|
||||||
if (eolPos == -1) {
|
|
||||||
doAppendMessage(out.mid(startPos));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
doAppendMessage(out.mid(startPos, eolPos - startPos));
|
|
||||||
|
|
||||||
m_prependLineFeed = true;
|
|
||||||
startPos = eolPos + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogFormatter::reset()
|
|
||||||
{
|
|
||||||
m_output->clear();
|
|
||||||
m_prependLineFeed = false;
|
|
||||||
m_prependCarriageReturn = false;
|
|
||||||
m_escapeCodeHandler = AnsiEscape();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogFormatter::doAppendMessage(const QString &text)
|
|
||||||
{
|
|
||||||
QTextCharFormat charFmt;
|
|
||||||
QList<FormattedText> formattedText = parseAnsi(text, charFmt);
|
|
||||||
|
|
||||||
for (FormattedText output : formattedText) {
|
|
||||||
append(output.text, output.format);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (formattedText.isEmpty()) {
|
|
||||||
append({}, charFmt); // This might cause insertion of a newline character.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogFormatter::append(const QString &text, const QTextCharFormat &format)
|
|
||||||
{
|
|
||||||
flushTrailingNewline();
|
|
||||||
|
|
||||||
int startPos = 0;
|
|
||||||
int crPos = -1;
|
|
||||||
|
|
||||||
while ((crPos = text.indexOf('\r', startPos)) >= 0) {
|
|
||||||
m_cursor.insertText(text.mid(startPos, crPos - startPos), format);
|
|
||||||
m_cursor.clearSelection();
|
|
||||||
m_cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
|
|
||||||
startPos = crPos + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startPos < text.size()) {
|
|
||||||
m_cursor.insertText(text.mid(startPos), format);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogFormatter::flushTrailingNewline()
|
|
||||||
{
|
|
||||||
if (m_prependLineFeed) {
|
|
||||||
m_cursor.insertText("\n");
|
|
||||||
m_prependLineFeed = false;
|
|
||||||
scroll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<FormattedText> LogFormatter::parseAnsi(const QString &text, const QTextCharFormat &format)
|
|
||||||
{
|
|
||||||
return m_escapeCodeHandler.parseText(FormattedText(text, format));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogFormatter::scroll()
|
|
||||||
{
|
|
||||||
auto bar = m_output->verticalScrollBar();
|
|
||||||
auto max = bar->maximum();
|
|
||||||
auto bottom = (bar->value() >= (max - 4)); // 4 is an error threshold.
|
|
||||||
|
|
||||||
if (bottom) {
|
|
||||||
bar->setValue(max);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
// This file is a derived works from Qt Creator.
|
|
||||||
// Licensed under GPL-3.0-only.
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ansi_escape.hpp"
|
|
||||||
|
|
||||||
#include <QList>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QTextCharFormat>
|
|
||||||
#include <QTextCursor>
|
|
||||||
|
|
||||||
class QPlainTextEdit;
|
|
||||||
|
|
||||||
class LogFormatter : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
LogFormatter(QPlainTextEdit *output, QObject *parent = nullptr);
|
|
||||||
~LogFormatter() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void appendMessage(const QString &text);
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void doAppendMessage(const QString &text);
|
|
||||||
void append(const QString &text, const QTextCharFormat &format);
|
|
||||||
void flushTrailingNewline();
|
|
||||||
QList<FormattedText> parseAnsi(const QString &text, const QTextCharFormat &format);
|
|
||||||
void scroll();
|
|
||||||
|
|
||||||
private:
|
|
||||||
AnsiEscape m_escapeCodeHandler;
|
|
||||||
QPlainTextEdit *m_output;
|
|
||||||
QTextCursor m_cursor;
|
|
||||||
bool m_prependLineFeed;
|
|
||||||
bool m_prependCarriageReturn;
|
|
||||||
};
|
|
@ -1,44 +0,0 @@
|
|||||||
#include "logs_viewer.hpp"
|
|
||||||
#include "log_formatter.hpp"
|
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QPlainTextEdit>
|
|
||||||
|
|
||||||
LogsViewer::LogsViewer() :
|
|
||||||
m_formatter(nullptr)
|
|
||||||
{
|
|
||||||
auto layout = new QHBoxLayout();
|
|
||||||
|
|
||||||
setWindowTitle("Obliteration Logs");
|
|
||||||
resize(1000, 500);
|
|
||||||
|
|
||||||
// Setup viewer.
|
|
||||||
auto viewer = new QPlainTextEdit();
|
|
||||||
|
|
||||||
viewer->setReadOnly(true);
|
|
||||||
viewer->setLineWrapMode(QPlainTextEdit::NoWrap);
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
viewer->document()->setDefaultFont(QFont("Courier New", 10));
|
|
||||||
#elif __APPLE__
|
|
||||||
viewer->document()->setDefaultFont(QFont("menlo", 10));
|
|
||||||
#else
|
|
||||||
viewer->document()->setDefaultFont(QFont("monospace", 10));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
layout->addWidget(viewer);
|
|
||||||
|
|
||||||
// Setup formatter.
|
|
||||||
m_formatter = new LogFormatter(viewer, this);
|
|
||||||
|
|
||||||
setLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogsViewer::~LogsViewer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogsViewer::append(const QString &text)
|
|
||||||
{
|
|
||||||
m_formatter->appendMessage(text);
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
class LogFormatter;
|
|
||||||
|
|
||||||
class LogsViewer final : public QWidget {
|
|
||||||
public:
|
|
||||||
LogsViewer();
|
|
||||||
~LogsViewer() override;
|
|
||||||
|
|
||||||
void append(const QString &text);
|
|
||||||
private:
|
|
||||||
LogFormatter *m_formatter;
|
|
||||||
};
|
|
@ -3,7 +3,6 @@
|
|||||||
#include "display_settings.hpp"
|
#include "display_settings.hpp"
|
||||||
#include "game_models.hpp"
|
#include "game_models.hpp"
|
||||||
#include "launch_settings.hpp"
|
#include "launch_settings.hpp"
|
||||||
#include "logs_viewer.hpp"
|
|
||||||
#include "path.hpp"
|
#include "path.hpp"
|
||||||
#include "pkg_installer.hpp"
|
#include "pkg_installer.hpp"
|
||||||
#include "profile_models.hpp"
|
#include "profile_models.hpp"
|
||||||
@ -79,14 +78,6 @@ MainWindow::MainWindow(
|
|||||||
fileMenu->addSeparator();
|
fileMenu->addSeparator();
|
||||||
fileMenu->addAction(quit);
|
fileMenu->addAction(quit);
|
||||||
|
|
||||||
// View menu.
|
|
||||||
auto viewMenu = menuBar()->addMenu("&View");
|
|
||||||
auto logs = new QAction("&Logs", this);
|
|
||||||
|
|
||||||
connect(logs, &QAction::triggered, this, &MainWindow::viewLogs);
|
|
||||||
|
|
||||||
viewMenu->addAction(logs);
|
|
||||||
|
|
||||||
// Help menu.
|
// Help menu.
|
||||||
auto helpMenu = menuBar()->addMenu("&Help");
|
auto helpMenu = menuBar()->addMenu("&Help");
|
||||||
auto reportIssue = new QAction("&Report Issue", this);
|
auto reportIssue = new QAction("&Report Issue", this);
|
||||||
@ -254,11 +245,6 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
|||||||
killVmm();
|
killVmm();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close child windows.
|
|
||||||
if (m_logs && !m_logs->close()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save geometry.
|
// Save geometry.
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
@ -312,18 +298,6 @@ void MainWindow::openSystemFolder()
|
|||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(folderPath));
|
QDesktopServices::openUrl(QUrl::fromLocalFile(folderPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::viewLogs()
|
|
||||||
{
|
|
||||||
if (m_logs) {
|
|
||||||
m_logs->activateWindow();
|
|
||||||
m_logs->raise();
|
|
||||||
} else {
|
|
||||||
m_logs = new LogsViewer();
|
|
||||||
m_logs->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
m_logs->show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::reportIssue()
|
void MainWindow::reportIssue()
|
||||||
{
|
{
|
||||||
if (!QDesktopServices::openUrl(QUrl("https://github.com/obhq/obliteration/issues/new"))) {
|
if (!QDesktopServices::openUrl(QUrl("https://github.com/obhq/obliteration/issues/new"))) {
|
||||||
@ -447,9 +421,6 @@ void MainWindow::waitKernelExit(bool success)
|
|||||||
|
|
||||||
void MainWindow::log(VmmLog type, const QString &msg)
|
void MainWindow::log(VmmLog type, const QString &msg)
|
||||||
{
|
{
|
||||||
if (m_logs) {
|
|
||||||
m_logs->append(msg);
|
|
||||||
} else {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case VmmLog_Info:
|
case VmmLog_Info:
|
||||||
std::cout << msg.toStdString();
|
std::cout << msg.toStdString();
|
||||||
@ -459,7 +430,6 @@ void MainWindow::log(VmmLog type, const QString &msg)
|
|||||||
std::cerr << msg.toStdString();
|
std::cerr << msg.toStdString();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setupDebugger()
|
void MainWindow::setupDebugger()
|
||||||
|
@ -4,14 +4,12 @@
|
|||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QPointer>
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
#include <QVulkanInstance>
|
#include <QVulkanInstance>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class GameListModel;
|
class GameListModel;
|
||||||
class LaunchSettings;
|
class LaunchSettings;
|
||||||
class LogsViewer;
|
|
||||||
class ProfileList;
|
class ProfileList;
|
||||||
class QCommandLineOption;
|
class QCommandLineOption;
|
||||||
class QCommandLineParser;
|
class QCommandLineParser;
|
||||||
@ -41,7 +39,6 @@ protected:
|
|||||||
private slots:
|
private slots:
|
||||||
void installPkg();
|
void installPkg();
|
||||||
void openSystemFolder();
|
void openSystemFolder();
|
||||||
void viewLogs();
|
|
||||||
void reportIssue();
|
void reportIssue();
|
||||||
void aboutObliteration();
|
void aboutObliteration();
|
||||||
void saveProfile(Profile *p);
|
void saveProfile(Profile *p);
|
||||||
@ -66,7 +63,6 @@ private:
|
|||||||
GameListModel *m_games;
|
GameListModel *m_games;
|
||||||
LaunchSettings *m_launch;
|
LaunchSettings *m_launch;
|
||||||
Screen *m_screen;
|
Screen *m_screen;
|
||||||
QPointer<LogsViewer> m_logs;
|
|
||||||
Rust<DebugServer> m_debugServer;
|
Rust<DebugServer> m_debugServer;
|
||||||
QSocketNotifier *m_debugNoti;
|
QSocketNotifier *m_debugNoti;
|
||||||
Rust<Vmm> m_vmm; // Destroy first.
|
Rust<Vmm> m_vmm; // Destroy first.
|
||||||
|
Loading…
Reference in New Issue
Block a user