8 Commits

38 changed files with 2094 additions and 1132 deletions

View File

@ -6,6 +6,23 @@ from pathlib import Path
versionFile = Path("ui/resources/VERSION")
assert versionFile.exists()
versionTexts = []
projectVersionText = "arcaea-offline-pyside-ui\n"
gitDescribe = os.popen("git describe --tags --long")
gitDescribeContent = gitDescribe.read().replace("\n", "")
if gitDescribe.close() is None:
projectVersionText += f"{gitDescribeContent}"
else:
gitRevParse = os.popen("git rev-parse --short HEAD")
gitRevParseContent = gitRevParse.read().replace("\n", "")
projectVersionText += f"commit {gitRevParseContent}"
gitRevParse.close()
projectVersionText += "\n"
versionTexts.append(projectVersionText)
# detect pip
pipName = None
possiblePipNames = ["pip3", "pip"]
@ -19,7 +36,6 @@ for possiblePipName in possiblePipNames:
pipName = possiblePipName
break
versionTexts = []
# if possiblePipName:
# pipFreezeLines = os.popen(f"{possiblePipName} freeze").read().split("\n")

View File

@ -6,14 +6,89 @@
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>350</height>
<width>400</width>
<height>322</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">ScoreEditor</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>formLabel.score</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string notr="true">Clear Type</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string notr="true">ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QComboBox" name="modifierComboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="previewLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">QLabel { color: gray }</string>
</property>
<property name="text">
<string notr="true">None</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QSpinBox" name="maxRecallSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="FocusSelectAllLineEdit" name="scoreLineEdit">
<property name="inputMask">
@ -21,7 +96,51 @@
</property>
</widget>
</item>
<item row="13" column="1">
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>formLabel.date</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QCheckBox" name="warnIfIncompleteCheckBox">
<property name="text">
<string>warnIfIncomplete</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>formLabel.preview</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string notr="true">MAX RECALL</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QCheckBox" name="dateNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QLabel" name="validateLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@ -37,48 +156,8 @@
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLineEdit" name="commentLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="6" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="13" column="2">
<widget class="QPushButton" name="commitButton">
<property name="text">
<string>commitButton</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QComboBox" name="clearTypeComboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="farSpinBox">
<item row="2" column="1">
<widget class="QSpinBox" name="pureSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
@ -93,26 +172,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>formLabel.score</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="11" column="2">
<widget class="QCheckBox" name="commentNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QCheckBox" name="farNoneCheckBox">
<property name="text">
@ -120,23 +179,10 @@
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string notr="true">Clear Type</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string notr="true">FAR</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<item row="10" column="1">
<widget class="QLineEdit" name="commentLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
@ -156,73 +202,6 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="idLabel">
<property name="text">
<string>idAutoInsert</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>formLabel.date</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string notr="true">Modifier</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QCheckBox" name="maxRecallNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="10" column="2">
<widget class="QCheckBox" name="clearTypeNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string notr="true">ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string notr="true">PURE</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
@ -233,7 +212,81 @@
</property>
</widget>
</item>
<item row="12" column="2">
<widget class="QPushButton" name="commitButton">
<property name="text">
<string>commitButton</string>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QCheckBox" name="clearTypeNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string notr="true">Modifier</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QComboBox" name="clearTypeComboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="10" column="2">
<widget class="QCheckBox" name="commentNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>formLabel.comment</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="idLabel">
<property name="text">
<string>idAutoInsert</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="pureNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QCheckBox" name="modifierNoneCheckBox">
<property name="text">
<string>setNone</string>
@ -259,40 +312,13 @@
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QComboBox" name="modifierComboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QCheckBox" name="dateNoneCheckBox">
<item row="7" column="2">
<widget class="QCheckBox" name="maxRecallNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="pureNoneCheckBox">
<property name="text">
<string>setNone</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="pureSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>0</number>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
@ -303,18 +329,18 @@
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QCheckBox" name="warnIfIncompleteCheckBox">
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>warnIfIncomplete</string>
<string notr="true">FAR</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="maxRecallSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<item row="3" column="1">
<widget class="QSpinBox" name="farSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
@ -327,60 +353,18 @@
<property name="maximum">
<number>0</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_9">
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>formLabel.comment</string>
<string notr="true">PURE</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string notr="true">MAX RECALL</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>formLabel.preview</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="12" column="1">
<widget class="QLabel" name="previewLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">QLabel { color: gray }</string>
</property>
<property name="text">
<string notr="true">None</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -17,7 +17,7 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QDateTimeEdit,
QGridLayout, QLabel, QLineEdit, QPushButton,
QSizePolicy, QSpacerItem, QSpinBox, QWidget)
QSizePolicy, QSpinBox, QWidget)
from ui.implements.components.focusSelectAllLineEdit import FocusSelectAllLineEdit
@ -25,126 +25,22 @@ class Ui_ScoreEditor(object):
def setupUi(self, ScoreEditor):
if not ScoreEditor.objectName():
ScoreEditor.setObjectName(u"ScoreEditor")
ScoreEditor.resize(450, 350)
ScoreEditor.resize(400, 322)
ScoreEditor.setWindowTitle(u"ScoreEditor")
self.gridLayout = QGridLayout(ScoreEditor)
self.gridLayout.setObjectName(u"gridLayout")
self.scoreLineEdit = FocusSelectAllLineEdit(ScoreEditor)
self.scoreLineEdit.setObjectName(u"scoreLineEdit")
self.scoreLineEdit.setInputMask(u"B9'999'999;_")
self.gridLayout.addWidget(self.scoreLineEdit, 1, 1, 1, 1)
self.validateLabel = QLabel(ScoreEditor)
self.validateLabel.setObjectName(u"validateLabel")
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.validateLabel.sizePolicy().hasHeightForWidth())
self.validateLabel.setSizePolicy(sizePolicy)
self.validateLabel.setText(u"...")
self.validateLabel.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.validateLabel, 13, 1, 1, 1)
self.commentLineEdit = QLineEdit(ScoreEditor)
self.commentLineEdit.setObjectName(u"commentLineEdit")
self.commentLineEdit.setEnabled(False)
self.gridLayout.addWidget(self.commentLineEdit, 11, 1, 1, 1)
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
self.gridLayout.addItem(self.verticalSpacer, 6, 1, 1, 1)
self.commitButton = QPushButton(ScoreEditor)
self.commitButton.setObjectName(u"commitButton")
self.gridLayout.addWidget(self.commitButton, 13, 2, 1, 1)
self.clearTypeComboBox = QComboBox(ScoreEditor)
self.clearTypeComboBox.setObjectName(u"clearTypeComboBox")
self.clearTypeComboBox.setEnabled(False)
self.clearTypeComboBox.setMinimumSize(QSize(100, 0))
self.gridLayout.addWidget(self.clearTypeComboBox, 10, 1, 1, 1)
self.farSpinBox = QSpinBox(ScoreEditor)
self.farSpinBox.setObjectName(u"farSpinBox")
self.farSpinBox.setMinimumSize(QSize(100, 0))
self.farSpinBox.setMinimum(0)
self.farSpinBox.setMaximum(0)
self.gridLayout.addWidget(self.farSpinBox, 3, 1, 1, 1)
self.label = QLabel(ScoreEditor)
self.label.setObjectName(u"label")
self.label.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
self.commentNoneCheckBox = QCheckBox(ScoreEditor)
self.commentNoneCheckBox.setObjectName(u"commentNoneCheckBox")
self.commentNoneCheckBox.setChecked(True)
self.gridLayout.addWidget(self.commentNoneCheckBox, 11, 2, 1, 1)
self.farNoneCheckBox = QCheckBox(ScoreEditor)
self.farNoneCheckBox.setObjectName(u"farNoneCheckBox")
self.gridLayout.addWidget(self.farNoneCheckBox, 3, 2, 1, 1)
self.label_8 = QLabel(ScoreEditor)
self.label_8.setObjectName(u"label_8")
self.label_8.setText(u"Clear Type")
self.label_8.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_8, 10, 0, 1, 1)
self.label_3 = QLabel(ScoreEditor)
self.label_3.setObjectName(u"label_3")
self.label_3.setText(u"FAR")
self.label_3.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_3, 3, 0, 1, 1)
self.lostSpinBox = QSpinBox(ScoreEditor)
self.lostSpinBox.setObjectName(u"lostSpinBox")
self.lostSpinBox.setMinimumSize(QSize(100, 0))
self.lostSpinBox.setMinimum(0)
self.lostSpinBox.setMaximum(0)
self.gridLayout.addWidget(self.lostSpinBox, 4, 1, 1, 1)
self.idLabel = QLabel(ScoreEditor)
self.idLabel.setObjectName(u"idLabel")
self.gridLayout.addWidget(self.idLabel, 0, 1, 1, 1)
self.label_5 = QLabel(ScoreEditor)
self.label_5.setObjectName(u"label_5")
self.label_5.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_5, 5, 0, 1, 1)
self.label_7 = QLabel(ScoreEditor)
self.label_7.setObjectName(u"label_7")
self.label_7.setText(u"Modifier")
self.label_7.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_7, 9, 0, 1, 1)
self.maxRecallNoneCheckBox = QCheckBox(ScoreEditor)
self.maxRecallNoneCheckBox.setObjectName(u"maxRecallNoneCheckBox")
self.maxRecallNoneCheckBox.setChecked(True)
self.gridLayout.addWidget(self.maxRecallNoneCheckBox, 8, 2, 1, 1)
self.clearTypeNoneCheckBox = QCheckBox(ScoreEditor)
self.clearTypeNoneCheckBox.setObjectName(u"clearTypeNoneCheckBox")
self.clearTypeNoneCheckBox.setChecked(True)
self.gridLayout.addWidget(self.clearTypeNoneCheckBox, 10, 2, 1, 1)
self.gridLayout.addWidget(self.label_8, 9, 0, 1, 1)
self.label_10 = QLabel(ScoreEditor)
self.label_10.setObjectName(u"label_10")
@ -153,71 +49,23 @@ class Ui_ScoreEditor(object):
self.gridLayout.addWidget(self.label_10, 0, 0, 1, 1)
self.label_2 = QLabel(ScoreEditor)
self.label_2.setObjectName(u"label_2")
self.label_2.setText(u"PURE")
self.label_2.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.label_4 = QLabel(ScoreEditor)
self.label_4.setObjectName(u"label_4")
self.label_4.setText(u"LOST")
self.label_4.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1)
self.modifierNoneCheckBox = QCheckBox(ScoreEditor)
self.modifierNoneCheckBox.setObjectName(u"modifierNoneCheckBox")
self.modifierNoneCheckBox.setChecked(True)
self.gridLayout.addWidget(self.modifierNoneCheckBox, 9, 2, 1, 1)
self.dateTimeEdit = QDateTimeEdit(ScoreEditor)
self.dateTimeEdit.setObjectName(u"dateTimeEdit")
sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
sizePolicy1.setHorizontalStretch(0)
sizePolicy1.setVerticalStretch(0)
sizePolicy1.setHeightForWidth(self.dateTimeEdit.sizePolicy().hasHeightForWidth())
self.dateTimeEdit.setSizePolicy(sizePolicy1)
self.dateTimeEdit.setDisplayFormat(u"yyyy/MM/dd HH:mm:ss")
self.dateTimeEdit.setCalendarPopup(False)
self.gridLayout.addWidget(self.dateTimeEdit, 5, 1, 1, 1)
self.modifierComboBox = QComboBox(ScoreEditor)
self.modifierComboBox.setObjectName(u"modifierComboBox")
self.modifierComboBox.setEnabled(False)
self.gridLayout.addWidget(self.modifierComboBox, 9, 1, 1, 1)
self.gridLayout.addWidget(self.modifierComboBox, 8, 1, 1, 1)
self.dateNoneCheckBox = QCheckBox(ScoreEditor)
self.dateNoneCheckBox.setObjectName(u"dateNoneCheckBox")
self.previewLabel = QLabel(ScoreEditor)
self.previewLabel.setObjectName(u"previewLabel")
sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.previewLabel.sizePolicy().hasHeightForWidth())
self.previewLabel.setSizePolicy(sizePolicy)
self.previewLabel.setStyleSheet(u"QLabel { color: gray }")
self.previewLabel.setText(u"None")
self.gridLayout.addWidget(self.dateNoneCheckBox, 5, 2, 1, 1)
self.pureNoneCheckBox = QCheckBox(ScoreEditor)
self.pureNoneCheckBox.setObjectName(u"pureNoneCheckBox")
self.gridLayout.addWidget(self.pureNoneCheckBox, 2, 2, 1, 1)
self.pureSpinBox = QSpinBox(ScoreEditor)
self.pureSpinBox.setObjectName(u"pureSpinBox")
self.pureSpinBox.setMinimumSize(QSize(100, 0))
self.pureSpinBox.setMinimum(0)
self.pureSpinBox.setMaximum(0)
self.gridLayout.addWidget(self.pureSpinBox, 2, 1, 1, 1)
self.lostNoneCheckBox = QCheckBox(ScoreEditor)
self.lostNoneCheckBox.setObjectName(u"lostNoneCheckBox")
self.gridLayout.addWidget(self.lostNoneCheckBox, 4, 2, 1, 1)
self.warnIfIncompleteCheckBox = QCheckBox(ScoreEditor)
self.warnIfIncompleteCheckBox.setObjectName(u"warnIfIncompleteCheckBox")
self.gridLayout.addWidget(self.warnIfIncompleteCheckBox, 13, 0, 1, 1)
self.gridLayout.addWidget(self.previewLabel, 11, 1, 1, 1)
self.maxRecallSpinBox = QSpinBox(ScoreEditor)
self.maxRecallSpinBox.setObjectName(u"maxRecallSpinBox")
@ -227,39 +75,186 @@ class Ui_ScoreEditor(object):
self.maxRecallSpinBox.setMaximum(0)
self.maxRecallSpinBox.setValue(0)
self.gridLayout.addWidget(self.maxRecallSpinBox, 8, 1, 1, 1)
self.gridLayout.addWidget(self.maxRecallSpinBox, 7, 1, 1, 1)
self.label_9 = QLabel(ScoreEditor)
self.label_9.setObjectName(u"label_9")
self.label_9.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.scoreLineEdit = FocusSelectAllLineEdit(ScoreEditor)
self.scoreLineEdit.setObjectName(u"scoreLineEdit")
self.scoreLineEdit.setInputMask(u"B9'999'999;_")
self.gridLayout.addWidget(self.label_9, 11, 0, 1, 1)
self.gridLayout.addWidget(self.scoreLineEdit, 1, 1, 1, 1)
self.label_5 = QLabel(ScoreEditor)
self.label_5.setObjectName(u"label_5")
self.label_5.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_5, 5, 0, 1, 1)
self.warnIfIncompleteCheckBox = QCheckBox(ScoreEditor)
self.warnIfIncompleteCheckBox.setObjectName(u"warnIfIncompleteCheckBox")
self.gridLayout.addWidget(self.warnIfIncompleteCheckBox, 12, 0, 1, 1)
self.label_11 = QLabel(ScoreEditor)
self.label_11.setObjectName(u"label_11")
self.label_11.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_11, 11, 0, 1, 1)
self.label_6 = QLabel(ScoreEditor)
self.label_6.setObjectName(u"label_6")
self.label_6.setText(u"MAX RECALL")
self.label_6.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_6, 8, 0, 1, 1)
self.gridLayout.addWidget(self.label_6, 7, 0, 1, 1)
self.label_11 = QLabel(ScoreEditor)
self.label_11.setObjectName(u"label_11")
self.label_11.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.dateNoneCheckBox = QCheckBox(ScoreEditor)
self.dateNoneCheckBox.setObjectName(u"dateNoneCheckBox")
self.gridLayout.addWidget(self.label_11, 12, 0, 1, 1)
self.gridLayout.addWidget(self.dateNoneCheckBox, 5, 2, 1, 1)
self.previewLabel = QLabel(ScoreEditor)
self.previewLabel.setObjectName(u"previewLabel")
sizePolicy2 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
self.validateLabel = QLabel(ScoreEditor)
self.validateLabel.setObjectName(u"validateLabel")
sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
sizePolicy1.setHorizontalStretch(0)
sizePolicy1.setVerticalStretch(0)
sizePolicy1.setHeightForWidth(self.validateLabel.sizePolicy().hasHeightForWidth())
self.validateLabel.setSizePolicy(sizePolicy1)
self.validateLabel.setText(u"...")
self.validateLabel.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.validateLabel, 12, 1, 1, 1)
self.pureSpinBox = QSpinBox(ScoreEditor)
self.pureSpinBox.setObjectName(u"pureSpinBox")
self.pureSpinBox.setMinimumSize(QSize(100, 0))
self.pureSpinBox.setMinimum(0)
self.pureSpinBox.setMaximum(0)
self.gridLayout.addWidget(self.pureSpinBox, 2, 1, 1, 1)
self.farNoneCheckBox = QCheckBox(ScoreEditor)
self.farNoneCheckBox.setObjectName(u"farNoneCheckBox")
self.gridLayout.addWidget(self.farNoneCheckBox, 3, 2, 1, 1)
self.commentLineEdit = QLineEdit(ScoreEditor)
self.commentLineEdit.setObjectName(u"commentLineEdit")
self.commentLineEdit.setEnabled(False)
self.gridLayout.addWidget(self.commentLineEdit, 10, 1, 1, 1)
self.lostSpinBox = QSpinBox(ScoreEditor)
self.lostSpinBox.setObjectName(u"lostSpinBox")
self.lostSpinBox.setMinimumSize(QSize(100, 0))
self.lostSpinBox.setMinimum(0)
self.lostSpinBox.setMaximum(0)
self.gridLayout.addWidget(self.lostSpinBox, 4, 1, 1, 1)
self.label_4 = QLabel(ScoreEditor)
self.label_4.setObjectName(u"label_4")
self.label_4.setText(u"LOST")
self.label_4.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1)
self.commitButton = QPushButton(ScoreEditor)
self.commitButton.setObjectName(u"commitButton")
self.gridLayout.addWidget(self.commitButton, 12, 2, 1, 1)
self.clearTypeNoneCheckBox = QCheckBox(ScoreEditor)
self.clearTypeNoneCheckBox.setObjectName(u"clearTypeNoneCheckBox")
self.clearTypeNoneCheckBox.setChecked(True)
self.gridLayout.addWidget(self.clearTypeNoneCheckBox, 9, 2, 1, 1)
self.label_7 = QLabel(ScoreEditor)
self.label_7.setObjectName(u"label_7")
self.label_7.setText(u"Modifier")
self.label_7.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_7, 8, 0, 1, 1)
self.clearTypeComboBox = QComboBox(ScoreEditor)
self.clearTypeComboBox.setObjectName(u"clearTypeComboBox")
self.clearTypeComboBox.setEnabled(False)
self.clearTypeComboBox.setMinimumSize(QSize(100, 0))
self.gridLayout.addWidget(self.clearTypeComboBox, 9, 1, 1, 1)
self.commentNoneCheckBox = QCheckBox(ScoreEditor)
self.commentNoneCheckBox.setObjectName(u"commentNoneCheckBox")
self.commentNoneCheckBox.setChecked(True)
self.gridLayout.addWidget(self.commentNoneCheckBox, 10, 2, 1, 1)
self.label_9 = QLabel(ScoreEditor)
self.label_9.setObjectName(u"label_9")
self.label_9.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_9, 10, 0, 1, 1)
self.idLabel = QLabel(ScoreEditor)
self.idLabel.setObjectName(u"idLabel")
self.gridLayout.addWidget(self.idLabel, 0, 1, 1, 1)
self.pureNoneCheckBox = QCheckBox(ScoreEditor)
self.pureNoneCheckBox.setObjectName(u"pureNoneCheckBox")
self.gridLayout.addWidget(self.pureNoneCheckBox, 2, 2, 1, 1)
self.modifierNoneCheckBox = QCheckBox(ScoreEditor)
self.modifierNoneCheckBox.setObjectName(u"modifierNoneCheckBox")
self.modifierNoneCheckBox.setChecked(True)
self.gridLayout.addWidget(self.modifierNoneCheckBox, 8, 2, 1, 1)
self.dateTimeEdit = QDateTimeEdit(ScoreEditor)
self.dateTimeEdit.setObjectName(u"dateTimeEdit")
sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
sizePolicy2.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0)
sizePolicy2.setHeightForWidth(self.previewLabel.sizePolicy().hasHeightForWidth())
self.previewLabel.setSizePolicy(sizePolicy2)
self.previewLabel.setStyleSheet(u"QLabel { color: gray }")
self.previewLabel.setText(u"None")
self.previewLabel.setWordWrap(True)
sizePolicy2.setHeightForWidth(self.dateTimeEdit.sizePolicy().hasHeightForWidth())
self.dateTimeEdit.setSizePolicy(sizePolicy2)
self.dateTimeEdit.setDisplayFormat(u"yyyy/MM/dd HH:mm:ss")
self.dateTimeEdit.setCalendarPopup(False)
self.gridLayout.addWidget(self.previewLabel, 12, 1, 1, 1)
self.gridLayout.addWidget(self.dateTimeEdit, 5, 1, 1, 1)
self.maxRecallNoneCheckBox = QCheckBox(ScoreEditor)
self.maxRecallNoneCheckBox.setObjectName(u"maxRecallNoneCheckBox")
self.maxRecallNoneCheckBox.setChecked(True)
self.gridLayout.addWidget(self.maxRecallNoneCheckBox, 7, 2, 1, 1)
self.lostNoneCheckBox = QCheckBox(ScoreEditor)
self.lostNoneCheckBox.setObjectName(u"lostNoneCheckBox")
self.gridLayout.addWidget(self.lostNoneCheckBox, 4, 2, 1, 1)
self.label_3 = QLabel(ScoreEditor)
self.label_3.setObjectName(u"label_3")
self.label_3.setText(u"FAR")
self.label_3.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_3, 3, 0, 1, 1)
self.farSpinBox = QSpinBox(ScoreEditor)
self.farSpinBox.setObjectName(u"farSpinBox")
self.farSpinBox.setMinimumSize(QSize(100, 0))
self.farSpinBox.setMinimum(0)
self.farSpinBox.setMaximum(0)
self.gridLayout.addWidget(self.farSpinBox, 3, 1, 1, 1)
self.label_2 = QLabel(ScoreEditor)
self.label_2.setObjectName(u"label_2")
self.label_2.setText(u"PURE")
self.label_2.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
QWidget.setTabOrder(self.scoreLineEdit, self.pureSpinBox)
QWidget.setTabOrder(self.pureSpinBox, self.pureNoneCheckBox)
@ -293,21 +288,21 @@ class Ui_ScoreEditor(object):
# setupUi
def retranslateUi(self, ScoreEditor):
self.commitButton.setText(QCoreApplication.translate("ScoreEditor", u"commitButton", None))
self.label.setText(QCoreApplication.translate("ScoreEditor", u"formLabel.score", None))
self.commentNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.farNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.idLabel.setText(QCoreApplication.translate("ScoreEditor", u"idAutoInsert", None))
self.label_5.setText(QCoreApplication.translate("ScoreEditor", u"formLabel.date", None))
self.maxRecallNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.clearTypeNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.modifierNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.dateNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.pureNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.lostNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.warnIfIncompleteCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"warnIfIncomplete", None))
self.label_9.setText(QCoreApplication.translate("ScoreEditor", u"formLabel.comment", None))
self.label_11.setText(QCoreApplication.translate("ScoreEditor", u"formLabel.preview", None))
self.dateNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.farNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.commitButton.setText(QCoreApplication.translate("ScoreEditor", u"commitButton", None))
self.clearTypeNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.commentNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.label_9.setText(QCoreApplication.translate("ScoreEditor", u"formLabel.comment", None))
self.idLabel.setText(QCoreApplication.translate("ScoreEditor", u"idAutoInsert", None))
self.pureNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.modifierNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.maxRecallNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
self.lostNoneCheckBox.setText(QCoreApplication.translate("ScoreEditor", u"setNone", None))
pass
# retranslateUi

View File

@ -20,7 +20,7 @@
<item>
<widget class="QLabel" name="databaseDescribeLabel">
<property name="text">
<string extracomment="This database now have {} packs, {} songs, {} difficulties, {} chart info ({} complete) and {} scores.">databaseDescribeLabel {} {} {} {} {} {}</string>
<string notr="true" extracomment="This database now have {} packs, {} songs, {} difficulties, {} chart info ({} complete) and {} scores.">...</string>
</property>
</widget>
</item>

View File

@ -33,6 +33,7 @@ class Ui_TabOverview(object):
self.databaseDescribeLabel = QLabel(TabOverview)
self.databaseDescribeLabel.setObjectName(u"databaseDescribeLabel")
self.databaseDescribeLabel.setText(u"...")
self.verticalLayout.addWidget(self.databaseDescribeLabel)
@ -108,7 +109,6 @@ class Ui_TabOverview(object):
# setupUi
def retranslateUi(self, TabOverview):
self.databaseDescribeLabel.setText(QCoreApplication.translate("TabOverview", u"databaseDescribeLabel {} {} {} {} {} {}", None))
pass
# retranslateUi

View File

@ -0,0 +1,297 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TabTools_ChartRecommend</class>
<widget class="QWidget" name="TabTools_ChartRecommend">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>668</width>
<height>546</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">TabTools_ChartRecommend</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>constantRangeFromPlayRating</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QDoubleSpinBox" name="rangeFromPlayRating_playRatingSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string notr="true">AA</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string notr="true">EX</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string notr="true">EX+</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="rangeFromPlayRating_ExPlusLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="rangeFromPlayRating_ExLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="rangeFromPlayRating_AaLabel">
<property name="text">
<string notr="true">...</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>chartsByConstant</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QDoubleSpinBox" name="chartsByConstant_constantSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="chartsByConstant_numLabel">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="chartsByConstant_refreshButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>refreshButton</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="chartsByConstant_gridLayout"/>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>chartsRecommendFromPlayRating</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QDoubleSpinBox" name="chartsRecommendFromPlayRating_playRatingSpinBox">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string notr="true">±</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="chartsRecommendFromPlayRating_boundsSpinBox">
<property name="maximum">
<double>2.000000000000000</double>
</property>
<property name="singleStep">
<double>0.010000000000000</double>
</property>
<property name="value">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="chartsRecommendFromPlayRating_numLabel">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="chartsRecommendFromPlayRating_refreshButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>refreshButton</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="chartsRecommendFromPlayRating_gridLayout"/>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,219 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'tabTools_ChartRecommend.ui'
##
## Created by: Qt User Interface Compiler version 6.5.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QDoubleSpinBox, QGridLayout, QGroupBox,
QHBoxLayout, QLabel, QPushButton, QSizePolicy,
QSpacerItem, QVBoxLayout, QWidget)
class Ui_TabTools_ChartRecommend(object):
def setupUi(self, TabTools_ChartRecommend):
if not TabTools_ChartRecommend.objectName():
TabTools_ChartRecommend.setObjectName(u"TabTools_ChartRecommend")
TabTools_ChartRecommend.resize(668, 546)
TabTools_ChartRecommend.setWindowTitle(u"TabTools_ChartRecommend")
self.verticalLayout = QVBoxLayout(TabTools_ChartRecommend)
self.verticalLayout.setObjectName(u"verticalLayout")
self.groupBox = QGroupBox(TabTools_ChartRecommend)
self.groupBox.setObjectName(u"groupBox")
self.verticalLayout_2 = QVBoxLayout(self.groupBox)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.rangeFromPlayRating_playRatingSpinBox = QDoubleSpinBox(self.groupBox)
self.rangeFromPlayRating_playRatingSpinBox.setObjectName(u"rangeFromPlayRating_playRatingSpinBox")
self.rangeFromPlayRating_playRatingSpinBox.setMinimumSize(QSize(100, 0))
self.rangeFromPlayRating_playRatingSpinBox.setMaximumSize(QSize(100, 16777215))
self.rangeFromPlayRating_playRatingSpinBox.setDecimals(3)
self.rangeFromPlayRating_playRatingSpinBox.setMaximum(100.000000000000000)
self.rangeFromPlayRating_playRatingSpinBox.setSingleStep(0.100000000000000)
self.verticalLayout_2.addWidget(self.rangeFromPlayRating_playRatingSpinBox)
self.gridLayout_3 = QGridLayout()
self.gridLayout_3.setObjectName(u"gridLayout_3")
self.label_3 = QLabel(self.groupBox)
self.label_3.setObjectName(u"label_3")
self.label_3.setText(u"AA")
self.label_3.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label_3, 0, 2, 1, 1)
self.label_2 = QLabel(self.groupBox)
self.label_2.setObjectName(u"label_2")
self.label_2.setText(u"EX")
self.label_2.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label_2, 0, 1, 1, 1)
self.label = QLabel(self.groupBox)
self.label.setObjectName(u"label")
self.label.setText(u"EX+")
self.label.setAlignment(Qt.AlignBottom|Qt.AlignLeading|Qt.AlignLeft)
self.gridLayout_3.addWidget(self.label, 0, 0, 1, 1)
self.rangeFromPlayRating_ExPlusLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ExPlusLabel.setObjectName(u"rangeFromPlayRating_ExPlusLabel")
self.rangeFromPlayRating_ExPlusLabel.setText(u"...")
self.rangeFromPlayRating_ExPlusLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_ExPlusLabel, 1, 0, 1, 1)
self.rangeFromPlayRating_ExLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_ExLabel.setObjectName(u"rangeFromPlayRating_ExLabel")
self.rangeFromPlayRating_ExLabel.setText(u"...")
self.rangeFromPlayRating_ExLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_ExLabel, 1, 1, 1, 1)
self.rangeFromPlayRating_AaLabel = QLabel(self.groupBox)
self.rangeFromPlayRating_AaLabel.setObjectName(u"rangeFromPlayRating_AaLabel")
self.rangeFromPlayRating_AaLabel.setText(u"...")
self.rangeFromPlayRating_AaLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
self.gridLayout_3.addWidget(self.rangeFromPlayRating_AaLabel, 1, 2, 1, 1)
self.verticalLayout_2.addLayout(self.gridLayout_3)
self.verticalLayout.addWidget(self.groupBox)
self.groupBox_2 = QGroupBox(TabTools_ChartRecommend)
self.groupBox_2.setObjectName(u"groupBox_2")
self.verticalLayout_3 = QVBoxLayout(self.groupBox_2)
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
self.horizontalLayout_3 = QHBoxLayout()
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.chartsByConstant_constantSpinBox = QDoubleSpinBox(self.groupBox_2)
self.chartsByConstant_constantSpinBox.setObjectName(u"chartsByConstant_constantSpinBox")
self.chartsByConstant_constantSpinBox.setMinimumSize(QSize(100, 0))
self.chartsByConstant_constantSpinBox.setMaximumSize(QSize(100, 16777215))
self.chartsByConstant_constantSpinBox.setDecimals(1)
self.chartsByConstant_constantSpinBox.setMaximum(100.000000000000000)
self.chartsByConstant_constantSpinBox.setSingleStep(0.100000000000000)
self.horizontalLayout_3.addWidget(self.chartsByConstant_constantSpinBox)
self.chartsByConstant_numLabel = QLabel(self.groupBox_2)
self.chartsByConstant_numLabel.setObjectName(u"chartsByConstant_numLabel")
self.chartsByConstant_numLabel.setText(u"...")
self.horizontalLayout_3.addWidget(self.chartsByConstant_numLabel)
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalLayout_3.addItem(self.horizontalSpacer)
self.chartsByConstant_refreshButton = QPushButton(self.groupBox_2)
self.chartsByConstant_refreshButton.setObjectName(u"chartsByConstant_refreshButton")
self.chartsByConstant_refreshButton.setEnabled(False)
self.horizontalLayout_3.addWidget(self.chartsByConstant_refreshButton)
self.verticalLayout_3.addLayout(self.horizontalLayout_3)
self.widget = QWidget(self.groupBox_2)
self.widget.setObjectName(u"widget")
sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
self.widget.setSizePolicy(sizePolicy)
self.chartsByConstant_gridLayout = QGridLayout(self.widget)
self.chartsByConstant_gridLayout.setObjectName(u"chartsByConstant_gridLayout")
self.verticalLayout_3.addWidget(self.widget)
self.verticalLayout.addWidget(self.groupBox_2)
self.groupBox_3 = QGroupBox(TabTools_ChartRecommend)
self.groupBox_3.setObjectName(u"groupBox_3")
self.verticalLayout_4 = QVBoxLayout(self.groupBox_3)
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
self.horizontalLayout_2 = QHBoxLayout()
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.chartsRecommendFromPlayRating_playRatingSpinBox = QDoubleSpinBox(self.groupBox_3)
self.chartsRecommendFromPlayRating_playRatingSpinBox.setObjectName(u"chartsRecommendFromPlayRating_playRatingSpinBox")
self.chartsRecommendFromPlayRating_playRatingSpinBox.setMinimumSize(QSize(100, 0))
self.chartsRecommendFromPlayRating_playRatingSpinBox.setMaximumSize(QSize(100, 16777215))
self.chartsRecommendFromPlayRating_playRatingSpinBox.setDecimals(3)
self.chartsRecommendFromPlayRating_playRatingSpinBox.setMaximum(100.000000000000000)
self.chartsRecommendFromPlayRating_playRatingSpinBox.setSingleStep(0.100000000000000)
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_playRatingSpinBox)
self.label_4 = QLabel(self.groupBox_3)
self.label_4.setObjectName(u"label_4")
self.label_4.setText(u"\u00b1")
self.horizontalLayout_2.addWidget(self.label_4)
self.chartsRecommendFromPlayRating_boundsSpinBox = QDoubleSpinBox(self.groupBox_3)
self.chartsRecommendFromPlayRating_boundsSpinBox.setObjectName(u"chartsRecommendFromPlayRating_boundsSpinBox")
self.chartsRecommendFromPlayRating_boundsSpinBox.setMaximum(2.000000000000000)
self.chartsRecommendFromPlayRating_boundsSpinBox.setSingleStep(0.010000000000000)
self.chartsRecommendFromPlayRating_boundsSpinBox.setValue(0.100000000000000)
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_boundsSpinBox)
self.chartsRecommendFromPlayRating_numLabel = QLabel(self.groupBox_3)
self.chartsRecommendFromPlayRating_numLabel.setObjectName(u"chartsRecommendFromPlayRating_numLabel")
self.chartsRecommendFromPlayRating_numLabel.setText(u"...")
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_numLabel)
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(self.horizontalSpacer_2)
self.chartsRecommendFromPlayRating_refreshButton = QPushButton(self.groupBox_3)
self.chartsRecommendFromPlayRating_refreshButton.setObjectName(u"chartsRecommendFromPlayRating_refreshButton")
self.chartsRecommendFromPlayRating_refreshButton.setEnabled(False)
self.horizontalLayout_2.addWidget(self.chartsRecommendFromPlayRating_refreshButton)
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
self.widget_2 = QWidget(self.groupBox_3)
self.widget_2.setObjectName(u"widget_2")
sizePolicy.setHeightForWidth(self.widget_2.sizePolicy().hasHeightForWidth())
self.widget_2.setSizePolicy(sizePolicy)
self.chartsRecommendFromPlayRating_gridLayout = QGridLayout(self.widget_2)
self.chartsRecommendFromPlayRating_gridLayout.setObjectName(u"chartsRecommendFromPlayRating_gridLayout")
self.verticalLayout_4.addWidget(self.widget_2)
self.verticalLayout.addWidget(self.groupBox_3)
self.retranslateUi(TabTools_ChartRecommend)
QMetaObject.connectSlotsByName(TabTools_ChartRecommend)
# setupUi
def retranslateUi(self, TabTools_ChartRecommend):
self.groupBox.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"constantRangeFromPlayRating", None))
self.groupBox_2.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"chartsByConstant", None))
self.chartsByConstant_refreshButton.setText(QCoreApplication.translate("TabTools_ChartRecommend", u"refreshButton", None))
self.groupBox_3.setTitle(QCoreApplication.translate("TabTools_ChartRecommend", u"chartsRecommendFromPlayRating", None))
self.chartsRecommendFromPlayRating_refreshButton.setText(QCoreApplication.translate("TabTools_ChartRecommend", u"refreshButton", None))
pass
# retranslateUi

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>665</width>
<height>570</height>
<height>574</height>
</rect>
</property>
<property name="windowTitle">
@ -689,6 +689,66 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>playRatingCalculate</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLineEdit" name="playRatingCalculateScoreLineEdit">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="inputMask">
<string notr="true">B9'999'999;_</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string notr="true">&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="playRatingCalculateResultLabel">
<property name="font">
<font>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,11 @@
<string>tab.stepCalculator</string>
</attribute>
</widget>
<widget class="TabTools_ChartRecommend" name="tab_4">
<attribute name="title">
<string>tab.chartRecommend</string>
</attribute>
</widget>
<widget class="TabTools_Andreal" name="tab_3">
<attribute name="title">
<string>tab.andreal</string>
@ -57,6 +62,12 @@
<header>ui.implements.tabs.tabTools.tabTools_Andreal</header>
<container>1</container>
</customwidget>
<customwidget>
<class>TabTools_ChartRecommend</class>
<extends>QWidget</extends>
<header>ui.implements.tabs.tabTools.tabTools_ChartRecommend</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -19,6 +19,7 @@ from PySide6.QtWidgets import (QApplication, QSizePolicy, QTabWidget, QVBoxLayou
QWidget)
from ui.implements.tabs.tabTools.tabTools_Andreal import TabTools_Andreal
from ui.implements.tabs.tabTools.tabTools_ChartRecommend import TabTools_ChartRecommend
from ui.implements.tabs.tabTools.tabTools_InfoLookup import TabTools_InfoLookup
from ui.implements.tabs.tabTools.tabTools_StepCalculator import TabTools_StepCalculator
@ -38,6 +39,9 @@ class Ui_TabToolsEntry(object):
self.tab_2 = TabTools_StepCalculator()
self.tab_2.setObjectName(u"tab_2")
self.tabWidget.addTab(self.tab_2, "")
self.tab_4 = TabTools_ChartRecommend()
self.tab_4.setObjectName(u"tab_4")
self.tabWidget.addTab(self.tab_4, "")
self.tab_3 = TabTools_Andreal()
self.tab_3.setObjectName(u"tab_3")
self.tabWidget.addTab(self.tab_3, "")
@ -56,6 +60,7 @@ class Ui_TabToolsEntry(object):
def retranslateUi(self, TabToolsEntry):
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("TabToolsEntry", u"tab.infoLookup", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("TabToolsEntry", u"tab.stepCalculator", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), QCoreApplication.translate("TabToolsEntry", u"tab.chartRecommend", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("TabToolsEntry", u"tab.andreal", None))
pass
# retranslateUi

View File

@ -263,7 +263,13 @@ class OcrQueueModel(QAbstractListModel):
index = self.index(row, 0)
chart = index.data(self.ChartRole)
score = index.data(self.ScoreRole)
if isinstance(chart, Chart) and isinstance(score, Score):
if (
isinstance(chart, Chart)
and isinstance(score, Score)
and chart.notes
and score.pure
and score.far
):
scoreRange = calculate_score_range(chart.notes, score.pure, score.far)
scoreValidateOk = scoreRange[0] <= score.score <= scoreRange[1]
self.setData(index, scoreValidateOk, self.ScoreValidateOkRole)

View File

@ -93,13 +93,18 @@ class ChartDelegate(TextSegmentDelegate):
[{self.TextRole: "Chart Invalid", self.ColorRole: QColor("#ff0000")}]
]
chartConstantString = (
f"{chart.constant / 10:.1f}"
if chart.constant is not None and chart.constant > 0
else "?"
)
return [
[
{self.TextRole: f"{chart.title}"},
],
[
{
self.TextRole: f"{rating_class_to_text(chart.rating_class)} {chart.constant / 10:.1f}",
self.TextRole: f"{rating_class_to_text(chart.rating_class)} {chartConstantString}",
self.ColorRole: self.RatingClassColors[chart.rating_class],
},
],

View File

@ -96,7 +96,13 @@ class ScoreDelegate(TextSegmentDelegate):
score = self.getScore(index)
chart = self.getChart(index)
if isinstance(score, Score) and isinstance(chart, Chart):
if (
isinstance(score, Score)
and isinstance(chart, Chart)
and chart.notes is not None
and score.pure is not None
and score.far is not None
):
scoreRange = calculate_score_range(chart.notes, score.pure, score.far)
return scoreRange[0] <= score.score <= scoreRange[1]

View File

@ -29,12 +29,26 @@ class DbScoreTableModel(DbTableModel):
def syncDb(self):
newScores = self._db.get_scores()
newScores = sorted(newScores, key=lambda x: x.id)
newCharts = [
self._db.get_chart(score.song_id, score.rating_class) for score in newScores
]
newCharts = []
for score in newScores:
dbChart = self._db.get_chart(score.song_id, score.rating_class)
newCharts.append(
dbChart
if isinstance(dbChart, Chart)
else Chart(
song_id=score.song_id,
rating_class=score.rating_class,
title=score.song_id,
set="unknown",
)
)
newPtts = []
for chart, score in zip(newCharts, newScores):
if isinstance(chart, Chart) and isinstance(score, Score):
if (
isinstance(chart, Chart)
and chart.constant is not None
and isinstance(score, Score)
):
newPtts.append(calculate_play_rating(chart.constant / 10, score.score))
else:
newPtts.append(None)
@ -103,10 +117,11 @@ class DbScoreTableModel(DbTableModel):
elif index.column() == 2 and role in [self.ChartRole, self.ScoreRole]:
return self.__items[index.row()][role]
elif index.column() == 3:
potential = self.__items[index.row()][self.PttRole]
if role == Qt.ItemDataRole.DisplayRole:
return f"{self.__items[index.row()][self.PttRole]:.3f}"
return f"{potential:.3f}" if potential is not None else "-"
elif role == self.PttRole:
return self.__items[index.row()][self.PttRole]
return potential
return None
def setData(self, index, value, role):
@ -165,30 +180,35 @@ class DbScoreTableSortFilterProxyModel(QSortFilterProxyModel):
Sort_C2_ScoreRole = Qt.ItemDataRole.UserRole + 75
Sort_C2_TimeRole = Qt.ItemDataRole.UserRole + 76
def lessThan(self, source_left, source_right) -> bool:
if source_left.column() != source_right.column():
def lessThan(self, sourceLeft, sourceRight) -> bool:
if sourceLeft.column() != sourceRight.column():
return
column = source_left.column()
column = sourceLeft.column()
if column == 0:
return source_left.data(DbScoreTableModel.IdRole) < source_right.data(
return sourceLeft.data(DbScoreTableModel.IdRole) < sourceRight.data(
DbScoreTableModel.IdRole
)
elif column == 2:
score_left = source_left.data(DbScoreTableModel.ScoreRole)
score_right = source_right.data(DbScoreTableModel.ScoreRole)
if isinstance(score_left, Score) and isinstance(score_right, Score):
scoreLeft = sourceLeft.data(DbScoreTableModel.ScoreRole)
scoreRight = sourceRight.data(DbScoreTableModel.ScoreRole)
if isinstance(scoreLeft, Score) and isinstance(scoreRight, Score):
if self.sortRole() == self.Sort_C2_ScoreRole:
return score_left.score < score_right.score
return scoreLeft.score < scoreRight.score
elif self.sortRole() == self.Sort_C2_TimeRole:
if score_left.date and score_right.date:
return score_left.date < score_right.date
elif score_left.date:
if scoreLeft.date and scoreRight.date:
return scoreLeft.date < scoreRight.date
elif scoreLeft.date:
return False
else:
return True
elif column == 3:
return source_left.data(DbScoreTableModel.PttRole) < source_right.data(
DbScoreTableModel.PttRole
)
return super().lessThan(source_left, source_right)
pttLeft = sourceLeft.data(DbScoreTableModel.PttRole)
pttRight = sourceRight.data(DbScoreTableModel.PttRole)
if pttLeft and pttRight:
return pttLeft < pttRight
elif pttLeft:
return False
else:
return True
return super().lessThan(sourceLeft, sourceRight)

View File

@ -10,6 +10,9 @@ def keepWidgetInScreen(widget: QWidget, screen: QScreen = None):
# for why using frameGeometry.width() / frameGeometry.height()
# instead of width() / height().
# https://stackoverflow.com/questions/49700394/qt-unable-to-set-geometry
widget.adjustSize()
screen = screen or QGuiApplication.primaryScreen()
screenAvailableGeometry = screen.availableGeometry()

View File

@ -1,7 +1,7 @@
import logging
from arcaea_offline.database import Database
from arcaea_offline.models import Score
from arcaea_offline.models import Chart, Score
from arcaea_offline_ocr.b30.chieri.v4.ocr import ChieriBotV4Ocr
from arcaea_offline_ocr.b30.shared import B30OcrResultItem
from PySide6.QtGui import QImage
@ -49,4 +49,12 @@ def b30ResultToScore(_: None, qImage: QImage, result: B30OcrResultItem):
comment="B30 OCR",
)
if not chart:
chart = Chart(
song_id=song_id,
rating_class=result.rating_class,
title=song_id,
constant=0.0,
)
return (chart, score)

View File

@ -85,4 +85,11 @@ class ScoreConverter:
comment=f"OCR {QFileInfo(imagePath).fileName()}",
)
chart = db.get_chart(score.song_id, score.rating_class)
if not chart:
chart = Chart(
song_id=result.song_id,
rating_class=result.rating_class,
title=result.song_id,
constant=0.0,
)
return (chart, score)

View File

@ -2,6 +2,7 @@ from PySide6.QtCore import Signal
from PySide6.QtWidgets import QWidget
from ui.designer.components.chartAndScoreInput_ui import Ui_ChartAndScoreInput
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.implements.components.songIdSelector import SongIdSelectorMode
@ -12,6 +13,9 @@ class ChartAndScoreInput(Ui_ChartAndScoreInput, QWidget):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.chartSelector.valueChanged.connect(self.updateScoreEditorChart)
self.scoreEditor.accepted.connect(self.commit)

View File

@ -151,12 +151,19 @@ class ScoreEditor(Ui_ScoreEditor, QWidget):
if score := self.value():
texts = [
f"({score.song_id}, {score.rating_class}), Score {score.score}",
f"PURE {score.pure}, FAR {score.far}, LOST {score.lost}, MR {score.max_recall}",
f"Date {score.date}, Clear type {score.clear_type}, Modifier {score.modifier}",
f"PURE {score.pure}, FAR {score.far}, LOST {score.lost}",
f"MAX RECALL {score.max_recall}",
f"Date {score.date}",
f"Clear type {score.clear_type}",
f"Modifier {score.modifier}",
]
self.previewLabel.setText("<br>".join(texts))
self.previewLabel.setText(
f"{score.score}, P{score.pure} F{score.far} L{score.lost}, MR {score.max_recall}"
)
self.previewLabel.setToolTip("<br>".join(texts))
else:
self.previewLabel.setText("None")
self.previewLabel.setToolTip("")
def validateBeforeAccept(self):
return self.__validateBeforeAccept

View File

@ -1,7 +1,8 @@
from PySide6.QtCore import QCoreApplication, Qt
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QLabel, QPushButton, QWidget
from ui.designer.settings.settingsBaseWidget_ui import Ui_SettingsBaseWidget
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.settings import Settings
@ -10,6 +11,9 @@ class SettingsBaseWidget(Ui_SettingsBaseWidget, QWidget):
super().__init__(parent)
self.settings = Settings()
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
def setTitle(self, title: str):
self.titleLabel.setText(title)

View File

@ -1,8 +1,9 @@
from PySide6.QtCore import QFile, Qt, Slot
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import QMessageBox, QWidget
from PySide6.QtWidgets import QMessageBox, QTextBrowser, QWidget
from ui.designer.tabs.tabAbout_ui import Ui_TabAbout
from ui.extends.shared.language import LanguageChangeEventFilter
class TabAbout(Ui_TabAbout, QWidget):
@ -10,6 +11,9 @@ class TabAbout(Ui_TabAbout, QWidget):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
logoPixmap = QPixmap(":/images/logo.png").scaled(
300,
300,
@ -24,8 +28,12 @@ class TabAbout(Ui_TabAbout, QWidget):
@Slot()
def on_versionInfoButton_clicked(self):
textBrowser = QTextBrowser(self)
textBrowser.setWindowFlag(Qt.WindowType.Dialog, True)
textBrowser.setWindowTitle("version")
versionFile = QFile(":/VERSION")
versionFile.open(QFile.OpenModeFlag.ReadOnly)
versionText = str(versionFile.readAll(), encoding="utf-8")
versionFile.close()
QMessageBox.information(self, None, versionText)
textBrowser.setText(versionText)
textBrowser.show()

View File

@ -4,6 +4,7 @@ from PySide6.QtWidgets import QMessageBox
from ui.extends.shared.delegates.chartDelegate import ChartDelegate
from ui.extends.shared.delegates.scoreDelegate import ScoreDelegate
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.models.tables.b30 import (
DbB30TableModel,
DbB30TableSortFilterProxyModel,
@ -34,6 +35,10 @@ class TableScoreDelegate(ScoreDelegate):
class DbB30TableViewer(DbTableViewer):
def __init__(self, parent=None):
super().__init__(parent)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.tableView.verticalHeader().setVisible(True)
self.tableModel = DbB30TableModel(self)

View File

@ -18,6 +18,7 @@ from PySide6.QtWidgets import QFileDialog, QMessageBox, QWidget
from ui.designer.tabs.tabDb.tabDb_Manage_ui import Ui_TabDb_Manage
from ui.extends.shared.database import databaseUpdateSignals
from ui.extends.shared.language import LanguageChangeEventFilter
logger = logging.getLogger(__name__)
@ -27,6 +28,9 @@ class TabDb_Manage(Ui_TabDb_Manage, QWidget):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
@Slot()
def on_syncArcSongDbButton_clicked(self):
dbFile, filter = QFileDialog.getOpenFileName(

View File

@ -5,6 +5,7 @@ from PySide6.QtWidgets import QMessageBox
from ui.extends.shared.delegates.chartDelegate import ChartDelegate
from ui.extends.shared.delegates.scoreDelegate import ScoreDelegate
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.models.tables.score import (
DbScoreTableModel,
DbScoreTableSortFilterProxyModel,
@ -33,6 +34,9 @@ class DbScoreTableViewer(DbTableViewer):
def __init__(self, parent=None):
super().__init__(parent)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.tableModel = DbScoreTableModel(self)
self.tableProxyModel = DbScoreTableSortFilterProxyModel(self)
self.tableProxyModel.setSourceModel(self.tableModel)

View File

@ -2,6 +2,7 @@ from PySide6.QtCore import QCoreApplication
from PySide6.QtWidgets import QWidget
from ui.designer.tabs.tabDbEntry_ui import Ui_TabDbEntry
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.implements.tabs.tabDb.tabDb_B30TableViewer import DbB30TableViewer
from ui.implements.tabs.tabDb.tabDb_ScoreTableViewer import DbScoreTableViewer
@ -11,6 +12,9 @@ class TabDbEntry(Ui_TabDbEntry, QWidget):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.tabWidget.addTab(
DbScoreTableViewer(self),
QCoreApplication.translate("TabDbEntry", "tab.scoreTableViewer"),

View File

@ -2,12 +2,17 @@ from arcaea_offline.database import Database
from PySide6.QtWidgets import QWidget
from ui.designer.tabs.tabInputScore_ui import Ui_TabInputScore
from ui.extends.shared.language import LanguageChangeEventFilter
class TabInputScore(Ui_TabInputScore, QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.chartAndScoreInput.scoreCommited.connect(self.commit)
def commit(self):

View File

@ -1,5 +1,4 @@
import logging
from pathlib import Path
import cv2
from arcaea_offline_ocr.b30.chieri.v4.ocr import ChieriBotV4Ocr
@ -11,6 +10,7 @@ from PySide6.QtWidgets import QWidget
from ui.designer.tabs.tabOcr.tabOcr_B30_ui import Ui_TabOcr_B30
from ui.extends.components.ocrQueue import OcrQueueModel
from ui.extends.shared.cv2_utils import cv2BgrMatToQImage, qImageToCvMatBgr
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.settings import KNN_MODEL_FILE, SIFT_DATABASE_FILE, Settings
from ui.extends.tabs.tabOcr.tabOcr_B30 import ChieriV4OcrRunnable, b30ResultToScore
@ -24,6 +24,9 @@ class TabOcr_B30(Ui_TabOcr_B30, QWidget):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.b30TypeComboBox.addItem("ChieriV4", "chieri_v4")
self.b30TypeComboBox.setCurrentIndex(0)
self.b30TypeComboBox.setEnabled(False)

View File

@ -11,6 +11,7 @@ from PySide6.QtWidgets import QApplication, QFileDialog, QWidget
from ui.designer.tabs.tabOcr.tabOcr_Device_ui import Ui_TabOcr_Device
from ui.extends.components.ocrQueue import OcrQueueModel
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.settings import (
DEVICES_JSON_FILE,
KNN_MODEL_FILE,
@ -32,6 +33,9 @@ class TabOcr_Device(Ui_TabOcr_Device, QWidget):
self.setupUi(self)
self.openWizardButton.setEnabled(False)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.deviceFileSelector.filesSelected.connect(self.deviceFileSelected)
self.knnModelSelector.filesSelected.connect(self.knnModelFileSelected)
self.siftDatabaseSelector.filesSelected.connect(self.siftDatabaseFileSelected)

View File

@ -1,9 +1,13 @@
from PySide6.QtWidgets import QWidget
from ui.designer.tabs.tabOcrEntry_ui import Ui_TabOcrEntry
from ui.extends.shared.language import LanguageChangeEventFilter
class TabOcrEntry(Ui_TabOcrEntry, QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)

View File

@ -1,8 +1,10 @@
from arcaea_offline.database import Database
from PySide6.QtCore import QCoreApplication
from PySide6.QtGui import QShowEvent
from PySide6.QtWidgets import QWidget
from ui.designer.tabs.tabOverview_ui import Ui_TabOverview
from ui.extends.shared.language import LanguageChangeEventFilter
class TabOverview(Ui_TabOverview, QWidget):
@ -10,9 +12,10 @@ class TabOverview(Ui_TabOverview, QWidget):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.db = Database()
# self.db.register_update_hook(self.updateOverview)
# self.updateOverview()
def showEvent(self, event: QShowEvent) -> None:
self.updateOverview()
@ -21,18 +24,19 @@ class TabOverview(Ui_TabOverview, QWidget):
def updateOverview(self):
b30 = self.db.get_b30() or 0.00
self.b30Label.setText(str(f"{b30:.3f}"))
self.retranslateUi(self)
self.databaseDescribeLabel.setText(
self.describeFormatString.format(
self.db.count_packs(),
self.db.count_songs(),
self.db.count_difficulties(),
self.db.count_chart_infos(),
self.db.count_complete_chart_infos(),
self.db.count_scores(),
)
)
def retranslateUi(self, *args):
super().retranslateUi(self)
db = Database()
describeText = self.databaseDescribeLabel.text()
describeText = describeText.format(
db.count_packs(),
db.count_songs(),
db.count_difficulties(),
db.count_chart_infos(),
db.count_complete_chart_infos(),
db.count_scores(),
)
self.databaseDescribeLabel.setText(describeText)
# fmt: off
self.describeFormatString = QCoreApplication.translate("TabOverview", "databaseDescribeLabel {} {} {} {} {} {}")
# fmt: on

View File

@ -9,18 +9,10 @@ from arcaea_offline.external.andreal.api_data import (
from arcaea_offline.models import Chart
from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, Qt, Slot
from PySide6.QtGui import QGuiApplication, QImage, QPainter, QPaintEvent, QPixmap
from PySide6.QtWidgets import (
QButtonGroup,
QDialog,
QDialogButtonBox,
QFileDialog,
QLabel,
QMessageBox,
QVBoxLayout,
QWidget,
)
from PySide6.QtWidgets import QButtonGroup, QFileDialog, QLabel, QMessageBox, QWidget
from ui.designer.tabs.tabTools.tabTools_Andreal_ui import Ui_TabTools_Andreal
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.settings import ANDREAL_EXECUTABLE, ANDREAL_FOLDER
from ui.extends.tabs.tabTools.tabTools_Andreal import AndrealHelper
from ui.implements.components.chartSelector import ChartSelector
@ -69,32 +61,14 @@ class ChartSelectorDialog(ChartSelector):
self.setSongIdSelectorMode(SongIdSelectorMode.Chart)
class ImageTypeWhatIsThisDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.verticalLayout = QVBoxLayout(self)
self.label = QLabel(
# fmt: off
QCoreApplication.translate('TabTools_Andreal', 'imageWhatIsThisDialog.description')
# fmt: on
)
self.verticalLayout.addWidget(self.label)
self.buttonBox = QDialogButtonBox(Qt.Orientation.Horizontal)
self.buttonBox.addButton(QDialogButtonBox.StandardButton.Ok)
self.buttonBox.accepted.connect(self.close)
self.buttonBox.rejected.connect(self.close)
self.verticalLayout.addWidget(self.buttonBox)
class TabTools_Andreal(Ui_TabTools_Andreal, QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.db = Database()
self.andrealHelper = AndrealHelper(self)
@ -125,10 +99,6 @@ class TabTools_Andreal(Ui_TabTools_Andreal, QWidget):
self.andrealHelper.ready.connect(self.generateReady)
self.andrealHelper.finished.connect(self.generateFinished)
self.imageTypeWhatIsThisButton.clicked.connect(
lambda: ImageTypeWhatIsThisDialog(self).show()
)
self.imageTypeButtonGroup = QButtonGroup(self)
self.imageTypeButtonGroup.addButton(self.imageType_infoRadioButton, 0)
self.imageTypeButtonGroup.addButton(self.imageType_bestRadioButton, 1)
@ -159,6 +129,16 @@ class TabTools_Andreal(Ui_TabTools_Andreal, QWidget):
f"{chart.title}({chart.song_id}), {chart.rating_class}"
)
@Slot()
def on_imageTypeWhatIsThisButton_clicked(self):
QMessageBox.information(
self,
None,
# fmt: off
QCoreApplication.translate("TabTools_Andreal", "imageWhatIsThisDialog.description"),
# fmt: on
)
def imageFormat(self):
buttonId = self.imageFormatButtonGroup.checkedId()
return ["jpg", "png"][buttonId] if buttonId > -1 else None

View File

@ -0,0 +1,123 @@
import logging
import random
from arcaea_offline.calculate import calculate_constants_from_play_rating
from arcaea_offline.database import Database
from arcaea_offline.models import Chart, ScoreBest
from arcaea_offline.utils.rating import rating_class_to_text
from arcaea_offline.utils.score import score_to_grade_text
from PySide6.QtCore import Slot
from PySide6.QtWidgets import QLabel, QWidget
from ui.designer.tabs.tabTools.tabTools_ChartRecommend_ui import (
Ui_TabTools_ChartRecommend,
)
logger = logging.getLogger(__name__)
def chartToText(chart: Chart):
return f"{chart.artist} - {chart.title}<br>({chart.song_id}) {rating_class_to_text(chart.rating_class)}"
def scoreBestToText(score: ScoreBest):
return f"{score_to_grade_text(score.score)} {score.score} > {score.potential:.4f}"
class TabTools_ChartRecommend(Ui_TabTools_ChartRecommend, QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.db = Database()
self.chartsByConstant = []
self.chartsRecommendFromPlayRating = []
self.numLabelFormatString = "{} charts"
self.chartsRecommendFromPlayRating_playRatingSpinBox.valueChanged.connect(
self.updateChartsRecommendFromPlayRating
)
self.chartsRecommendFromPlayRating_boundsSpinBox.valueChanged.connect(
self.updateChartsRecommendFromPlayRating
)
self.chartsByConstant_refreshButton.clicked.connect(self.fillChartsByConstant)
self.chartsRecommendFromPlayRating_refreshButton.clicked.connect(
self.fillChartsRecommendFromPlayRating
)
@Slot(float)
def on_rangeFromPlayRating_playRatingSpinBox_valueChanged(self, value: float):
try:
result = calculate_constants_from_play_rating(value)
exPlusLower, exPlusUpper = result.EXPlus
exLower, exUpper = result.EX
aaLower, aaUpper = result.AA
self.rangeFromPlayRating_ExPlusLabel.setText(
f"{exPlusLower:.3f}~{exPlusUpper:.3f}"
)
self.rangeFromPlayRating_ExLabel.setText(f"{exLower:.3f}~{exUpper:.3f}")
self.rangeFromPlayRating_AaLabel.setText(f"{aaLower:.3f}~{aaUpper:.3f}")
except Exception:
logging.exception("cannot calculate constant from play rating")
self.rangeFromPlayRating_ExPlusLabel.setText("...")
self.rangeFromPlayRating_ExLabel.setText("...")
self.rangeFromPlayRating_AaLabel.setText("...")
def fillChartsByConstant(self):
while item := self.chartsByConstant_gridLayout.takeAt(0):
item.widget().deleteLater()
charts = random.sample(
self.chartsByConstant, k=min(len(self.chartsByConstant), 6)
)
row = 0
for i, chart in enumerate(charts):
if i % 3 == 0:
row += 1
label = QLabel(self)
label.setText(chartToText(chart))
self.chartsByConstant_gridLayout.addWidget(label, row, i % 3)
@Slot(float)
def on_chartsByConstant_constantSpinBox_valueChanged(self, value: float):
self.chartsByConstant = self.db.get_charts_by_constant(int(value * 10))
chartsNum = len(self.chartsByConstant)
self.chartsByConstant_refreshButton.setEnabled(chartsNum > 6)
self.chartsByConstant_numLabel.setText(
self.numLabelFormatString.format(chartsNum)
)
self.fillChartsByConstant()
def fillChartsRecommendFromPlayRating(self):
while item := self.chartsRecommendFromPlayRating_gridLayout.takeAt(0):
item.widget().deleteLater()
charts = random.sample(
self.chartsRecommendFromPlayRating,
k=min(len(self.chartsRecommendFromPlayRating), 6),
)
row = 0
for i, chart in enumerate(charts):
if i % 3 == 0:
row += 1
scoreBest = self.db.get_score_best(chart.song_id, chart.rating_class)
label = QLabel(self)
label.setText(f"{chartToText(chart)}<br>-<br>{scoreBestToText(scoreBest)}")
self.chartsRecommendFromPlayRating_gridLayout.addWidget(label, row, i % 3)
def updateChartsRecommendFromPlayRating(self):
playRating = self.chartsRecommendFromPlayRating_playRatingSpinBox.value()
bounds = self.chartsRecommendFromPlayRating_boundsSpinBox.value()
self.chartsRecommendFromPlayRating = self.db.recommend_charts(
playRating, bounds
)
chartsNum = len(self.chartsRecommendFromPlayRating)
self.chartsRecommendFromPlayRating_refreshButton.setEnabled(chartsNum > 6)
self.chartsRecommendFromPlayRating_numLabel.setText(
self.numLabelFormatString.format(chartsNum)
)
self.fillChartsRecommendFromPlayRating()

View File

@ -1,10 +1,12 @@
import re
from arcaea_offline.calculate import calculate_play_rating
from arcaea_offline.database import Database
from PySide6.QtCore import QDateTime
from PySide6.QtWidgets import QVBoxLayout, QWidget
from ui.designer.tabs.tabTools.tabTools_InfoLookup_ui import Ui_TabTools_InfoLookup
from ui.extends.shared.language import LanguageChangeEventFilter
class TabTools_InfoLookup(Ui_TabTools_InfoLookup, QWidget):
@ -12,6 +14,9 @@ class TabTools_InfoLookup(Ui_TabTools_InfoLookup, QWidget):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.ratingClassSelector.setLayout(QVBoxLayout)
self.db = Database()
@ -22,6 +27,16 @@ class TabTools_InfoLookup(Ui_TabTools_InfoLookup, QWidget):
self.ratingClassSelector.valueChanged.connect(self.updateDifficultyLabels)
self.ratingClassSelector.valueChanged.connect(self.updateChartInfoLabels)
self.songIdSelector.valueChanged.connect(
self.updatePlayRatingCalculateResultLabel
)
self.ratingClassSelector.valueChanged.connect(
self.updatePlayRatingCalculateResultLabel
)
self.playRatingCalculateScoreLineEdit.textChanged.connect(
self.updatePlayRatingCalculateResultLabel
)
self.langSelectComboBox.addItem("En - English [en]", "en")
self.langSelectComboBox.addItem("あ - Japanese [ja]", "ja")
self.langSelectComboBox.addItem("한 - Korean [ko]", "ko")
@ -189,7 +204,38 @@ class TabTools_InfoLookup(Ui_TabTools_InfoLookup, QWidget):
chartInfo = self.db.get_chart_info(songId, ratingClass)
if not chartInfo:
self.resetChartInfoLabels()
return
self.chartConstantLabel.setText(str(chartInfo.constant / 10))
self.chartNotesLabel.setText(
str(chartInfo.notes) if chartInfo.notes is not None else "-"
)
def resetPlayRatingCalculateResultLabel(self):
self.playRatingCalculateResultLabel.setText("...")
def updatePlayRatingCalculateResultLabel(self):
songId = self.songIdSelector.songId()
ratingClass = self.ratingClassSelector.value()
if not songId or ratingClass is None:
self.resetPlayRatingCalculateResultLabel()
return
chartInfo = self.db.get_chart_info(songId, ratingClass)
if not chartInfo or not chartInfo.constant:
self.resetPlayRatingCalculateResultLabel()
return
if scoreText := self.playRatingCalculateScoreLineEdit.text().replace("'", ""):
score = int(scoreText)
self.playRatingCalculateResultLabel.setText(
f"{calculate_play_rating(chartInfo.constant / 10, score):.3f}"
)
else:
self.resetPlayRatingCalculateResultLabel()
return

View File

@ -29,6 +29,7 @@ from PySide6.QtWidgets import (
from ui.designer.tabs.tabTools.tabTools_StepCalculator_ui import (
Ui_TabTools_StepCalculator,
)
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.implements.components.chartAndScoreInput import ChartAndScoreInput
from ui.implements.components.songIdSelector import SongIdSelectorMode
@ -90,6 +91,9 @@ class TabTools_StepCalculator(Ui_TabTools_StepCalculator, QWidget):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.calculate_toStep_calculatePlayResultFromScoreButton.clicked.connect(
self.openChartAndScoreInputDialog
)

View File

@ -1,9 +1,13 @@
from PySide6.QtWidgets import QWidget
from ui.designer.tabs.tabToolsEntry_ui import Ui_TabToolsEntry
from ui.extends.shared.language import LanguageChangeEventFilter
class TabToolsEntry(Ui_TabToolsEntry, QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)

View File

@ -89,12 +89,12 @@
<translation>Continue</translation>
</message>
<message>
<location filename="../../startup/databaseChecker.py" line="117"/>
<location filename="../../startup/databaseChecker.py" line="115"/>
<source>dialog.tryInitExistingDatabase</source>
<translation>The existing database doesn&apos;t seem to be initialized properly, try initialize again?</translation>
</message>
<message>
<location filename="../../startup/databaseChecker.py" line="133"/>
<location filename="../../startup/databaseChecker.py" line="131"/>
<source>dialog.confirmNewDatabase</source>
<translation>Database file does not exist. Create now?</translation>
</message>
@ -283,22 +283,22 @@ validation</translation>
<context>
<name>OcrTableModel</name>
<message>
<location filename="../../extends/components/ocrQueue.py" line="341"/>
<location filename="../../extends/components/ocrQueue.py" line="347"/>
<source>horizontalHeader.title.select</source>
<translation>Select</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="342"/>
<location filename="../../extends/components/ocrQueue.py" line="348"/>
<source>horizontalHeader.title.imagePreview</source>
<translation>Image Preview</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="343"/>
<location filename="../../extends/components/ocrQueue.py" line="349"/>
<source>horizontalHeader.title.chart</source>
<translation>Chart</translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="344"/>
<location filename="../../extends/components/ocrQueue.py" line="350"/>
<source>horizontalHeader.title.score</source>
<translation>Score</translation>
</message>
@ -314,54 +314,54 @@ validation</translation>
<context>
<name>ScoreEditor</name>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="109"/>
<location filename="../../designer/components/scoreEditor.ui" line="119"/>
<location filename="../../designer/components/scoreEditor.ui" line="189"/>
<location filename="../../designer/components/scoreEditor.ui" line="199"/>
<location filename="../../designer/components/scoreEditor.ui" line="239"/>
<location filename="../../designer/components/scoreEditor.ui" line="272"/>
<location filename="../../designer/components/scoreEditor.ui" line="279"/>
<location filename="../../designer/components/scoreEditor.ui" line="302"/>
<location filename="../../designer/components/scoreEditor.ui" line="139"/>
<location filename="../../designer/components/scoreEditor.ui" line="178"/>
<location filename="../../designer/components/scoreEditor.ui" line="225"/>
<location filename="../../designer/components/scoreEditor.ui" line="258"/>
<location filename="../../designer/components/scoreEditor.ui" line="285"/>
<location filename="../../designer/components/scoreEditor.ui" line="292"/>
<location filename="../../designer/components/scoreEditor.ui" line="318"/>
<location filename="../../designer/components/scoreEditor.ui" line="328"/>
<source>setNone</source>
<translation>None</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="169"/>
<location filename="../../designer/components/scoreEditor.ui" line="102"/>
<source>formLabel.date</source>
<translation>Time</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="338"/>
<location filename="../../designer/components/scoreEditor.ui" line="268"/>
<source>formLabel.comment</source>
<translation>Comment</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="358"/>
<location filename="../../designer/components/scoreEditor.ui" line="119"/>
<source>formLabel.preview</source>
<translation>Preview</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="99"/>
<location filename="../../designer/components/scoreEditor.ui" line="20"/>
<source>formLabel.score</source>
<translation>Score</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="162"/>
<location filename="../../designer/components/scoreEditor.ui" line="278"/>
<source>idAutoInsert</source>
<translation>(Auto insert)</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="309"/>
<location filename="../../designer/components/scoreEditor.ui" line="112"/>
<source>warnIfIncomplete</source>
<translation>Warn if incomplete</translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="63"/>
<location filename="../../designer/components/scoreEditor.ui" line="218"/>
<source>commitButton</source>
<translation>Commit</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="320"/>
<location filename="../../implements/components/scoreEditor.py" line="327"/>
<source>validate.ok</source>
<translation>OK</translation>
</message>
@ -406,57 +406,57 @@ validation</translation>
<translation>Cannot verify an incomplete score. Commit anyway?</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="205"/>
<location filename="../../implements/components/scoreEditor.py" line="212"/>
<source>confirmDialog.chartNotSet.title</source>
<translation>Chart not set</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="206"/>
<location filename="../../implements/components/scoreEditor.py" line="213"/>
<source>confirmDialog.chartNotSet.text</source>
<translation>Chart not set, cannot commit.</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="214"/>
<location filename="../../implements/components/scoreEditor.py" line="221"/>
<source>confirmDialog.scoreIncomplete.title</source>
<translation>Score incomplete</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="215"/>
<location filename="../../implements/components/scoreEditor.py" line="222"/>
<source>confirmDialog.scoreIncomplete.text</source>
<translation>Necessary score field missing, cannot commit.</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="324"/>
<location filename="../../implements/components/scoreEditor.py" line="331"/>
<source>validate.chartNotSet</source>
<translation>Chart not set</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="328"/>
<location filename="../../implements/components/scoreEditor.py" line="335"/>
<source>validate.chartIncomple</source>
<translation>No chart data, cannot verify</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="332"/>
<location filename="../../implements/components/scoreEditor.py" line="339"/>
<source>validate.scoreMismatch</source>
<translation>Possible invalid score</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="336"/>
<location filename="../../implements/components/scoreEditor.py" line="343"/>
<source>validate.scoreEmpty</source>
<translation>Empty score</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="340"/>
<location filename="../../implements/components/scoreEditor.py" line="347"/>
<source>validate.scoreIncomplete</source>
<translation>Missing necessary score field</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="346"/>
<location filename="../../implements/components/scoreEditor.py" line="353"/>
<source>validate.scoreIncompleteForValidate</source>
<translation>Score incomplete, cannot verify</translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="351"/>
<location filename="../../implements/components/scoreEditor.py" line="358"/>
<source>validate.unknownState</source>
<translation>Unknown</translation>
</message>
@ -581,12 +581,12 @@ validation</translation>
<translation>Manage</translation>
</message>
<message>
<location filename="../../implements/tabs/tabDbEntry.py" line="16"/>
<location filename="../../implements/tabs/tabDbEntry.py" line="20"/>
<source>tab.scoreTableViewer</source>
<translation>Table [Score]</translation>
</message>
<message>
<location filename="../../implements/tabs/tabDbEntry.py" line="20"/>
<location filename="../../implements/tabs/tabDbEntry.py" line="24"/>
<source>tab.b30TableViewer</source>
<translation>Table [B30]</translation>
</message>
@ -752,7 +752,7 @@ validation</translation>
<location filename="../../designer/tabs/tabOverview.ui" line="23"/>
<source>databaseDescribeLabel {} {} {} {} {} {}</source>
<extracomment>This database now have {} packs, {} songs, {} difficulties, {} chart info ({} complete) and {} scores.</extracomment>
<translation>This database now have {} packs, {} songs, {} difficulties, {} chart info ({} complete) and {} scores.</translation>
<translation>There are {} packs, {} songs, {} difficulties, {} chart info ({} complete) and {} scores in database.</translation>
</message>
</context>
<context>
@ -769,6 +769,11 @@ validation</translation>
</message>
<message>
<location filename="../../designer/tabs/tabToolsEntry.ui" line="34"/>
<source>tab.chartRecommend</source>
<translation>Chart Recommend</translation>
</message>
<message>
<location filename="../../designer/tabs/tabToolsEntry.ui" line="39"/>
<source>tab.andreal</source>
<translation>Andreal Image Generator</translation>
</message>
@ -836,11 +841,35 @@ validation</translation>
<translation>Generate</translation>
</message>
<message>
<location filename="../../implements/tabs/tabTools/tabTools_Andreal.py" line="81"/>
<location filename="../../implements/tabs/tabTools/tabTools_Andreal.py" line="82"/>
<source>imageWhatIsThisDialog.description</source>
<translation>Generate image of...&lt;ul&gt;&lt;li&gt;/a - the most recent score&lt;/li&gt;&lt;li&gt;/a b30 - best30 image&lt;/li&gt;&lt;li&gt;/a info - best score of the selected chart&lt;/li&gt;&lt;/ul&gt;</translation>
</message>
</context>
<context>
<name>TabTools_ChartRecommend</name>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="20"/>
<source>constantRangeFromPlayRating</source>
<translation>Chart Constant Range from Play Rating</translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="118"/>
<source>chartsByConstant</source>
<translation>Charts by Constant</translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="174"/>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="273"/>
<source>refreshButton</source>
<translation>Roll</translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="197"/>
<source>chartsRecommendFromPlayRating</source>
<translation>Chart from Play Rating Based on Best Score</translation>
</message>
</context>
<context>
<name>TabTools_InfoLookup</name>
<message>
@ -1008,6 +1037,11 @@ validation</translation>
<source>difficulty.title</source>
<translation>Title</translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_InfoLookup.ui" line="695"/>
<source>playRatingCalculate</source>
<translation>Calculate Play Rating</translation>
</message>
</context>
<context>
<name>TabTools_StepCalculator</name>

View File

@ -89,12 +89,12 @@
<translation></translation>
</message>
<message>
<location filename="../../startup/databaseChecker.py" line="117"/>
<location filename="../../startup/databaseChecker.py" line="115"/>
<source>dialog.tryInitExistingDatabase</source>
<translation></translation>
</message>
<message>
<location filename="../../startup/databaseChecker.py" line="133"/>
<location filename="../../startup/databaseChecker.py" line="131"/>
<source>dialog.confirmNewDatabase</source>
<translation></translation>
</message>
@ -282,22 +282,22 @@
<context>
<name>OcrTableModel</name>
<message>
<location filename="../../extends/components/ocrQueue.py" line="341"/>
<location filename="../../extends/components/ocrQueue.py" line="347"/>
<source>horizontalHeader.title.select</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="342"/>
<location filename="../../extends/components/ocrQueue.py" line="348"/>
<source>horizontalHeader.title.imagePreview</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="343"/>
<location filename="../../extends/components/ocrQueue.py" line="349"/>
<source>horizontalHeader.title.chart</source>
<translation></translation>
</message>
<message>
<location filename="../../extends/components/ocrQueue.py" line="344"/>
<location filename="../../extends/components/ocrQueue.py" line="350"/>
<source>horizontalHeader.title.score</source>
<translation></translation>
</message>
@ -313,54 +313,54 @@
<context>
<name>ScoreEditor</name>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="109"/>
<location filename="../../designer/components/scoreEditor.ui" line="119"/>
<location filename="../../designer/components/scoreEditor.ui" line="189"/>
<location filename="../../designer/components/scoreEditor.ui" line="199"/>
<location filename="../../designer/components/scoreEditor.ui" line="239"/>
<location filename="../../designer/components/scoreEditor.ui" line="272"/>
<location filename="../../designer/components/scoreEditor.ui" line="279"/>
<location filename="../../designer/components/scoreEditor.ui" line="302"/>
<location filename="../../designer/components/scoreEditor.ui" line="139"/>
<location filename="../../designer/components/scoreEditor.ui" line="178"/>
<location filename="../../designer/components/scoreEditor.ui" line="225"/>
<location filename="../../designer/components/scoreEditor.ui" line="258"/>
<location filename="../../designer/components/scoreEditor.ui" line="285"/>
<location filename="../../designer/components/scoreEditor.ui" line="292"/>
<location filename="../../designer/components/scoreEditor.ui" line="318"/>
<location filename="../../designer/components/scoreEditor.ui" line="328"/>
<source>setNone</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="169"/>
<location filename="../../designer/components/scoreEditor.ui" line="102"/>
<source>formLabel.date</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="338"/>
<location filename="../../designer/components/scoreEditor.ui" line="268"/>
<source>formLabel.comment</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="358"/>
<location filename="../../designer/components/scoreEditor.ui" line="119"/>
<source>formLabel.preview</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="99"/>
<location filename="../../designer/components/scoreEditor.ui" line="20"/>
<source>formLabel.score</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="162"/>
<location filename="../../designer/components/scoreEditor.ui" line="278"/>
<source>idAutoInsert</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="309"/>
<location filename="../../designer/components/scoreEditor.ui" line="112"/>
<source>warnIfIncomplete</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/components/scoreEditor.ui" line="63"/>
<location filename="../../designer/components/scoreEditor.ui" line="218"/>
<source>commitButton</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="320"/>
<location filename="../../implements/components/scoreEditor.py" line="327"/>
<source>validate.ok</source>
<translation>OK</translation>
</message>
@ -405,57 +405,57 @@
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="205"/>
<location filename="../../implements/components/scoreEditor.py" line="212"/>
<source>confirmDialog.chartNotSet.title</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="206"/>
<location filename="../../implements/components/scoreEditor.py" line="213"/>
<source>confirmDialog.chartNotSet.text</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="214"/>
<location filename="../../implements/components/scoreEditor.py" line="221"/>
<source>confirmDialog.scoreIncomplete.title</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="215"/>
<location filename="../../implements/components/scoreEditor.py" line="222"/>
<source>confirmDialog.scoreIncomplete.text</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="324"/>
<location filename="../../implements/components/scoreEditor.py" line="331"/>
<source>validate.chartNotSet</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="328"/>
<location filename="../../implements/components/scoreEditor.py" line="335"/>
<source>validate.chartIncomple</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="332"/>
<location filename="../../implements/components/scoreEditor.py" line="339"/>
<source>validate.scoreMismatch</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="336"/>
<location filename="../../implements/components/scoreEditor.py" line="343"/>
<source>validate.scoreEmpty</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="340"/>
<location filename="../../implements/components/scoreEditor.py" line="347"/>
<source>validate.scoreIncomplete</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="346"/>
<location filename="../../implements/components/scoreEditor.py" line="353"/>
<source>validate.scoreIncompleteForValidate</source>
<translation></translation>
</message>
<message>
<location filename="../../implements/components/scoreEditor.py" line="351"/>
<location filename="../../implements/components/scoreEditor.py" line="358"/>
<source>validate.unknownState</source>
<translation></translation>
</message>
@ -580,12 +580,12 @@
<translation></translation>
</message>
<message>
<location filename="../../implements/tabs/tabDbEntry.py" line="16"/>
<location filename="../../implements/tabs/tabDbEntry.py" line="20"/>
<source>tab.scoreTableViewer</source>
<translation> []</translation>
</message>
<message>
<location filename="../../implements/tabs/tabDbEntry.py" line="20"/>
<location filename="../../implements/tabs/tabDbEntry.py" line="24"/>
<source>tab.b30TableViewer</source>
<translation> [B30]</translation>
</message>
@ -768,6 +768,11 @@
</message>
<message>
<location filename="../../designer/tabs/tabToolsEntry.ui" line="34"/>
<source>tab.chartRecommend</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/tabs/tabToolsEntry.ui" line="39"/>
<source>tab.andreal</source>
<translation>Andreal </translation>
</message>
@ -835,11 +840,35 @@
<translation></translation>
</message>
<message>
<location filename="../../implements/tabs/tabTools/tabTools_Andreal.py" line="81"/>
<location filename="../../implements/tabs/tabTools/tabTools_Andreal.py" line="82"/>
<source>imageWhatIsThisDialog.description</source>
<translation>&lt;ul&gt;&lt;li&gt;/a - &lt;/li&gt;&lt;li&gt;/a b30 - /a b30&lt;/li&gt;&lt;li&gt;/a info - &lt;/li&gt;&lt;/ul&gt;</translation>
</message>
</context>
<context>
<name>TabTools_ChartRecommend</name>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="20"/>
<source>constantRangeFromPlayRating</source>
<translation> PTT </translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="118"/>
<source>chartsByConstant</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="174"/>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="273"/>
<source>refreshButton</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_ChartRecommend.ui" line="197"/>
<source>chartsRecommendFromPlayRating</source>
<translation> PTT </translation>
</message>
</context>
<context>
<name>TabTools_InfoLookup</name>
<message>
@ -1007,6 +1036,11 @@
<source>difficulty.title</source>
<translation></translation>
</message>
<message>
<location filename="../../designer/tabs/tabTools/tabTools_InfoLookup.ui" line="695"/>
<source>playRatingCalculate</source>
<translation> PTT</translation>
</message>
</context>
<context>
<name>TabTools_StepCalculator</name>