1
0
Fork 0
mirror of synced 2024-06-02 02:34:40 +12:00

Add a debug console for games

This commit is contained in:
Dummerle 2021-08-13 22:51:36 +02:00
parent 5dcaa3f8af
commit e1c6e03812
6 changed files with 409 additions and 337 deletions

View file

@ -0,0 +1,57 @@
from PyQt5.QtGui import QTextCursor
from PyQt5.QtWidgets import QPlainTextEdit, QWidget, QPushButton, QFileDialog, QVBoxLayout
class ConsoleWindow(QWidget):
def __init__(self):
super(ConsoleWindow, self).__init__()
self.layout = QVBoxLayout()
self.setGeometry(0, 0, 600, 400)
self.console = Console()
self.layout.addWidget(self.console)
self.save_button = QPushButton(self.tr("Save output to file"))
self.layout.addWidget(self.save_button)
self.save_button.clicked.connect(self.save)
self.setLayout(self.layout)
def save(self):
file, ok = QFileDialog.getSaveFileName(self, "Save output", "", "Log Files (*.log);;All Files (*)")
if ok:
if "." not in file:
file += ".log"
with open(file, "w") as f:
f.write(self.console.toPlainText())
f.close()
self.save_button.setText(self.tr("Saved"))
def log(self, text):
self.console.log(text)
def error(self, text):
self.console.error(text)
class Console(QPlainTextEdit):
def __init__(self):
super().__init__()
self.setReadOnly(True)
self._cursor_output = self.textCursor()
def log(self, text):
self._cursor_output.insertText(text)
self.scroll_to_last_line()
def error(self, text):
self._cursor_output.insertHtml(f"<font color=\"Red\">{text}</font>")
self.scroll_to_last_line()
def scroll_to_last_line(self):
cursor = self.textCursor()
cursor.movePosition(QTextCursor.End)
cursor.movePosition(QTextCursor.Up if cursor.atBlockStart() else
QTextCursor.StartOfLine)
self.setTextCursor(cursor)

View file

View file

@ -8,6 +8,7 @@ from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction
from custom_legendary.core import LegendaryCore
from custom_legendary.models.game import InstalledGame
from rare.components.dialogs.uninstall_dialog import UninstallDialog
from rare.components.extra.Console import ConsoleWindow
from rare.utils import legendary_utils
from rare.utils.utils import create_desktop_link
@ -32,6 +33,7 @@ class BaseInstalledWidget(QGroupBox):
self.update_available = self.core.get_asset(self.game.app_name, True).build_version != igame.version
self.data = QByteArray()
self.setContentsMargins(0, 0, 0, 0)
self.settings = QSettings()
self.setContextMenuPolicy(Qt.ActionsContextMenu)
launch = QAction(self.tr("Launch"), self)
@ -114,17 +116,26 @@ class BaseInstalledWidget(QGroupBox):
except Exception as e:
logger.error(e)
QMessageBox.warning(self, "Error",
self.tr("An error occurred while starting game. Maybe game files are missing"))
str(e))
return
if not self.proc:
logger.error("Could not start process")
return 1
self.game_logger = getLogger(self.game.app_name)
self.proc.finished.connect(self.finished)
self.proc.readyReadStandardOutput.connect(self.stdout)
self.proc.readyReadStandardError.connect(self.stderr)
if self.settings.value("show_console", False, bool):
self.console = ConsoleWindow()
self.console.show()
self.proc.readyReadStandardOutput.connect(lambda: self.console.log(
bytes(self.proc.readAllStandardOutput()).decode("utf-8", errors="ignore")))
self.proc.readyReadStandardError.connect(lambda: self.console.error(
bytes(self.proc.readAllStandardOutput()).decode("utf-8", errors="ignore")))
else:
self.proc.readyReadStandardOutput.connect(self.stdout)
self.proc.readyReadStandardError.connect(self.stderr)
self.proc.start(params[0], params[1:])
self.launch_signal.emit(self.igame.app_name)
self.game_running = True
@ -134,17 +145,19 @@ class BaseInstalledWidget(QGroupBox):
def stdout(self):
data = self.proc.readAllStandardOutput()
stdout = bytes(data).decode("utf-8", errors="ignore")
self.game_logger.info(stdout)
print(stdout)
def stderr(self):
stderr = bytes(self.proc.readAllStandardError()).decode("utf-8", errors="ignore")
self.game_logger.error(stderr)
QMessageBox.warning(self, "Warning", stderr + "\nSee ~/.cache/rare/logs/")
print(stderr)
# QMessageBox.warning(self, "Warning", stderr + "\nSee ~/.cache/rare/logs/")
def finished(self, exit_code):
logger.info("Game exited with exit code: " + str(exit_code))
self.finish_signal.emit(self.game.app_name)
self.game_running = False
if self.settings.value("show_console", False, bool):
self.console.log(f"Game exited with code: {exit_code}")
def uninstall(self):
infos = UninstallDialog(self.game).get_information()

View file

@ -35,7 +35,8 @@ class RareSettings(QWidget, Ui_RareSettings):
(self.confirm_start, "confirm_start", False),
(self.auto_sync_cloud, "auto_sync_cloud", True),
(self.notification, "notification", True),
(self.save_size, "save_size", False)
(self.save_size, "save_size", False),
(self.log_games, "show_console", False)
]
self.settings = QSettings()
@ -81,25 +82,12 @@ class RareSettings(QWidget, Ui_RareSettings):
self.rpc = RPCSettings()
self.rpc_layout.addWidget(self.rpc, alignment=Qt.AlignTop)
self.init_checkboxes(self.checkboxes)
self.sys_tray.stateChanged.connect(
lambda: self.settings.setValue("sys_tray", self.sys_tray.isChecked())
)
self.auto_update.stateChanged.connect(
lambda: self.settings.setValue("auto_update", self.auto_update.isChecked())
)
self.confirm_start.stateChanged.connect(
lambda: self.settings.setValue("confirm_start", self.confirm_start.isChecked())
)
self.auto_sync_cloud.stateChanged.connect(
lambda: self.settings.setValue("auto_sync_cloud", self.auto_sync_cloud.isChecked())
)
self.notification.stateChanged.connect(
lambda: self.settings.setValue("notification", self.notification.isChecked())
)
self.save_size.stateChanged.connect(
lambda: self.settings.setValue("save_size", self.save_size.isChecked())
)
for cb in self.checkboxes:
widget, option, default = cb
widget.setChecked(self.settings.value(option, default, bool))
widget.stateChanged.connect(
lambda: self.settings.setValue(option, widget.isChecked())
)
if platform.system() == "Linux":
self.desktop_file = os.path.expanduser("~/Desktop/Rare.desktop")
@ -129,7 +117,6 @@ class RareSettings(QWidget, Ui_RareSettings):
size += os.path.getsize(os.path.join(logdir, i))
self.log_dir_size_label.setText(utils.get_size(size))
# TODO: Implement
# self.log_dir_clean_button.setVisible(False)
# self.log_dir_size_label.setVisible(False)
@ -211,8 +198,3 @@ class RareSettings(QWidget, Ui_RareSettings):
os.rmdir(old_path)
self.img_dir_path = new_path
self.settings.setValue("img_dir", new_path)
def init_checkboxes(self, checkboxes):
for cb in checkboxes:
widget, option, default = cb
widget.setChecked(self.settings.value(option, default, bool))

View file

@ -14,11 +14,76 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_RareSettings(object):
def setupUi(self, RareSettings):
RareSettings.setObjectName("RareSettings")
RareSettings.resize(694, 532)
self.rare_layout = QtWidgets.QGridLayout(RareSettings)
self.rare_layout.setObjectName("rare_layout")
self.rpc_layout = QtWidgets.QVBoxLayout()
self.rpc_layout.setObjectName("rpc_layout")
self.rare_layout.addLayout(self.rpc_layout, 1, 1, 1, 1)
self.settings_group = QtWidgets.QGroupBox(RareSettings)
self.settings_group.setObjectName("settings_group")
self.behavior_layout = QtWidgets.QGridLayout(self.settings_group)
self.behavior_layout.setObjectName("behavior_layout")
self.confirm_start = QtWidgets.QCheckBox(self.settings_group)
self.confirm_start.setObjectName("confirm_start")
self.behavior_layout.addWidget(self.confirm_start, 2, 0, 1, 1)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.behavior_layout.addItem(spacerItem, 2, 1, 2, 1)
self.auto_update = QtWidgets.QCheckBox(self.settings_group)
self.auto_update.setObjectName("auto_update")
self.behavior_layout.addWidget(self.auto_update, 1, 0, 1, 1)
self.save_size = QtWidgets.QCheckBox(self.settings_group)
self.save_size.setObjectName("save_size")
self.behavior_layout.addWidget(self.save_size, 5, 0, 1, 1)
self.auto_sync_cloud = QtWidgets.QCheckBox(self.settings_group)
self.auto_sync_cloud.setObjectName("auto_sync_cloud")
self.behavior_layout.addWidget(self.auto_sync_cloud, 3, 0, 1, 1)
self.notification = QtWidgets.QCheckBox(self.settings_group)
self.notification.setObjectName("notification")
self.behavior_layout.addWidget(self.notification, 4, 0, 1, 1)
self.sys_tray = QtWidgets.QCheckBox(self.settings_group)
self.sys_tray.setObjectName("sys_tray")
self.behavior_layout.addWidget(self.sys_tray, 0, 0, 1, 1)
self.log_games = QtWidgets.QCheckBox(self.settings_group)
self.log_games.setObjectName("log_games")
self.behavior_layout.addWidget(self.log_games, 6, 0, 1, 1)
self.rare_layout.addWidget(self.settings_group, 2, 0, 1, 1, QtCore.Qt.AlignTop)
self.interface_group = QtWidgets.QGroupBox(RareSettings)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.interface_group.sizePolicy().hasHeightForWidth())
self.interface_group.setSizePolicy(sizePolicy)
self.interface_group.setObjectName("interface_group")
self.interface_layout = QtWidgets.QGridLayout(self.interface_group)
self.interface_layout.setObjectName("interface_layout")
self.style_label = QtWidgets.QLabel(self.interface_group)
self.style_label.setObjectName("style_label")
self.interface_layout.addWidget(self.style_label, 2, 0, 1, 1, QtCore.Qt.AlignRight)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.interface_layout.addItem(spacerItem1, 1, 2, 1, 1)
self.lang_select = QtWidgets.QComboBox(self.interface_group)
self.lang_select.setObjectName("lang_select")
self.interface_layout.addWidget(self.lang_select, 0, 1, 1, 1)
self.color_select = QtWidgets.QComboBox(self.interface_group)
self.color_select.setObjectName("color_select")
self.color_select.addItem("")
self.interface_layout.addWidget(self.color_select, 1, 1, 1, 1)
self.style_select = QtWidgets.QComboBox(self.interface_group)
self.style_select.setObjectName("style_select")
self.style_select.addItem("")
self.interface_layout.addWidget(self.style_select, 2, 1, 1, 1)
self.lang_label = QtWidgets.QLabel(self.interface_group)
self.lang_label.setObjectName("lang_label")
self.interface_layout.addWidget(self.lang_label, 0, 0, 1, 1, QtCore.Qt.AlignRight)
self.color_label = QtWidgets.QLabel(self.interface_group)
self.color_label.setObjectName("color_label")
self.interface_layout.addWidget(self.color_label, 1, 0, 1, 1, QtCore.Qt.AlignRight)
self.interface_info = QtWidgets.QLabel(self.interface_group)
font = QtGui.QFont()
font.setItalic(True)
self.interface_info.setFont(font)
self.interface_info.setWordWrap(True)
self.interface_info.setObjectName("interface_info")
self.interface_layout.addWidget(self.interface_info, 3, 0, 1, 3)
self.rare_layout.addWidget(self.interface_group, 1, 0, 1, 1, QtCore.Qt.AlignTop)
self.groupBox = QtWidgets.QGroupBox(RareSettings)
self.groupBox.setObjectName("groupBox")
self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox)
@ -30,31 +95,11 @@ class Ui_RareSettings(object):
self.startmenu_link.setObjectName("startmenu_link")
self.verticalLayout.addWidget(self.startmenu_link)
self.rare_layout.addWidget(self.groupBox, 2, 1, 1, 1, QtCore.Qt.AlignTop)
self.settings_group = QtWidgets.QGroupBox(RareSettings)
self.settings_group.setObjectName("settings_group")
self.behavior_layout = QtWidgets.QGridLayout(self.settings_group)
self.behavior_layout.setObjectName("behavior_layout")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.behavior_layout.addItem(spacerItem, 2, 1, 2, 1)
self.save_size = QtWidgets.QCheckBox(self.settings_group)
self.save_size.setObjectName("save_size")
self.behavior_layout.addWidget(self.save_size, 5, 0, 1, 1)
self.notification = QtWidgets.QCheckBox(self.settings_group)
self.notification.setObjectName("notification")
self.behavior_layout.addWidget(self.notification, 4, 0, 1, 1)
self.auto_sync_cloud = QtWidgets.QCheckBox(self.settings_group)
self.auto_sync_cloud.setObjectName("auto_sync_cloud")
self.behavior_layout.addWidget(self.auto_sync_cloud, 3, 0, 1, 1)
self.confirm_start = QtWidgets.QCheckBox(self.settings_group)
self.confirm_start.setObjectName("confirm_start")
self.behavior_layout.addWidget(self.confirm_start, 2, 0, 1, 1)
self.auto_update = QtWidgets.QCheckBox(self.settings_group)
self.auto_update.setObjectName("auto_update")
self.behavior_layout.addWidget(self.auto_update, 1, 0, 1, 1)
self.sys_tray = QtWidgets.QCheckBox(self.settings_group)
self.sys_tray.setObjectName("sys_tray")
self.behavior_layout.addWidget(self.sys_tray, 0, 0, 1, 1)
self.rare_layout.addWidget(self.settings_group, 2, 0, 1, 1, QtCore.Qt.AlignTop)
self.rpc_layout = QtWidgets.QVBoxLayout()
self.rpc_layout.setObjectName("rpc_layout")
self.rare_layout.addLayout(self.rpc_layout, 1, 1, 1, 1)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.rare_layout.addItem(spacerItem2, 3, 0, 1, 2)
self.log_dir_group = QtWidgets.QGroupBox(RareSettings)
self.log_dir_group.setObjectName("log_dir_group")
self.log_dir_layout = QtWidgets.QVBoxLayout(self.log_dir_group)
@ -70,53 +115,12 @@ class Ui_RareSettings(object):
self.log_dir_size_label.setWordWrap(True)
self.log_dir_size_label.setObjectName("log_dir_size_label")
self.log_dir_layout.addWidget(self.log_dir_size_label)
self.rare_layout.addWidget(self.log_dir_group, 0, 1, 1, 1, QtCore.Qt.AlignTop)
self.interface_group = QtWidgets.QGroupBox(RareSettings)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.interface_group.sizePolicy().hasHeightForWidth())
self.interface_group.setSizePolicy(sizePolicy)
self.interface_group.setObjectName("interface_group")
self.interface_layout = QtWidgets.QGridLayout(self.interface_group)
self.interface_layout.setObjectName("interface_layout")
self.color_select = QtWidgets.QComboBox(self.interface_group)
self.color_select.setObjectName("color_select")
self.color_select.addItem("")
self.interface_layout.addWidget(self.color_select, 1, 1, 1, 1)
self.style_label = QtWidgets.QLabel(self.interface_group)
self.style_label.setObjectName("style_label")
self.interface_layout.addWidget(self.style_label, 2, 0, 1, 1, QtCore.Qt.AlignRight)
self.style_select = QtWidgets.QComboBox(self.interface_group)
self.style_select.setObjectName("style_select")
self.style_select.addItem("")
self.interface_layout.addWidget(self.style_select, 2, 1, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.interface_layout.addItem(spacerItem1, 1, 2, 1, 1)
self.interface_info = QtWidgets.QLabel(self.interface_group)
font = QtGui.QFont()
font.setItalic(True)
self.interface_info.setFont(font)
self.interface_info.setWordWrap(True)
self.interface_info.setObjectName("interface_info")
self.interface_layout.addWidget(self.interface_info, 3, 0, 1, 3)
self.lang_label = QtWidgets.QLabel(self.interface_group)
self.lang_label.setObjectName("lang_label")
self.interface_layout.addWidget(self.lang_label, 0, 0, 1, 1, QtCore.Qt.AlignRight)
self.lang_select = QtWidgets.QComboBox(self.interface_group)
self.lang_select.setObjectName("lang_select")
self.interface_layout.addWidget(self.lang_select, 0, 1, 1, 1)
self.color_label = QtWidgets.QLabel(self.interface_group)
self.color_label.setObjectName("color_label")
self.interface_layout.addWidget(self.color_label, 1, 0, 1, 1, QtCore.Qt.AlignRight)
self.rare_layout.addWidget(self.interface_group, 1, 0, 1, 1, QtCore.Qt.AlignTop)
self.rare_layout.addWidget(self.log_dir_group, 0, 1, 1, 1)
self.img_dir_group = QtWidgets.QGroupBox(RareSettings)
self.img_dir_group.setObjectName("img_dir_group")
self.img_dir_layout = QtWidgets.QVBoxLayout(self.img_dir_group)
self.img_dir_layout.setObjectName("img_dir_layout")
self.rare_layout.addWidget(self.img_dir_group, 0, 0, 1, 1, QtCore.Qt.AlignTop)
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.rare_layout.addItem(spacerItem2, 3, 0, 1, 2)
self.rare_layout.addWidget(self.img_dir_group, 0, 0, 1, 1)
self.retranslateUi(RareSettings)
QtCore.QMetaObject.connectSlotsByName(RareSettings)
@ -124,26 +128,27 @@ class Ui_RareSettings(object):
def retranslateUi(self, RareSettings):
_translate = QtCore.QCoreApplication.translate
RareSettings.setWindowTitle(_translate("RareSettings", "RareSettings"))
self.settings_group.setTitle(_translate("RareSettings", "Behavior"))
self.confirm_start.setText(_translate("RareSettings", "Confirm game launch"))
self.auto_update.setText(_translate("RareSettings", "Update games on application startup"))
self.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically sync with cloud"))
self.notification.setText(_translate("RareSettings", "Show notification on download completion"))
self.sys_tray.setText(_translate("RareSettings", "Exit to System tray"))
self.log_games.setText(_translate("RareSettings", "Show console for game debug"))
self.interface_group.setTitle(_translate("RareSettings", "Interface"))
self.style_label.setText(_translate("RareSettings", "Style Sheet"))
self.color_select.setItemText(0, _translate("RareSettings", "None"))
self.style_select.setItemText(0, _translate("RareSettings", "None"))
self.lang_label.setText(_translate("RareSettings", "Language"))
self.color_label.setText(_translate("RareSettings", "Color Scheme"))
self.interface_info.setText(_translate("RareSettings", "Restart Rare to apply."))
self.groupBox.setTitle(_translate("RareSettings", "Shortcuts"))
self.desktop_link.setText(_translate("RareSettings", "Create Desktop link"))
self.startmenu_link.setText(_translate("RareSettings", "Create start menu link"))
self.settings_group.setTitle(_translate("RareSettings", "Behavior"))
self.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
self.notification.setText(_translate("RareSettings", "Show notification on download completion"))
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically sync with cloud"))
self.confirm_start.setText(_translate("RareSettings", "Confirm game launch"))
self.auto_update.setText(_translate("RareSettings", "Update games on application startup"))
self.sys_tray.setText(_translate("RareSettings", "Exit to System tray"))
self.log_dir_group.setTitle(_translate("RareSettings", "Logs"))
self.log_dir_open_button.setText(_translate("RareSettings", "Open Log directory"))
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean Log directory"))
self.interface_group.setTitle(_translate("RareSettings", "Interface"))
self.color_select.setItemText(0, _translate("RareSettings", "None"))
self.style_label.setText(_translate("RareSettings", "Style Sheet"))
self.style_select.setItemText(0, _translate("RareSettings", "None"))
self.interface_info.setText(_translate("RareSettings", "Restart Rare to apply."))
self.lang_label.setText(_translate("RareSettings", "Language"))
self.color_label.setText(_translate("RareSettings", "Color Scheme"))
self.img_dir_group.setTitle(_translate("RareSettings", "Image Cache Directory"))

View file

@ -2,131 +2,87 @@
<ui version="4.0">
<class>RareSettings</class>
<widget class="QWidget" name="RareSettings">
<property name="windowTitle">
<string>RareSettings</string>
</property>
<layout class="QGridLayout" name="rare_layout">
<item row="1" column="1">
<layout class="QVBoxLayout" name="rpc_layout"/>
</item>
<item row="2" column="1" alignment="Qt::AlignTop">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Shortcuts</string>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>694</width>
<height>532</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="desktop_link">
<property name="text">
<string>Create Desktop link</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="startmenu_link">
<property name="text">
<string>Create start menu link</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" alignment="Qt::AlignTop">
<widget class="QGroupBox" name="settings_group">
<property name="title">
<string>Behavior</string>
<property name="windowTitle">
<string>RareSettings</string>
</property>
<layout class="QGridLayout" name="behavior_layout">
<item row="2" column="1" rowspan="2">
<spacer name="settings_hspacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="save_size">
<property name="text">
<string>Restore window size on application startup</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="notification">
<property name="text">
<string>Show notification on download completion</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="auto_sync_cloud">
<property name="text">
<string>Automatically sync with cloud</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="confirm_start">
<property name="text">
<string>Confirm game launch</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="auto_update">
<property name="text">
<string>Update games on application startup</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="sys_tray">
<property name="text">
<string>Exit to System tray</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1" alignment="Qt::AlignTop">
<widget class="QGroupBox" name="log_dir_group">
<property name="title">
<string>Logs</string>
</property>
<layout class="QVBoxLayout" name="log_dir_layout">
<item>
<widget class="QPushButton" name="log_dir_open_button">
<property name="text">
<string>Open Log directory</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="log_dir_clean_button">
<property name="text">
<string>Clean Log directory</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="log_dir_size_label">
<property name="text">
<string notr="true"/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
<layout class="QGridLayout" name="rare_layout">
<item row="2" column="0" alignment="Qt::AlignTop">
<widget class="QGroupBox" name="settings_group">
<property name="title">
<string>Behavior</string>
</property>
<layout class="QGridLayout" name="behavior_layout">
<item row="2" column="0">
<widget class="QCheckBox" name="confirm_start">
<property name="text">
<string>Confirm game launch</string>
</property>
</widget>
</item>
<item row="2" column="1" rowspan="2">
<spacer name="settings_hspacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="auto_update">
<property name="text">
<string>Update games on application startup</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="save_size">
<property name="text">
<string>Restore window size on application startup</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="auto_sync_cloud">
<property name="text">
<string>Automatically sync with cloud</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="notification">
<property name="text">
<string>Show notification on download completion</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="sys_tray">
<property name="text">
<string>Exit to System tray</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="log_games">
<property name="text">
<string>Show console for game debug</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" alignment="Qt::AlignTop">
@ -140,102 +96,161 @@
<property name="title">
<string>Interface</string>
</property>
<layout class="QGridLayout" name="interface_layout">
<item row="1" column="1">
<widget class="QComboBox" name="color_select">
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="style_label">
<property name="text">
<string>Style Sheet</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="style_select">
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item row="1" column="2">
<spacer name="interface_hspacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="3">
<widget class="QLabel" name="interface_info">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Restart Rare to apply.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lang_label">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="lang_select"/>
</item>
<item row="1" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="color_label">
<property name="text">
<string>Color Scheme</string>
</property>
</widget>
</item>
<layout class="QGridLayout" name="interface_layout">
<item row="2" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="style_label">
<property name="text">
<string>Style Sheet</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="interface_hspacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="lang_select"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="color_select">
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="style_select">
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lang_label">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="1" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="color_label">
<property name="text">
<string>Color Scheme</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QLabel" name="interface_info">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Restart Rare to apply.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="1" alignment="Qt::AlignTop">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Shortcuts</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="desktop_link">
<property name="text">
<string>Create Desktop link</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="startmenu_link">
<property name="text">
<string>Create start menu link</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="rpc_layout"/>
</item>
<item row="3" column="0" colspan="2">
<spacer name="rare_vspacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="log_dir_group">
<property name="title">
<string>Logs</string>
</property>
<layout class="QVBoxLayout" name="log_dir_layout">
<item>
<widget class="QPushButton" name="log_dir_open_button">
<property name="text">
<string>Open Log directory</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="log_dir_clean_button">
<property name="text">
<string>Clean Log directory</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="log_dir_size_label">
<property name="text">
<string notr="true"/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="img_dir_group">
<property name="title">
<string>Image Cache Directory</string>
</property>
<layout class="QVBoxLayout" name="img_dir_layout"/>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0" alignment="Qt::AlignTop">
<widget class="QGroupBox" name="img_dir_group">
<property name="title">
<string>Image Cache Directory</string>
</property>
<layout class="QVBoxLayout" name="img_dir_layout"/>
</widget>
</item>
<item row="3" column="0" colspan="2">
<spacer name="rare_vspacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>