mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 03:18:55 +02:00
[desktop] Port some QtCommon changes from QML branch (#3703)
- Linker now resolves implementation differences - Remove unneeded ifdefs - Better abstractions overall Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3703 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
This commit is contained in:
parent
07e3a2aa46
commit
0ff1d215c8
36 changed files with 405 additions and 371 deletions
|
|
@ -115,7 +115,7 @@ for file in $FILES; do
|
||||||
*.cmake|*.sh|*CMakeLists.txt)
|
*.cmake|*.sh|*CMakeLists.txt)
|
||||||
begin="#"
|
begin="#"
|
||||||
;;
|
;;
|
||||||
*.kt*|*.cpp|*.h)
|
*.kt*|*.cpp|*.h|*.qml)
|
||||||
begin="//"
|
begin="//"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
|
@ -193,7 +193,7 @@ if [ "$UPDATE" = "true" ]; then
|
||||||
begin="#"
|
begin="#"
|
||||||
shell=true
|
shell=true
|
||||||
;;
|
;;
|
||||||
*.kt*|*.cpp|*.h)
|
*)
|
||||||
begin="//"
|
begin="//"
|
||||||
shell="false"
|
shell="false"
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,6 @@ if (YUZU_CMD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_QT)
|
if (ENABLE_QT)
|
||||||
add_definitions(-DYUZU_QT_WIDGETS)
|
|
||||||
add_subdirectory(qt_common)
|
add_subdirectory(qt_common)
|
||||||
add_subdirectory(yuzu)
|
add_subdirectory(yuzu)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
add_library(qt_common STATIC
|
add_library(qt_common STATIC
|
||||||
qt_common.h
|
qt_common.h
|
||||||
qt_common.cpp
|
qt_common.cpp
|
||||||
|
|
@ -26,7 +28,7 @@ add_library(qt_common STATIC
|
||||||
util/mod.h util/mod.cpp
|
util/mod.h util/mod.cpp
|
||||||
|
|
||||||
abstract/frontend.h abstract/frontend.cpp
|
abstract/frontend.h abstract/frontend.cpp
|
||||||
abstract/qt_progress_dialog.h abstract/qt_progress_dialog.cpp
|
abstract/progress.h abstract/progress.cpp
|
||||||
|
|
||||||
qt_string_lookup.h
|
qt_string_lookup.h
|
||||||
qt_compat.h
|
qt_compat.h
|
||||||
|
|
@ -93,3 +95,5 @@ if (UNIX AND NOT APPLE)
|
||||||
target_link_libraries(qt_common PRIVATE Qt6::GuiPrivate)
|
target_link_libraries(qt_common PRIVATE Qt6::GuiPrivate)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
create_target_directory_groups(qt_common)
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1,27 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include "frontend.h"
|
#include "frontend.h"
|
||||||
#include "qt_common/qt_common.h"
|
|
||||||
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
#include <QFileDialog>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QAbstractButton>
|
|
||||||
#include <QInputDialog>
|
|
||||||
|
|
||||||
namespace QtCommon::Frontend {
|
namespace QtCommon::Frontend {
|
||||||
|
|
||||||
StandardButton ShowMessage(Icon icon, const QString& title, const QString& text,
|
|
||||||
StandardButtons buttons, QObject* parent) {
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
QMessageBox* box = new QMessageBox(icon, title, text, buttons, (QWidget*)parent);
|
|
||||||
return static_cast<QMessageBox::StandardButton>(box->exec());
|
|
||||||
#endif
|
|
||||||
// TODO(crueter): If Qt Widgets is disabled...
|
|
||||||
// need a way to reference icon/buttons too
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString GetOpenFileName(const QString& title, const QString& dir, const QString& filter,
|
const QString GetOpenFileName(const QString& title, const QString& dir, const QString& filter,
|
||||||
QString* selectedFilter, Options options) {
|
QString* selectedFilter) {
|
||||||
#ifdef YUZU_QT_WIDGETS
|
return QFileDialog::getOpenFileName(rootObject, title, dir, filter, selectedFilter);
|
||||||
return QFileDialog::getOpenFileName(rootObject, title, dir, filter, selectedFilter, options);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringList GetOpenFileNames(const QString& title, const QString& dir, const QString& filter,
|
const QStringList GetOpenFileNames(const QString& title, const QString& dir, const QString& filter,
|
||||||
QString* selectedFilter, Options options) {
|
QString* selectedFilter) {
|
||||||
#ifdef YUZU_QT_WIDGETS
|
return QFileDialog::getOpenFileNames(rootObject, title, dir, filter, selectedFilter);
|
||||||
return QFileDialog::getOpenFileNames(rootObject, title, dir, filter, selectedFilter, options);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString GetSaveFileName(const QString& title, const QString& dir, const QString& filter,
|
const QString GetSaveFileName(const QString& title, const QString& dir, const QString& filter,
|
||||||
QString* selectedFilter, Options options) {
|
QString* selectedFilter) {
|
||||||
#ifdef YUZU_QT_WIDGETS
|
return QFileDialog::getSaveFileName(rootObject, title, dir, filter, selectedFilter);
|
||||||
return QFileDialog::getSaveFileName(rootObject, title, dir, filter, selectedFilter, options);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString GetExistingDirectory(const QString& caption, const QString& dir, Options options) {
|
const QString GetExistingDirectory(const QString& caption, const QString& dir) {
|
||||||
#ifdef YUZU_QT_WIDGETS
|
return QFileDialog::getExistingDirectory(rootObject, caption, dir);
|
||||||
return QFileDialog::getExistingDirectory(rootObject, caption, dir, options);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int Choice(const QString& title, const QString& caption, const QStringList& options) {
|
|
||||||
QMessageBox box(rootObject);
|
|
||||||
box.setText(caption);
|
|
||||||
box.setWindowTitle(title);
|
|
||||||
|
|
||||||
for (const QString& opt : options) {
|
|
||||||
box.addButton(opt, QMessageBox::AcceptRole);
|
|
||||||
}
|
|
||||||
|
|
||||||
box.addButton(QMessageBox::Cancel);
|
|
||||||
|
|
||||||
box.exec();
|
|
||||||
auto button = box.clickedButton();
|
|
||||||
return options.indexOf(button->text());
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString GetTextInput(const QString& title, const QString& caption,
|
|
||||||
const QString& defaultText) {
|
|
||||||
return QInputDialog::getText(rootObject, title, caption, QLineEdit::Normal, defaultText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QtCommon::Frontend
|
} // namespace QtCommon::Frontend
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,7 @@
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include "qt_common/qt_common.h"
|
#include "qt_common/qt_common.h"
|
||||||
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QWidget>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* manages common functionality e.g. message boxes and such for Qt/QML
|
* manages common functionality e.g. message boxes and such for Qt/QML
|
||||||
|
|
@ -20,30 +16,9 @@ namespace QtCommon::Frontend {
|
||||||
|
|
||||||
Q_NAMESPACE
|
Q_NAMESPACE
|
||||||
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
using Options = QFileDialog::Options;
|
|
||||||
using Option = QFileDialog::Option;
|
|
||||||
|
|
||||||
using StandardButton = QMessageBox::StandardButton;
|
|
||||||
using StandardButtons = QMessageBox::StandardButtons;
|
|
||||||
|
|
||||||
using Icon = QMessageBox::Icon;
|
|
||||||
#else
|
|
||||||
enum Option {
|
|
||||||
ShowDirsOnly = 0x00000001,
|
|
||||||
DontResolveSymlinks = 0x00000002,
|
|
||||||
DontConfirmOverwrite = 0x00000004,
|
|
||||||
DontUseNativeDialog = 0x00000008,
|
|
||||||
ReadOnly = 0x00000010,
|
|
||||||
HideNameFilterDetails = 0x00000020,
|
|
||||||
DontUseCustomDirectoryIcons = 0x00000040
|
|
||||||
};
|
|
||||||
Q_ENUM_NS(Option)
|
|
||||||
Q_DECLARE_FLAGS(Options, Option)
|
|
||||||
Q_FLAG_NS(Options)
|
|
||||||
|
|
||||||
enum StandardButton {
|
enum StandardButton {
|
||||||
// keep this in sync with QDialogButtonBox::StandardButton and QPlatformDialogHelper::StandardButton
|
// keep this in sync with QDialogButtonBox::StandardButton and
|
||||||
|
// QPlatformDialogHelper::StandardButton
|
||||||
NoButton = 0x00000000,
|
NoButton = 0x00000000,
|
||||||
Ok = 0x00000400,
|
Ok = 0x00000400,
|
||||||
Save = 0x00000800,
|
Save = 0x00000800,
|
||||||
|
|
@ -83,7 +58,7 @@ typedef StandardButton Button;
|
||||||
Q_DECLARE_FLAGS(StandardButtons, StandardButton)
|
Q_DECLARE_FLAGS(StandardButtons, StandardButton)
|
||||||
Q_FLAG_NS(StandardButtons)
|
Q_FLAG_NS(StandardButtons)
|
||||||
|
|
||||||
enum Icon {
|
enum class Icon {
|
||||||
// keep this in sync with QMessageDialogOptions::StandardIcon
|
// keep this in sync with QMessageDialogOptions::StandardIcon
|
||||||
NoIcon = 0,
|
NoIcon = 0,
|
||||||
Information = 1,
|
Information = 1,
|
||||||
|
|
@ -93,29 +68,26 @@ enum Icon {
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(Icon)
|
Q_ENUM_NS(Icon)
|
||||||
|
|
||||||
#endif
|
StandardButton ShowMessage(Icon icon, const QString& title, const QString& text,
|
||||||
|
|
||||||
// TODO(crueter) widgets-less impl, choices et al.
|
|
||||||
StandardButton ShowMessage(Icon icon,
|
|
||||||
const QString &title,
|
|
||||||
const QString &text,
|
|
||||||
StandardButtons buttons = StandardButton::NoButton,
|
StandardButtons buttons = StandardButton::NoButton,
|
||||||
QObject *parent = nullptr);
|
QObject* parent = nullptr);
|
||||||
|
|
||||||
#define UTIL_OVERRIDES(level) \
|
#define UTIL_OVERRIDES(level) \
|
||||||
inline StandardButton level(QObject *parent, \
|
inline StandardButton level(QObject* parent, const QString& title, const QString& text, \
|
||||||
const QString &title, \
|
StandardButtons buttons) { \
|
||||||
const QString &text, \
|
|
||||||
StandardButtons buttons = StandardButton::Ok) \
|
|
||||||
{ \
|
|
||||||
return ShowMessage(Icon::level, title, text, buttons, parent); \
|
return ShowMessage(Icon::level, title, text, buttons, parent); \
|
||||||
} \
|
} \
|
||||||
inline StandardButton level(const QString title, \
|
inline StandardButton level(QObject* parent, const QString& title, const QString& text, \
|
||||||
const QString &text, \
|
int buttons = StandardButton::Ok) { \
|
||||||
StandardButtons buttons \
|
return ShowMessage(Icon::level, title, text, StandardButtons(buttons), parent); \
|
||||||
= StandardButton::Ok) \
|
} \
|
||||||
{ \
|
inline StandardButton level(const QString title, const QString& text, \
|
||||||
|
StandardButtons buttons) { \
|
||||||
return ShowMessage(Icon::level, title, text, buttons, rootObject); \
|
return ShowMessage(Icon::level, title, text, buttons, rootObject); \
|
||||||
|
} \
|
||||||
|
inline StandardButton level(const QString& title, const QString& text, \
|
||||||
|
int buttons = StandardButton::Ok) { \
|
||||||
|
return ShowMessage(Icon::level, title, text, StandardButtons(buttons), rootObject); \
|
||||||
}
|
}
|
||||||
|
|
||||||
UTIL_OVERRIDES(Information)
|
UTIL_OVERRIDES(Information)
|
||||||
|
|
@ -123,27 +95,17 @@ UTIL_OVERRIDES(Warning)
|
||||||
UTIL_OVERRIDES(Critical)
|
UTIL_OVERRIDES(Critical)
|
||||||
UTIL_OVERRIDES(Question)
|
UTIL_OVERRIDES(Question)
|
||||||
|
|
||||||
const QString GetOpenFileName(const QString &title,
|
const QString GetOpenFileName(const QString& title, const QString& dir, const QString& filter,
|
||||||
const QString &dir,
|
QString* selectedFilter = nullptr);
|
||||||
const QString &filter,
|
|
||||||
QString *selectedFilter = nullptr,
|
|
||||||
Options options = Options());
|
|
||||||
|
|
||||||
const QStringList GetOpenFileNames(const QString &title,
|
const QStringList GetOpenFileNames(const QString& title, const QString& dir, const QString& filter,
|
||||||
const QString &dir,
|
QString* selectedFilter = nullptr);
|
||||||
const QString &filter,
|
|
||||||
QString *selectedFilter = nullptr,
|
|
||||||
Options options = Options());
|
|
||||||
|
|
||||||
const QString GetSaveFileName(const QString &title,
|
const QString GetSaveFileName(const QString& title, const QString& dir, const QString& filter,
|
||||||
const QString &dir,
|
QString* selectedFilter = nullptr);
|
||||||
const QString &filter,
|
|
||||||
QString *selectedFilter = nullptr,
|
|
||||||
Options options = Options());
|
|
||||||
|
|
||||||
const QString GetExistingDirectory(const QString &caption = QString(),
|
const QString GetExistingDirectory(const QString& caption = QString(),
|
||||||
const QString &dir = QString(),
|
const QString& dir = QString());
|
||||||
Options options = Option::ShowDirsOnly);
|
|
||||||
|
|
||||||
int Choice(const QString& title = QString(), const QString& caption = QString(),
|
int Choice(const QString& title = QString(), const QString& caption = QString(),
|
||||||
const QStringList& options = {});
|
const QStringList& options = {});
|
||||||
|
|
|
||||||
17
src/qt_common/abstract/progress.cpp
Normal file
17
src/qt_common/abstract/progress.cpp
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "progress.h"
|
||||||
|
|
||||||
|
namespace QtCommon::Frontend {
|
||||||
|
|
||||||
|
QtProgressDialog::QtProgressDialog(const QString&,
|
||||||
|
const QString&,
|
||||||
|
int,
|
||||||
|
int,
|
||||||
|
QObject* parent,
|
||||||
|
Qt::WindowFlags)
|
||||||
|
: QObject(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
}
|
||||||
45
src/qt_common/abstract/progress.h
Normal file
45
src/qt_common/abstract/progress.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
namespace QtCommon::Frontend {
|
||||||
|
|
||||||
|
class QtProgressDialog : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QtProgressDialog(const QString& labelText, const QString& cancelButtonText, int minimum,
|
||||||
|
int maximum, QObject* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
|
||||||
|
virtual ~QtProgressDialog() = default;
|
||||||
|
|
||||||
|
virtual bool wasCanceled() const = 0;
|
||||||
|
virtual void setWindowModality(Qt::WindowModality modality) = 0;
|
||||||
|
virtual void setMinimumDuration(int durationMs) = 0;
|
||||||
|
virtual void setAutoClose(bool autoClose) = 0;
|
||||||
|
virtual void setAutoReset(bool autoReset) = 0;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void setTitle(QString title) = 0;
|
||||||
|
virtual void setLabelText(QString text) = 0;
|
||||||
|
virtual void setMinimum(int min) = 0;
|
||||||
|
virtual void setMaximum(int max) = 0;
|
||||||
|
virtual void setValue(int value) = 0;
|
||||||
|
|
||||||
|
virtual bool close() = 0;
|
||||||
|
virtual void show() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<QtProgressDialog> newProgressDialog(const QString& labelText,
|
||||||
|
const QString& cancelButtonText, int minimum,
|
||||||
|
int maximum,
|
||||||
|
Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
|
||||||
|
QtProgressDialog* newProgressDialogPtr(const QString& labelText, const QString& cancelButtonText,
|
||||||
|
int minimum, int maximum,
|
||||||
|
Qt::WindowFlags f = Qt::WindowFlags());
|
||||||
|
|
||||||
|
} // namespace QtCommon::Frontend
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#include "qt_progress_dialog.h"
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
#ifndef QT_PROGRESS_DIALOG_H
|
|
||||||
#define QT_PROGRESS_DIALOG_H
|
|
||||||
|
|
||||||
#include <QWindow>
|
|
||||||
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
#include <QProgressDialog>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace QtCommon::Frontend {
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
|
|
||||||
using QtProgressDialog = QProgressDialog;
|
|
||||||
|
|
||||||
// TODO(crueter): QML impl
|
|
||||||
#else
|
|
||||||
class QtProgressDialog
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QtProgressDialog(const QString &labelText,
|
|
||||||
const QString &cancelButtonText,
|
|
||||||
int minimum,
|
|
||||||
int maximum,
|
|
||||||
QObject *parent = nullptr,
|
|
||||||
Qt::WindowFlags f = Qt::WindowFlags());
|
|
||||||
|
|
||||||
bool wasCanceled() const;
|
|
||||||
void setWindowModality(Qt::WindowModality modality);
|
|
||||||
void setMinimumDuration(int durationMs);
|
|
||||||
void setAutoClose(bool autoClose);
|
|
||||||
void setAutoReset(bool autoReset);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void setLabelText(QString &text);
|
|
||||||
void setRange(int min, int max);
|
|
||||||
void setValue(int progress);
|
|
||||||
bool close();
|
|
||||||
|
|
||||||
void show();
|
|
||||||
};
|
|
||||||
#endif // YUZU_QT_WIDGETS
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif // QT_PROGRESS_DIALOG_H
|
|
||||||
|
|
@ -319,7 +319,7 @@ void QtConfig::ReadUIGamelistValues() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtConfig::ReadUILayoutValues() {
|
void QtConfig::ReadUILayoutValues() {
|
||||||
BeginGroup(Settings::TranslateCategory(Settings::Category::UiGameList));
|
BeginGroup(Settings::TranslateCategory(Settings::Category::UiLayout));
|
||||||
|
|
||||||
ReadCategory(Settings::Category::UiLayout);
|
ReadCategory(Settings::Category::UiLayout);
|
||||||
|
|
||||||
|
|
@ -578,10 +578,10 @@ void QtConfig::SaveMultiplayerValues() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Settings::BasicSetting*>& QtConfig::FindRelevantList(Settings::Category category) {
|
std::vector<Settings::BasicSetting*>& QtConfig::FindRelevantList(Settings::Category category) {
|
||||||
auto& map = Settings::values.linkage.by_category;
|
auto& list = Settings::values.linkage.by_category[category];
|
||||||
if (map.contains(category)) {
|
if (!list.empty())
|
||||||
return Settings::values.linkage.by_category[category];
|
return list;
|
||||||
}
|
|
||||||
return UISettings::values.linkage.by_category[category];
|
return UISettings::values.linkage.by_category[category];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 Torzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 Torzu Emulator Project
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2018 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2018 Citra Emulator Project
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "gui_settings.h"
|
#include "gui_settings.h"
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,14 @@
|
||||||
|
|
||||||
#include "qt_common.h"
|
#include "qt_common.h"
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
#include "common/fs/ryujinx_compat.h"
|
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QStringLiteral>
|
#include <QStringLiteral>
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
#include "qt_common/abstract/frontend.h"
|
|
||||||
#include "qt_common/qt_string_lookup.h"
|
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
||||||
#include <QMessageBox>
|
|
||||||
|
|
||||||
#include <JlCompress.h>
|
#include <JlCompress.h>
|
||||||
|
|
||||||
#if !defined(WIN32) && !defined(__APPLE__)
|
#if !defined(WIN32) && !defined(__APPLE__)
|
||||||
|
|
@ -27,11 +22,7 @@
|
||||||
|
|
||||||
namespace QtCommon {
|
namespace QtCommon {
|
||||||
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
QWidget* rootObject = nullptr;
|
QWidget* rootObject = nullptr;
|
||||||
#else
|
|
||||||
QObject* rootObject = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::unique_ptr<Core::System> system = nullptr;
|
std::unique_ptr<Core::System> system = nullptr;
|
||||||
std::shared_ptr<FileSys::RealVfsFilesystem> vfs = nullptr;
|
std::shared_ptr<FileSys::RealVfsFilesystem> vfs = nullptr;
|
||||||
|
|
@ -118,11 +109,7 @@ const QString tr(const std::string& str)
|
||||||
return QGuiApplication::tr(str.c_str());
|
return QGuiApplication::tr(str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
void Init(QWidget* root)
|
void Init(QWidget* root)
|
||||||
#else
|
|
||||||
void Init(QObject* root)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
system = std::make_unique<Core::System>();
|
system = std::make_unique<Core::System>();
|
||||||
rootObject = root;
|
rootObject = root;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#ifndef QT_COMMON_H
|
#ifndef QT_COMMON_H
|
||||||
|
|
@ -14,11 +14,7 @@
|
||||||
|
|
||||||
namespace QtCommon {
|
namespace QtCommon {
|
||||||
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
extern QWidget *rootObject;
|
extern QWidget *rootObject;
|
||||||
#else
|
|
||||||
extern QObject *rootObject;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern std::unique_ptr<Core::System> system;
|
extern std::unique_ptr<Core::System> system;
|
||||||
extern std::shared_ptr<FileSys::RealVfsFilesystem> vfs;
|
extern std::shared_ptr<FileSys::RealVfsFilesystem> vfs;
|
||||||
|
|
@ -30,11 +26,7 @@ Core::Frontend::WindowSystemType GetWindowSystemType();
|
||||||
|
|
||||||
Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow *window);
|
Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow *window);
|
||||||
|
|
||||||
#ifdef YUZU_QT_WIDGETS
|
|
||||||
void Init(QWidget *root);
|
void Init(QWidget *root);
|
||||||
#else
|
|
||||||
void Init(QObject *root);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const QString tr(const char *str);
|
const QString tr(const char *str);
|
||||||
const QString tr(const std::string &str);
|
const QString tr(const std::string &str);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#ifndef QT_APPLET_UTIL_H
|
#ifndef QT_APPLET_UTIL_H
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include "compress.h"
|
#include "compress.h"
|
||||||
#include "qt_common/abstract/frontend.h"
|
#include "qt_common/abstract/frontend.h"
|
||||||
#include "qt_common/abstract/qt_progress_dialog.h"
|
#include "qt_common/abstract/progress.h"
|
||||||
#include "qt_common/qt_common.h"
|
#include "qt_common/qt_common.h"
|
||||||
|
|
||||||
#include <QFuture>
|
#include <QFuture>
|
||||||
|
|
@ -22,20 +22,18 @@
|
||||||
|
|
||||||
namespace QtCommon::Content {
|
namespace QtCommon::Content {
|
||||||
|
|
||||||
bool CheckGameFirmware(u64 program_id, QObject* parent)
|
bool CheckGameFirmware(u64 program_id)
|
||||||
{
|
{
|
||||||
if (FirmwareManager::GameRequiresFirmware(program_id)
|
if (FirmwareManager::GameRequiresFirmware(program_id)
|
||||||
&& !FirmwareManager::CheckFirmwarePresence(*system)) {
|
&& !FirmwareManager::CheckFirmwarePresence(*system)) {
|
||||||
auto result = QtCommon::Frontend::ShowMessage(
|
auto result = QtCommon::Frontend::Warning(
|
||||||
QMessageBox::Warning,
|
|
||||||
tr("Game Requires Firmware"),
|
tr("Game Requires Firmware"),
|
||||||
tr("The game you are trying to launch requires firmware to boot or to get past the "
|
tr("The game you are trying to launch requires firmware to boot or to get past the "
|
||||||
"opening menu. Please <a href='https://yuzu-mirror.github.io/help/quickstart'>"
|
"opening menu. Please <a href='https://yuzu-mirror.github.io/help/quickstart'>"
|
||||||
"dump and install firmware</a>, or press \"OK\" to launch anyways."),
|
"dump and install firmware</a>, or press \"OK\" to launch anyways."),
|
||||||
QMessageBox::Ok | QMessageBox::Cancel,
|
QtCommon::Frontend::Ok | QtCommon::Frontend::Cancel);
|
||||||
parent);
|
|
||||||
|
|
||||||
return result == QMessageBox::Ok;
|
return result == QtCommon::Frontend::Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -43,26 +41,23 @@ bool CheckGameFirmware(u64 program_id, QObject* parent)
|
||||||
|
|
||||||
void InstallFirmware(const QString& location, bool recursive)
|
void InstallFirmware(const QString& location, bool recursive)
|
||||||
{
|
{
|
||||||
QtCommon::Frontend::QtProgressDialog progress(tr("Installing Firmware..."),
|
// Initialize a progress dialog.
|
||||||
tr("Cancel"),
|
auto progress = QtCommon::Frontend::newProgressDialog(tr("Installing Firmware..."),
|
||||||
0,
|
tr("Cancel"), 0, 100);
|
||||||
100,
|
progress->show();
|
||||||
rootObject);
|
|
||||||
progress.setWindowModality(Qt::WindowModal);
|
QGuiApplication::processEvents();
|
||||||
progress.setMinimumDuration(100);
|
|
||||||
progress.setAutoClose(false);
|
|
||||||
progress.setAutoReset(false);
|
|
||||||
progress.show();
|
|
||||||
|
|
||||||
// Declare progress callback.
|
// Declare progress callback.
|
||||||
auto callback = [&](size_t total_size, size_t processed_size) {
|
auto callback = [&](size_t total_size, size_t processed_size) {
|
||||||
progress.setValue(static_cast<int>((processed_size * 100) / total_size));
|
QGuiApplication::processEvents();
|
||||||
return progress.wasCanceled();
|
progress->setValue(static_cast<int>((processed_size * 100) / total_size));
|
||||||
|
return progress->wasCanceled();
|
||||||
};
|
};
|
||||||
|
|
||||||
QString failedTitle = tr("Firmware Install Failed");
|
QString failedTitle = tr("Firmware Install Failed");
|
||||||
QString successTitle = tr("Firmware Install Succeeded");
|
QString successTitle = tr("Firmware Install Succeeded");
|
||||||
QMessageBox::Icon icon;
|
QtCommon::Frontend::Icon icon;
|
||||||
FirmwareInstallResult result;
|
FirmwareInstallResult result;
|
||||||
|
|
||||||
const auto ShowMessage = [&]() {
|
const auto ShowMessage = [&]() {
|
||||||
|
|
@ -104,7 +99,7 @@ void InstallFirmware(const QString& location, bool recursive)
|
||||||
|
|
||||||
if (out.size() <= 0) {
|
if (out.size() <= 0) {
|
||||||
result = FirmwareInstallResult::NoNCAs;
|
result = FirmwareInstallResult::NoNCAs;
|
||||||
icon = QMessageBox::Warning;
|
icon = QtCommon::Frontend::Icon::Warning;
|
||||||
ShowMessage();
|
ShowMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +109,7 @@ void InstallFirmware(const QString& location, bool recursive)
|
||||||
if (sysnand_content_vdir->IsWritable()
|
if (sysnand_content_vdir->IsWritable()
|
||||||
&& !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) {
|
&& !sysnand_content_vdir->CleanSubdirectoryRecursive("registered")) {
|
||||||
result = FirmwareInstallResult::FailedDelete;
|
result = FirmwareInstallResult::FailedDelete;
|
||||||
icon = QMessageBox::Critical;
|
icon = QtCommon::Frontend::Icon::Critical;
|
||||||
ShowMessage();
|
ShowMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +140,7 @@ void InstallFirmware(const QString& location, bool recursive)
|
||||||
|
|
||||||
if (callback(100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) {
|
if (callback(100, 20 + static_cast<int>(((i) / static_cast<float>(out.size())) * 70.0))) {
|
||||||
result = FirmwareInstallResult::FailedCorrupted;
|
result = FirmwareInstallResult::FailedCorrupted;
|
||||||
icon = QMessageBox::Warning;
|
icon = QtCommon::Frontend::Icon::Warning;
|
||||||
ShowMessage();
|
ShowMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +148,7 @@ void InstallFirmware(const QString& location, bool recursive)
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
result = FirmwareInstallResult::FailedCopy;
|
result = FirmwareInstallResult::FailedCopy;
|
||||||
icon = QMessageBox::Critical;
|
icon = QtCommon::Frontend::Icon::Critical;
|
||||||
ShowMessage();
|
ShowMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -162,8 +157,9 @@ void InstallFirmware(const QString& location, bool recursive)
|
||||||
system->GetFileSystemController().CreateFactories(*vfs);
|
system->GetFileSystemController().CreateFactories(*vfs);
|
||||||
|
|
||||||
auto VerifyFirmwareCallback = [&](size_t total_size, size_t processed_size) {
|
auto VerifyFirmwareCallback = [&](size_t total_size, size_t processed_size) {
|
||||||
progress.setValue(90 + static_cast<int>((processed_size * 10) / total_size));
|
QGuiApplication::processEvents();
|
||||||
return progress.wasCanceled();
|
progress->setValue(90 + static_cast<int>((processed_size * 10) / total_size));
|
||||||
|
return progress->wasCanceled();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto results = ContentManager::VerifyInstalledContents(*QtCommon::system,
|
auto results = ContentManager::VerifyInstalledContents(*QtCommon::system,
|
||||||
|
|
@ -174,14 +170,15 @@ void InstallFirmware(const QString& location, bool recursive)
|
||||||
if (results.size() > 0) {
|
if (results.size() > 0) {
|
||||||
const auto failed_names = QString::fromStdString(
|
const auto failed_names = QString::fromStdString(
|
||||||
fmt::format("{}", fmt::join(results, "\n")));
|
fmt::format("{}", fmt::join(results, "\n")));
|
||||||
progress.close();
|
progress->close();
|
||||||
QtCommon::Frontend::Critical(
|
QtCommon::Frontend::Critical(
|
||||||
tr("Firmware integrity verification failed!"),
|
tr("Firmware integrity verification failed!"),
|
||||||
tr("Verification failed for the following files:\n\n%1").arg(failed_names));
|
tr("Verification failed for the following files:\n\n%1").arg(failed_names));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.close();
|
progress->close();
|
||||||
|
QGuiApplication::processEvents();
|
||||||
|
|
||||||
const auto pair = FirmwareManager::GetFirmwareVersion(*system);
|
const auto pair = FirmwareManager::GetFirmwareVersion(*system);
|
||||||
const auto firmware_data = pair.first;
|
const auto firmware_data = pair.first;
|
||||||
|
|
@ -221,19 +218,16 @@ QString UnzipFirmwareToTmp(const QString& location)
|
||||||
// Content //
|
// Content //
|
||||||
void VerifyGameContents(const std::string& game_path)
|
void VerifyGameContents(const std::string& game_path)
|
||||||
{
|
{
|
||||||
QtCommon::Frontend::QtProgressDialog progress(tr("Verifying integrity..."),
|
auto progress =
|
||||||
tr("Cancel"),
|
QtCommon::Frontend::newProgressDialog(tr("Verifying integrity..."), tr("Cancel"), 0, 100);
|
||||||
0,
|
progress->show();
|
||||||
100,
|
|
||||||
rootObject);
|
QGuiApplication::processEvents();
|
||||||
progress.setWindowModality(Qt::WindowModal);
|
|
||||||
progress.setMinimumDuration(100);
|
|
||||||
progress.setAutoClose(false);
|
|
||||||
progress.setAutoReset(false);
|
|
||||||
|
|
||||||
const auto callback = [&](size_t total_size, size_t processed_size) {
|
const auto callback = [&](size_t total_size, size_t processed_size) {
|
||||||
progress.setValue(static_cast<int>((processed_size * 100) / total_size));
|
QGuiApplication::processEvents();
|
||||||
return progress.wasCanceled();
|
progress->setValue(static_cast<int>((processed_size * 100) / total_size));
|
||||||
|
return progress->wasCanceled();
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto result = ContentManager::VerifyGameContents(*system, game_path, callback);
|
const auto result = ContentManager::VerifyGameContents(*system, game_path, callback);
|
||||||
|
|
@ -260,12 +254,8 @@ void VerifyGameContents(const std::string& game_path)
|
||||||
|
|
||||||
void InstallKeys()
|
void InstallKeys()
|
||||||
{
|
{
|
||||||
const QString key_source_location
|
const QString key_source_location = QtCommon::Frontend::GetOpenFileName(
|
||||||
= QtCommon::Frontend::GetOpenFileName(tr("Select Dumped Keys Location"),
|
tr("Select Dumped Keys Location"), {}, QStringLiteral("Decryption Keys (*.keys)"), {});
|
||||||
{},
|
|
||||||
QStringLiteral("Decryption Keys (*.keys)"),
|
|
||||||
{},
|
|
||||||
QtCommon::Frontend::Option::ReadOnly);
|
|
||||||
|
|
||||||
if (key_source_location.isEmpty())
|
if (key_source_location.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
@ -289,27 +279,22 @@ void InstallKeys()
|
||||||
void VerifyInstalledContents()
|
void VerifyInstalledContents()
|
||||||
{
|
{
|
||||||
// Initialize a progress dialog.
|
// Initialize a progress dialog.
|
||||||
QtCommon::Frontend::QtProgressDialog progress(tr("Verifying integrity..."),
|
auto progress = QtCommon::Frontend::newProgressDialog(tr("Verifying integrity..."),
|
||||||
tr("Cancel"),
|
tr("Cancel"), 0, 100);
|
||||||
0,
|
progress->show();
|
||||||
100,
|
|
||||||
rootObject);
|
QGuiApplication::processEvents();
|
||||||
progress.setWindowModality(Qt::WindowModal);
|
|
||||||
progress.setMinimumDuration(100);
|
|
||||||
progress.setAutoClose(false);
|
|
||||||
progress.setAutoReset(false);
|
|
||||||
|
|
||||||
// Declare progress callback.
|
// Declare progress callback.
|
||||||
auto QtProgressCallback = [&](size_t total_size, size_t processed_size) {
|
auto QtProgressCallback = [&](size_t total_size, size_t processed_size) {
|
||||||
progress.setValue(static_cast<int>((processed_size * 100) / total_size));
|
QGuiApplication::processEvents();
|
||||||
return progress.wasCanceled();
|
progress->setValue(static_cast<int>((processed_size * 100) / total_size));
|
||||||
};
|
return progress->wasCanceled(); };
|
||||||
|
|
||||||
const std::vector<std::string> result
|
const std::vector<std::string> result = ContentManager::VerifyInstalledContents(
|
||||||
= ContentManager::VerifyInstalledContents(*QtCommon::system,
|
*QtCommon::system, *QtCommon::provider, QtProgressCallback);
|
||||||
*QtCommon::provider,
|
|
||||||
QtProgressCallback);
|
progress->close();
|
||||||
progress.close();
|
|
||||||
|
|
||||||
if (result.empty()) {
|
if (result.empty()) {
|
||||||
QtCommon::Frontend::Information(tr("Integrity verification succeeded!"),
|
QtCommon::Frontend::Information(tr("Integrity verification succeeded!"),
|
||||||
|
|
@ -374,28 +359,29 @@ void FixProfiles()
|
||||||
|
|
||||||
void ClearDataDir(FrontendCommon::DataManager::DataDir dir, const std::string& user_id)
|
void ClearDataDir(FrontendCommon::DataManager::DataDir dir, const std::string& user_id)
|
||||||
{
|
{
|
||||||
auto result = QtCommon::Frontend::Warning(tr("Really clear data?"),
|
using namespace QtCommon::Frontend;
|
||||||
|
auto result = Warning(tr("Really clear data?"),
|
||||||
tr("Important data may be lost!"),
|
tr("Important data may be lost!"),
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
Yes | No);
|
||||||
|
|
||||||
if (result != QMessageBox::Yes)
|
if (result != Yes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
result = QtCommon::Frontend::Warning(
|
result = Warning(
|
||||||
tr("Are you REALLY sure?"),
|
tr("Are you REALLY sure?"),
|
||||||
tr("Once deleted, your data will NOT come back!\n"
|
tr("Once deleted, your data will NOT come back!\n"
|
||||||
"Only do this if you're 100% sure you want to delete this data."),
|
"Only do this if you're 100% sure you want to delete this data."),
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
Yes | No);
|
||||||
|
|
||||||
if (result != QMessageBox::Yes)
|
if (result != Yes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QtCommon::Frontend::QtProgressDialog dialog(tr("Clearing..."), QString(), 0, 0);
|
auto dialog = newProgressDialog(tr("Clearing..."), QString(), 0, 0);
|
||||||
dialog.show();
|
dialog->show();
|
||||||
|
|
||||||
FrontendCommon::DataManager::ClearDir(dir, user_id);
|
FrontendCommon::DataManager::ClearDir(dir, user_id);
|
||||||
|
|
||||||
dialog.close();
|
dialog->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir,
|
void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir,
|
||||||
|
|
@ -413,18 +399,12 @@ void ExportDataDir(FrontendCommon::DataManager::DataDir data_dir,
|
||||||
if (zip_dump_location.isEmpty())
|
if (zip_dump_location.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QtProgressDialog* progress = new QtProgressDialog(
|
auto progress = QtCommon::Frontend::newProgressDialogPtr(
|
||||||
tr("Exporting data. This may take a while..."), tr("Cancel"), 0, 100, rootObject);
|
tr("Exporting data. This may take a while..."), tr("Cancel"), 0, 100);
|
||||||
|
|
||||||
progress->setWindowTitle(tr("Exporting"));
|
progress->setTitle(tr("Exporting"));
|
||||||
progress->setWindowModality(Qt::WindowModal);
|
|
||||||
progress->setMinimumDuration(100);
|
|
||||||
progress->setAutoClose(false);
|
|
||||||
progress->setAutoReset(false);
|
|
||||||
progress->show();
|
progress->show();
|
||||||
|
|
||||||
QGuiApplication::processEvents();
|
|
||||||
|
|
||||||
auto progress_callback = [=](size_t total_size, size_t processed_size) {
|
auto progress_callback = [=](size_t total_size, size_t processed_size) {
|
||||||
QMetaObject::invokeMethod(progress,
|
QMetaObject::invokeMethod(progress,
|
||||||
"setValue",
|
"setValue",
|
||||||
|
|
@ -485,21 +465,14 @@ void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir,
|
||||||
"proceed?"),
|
"proceed?"),
|
||||||
StandardButton::Yes | StandardButton::No);
|
StandardButton::Yes | StandardButton::No);
|
||||||
|
|
||||||
if (button != QMessageBox::Yes)
|
if (button != QtCommon::Frontend::Yes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QtProgressDialog* progress = new QtProgressDialog(
|
QtProgressDialog* progress = newProgressDialogPtr(
|
||||||
tr("Importing data. This may take a while..."), tr("Cancel"), 0, 100, rootObject);
|
tr("Importing data. This may take a while..."), tr("Cancel"), 0, 100);
|
||||||
|
|
||||||
progress->setWindowTitle(tr("Importing"));
|
progress->setTitle(tr("Importing"));
|
||||||
progress->setWindowModality(Qt::WindowModal);
|
|
||||||
progress->setMinimumDuration(100);
|
|
||||||
progress->setAutoClose(false);
|
|
||||||
progress->setAutoReset(false);
|
|
||||||
progress->show();
|
progress->show();
|
||||||
progress->setValue(0);
|
|
||||||
|
|
||||||
QGuiApplication::processEvents();
|
|
||||||
|
|
||||||
// to prevent GUI mangling we have to run this in a thread as well
|
// to prevent GUI mangling we have to run this in a thread as well
|
||||||
QFuture<bool> delete_future = QtConcurrent::run([=]() {
|
QFuture<bool> delete_future = QtConcurrent::run([=]() {
|
||||||
|
|
@ -553,4 +526,5 @@ void ImportDataDir(FrontendCommon::DataManager::DataDir data_dir,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(crueter): Port InstallFirmware et al. from QML Branch
|
||||||
} // namespace QtCommon::Content
|
} // namespace QtCommon::Content
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#ifndef QT_CONTENT_UTIL_H
|
#ifndef QT_CONTENT_UTIL_H
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
namespace QtCommon::Content {
|
namespace QtCommon::Content {
|
||||||
|
|
||||||
//
|
//
|
||||||
bool CheckGameFirmware(u64 program_id, QObject *parent);
|
bool CheckGameFirmware(u64 program_id);
|
||||||
|
|
||||||
enum class FirmwareInstallResult {
|
enum class FirmwareInstallResult {
|
||||||
Success,
|
Success,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
|
||||||
|
|
@ -403,29 +403,29 @@ void ResetMetadata(bool show_message) {
|
||||||
inline constexpr bool CreateShortcutMessagesGUI(ShortcutMessages imsg, const QString& game_title)
|
inline constexpr bool CreateShortcutMessagesGUI(ShortcutMessages imsg, const QString& game_title)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
QMessageBox::StandardButtons buttons;
|
using namespace QtCommon::Frontend;
|
||||||
|
int buttons;
|
||||||
|
|
||||||
switch (imsg) {
|
switch (imsg) {
|
||||||
case ShortcutMessages::Fullscreen:
|
case ShortcutMessages::Fullscreen:
|
||||||
buttons = QMessageBox::Yes | QMessageBox::No;
|
buttons = Yes | No;
|
||||||
result
|
result = QtCommon::Frontend::Information(
|
||||||
= QtCommon::Frontend::Information(tr("Create Shortcut"),
|
tr("Create Shortcut"), tr("Do you want to launch the game in fullscreen?"), buttons);
|
||||||
tr("Do you want to launch the game in fullscreen?"),
|
return result == Yes;
|
||||||
buttons);
|
|
||||||
return result == QMessageBox::Yes;
|
|
||||||
case ShortcutMessages::Success:
|
case ShortcutMessages::Success:
|
||||||
QtCommon::Frontend::Information(tr("Shortcut Created"),
|
QtCommon::Frontend::Information(
|
||||||
tr("Successfully created a shortcut to %1").arg(game_title));
|
tr("Shortcut Created"), tr("Successfully created a shortcut to %1").arg(game_title));
|
||||||
return false;
|
return false;
|
||||||
case ShortcutMessages::Volatile:
|
case ShortcutMessages::Volatile:
|
||||||
buttons = QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel;
|
buttons = Ok | Cancel;
|
||||||
result = QtCommon::Frontend::Warning(
|
result = QtCommon::Frontend::Warning(
|
||||||
tr("Shortcut may be Volatile!"),
|
tr("Shortcut may be Volatile!"),
|
||||||
tr("This will create a shortcut to the current AppImage. This may "
|
tr("This will create a shortcut to the current AppImage. This may "
|
||||||
"not work well if you update. Continue?"),
|
"not work well if you update. Continue?"),
|
||||||
buttons);
|
buttons);
|
||||||
return result == QMessageBox::Ok;
|
return result == Ok;
|
||||||
default:
|
default:
|
||||||
buttons = QMessageBox::Ok;
|
buttons = Ok;
|
||||||
QtCommon::Frontend::Critical(tr("Failed to Create Shortcut"),
|
QtCommon::Frontend::Critical(tr("Failed to Create Shortcut"),
|
||||||
tr("Failed to create a shortcut to %1").arg(game_title),
|
tr("Failed to create a shortcut to %1").arg(game_title),
|
||||||
buttons);
|
buttons);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#ifndef QT_GAME_UTIL_H
|
#ifndef QT_GAME_UTIL_H
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "qt_common/util/meta.h"
|
#include "qt_common/util/meta.h"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#ifndef QT_META_H
|
#ifndef QT_META_H
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,24 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "qt_common/util/path.h"
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <fmt/format.h>
|
||||||
#include "common/fs/fs.h"
|
#include "common/fs/fs.h"
|
||||||
#include "common/fs/path_util.h"
|
#include "common/fs/path_util.h"
|
||||||
#include "qt_common/abstract/frontend.h"
|
#include "qt_common/abstract/frontend.h"
|
||||||
#include <fmt/format.h>
|
#include "qt_common/util/path.h"
|
||||||
|
|
||||||
namespace QtCommon::Path {
|
namespace QtCommon::Path {
|
||||||
|
|
||||||
bool OpenShaderCache(u64 program_id, QObject *parent)
|
bool OpenShaderCache(u64 program_id, QObject* parent) {
|
||||||
{
|
|
||||||
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
const auto shader_cache_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||||
const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
|
const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
|
||||||
if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
|
if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
|
||||||
QtCommon::Frontend::ShowMessage(QMessageBox::Warning,
|
QtCommon::Frontend::Warning(tr("Error Opening Shader Cache"),
|
||||||
tr("Error Opening Shader Cache"),
|
|
||||||
tr("Failed to create or open shader cache for this title, "
|
tr("Failed to create or open shader cache for this title, "
|
||||||
"ensure your app data directory has write permissions."),
|
"ensure your app data directory has write permissions."));
|
||||||
QMessageBox::Ok,
|
|
||||||
parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)};
|
const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)};
|
||||||
|
|
@ -30,4 +26,4 @@ bool OpenShaderCache(u64 program_id, QObject *parent)
|
||||||
return QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
|
return QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace QtCommon::Path
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#ifndef QT_PATH_UTIL_H
|
#ifndef QT_PATH_UTIL_H
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#include "qt_common/util/rom.h"
|
#include "qt_common/util/rom.h"
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#ifndef QT_ROM_UTIL_H
|
#ifndef QT_ROM_UTIL_H
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ add_executable(yuzu
|
||||||
configuration/addon/mod_select_dialog.h configuration/addon/mod_select_dialog.cpp configuration/addon/mod_select_dialog.ui
|
configuration/addon/mod_select_dialog.h configuration/addon/mod_select_dialog.cpp configuration/addon/mod_select_dialog.ui
|
||||||
|
|
||||||
render/performance_overlay.h render/performance_overlay.cpp render/performance_overlay.ui
|
render/performance_overlay.h render/performance_overlay.cpp render/performance_overlay.ui
|
||||||
|
libqt_common.h libqt_common.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")
|
set_target_properties(yuzu PROPERTIES OUTPUT_NAME "eden")
|
||||||
|
|
|
||||||
119
src/yuzu/libqt_common.cpp
Normal file
119
src/yuzu/libqt_common.cpp
Normal file
|
|
@ -0,0 +1,119 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QProgressDialog>
|
||||||
|
#include <QAbstractButton>
|
||||||
|
|
||||||
|
#include "libqt_common.h"
|
||||||
|
#include "qt_common/abstract/frontend.h"
|
||||||
|
#include "qt_common/abstract/progress.h"
|
||||||
|
#include "qt_common/qt_common.h"
|
||||||
|
|
||||||
|
namespace QtCommon::Frontend {
|
||||||
|
|
||||||
|
StandardButton ShowMessage(
|
||||||
|
Icon icon, const QString &title, const QString &text, StandardButtons buttons, QObject *parent)
|
||||||
|
{
|
||||||
|
QMessageBox *box = new QMessageBox(QMessageBox::Icon(int(icon)), title, text, QMessageBox::StandardButtons(int(buttons)), (QWidget *) parent);
|
||||||
|
return StandardButton(box->exec());
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetsProgressDialog::WidgetsProgressDialog(const QString& labelText,
|
||||||
|
const QString& cancelButtonText, int minimum,
|
||||||
|
int maximum, QWidget* parent, Qt::WindowFlags f)
|
||||||
|
: QtProgressDialog(labelText, cancelButtonText, minimum, maximum, parent, f),
|
||||||
|
m_dialog(new QProgressDialog(labelText, cancelButtonText, minimum, maximum, parent, f)) {
|
||||||
|
m_dialog->setAutoClose(false);
|
||||||
|
m_dialog->setAutoReset(false);
|
||||||
|
m_dialog->setMinimumDuration(100);
|
||||||
|
m_dialog->setWindowModality(Qt::WindowModal);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WidgetsProgressDialog::wasCanceled() const {
|
||||||
|
return m_dialog->wasCanceled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setWindowModality(Qt::WindowModality modality) {
|
||||||
|
m_dialog->setWindowModality(modality);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setMinimumDuration(int durationMs) {
|
||||||
|
m_dialog->setMinimumDuration(durationMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setAutoClose(bool autoClose) {
|
||||||
|
m_dialog->setAutoClose(autoClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setAutoReset(bool autoReset) {
|
||||||
|
m_dialog->setAutoReset(autoReset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setTitle(QString title) {
|
||||||
|
m_dialog->setWindowTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setLabelText(QString text) {
|
||||||
|
m_dialog->setLabelText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setMinimum(int min) {
|
||||||
|
m_dialog->setMinimum(min);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setMaximum(int max) {
|
||||||
|
m_dialog->setMaximum(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::setValue(int value) {
|
||||||
|
m_dialog->setValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WidgetsProgressDialog::close() {
|
||||||
|
m_dialog->close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WidgetsProgressDialog::show() {
|
||||||
|
m_dialog->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<QtProgressDialog> newProgressDialog(const QString& labelText, const QString& cancelButtonText,
|
||||||
|
int minimum, int maximum, Qt::WindowFlags f) {
|
||||||
|
return std::make_unique<WidgetsProgressDialog>(labelText, cancelButtonText, minimum, maximum,
|
||||||
|
(QWidget*)rootObject, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
QtProgressDialog* newProgressDialogPtr(const QString& labelText, const QString& cancelButtonText,
|
||||||
|
int minimum, int maximum,
|
||||||
|
Qt::WindowFlags f) {
|
||||||
|
return new WidgetsProgressDialog(labelText, cancelButtonText, minimum, maximum,
|
||||||
|
(QWidget*)rootObject, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Choice(const QString& title, const QString& caption, const QStringList& options) {
|
||||||
|
QMessageBox box(rootObject);
|
||||||
|
box.setText(caption);
|
||||||
|
box.setWindowTitle(title);
|
||||||
|
|
||||||
|
for (const QString& opt : options) {
|
||||||
|
box.addButton(opt, QMessageBox::AcceptRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
box.addButton(QMessageBox::Cancel);
|
||||||
|
|
||||||
|
box.exec();
|
||||||
|
auto button = box.clickedButton();
|
||||||
|
return options.indexOf(button->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString GetTextInput(const QString& title, const QString& caption,
|
||||||
|
const QString& defaultText) {
|
||||||
|
return QInputDialog::getText(rootObject, title, caption, QLineEdit::Normal, defaultText);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace QtCommon::Frontend
|
||||||
37
src/yuzu/libqt_common.h
Normal file
37
src/yuzu/libqt_common.h
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "qt_common/abstract/progress.h"
|
||||||
|
|
||||||
|
#include <QProgressDialog>
|
||||||
|
|
||||||
|
namespace QtCommon::Frontend {
|
||||||
|
|
||||||
|
class WidgetsProgressDialog : public QtProgressDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WidgetsProgressDialog(const QString& labelText, const QString& cancelButtonText, int minimum,
|
||||||
|
int maximum, QWidget* parent = nullptr, Qt::WindowFlags f = {});
|
||||||
|
|
||||||
|
bool wasCanceled() const override;
|
||||||
|
void setWindowModality(Qt::WindowModality modality) override;
|
||||||
|
void setMinimumDuration(int durationMs) override;
|
||||||
|
void setAutoClose(bool autoClose) override;
|
||||||
|
void setAutoReset(bool autoReset) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setTitle(QString title) override;
|
||||||
|
void setLabelText(QString text) override;
|
||||||
|
void setMinimum(int min) override;
|
||||||
|
void setMaximum(int max) override;
|
||||||
|
void setValue(int value) override;
|
||||||
|
bool close() override;
|
||||||
|
void show() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QProgressDialog* m_dialog;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1929,9 +1929,8 @@ bool MainWindow::LoadROM(const QString& filename, Service::AM::FrontendAppletPar
|
||||||
|
|
||||||
/** firmware check */
|
/** firmware check */
|
||||||
|
|
||||||
if (!QtCommon::Content::CheckGameFirmware(params.program_id, this)) {
|
if (!QtCommon::Content::CheckGameFirmware(params.program_id))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/** Exec */
|
/** Exec */
|
||||||
const Core::SystemResultStatus result{
|
const Core::SystemResultStatus result{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
exec find src -iname "*.h" -o -iname "*.cpp" | xargs clang-format -i -style=file:src/.clang-format
|
# Only clang-formats Qt stuff. :)
|
||||||
|
find src/qt_common src/yuzu -iname "*.h" -o -iname "*.cpp" | xargs clang-format -i -style=file:src/.clang-format
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue