Skip to content

Commit d29655a

Browse files
Wrappers: add checkbox to enable/disable wrappers per game
1 parent 4b95609 commit d29655a

File tree

3 files changed

+102
-40
lines changed

3 files changed

+102
-40
lines changed

rare/components/tabs/settings/widgets/wrappers.py

+26-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
QPushButton,
2929
QLineEdit,
3030
QVBoxLayout,
31-
QComboBox,
31+
QComboBox, QCheckBox,
3232
)
3333

3434
from rare.models.wrapper import Wrapper
@@ -104,6 +104,8 @@ def __on_index_changed(self, index: int):
104104

105105

106106
class WrapperWidget(QFrame):
107+
# object: current
108+
disable_wrapper = Signal(object)
107109
# object: current, object: new
108110
update_wrapper = Signal(object, object)
109111
# object: current
@@ -115,9 +117,11 @@ def __init__(self, wrapper: Wrapper, parent=None):
115117
self.setSizePolicy(QSizePolicy.Policy.Maximum, QSizePolicy.Policy.Fixed)
116118
self.setToolTip(wrapper.as_str)
117119

118-
text_lbl = QLabel(wrapper.name, parent=self)
119-
text_lbl.setFont(QFont("monospace"))
120-
text_lbl.setEnabled(wrapper.is_editable)
120+
self.text_lbl = QCheckBox(wrapper.name, parent=self)
121+
self.text_lbl.setChecked(wrapper.is_enabled)
122+
self.text_lbl.setFont(QFont("monospace"))
123+
self.text_lbl.setEnabled(wrapper.is_editable)
124+
self.text_lbl.checkStateChanged.connect(self.__on_state_changed)
121125

122126
image_lbl = QLabel(parent=self)
123127
image_lbl.setPixmap(qta_icon("mdi.drag-vertical").pixmap(QSize(20, 20)))
@@ -142,7 +146,7 @@ def __init__(self, wrapper: Wrapper, parent=None):
142146
layout = QHBoxLayout(self)
143147
layout.setContentsMargins(0, 0, 0, 0)
144148
layout.addWidget(image_lbl)
145-
layout.addWidget(text_lbl)
149+
layout.addWidget(self.text_lbl)
146150
layout.addWidget(manage_button)
147151
self.setLayout(layout)
148152

@@ -155,6 +159,12 @@ def __init__(self, wrapper: Wrapper, parent=None):
155159
def data(self) -> Wrapper:
156160
return self.wrapper
157161

162+
@Slot(Qt.CheckState)
163+
def __on_state_changed(self, state: Qt.CheckState) -> None:
164+
new_wrapper = Wrapper(command=self.wrapper.command, enabled=self.text_lbl.isChecked())
165+
self.update_wrapper.emit(self.wrapper, new_wrapper)
166+
self.deleteLater()
167+
158168
@Slot()
159169
def __on_delete(self) -> None:
160170
self.delete_wrapper.emit(self.wrapper)
@@ -293,6 +303,7 @@ def __add_wrapper(self, wrapper: Wrapper, position: int = -1):
293303
self.wrapper_container.addWidget(widget)
294304
else:
295305
self.wrapper_container.insertWidget(position, widget)
306+
# widget.disable_wrapper.connect(self.__disable_wrapper)
296307
widget.update_wrapper.connect(self.__update_wrapper)
297308
widget.delete_wrapper.connect(self.__delete_wrapper)
298309

@@ -319,7 +330,7 @@ def add_user_wrapper(self, wrapper: Wrapper, position: int = -1):
319330
)
320331
return
321332

322-
if wrapper.checksum in self.wrappers.get_game_md5sum_list(self.app_name):
333+
if wrapper.checksum in self.wrappers.get_game_csum_list(self.app_name):
323334
QMessageBox.warning(
324335
self,
325336
self.tr("Warning"),
@@ -340,6 +351,15 @@ def add_user_wrapper(self, wrapper: Wrapper, position: int = -1):
340351

341352
self.add_wrapper(wrapper, position)
342353

354+
@Slot(object)
355+
def __disable_wrapper(self, wrapper: Wrapper):
356+
wrappers = self.wrappers.get_game_wrapper_list(self.app_name)
357+
index = wrappers.index(wrapper)
358+
wrappers.remove(wrapper)
359+
wrappers.insert(index, wrapper)
360+
self.wrappers.set_game_wrapper_list(self.app_name, wrappers)
361+
self.__add_wrapper(wrapper, index)
362+
343363
@Slot(object)
344364
def __delete_wrapper(self, wrapper: Wrapper):
345365
wrappers = self.wrappers.get_game_wrapper_list(self.app_name)

rare/models/wrapper.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@ class WrapperType(IntEnum):
1313

1414

1515
class Wrapper:
16-
def __init__(self, command: Union[str, List[str]], name: str = None, wtype: WrapperType = None):
16+
def __init__(
17+
self, command: Union[str, List[str]], name: str = None, wtype: WrapperType = None, enabled: bool = True
18+
):
1719
self.__command: List[str] = shlex.split(command) if isinstance(command, str) else command
1820
self.__name: str = name if name is not None else os.path.basename(self.__command[0])
1921
self.__wtype: WrapperType = wtype if wtype is not None else WrapperType.USER_DEFINED
22+
self.__enabled: bool = enabled or self.__wtype == WrapperType.COMPAT_TOOL
2023

2124
@property
2225
def is_compat_tool(self) -> bool:
@@ -26,6 +29,14 @@ def is_compat_tool(self) -> bool:
2629
def is_editable(self) -> bool:
2730
return self.__wtype in {WrapperType.USER_DEFINED, WrapperType.LEGENDARY_IMPORT}
2831

32+
@property
33+
def is_enabled(self) -> bool:
34+
return self.__enabled or self.is_compat_tool
35+
36+
@is_enabled.setter
37+
def is_enabled(self, state: bool) -> None:
38+
self.__enabled = state if not self.is_compat_tool else True
39+
2940
@property
3041
def checksum(self) -> str:
3142
return md5(self.as_str.encode("utf-8")).hexdigest()

rare/shared/wrappers.py

+64-33
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import os
33
from logging import getLogger
44
import shlex
5-
from typing import List, Dict, Iterable
5+
from typing import List, Dict, Iterable, Union, Tuple, Set
66
from rare.utils import config_helper as config
77

88
from PySide6.QtCore import QSettings
@@ -14,6 +14,31 @@
1414
logger = getLogger("Wrappers")
1515

1616

17+
class WrapperEntry:
18+
def __init__(self, checksum: str, enabled: bool = True):
19+
self.__checksum: str = checksum
20+
self.__enabled: bool = enabled
21+
22+
@property
23+
def checksum(self) -> str:
24+
return self.__checksum
25+
26+
@property
27+
def enabled(self) -> bool:
28+
return self.__enabled
29+
30+
@classmethod
31+
def from_dict(cls, data: Dict):
32+
return cls(checksum=data.get("checksum"), enabled=data.get("enabled", True))
33+
34+
@property
35+
def __dict__(self):
36+
return dict(checksum=self.__checksum, enabled=self.__enabled)
37+
38+
# def __eq__(self, other) -> bool:
39+
# return self.checksum == other.checksum
40+
41+
1742
class Wrappers:
1843
def __init__(self):
1944
self.__file = os.path.join(config_dir(), "wrappers.json")
@@ -30,9 +55,15 @@ def __init__(self):
3055
for wrap_id, wrapper in self.__wrappers_dict.get("wrappers", {}).items():
3156
self.__wrappers.update({wrap_id: Wrapper.from_dict(wrapper)})
3257

33-
self.__applists: Dict[str, List[str]] = {}
58+
self.__applists: Dict[str, List[WrapperEntry]] = {}
3459
for app_name, wrapper_list in self.__wrappers_dict.get("applists", {}).items():
35-
self.__applists.update({app_name: wrapper_list})
60+
if all(isinstance(x, str) for x in wrapper_list):
61+
wlist = [WrapperEntry(y) for y in wrapper_list]
62+
elif all(isinstance(x, dict) for x in wrapper_list):
63+
wlist = [WrapperEntry.from_dict(y) for y in wrapper_list]
64+
else:
65+
wlist = []
66+
self.__applists.update({app_name: wlist})
3667

3768
def import_wrappers(self, core: LegendaryCore, settings: QSettings, app_names: List):
3869
for app_name in app_names:
@@ -69,34 +100,31 @@ def user_wrappers(self) -> Iterable[Wrapper]:
69100
# yield wrap
70101

71102
def get_game_wrapper_string(self, app_name: str) -> str:
72-
commands = [wrapper.as_str for wrapper in self.get_game_wrapper_list(app_name)]
103+
commands = [wrapper.as_str for wrapper in self.get_game_wrapper_list(app_name) if wrapper.is_enabled]
73104
return " ".join(commands)
74105

75106
def get_game_wrapper_list(self, app_name: str) -> List[Wrapper]:
76-
_wrappers = []
77-
for wrap_id in self.__applists.get(app_name, []):
78-
if wrap := self.__wrappers.get(wrap_id, None):
79-
_wrappers.append(wrap)
80-
return _wrappers
107+
wrappers = []
108+
for entry in self.__applists.get(app_name, []):
109+
if wrap := self.__wrappers.get(entry.checksum, None):
110+
wrap.is_enabled = entry.enabled
111+
wrappers.append(wrap)
112+
return wrappers
81113

82-
def get_game_md5sum_list(self, app_name: str) -> List[str]:
83-
return self.__applists.get(app_name, [])
114+
def get_game_csum_list(self, app_name: str) -> Set[str]:
115+
return {entry.checksum for entry in self.__applists.get(app_name, [])}
84116

85117
def set_game_wrapper_list(self, app_name: str, wrappers: List[Wrapper]) -> None:
86118
_wrappers = sorted(wrappers, key=lambda w: w.is_compat_tool)
87119
for w in _wrappers:
88120
if (md5sum := w.checksum) in self.__wrappers.keys():
89121
if w != self.__wrappers[md5sum]:
90-
logger.error(
91-
"Non-unique md5sum for different wrappers %s, %s",
92-
w.name,
93-
self.__wrappers[md5sum].name,
94-
)
122+
logger.error("Equal csum for unequal wrappers %s, %s", w.name, self.__wrappers[md5sum].name)
95123
if w.is_compat_tool:
96124
self.__wrappers.update({md5sum: w})
97125
else:
98126
self.__wrappers.update({md5sum: w})
99-
self.__applists[app_name] = [w.checksum for w in _wrappers]
127+
self.__applists[app_name] = [WrapperEntry(w.checksum, w.is_enabled) for w in _wrappers]
100128
self.__save_config(app_name)
101129
self.__save_wrappers()
102130

@@ -105,8 +133,8 @@ def __save_config(self, app_name: str):
105133
config.save_option(app_name, "wrapper", command_string)
106134

107135
def __save_wrappers(self):
108-
existing = {wrap_id for wrap_id in self.__wrappers.keys()}
109-
in_use = {wrap_id for wrappers in self.__applists.values() for wrap_id in wrappers}
136+
existing = {csum for csum in self.__wrappers.keys()}
137+
in_use = {entry.checksum for wrappers in self.__applists.values() for entry in wrappers}
110138

111139
for redudant in existing.difference(in_use):
112140
del self.__wrappers[redudant]
@@ -128,15 +156,16 @@ def __save_wrappers(self):
128156
config_dir = os.getcwd
129157
global config
130158
config = Namespace()
131-
config.set_option = lambda x, y, z: print(x, y, z)
132-
config.remove_option = lambda x, y: print(x, y)
133-
config.save_config = lambda: print()
159+
config.set_option = lambda x, y, z: print("set_option:", x, y, z)
160+
config.remove_option = lambda x, y: print("remove_option:", x, y)
161+
config.save_config = lambda: print("save_config:")
162+
config.save_option = lambda x, y, z: print("save_option:", x, y, z)
134163

135164
wr = Wrappers()
136165

137166
w1 = Wrapper(command=["/usr/bin/w1"], wtype=WrapperType.NONE)
138167
w2 = Wrapper(command=["/usr/bin/w2"], wtype=WrapperType.COMPAT_TOOL)
139-
w3 = Wrapper(command=["/usr/bin/w3"], wtype=WrapperType.USER_DEFINED)
168+
w3 = Wrapper(command=["/usr/bin/w3"], wtype=WrapperType.USER_DEFINED, enabled=False)
140169
w4 = Wrapper(command=["/usr/bin/w4"], wtype=WrapperType.USER_DEFINED)
141170
wr.set_game_wrapper_list("testgame", [w1, w2, w3, w4])
142171

@@ -147,19 +176,21 @@ def __save_wrappers(self):
147176
wr.set_game_wrapper_list("testgame", [w1, w2, w3, w6])
148177

149178
w7 = Wrapper(command=["/usr/bin/w2"], wtype=WrapperType.COMPAT_TOOL)
150-
wrs = wr.get_game_wrapper_list("testgame")
151-
wrs.remove(w7)
152-
wr.set_game_wrapper_list("testgame", wrs)
179+
app_wrappers = wr.get_game_wrapper_list("testgame")
180+
pprint([w.as_str for w in app_wrappers])
181+
# item = next(item for item in app_wrappers if item.checksum == w3.checksum)
182+
app_wrappers.remove(w3)
183+
wr.set_game_wrapper_list("testgame", app_wrappers)
153184

154185
game_wrappers = wr.get_game_wrapper_list("testgame")
155-
pprint(game_wrappers)
186+
pprint([w.as_str for w in game_wrappers])
156187
game_wrappers = wr.get_game_wrapper_list("testgame2")
157-
pprint(game_wrappers)
188+
pprint([w.as_str for w in game_wrappers])
158189

159-
for i, tool in enumerate(steam.find_tools()):
160-
wt = Wrapper(command=tool.command(), name=tool.name, wtype=WrapperType.COMPAT_TOOL)
161-
wr.set_game_wrapper_list(f"compat_game_{i}", [wt])
162-
print(wt.as_str)
190+
# for i, tool in enumerate(steam.find_tools()):
191+
# wt = Wrapper(command=tool.command(), name=tool.name, wtype=WrapperType.COMPAT_TOOL)
192+
# wr.set_game_wrapper_list(f"compat_game_{i}", [wt])
193+
# print(wt.as_str)
163194

164195
for wrp in wr.user_wrappers:
165-
pprint(wrp)
196+
pprint(wrp.as_str)

0 commit comments

Comments
 (0)