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
|
||||
|
||||
- `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.
|
||||
- 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.
|
||||
|
@ -12,7 +12,6 @@ endif()
|
||||
|
||||
# Setup GUI.
|
||||
add_executable(obliteration WIN32 MACOSX_BUNDLE
|
||||
ansi_escape.cpp
|
||||
app_data.cpp
|
||||
core.cpp
|
||||
cpu_settings.cpp
|
||||
@ -20,8 +19,6 @@ add_executable(obliteration WIN32 MACOSX_BUNDLE
|
||||
game_models.cpp
|
||||
initialize_wizard.cpp
|
||||
launch_settings.cpp
|
||||
log_formatter.cpp
|
||||
logs_viewer.cpp
|
||||
main.cpp
|
||||
main_window.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 "game_models.hpp"
|
||||
#include "launch_settings.hpp"
|
||||
#include "logs_viewer.hpp"
|
||||
#include "path.hpp"
|
||||
#include "pkg_installer.hpp"
|
||||
#include "profile_models.hpp"
|
||||
@ -79,14 +78,6 @@ MainWindow::MainWindow(
|
||||
fileMenu->addSeparator();
|
||||
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.
|
||||
auto helpMenu = menuBar()->addMenu("&Help");
|
||||
auto reportIssue = new QAction("&Report Issue", this);
|
||||
@ -254,11 +245,6 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
killVmm();
|
||||
}
|
||||
|
||||
// Close child windows.
|
||||
if (m_logs && !m_logs->close()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save geometry.
|
||||
QSettings settings;
|
||||
|
||||
@ -312,18 +298,6 @@ void MainWindow::openSystemFolder()
|
||||
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()
|
||||
{
|
||||
if (!QDesktopServices::openUrl(QUrl("https://github.com/obhq/obliteration/issues/new"))) {
|
||||
@ -447,18 +421,14 @@ void MainWindow::waitKernelExit(bool success)
|
||||
|
||||
void MainWindow::log(VmmLog type, const QString &msg)
|
||||
{
|
||||
if (m_logs) {
|
||||
m_logs->append(msg);
|
||||
} else {
|
||||
switch (type) {
|
||||
case VmmLog_Info:
|
||||
std::cout << msg.toStdString();
|
||||
break;
|
||||
case VmmLog_Warn:
|
||||
case VmmLog_Error:
|
||||
std::cerr << msg.toStdString();
|
||||
break;
|
||||
}
|
||||
switch (type) {
|
||||
case VmmLog_Info:
|
||||
std::cout << msg.toStdString();
|
||||
break;
|
||||
case VmmLog_Warn:
|
||||
case VmmLog_Error:
|
||||
std::cerr << msg.toStdString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,14 +4,12 @@
|
||||
|
||||
#include <QList>
|
||||
#include <QMainWindow>
|
||||
#include <QPointer>
|
||||
#ifndef __APPLE__
|
||||
#include <QVulkanInstance>
|
||||
#endif
|
||||
|
||||
class GameListModel;
|
||||
class LaunchSettings;
|
||||
class LogsViewer;
|
||||
class ProfileList;
|
||||
class QCommandLineOption;
|
||||
class QCommandLineParser;
|
||||
@ -41,7 +39,6 @@ protected:
|
||||
private slots:
|
||||
void installPkg();
|
||||
void openSystemFolder();
|
||||
void viewLogs();
|
||||
void reportIssue();
|
||||
void aboutObliteration();
|
||||
void saveProfile(Profile *p);
|
||||
@ -66,7 +63,6 @@ private:
|
||||
GameListModel *m_games;
|
||||
LaunchSettings *m_launch;
|
||||
Screen *m_screen;
|
||||
QPointer<LogsViewer> m_logs;
|
||||
Rust<DebugServer> m_debugServer;
|
||||
QSocketNotifier *m_debugNoti;
|
||||
Rust<Vmm> m_vmm; // Destroy first.
|
||||
|
Loading…
Reference in New Issue
Block a user