1
0
Fork 0
mirror of synced 2024-06-26 10:11:19 +12:00

Better style for uninstalled info; add raw json view

This commit is contained in:
Dummerle 2021-05-17 21:27:23 +02:00
parent 61fe881c1a
commit 530cff2a14
5 changed files with 396 additions and 24 deletions

View file

@ -73,7 +73,7 @@ class TabWidget(QTabWidget):
self.games_tab.game_info.dlc_tab.install_dlc.connect(self.start_download)
# install game
self.games_tab.uninstalled_info_widget.install_button.clicked.connect(self.install_game)
self.games_tab.uninstalled_info_widget.info.install_game.connect(self.install_game)
# repair game
self.games_tab.game_info.info.verify_game.connect(lambda app_name: self.downloadTab.install_game(
@ -88,8 +88,7 @@ class TabWidget(QTabWidget):
self.tabBarClicked.connect(lambda x: self.games_tab.layout.setCurrentIndex(0) if x == 0 else None)
self.setIconSize(QSize(25, 25))
def install_game(self):
app_name = self.games_tab.uninstalled_info_widget.game.app_name
def install_game(self, app_name):
infos = InstallDialog(app_name, self.core).get_information()
if infos != 0:
path, max_workers, force, ignore_free_space = infos

View file

@ -3,7 +3,7 @@ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QCheckBox, QLineE
from qtawesome import icon
from rare.components.tabs.games.game_info import InfoTabs
from rare.components.tabs.games.game_info.uninstalled_info import UninstalledInfo
from rare.components.tabs.games.game_info.uninstalled_info import UninstalledInfo, UninstalledTabInfo
from rare.components.tabs.games.game_list import GameList
from rare.components.tabs.games.import_widget import ImportWidget
from rare.utils.extra_widgets import SelectViewWidget
@ -30,9 +30,9 @@ class GameTab(QWidget):
self.import_widget.back_button.clicked.connect(lambda: self.layout.setCurrentIndex(0))
self.import_widget.update_list.connect(self.update_list)
self.uninstalled_info_widget = UninstalledInfo(core)
self.uninstalled_info_widget = UninstalledTabInfo(core, self)
self.layout.addWidget(self.uninstalled_info_widget)
self.uninstalled_info_widget.back.clicked.connect(lambda: self.layout.setCurrentIndex(0))
# self.uninstalled_info_widget.back.clicked.connect(lambda: self.layout.setCurrentIndex(0))
self.setLayout(self.layout)
@ -42,6 +42,7 @@ class GameTab(QWidget):
def show_uninstalled(self, app_name):
self.uninstalled_info_widget.update_game(app_name)
self.uninstalled_info_widget.setCurrentIndex(1)
self.layout.setCurrentIndex(3)
def show_info(self, app_name):

View file

@ -1,12 +1,52 @@
import os
import json
import os
from PyQt5.QtCore import pyqtSignal, QSettings
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel
from PyQt5.QtCore import pyqtSignal, QSettings, Qt
from PyQt5.QtGui import QPixmap, QKeyEvent
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QTreeView
from qtawesome import icon
from custom_legendary.core import LegendaryCore
from custom_legendary.models.game import Game
from rare.utils.extra_widgets import SideTabBar
from rare.utils.json_formatter import QJsonModel
class UninstalledTabInfo(QTabWidget):
def __init__(self, core, parent):
super(UninstalledTabInfo, self).__init__(parent=parent)
self.app_name = ""
self.core = core
self.setTabBar(SideTabBar())
self.setTabPosition(QTabWidget.West)
self.addTab(QWidget(), icon("mdi.keyboard-backspace", color="white"), self.tr("Back"))
self.tabBarClicked.connect(lambda x: self.parent().layout.setCurrentIndex(0) if x == 0 else None)
self.info = UninstalledInfo(core, self)
self.addTab(self.info, self.tr("Game Info"))
self.view = QTreeView()
self.view.setColumnWidth(0, 300)
self.view.setWordWrap(True)
self.model = QJsonModel()
self.view.setModel(self.model)
self.addTab(self.view, self.tr("Metadata"))
# self.setTabEnabled(1, False)
self.setCurrentIndex(1)
def update_game(self, app_name):
self.info.update_game(app_name)
self.model.clear()
self.model.load(json.load(open(os.path.expanduser(f"~/.config/legendary/metadata/{app_name}.json"), "r")))
def keyPressEvent(self, e: QKeyEvent):
if e.key() == Qt.Key_Escape:
self.parent().layout.setCurrentIndex(0)
class UninstalledInfo(QWidget):
@ -15,11 +55,11 @@ class UninstalledInfo(QWidget):
grade_table = json.load(open(os.path.expanduser("~/.cache/rare/game_list.json")))
def __init__(self, core: LegendaryCore):
super(UninstalledInfo, self).__init__()
def __init__(self, core: LegendaryCore, parent):
super(UninstalledInfo, self).__init__(parent=parent)
self.layout = QVBoxLayout()
self.ratings = {"platinum": self.tr("Platimum"),
self.ratings = {"platinum": self.tr("Platinum"),
"gold": self.tr("Gold"),
"silver": self.tr("Silver"),
"bronze": self.tr("Bronze"),
@ -38,9 +78,6 @@ class UninstalledInfo(QWidget):
self.top_layout.addLayout(left_layout)
self.right_layout = QVBoxLayout()
self.back = QPushButton(self.tr("Back"))
self.right_layout.addWidget(self.back)
self.title = QLabel("Error")
self.right_layout.addWidget(self.title)
@ -51,7 +88,12 @@ class UninstalledInfo(QWidget):
self.right_layout.addWidget(self.rating)
self.install_button = QPushButton(self.tr("Install"))
self.install_button.setFixedWidth(300)
self.install_button.setStyleSheet("""background-color: #090""")
self.install_button.clicked.connect(lambda: self.install_game.emit(self.game.app_name))
self.right_layout.addWidget(self.install_button)
self.version = QLabel("Error")
self.right_layout.addWidget(self.version)
self.right_layout.addStretch(1)
self.top_layout.addLayout(self.right_layout)
@ -65,7 +107,7 @@ class UninstalledInfo(QWidget):
self.game = self.core.get_game(app_name)
self.title.setText(f"<h2>{self.game.app_title}</h2>")
self.app_name.setText(app_name)
self.app_name.setText("Appname: " + app_name)
IMAGE_DIR = self.settings.value("img_dir", os.path.expanduser("~/.cache/rare/images"), str)
@ -83,6 +125,10 @@ class UninstalledInfo(QWidget):
pixmap = pixmap.scaled(w, int(w * 4 / 3))
self.image.setPixmap(pixmap)
rating = self.grade_table[app_name]["grade"]
self.rating.setText(self.ratings[rating])
self.version.setText(self.game.asset_info.build_version)
rating = self.grade_table[app_name]["grade"]
if rating not in ["fail", "pending"]:
self.rating.setText(self.tr("Rating from ProtonDB: ") + self.ratings[rating])
else:
self.rating.setText(self.ratings[rating])

View file

@ -58,11 +58,6 @@ QGroupBox#group {
padding: 8px;
}
QTabBar::tab:disabled {
color: transparent;
background-color: transparent;
}
QToolButton {
padding: 6px;
@ -142,6 +137,11 @@ QTabBar::tab::selected#settings_bar {
background-color: #334;
}
QTabBar::tab:disabled#settings_bar {
color: transparent;
background-color: transparent;
}
/*
QScrollBar:vertical{
border: 1px solid white;

View file

@ -0,0 +1,326 @@
"""Python adaptation of https://github.com/dridk/QJsonModel
Supports Python 2 and 3 with PySide, PySide2, PyQt4 or PyQt5.
Requires https://github.com/mottosso/Qt.py
Usage:
Use it like you would the C++ version.
>>> import qjsonmodel
>>> model = qjsonmodel.QJsonModel()
>>> model.load({"key": "value"})
Test:
Run the provided example to sanity check your Python,
dependencies and Qt binding.
$ python qjsonmodel.py
Changes:
This module differs from the C++ version in the following ways.
1. Setters and getters are replaced by Python properties
2. Objects are sorted by default, disabled via load(sort=False)
3. load() takes a Python dictionary as opposed to
a string or file handle.
- To load from a string, use built-in `json.loads()`
>>> import json
>>> document = json.loads("{'key': 'value'}")
>>> model.load(document)
- To load from a file, use `with open(fname)`
>>> import json
>>> with open("file.json") as f:
... document = json.load(f)
... model.load(document)
"""
import json
from PyQt5 import QtCore, QtWidgets
class QJsonTreeItem(object):
def __init__(self, parent=None):
self._parent = parent
self._key = ""
self._value = ""
self._type = None
self._children = list()
def appendChild(self, item):
self._children.append(item)
def child(self, row):
return self._children[row]
def parent(self):
return self._parent
def childCount(self):
return len(self._children)
def row(self):
return (
self._parent._children.index(self)
if self._parent else 0
)
@property
def key(self):
return self._key
@key.setter
def key(self, key):
self._key = key
@property
def value(self):
return self._value
@value.setter
def value(self, value):
self._value = value
@property
def type(self):
return self._type
@type.setter
def type(self, typ):
self._type = typ
@classmethod
def load(self, value, parent=None, sort=True):
rootItem = QJsonTreeItem(parent)
rootItem.key = "root"
if isinstance(value, dict):
items = (
sorted(value.items())
if sort else value.items()
)
for key, value in items:
child = self.load(value, rootItem)
child.key = key
child.type = type(value)
rootItem.appendChild(child)
elif isinstance(value, list):
for index, value in enumerate(value):
child = self.load(value, rootItem)
child.key = index
child.type = type(value)
rootItem.appendChild(child)
else:
rootItem.value = value
rootItem.type = type(value)
return rootItem
class QJsonModel(QtCore.QAbstractItemModel):
def __init__(self, parent=None):
super(QJsonModel, self).__init__(parent)
self._rootItem = QJsonTreeItem()
self._headers = ("key", "value")
def clear(self):
self.load({})
def load(self, document):
"""Load from dictionary
Arguments:
document (dict): JSON-compatible dictionary
"""
assert isinstance(document, (dict, list, tuple)), (
"`document` must be of dict, list or tuple, "
"not %s" % type(document)
)
self.beginResetModel()
self._rootItem = QJsonTreeItem.load(document)
self._rootItem.type = type(document)
self.endResetModel()
return True
def json(self, root=None):
"""Serialise model as JSON-compliant dictionary
Arguments:
root (QJsonTreeItem, optional): Serialise from here
defaults to the the top-level item
Returns:
model as dict
"""
root = root or self._rootItem
return self.genJson(root)
def data(self, index, role):
if not index.isValid():
return None
item = index.internalPointer()
if role == QtCore.Qt.DisplayRole:
if index.column() == 0:
return item.key
if index.column() == 1:
return item.value
elif role == QtCore.Qt.EditRole:
if index.column() == 1:
return item.value
def setData(self, index, value, role):
if role == QtCore.Qt.EditRole:
if index.column() == 1:
item = index.internalPointer()
item.value = str(value)
self.dataChanged.emit(index, index, [QtCore.Qt.EditRole])
return True
return False
def headerData(self, section, orientation, role):
if role != QtCore.Qt.DisplayRole:
return None
if orientation == QtCore.Qt.Horizontal:
return self._headers[section]
def index(self, row, column, parent=QtCore.QModelIndex()):
if not self.hasIndex(row, column, parent):
return QtCore.QModelIndex()
if not parent.isValid():
parentItem = self._rootItem
else:
parentItem = parent.internalPointer()
childItem = parentItem.child(row)
if childItem:
return self.createIndex(row, column, childItem)
else:
return QtCore.QModelIndex()
def parent(self, index):
if not index.isValid():
return QtCore.QModelIndex()
childItem = index.internalPointer()
parentItem = childItem.parent()
if parentItem == self._rootItem:
return QtCore.QModelIndex()
return self.createIndex(parentItem.row(), 0, parentItem)
def rowCount(self, parent=QtCore.QModelIndex()):
if parent.column() > 0:
return 0
if not parent.isValid():
parentItem = self._rootItem
else:
parentItem = parent.internalPointer()
return parentItem.childCount()
def columnCount(self, parent=QtCore.QModelIndex()):
return 2
def flags(self, index):
flags = super(QJsonModel, self).flags(index)
if index.column() == 1:
return QtCore.Qt.ItemIsEditable | flags
else:
return flags
def genJson(self, item):
nchild = item.childCount()
if item.type is dict:
document = {}
for i in range(nchild):
ch = item.child(i)
document[ch.key] = self.genJson(ch)
return document
elif item.type == list:
document = []
for i in range(nchild):
ch = item.child(i)
document.append(self.genJson(ch))
return document
else:
return item.value
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
view = QtWidgets.QTreeView()
model = QJsonModel()
view.setModel(model)
document = json.loads("""\
{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021"
},
"phoneNumber": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "fax",
"number": "646 555-4567"
}
]
}
""")
model.load(document)
model.clear()
model.load(document)
# Sanity check
assert (
json.dumps(model.json(), sort_keys=True) ==
json.dumps(document, sort_keys=True)
)
view.show()
view.resize(500, 300)
app.exec_()