aboutsummaryrefslogtreecommitdiff
path: root/libs/basic_games/games/oblivion_remaster/ue4ss/model.py
blob: a3804fe731dff6589fdf68ceb4da10aa2f47d6fa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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