Compare commits

...

6 Commits

Author SHA1 Message Date
ElTioRata
4fa005ade0 GameDB: resident evil 4 - HPO Native w/ Texture Offset
Added 'Align to Native w/ Texture Offset'
2025-04-04 02:29:53 +02:00
PCSX2 Bot
bf656e892f [ci skip] Qt: Update Base Translation. 2025-04-04 02:29:37 +02:00
chaoticgd
abf074eaf4 Debugger: Fix some theming issues 2025-04-03 16:13:50 +02:00
chaoticgd
47657b51ab Debugger: Extract custom menu bar as its own class 2025-04-03 16:13:50 +02:00
PCSX2 Bot
76f8ffeb90 [ci skip] Qt: Update Base Translation. 2025-04-03 02:12:13 +02:00
TellowKrinkle
e68ae91b59 MacOS: Mark our help menu as the macOS help menu
This gives it a nice search box for searching other menus
2025-04-02 18:48:34 -04:00
15 changed files with 847 additions and 483 deletions

View File

@@ -23409,7 +23409,7 @@ SLES-53702:
region: "PAL-M5"
compat: 5
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLES-53703:
name: "Peter Jackson's King Kong - The Official Game of the Movie"
name-sort: "King Kong, Peter Jackson's - The Official Game of the Movie"
@@ -23643,7 +23643,7 @@ SLES-53756:
name: "Resident Evil 4"
region: "PAL-M5"
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLES-53758:
name: "Sniper Elite [Pre-Production]"
region: "PAL-E"
@@ -31588,7 +31588,7 @@ SLKA-25410:
gameFixes:
- BlitInternalFPSHack # Fixes internal FPS detection.
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLKA-25411:
name: "Need for Speed - ProStreet"
region: "NTSC-K"
@@ -67457,7 +67457,7 @@ SLUS-21134:
gameFixes:
- BlitInternalFPSHack # Fixes internal FPS detection.
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLUS-21135:
name: "MVP Baseball 2005"
region: "NTSC-U"
@@ -73016,7 +73016,7 @@ SLUS-29169:
gameFixes:
- BlitInternalFPSHack # Fixes internal FPS detection.
gsHWFixes:
halfPixelOffset: 2 # Fixes blurriness.
halfPixelOffset: 5 # Fixes blurriness.
SLUS-29170:
name: "Total Overdose - A Gunslinger's Tale in Mexico [Demo]"
region: "NTSC-U"

View File

@@ -19,6 +19,8 @@ namespace CocoaTools
void AddThemeChangeHandler(void* ctx, void(handler)(void* ctx));
/// Remove a handler previously added using AddThemeChangeHandler with the given context
void RemoveThemeChangeHandler(void* ctx);
/// Mark an NSMenu as the help menu
void MarkHelpMenu(void* menu);
/// Returns the bundle path.
std::optional<std::string> GetBundlePath();
/// Get the bundle path to the actual application without any translocation fun

View File

@@ -143,6 +143,11 @@ void CocoaTools::RemoveThemeChangeHandler(void* ctx)
[s_themeChangeHandler removeCallback:ctx];
}
void CocoaTools::MarkHelpMenu(void* menu)
{
[NSApp setHelpMenu:(__bridge NSMenu*)menu];
}
// MARK: - Sound playback
bool Common::PlaySoundAsync(const char* path)

View File

@@ -196,6 +196,8 @@ target_sources(pcsx2-qt PRIVATE
Debugger/Docking/DockLayout.h
Debugger/Docking/DockManager.cpp
Debugger/Docking/DockManager.h
Debugger/Docking/DockMenuBar.cpp
Debugger/Docking/DockMenuBar.h
Debugger/Docking/DockTables.cpp
Debugger/Docking/DockTables.h
Debugger/Docking/DockUtils.cpp

View File

@@ -112,7 +112,9 @@ DebuggerWindow::DebuggerWindow(QWidget* parent)
QMenuBar* menu_bar = menuBar();
setMenuWidget(m_dock_manager->createLayoutSwitcher(menu_bar));
setMenuWidget(m_dock_manager->createMenuBar(menu_bar));
updateTheme();
Host::RunOnCPUThread([]() {
R5900SymbolImporter.OnDebuggerOpened();
@@ -193,7 +195,7 @@ void DebuggerWindow::setupFonts()
m_font_size++;
updateFontActions();
updateStyleSheets();
updateTheme();
saveFontSize();
});
@@ -205,7 +207,7 @@ void DebuggerWindow::setupFonts()
m_font_size--;
updateFontActions();
updateStyleSheets();
updateTheme();
saveFontSize();
});
@@ -213,12 +215,11 @@ void DebuggerWindow::setupFonts()
m_font_size = DEFAULT_FONT_SIZE;
updateFontActions();
updateStyleSheets();
updateTheme();
saveFontSize();
});
updateFontActions();
updateStyleSheets();
}
void DebuggerWindow::updateFontActions()
@@ -239,7 +240,7 @@ int DebuggerWindow::fontSize()
return m_font_size;
}
void DebuggerWindow::updateStyleSheets()
void DebuggerWindow::updateTheme()
{
// TODO: Migrate away from stylesheets to improve performance.
if (m_font_size != DEFAULT_FONT_SIZE)
@@ -252,7 +253,7 @@ void DebuggerWindow::updateStyleSheets()
setStyleSheet(QString());
}
dockManager().updateStyleSheets();
dockManager().updateTheme();
}
void DebuggerWindow::saveWindowGeometry()

View File

@@ -31,7 +31,7 @@ public:
void updateFontActions();
void saveFontSize();
int fontSize();
void updateStyleSheets();
void updateTheme();
void saveWindowGeometry();
void restoreWindowGeometry();

View File

@@ -25,7 +25,8 @@
#include <QtCore/QTimer>
#include <QtCore/QtTranslation>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QProxyStyle>
#include <QtWidgets/QStyleFactory>
DockManager::DockManager(QObject* parent)
: QObject(parent)
@@ -33,9 +34,6 @@ DockManager::DockManager(QObject* parent)
QTimer* autosave_timer = new QTimer(this);
connect(autosave_timer, &QTimer::timeout, this, &DockManager::saveCurrentLayout);
autosave_timer->start(60 * 1000);
m_blink_timer = new QTimer(this);
connect(m_blink_timer, &QTimer::timeout, this, &DockManager::layoutSwitcherUpdateBlink);
}
void DockManager::configureDockingSystem()
@@ -144,17 +142,13 @@ void DockManager::switchToLayout(DockLayout::Index layout_index, bool blink_tab)
layout.thaw();
int tab_index = static_cast<int>(layout_index);
if (m_switcher && tab_index >= 0 && tab_index < m_plus_tab_index)
{
m_ignore_current_tab_changed = true;
m_switcher->setCurrentIndex(tab_index);
m_ignore_current_tab_changed = false;
}
if (m_menu_bar && tab_index >= 0)
m_menu_bar->onCurrentLayoutChanged(layout_index);
}
}
if (blink_tab)
layoutSwitcherStartBlink();
m_menu_bar->startBlink(m_current_layout);
}
bool DockManager::switchToLayoutWithCPU(BreakPointCpu cpu, bool blink_tab)
@@ -476,168 +470,195 @@ void DockManager::createWindowsMenu(QMenu* menu)
menu->addAction(toggle.action);
}
QWidget* DockManager::createLayoutSwitcher(QWidget* menu_bar)
QWidget* DockManager::createMenuBar(QWidget* original_menu_bar)
{
QWidget* container = new QWidget;
pxAssert(!m_menu_bar);
QHBoxLayout* layout = new QHBoxLayout;
layout->setContentsMargins(0, 2, 2, 0);
container->setLayout(layout);
m_menu_bar = new DockMenuBar(original_menu_bar);
QWidget* menu_wrapper = new QWidget;
menu_wrapper->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
layout->addWidget(menu_wrapper);
connect(m_menu_bar, &DockMenuBar::currentLayoutChanged, this, [this](DockLayout::Index layout_index) {
if (layout_index >= m_layouts.size())
return;
QHBoxLayout* menu_layout = new QHBoxLayout;
menu_layout->setContentsMargins(0, 4, 0, 4);
menu_wrapper->setLayout(menu_layout);
menu_layout->addWidget(menu_bar);
m_switcher = new QTabBar;
m_switcher->setContentsMargins(0, 0, 0, 0);
m_switcher->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
m_switcher->setContextMenuPolicy(Qt::CustomContextMenu);
m_switcher->setMovable(true);
layout->addWidget(m_switcher);
switchToLayout(layout_index);
});
connect(m_menu_bar, &DockMenuBar::newButtonClicked, this, &DockManager::newLayoutClicked);
connect(m_menu_bar, &DockMenuBar::layoutMoved, this, &DockManager::layoutSwitcherTabMoved);
connect(m_menu_bar, &DockMenuBar::lockButtonToggled, this, &DockManager::setLayoutLockedAndSaveSetting);
connect(m_menu_bar, &DockMenuBar::layoutSwitcherContextMenuRequested,
this, &DockManager::openLayoutSwitcherContextMenu);
updateLayoutSwitcher();
connect(m_switcher, &QTabBar::tabMoved, this, &DockManager::layoutSwitcherTabMoved);
connect(m_switcher, &QTabBar::customContextMenuRequested, this, &DockManager::layoutSwitcherContextMenu);
QWidget* spacer = new QWidget;
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
layout->addWidget(spacer);
bool layout_locked = Host::GetBaseBoolSettingValue("Debugger/UserInterface", "LayoutLocked", true);
setLayoutLocked(layout_locked, false);
QPushButton* lock_layout_toggle = new QPushButton;
lock_layout_toggle->setCheckable(true);
lock_layout_toggle->setChecked(layout_locked);
lock_layout_toggle->setFlat(true);
connect(lock_layout_toggle, &QPushButton::toggled, this, [this, lock_layout_toggle](bool checked) {
setLayoutLocked(checked, lock_layout_toggle, true);
});
layout->addWidget(lock_layout_toggle);
setLayoutLocked(layout_locked, lock_layout_toggle, false);
return container;
return m_menu_bar;
}
void DockManager::updateLayoutSwitcher()
{
if (!m_switcher)
return;
disconnect(m_tab_connection);
for (int i = m_switcher->count(); i > 0; i--)
m_switcher->removeTab(i - 1);
for (DockLayout& layout : m_layouts)
{
const char* cpu_name = DebugInterface::cpuName(layout.cpu());
QString tab_name = QString("%1 (%2)").arg(layout.name()).arg(cpu_name);
m_switcher->addTab(tab_name);
}
m_plus_tab_index = m_switcher->addTab("+");
m_current_tab_index = m_current_layout;
if (m_current_layout != DockLayout::INVALID_INDEX)
m_switcher->setCurrentIndex(m_current_layout);
// If we don't have any layouts, the currently selected tab will never be
// changed, so we respond to all clicks instead.
if (!m_layouts.empty())
m_tab_connection = connect(m_switcher, &QTabBar::currentChanged, this, &DockManager::layoutSwitcherTabChanged);
else
m_tab_connection = connect(m_switcher, &QTabBar::tabBarClicked, this, &DockManager::layoutSwitcherTabChanged);
layoutSwitcherStopBlink();
if (m_menu_bar)
m_menu_bar->updateLayoutSwitcher(m_current_layout, m_layouts);
}
void DockManager::layoutSwitcherTabChanged(int index)
void DockManager::newLayoutClicked()
{
// Prevent recursion.
if (m_ignore_current_tab_changed)
return;
// The plus button has just been made the current tab, so set it back to the
// one corresponding to the current layout again.
m_menu_bar->onCurrentLayoutChanged(m_current_layout);
if (index == m_plus_tab_index)
auto name_validator = [this](const QString& name) {
return !hasNameConflict(name, DockLayout::INVALID_INDEX);
};
bool can_clone_current_layout = m_current_layout != DockLayout::INVALID_INDEX;
QPointer<LayoutEditorDialog> dialog = new LayoutEditorDialog(
name_validator, can_clone_current_layout, g_debugger_window);
if (dialog->exec() == QDialog::Accepted && name_validator(dialog->name()))
{
if (m_current_tab_index >= 0 && m_current_tab_index < m_plus_tab_index)
DockLayout::Index new_layout = DockLayout::INVALID_INDEX;
const auto [mode, index] = dialog->initialState();
switch (mode)
{
m_ignore_current_tab_changed = true;
m_switcher->setCurrentIndex(m_current_tab_index);
m_ignore_current_tab_changed = false;
case LayoutEditorDialog::DEFAULT_LAYOUT:
{
const DockTables::DefaultDockLayout& default_layout = DockTables::DEFAULT_DOCK_LAYOUTS.at(index);
new_layout = createLayout(dialog->name(), dialog->cpu(), false, default_layout.name);
break;
}
case LayoutEditorDialog::BLANK_LAYOUT:
{
new_layout = createLayout(dialog->name(), dialog->cpu(), false);
break;
}
case LayoutEditorDialog::CLONE_LAYOUT:
{
if (m_current_layout == DockLayout::INVALID_INDEX)
break;
DockLayout::Index old_layout = m_current_layout;
// Freeze the current layout so we can copy the geometry.
switchToLayout(DockLayout::INVALID_INDEX);
new_layout = createLayout(dialog->name(), dialog->cpu(), false, m_layouts.at(old_layout));
break;
}
}
auto name_validator = [this](const QString& name) {
return !hasNameConflict(name, DockLayout::INVALID_INDEX);
};
bool can_clone_current_layout = m_current_layout != DockLayout::INVALID_INDEX;
QPointer<LayoutEditorDialog> dialog = new LayoutEditorDialog(
name_validator, can_clone_current_layout, g_debugger_window);
if (dialog->exec() == QDialog::Accepted && name_validator(dialog->name()))
if (new_layout != DockLayout::INVALID_INDEX)
{
DockLayout::Index new_layout = DockLayout::INVALID_INDEX;
const auto [mode, index] = dialog->initialState();
switch (mode)
{
case LayoutEditorDialog::DEFAULT_LAYOUT:
{
const DockTables::DefaultDockLayout& default_layout = DockTables::DEFAULT_DOCK_LAYOUTS.at(index);
new_layout = createLayout(dialog->name(), dialog->cpu(), false, default_layout.name);
break;
}
case LayoutEditorDialog::BLANK_LAYOUT:
{
new_layout = createLayout(dialog->name(), dialog->cpu(), false);
break;
}
case LayoutEditorDialog::CLONE_LAYOUT:
{
if (m_current_layout == DockLayout::INVALID_INDEX)
return;
DockLayout::Index old_layout = m_current_layout;
// Freeze the current layout so we can copy the geometry.
switchToLayout(DockLayout::INVALID_INDEX);
new_layout = createLayout(dialog->name(), dialog->cpu(), false, m_layouts.at(old_layout));
break;
}
}
updateLayoutSwitcher();
switchToLayout(new_layout);
}
delete dialog.get();
}
else
{
DockLayout::Index layout_index = static_cast<DockLayout::Index>(index);
if (layout_index < 0 || layout_index >= m_layouts.size())
return;
switchToLayout(layout_index);
m_current_tab_index = index;
}
delete dialog.get();
}
void DockManager::layoutSwitcherTabMoved(int from, int to)
void DockManager::openLayoutSwitcherContextMenu(const QPoint& pos, QTabBar* layout_switcher)
{
DockLayout::Index from_index = static_cast<DockLayout::Index>(from);
DockLayout::Index to_index = static_cast<DockLayout::Index>(to);
DockLayout::Index layout_index = static_cast<DockLayout::Index>(layout_switcher->tabAt(pos));
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
QMenu* menu = new QMenu(layout_switcher);
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction* edit_action = menu->addAction(tr("Edit Layout"));
connect(edit_action, &QAction::triggered, [this, layout_index]() {
editLayoutClicked(layout_index);
});
QAction* reset_action = menu->addAction(tr("Reset Layout"));
reset_action->setEnabled(layout.canReset());
reset_action->connect(reset_action, &QAction::triggered, [this, layout_index]() {
resetLayoutClicked(layout_index);
});
QAction* delete_action = menu->addAction(tr("Delete Layout"));
connect(delete_action, &QAction::triggered, [this, layout_index]() {
deleteLayoutClicked(layout_index);
});
menu->popup(layout_switcher->mapToGlobal(pos));
}
void DockManager::editLayoutClicked(DockLayout::Index layout_index)
{
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
auto name_validator = [this, layout_index](const QString& name) {
return !hasNameConflict(name, layout_index);
};
QPointer<LayoutEditorDialog> dialog = new LayoutEditorDialog(
layout.name(), layout.cpu(), name_validator, g_debugger_window);
if (dialog->exec() != QDialog::Accepted || !name_validator(dialog->name()))
return;
layout.setName(dialog->name());
layout.setCpu(dialog->cpu());
layout.save(layout_index);
delete dialog.get();
updateLayoutSwitcher();
}
void DockManager::resetLayoutClicked(DockLayout::Index layout_index)
{
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
if (!layout.canReset())
return;
QString text = tr("Are you sure you want to reset layout '%1'?").arg(layout.name());
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
return;
bool current_layout = layout_index == m_current_layout;
if (current_layout)
switchToLayout(DockLayout::INVALID_INDEX);
layout.reset();
layout.save(layout_index);
if (current_layout)
switchToLayout(layout_index);
}
void DockManager::deleteLayoutClicked(DockLayout::Index layout_index)
{
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
QString text = tr("Are you sure you want to delete layout '%1'?").arg(layout.name());
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
return;
deleteLayout(layout_index);
updateLayoutSwitcher();
}
void DockManager::layoutSwitcherTabMoved(DockLayout::Index from_index, DockLayout::Index to_index)
{
if (from_index >= m_layouts.size() || to_index >= m_layouts.size())
{
// This happens when the user tries to move a layout to the right of the
@@ -660,135 +681,6 @@ void DockManager::layoutSwitcherTabMoved(int from, int to)
m_current_layout = from_index;
}
void DockManager::layoutSwitcherContextMenu(QPoint pos)
{
DockLayout::Index layout_index = static_cast<DockLayout::Index>(m_switcher->tabAt(pos));
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
QMenu* menu = new QMenu(m_switcher);
menu->setAttribute(Qt::WA_DeleteOnClose);
QAction* edit_action = menu->addAction(tr("Edit Layout"));
connect(edit_action, &QAction::triggered, [this, layout_index]() {
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
auto name_validator = [this, layout_index](const QString& name) {
return !hasNameConflict(name, layout_index);
};
QPointer<LayoutEditorDialog> dialog = new LayoutEditorDialog(
layout.name(), layout.cpu(), name_validator, g_debugger_window);
if (dialog->exec() != QDialog::Accepted || !name_validator(dialog->name()))
return;
layout.setName(dialog->name());
layout.setCpu(dialog->cpu());
layout.save(layout_index);
delete dialog.get();
updateLayoutSwitcher();
});
QAction* reset_action = menu->addAction(tr("Reset Layout"));
reset_action->setEnabled(layout.canReset());
reset_action->connect(reset_action, &QAction::triggered, [this, layout_index]() {
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
if (!layout.canReset())
return;
QString text = tr("Are you sure you want to reset layout '%1'?").arg(layout.name());
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
return;
bool current_layout = layout_index == m_current_layout;
if (current_layout)
switchToLayout(DockLayout::INVALID_INDEX);
layout.reset();
layout.save(layout_index);
if (current_layout)
switchToLayout(layout_index);
});
QAction* delete_action = menu->addAction(tr("Delete Layout"));
connect(delete_action, &QAction::triggered, [this, layout_index]() {
if (layout_index >= m_layouts.size())
return;
DockLayout& layout = m_layouts[layout_index];
QString text = tr("Are you sure you want to delete layout '%1'?").arg(layout.name());
if (QMessageBox::question(g_debugger_window, tr("Confirmation"), text) != QMessageBox::Yes)
return;
deleteLayout(layout_index);
updateLayoutSwitcher();
});
menu->popup(m_switcher->mapToGlobal(pos));
}
void DockManager::layoutSwitcherStartBlink()
{
if (!m_switcher)
return;
layoutSwitcherStopBlink();
if (m_current_layout == DockLayout::INVALID_INDEX)
return;
m_blink_tab = m_current_layout;
m_blink_stage = 0;
m_blink_timer->start(500);
layoutSwitcherUpdateBlink();
}
void DockManager::layoutSwitcherUpdateBlink()
{
if (!m_switcher)
return;
if (m_blink_tab < m_switcher->count())
{
if (m_blink_stage % 2 == 0)
m_switcher->setTabTextColor(m_blink_tab, Qt::red);
else
m_switcher->setTabTextColor(m_blink_tab, m_switcher->palette().text().color());
}
m_blink_stage++;
if (m_blink_stage > 7)
m_blink_timer->stop();
}
void DockManager::layoutSwitcherStopBlink()
{
if (m_blink_timer->isActive())
{
if (m_blink_tab < m_switcher->count())
m_switcher->setTabTextColor(m_blink_tab, m_switcher->palette().text().color());
m_blink_timer->stop();
}
}
bool DockManager::hasNameConflict(const QString& name, DockLayout::Index layout_index)
{
std::string safe_name = Path::SanitizeFileName(name.toStdString());
@@ -867,11 +759,23 @@ void DockManager::switchToDebuggerWidget(DebuggerWidget* widget)
}
}
void DockManager::updateStyleSheets()
void DockManager::updateTheme()
{
if (m_menu_bar)
m_menu_bar->updateTheme();
for (DockLayout& layout : m_layouts)
for (const auto& [unique_name, widget] : layout.debuggerWidgets())
widget->updateStyleSheet();
// KDDockWidgets::QtWidgets::TabBar sets its own style to a subclass of
// QProxyStyle in its constructor, so we need to update that here.
for (KDDockWidgets::Core::Group* group : KDDockWidgets::DockRegistry::self()->groups())
{
auto tab_bar = static_cast<KDDockWidgets::QtWidgets::TabBar*>(group->tabBar()->view());
if (QProxyStyle* style = qobject_cast<QProxyStyle*>(tab_bar->style()))
style->setBaseStyle(QStyleFactory::create(qApp->style()->name()));
}
}
bool DockManager::isLayoutLocked()
@@ -879,23 +783,17 @@ bool DockManager::isLayoutLocked()
return m_layout_locked;
}
void DockManager::setLayoutLocked(bool locked, QPushButton* lock_layout_toggle, bool write_back)
void DockManager::setLayoutLockedAndSaveSetting(bool locked)
{
setLayoutLocked(locked, true);
}
void DockManager::setLayoutLocked(bool locked, bool save_setting)
{
m_layout_locked = locked;
if (lock_layout_toggle)
{
if (m_layout_locked)
{
lock_layout_toggle->setText(tr("Layout Locked"));
lock_layout_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-lock")));
}
else
{
lock_layout_toggle->setText(tr("Layout Unlocked"));
lock_layout_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-unlock")));
}
}
if (m_menu_bar)
m_menu_bar->onLockStateChanged(locked);
updateToolBarLockState();
@@ -909,7 +807,7 @@ void DockManager::setLayoutLocked(bool locked, QPushButton* lock_layout_toggle,
stack->tabBar()->setTabText(0, stack->tabBar()->tabText(0));
}
if (write_back)
if (save_setting)
{
Host::SetBaseBoolSettingValue("Debugger/UserInterface", "LayoutLocked", m_layout_locked);
Host::CommitBaseSettingChanges();

View File

@@ -4,6 +4,7 @@
#pragma once
#include "Debugger/Docking/DockLayout.h"
#include "Debugger/Docking/DockMenuBar.h"
#include <kddockwidgets/MainWindow.h>
#include <kddockwidgets/DockWidget.h>
@@ -68,14 +69,14 @@ public:
void createToolsMenu(QMenu* menu);
void createWindowsMenu(QMenu* menu);
QWidget* createLayoutSwitcher(QWidget* menu_bar);
QWidget* createMenuBar(QWidget* original_menu_bar);
void updateLayoutSwitcher();
void layoutSwitcherTabChanged(int index);
void layoutSwitcherTabMoved(int from, int to);
void layoutSwitcherContextMenu(QPoint pos);
void layoutSwitcherStartBlink();
void layoutSwitcherUpdateBlink();
void layoutSwitcherStopBlink();
void newLayoutClicked();
void openLayoutSwitcherContextMenu(const QPoint& pos, QTabBar* layout_switcher);
void editLayoutClicked(DockLayout::Index layout_index);
void resetLayoutClicked(DockLayout::Index layout_index);
void deleteLayoutClicked(DockLayout::Index layout_index);
void layoutSwitcherTabMoved(DockLayout::Index from_index, DockLayout::Index to_index);
bool hasNameConflict(const QString& name, DockLayout::Index layout_index);
@@ -88,10 +89,11 @@ public:
void setPrimaryDebuggerWidget(DebuggerWidget* widget, bool is_primary);
void switchToDebuggerWidget(DebuggerWidget* widget);
void updateStyleSheets();
void updateTheme();
bool isLayoutLocked();
void setLayoutLocked(bool locked, QPushButton* lock_layout_toggle, bool write_back);
void setLayoutLockedAndSaveSetting(bool locked);
void setLayoutLocked(bool locked, bool save_setting);
void updateToolBarLockState();
std::optional<BreakPointCpu> cpu();
@@ -103,16 +105,7 @@ private:
std::vector<DockLayout> m_layouts;
DockLayout::Index m_current_layout = DockLayout::INVALID_INDEX;
QTabBar* m_switcher = nullptr;
int m_plus_tab_index = -1;
int m_current_tab_index = -1;
bool m_ignore_current_tab_changed = false;
QMetaObject::Connection m_tab_connection;
DockMenuBar* m_menu_bar = nullptr;
bool m_layout_locked = true;
QTimer* m_blink_timer = nullptr;
int m_blink_tab = 0;
int m_blink_stage = 0;
};

View File

@@ -0,0 +1,342 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "DockMenuBar.h"
#include <QtCore/QTimer>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>
#include <QtWidgets/QBoxLayout>
#include <QtWidgets/QStyleFactory>
#include <QtWidgets/QStyleOption>
static const int OUTER_MENU_MARGIN = 2;
static const int INNER_MENU_MARGIN = 4;
DockMenuBar::DockMenuBar(QWidget* original_menu_bar, QWidget* parent)
: QWidget(parent)
, m_original_menu_bar(original_menu_bar)
{
QHBoxLayout* layout = new QHBoxLayout;
layout->setContentsMargins(0, OUTER_MENU_MARGIN, OUTER_MENU_MARGIN, 0);
setLayout(layout);
QWidget* menu_wrapper = new QWidget;
menu_wrapper->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
layout->addWidget(menu_wrapper);
QHBoxLayout* menu_layout = new QHBoxLayout;
menu_layout->setContentsMargins(0, INNER_MENU_MARGIN, 0, INNER_MENU_MARGIN);
menu_wrapper->setLayout(menu_layout);
menu_layout->addWidget(original_menu_bar);
m_layout_switcher = new QTabBar;
m_layout_switcher->setContentsMargins(0, 0, 0, 0);
m_layout_switcher->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
m_layout_switcher->setContextMenuPolicy(Qt::CustomContextMenu);
m_layout_switcher->setDrawBase(false);
m_layout_switcher->setExpanding(false);
m_layout_switcher->setMovable(true);
layout->addWidget(m_layout_switcher);
connect(m_layout_switcher, &QTabBar::tabMoved, this, [this](int from, int to) {
DockLayout::Index from_index = static_cast<DockLayout::Index>(from);
DockLayout::Index to_index = static_cast<DockLayout::Index>(to);
emit layoutMoved(from_index, to_index);
});
connect(m_layout_switcher, &QTabBar::customContextMenuRequested, this, [this](const QPoint& pos) {
emit layoutSwitcherContextMenuRequested(pos, m_layout_switcher);
});
m_blink_timer = new QTimer(this);
connect(m_blink_timer, &QTimer::timeout, this, &DockMenuBar::updateBlink);
m_layout_locked_toggle = new QPushButton;
m_layout_locked_toggle->setCheckable(true);
connect(m_layout_locked_toggle, &QPushButton::clicked, this, [this](bool checked) {
if (m_ignore_lock_state_changed)
return;
emit lockButtonToggled(checked);
});
layout->addWidget(m_layout_locked_toggle);
updateTheme();
}
void DockMenuBar::updateTheme()
{
DockMenuBarStyle* style = new DockMenuBarStyle(m_layout_switcher);
m_original_menu_bar->setStyle(style);
m_layout_switcher->setStyle(style);
m_layout_locked_toggle->setStyle(style);
delete m_style;
m_style = style;
}
void DockMenuBar::updateLayoutSwitcher(DockLayout::Index current_index, const std::vector<DockLayout>& layouts)
{
disconnect(m_tab_connection);
for (int i = m_layout_switcher->count(); i > 0; i--)
m_layout_switcher->removeTab(i - 1);
for (const DockLayout& layout : layouts)
{
const char* cpu_name = DebugInterface::cpuName(layout.cpu());
QString tab_name = QString("%1 (%2)").arg(layout.name()).arg(cpu_name);
m_layout_switcher->addTab(tab_name);
}
m_plus_tab_index = m_layout_switcher->addTab("+");
m_current_tab_index = current_index;
if (current_index != DockLayout::INVALID_INDEX)
m_layout_switcher->setCurrentIndex(current_index);
else
m_layout_switcher->setCurrentIndex(m_plus_tab_index);
// If we don't have any layouts, the currently selected tab will never be
// changed, so we respond to all clicks instead.
if (m_plus_tab_index > 0)
m_tab_connection = connect(m_layout_switcher, &QTabBar::currentChanged, this, &DockMenuBar::tabChanged);
else
m_tab_connection = connect(m_layout_switcher, &QTabBar::tabBarClicked, this, &DockMenuBar::tabChanged);
stopBlink();
}
void DockMenuBar::onCurrentLayoutChanged(DockLayout::Index current_index)
{
m_ignore_current_tab_changed = true;
if (current_index != DockLayout::INVALID_INDEX)
m_layout_switcher->setCurrentIndex(current_index);
else
m_layout_switcher->setCurrentIndex(m_plus_tab_index);
m_ignore_current_tab_changed = false;
}
void DockMenuBar::onLockStateChanged(bool layout_locked)
{
m_ignore_lock_state_changed = true;
m_layout_locked_toggle->setChecked(layout_locked);
if (layout_locked)
{
m_layout_locked_toggle->setText(tr("Layout Locked"));
m_layout_locked_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-lock")));
}
else
{
m_layout_locked_toggle->setText(tr("Layout Unlocked"));
m_layout_locked_toggle->setIcon(QIcon::fromTheme(QString::fromUtf8("padlock-unlock")));
}
m_ignore_lock_state_changed = false;
}
void DockMenuBar::startBlink(DockLayout::Index layout_index)
{
stopBlink();
if (layout_index == DockLayout::INVALID_INDEX)
return;
m_blink_tab = static_cast<int>(layout_index);
m_blink_stage = 0;
m_blink_timer->start(500);
updateBlink();
}
void DockMenuBar::updateBlink()
{
if (m_blink_tab < m_layout_switcher->count())
{
if (m_blink_stage % 2 == 0)
m_layout_switcher->setTabTextColor(m_blink_tab, Qt::red);
else
m_layout_switcher->setTabTextColor(m_blink_tab, m_layout_switcher->palette().text().color());
}
m_blink_stage++;
if (m_blink_stage > 7)
m_blink_timer->stop();
}
void DockMenuBar::stopBlink()
{
if (m_blink_timer->isActive())
{
if (m_blink_tab < m_layout_switcher->count())
m_layout_switcher->setTabTextColor(m_blink_tab, m_layout_switcher->palette().text().color());
m_blink_timer->stop();
}
}
int DockMenuBar::innerHeight() const
{
return m_original_menu_bar->sizeHint().height() + INNER_MENU_MARGIN * 2;
}
void DockMenuBar::paintEvent(QPaintEvent* event)
{
QPainter painter(this);
// This fixes the background colour of the menu bar when using the Windows
// Vista style.
QStyleOptionMenuItem menu_option;
menu_option.palette = palette();
menu_option.state = QStyle::State_None;
menu_option.menuItemType = QStyleOptionMenuItem::EmptyArea;
menu_option.checkType = QStyleOptionMenuItem::NotCheckable;
menu_option.rect = rect();
menu_option.menuRect = rect();
style()->drawControl(QStyle::CE_MenuBarEmptyArea, &menu_option, &painter, this);
}
void DockMenuBar::tabChanged(int index)
{
// Prevent recursion.
if (m_ignore_current_tab_changed)
return;
if (index < m_plus_tab_index)
{
DockLayout::Index layout_index = static_cast<DockLayout::Index>(index);
emit currentLayoutChanged(layout_index);
}
else if (index == m_plus_tab_index)
{
emit newButtonClicked();
}
}
// *****************************************************************************
DockMenuBarStyle::DockMenuBarStyle(QObject* parent)
: QProxyStyle(QStyleFactory::create(qApp->style()->name()))
{
setParent(parent);
}
void DockMenuBarStyle::drawControl(
ControlElement element,
const QStyleOption* option,
QPainter* painter,
const QWidget* widget) const
{
switch (element)
{
case CE_MenuBarItem:
{
const QStyleOptionMenuItem* opt = qstyleoption_cast<const QStyleOptionMenuItem*>(option);
if (!opt)
break;
QWidget* menu_wrapper = widget->parentWidget();
if (!menu_wrapper)
break;
const DockMenuBar* menu_bar = qobject_cast<const DockMenuBar*>(menu_wrapper->parentWidget());
if (!menu_bar)
break;
if (baseStyle()->name() != "fusion")
break;
// This mirrors a check in QFusionStyle::drawControl. If act is
// false, QFusionStyle will try to draw a border along the bottom.
bool act = opt->state & State_Selected && opt->state & State_Sunken;
if (act)
break;
// Extend the menu item to the bottom of the menu bar to fix the
// position in which it draws its bottom border. We also need to
// extend it up by the same amount so that the text isn't moved.
QStyleOptionMenuItem menu_opt = *opt;
int difference = (menu_bar->innerHeight() - option->rect.top()) - menu_opt.rect.height();
menu_opt.rect.adjust(0, -difference, 0, difference);
QProxyStyle::drawControl(element, &menu_opt, painter, widget);
return;
}
case CE_TabBarTab:
{
QProxyStyle::drawControl(element, option, painter, widget);
// Draw a slick-looking highlight under the currently selected tab.
if (baseStyle()->name() == "fusion")
{
const QStyleOptionTab* tab = qstyleoption_cast<const QStyleOptionTab*>(option);
if (tab && (tab->state & State_Selected))
{
painter->setPen(tab->palette.highlight().color());
painter->drawLine(tab->rect.bottomLeft(), tab->rect.bottomRight());
}
}
return;
}
case CE_MenuBarEmptyArea:
{
// Prevent it from drawing a border in the wrong position.
return;
}
default:
{
break;
}
}
QProxyStyle::drawControl(element, option, painter, widget);
}
QSize DockMenuBarStyle::sizeFromContents(
QStyle::ContentsType type, const QStyleOption* option, const QSize& contents_size, const QWidget* widget) const
{
QSize size = QProxyStyle::sizeFromContents(type, option, contents_size, widget);
#ifdef Q_OS_WIN32
// Adjust the sizes of the layout switcher tabs depending on the theme.
if (type == CT_TabBarTab)
{
const QStyleOptionTab* opt = qstyleoption_cast<const QStyleOptionTab*>(option);
if (!opt)
return size;
const QTabBar* tab_bar = qobject_cast<const QTabBar*>(widget);
if (!tab_bar)
return size;
const DockMenuBar* menu_bar = qobject_cast<const DockMenuBar*>(tab_bar->parentWidget());
if (!menu_bar)
return size;
if (baseStyle()->name() == "fusion" || baseStyle()->name() == "windowsvista")
{
// Make sure the tab extends to the bottom of the widget.
size.setHeight(menu_bar->innerHeight() - opt->rect.top());
}
else if (baseStyle()->name() == "windows11")
{
// Adjust the size of the tab such that it is vertically centred.
size.setHeight(menu_bar->innerHeight() - opt->rect.top() * 2 - OUTER_MENU_MARGIN);
// Make the plus button square.
if (opt->tabIndex + 1 == tab_bar->count())
size.setWidth(size.height());
}
}
#endif
return size;
}

View File

@@ -0,0 +1,93 @@
// SPDX-FileCopyrightText: 2002-2025 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#pragma once
#include "Debugger/Docking/DockLayout.h"
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QProxyStyle>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTabBar>
#include <QtWidgets/QWidget>
class DockMenuBarStyle;
// The widget that replaces the normal menu bar. This contains the original menu
// bar, the layout switcher and the layout locked/unlocked toggle button.
class DockMenuBar : public QWidget
{
Q_OBJECT
public:
DockMenuBar(QWidget* original_menu_bar, QWidget* parent = nullptr);
void updateLayoutSwitcher(DockLayout::Index current_index, const std::vector<DockLayout>& layouts);
void updateTheme();
// Notify the menu bar that a new layout has been selected.
void onCurrentLayoutChanged(DockLayout::Index current_index);
// Notify the menu bar that the layout has been locked/unlocked.
void onLockStateChanged(bool layout_locked);
void startBlink(DockLayout::Index layout_index);
void updateBlink();
void stopBlink();
int innerHeight() const;
Q_SIGNALS:
void currentLayoutChanged(DockLayout::Index layout_index);
void newButtonClicked();
void layoutMoved(DockLayout::Index from_index, DockLayout::Index to_index);
void lockButtonToggled(bool locked);
void layoutSwitcherContextMenuRequested(const QPoint& pos, QTabBar* layout_switcher);
protected:
void paintEvent(QPaintEvent* event) override;
private:
void tabChanged(int index);
QWidget* m_original_menu_bar;
QTabBar* m_layout_switcher;
QMetaObject::Connection m_tab_connection;
int m_plus_tab_index = -1;
int m_current_tab_index = -1;
bool m_ignore_current_tab_changed = false;
QTimer* m_blink_timer = nullptr;
int m_blink_tab = 0;
int m_blink_stage = 0;
QPushButton* m_layout_locked_toggle;
bool m_ignore_lock_state_changed = false;
DockMenuBarStyle* m_style = nullptr;
};
// Fixes some theming issues relating to the menu bar, the layout switcher and
// the layout locked/unlocked toggle button.
class DockMenuBarStyle : public QProxyStyle
{
Q_OBJECT
public:
DockMenuBarStyle(QObject* parent = nullptr);
void drawControl(
ControlElement element,
const QStyleOption* option,
QPainter* painter,
const QWidget* widget = nullptr) const override;
QSize sizeFromContents(
QStyle::ContentsType type,
const QStyleOption* option,
const QSize& contents_size,
const QWidget* widget = nullptr) const override;
};

View File

@@ -20,6 +20,7 @@
#include <QtWidgets/QInputDialog>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QMenu>
#include <QtWidgets/QStyleFactory>
KDDockWidgets::Core::View* DockViewFactory::createDockWidget(
const QString& unique_name,
@@ -143,6 +144,14 @@ DockTabBar::DockTabBar(KDDockWidgets::Core::TabBar* controller, QWidget* parent)
{
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &DockTabBar::customContextMenuRequested, this, &DockTabBar::openContextMenu);
// The constructor of KDDockWidgets::QtWidgets::TabBar makes a QProxyStyle
// that ends up taking ownerhsip of the style for the entire application!
if (QProxyStyle* proxy_style = qobject_cast<QProxyStyle*>(style()))
{
proxy_style->baseStyle()->setParent(qApp);
proxy_style->setBaseStyle(QStyleFactory::create(qApp->style()->name()));
}
}
void DockTabBar::openContextMenu(QPoint pos)

View File

@@ -151,6 +151,10 @@ void MainWindow::initialize()
ctx->updateTheme(); // Qt won't notice the style change without us touching the palette in some way
});
});
// The cocoa backing isn't initialized yet, delay this until stuff is set up with a `RunOnUIThread` call
QtHost::RunOnUIThread([this]{
CocoaTools::MarkHelpMenu(m_ui.menuHelp->toNSMenu());
});
#endif
m_ui.setupUi(this);
setupAdditionalUi();
@@ -1781,7 +1785,7 @@ void MainWindow::updateTheme()
reloadThemeSpecificImages();
if (g_debugger_window)
g_debugger_window->updateStyleSheets();
g_debugger_window->updateTheme();
}
void MainWindow::reloadThemeSpecificImages()

View File

@@ -3872,7 +3872,7 @@ Do you want to overwrite?</source>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.ui" line="44"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="69"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="80"/>
<source>Automatically Select Symbols To Clear</source>
<translation type="unfinished"></translation>
</message>
@@ -3888,25 +3888,25 @@ Do you want to overwrite?</source>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.ui" line="132"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="88"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="99"/>
<source>Import From ELF</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.ui" line="139"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="92"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="103"/>
<source>Demangle Symbols</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.ui" line="146"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="95"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="106"/>
<source>Demangle Parameters</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.ui" line="153"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="90"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="101"/>
<source>Import Default .sym File</source>
<translation type="unfinished"></translation>
</message>
@@ -3937,7 +3937,7 @@ Do you want to overwrite?</source>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.ui" line="289"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="115"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="126"/>
<source>Scan ELF</source>
<translation type="unfinished"></translation>
</message>
@@ -3973,102 +3973,102 @@ Do you want to overwrite?</source>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.ui" line="401"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="141"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="160"/>
<source>Gray Out Symbols For Overwritten Functions</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="69"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="88"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="90"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="92"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="95"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="141"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="80"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="99"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="101"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="103"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="106"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="160"/>
<source>Checked</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="70"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="81"/>
<source>Automatically delete symbols that were generated by any previous analysis runs.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="89"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="100"/>
<source>Import symbol tables stored in the game&apos;s boot ELF.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="91"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="102"/>
<source>Import symbols from a .sym file with the same name as the loaded ISO file on disk if such a file exists.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="93"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="104"/>
<source>Demangle C++ symbols during the import process so that the function and global variable names shown in the debugger are more readable.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="96"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="107"/>
<source>Include parameter lists in demangled function names.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="115"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="126"/>
<source>Scan Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="116"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="127"/>
<source>Choose where the function scanner looks to find functions. This option can be useful if the application loads additional code at runtime.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="128"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="147"/>
<source>Custom Address Range</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="128"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="147"/>
<source>Unchecked</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="129"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="148"/>
<source>Whether to look for functions from the address range specified (Checked), or from the ELF segment containing the entry point (Unchecked).</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="142"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="161"/>
<source>Generate hashes for all the detected functions, and gray out the symbols displayed in the debugger for functions that no longer match.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="220"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="239"/>
<source>&lt;i&gt;No symbol sources in database.&lt;/i&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="240"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="259"/>
<source>&lt;i&gt;Start this game to modify the symbol sources list.&lt;/i&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="312"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="334"/>
<source>Path</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="313"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="335"/>
<source>Base Address</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="314"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="336"/>
<source>Condition</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="361"/>
<location filename="../Settings/DebugAnalysisSettingsWidget.cpp" line="383"/>
<source>Add Symbol File</source>
<translation type="unfinished"></translation>
</message>
@@ -4984,7 +4984,7 @@ Do you want to overwrite?</source>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.ui" line="157"/>
<location filename="../Debugger/DebuggerWindow.cpp" line="303"/>
<location filename="../Debugger/DebuggerWindow.cpp" line="304"/>
<source>Run</source>
<translation type="unfinished"></translation>
</message>
@@ -5110,7 +5110,7 @@ Do you want to overwrite?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/DebuggerWindow.cpp" line="337"/>
<location filename="../Debugger/DebuggerWindow.cpp" line="338"/>
<source>Pause</source>
<translation type="unfinished"></translation>
</message>
@@ -5292,53 +5292,56 @@ Do you want to overwrite?</source>
<context>
<name>DockManager</name>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="113"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="111"/>
<source>No Layouts</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="366"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="360"/>
<source>Add Another...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="674"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="574"/>
<source>Edit Layout</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="701"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="579"/>
<source>Reset Layout</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="711"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="629"/>
<source>Are you sure you want to reset layout &apos;%1&apos;?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="712"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="735"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="630"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="653"/>
<source>Confirmation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="727"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="585"/>
<source>Delete Layout</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="734"/>
<location filename="../Debugger/Docking/DockManager.cpp" line="652"/>
<source>Are you sure you want to delete layout &apos;%1&apos;?</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DockMenuBar</name>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="890"/>
<location filename="../Debugger/Docking/DockMenuBar.cpp" line="132"/>
<source>Layout Locked</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockManager.cpp" line="895"/>
<location filename="../Debugger/Docking/DockMenuBar.cpp" line="137"/>
<source>Layout Unlocked</source>
<translation type="unfinished"></translation>
</message>
@@ -5346,52 +5349,52 @@ Do you want to overwrite?</source>
<context>
<name>DockTabBar</name>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="166"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="175"/>
<source>Rename</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="177"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="186"/>
<source>Rename Window</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="177"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="186"/>
<source>New name:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="183"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="192"/>
<source>Invalid Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="183"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="192"/>
<source>The specified name is too long.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="190"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="199"/>
<source>Reset Name</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="204"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="213"/>
<source>Primary</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="219"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="228"/>
<source>Set Target</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="240"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="249"/>
<source>Inherit From Layout</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../Debugger/Docking/DockViews.cpp" line="248"/>
<location filename="../Debugger/Docking/DockViews.cpp" line="257"/>
<source>Close</source>
<translation type="unfinished"></translation>
</message>
@@ -16027,13 +16030,13 @@ Right click to clear binding</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1485"/>
<location filename="../MainWindow.cpp" line="1546"/>
<location filename="../MainWindow.cpp" line="1489"/>
<location filename="../MainWindow.cpp" line="1550"/>
<source>Change Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2925"/>
<location filename="../MainWindow.cpp" line="2929"/>
<source>Load State</source>
<translation type="unfinished"></translation>
</message>
@@ -16596,50 +16599,50 @@ Right click to clear binding</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1589"/>
<location filename="../MainWindow.cpp" line="1593"/>
<source>Start Big Picture Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.ui" line="1008"/>
<location filename="../MainWindow.cpp" line="1590"/>
<location filename="../MainWindow.cpp" line="1594"/>
<source>Big Picture</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="688"/>
<location filename="../MainWindow.cpp" line="692"/>
<source>Show Advanced Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="759"/>
<location filename="../MainWindow.cpp" line="808"/>
<location filename="../MainWindow.cpp" line="763"/>
<location filename="../MainWindow.cpp" line="812"/>
<source>Video Capture</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="269"/>
<location filename="../MainWindow.cpp" line="273"/>
<source>Internal Resolution</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="269"/>
<location filename="../MainWindow.cpp" line="273"/>
<source>%1x Scale</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="666"/>
<location filename="../MainWindow.cpp" line="670"/>
<source>Select location to save block dump:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="684"/>
<location filename="../MainWindow.cpp" line="688"/>
<source>Do not show again</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="689"/>
<location filename="../MainWindow.cpp" line="693"/>
<source>Changing advanced settings can have unpredictable effects on games, including graphical glitches, lock-ups, and even corrupted save files. We do not recommend changing advanced settings unless you know what you are doing, and the implications of changing each setting.
The PCSX2 team will not provide any support for configurations that modify these settings, you are on your own.
@@ -16648,321 +16651,321 @@ Are you sure you want to continue?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="746"/>
<location filename="../MainWindow.cpp" line="771"/>
<location filename="../MainWindow.cpp" line="750"/>
<location filename="../MainWindow.cpp" line="775"/>
<source>Record On Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="748"/>
<location filename="../MainWindow.cpp" line="752"/>
<source>Did you want to start recording on boot?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="756"/>
<location filename="../MainWindow.cpp" line="805"/>
<location filename="../MainWindow.cpp" line="760"/>
<location filename="../MainWindow.cpp" line="809"/>
<source>%1 Files (*.%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="773"/>
<location filename="../MainWindow.cpp" line="777"/>
<source>Did you want to cancel recording on boot?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="798"/>
<location filename="../MainWindow.cpp" line="802"/>
<source>Recording will start in a moment</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1153"/>
<location filename="../MainWindow.cpp" line="1157"/>
<source>WARNING: Memory Card Busy</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1279"/>
<location filename="../MainWindow.cpp" line="1283"/>
<source>Confirm Shutdown</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1282"/>
<location filename="../MainWindow.cpp" line="1286"/>
<source>Are you sure you want to shut down the virtual machine?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1284"/>
<location filename="../MainWindow.cpp" line="1288"/>
<source>Save State For Resume</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1392"/>
<location filename="../MainWindow.cpp" line="1762"/>
<location filename="../MainWindow.cpp" line="2229"/>
<location filename="../MainWindow.cpp" line="2393"/>
<location filename="../MainWindow.cpp" line="2830"/>
<location filename="../MainWindow.cpp" line="2944"/>
<location filename="../MainWindow.cpp" line="1396"/>
<location filename="../MainWindow.cpp" line="1766"/>
<location filename="../MainWindow.cpp" line="2233"/>
<location filename="../MainWindow.cpp" line="2397"/>
<location filename="../MainWindow.cpp" line="2834"/>
<location filename="../MainWindow.cpp" line="2948"/>
<source>Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1392"/>
<location filename="../MainWindow.cpp" line="1396"/>
<source>You must select a disc to change discs.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1424"/>
<location filename="../MainWindow.cpp" line="1428"/>
<source>Properties...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1440"/>
<location filename="../MainWindow.cpp" line="1444"/>
<source>Set Cover Image...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1443"/>
<location filename="../MainWindow.cpp" line="1447"/>
<source>Exclude From List</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1446"/>
<location filename="../MainWindow.cpp" line="1450"/>
<source>Reset Play Time</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1450"/>
<location filename="../MainWindow.cpp" line="1454"/>
<source>Check Wiki Page</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1457"/>
<location filename="../MainWindow.cpp" line="1461"/>
<source>Default Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1464"/>
<location filename="../MainWindow.cpp" line="1468"/>
<source>Fast Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1467"/>
<location filename="../MainWindow.cpp" line="1471"/>
<source>Full Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1472"/>
<location filename="../MainWindow.cpp" line="1476"/>
<source>Boot and Debug</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1496"/>
<location filename="../MainWindow.cpp" line="1500"/>
<source>Add Search Directory...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1505"/>
<location filename="../MainWindow.cpp" line="1509"/>
<source>Start File</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1514"/>
<location filename="../MainWindow.cpp" line="1518"/>
<source>Start Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1531"/>
<location filename="../MainWindow.cpp" line="1535"/>
<source>Select Disc Image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1675"/>
<location filename="../MainWindow.cpp" line="1679"/>
<source>Updater Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1681"/>
<location filename="../MainWindow.cpp" line="1685"/>
<source>&lt;p&gt;Sorry, you are trying to update a PCSX2 version which is not an official GitHub release. To prevent incompatibilities, the auto-updater is only enabled on official builds.&lt;/p&gt;&lt;p&gt;To obtain an official build, please download from the link below:&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://pcsx2.net/downloads/&quot;&gt;https://pcsx2.net/downloads/&lt;/a&gt;&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1686"/>
<location filename="../MainWindow.cpp" line="1690"/>
<source>Automatic updating is not supported on the current platform.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1752"/>
<location filename="../MainWindow.cpp" line="1756"/>
<source>Confirm File Creation</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1753"/>
<location filename="../MainWindow.cpp" line="1757"/>
<source>The pnach file &apos;%1&apos; does not currently exist. Do you want to create it?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1762"/>
<location filename="../MainWindow.cpp" line="1766"/>
<source>Failed to create &apos;%1&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1861"/>
<location filename="../MainWindow.cpp" line="1865"/>
<source>Input Recording Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1862"/>
<location filename="../MainWindow.cpp" line="1866"/>
<source>Failed to create file: {}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1885"/>
<location filename="../MainWindow.cpp" line="1889"/>
<source>Input Recording Files (*.p2m2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1920"/>
<location filename="../MainWindow.cpp" line="1924"/>
<source>Input Playback Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1921"/>
<location filename="../MainWindow.cpp" line="1925"/>
<source>Failed to open file: {}</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2007"/>
<location filename="../MainWindow.cpp" line="2011"/>
<source>Paused</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2186"/>
<location filename="../MainWindow.cpp" line="2190"/>
<source>Load State Failed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2186"/>
<location filename="../MainWindow.cpp" line="2190"/>
<source>Cannot load a save state without a running VM.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2214"/>
<location filename="../MainWindow.cpp" line="2218"/>
<source>The new ELF cannot be loaded without resetting the virtual machine. Do you want to reset the virtual machine now?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2229"/>
<location filename="../MainWindow.cpp" line="2233"/>
<source>Cannot change from game to GS dump without shutting down first.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2393"/>
<location filename="../MainWindow.cpp" line="2397"/>
<source>Failed to get window info from widget</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1589"/>
<location filename="../MainWindow.cpp" line="1593"/>
<source>Stop Big Picture Mode</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1590"/>
<location filename="../MainWindow.cpp" line="1594"/>
<source>Exit Big Picture</source>
<comment>In Toolbar</comment>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2736"/>
<location filename="../MainWindow.cpp" line="2740"/>
<source>Game Properties</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2736"/>
<location filename="../MainWindow.cpp" line="2740"/>
<source>Game properties is unavailable for the current game.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2788"/>
<location filename="../MainWindow.cpp" line="2792"/>
<source>Could not find any CD/DVD-ROM devices. Please ensure you have a drive connected and sufficient permissions to access it.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2806"/>
<location filename="../MainWindow.cpp" line="2810"/>
<source>Select disc drive:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2830"/>
<location filename="../MainWindow.cpp" line="2834"/>
<source>This save state does not exist.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2843"/>
<location filename="../MainWindow.cpp" line="2847"/>
<source>Select Cover Image</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2860"/>
<location filename="../MainWindow.cpp" line="2864"/>
<source>Cover Already Exists</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2861"/>
<location filename="../MainWindow.cpp" line="2865"/>
<source>A cover image for this game already exists, do you wish to replace it?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2856"/>
<location filename="../MainWindow.cpp" line="2870"/>
<location filename="../MainWindow.cpp" line="2876"/>
<location filename="../MainWindow.cpp" line="2882"/>
<location filename="../MainWindow.cpp" line="2860"/>
<location filename="../MainWindow.cpp" line="2874"/>
<location filename="../MainWindow.cpp" line="2880"/>
<location filename="../MainWindow.cpp" line="2886"/>
<source>Copy Error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2870"/>
<location filename="../MainWindow.cpp" line="2874"/>
<source>Failed to remove existing cover &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2876"/>
<location filename="../MainWindow.cpp" line="2880"/>
<source>Failed to copy &apos;%1&apos; to &apos;%2&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2882"/>
<location filename="../MainWindow.cpp" line="2886"/>
<source>Failed to remove &apos;%1&apos;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2213"/>
<location filename="../MainWindow.cpp" line="2891"/>
<location filename="../MainWindow.cpp" line="2217"/>
<location filename="../MainWindow.cpp" line="2895"/>
<source>Confirm Reset</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2843"/>
<location filename="../MainWindow.cpp" line="2847"/>
<source>All Cover Image Types (*.jpg *.jpeg *.png *.webp)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2856"/>
<location filename="../MainWindow.cpp" line="2860"/>
<source>You must select a different file to the current cover image.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2892"/>
<location filename="../MainWindow.cpp" line="2896"/>
<source>Are you sure you want to reset the play time for &apos;%1&apos;?
This action cannot be undone.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2919"/>
<location filename="../MainWindow.cpp" line="2923"/>
<source>Load Resume State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2922"/>
<location filename="../MainWindow.cpp" line="2926"/>
<source>A resume save state was found for this game, saved at:
%1.
@@ -16971,43 +16974,43 @@ Do you want to load this state, or start from a fresh boot?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2926"/>
<location filename="../MainWindow.cpp" line="2930"/>
<source>Fresh Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2927"/>
<location filename="../MainWindow.cpp" line="2931"/>
<source>Delete And Boot</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="2944"/>
<location filename="../MainWindow.cpp" line="2948"/>
<source>Failed to delete save state file &apos;%1&apos;.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3002"/>
<location filename="../MainWindow.cpp" line="3006"/>
<source>Load State File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3002"/>
<location filename="../MainWindow.cpp" line="3006"/>
<source>Load From File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3005"/>
<location filename="../MainWindow.cpp" line="3076"/>
<location filename="../MainWindow.cpp" line="3009"/>
<location filename="../MainWindow.cpp" line="3080"/>
<source>Select Save State File</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3076"/>
<location filename="../MainWindow.cpp" line="3080"/>
<source>Save States (*.p2s)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3012"/>
<location filename="../MainWindow.cpp" line="3016"/>
<source>Delete Save States...</source>
<translation type="unfinished"></translation>
</message>
@@ -17022,80 +17025,80 @@ Do you want to load this state, or start from a fresh boot?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="1154"/>
<location filename="../MainWindow.cpp" line="1158"/>
<source>WARNING: Your memory card is still writing data. Shutting down now &lt;b&gt;WILL IRREVERSIBLY DESTROY YOUR MEMORY CARD.&lt;/b&gt; It is strongly recommended to resume your game and let it finish writing to your memory card.&lt;br&gt;&lt;br&gt;Do you wish to shutdown anyways and &lt;b&gt;IRREVERSIBLY DESTROY YOUR MEMORY CARD?&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3005"/>
<location filename="../MainWindow.cpp" line="3009"/>
<source>Save States (*.p2s *.p2s.backup)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3017"/>
<location filename="../MainWindow.cpp" line="3021"/>
<source>Undo Load State</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3031"/>
<location filename="../MainWindow.cpp" line="3035"/>
<source>Resume (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3047"/>
<location filename="../MainWindow.cpp" line="3051"/>
<source>Load Slot %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3056"/>
<location filename="../MainWindow.cpp" line="3064"/>
<location filename="../MainWindow.cpp" line="3060"/>
<location filename="../MainWindow.cpp" line="3068"/>
<source>Delete Save States</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3057"/>
<location filename="../MainWindow.cpp" line="3061"/>
<source>Are you sure you want to delete all save states for %1?
The saves will not be recoverable.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3064"/>
<location filename="../MainWindow.cpp" line="3068"/>
<source>%1 save states deleted.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3074"/>
<location filename="../MainWindow.cpp" line="3078"/>
<source>Save To File...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3094"/>
<location filename="../MainWindow.cpp" line="3098"/>
<source>Empty</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3096"/>
<location filename="../MainWindow.cpp" line="3100"/>
<source>Save Slot %1 (%2)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3147"/>
<location filename="../MainWindow.cpp" line="3151"/>
<source>Confirm Disc Change</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3148"/>
<location filename="../MainWindow.cpp" line="3152"/>
<source>Do you want to swap discs or boot the new image (via system reset)?</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3149"/>
<location filename="../MainWindow.cpp" line="3153"/>
<source>Swap Disc</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../MainWindow.cpp" line="3150"/>
<location filename="../MainWindow.cpp" line="3154"/>
<source>Reset</source>
<translation type="unfinished"></translation>
</message>

View File

@@ -126,6 +126,7 @@
<ClCompile Include="Debugger\Breakpoints\BreakpointWidget.cpp" />
<ClCompile Include="Debugger\Docking\DockLayout.cpp" />
<ClCompile Include="Debugger\Docking\DockManager.cpp" />
<ClCompile Include="Debugger\Docking\DockMenuBar.cpp" />
<ClCompile Include="Debugger\Docking\DockTables.cpp" />
<ClCompile Include="Debugger\Docking\DockUtils.cpp" />
<ClCompile Include="Debugger\Docking\DockViews.cpp" />
@@ -242,6 +243,7 @@
<QtMoc Include="Debugger\Breakpoints\BreakpointWidget.h" />
<QtMoc Include="Debugger\Docking\DockLayout.h" />
<QtMoc Include="Debugger\Docking\DockManager.h" />
<QtMoc Include="Debugger\Docking\DockMenuBar.h" />
<QtMoc Include="Debugger\Docking\DockTables.h" />
<QtMoc Include="Debugger\Docking\DockUtils.h" />
<QtMoc Include="Debugger\Docking\DockViews.h" />
@@ -313,6 +315,7 @@
<ClCompile Include="$(IntDir)Debugger\Breakpoints\moc_BreakpointModel.cpp" />
<ClCompile Include="$(IntDir)Debugger\Breakpoints\moc_BreakpointWidget.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DockManager.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DockMenuBar.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DockViews.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DropIndicators.cpp" />
<ClCompile Include="$(IntDir)Debugger\Docking\moc_LayoutEditorDialog.cpp" />

View File

@@ -488,6 +488,12 @@
<ClCompile Include="$(IntDir)Debugger\SymbolTree\moc_TypeString.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)Debugger\Docking\moc_DockMenuBar.cpp">
<Filter>moc</Filter>
</ClCompile>
<ClCompile Include="Debugger\Docking\DockMenuBar.cpp">
<Filter>Debugger\Docking</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Manifest Include="..\pcsx2\windows\PCSX2.manifest">
@@ -719,6 +725,9 @@
<QtMoc Include="Debugger\SymbolTree\NewSymbolDialogs.h">
<Filter>Debugger\SymbolTree</Filter>
</QtMoc>
<QtMoc Include="Debugger\Docking\DockMenuBar.h">
<Filter>Debugger\Docking</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<QtResource Include="resources\resources.qrc">