diff --git a/ui/designer/tabs/tabTools/tabTools_ChartRecommend.ui b/ui/designer/tabs/tabTools/tabTools_ChartRecommend.ui new file mode 100644 index 0000000..4e5da0f --- /dev/null +++ b/ui/designer/tabs/tabTools/tabTools_ChartRecommend.ui @@ -0,0 +1,297 @@ + + + TabTools_ChartRecommend + + + + 0 + 0 + 668 + 546 + + + + TabTools_ChartRecommend + + + + + + constantRangeFromPlayRating + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + 3 + + + 100.000000000000000 + + + 0.100000000000000 + + + + + + + + + AA + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + EX + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + EX+ + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + ... + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + ... + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + ... + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + + + + + + chartsByConstant + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + 1 + + + 100.000000000000000 + + + 0.100000000000000 + + + + + + + ... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + refreshButton + + + + + + + + + + 0 + 0 + + + + + + + + + + + + chartsRecommendFromPlayRating + + + + + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + 3 + + + 100.000000000000000 + + + 0.100000000000000 + + + + + + + ± + + + + + + + 2.000000000000000 + + + 0.010000000000000 + + + 0.100000000000000 + + + + + + + ... + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + refreshButton + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + diff --git a/ui/designer/tabs/tabTools/tabTools_ChartRecommend_ui.py b/ui/designer/tabs/tabTools/tabTools_ChartRecommend_ui.py new file mode 100644 index 0000000..92fc2cc --- /dev/null +++ b/ui/designer/tabs/tabTools/tabTools_ChartRecommend_ui.py @@ -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 + diff --git a/ui/designer/tabs/tabToolsEntry.ui b/ui/designer/tabs/tabToolsEntry.ui index ae30179..83be3bf 100644 --- a/ui/designer/tabs/tabToolsEntry.ui +++ b/ui/designer/tabs/tabToolsEntry.ui @@ -29,6 +29,11 @@ tab.stepCalculator + + + tab.chartRecommend + + tab.andreal @@ -57,6 +62,12 @@
ui.implements.tabs.tabTools.tabTools_Andreal
1 + + TabTools_ChartRecommend + QWidget +
ui.implements.tabs.tabTools.tabTools_ChartRecommend
+ 1 +
diff --git a/ui/designer/tabs/tabToolsEntry_ui.py b/ui/designer/tabs/tabToolsEntry_ui.py index 7607b9c..c963061 100644 --- a/ui/designer/tabs/tabToolsEntry_ui.py +++ b/ui/designer/tabs/tabToolsEntry_ui.py @@ -19,6 +19,7 @@ from PySide6.QtWidgets import (QApplication, QSizePolicy, QTabWidget, QVBoxLayou QWidget) from ui.implements.tabs.tabTools.tabTools_Andreal import TabTools_Andreal +from ui.implements.tabs.tabTools.tabTools_ChartRecommend import TabTools_ChartRecommend from ui.implements.tabs.tabTools.tabTools_InfoLookup import TabTools_InfoLookup from ui.implements.tabs.tabTools.tabTools_StepCalculator import TabTools_StepCalculator @@ -38,6 +39,9 @@ class Ui_TabToolsEntry(object): self.tab_2 = TabTools_StepCalculator() self.tab_2.setObjectName(u"tab_2") self.tabWidget.addTab(self.tab_2, "") + self.tab_4 = TabTools_ChartRecommend() + self.tab_4.setObjectName(u"tab_4") + self.tabWidget.addTab(self.tab_4, "") self.tab_3 = TabTools_Andreal() self.tab_3.setObjectName(u"tab_3") self.tabWidget.addTab(self.tab_3, "") @@ -56,6 +60,7 @@ class Ui_TabToolsEntry(object): def retranslateUi(self, TabToolsEntry): self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("TabToolsEntry", u"tab.infoLookup", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("TabToolsEntry", u"tab.stepCalculator", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), QCoreApplication.translate("TabToolsEntry", u"tab.chartRecommend", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("TabToolsEntry", u"tab.andreal", None)) pass # retranslateUi diff --git a/ui/implements/tabs/tabTools/tabTools_ChartRecommend.py b/ui/implements/tabs/tabTools/tabTools_ChartRecommend.py new file mode 100644 index 0000000..a9a1b82 --- /dev/null +++ b/ui/implements/tabs/tabTools/tabTools_ChartRecommend.py @@ -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}
({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)}
-
{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() diff --git a/ui/resources/lang/en_US.ts b/ui/resources/lang/en_US.ts index 59fb82e..d6765f0 100644 --- a/ui/resources/lang/en_US.ts +++ b/ui/resources/lang/en_US.ts @@ -89,12 +89,12 @@ Continue - + dialog.tryInitExistingDatabase The existing database doesn't seem to be initialized properly, try initialize again? - + dialog.confirmNewDatabase Database file does not exist. Create now? @@ -283,22 +283,22 @@ validation OcrTableModel - + horizontalHeader.title.select Select - + horizontalHeader.title.imagePreview Image Preview - + horizontalHeader.title.chart Chart - + horizontalHeader.title.score Score @@ -314,54 +314,54 @@ validation ScoreEditor - - - - - - - - + + + + + + + + setNone None - + formLabel.date Time - + formLabel.comment Comment - + formLabel.preview Preview - + formLabel.score Score - + idAutoInsert (Auto insert) - + warnIfIncomplete Warn if incomplete - + commitButton Commit - + validate.ok OK @@ -406,57 +406,57 @@ validation Cannot verify an incomplete score. Commit anyway? - + confirmDialog.chartNotSet.title Chart not set - + confirmDialog.chartNotSet.text Chart not set, cannot commit. - + confirmDialog.scoreIncomplete.title Score incomplete - + confirmDialog.scoreIncomplete.text Necessary score field missing, cannot commit. - + validate.chartNotSet Chart not set - + validate.chartIncomple No chart data, cannot verify - + validate.scoreMismatch Possible invalid score - + validate.scoreEmpty Empty score - + validate.scoreIncomplete Missing necessary score field - + validate.scoreIncompleteForValidate Score incomplete, cannot verify - + validate.unknownState Unknown @@ -581,12 +581,12 @@ validation Manage - + tab.scoreTableViewer Table [Score] - + tab.b30TableViewer Table [B30] @@ -769,6 +769,11 @@ validation + tab.chartRecommend + Chart Recommend + + + tab.andreal Andreal Image Generator @@ -836,11 +841,35 @@ validation Generate - + imageWhatIsThisDialog.description Generate image of...<ul><li>/a - the most recent score</li><li>/a b30 - best30 image</li><li>/a info - best score of the selected chart</li></ul> + + TabTools_ChartRecommend + + + constantRangeFromPlayRating + Chart Constant Range from Play Rating + + + + chartsByConstant + Charts by Constant + + + + + refreshButton + Roll + + + + chartsRecommendFromPlayRating + Chart from Play Rating Based on Best Score + + TabTools_InfoLookup @@ -1008,6 +1037,11 @@ validation difficulty.title Title + + + playRatingCalculate + + TabTools_StepCalculator diff --git a/ui/resources/lang/zh_CN.ts b/ui/resources/lang/zh_CN.ts index 1d74fd2..d4d4fbc 100644 --- a/ui/resources/lang/zh_CN.ts +++ b/ui/resources/lang/zh_CN.ts @@ -89,12 +89,12 @@ 继续 - + dialog.tryInitExistingDatabase 现有的数据库似乎没有正确初始化,是否尝试再次初始化? - + dialog.confirmNewDatabase 数据库文件不存在,是否创建? @@ -282,22 +282,22 @@ OcrTableModel - + horizontalHeader.title.select 选择 - + horizontalHeader.title.imagePreview 图像预览 - + horizontalHeader.title.chart 谱面 - + horizontalHeader.title.score 分数 @@ -313,54 +313,54 @@ ScoreEditor - - - - - - - - + + + + + + + + setNone 置空 - + formLabel.date 时间 - + formLabel.comment 注释 - + formLabel.preview 预览 - + formLabel.score 分数 - + idAutoInsert (自动插入) - + warnIfIncomplete 不完整时要求确认 - + commitButton 提交 - + validate.ok OK @@ -405,57 +405,57 @@ 无法验证不完整的分数。继续提交吗? - + confirmDialog.chartNotSet.title 未指定谱面 - + confirmDialog.chartNotSet.text 未指定谱面,无法提交。 - + confirmDialog.scoreIncomplete.title 分数不完整 - + confirmDialog.scoreIncomplete.text 缺失必要的分数数据,无法提交。 - + validate.chartNotSet 未指定谱面 - + validate.chartIncomple 谱面数据缺失,无法验证分数 - + validate.scoreMismatch 分数可能有误 - + validate.scoreEmpty 分数为空 - + validate.scoreIncomplete 缺失必要分数数据 - + validate.scoreIncompleteForValidate 分数不完整,无法验证 - + validate.unknownState 未知 @@ -580,12 +580,12 @@ 管理 - + tab.scoreTableViewer 表 [分数] - + tab.b30TableViewer 表 [B30] @@ -768,6 +768,11 @@ + tab.chartRecommend + 谱面推荐 + + + tab.andreal Andreal 图片生成 @@ -835,11 +840,35 @@ 生成 - + imageWhatIsThisDialog.description 生成……<ul><li>/a - 最近一次成绩</li><li>/a b30 - /a b30</li><li>/a info - 所选谱面的最好成绩</li></ul> + + TabTools_ChartRecommend + + + constantRangeFromPlayRating + 由单曲 PTT 逆算谱面定数范围 + + + + chartsByConstant + 按定数查谱 + + + + + refreshButton + 换一批 + + + + chartsRecommendFromPlayRating + 由单曲 PTT 结合最好成绩推荐谱面 + + TabTools_InfoLookup @@ -1007,6 +1036,11 @@ difficulty.title 标题 + + + playRatingCalculate + + TabTools_StepCalculator