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") versionFile = Path("ui/resources/VERSION")
assert versionFile.exists() 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 # detect pip
pipName = None pipName = None
possiblePipNames = ["pip3", "pip"] possiblePipNames = ["pip3", "pip"]
@ -19,7 +36,6 @@ for possiblePipName in possiblePipNames:
pipName = possiblePipName pipName = possiblePipName
break break
versionTexts = []
# if possiblePipName: # if possiblePipName:
# pipFreezeLines = os.popen(f"{possiblePipName} freeze").read().split("\n") # pipFreezeLines = os.popen(f"{possiblePipName} freeze").read().split("\n")

View File

@ -6,14 +6,89 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>450</width> <width>400</width>
<height>350</height> <height>322</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string notr="true">ScoreEditor</string> <string notr="true">ScoreEditor</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <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"> <item row="1" column="1">
<widget class="FocusSelectAllLineEdit" name="scoreLineEdit"> <widget class="FocusSelectAllLineEdit" name="scoreLineEdit">
<property name="inputMask"> <property name="inputMask">
@ -21,7 +96,51 @@
</property> </property>
</widget> </widget>
</item> </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"> <widget class="QLabel" name="validateLabel">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@ -37,48 +156,8 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="1"> <item row="2" column="1">
<widget class="QLineEdit" name="commentLineEdit"> <widget class="QSpinBox" name="pureSpinBox">
<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">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>100</width> <width>100</width>
@ -93,26 +172,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="3" column="2">
<widget class="QCheckBox" name="farNoneCheckBox"> <widget class="QCheckBox" name="farNoneCheckBox">
<property name="text"> <property name="text">
@ -120,23 +179,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="10" column="0"> <item row="10" column="1">
<widget class="QLabel" name="label_8"> <widget class="QLineEdit" name="commentLineEdit">
<property name="text"> <property name="enabled">
<string notr="true">Clear Type</string> <bool>false</bool>
</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>
</property> </property>
</widget> </widget>
</item> </item>
@ -156,73 +202,6 @@
</property> </property>
</widget> </widget>
</item> </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"> <item row="4" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
@ -233,7 +212,81 @@
</property> </property>
</widget> </widget>
</item> </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"> <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"> <widget class="QCheckBox" name="modifierNoneCheckBox">
<property name="text"> <property name="text">
<string>setNone</string> <string>setNone</string>
@ -259,40 +312,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="9" column="1"> <item row="7" column="2">
<widget class="QComboBox" name="modifierComboBox"> <widget class="QCheckBox" name="maxRecallNoneCheckBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QCheckBox" name="dateNoneCheckBox">
<property name="text"> <property name="text">
<string>setNone</string> <string>setNone</string>
</property> </property>
</widget> <property name="checked">
</item> <bool>true</bool>
<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> </property>
</widget> </widget>
</item> </item>
@ -303,18 +329,18 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="0"> <item row="3" column="0">
<widget class="QCheckBox" name="warnIfIncompleteCheckBox"> <widget class="QLabel" name="label_3">
<property name="text"> <property name="text">
<string>warnIfIncomplete</string> <string notr="true">FAR</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
</widget> </widget>
</item> </item>
<item row="8" column="1"> <item row="3" column="1">
<widget class="QSpinBox" name="maxRecallSpinBox"> <widget class="QSpinBox" name="farSpinBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>100</width> <width>100</width>
@ -327,60 +353,18 @@
<property name="maximum"> <property name="maximum">
<number>0</number> <number>0</number>
</property> </property>
<property name="value">
<number>0</number>
</property>
</widget> </widget>
</item> </item>
<item row="11" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>formLabel.comment</string> <string notr="true">PURE</string>
</property> </property>
<property name="alignment"> <property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property> </property>
</widget> </widget>
</item> </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> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

View File

@ -17,7 +17,7 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QPalette, QPixmap, QRadialGradient, QTransform) QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QDateTimeEdit, from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QDateTimeEdit,
QGridLayout, QLabel, QLineEdit, QPushButton, QGridLayout, QLabel, QLineEdit, QPushButton,
QSizePolicy, QSpacerItem, QSpinBox, QWidget) QSizePolicy, QSpinBox, QWidget)
from ui.implements.components.focusSelectAllLineEdit import FocusSelectAllLineEdit from ui.implements.components.focusSelectAllLineEdit import FocusSelectAllLineEdit
@ -25,126 +25,22 @@ class Ui_ScoreEditor(object):
def setupUi(self, ScoreEditor): def setupUi(self, ScoreEditor):
if not ScoreEditor.objectName(): if not ScoreEditor.objectName():
ScoreEditor.setObjectName(u"ScoreEditor") ScoreEditor.setObjectName(u"ScoreEditor")
ScoreEditor.resize(450, 350) ScoreEditor.resize(400, 322)
ScoreEditor.setWindowTitle(u"ScoreEditor") ScoreEditor.setWindowTitle(u"ScoreEditor")
self.gridLayout = QGridLayout(ScoreEditor) self.gridLayout = QGridLayout(ScoreEditor)
self.gridLayout.setObjectName(u"gridLayout") 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 = QLabel(ScoreEditor)
self.label.setObjectName(u"label") self.label.setObjectName(u"label")
self.label.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.label.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label, 1, 0, 1, 1) 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 = QLabel(ScoreEditor)
self.label_8.setObjectName(u"label_8") self.label_8.setObjectName(u"label_8")
self.label_8.setText(u"Clear Type") self.label_8.setText(u"Clear Type")
self.label_8.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.label_8.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_8, 10, 0, 1, 1) self.gridLayout.addWidget(self.label_8, 9, 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.label_10 = QLabel(ScoreEditor) self.label_10 = QLabel(ScoreEditor)
self.label_10.setObjectName(u"label_10") 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.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 = QComboBox(ScoreEditor)
self.modifierComboBox.setObjectName(u"modifierComboBox") self.modifierComboBox.setObjectName(u"modifierComboBox")
self.modifierComboBox.setEnabled(False) 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.previewLabel = QLabel(ScoreEditor)
self.dateNoneCheckBox.setObjectName(u"dateNoneCheckBox") 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.gridLayout.addWidget(self.previewLabel, 11, 1, 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.maxRecallSpinBox = QSpinBox(ScoreEditor) self.maxRecallSpinBox = QSpinBox(ScoreEditor)
self.maxRecallSpinBox.setObjectName(u"maxRecallSpinBox") self.maxRecallSpinBox.setObjectName(u"maxRecallSpinBox")
@ -227,39 +75,186 @@ class Ui_ScoreEditor(object):
self.maxRecallSpinBox.setMaximum(0) self.maxRecallSpinBox.setMaximum(0)
self.maxRecallSpinBox.setValue(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.scoreLineEdit = FocusSelectAllLineEdit(ScoreEditor)
self.label_9.setObjectName(u"label_9") self.scoreLineEdit.setObjectName(u"scoreLineEdit")
self.label_9.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) 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 = QLabel(ScoreEditor)
self.label_6.setObjectName(u"label_6") self.label_6.setObjectName(u"label_6")
self.label_6.setText(u"MAX RECALL") self.label_6.setText(u"MAX RECALL")
self.label_6.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) 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.dateNoneCheckBox = QCheckBox(ScoreEditor)
self.label_11.setObjectName(u"label_11") self.dateNoneCheckBox.setObjectName(u"dateNoneCheckBox")
self.label_11.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.gridLayout.addWidget(self.label_11, 12, 0, 1, 1) self.gridLayout.addWidget(self.dateNoneCheckBox, 5, 2, 1, 1)
self.previewLabel = QLabel(ScoreEditor) self.validateLabel = QLabel(ScoreEditor)
self.previewLabel.setObjectName(u"previewLabel") self.validateLabel.setObjectName(u"validateLabel")
sizePolicy2 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) 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.setHorizontalStretch(0)
sizePolicy2.setVerticalStretch(0) sizePolicy2.setVerticalStretch(0)
sizePolicy2.setHeightForWidth(self.previewLabel.sizePolicy().hasHeightForWidth()) sizePolicy2.setHeightForWidth(self.dateTimeEdit.sizePolicy().hasHeightForWidth())
self.previewLabel.setSizePolicy(sizePolicy2) self.dateTimeEdit.setSizePolicy(sizePolicy2)
self.previewLabel.setStyleSheet(u"QLabel { color: gray }") self.dateTimeEdit.setDisplayFormat(u"yyyy/MM/dd HH:mm:ss")
self.previewLabel.setText(u"None") self.dateTimeEdit.setCalendarPopup(False)
self.previewLabel.setWordWrap(True)
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.scoreLineEdit, self.pureSpinBox)
QWidget.setTabOrder(self.pureSpinBox, self.pureNoneCheckBox) QWidget.setTabOrder(self.pureSpinBox, self.pureNoneCheckBox)
@ -293,21 +288,21 @@ class Ui_ScoreEditor(object):
# setupUi # setupUi
def retranslateUi(self, ScoreEditor): def retranslateUi(self, ScoreEditor):
self.commitButton.setText(QCoreApplication.translate("ScoreEditor", u"commitButton", None))
self.label.setText(QCoreApplication.translate("ScoreEditor", u"formLabel.score", 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.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.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.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 pass
# retranslateUi # retranslateUi

View File

@ -20,7 +20,7 @@
<item> <item>
<widget class="QLabel" name="databaseDescribeLabel"> <widget class="QLabel" name="databaseDescribeLabel">
<property name="text"> <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> </property>
</widget> </widget>
</item> </item>

View File

@ -33,6 +33,7 @@ class Ui_TabOverview(object):
self.databaseDescribeLabel = QLabel(TabOverview) self.databaseDescribeLabel = QLabel(TabOverview)
self.databaseDescribeLabel.setObjectName(u"databaseDescribeLabel") self.databaseDescribeLabel.setObjectName(u"databaseDescribeLabel")
self.databaseDescribeLabel.setText(u"...")
self.verticalLayout.addWidget(self.databaseDescribeLabel) self.verticalLayout.addWidget(self.databaseDescribeLabel)
@ -108,7 +109,6 @@ class Ui_TabOverview(object):
# setupUi # setupUi
def retranslateUi(self, TabOverview): def retranslateUi(self, TabOverview):
self.databaseDescribeLabel.setText(QCoreApplication.translate("TabOverview", u"databaseDescribeLabel {} {} {} {} {} {}", None))
pass pass
# retranslateUi # 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> <x>0</x>
<y>0</y> <y>0</y>
<width>665</width> <width>665</width>
<height>570</height> <height>574</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -689,6 +689,66 @@
</layout> </layout>
</widget> </widget>
</item> </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> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -19,6 +19,7 @@ from PySide6.QtWidgets import (QApplication, QSizePolicy, QTabWidget, QVBoxLayou
QWidget) QWidget)
from ui.implements.tabs.tabTools.tabTools_Andreal import TabTools_Andreal 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_InfoLookup import TabTools_InfoLookup
from ui.implements.tabs.tabTools.tabTools_StepCalculator import TabTools_StepCalculator 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 = TabTools_StepCalculator()
self.tab_2.setObjectName(u"tab_2") self.tab_2.setObjectName(u"tab_2")
self.tabWidget.addTab(self.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 = TabTools_Andreal()
self.tab_3.setObjectName(u"tab_3") self.tab_3.setObjectName(u"tab_3")
self.tabWidget.addTab(self.tab_3, "") self.tabWidget.addTab(self.tab_3, "")
@ -56,6 +60,7 @@ class Ui_TabToolsEntry(object):
def retranslateUi(self, TabToolsEntry): 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), 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_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)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("TabToolsEntry", u"tab.andreal", None))
pass pass
# retranslateUi # retranslateUi

View File

@ -263,7 +263,13 @@ class OcrQueueModel(QAbstractListModel):
index = self.index(row, 0) index = self.index(row, 0)
chart = index.data(self.ChartRole) chart = index.data(self.ChartRole)
score = index.data(self.ScoreRole) 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) scoreRange = calculate_score_range(chart.notes, score.pure, score.far)
scoreValidateOk = scoreRange[0] <= score.score <= scoreRange[1] scoreValidateOk = scoreRange[0] <= score.score <= scoreRange[1]
self.setData(index, scoreValidateOk, self.ScoreValidateOkRole) self.setData(index, scoreValidateOk, self.ScoreValidateOkRole)

View File

@ -93,13 +93,18 @@ class ChartDelegate(TextSegmentDelegate):
[{self.TextRole: "Chart Invalid", self.ColorRole: QColor("#ff0000")}] [{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 [ return [
[ [
{self.TextRole: f"{chart.title}"}, {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], self.ColorRole: self.RatingClassColors[chart.rating_class],
}, },
], ],

View File

@ -96,7 +96,13 @@ class ScoreDelegate(TextSegmentDelegate):
score = self.getScore(index) score = self.getScore(index)
chart = self.getChart(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) scoreRange = calculate_score_range(chart.notes, score.pure, score.far)
return scoreRange[0] <= score.score <= scoreRange[1] return scoreRange[0] <= score.score <= scoreRange[1]

View File

@ -29,12 +29,26 @@ class DbScoreTableModel(DbTableModel):
def syncDb(self): def syncDb(self):
newScores = self._db.get_scores() newScores = self._db.get_scores()
newScores = sorted(newScores, key=lambda x: x.id) newScores = sorted(newScores, key=lambda x: x.id)
newCharts = [ newCharts = []
self._db.get_chart(score.song_id, score.rating_class) for score in newScores 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 = [] newPtts = []
for chart, score in zip(newCharts, newScores): 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)) newPtts.append(calculate_play_rating(chart.constant / 10, score.score))
else: else:
newPtts.append(None) newPtts.append(None)
@ -103,10 +117,11 @@ class DbScoreTableModel(DbTableModel):
elif index.column() == 2 and role in [self.ChartRole, self.ScoreRole]: elif index.column() == 2 and role in [self.ChartRole, self.ScoreRole]:
return self.__items[index.row()][role] return self.__items[index.row()][role]
elif index.column() == 3: elif index.column() == 3:
potential = self.__items[index.row()][self.PttRole]
if role == Qt.ItemDataRole.DisplayRole: 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: elif role == self.PttRole:
return self.__items[index.row()][self.PttRole] return potential
return None return None
def setData(self, index, value, role): def setData(self, index, value, role):
@ -165,30 +180,35 @@ class DbScoreTableSortFilterProxyModel(QSortFilterProxyModel):
Sort_C2_ScoreRole = Qt.ItemDataRole.UserRole + 75 Sort_C2_ScoreRole = Qt.ItemDataRole.UserRole + 75
Sort_C2_TimeRole = Qt.ItemDataRole.UserRole + 76 Sort_C2_TimeRole = Qt.ItemDataRole.UserRole + 76
def lessThan(self, source_left, source_right) -> bool: def lessThan(self, sourceLeft, sourceRight) -> bool:
if source_left.column() != source_right.column(): if sourceLeft.column() != sourceRight.column():
return return
column = source_left.column() column = sourceLeft.column()
if column == 0: if column == 0:
return source_left.data(DbScoreTableModel.IdRole) < source_right.data( return sourceLeft.data(DbScoreTableModel.IdRole) < sourceRight.data(
DbScoreTableModel.IdRole DbScoreTableModel.IdRole
) )
elif column == 2: elif column == 2:
score_left = source_left.data(DbScoreTableModel.ScoreRole) scoreLeft = sourceLeft.data(DbScoreTableModel.ScoreRole)
score_right = source_right.data(DbScoreTableModel.ScoreRole) scoreRight = sourceRight.data(DbScoreTableModel.ScoreRole)
if isinstance(score_left, Score) and isinstance(score_right, Score): if isinstance(scoreLeft, Score) and isinstance(scoreRight, Score):
if self.sortRole() == self.Sort_C2_ScoreRole: 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: elif self.sortRole() == self.Sort_C2_TimeRole:
if score_left.date and score_right.date: if scoreLeft.date and scoreRight.date:
return score_left.date < score_right.date return scoreLeft.date < scoreRight.date
elif score_left.date: elif scoreLeft.date:
return False return False
else: else:
return True return True
elif column == 3: elif column == 3:
return source_left.data(DbScoreTableModel.PttRole) < source_right.data( pttLeft = sourceLeft.data(DbScoreTableModel.PttRole)
DbScoreTableModel.PttRole pttRight = sourceRight.data(DbScoreTableModel.PttRole)
) if pttLeft and pttRight:
return super().lessThan(source_left, source_right) 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() # for why using frameGeometry.width() / frameGeometry.height()
# instead of width() / height(). # instead of width() / height().
# https://stackoverflow.com/questions/49700394/qt-unable-to-set-geometry
widget.adjustSize()
screen = screen or QGuiApplication.primaryScreen() screen = screen or QGuiApplication.primaryScreen()
screenAvailableGeometry = screen.availableGeometry() screenAvailableGeometry = screen.availableGeometry()

View File

@ -1,7 +1,7 @@
import logging import logging
from arcaea_offline.database import Database 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.chieri.v4.ocr import ChieriBotV4Ocr
from arcaea_offline_ocr.b30.shared import B30OcrResultItem from arcaea_offline_ocr.b30.shared import B30OcrResultItem
from PySide6.QtGui import QImage from PySide6.QtGui import QImage
@ -49,4 +49,12 @@ def b30ResultToScore(_: None, qImage: QImage, result: B30OcrResultItem):
comment="B30 OCR", 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) return (chart, score)

View File

@ -85,4 +85,11 @@ class ScoreConverter:
comment=f"OCR {QFileInfo(imagePath).fileName()}", comment=f"OCR {QFileInfo(imagePath).fileName()}",
) )
chart = db.get_chart(score.song_id, score.rating_class) 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) return (chart, score)

View File

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

View File

@ -151,12 +151,19 @@ class ScoreEditor(Ui_ScoreEditor, QWidget):
if score := self.value(): if score := self.value():
texts = [ texts = [
f"({score.song_id}, {score.rating_class}), Score {score.score}", 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"PURE {score.pure}, FAR {score.far}, LOST {score.lost}",
f"Date {score.date}, Clear type {score.clear_type}, Modifier {score.modifier}", 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: else:
self.previewLabel.setText("None") self.previewLabel.setText("None")
self.previewLabel.setToolTip("")
def validateBeforeAccept(self): def validateBeforeAccept(self):
return self.__validateBeforeAccept 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 PySide6.QtWidgets import QLabel, QPushButton, QWidget
from ui.designer.settings.settingsBaseWidget_ui import Ui_SettingsBaseWidget from ui.designer.settings.settingsBaseWidget_ui import Ui_SettingsBaseWidget
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.settings import Settings from ui.extends.shared.settings import Settings
@ -10,6 +11,9 @@ class SettingsBaseWidget(Ui_SettingsBaseWidget, QWidget):
super().__init__(parent) super().__init__(parent)
self.settings = Settings() self.settings = Settings()
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
def setTitle(self, title: str): def setTitle(self, title: str):
self.titleLabel.setText(title) self.titleLabel.setText(title)

View File

@ -1,8 +1,9 @@
from PySide6.QtCore import QFile, Qt, Slot from PySide6.QtCore import QFile, Qt, Slot
from PySide6.QtGui import QPixmap 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.designer.tabs.tabAbout_ui import Ui_TabAbout
from ui.extends.shared.language import LanguageChangeEventFilter
class TabAbout(Ui_TabAbout, QWidget): class TabAbout(Ui_TabAbout, QWidget):
@ -10,6 +11,9 @@ class TabAbout(Ui_TabAbout, QWidget):
super().__init__(parent) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
logoPixmap = QPixmap(":/images/logo.png").scaled( logoPixmap = QPixmap(":/images/logo.png").scaled(
300, 300,
300, 300,
@ -24,8 +28,12 @@ class TabAbout(Ui_TabAbout, QWidget):
@Slot() @Slot()
def on_versionInfoButton_clicked(self): def on_versionInfoButton_clicked(self):
textBrowser = QTextBrowser(self)
textBrowser.setWindowFlag(Qt.WindowType.Dialog, True)
textBrowser.setWindowTitle("version")
versionFile = QFile(":/VERSION") versionFile = QFile(":/VERSION")
versionFile.open(QFile.OpenModeFlag.ReadOnly) versionFile.open(QFile.OpenModeFlag.ReadOnly)
versionText = str(versionFile.readAll(), encoding="utf-8") versionText = str(versionFile.readAll(), encoding="utf-8")
versionFile.close() 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.chartDelegate import ChartDelegate
from ui.extends.shared.delegates.scoreDelegate import ScoreDelegate from ui.extends.shared.delegates.scoreDelegate import ScoreDelegate
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.models.tables.b30 import ( from ui.extends.shared.models.tables.b30 import (
DbB30TableModel, DbB30TableModel,
DbB30TableSortFilterProxyModel, DbB30TableSortFilterProxyModel,
@ -34,6 +35,10 @@ class TableScoreDelegate(ScoreDelegate):
class DbB30TableViewer(DbTableViewer): class DbB30TableViewer(DbTableViewer):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.tableView.verticalHeader().setVisible(True) self.tableView.verticalHeader().setVisible(True)
self.tableModel = DbB30TableModel(self) 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.designer.tabs.tabDb.tabDb_Manage_ui import Ui_TabDb_Manage
from ui.extends.shared.database import databaseUpdateSignals from ui.extends.shared.database import databaseUpdateSignals
from ui.extends.shared.language import LanguageChangeEventFilter
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -27,6 +28,9 @@ class TabDb_Manage(Ui_TabDb_Manage, QWidget):
super().__init__(parent) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
@Slot() @Slot()
def on_syncArcSongDbButton_clicked(self): def on_syncArcSongDbButton_clicked(self):
dbFile, filter = QFileDialog.getOpenFileName( 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.chartDelegate import ChartDelegate
from ui.extends.shared.delegates.scoreDelegate import ScoreDelegate from ui.extends.shared.delegates.scoreDelegate import ScoreDelegate
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.models.tables.score import ( from ui.extends.shared.models.tables.score import (
DbScoreTableModel, DbScoreTableModel,
DbScoreTableSortFilterProxyModel, DbScoreTableSortFilterProxyModel,
@ -33,6 +34,9 @@ class DbScoreTableViewer(DbTableViewer):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.tableModel = DbScoreTableModel(self) self.tableModel = DbScoreTableModel(self)
self.tableProxyModel = DbScoreTableSortFilterProxyModel(self) self.tableProxyModel = DbScoreTableSortFilterProxyModel(self)
self.tableProxyModel.setSourceModel(self.tableModel) self.tableProxyModel.setSourceModel(self.tableModel)

View File

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

View File

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

View File

@ -1,5 +1,4 @@
import logging import logging
from pathlib import Path
import cv2 import cv2
from arcaea_offline_ocr.b30.chieri.v4.ocr import ChieriBotV4Ocr 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.designer.tabs.tabOcr.tabOcr_B30_ui import Ui_TabOcr_B30
from ui.extends.components.ocrQueue import OcrQueueModel from ui.extends.components.ocrQueue import OcrQueueModel
from ui.extends.shared.cv2_utils import cv2BgrMatToQImage, qImageToCvMatBgr 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.shared.settings import KNN_MODEL_FILE, SIFT_DATABASE_FILE, Settings
from ui.extends.tabs.tabOcr.tabOcr_B30 import ChieriV4OcrRunnable, b30ResultToScore from ui.extends.tabs.tabOcr.tabOcr_B30 import ChieriV4OcrRunnable, b30ResultToScore
@ -24,6 +24,9 @@ class TabOcr_B30(Ui_TabOcr_B30, QWidget):
super().__init__(parent) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.b30TypeComboBox.addItem("ChieriV4", "chieri_v4") self.b30TypeComboBox.addItem("ChieriV4", "chieri_v4")
self.b30TypeComboBox.setCurrentIndex(0) self.b30TypeComboBox.setCurrentIndex(0)
self.b30TypeComboBox.setEnabled(False) 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.designer.tabs.tabOcr.tabOcr_Device_ui import Ui_TabOcr_Device
from ui.extends.components.ocrQueue import OcrQueueModel from ui.extends.components.ocrQueue import OcrQueueModel
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.extends.shared.settings import ( from ui.extends.shared.settings import (
DEVICES_JSON_FILE, DEVICES_JSON_FILE,
KNN_MODEL_FILE, KNN_MODEL_FILE,
@ -32,6 +33,9 @@ class TabOcr_Device(Ui_TabOcr_Device, QWidget):
self.setupUi(self) self.setupUi(self)
self.openWizardButton.setEnabled(False) self.openWizardButton.setEnabled(False)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.deviceFileSelector.filesSelected.connect(self.deviceFileSelected) self.deviceFileSelector.filesSelected.connect(self.deviceFileSelected)
self.knnModelSelector.filesSelected.connect(self.knnModelFileSelected) self.knnModelSelector.filesSelected.connect(self.knnModelFileSelected)
self.siftDatabaseSelector.filesSelected.connect(self.siftDatabaseFileSelected) self.siftDatabaseSelector.filesSelected.connect(self.siftDatabaseFileSelected)

View File

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

View File

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

View File

@ -9,18 +9,10 @@ from arcaea_offline.external.andreal.api_data import (
from arcaea_offline.models import Chart from arcaea_offline.models import Chart
from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, Qt, Slot from PySide6.QtCore import QCoreApplication, QDir, QFileInfo, Qt, Slot
from PySide6.QtGui import QGuiApplication, QImage, QPainter, QPaintEvent, QPixmap from PySide6.QtGui import QGuiApplication, QImage, QPainter, QPaintEvent, QPixmap
from PySide6.QtWidgets import ( from PySide6.QtWidgets import QButtonGroup, QFileDialog, QLabel, QMessageBox, QWidget
QButtonGroup,
QDialog,
QDialogButtonBox,
QFileDialog,
QLabel,
QMessageBox,
QVBoxLayout,
QWidget,
)
from ui.designer.tabs.tabTools.tabTools_Andreal_ui import Ui_TabTools_Andreal 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.shared.settings import ANDREAL_EXECUTABLE, ANDREAL_FOLDER
from ui.extends.tabs.tabTools.tabTools_Andreal import AndrealHelper from ui.extends.tabs.tabTools.tabTools_Andreal import AndrealHelper
from ui.implements.components.chartSelector import ChartSelector from ui.implements.components.chartSelector import ChartSelector
@ -69,32 +61,14 @@ class ChartSelectorDialog(ChartSelector):
self.setSongIdSelectorMode(SongIdSelectorMode.Chart) 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): class TabTools_Andreal(Ui_TabTools_Andreal, QWidget):
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.db = Database() self.db = Database()
self.andrealHelper = AndrealHelper(self) self.andrealHelper = AndrealHelper(self)
@ -125,10 +99,6 @@ class TabTools_Andreal(Ui_TabTools_Andreal, QWidget):
self.andrealHelper.ready.connect(self.generateReady) self.andrealHelper.ready.connect(self.generateReady)
self.andrealHelper.finished.connect(self.generateFinished) self.andrealHelper.finished.connect(self.generateFinished)
self.imageTypeWhatIsThisButton.clicked.connect(
lambda: ImageTypeWhatIsThisDialog(self).show()
)
self.imageTypeButtonGroup = QButtonGroup(self) self.imageTypeButtonGroup = QButtonGroup(self)
self.imageTypeButtonGroup.addButton(self.imageType_infoRadioButton, 0) self.imageTypeButtonGroup.addButton(self.imageType_infoRadioButton, 0)
self.imageTypeButtonGroup.addButton(self.imageType_bestRadioButton, 1) 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}" 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): def imageFormat(self):
buttonId = self.imageFormatButtonGroup.checkedId() buttonId = self.imageFormatButtonGroup.checkedId()
return ["jpg", "png"][buttonId] if buttonId > -1 else None 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 import re
from arcaea_offline.calculate import calculate_play_rating
from arcaea_offline.database import Database from arcaea_offline.database import Database
from PySide6.QtCore import QDateTime from PySide6.QtCore import QDateTime
from PySide6.QtWidgets import QVBoxLayout, QWidget from PySide6.QtWidgets import QVBoxLayout, QWidget
from ui.designer.tabs.tabTools.tabTools_InfoLookup_ui import Ui_TabTools_InfoLookup 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): class TabTools_InfoLookup(Ui_TabTools_InfoLookup, QWidget):
@ -12,6 +14,9 @@ class TabTools_InfoLookup(Ui_TabTools_InfoLookup, QWidget):
super().__init__(parent) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.ratingClassSelector.setLayout(QVBoxLayout) self.ratingClassSelector.setLayout(QVBoxLayout)
self.db = Database() 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.updateDifficultyLabels)
self.ratingClassSelector.valueChanged.connect(self.updateChartInfoLabels) 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("En - English [en]", "en")
self.langSelectComboBox.addItem("あ - Japanese [ja]", "ja") self.langSelectComboBox.addItem("あ - Japanese [ja]", "ja")
self.langSelectComboBox.addItem("한 - Korean [ko]", "ko") 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) chartInfo = self.db.get_chart_info(songId, ratingClass)
if not chartInfo:
self.resetChartInfoLabels()
return
self.chartConstantLabel.setText(str(chartInfo.constant / 10)) self.chartConstantLabel.setText(str(chartInfo.constant / 10))
self.chartNotesLabel.setText( self.chartNotesLabel.setText(
str(chartInfo.notes) if chartInfo.notes is not None else "-" 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 ( from ui.designer.tabs.tabTools.tabTools_StepCalculator_ui import (
Ui_TabTools_StepCalculator, Ui_TabTools_StepCalculator,
) )
from ui.extends.shared.language import LanguageChangeEventFilter
from ui.implements.components.chartAndScoreInput import ChartAndScoreInput from ui.implements.components.chartAndScoreInput import ChartAndScoreInput
from ui.implements.components.songIdSelector import SongIdSelectorMode from ui.implements.components.songIdSelector import SongIdSelectorMode
@ -90,6 +91,9 @@ class TabTools_StepCalculator(Ui_TabTools_StepCalculator, QWidget):
super().__init__(parent) super().__init__(parent)
self.setupUi(self) self.setupUi(self)
self.languageChangeEventFilter = LanguageChangeEventFilter(self)
self.installEventFilter(self.languageChangeEventFilter)
self.calculate_toStep_calculatePlayResultFromScoreButton.clicked.connect( self.calculate_toStep_calculatePlayResultFromScoreButton.clicked.connect(
self.openChartAndScoreInputDialog self.openChartAndScoreInputDialog
) )

View File

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

View File

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

View File

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