mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-18 17:34:52 +00:00
Multiple Install Folders (#1308)
* multiple install folders implimentation * clang format * paths setting tab * clang format
This commit is contained in:
parent
c9f894c45a
commit
56e8ed7833
11 changed files with 278 additions and 21 deletions
|
@ -693,6 +693,8 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||||
src/qt_gui/game_grid_frame.h
|
src/qt_gui/game_grid_frame.h
|
||||||
src/qt_gui/game_install_dialog.cpp
|
src/qt_gui/game_install_dialog.cpp
|
||||||
src/qt_gui/game_install_dialog.h
|
src/qt_gui/game_install_dialog.h
|
||||||
|
src/qt_gui/install_dir_select.cpp
|
||||||
|
src/qt_gui/install_dir_select.h
|
||||||
src/qt_gui/pkg_viewer.cpp
|
src/qt_gui/pkg_viewer.cpp
|
||||||
src/qt_gui/pkg_viewer.h
|
src/qt_gui/pkg_viewer.h
|
||||||
src/qt_gui/trophy_viewer.cpp
|
src/qt_gui/trophy_viewer.cpp
|
||||||
|
|
|
@ -62,7 +62,7 @@ static s16 cursorState = HideCursorState::Idle;
|
||||||
static int cursorHideTimeout = 5; // 5 seconds (default)
|
static int cursorHideTimeout = 5; // 5 seconds (default)
|
||||||
|
|
||||||
// Gui
|
// Gui
|
||||||
std::filesystem::path settings_install_dir = {};
|
std::vector<std::filesystem::path> settings_install_dirs = {};
|
||||||
std::filesystem::path settings_addon_install_dir = {};
|
std::filesystem::path settings_addon_install_dir = {};
|
||||||
u32 main_window_geometry_x = 400;
|
u32 main_window_geometry_x = 400;
|
||||||
u32 main_window_geometry_y = 400;
|
u32 main_window_geometry_y = 400;
|
||||||
|
@ -325,8 +325,9 @@ void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) {
|
||||||
main_window_geometry_w = w;
|
main_window_geometry_w = w;
|
||||||
main_window_geometry_h = h;
|
main_window_geometry_h = h;
|
||||||
}
|
}
|
||||||
void setGameInstallDir(const std::filesystem::path& dir) {
|
void setGameInstallDirs(const std::vector<std::filesystem::path>& dir) {
|
||||||
settings_install_dir = dir;
|
settings_install_dirs.resize(dir.size());
|
||||||
|
settings_install_dirs = dir;
|
||||||
}
|
}
|
||||||
void setAddonInstallDir(const std::filesystem::path& dir) {
|
void setAddonInstallDir(const std::filesystem::path& dir) {
|
||||||
settings_addon_install_dir = dir;
|
settings_addon_install_dir = dir;
|
||||||
|
@ -384,8 +385,8 @@ u32 getMainWindowGeometryW() {
|
||||||
u32 getMainWindowGeometryH() {
|
u32 getMainWindowGeometryH() {
|
||||||
return main_window_geometry_h;
|
return main_window_geometry_h;
|
||||||
}
|
}
|
||||||
std::filesystem::path getGameInstallDir() {
|
std::vector<std::filesystem::path> getGameInstallDirs() {
|
||||||
return settings_install_dir;
|
return settings_install_dirs;
|
||||||
}
|
}
|
||||||
std::filesystem::path getAddonInstallDir() {
|
std::filesystem::path getAddonInstallDir() {
|
||||||
if (settings_addon_install_dir.empty()) {
|
if (settings_addon_install_dir.empty()) {
|
||||||
|
@ -523,7 +524,19 @@ void load(const std::filesystem::path& path) {
|
||||||
mw_themes = toml::find_or<int>(gui, "theme", 0);
|
mw_themes = toml::find_or<int>(gui, "theme", 0);
|
||||||
m_window_size_W = toml::find_or<int>(gui, "mw_width", 0);
|
m_window_size_W = toml::find_or<int>(gui, "mw_width", 0);
|
||||||
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
||||||
settings_install_dir = toml::find_fs_path_or(gui, "installDir", {});
|
|
||||||
|
auto old_game_install_dir = toml::find_fs_path_or(gui, "installDir", {});
|
||||||
|
if (!old_game_install_dir.empty()) {
|
||||||
|
settings_install_dirs.push_back(old_game_install_dir);
|
||||||
|
data.as_table().erase("installDir");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto install_dir_array =
|
||||||
|
toml::find_or<std::vector<std::string>>(gui, "installDirs", {});
|
||||||
|
for (const auto& dir : install_dir_array) {
|
||||||
|
settings_install_dirs.emplace_back(std::filesystem::path{dir});
|
||||||
|
}
|
||||||
|
|
||||||
settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {});
|
settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {});
|
||||||
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
|
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
|
||||||
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
||||||
|
@ -601,7 +614,13 @@ void save(const std::filesystem::path& path) {
|
||||||
data["GUI"]["gameTableMode"] = m_table_mode;
|
data["GUI"]["gameTableMode"] = m_table_mode;
|
||||||
data["GUI"]["mw_width"] = m_window_size_W;
|
data["GUI"]["mw_width"] = m_window_size_W;
|
||||||
data["GUI"]["mw_height"] = m_window_size_H;
|
data["GUI"]["mw_height"] = m_window_size_H;
|
||||||
data["GUI"]["installDir"] = std::string{fmt::UTF(settings_install_dir.u8string()).data};
|
|
||||||
|
std::vector<std::string> install_dirs;
|
||||||
|
for (const auto& dirString : settings_install_dirs) {
|
||||||
|
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
|
||||||
|
}
|
||||||
|
data["GUI"]["installDirs"] = install_dirs;
|
||||||
|
|
||||||
data["GUI"]["addonInstallDir"] =
|
data["GUI"]["addonInstallDir"] =
|
||||||
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
||||||
data["GUI"]["geometry_x"] = main_window_geometry_x;
|
data["GUI"]["geometry_x"] = main_window_geometry_x;
|
||||||
|
|
|
@ -85,7 +85,7 @@ bool vkCrashDiagnosticEnabled();
|
||||||
|
|
||||||
// Gui
|
// Gui
|
||||||
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);
|
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);
|
||||||
void setGameInstallDir(const std::filesystem::path& dir);
|
void setGameInstallDirs(const std::vector<std::filesystem::path>& dir);
|
||||||
void setAddonInstallDir(const std::filesystem::path& dir);
|
void setAddonInstallDir(const std::filesystem::path& dir);
|
||||||
void setMainWindowTheme(u32 theme);
|
void setMainWindowTheme(u32 theme);
|
||||||
void setIconSize(u32 size);
|
void setIconSize(u32 size);
|
||||||
|
@ -104,7 +104,7 @@ u32 getMainWindowGeometryX();
|
||||||
u32 getMainWindowGeometryY();
|
u32 getMainWindowGeometryY();
|
||||||
u32 getMainWindowGeometryW();
|
u32 getMainWindowGeometryW();
|
||||||
u32 getMainWindowGeometryH();
|
u32 getMainWindowGeometryH();
|
||||||
std::filesystem::path getGameInstallDir();
|
std::vector<std::filesystem::path> getGameInstallDirs();
|
||||||
std::filesystem::path getAddonInstallDir();
|
std::filesystem::path getAddonInstallDir();
|
||||||
u32 getMainWindowTheme();
|
u32 getMainWindowTheme();
|
||||||
u32 getIconSize();
|
u32 getIconSize();
|
||||||
|
|
|
@ -10,14 +10,16 @@ GameInfoClass::GameInfoClass() = default;
|
||||||
GameInfoClass::~GameInfoClass() = default;
|
GameInfoClass::~GameInfoClass() = default;
|
||||||
|
|
||||||
void GameInfoClass::GetGameInfo(QWidget* parent) {
|
void GameInfoClass::GetGameInfo(QWidget* parent) {
|
||||||
QString installDir;
|
|
||||||
Common::FS::PathToQString(installDir, Config::getGameInstallDir());
|
|
||||||
QStringList filePaths;
|
QStringList filePaths;
|
||||||
QDir parentFolder(installDir);
|
for (const auto& installLoc : Config::getGameInstallDirs()) {
|
||||||
QFileInfoList fileList = parentFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
QString installDir;
|
||||||
for (const auto& fileInfo : fileList) {
|
Common::FS::PathToQString(installDir, installLoc);
|
||||||
if (fileInfo.isDir()) {
|
QDir parentFolder(installDir);
|
||||||
filePaths.append(fileInfo.absoluteFilePath());
|
QFileInfoList fileList = parentFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
|
for (const auto& fileInfo : fileList) {
|
||||||
|
if (fileInfo.isDir()) {
|
||||||
|
filePaths.append(fileInfo.absoluteFilePath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_games = QtConcurrent::mapped(filePaths, [&](const QString& path) {
|
m_games = QtConcurrent::mapped(filePaths, [&](const QString& path) {
|
||||||
|
|
|
@ -51,7 +51,9 @@ QWidget* GameInstallDialog::SetupGamesDirectory() {
|
||||||
// Input.
|
// Input.
|
||||||
m_gamesDirectory = new QLineEdit();
|
m_gamesDirectory = new QLineEdit();
|
||||||
QString install_dir;
|
QString install_dir;
|
||||||
Common::FS::PathToQString(install_dir, Config::getGameInstallDir());
|
std::filesystem::path install_path =
|
||||||
|
Config::getGameInstallDirs().empty() ? "" : Config::getGameInstallDirs().front();
|
||||||
|
Common::FS::PathToQString(install_dir, install_path);
|
||||||
m_gamesDirectory->setText(install_dir);
|
m_gamesDirectory->setText(install_dir);
|
||||||
m_gamesDirectory->setMinimumWidth(400);
|
m_gamesDirectory->setMinimumWidth(400);
|
||||||
|
|
||||||
|
@ -125,7 +127,9 @@ void GameInstallDialog::Save() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Config::setGameInstallDir(Common::FS::PathFromQString(gamesDirectory));
|
std::vector<std::filesystem::path> install_dirs;
|
||||||
|
install_dirs.emplace_back(Common::FS::PathFromQString(gamesDirectory));
|
||||||
|
Config::setGameInstallDirs(install_dirs);
|
||||||
Config::setAddonInstallDir(Common::FS::PathFromQString(addonsDirectory));
|
Config::setAddonInstallDir(Common::FS::PathFromQString(addonsDirectory));
|
||||||
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||||
Config::save(config_dir / "config.toml");
|
Config::save(config_dir / "config.toml");
|
||||||
|
|
76
src/qt_gui/install_dir_select.cpp
Normal file
76
src/qt_gui/install_dir_select.cpp
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "install_dir_select.h"
|
||||||
|
|
||||||
|
InstallDirSelect::InstallDirSelect() : selected_dir() {
|
||||||
|
selected_dir = Config::getGameInstallDirs().empty() ? "" : Config::getGameInstallDirs().front();
|
||||||
|
|
||||||
|
if (!Config::getGameInstallDirs().empty() && Config::getGameInstallDirs().size() == 1) {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto layout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
layout->addWidget(SetupInstallDirList());
|
||||||
|
layout->addStretch();
|
||||||
|
layout->addWidget(SetupDialogActions());
|
||||||
|
|
||||||
|
setWindowTitle(tr("shadPS4 - Choose directory"));
|
||||||
|
setWindowIcon(QIcon(":images/shadps4.ico"));
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallDirSelect::~InstallDirSelect() {}
|
||||||
|
|
||||||
|
QWidget* InstallDirSelect::SetupInstallDirList() {
|
||||||
|
auto group = new QGroupBox(tr("Select which directory you want to install to."));
|
||||||
|
auto vlayout = new QVBoxLayout();
|
||||||
|
|
||||||
|
auto m_path_list = new QListWidget();
|
||||||
|
QList<QString> qt_list;
|
||||||
|
for (const auto& str : Config::getGameInstallDirs()) {
|
||||||
|
QString installDirPath;
|
||||||
|
Common::FS::PathToQString(installDirPath, str);
|
||||||
|
qt_list.append(installDirPath);
|
||||||
|
}
|
||||||
|
m_path_list->insertItems(0, qt_list);
|
||||||
|
m_path_list->setSpacing(1);
|
||||||
|
|
||||||
|
connect(m_path_list, &QListWidget::itemClicked, this, &InstallDirSelect::setSelectedDirectory);
|
||||||
|
connect(m_path_list, &QListWidget::itemActivated, this,
|
||||||
|
&InstallDirSelect::setSelectedDirectory);
|
||||||
|
|
||||||
|
vlayout->addWidget(m_path_list);
|
||||||
|
|
||||||
|
group->setLayout(vlayout);
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InstallDirSelect::setSelectedDirectory(QListWidgetItem* item) {
|
||||||
|
if (item) {
|
||||||
|
const auto highlighted_path = Common::FS::PathFromQString(item->text());
|
||||||
|
if (!highlighted_path.empty()) {
|
||||||
|
selected_dir = highlighted_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* InstallDirSelect::SetupDialogActions() {
|
||||||
|
auto actions = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
|
||||||
|
connect(actions, &QDialogButtonBox::accepted, this, &InstallDirSelect::accept);
|
||||||
|
connect(actions, &QDialogButtonBox::rejected, this, &InstallDirSelect::reject);
|
||||||
|
|
||||||
|
return actions;
|
||||||
|
}
|
31
src/qt_gui/install_dir_select.h
Normal file
31
src/qt_gui/install_dir_select.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QListWidget>
|
||||||
|
|
||||||
|
#include "common/config.h"
|
||||||
|
#include "common/path_util.h"
|
||||||
|
|
||||||
|
class QLineEdit;
|
||||||
|
|
||||||
|
class InstallDirSelect final : public QDialog {
|
||||||
|
public:
|
||||||
|
InstallDirSelect();
|
||||||
|
~InstallDirSelect();
|
||||||
|
|
||||||
|
std::filesystem::path getSelectedDirectory() {
|
||||||
|
return selected_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void BrowseGamesDirectory();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QWidget* SetupInstallDirList();
|
||||||
|
QWidget* SetupDialogActions();
|
||||||
|
void setSelectedDirectory(QListWidgetItem* item);
|
||||||
|
std::filesystem::path selected_dir;
|
||||||
|
};
|
|
@ -30,7 +30,7 @@ int main(int argc, char* argv[]) {
|
||||||
bool has_command_line_argument = argc > 1;
|
bool has_command_line_argument = argc > 1;
|
||||||
|
|
||||||
// Check if the game install directory is set
|
// Check if the game install directory is set
|
||||||
if (Config::getGameInstallDir().empty() && !has_command_line_argument) {
|
if (Config::getGameInstallDirs().empty() && !has_command_line_argument) {
|
||||||
GameInstallDialog dlg;
|
GameInstallDialog dlg;
|
||||||
dlg.exec();
|
dlg.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "core/file_format/pkg.h"
|
#include "core/file_format/pkg.h"
|
||||||
#include "core/loader.h"
|
#include "core/loader.h"
|
||||||
#include "game_install_dialog.h"
|
#include "game_install_dialog.h"
|
||||||
|
#include "install_dir_select.h"
|
||||||
#include "main_window.h"
|
#include "main_window.h"
|
||||||
#include "settings_dialog.h"
|
#include "settings_dialog.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
|
@ -672,7 +673,10 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
||||||
QMessageBox::critical(this, tr("PKG ERROR"), QString::fromStdString(failreason));
|
QMessageBox::critical(this, tr("PKG ERROR"), QString::fromStdString(failreason));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto extract_path = Config::getGameInstallDir() / pkg.GetTitleID();
|
InstallDirSelect ids;
|
||||||
|
ids.exec();
|
||||||
|
auto game_install_dir = ids.getSelectedDirectory();
|
||||||
|
auto extract_path = game_install_dir / pkg.GetTitleID();
|
||||||
QString pkgType = QString::fromStdString(pkg.GetPkgFlags());
|
QString pkgType = QString::fromStdString(pkg.GetPkgFlags());
|
||||||
QString gameDirPath;
|
QString gameDirPath;
|
||||||
Common::FS::PathToQString(gameDirPath, extract_path);
|
Common::FS::PathToQString(gameDirPath, extract_path);
|
||||||
|
@ -821,7 +825,7 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
||||||
connect(&futureWatcher, &QFutureWatcher<void>::finished, this, [=, this]() {
|
connect(&futureWatcher, &QFutureWatcher<void>::finished, this, [=, this]() {
|
||||||
if (pkgNum == nPkg) {
|
if (pkgNum == nPkg) {
|
||||||
QString path;
|
QString path;
|
||||||
Common::FS::PathToQString(path, Config::getGameInstallDir());
|
Common::FS::PathToQString(path, game_install_dir);
|
||||||
QMessageBox extractMsgBox(this);
|
QMessageBox extractMsgBox(this);
|
||||||
extractMsgBox.setWindowTitle(tr("Extraction Finished"));
|
extractMsgBox.setWindowTitle(tr("Extraction Finished"));
|
||||||
extractMsgBox.setText(
|
extractMsgBox.setText(
|
||||||
|
|
|
@ -220,6 +220,55 @@ SettingsDialog::SettingsDialog(std::span<const QString> physical_devices, QWidge
|
||||||
[](int val) { Config::setNullGpu(val); });
|
[](int val) { Config::setNullGpu(val); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PATH TAB
|
||||||
|
{
|
||||||
|
for (const auto& dir : Config::getGameInstallDirs()) {
|
||||||
|
QString path_string;
|
||||||
|
Common::FS::PathToQString(path_string, dir);
|
||||||
|
QListWidgetItem* item = new QListWidgetItem(path_string);
|
||||||
|
ui->gameFoldersListWidget->addItem(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->removeFolderButton->setEnabled(false);
|
||||||
|
|
||||||
|
connect(ui->addFolderButton, &QPushButton::clicked, this, [this]() {
|
||||||
|
QString file_path_string =
|
||||||
|
QFileDialog::getExistingDirectory(this, tr("Directory to install games"));
|
||||||
|
auto file_path = Common::FS::PathFromQString(file_path_string);
|
||||||
|
if (!file_path.empty()) {
|
||||||
|
std::vector<std::filesystem::path> install_dirs = Config::getGameInstallDirs();
|
||||||
|
install_dirs.push_back(file_path);
|
||||||
|
Config::setGameInstallDirs(install_dirs);
|
||||||
|
QListWidgetItem* item = new QListWidgetItem(file_path_string);
|
||||||
|
ui->gameFoldersListWidget->addItem(item);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->gameFoldersListWidget, &QListWidget::itemSelectionChanged, this, [this]() {
|
||||||
|
ui->removeFolderButton->setEnabled(
|
||||||
|
!ui->gameFoldersListWidget->selectedItems().isEmpty());
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->removeFolderButton, &QPushButton::clicked, this, [this]() {
|
||||||
|
QListWidgetItem* selected_item = ui->gameFoldersListWidget->currentItem();
|
||||||
|
QString item_path_string = selected_item ? selected_item->text() : QString();
|
||||||
|
if (!item_path_string.isEmpty()) {
|
||||||
|
auto file_path = Common::FS::PathFromQString(item_path_string);
|
||||||
|
std::vector<std::filesystem::path> install_dirs = Config::getGameInstallDirs();
|
||||||
|
|
||||||
|
auto iterator = std::remove_if(
|
||||||
|
install_dirs.begin(), install_dirs.end(),
|
||||||
|
[&file_path](const std::filesystem::path& dir) { return file_path == dir; });
|
||||||
|
|
||||||
|
if (iterator != install_dirs.end()) {
|
||||||
|
install_dirs.erase(iterator, install_dirs.end());
|
||||||
|
delete selected_item;
|
||||||
|
}
|
||||||
|
Config::setGameInstallDirs(install_dirs);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// DEBUG TAB
|
// DEBUG TAB
|
||||||
{
|
{
|
||||||
connect(ui->debugDump, &QCheckBox::stateChanged, this,
|
connect(ui->debugDump, &QCheckBox::stateChanged, this,
|
||||||
|
|
|
@ -918,6 +918,76 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="pathsTab">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Paths</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QVBoxLayout" name="inputTabVLayout" stretch="0">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="gameFoldersGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Game Folders</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QListWidget" name="gameFoldersListWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>401</width>
|
||||||
|
<height>331</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="addFolderButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>100</x>
|
||||||
|
<y>360</y>
|
||||||
|
<width>80</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Add...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="removeFolderButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>210</x>
|
||||||
|
<y>360</y>
|
||||||
|
<width>80</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Remove</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeType">
|
||||||
|
<enum>QSizePolicy::Policy::Preferred</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
<widget class="QWidget" name="debugTab">
|
<widget class="QWidget" name="debugTab">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string>Debug</string>
|
<string>Debug</string>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue