mirror of
https://github.com/ModOrganizer2/modorganizer-basic_games.git
synced 2026-07-27 14:07:29 -07:00
* Oblivion Remastered updates - Handle invalid JSON - Remove outdated pak sorting code - Start from 8999 for pak directories - Leaves space for early loaders - Update MagicLoader handling for more dir names --------- Co-authored-by: Jeremy Rimpo <jeremy.rimpo@servermonkey.com>
126 lines
4.2 KiB
Python
126 lines
4.2 KiB
Python
import json
|
|
from json import JSONDecodeError
|
|
from typing import Any, Iterable
|
|
|
|
from PyQt6.QtCore import (
|
|
QDir,
|
|
QFileInfo,
|
|
QMimeData,
|
|
QModelIndex,
|
|
QStringListModel,
|
|
Qt,
|
|
)
|
|
from PyQt6.QtWidgets import QWidget
|
|
|
|
import mobase
|
|
|
|
from ..constants import DEFAULT_UE4SS_MODS
|
|
|
|
|
|
class UE4SSListModel(QStringListModel):
|
|
def __init__(self, parent: QWidget | None, organizer: mobase.IOrganizer):
|
|
super().__init__(parent)
|
|
self._checked_items: set[str] = set()
|
|
self._organizer = organizer
|
|
self._init_mod_states()
|
|
|
|
def _init_mod_states(self):
|
|
profile = QDir(self._organizer.profilePath())
|
|
mods_json = QFileInfo(profile.absoluteFilePath("mods.json"))
|
|
if mods_json.exists():
|
|
with open(mods_json.absoluteFilePath(), "r") as json_file:
|
|
try:
|
|
mod_data = json.load(json_file)
|
|
except JSONDecodeError:
|
|
mod_data = DEFAULT_UE4SS_MODS
|
|
for mod in mod_data:
|
|
if mod["mod_enabled"]:
|
|
self._checked_items.add(mod["mod_name"])
|
|
|
|
def _set_mod_states(self):
|
|
profile = QDir(self._organizer.profilePath())
|
|
mods_json = QFileInfo(profile.absoluteFilePath("mods.json"))
|
|
mod_list: dict[str, bool] = {}
|
|
if mods_json.exists():
|
|
with open(mods_json.absoluteFilePath(), "r") as json_file:
|
|
try:
|
|
mod_data = json.load(json_file)
|
|
except JSONDecodeError:
|
|
mod_data = DEFAULT_UE4SS_MODS
|
|
for mod in mod_data:
|
|
mod_list[mod["mod_name"]] = mod["mod_enabled"]
|
|
for i in range(self.rowCount()):
|
|
item = self.index(i, 0)
|
|
name = self.data(item, Qt.ItemDataRole.DisplayRole)
|
|
if name in mod_list:
|
|
self.setData(
|
|
item,
|
|
True if mod_list[name] else False,
|
|
Qt.ItemDataRole.CheckStateRole,
|
|
)
|
|
else:
|
|
self.setData(item, True, Qt.ItemDataRole.CheckStateRole)
|
|
|
|
def flags(self, index: QModelIndex) -> Qt.ItemFlag:
|
|
flags = super().flags(index)
|
|
if not index.isValid():
|
|
return (
|
|
Qt.ItemFlag.ItemIsSelectable
|
|
| Qt.ItemFlag.ItemIsDragEnabled
|
|
| Qt.ItemFlag.ItemIsDropEnabled
|
|
| Qt.ItemFlag.ItemIsEnabled
|
|
)
|
|
return (
|
|
flags
|
|
| Qt.ItemFlag.ItemIsUserCheckable
|
|
| Qt.ItemFlag.ItemIsDragEnabled & Qt.ItemFlag.ItemIsEditable
|
|
)
|
|
|
|
def setData(
|
|
self, index: QModelIndex, value: Any, role: int = Qt.ItemDataRole.EditRole
|
|
) -> bool:
|
|
if not index.isValid() or role != Qt.ItemDataRole.CheckStateRole:
|
|
return False
|
|
|
|
if (
|
|
bool(value)
|
|
and self.data(index, Qt.ItemDataRole.DisplayRole) not in self._checked_items
|
|
):
|
|
self._checked_items.add(self.data(index, Qt.ItemDataRole.DisplayRole))
|
|
elif (
|
|
not bool(value)
|
|
and self.data(index, Qt.ItemDataRole.DisplayRole) in self._checked_items
|
|
):
|
|
self._checked_items.remove(self.data(index, Qt.ItemDataRole.DisplayRole))
|
|
self.dataChanged.emit(index, index, [role])
|
|
return True
|
|
|
|
def setStringList(self, strings: Iterable[str | None]):
|
|
super().setStringList(strings)
|
|
self._set_mod_states()
|
|
|
|
def data(self, index: QModelIndex, role: int = Qt.ItemDataRole.DisplayRole) -> Any:
|
|
if not index.isValid():
|
|
return None
|
|
|
|
if role == Qt.ItemDataRole.CheckStateRole:
|
|
return (
|
|
Qt.CheckState.Checked
|
|
if self.data(index, Qt.ItemDataRole.DisplayRole) in self._checked_items
|
|
else Qt.CheckState.Unchecked
|
|
)
|
|
|
|
return super().data(index, role)
|
|
|
|
def canDropMimeData(
|
|
self,
|
|
data: QMimeData | None,
|
|
action: Qt.DropAction,
|
|
row: int,
|
|
column: int,
|
|
parent: QModelIndex,
|
|
) -> bool:
|
|
if action == Qt.DropAction.MoveAction and (row != -1 or column != -1):
|
|
return True
|
|
return False
|