mirror of https://github.com/PCSX2/pcsx2.git
Qt: Add log window
This commit is contained in:
parent
e908bbfae6
commit
ea98203ac5
|
@ -21,6 +21,8 @@ target_sources(pcsx2-qt PRIVATE
|
|||
DisplayWidget.cpp
|
||||
DisplayWidget.h
|
||||
EarlyHardwareCheck.cpp
|
||||
LogWindow.cpp
|
||||
LogWindow.h
|
||||
MainWindow.cpp
|
||||
MainWindow.h
|
||||
MainWindow.ui
|
||||
|
|
|
@ -0,0 +1,399 @@
|
|||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: LGPL-3.0+
|
||||
|
||||
#include "LogWindow.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "SettingWidgetBinder.h"
|
||||
|
||||
#include <QtCore/QLatin1StringView>
|
||||
#include <QtCore/QUtf8StringView>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtWidgets/QMenuBar>
|
||||
#include <QtWidgets/QScrollBar>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
// Need a lock so the other threads don't try to write to a deleting window.
|
||||
LogWindow* g_log_window;
|
||||
static std::mutex s_log_mutex;
|
||||
|
||||
static LOGLEVEL GetWindowLogLevel()
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
return LOGLEVEL_DEBUG;
|
||||
#else
|
||||
return (IsDevBuild || Host::GetBaseBoolSettingValue("Logging", "EnableVerbose", false)) ? LOGLEVEL_DEV : LOGLEVEL_INFO;
|
||||
#endif
|
||||
}
|
||||
|
||||
LogWindow::LogWindow(bool attach_to_main)
|
||||
: QMainWindow()
|
||||
, m_attached_to_main_window(attach_to_main)
|
||||
{
|
||||
restoreSize();
|
||||
createUi();
|
||||
|
||||
Log::SetHostOutputLevel(GetWindowLogLevel(), &LogWindow::logCallback);
|
||||
}
|
||||
|
||||
LogWindow::~LogWindow()
|
||||
{
|
||||
Log::SetHostOutputLevel(LOGLEVEL_NONE, nullptr);
|
||||
}
|
||||
|
||||
void LogWindow::updateSettings()
|
||||
{
|
||||
std::unique_lock lock(s_log_mutex);
|
||||
|
||||
const bool new_enabled = Host::GetBaseBoolSettingValue("Logging", "EnableLogWindow", false) && !QtHost::InNoGUIMode();
|
||||
const bool attach_to_main = Host::GetBaseBoolSettingValue("Logging", "AttachLogWindowToMainWindow", true);
|
||||
const bool curr_enabled = Log::IsHostOutputEnabled();
|
||||
|
||||
if (new_enabled == curr_enabled)
|
||||
{
|
||||
if (g_log_window && g_log_window->m_attached_to_main_window != attach_to_main)
|
||||
{
|
||||
g_log_window->m_attached_to_main_window = attach_to_main;
|
||||
if (attach_to_main)
|
||||
g_log_window->reattachToMainWindow();
|
||||
}
|
||||
|
||||
// Update level.
|
||||
if (new_enabled)
|
||||
Log::SetHostOutputLevel(GetWindowLogLevel(), &LogWindow::logCallback);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (new_enabled)
|
||||
{
|
||||
g_log_window = new LogWindow(attach_to_main);
|
||||
if (attach_to_main && g_main_window && g_main_window->isVisible())
|
||||
g_log_window->reattachToMainWindow();
|
||||
|
||||
g_log_window->show();
|
||||
}
|
||||
else if (g_log_window)
|
||||
{
|
||||
g_log_window->m_destroying = true;
|
||||
g_log_window->close();
|
||||
g_log_window->deleteLater();
|
||||
g_log_window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void LogWindow::destroy()
|
||||
{
|
||||
std::unique_lock lock(s_log_mutex);
|
||||
if (!g_log_window)
|
||||
return;
|
||||
|
||||
g_log_window->m_destroying = true;
|
||||
g_log_window->close();
|
||||
g_log_window->deleteLater();
|
||||
g_log_window = nullptr;
|
||||
}
|
||||
|
||||
void LogWindow::reattachToMainWindow()
|
||||
{
|
||||
// Skip when maximized.
|
||||
if (g_main_window->windowState() & (Qt::WindowMaximized | Qt::WindowFullScreen))
|
||||
return;
|
||||
|
||||
resize(width(), g_main_window->height());
|
||||
|
||||
const QPoint new_pos = g_main_window->pos() + QPoint(g_main_window->width() + 10, 0);
|
||||
if (pos() != new_pos)
|
||||
move(new_pos);
|
||||
}
|
||||
|
||||
void LogWindow::updateWindowTitle()
|
||||
{
|
||||
QString title;
|
||||
|
||||
const QString& serial = QtHost::GetCurrentGameSerial();
|
||||
|
||||
if (QtHost::IsVMValid() && !serial.isEmpty())
|
||||
{
|
||||
const QFileInfo fi(QtHost::GetCurrentGamePath());
|
||||
title = tr("Log Window - %1 [%2]").arg(serial).arg(fi.fileName());
|
||||
}
|
||||
else
|
||||
{
|
||||
title = tr("Log Window");
|
||||
}
|
||||
|
||||
setWindowTitle(title);
|
||||
}
|
||||
|
||||
void LogWindow::createUi()
|
||||
{
|
||||
setWindowIcon(QtHost::GetAppIcon());
|
||||
updateWindowTitle();
|
||||
|
||||
QAction* action;
|
||||
|
||||
QMenuBar* menu = new QMenuBar(this);
|
||||
setMenuBar(menu);
|
||||
|
||||
QMenu* log_menu = menu->addMenu("&Log");
|
||||
action = log_menu->addAction(tr("&Clear"));
|
||||
connect(action, &QAction::triggered, this, &LogWindow::onClearTriggered);
|
||||
action = log_menu->addAction(tr("&Save..."));
|
||||
connect(action, &QAction::triggered, this, &LogWindow::onSaveTriggered);
|
||||
|
||||
log_menu->addSeparator();
|
||||
|
||||
action = log_menu->addAction(tr("Cl&ose"));
|
||||
connect(action, &QAction::triggered, this, &LogWindow::close);
|
||||
|
||||
QMenu* settings_menu = menu->addMenu(tr("&Settings"));
|
||||
|
||||
#if 0
|
||||
// TODO: These are duplicated with the main window...
|
||||
action = settings_menu->addAction(tr("Log To &System Console"));
|
||||
action->setCheckable(true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableSystemConsole", false);
|
||||
|
||||
action = settings_menu->addAction(tr("Log To &Debug Console"));
|
||||
action->setCheckable(true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableDebugConsole", false);
|
||||
|
||||
action = settings_menu->addAction(tr("Log To &File"));
|
||||
action->setCheckable(true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableFileLogging", false);
|
||||
|
||||
settings_menu->addSeparator();
|
||||
#endif
|
||||
|
||||
action = settings_menu->addAction(tr("Attach To &Main Window"));
|
||||
action->setCheckable(true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "AttachLogWindowToMainWindow", true);
|
||||
|
||||
action = settings_menu->addAction(tr("Show &Timestamps"));
|
||||
action->setCheckable(true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, action, "Logging", "EnableTimestamps", true);
|
||||
|
||||
settings_menu->addSeparator();
|
||||
|
||||
// TODO: Log Level
|
||||
|
||||
m_text = new QPlainTextEdit(this);
|
||||
m_text->setReadOnly(true);
|
||||
m_text->setUndoRedoEnabled(false);
|
||||
m_text->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
|
||||
m_text->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
m_text->setWordWrapMode(QTextOption::WrapAnywhere);
|
||||
|
||||
#if defined(_WIN32)
|
||||
QFont font("Consolas");
|
||||
font.setPointSize(10);
|
||||
#elif defined(__APPLE__)
|
||||
QFont font("Monaco");
|
||||
font.setPointSize(11);
|
||||
#else
|
||||
QFont font("Monospace");
|
||||
font.setStyleHint(QFont::TypeWriter);
|
||||
#endif
|
||||
m_text->setFont(font);
|
||||
|
||||
setCentralWidget(m_text);
|
||||
}
|
||||
|
||||
void LogWindow::onClearTriggered()
|
||||
{
|
||||
m_text->clear();
|
||||
}
|
||||
|
||||
void LogWindow::onSaveTriggered()
|
||||
{
|
||||
const QString path = QFileDialog::getSaveFileName(this, tr("Select Log File"), QString(), tr("Log Files (*.txt)"));
|
||||
if (path.isEmpty())
|
||||
return;
|
||||
|
||||
QFile file(path);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Failed to open file for writing."));
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(m_text->toPlainText().toUtf8());
|
||||
file.close();
|
||||
|
||||
appendMessage(LOGLEVEL_INFO, Color_Default, tr("Log was written to %1.\n").arg(path));
|
||||
}
|
||||
|
||||
void LogWindow::logCallback(LOGLEVEL level, ConsoleColors color, std::string_view message)
|
||||
{
|
||||
std::unique_lock lock(s_log_mutex);
|
||||
if (!g_log_window)
|
||||
return;
|
||||
|
||||
// I don't like the memory allocations here either...
|
||||
QString qmessage;
|
||||
qmessage.reserve(message.length() + 1);
|
||||
qmessage.append(QUtf8StringView(message.data(), message.length()));
|
||||
qmessage.append(QChar('\n'));
|
||||
|
||||
if (g_emu_thread->isOnUIThread())
|
||||
{
|
||||
g_log_window->appendMessage(static_cast<u32>(level), static_cast<u32>(color), qmessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
QMetaObject::invokeMethod(g_log_window, "appendMessage", Qt::QueuedConnection,
|
||||
Q_ARG(quint32, static_cast<u32>(level)), Q_ARG(quint32, static_cast<u32>(color)),
|
||||
Q_ARG(const QString&, qmessage));
|
||||
}
|
||||
}
|
||||
|
||||
void LogWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
Log::SetHostOutputLevel(LOGLEVEL_NONE, nullptr);
|
||||
|
||||
// Save size when actually closing, disable ourselves if the user closed us.
|
||||
if (m_destroying)
|
||||
{
|
||||
saveSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
Host::SetBaseBoolSettingValue("Logging", "EnableLogWindow", false);
|
||||
Host::CommitBaseSettingChanges();
|
||||
}
|
||||
|
||||
QMainWindow::closeEvent(event);
|
||||
}
|
||||
|
||||
void LogWindow::appendMessage(quint32 level, quint32 color, const QString& message)
|
||||
{
|
||||
QTextCursor temp_cursor = m_text->textCursor();
|
||||
QScrollBar* scrollbar = m_text->verticalScrollBar();
|
||||
const bool cursor_at_end = temp_cursor.atEnd();
|
||||
const bool scroll_at_end = scrollbar->sliderPosition() == scrollbar->maximum();
|
||||
|
||||
temp_cursor.movePosition(QTextCursor::End);
|
||||
|
||||
{
|
||||
static constexpr const QColor qcolors[2][ConsoleColors_Count] = {
|
||||
// Light theme
|
||||
{
|
||||
QColor(0, 0, 0), // Color_Default
|
||||
QColor(0, 0, 0), // Color_Black
|
||||
QColor(128, 0, 0), // Color_Red
|
||||
QColor(0, 128, 0), // Color_Green
|
||||
QColor(0, 0, 128), // Color_Blue
|
||||
QColor(160, 0, 160), // Color_Magenta
|
||||
QColor(160, 120, 0), // Color_Orange
|
||||
QColor(108, 108, 108), // Color_Gray
|
||||
|
||||
QColor(128, 180, 180), // Color_Cyan
|
||||
QColor(180, 180, 128), // Color_Yellow
|
||||
QColor(160, 160, 160), // Color_White
|
||||
|
||||
QColor(0, 0, 0), // Color_StrongBlack
|
||||
QColor(128, 0, 0), // Color_StrongRed
|
||||
QColor(0, 128, 0), // Color_StrongGreen
|
||||
QColor(0, 0, 128), // Color_StrongBlue
|
||||
QColor(160, 0, 160), // Color_StrongMagenta
|
||||
QColor(160, 120, 0), // Color_StrongOrange
|
||||
QColor(108, 108, 108), // Color_StrongGray
|
||||
|
||||
QColor(128, 180, 180), // Color_StrongCyan
|
||||
QColor(180, 180, 128), // Color_StrongYellow
|
||||
QColor(160, 160, 160), // Color_StrongWhite
|
||||
},
|
||||
// Dark theme
|
||||
{
|
||||
QColor(208, 208, 208), // Color_Default
|
||||
QColor(255, 255, 255), // Color_Black
|
||||
QColor(180, 0, 0), // Color_Red
|
||||
QColor(0, 160, 0), // Color_Green
|
||||
QColor(32, 32, 204), // Color_Blue
|
||||
QColor(160, 0, 160), // Color_Magenta
|
||||
QColor(160, 120, 0), // Color_Orange
|
||||
QColor(128, 128, 128), // Color_Gray
|
||||
QColor(128, 180, 180), // Color_Cyan
|
||||
QColor(180, 180, 128), // Color_Yellow
|
||||
QColor(160, 160, 160), // Color_White
|
||||
QColor(255, 255, 255), // Color_StrongBlack
|
||||
QColor(180, 0, 0), // Color_StrongRed
|
||||
QColor(0, 160, 0), // Color_StrongGreen
|
||||
QColor(32, 32, 204), // Color_StrongBlue
|
||||
QColor(160, 0, 160), // Color_StrongMagenta
|
||||
QColor(160, 120, 0), // Color_StrongOrange
|
||||
QColor(128, 128, 128), // Color_StrongGray
|
||||
QColor(128, 180, 180), // Color_StrongCyan
|
||||
QColor(180, 180, 128), // Color_StrongYellow
|
||||
QColor(160, 160, 160), // Color_StrongWhite
|
||||
},
|
||||
};
|
||||
|
||||
static constexpr const QColor timestamp_color = QColor(0xcc, 0xcc, 0xcc);
|
||||
|
||||
QTextCharFormat format = temp_cursor.charFormat();
|
||||
|
||||
if (Log::AreTimestampsEnabled())
|
||||
{
|
||||
const float message_time = Log::GetCurrentMessageTime();
|
||||
const QString qtimestamp = QStringLiteral("[%1] ").arg(message_time, 10, 'f', 4);
|
||||
format.setForeground(QBrush(timestamp_color));
|
||||
temp_cursor.setCharFormat(format);
|
||||
temp_cursor.insertText(qtimestamp);
|
||||
}
|
||||
|
||||
const bool dark = static_cast<u32>(QtHost::IsDarkApplicationTheme());
|
||||
|
||||
// message has \n already
|
||||
format.setForeground(QBrush(qcolors[static_cast<u32>(dark)][color]));
|
||||
temp_cursor.setCharFormat(format);
|
||||
temp_cursor.insertText(message);
|
||||
}
|
||||
|
||||
if (cursor_at_end)
|
||||
{
|
||||
if (scroll_at_end)
|
||||
{
|
||||
m_text->setTextCursor(temp_cursor);
|
||||
scrollbar->setSliderPosition(scrollbar->maximum());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't let changing the cursor affect the scroll bar...
|
||||
const int pos = scrollbar->sliderPosition();
|
||||
m_text->setTextCursor(temp_cursor);
|
||||
scrollbar->setSliderPosition(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LogWindow::saveSize()
|
||||
{
|
||||
const int current_width = Host::GetBaseIntSettingValue("UI", "LogWindowWidth", DEFAULT_WIDTH);
|
||||
const int current_height = Host::GetBaseIntSettingValue("UI", "LogWindowHeight", DEFAULT_HEIGHT);
|
||||
const QSize wsize = size();
|
||||
|
||||
bool changed = false;
|
||||
if (current_width != wsize.width())
|
||||
{
|
||||
Host::SetBaseIntSettingValue("UI", "LogWindowWidth", wsize.width());
|
||||
changed = true;
|
||||
}
|
||||
if (current_height != wsize.height())
|
||||
{
|
||||
Host::SetBaseIntSettingValue("UI", "LogWindowHeight", wsize.height());
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed)
|
||||
Host::CommitBaseSettingChanges();
|
||||
}
|
||||
|
||||
void LogWindow::restoreSize()
|
||||
{
|
||||
const int width = Host::GetBaseIntSettingValue("UI", "LogWindowWidth", DEFAULT_WIDTH);
|
||||
const int height = Host::GetBaseIntSettingValue("UI", "LogWindowHeight", DEFAULT_HEIGHT);
|
||||
resize(width, height);
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||
// SPDX-License-Identifier: LGPL-3.0+
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/Console.h"
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QtWidgets/QPlainTextEdit>
|
||||
|
||||
class LogWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LogWindow(bool attach_to_main);
|
||||
~LogWindow();
|
||||
|
||||
static void updateSettings();
|
||||
static void destroy();
|
||||
|
||||
__fi bool isAttachedToMainWindow() const { return m_attached_to_main_window; }
|
||||
void reattachToMainWindow();
|
||||
|
||||
void updateWindowTitle();
|
||||
|
||||
private:
|
||||
void createUi();
|
||||
|
||||
static void logCallback(LOGLEVEL level, ConsoleColors color, std::string_view message);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent* event);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onClearTriggered();
|
||||
void onSaveTriggered();
|
||||
void appendMessage(quint32 level, quint32 color, const QString& message);
|
||||
|
||||
private:
|
||||
static constexpr int DEFAULT_WIDTH = 750;
|
||||
static constexpr int DEFAULT_HEIGHT = 400;
|
||||
|
||||
void saveSize();
|
||||
void restoreSize();
|
||||
|
||||
QPlainTextEdit* m_text;
|
||||
QMenu* m_level_menu;
|
||||
|
||||
bool m_attached_to_main_window = true;
|
||||
bool m_destroying = false;
|
||||
};
|
||||
|
||||
extern LogWindow* g_log_window;
|
|
@ -7,6 +7,7 @@
|
|||
#include "DisplayWidget.h"
|
||||
#include "GameList/GameListRefreshThread.h"
|
||||
#include "GameList/GameListWidget.h"
|
||||
#include "LogWindow.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtUtils.h"
|
||||
|
@ -255,7 +256,7 @@ void MainWindow::setupAdditionalUi()
|
|||
#ifdef ENABLE_RAINTEGRATION
|
||||
if (Achievements::IsUsingRAIntegration())
|
||||
{
|
||||
QMenu* raMenu = new QMenu(QStringLiteral("RAIntegration"), m_ui.menu_Tools);
|
||||
QMenu* raMenu = new QMenu(QStringLiteral("RAIntegration"), m_ui.menuTools);
|
||||
connect(raMenu, &QMenu::aboutToShow, this, [this, raMenu]() {
|
||||
raMenu->clear();
|
||||
|
||||
|
@ -279,7 +280,7 @@ void MainWindow::setupAdditionalUi()
|
|||
[id = id]() { Host::RunOnCPUThread([id]() { Achievements::RAIntegration::ActivateMenuItem(id); }, false); });
|
||||
}
|
||||
});
|
||||
m_ui.menu_Tools->insertMenu(m_ui.menuInput_Recording->menuAction(), raMenu);
|
||||
m_ui.menuTools->insertMenu(m_ui.menuInputRecording->menuAction(), raMenu);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -366,6 +367,14 @@ void MainWindow::connectSignals()
|
|||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionViewStatusBarVerbose, "UI", "VerboseStatusBar", false);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableSystemConsole, "Logging", "EnableSystemConsole", false);
|
||||
#ifdef _WIN32
|
||||
// Debug console only exists on Windows.
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableDebugConsole, "Logging", "EnableDebugConsole", false);
|
||||
#else
|
||||
m_ui.menuTools->removeAction(m_ui.actionEnableDebugConsole);
|
||||
m_ui.actionEnableDebugConsole->deleteLater();
|
||||
m_ui.actionEnableDebugConsole = nullptr;
|
||||
#endif
|
||||
#ifndef PCSX2_DEVBUILD
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableVerboseLogging, "Logging", "EnableVerbose", false);
|
||||
#else
|
||||
|
@ -375,6 +384,7 @@ void MainWindow::connectSignals()
|
|||
#endif
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableEEConsoleLogging, "Logging", "EnableEEConsole", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableIOPConsoleLogging, "Logging", "EnableIOPConsole", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableLogWindow, "Logging", "EnableLogWindow", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableFileLogging, "Logging", "EnableFileLogging", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableLogTimestamps, "Logging", "EnableTimestamps", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(nullptr, m_ui.actionEnableCDVDVerboseReads, "EmuCore", "CdvdVerboseReads", false);
|
||||
|
@ -508,6 +518,11 @@ void MainWindow::recreate()
|
|||
new_main_window->show();
|
||||
deleteLater();
|
||||
|
||||
// Recreate log window as well. Then make sure we're still on top.
|
||||
LogWindow::updateSettings();
|
||||
new_main_window->raise();
|
||||
new_main_window->activateWindow();
|
||||
|
||||
// Reload the sources we just closed.
|
||||
g_emu_thread->reloadInputSources();
|
||||
|
||||
|
@ -579,6 +594,8 @@ void MainWindow::destroySubWindows()
|
|||
}
|
||||
|
||||
SettingsWindow::closeGamePropertiesDialogs();
|
||||
|
||||
LogWindow::destroy();
|
||||
}
|
||||
|
||||
void MainWindow::onScreenshotActionTriggered()
|
||||
|
@ -920,6 +937,9 @@ void MainWindow::updateWindowTitle()
|
|||
if (container->windowTitle() != display_title)
|
||||
container->setWindowTitle(display_title);
|
||||
}
|
||||
|
||||
if (g_log_window)
|
||||
g_log_window->updateWindowTitle();
|
||||
}
|
||||
|
||||
void MainWindow::updateWindowState(bool force_visible)
|
||||
|
@ -1192,6 +1212,8 @@ void MainWindow::checkForSettingChanges()
|
|||
updateDisplayWidgetCursor();
|
||||
|
||||
updateWindowState();
|
||||
|
||||
LogWindow::updateSettings();
|
||||
}
|
||||
|
||||
std::optional<WindowInfo> MainWindow::getWindowInfo()
|
||||
|
@ -2041,6 +2063,22 @@ void MainWindow::dropEvent(QDropEvent* event)
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::moveEvent(QMoveEvent* event)
|
||||
{
|
||||
QMainWindow::moveEvent(event);
|
||||
|
||||
if (g_log_window && g_log_window->isAttachedToMainWindow())
|
||||
g_log_window->reattachToMainWindow();
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent* event)
|
||||
{
|
||||
QMainWindow::resizeEvent(event);
|
||||
|
||||
if (g_log_window && g_log_window->isAttachedToMainWindow())
|
||||
g_log_window->reattachToMainWindow();
|
||||
}
|
||||
|
||||
void MainWindow::registerForDeviceNotifications()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -197,15 +197,14 @@ protected:
|
|||
void changeEvent(QEvent* event) override;
|
||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||
void dropEvent(QDropEvent* event) override;
|
||||
void moveEvent(QMoveEvent* event) override;
|
||||
void resizeEvent(QResizeEvent* event) override;
|
||||
|
||||
#ifdef _WIN32
|
||||
bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;
|
||||
#endif
|
||||
|
||||
private:
|
||||
static void setStyleFromSettings();
|
||||
static void setIconThemeFromStyle();
|
||||
|
||||
void setupAdditionalUi();
|
||||
void connectSignals();
|
||||
void createRendererSwitchMenu();
|
||||
|
|
|
@ -146,7 +146,7 @@
|
|||
<addaction name="actionEnableIOPConsoleLogging"/>
|
||||
<addaction name="actionEnableCDVDVerboseReads"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_View">
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
<string>&View</string>
|
||||
</property>
|
||||
|
@ -176,11 +176,11 @@
|
|||
<addaction name="actionGridViewZoomOut"/>
|
||||
<addaction name="actionGridViewRefreshCovers"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_Tools">
|
||||
<widget class="QMenu" name="menuTools">
|
||||
<property name="title">
|
||||
<string>&Tools</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuInput_Recording">
|
||||
<widget class="QMenu" name="menuInputRecording">
|
||||
<property name="title">
|
||||
<string>Input Recording</string>
|
||||
</property>
|
||||
|
@ -206,10 +206,12 @@
|
|||
<addaction name="actionReloadPatches"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionToggleSoftwareRendering"/>
|
||||
<addaction name="menuInput_Recording"/>
|
||||
<addaction name="menuInputRecording"/>
|
||||
<addaction name="actionToolsVideoCapture"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionEnableSystemConsole"/>
|
||||
<addaction name="actionEnableDebugConsole"/>
|
||||
<addaction name="actionEnableLogWindow"/>
|
||||
<addaction name="actionEnableFileLogging"/>
|
||||
<addaction name="actionEnableVerboseLogging"/>
|
||||
<addaction name="separator"/>
|
||||
|
@ -219,8 +221,8 @@
|
|||
</widget>
|
||||
<addaction name="menuSystem"/>
|
||||
<addaction name="menuSettings"/>
|
||||
<addaction name="menu_View"/>
|
||||
<addaction name="menu_Tools"/>
|
||||
<addaction name="menuView"/>
|
||||
<addaction name="menuTools"/>
|
||||
<addaction name="menuDebug"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
|
@ -901,6 +903,22 @@
|
|||
<string>Enable System Console</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableDebugConsole">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Debug Console</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableLogWindow">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Log Window</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableVerboseLogging">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "AutoUpdaterDialog.h"
|
||||
#include "DisplayWidget.h"
|
||||
#include "GameList/GameListWidget.h"
|
||||
#include "LogWindow.h"
|
||||
#include "MainWindow.h"
|
||||
#include "QtHost.h"
|
||||
#include "QtProgressCallback.h"
|
||||
|
@ -101,11 +102,6 @@ EmuThread::EmuThread(QThread* ui_thread)
|
|||
|
||||
EmuThread::~EmuThread() = default;
|
||||
|
||||
bool EmuThread::isOnEmuThread() const
|
||||
{
|
||||
return QThread::currentThread() == this;
|
||||
}
|
||||
|
||||
void EmuThread::start()
|
||||
{
|
||||
pxAssertRel(!g_emu_thread, "Emu thread does not exist");
|
||||
|
@ -1918,6 +1914,9 @@ int main(int argc, char* argv[])
|
|||
// Set theme before creating any windows.
|
||||
QtHost::UpdateApplicationTheme();
|
||||
|
||||
// Start logging early.
|
||||
LogWindow::updateSettings();
|
||||
|
||||
// Start up the CPU thread.
|
||||
QtHost::HookSignals();
|
||||
EmuThread::start();
|
||||
|
@ -1942,7 +1941,11 @@ int main(int argc, char* argv[])
|
|||
|
||||
// Don't bother showing the window in no-gui mode.
|
||||
if (!s_nogui_mode)
|
||||
{
|
||||
g_main_window->show();
|
||||
g_main_window->raise();
|
||||
g_main_window->activateWindow();
|
||||
}
|
||||
|
||||
// Initialize big picture mode if requested.
|
||||
if (s_start_fullscreen_ui)
|
||||
|
|
|
@ -63,7 +63,8 @@ public:
|
|||
__fi bool isSurfaceless() const { return m_is_surfaceless; }
|
||||
__fi bool isRunningFullscreenUI() const { return m_run_fullscreen_ui; }
|
||||
|
||||
bool isOnEmuThread() const;
|
||||
__fi bool isOnEmuThread() const { return (QThread::currentThread() == this); }
|
||||
__fi bool isOnUIThread() const { return (QThread::currentThread() == m_ui_thread); }
|
||||
bool shouldRenderToMain() const;
|
||||
|
||||
/// Called back from the GS thread when the display state changes (e.g. fullscreen, render to main).
|
||||
|
@ -237,6 +238,9 @@ namespace QtHost
|
|||
/// Sets application theme according to settings.
|
||||
void UpdateApplicationTheme();
|
||||
|
||||
/// Returns true if the application theme is using dark colours.
|
||||
bool IsDarkApplicationTheme();
|
||||
|
||||
/// Sets the icon theme, based on the current style (light/dark).
|
||||
void SetIconThemeFromStyle();
|
||||
|
||||
|
|
|
@ -476,9 +476,14 @@ void QtHost::SetStyleFromSettings()
|
|||
}
|
||||
}
|
||||
|
||||
void QtHost::SetIconThemeFromStyle()
|
||||
bool QtHost::IsDarkApplicationTheme()
|
||||
{
|
||||
QPalette palette = qApp->palette();
|
||||
bool dark = palette.windowText().color().value() > palette.window().color().value();
|
||||
return (palette.windowText().color().value() > palette.window().color().value());
|
||||
}
|
||||
|
||||
void QtHost::SetIconThemeFromStyle()
|
||||
{
|
||||
const bool dark = IsDarkApplicationTheme();
|
||||
QIcon::setThemeName(dark ? QStringLiteral("white") : QStringLiteral("black"));
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
<ItemGroup>
|
||||
<ClCompile Include="ColorPickerButton.cpp" />
|
||||
<ClCompile Include="EarlyHardwareCheck.cpp" />
|
||||
<ClCompile Include="LogWindow.cpp" />
|
||||
<ClCompile Include="QtProgressCallback.cpp" />
|
||||
<ClCompile Include="Settings\DebugSettingsWidget.cpp" />
|
||||
<ClCompile Include="Settings\FolderSettingsWidget.cpp" />
|
||||
|
@ -172,6 +173,7 @@
|
|||
<QtMoc Include="Settings\DEV9UiCommon.h" />
|
||||
<QtMoc Include="QtProgressCallback.h" />
|
||||
<QtMoc Include="ColorPickerButton.h" />
|
||||
<QtMoc Include="LogWindow.h" />
|
||||
<ClInclude Include="Settings\ControllerSettingWidgetBinder.h" />
|
||||
<QtMoc Include="Settings\FolderSettingsWidget.h" />
|
||||
<QtMoc Include="Settings\DebugSettingsWidget.h" />
|
||||
|
@ -262,6 +264,7 @@
|
|||
<ClCompile Include="$(IntDir)moc_ColorPickerButton.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_CoverDownloadDialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_DisplayWidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_LogWindow.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_MainWindow.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_QtHost.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_QtProgressCallback.cpp" />
|
||||
|
|
|
@ -342,6 +342,10 @@
|
|||
<ClCompile Include="$(IntDir)moc_SetupWizardDialog.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LogWindow.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_LogWindow.cpp">
|
||||
<Filter>moc</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="..\pcsx2\windows\PCSX2.manifest">
|
||||
|
@ -499,6 +503,7 @@
|
|||
<QtMoc Include="Settings\GamePatchSettingsWidget.h">
|
||||
<Filter>Settings</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="LogWindow.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtResource Include="resources\resources.qrc">
|
||||
|
|
Loading…
Reference in New Issue