mirror of
https://github.com/283375/arcaea-offline-pyside-ui.git
synced 2025-04-11 13:40:17 +00:00
146 lines
5.3 KiB
Python
146 lines
5.3 KiB
Python
from arcaea_offline.models import Chart, Score, ScoreBest
|
|
from PySide6.QtCore import QCoreApplication, QModelIndex, QSortFilterProxyModel, Qt
|
|
|
|
from .base import DbTableModel
|
|
|
|
|
|
class DbB30TableModel(DbTableModel):
|
|
IdRole = Qt.ItemDataRole.UserRole + 10
|
|
ChartRole = Qt.ItemDataRole.UserRole + 11
|
|
ScoreRole = Qt.ItemDataRole.UserRole + 12
|
|
PttRole = Qt.ItemDataRole.UserRole + 13
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.__items = []
|
|
|
|
def retranslateHeaders(self):
|
|
self._horizontalHeaders = [
|
|
# fmt: off
|
|
QCoreApplication.translate("DbB30TableModel", "horizontalHeader.id"),
|
|
QCoreApplication.translate("DbB30TableModel", "horizontalHeader.chart"),
|
|
QCoreApplication.translate("DbB30TableModel", "horizontalHeader.score"),
|
|
QCoreApplication.translate("DbB30TableModel", "horizontalHeader.potential"),
|
|
# fmt: on
|
|
]
|
|
|
|
def syncDb(self):
|
|
self.beginResetModel()
|
|
self.beginRemoveRows(QModelIndex(), 0, self.rowCount())
|
|
self.__items.clear()
|
|
self.endRemoveRows()
|
|
self.endResetModel()
|
|
|
|
with self._db.sessionmaker() as session:
|
|
results = (
|
|
session.query(ScoreBest, Chart)
|
|
.join(
|
|
Chart,
|
|
(ScoreBest.song_id == Chart.song_id)
|
|
& (ScoreBest.rating_class == Chart.rating_class),
|
|
)
|
|
.order_by(ScoreBest.potential.desc())
|
|
.limit(50)
|
|
.all()
|
|
)
|
|
|
|
self.beginInsertRows(QModelIndex(), 0, len(results) - 1)
|
|
for scoreBest, chart in results:
|
|
self.__items.append(
|
|
{
|
|
self.IdRole: scoreBest.id,
|
|
self.ChartRole: chart,
|
|
self.ScoreRole: scoreBest,
|
|
self.PttRole: scoreBest.potential,
|
|
}
|
|
)
|
|
self.endInsertRows()
|
|
|
|
def rowCount(self, *args):
|
|
return len(self.__items)
|
|
|
|
def data(self, index, role):
|
|
if index.isValid() and self.checkIndex(index):
|
|
if index.column() == 0 and role in [
|
|
Qt.ItemDataRole.DisplayRole,
|
|
self.IdRole,
|
|
]:
|
|
return self.__items[index.row()][self.IdRole]
|
|
elif index.column() == 1 and role == self.ChartRole:
|
|
return self.__items[index.row()][self.ChartRole]
|
|
elif index.column() == 2 and role in [self.ChartRole, self.ScoreRole]:
|
|
return self.__items[index.row()][role]
|
|
elif index.column() == 3:
|
|
if role == Qt.ItemDataRole.DisplayRole:
|
|
return f"{self.__items[index.row()][self.PttRole]:.3f}"
|
|
elif role == self.PttRole:
|
|
return self.__items[index.row()][self.PttRole]
|
|
return None
|
|
|
|
def setData(self, index, value, role):
|
|
return False
|
|
|
|
def flags(self, index) -> Qt.ItemFlag:
|
|
flags = super().flags(index)
|
|
flags &= ~(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEditable)
|
|
return flags
|
|
|
|
def _removeRow(self, row: int, syncDb: bool = True):
|
|
return False
|
|
|
|
def removeRow(self, row: int, parent=...):
|
|
return False
|
|
|
|
def removeRows(self, row: int, count: int, parent=...):
|
|
return False
|
|
|
|
def removeRowList(self, rowList: list[int]):
|
|
return False
|
|
|
|
|
|
class DbB30TableSortFilterProxyModel(QSortFilterProxyModel):
|
|
Sort_C2_ScoreRole = Qt.ItemDataRole.UserRole + 75
|
|
Sort_C2_TimeRole = Qt.ItemDataRole.UserRole + 76
|
|
|
|
def headerData(self, section: int, orientation: Qt.Orientation, role: int):
|
|
# always show not sorted row sequence
|
|
if (
|
|
orientation != Qt.Orientation.Vertical
|
|
or role != Qt.ItemDataRole.DisplayRole
|
|
):
|
|
return super().headerData(section, orientation, role)
|
|
return section + 1
|
|
|
|
def lessThan(self, sourceLeft: QModelIndex, sourceRight: QModelIndex) -> bool:
|
|
if sourceLeft.column() != sourceRight.column():
|
|
return
|
|
|
|
column = sourceLeft.column()
|
|
if column == 0:
|
|
return sourceLeft.data(DbB30TableModel.IdRole) < sourceRight.data(
|
|
DbB30TableModel.IdRole
|
|
)
|
|
elif column == 2:
|
|
scoreLeft = sourceLeft.data(DbB30TableModel.ScoreRole)
|
|
scoreRight = sourceRight.data(DbB30TableModel.ScoreRole)
|
|
if isinstance(scoreLeft, Score) and isinstance(scoreRight, Score):
|
|
if self.sortRole() == self.Sort_C2_ScoreRole:
|
|
return scoreLeft.score < scoreRight.score
|
|
elif self.sortRole() == self.Sort_C2_TimeRole:
|
|
if scoreLeft.date and scoreRight.date:
|
|
return scoreLeft.date < scoreRight.date
|
|
elif scoreLeft.date:
|
|
return False
|
|
else:
|
|
return True
|
|
elif column == 3:
|
|
pttLeft = sourceLeft.data(DbB30TableModel.PttRole)
|
|
pttRight = sourceRight.data(DbB30TableModel.PttRole)
|
|
if pttLeft and pttRight:
|
|
return pttLeft < pttRight
|
|
elif pttLeft:
|
|
return False
|
|
else:
|
|
return True
|
|
return super().lessThan(sourceLeft, sourceRight)
|