From 84ae62b10768729b55bf1054ee1aa916556f8c1f Mon Sep 17 00:00:00 2001 From: ZnPdCo Date: Mon, 22 Dec 2025 14:29:11 +0800 Subject: [PATCH 1/4] feat(*): Make judge dialog non-modal to allow ranking list scrolling --- src/forms/judgingdialog.ui | 2 +- src/lemon.cpp | 27 ++++++++++++++++++++++++ src/lemon.h | 2 ++ src/resultviewer.cpp | 43 +++++++++++++++++++++----------------- src/resultviewer.h | 2 ++ 5 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/forms/judgingdialog.ui b/src/forms/judgingdialog.ui index 24489131..f65bfe1a 100755 --- a/src/forms/judgingdialog.ui +++ b/src/forms/judgingdialog.ui @@ -3,7 +3,7 @@ JudgingDialog - Qt::WindowModality::WindowModal + Qt::WindowModality::NonModal diff --git a/src/lemon.cpp b/src/lemon.cpp index 43fb77fe..41a5d750 100644 --- a/src/lemon.cpp +++ b/src/lemon.cpp @@ -81,6 +81,8 @@ LemonLime::LemonLime(QWidget *parent) : QMainWindow(parent), ui(new Ui::LemonLim connect(ui->moveDownButton, &QToolButton::clicked, this, &LemonLime::moveDownTask); connect(ui->resultViewer, &ResultViewer::itemSelectionChanged, this, &LemonLime::viewerSelectionChanged); connect(ui->resultViewer, &ResultViewer::contestantDeleted, this, &LemonLime::contestantDeleted); + connect(ui->resultViewer, &ResultViewer::requestEnterJudgeMode, this, &LemonLime::enterJudgeMode); + connect(ui->resultViewer, &ResultViewer::requestLeaveJudgeMode, this, &LemonLime::leaveJudgeMode); connect(ui->newAction, &QAction::triggered, this, &LemonLime::newAction); connect(ui->openAction, &QAction::triggered, this, &LemonLime::loadAction); connect(ui->saveAction, &QAction::triggered, this, &LemonLime::saveAction); @@ -597,6 +599,31 @@ void LemonLime::contestantDeleted() { ui->refreshAction->setEnabled(true); } +// 会锁定若干控件,防止用户操作,并禁止表格选中事件(这样双击时就会直接返回) +void LemonLime::enterJudgeMode() { + ui->tabWidget->tabBar()->setEnabled(false); + ui->cleanupButton->setEnabled(false); + ui->refreshButton->setEnabled(false); + ui->judgeButton->setEnabled(false); + ui->judgeAllButton->setEnabled(false); + ui->judgeUnjudgedButton->setEnabled(false); + ui->resultViewer->clearSelection(); + ui->resultViewer->setSelectionMode(QAbstractItemView::NoSelection); + + menuBar()->setEnabled(false); +} + +void LemonLime::leaveJudgeMode() { + ui->tabWidget->tabBar()->setEnabled(true); + ui->cleanupButton->setEnabled(true); + ui->refreshButton->setEnabled(true); + ui->judgeAllButton->setEnabled(true); + ui->judgeUnjudgedButton->setEnabled(true); + ui->resultViewer->setSelectionMode(QAbstractItemView::ExtendedSelection); + + menuBar()->setEnabled(true); +} + void LemonLime::saveContest(const QString &fileName) { QFile file(fileName); diff --git a/src/lemon.h b/src/lemon.h index 17385bc1..79049c58 100644 --- a/src/lemon.h +++ b/src/lemon.h @@ -65,6 +65,8 @@ class LemonLime : public QMainWindow { void moveDownTask(); void viewerSelectionChanged(); void contestantDeleted(); + void enterJudgeMode(); + void leaveJudgeMode(); void newAction(); void saveAction(); static void openFolderAction(); diff --git a/src/resultviewer.cpp b/src/resultviewer.cpp index c6c160ad..d2ada79a 100644 --- a/src/resultviewer.cpp +++ b/src/resultviewer.cpp @@ -96,34 +96,34 @@ void ResultViewer::setContest(Contest *contest) { } void ResultViewer::refreshViewer() { - clear(); - setRowCount(0); - setColumnCount(0); - - if (! curContest) + if (! curContest) { + clear(); + setRowCount(0); + setColumnCount(0); return; + } + clear(); + setSortingEnabled(false); - QStringList headerList; - headerList << tr("Rank") << tr("Name") << tr("Total Score"); - QList taskList = curContest->getTaskList(); Settings setting; curContest->copySettings(setting); ColorTheme colors = setting.getCurrentColorTheme(); - -#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) if (QGuiApplication::styleHints()->colorScheme() == Qt::ColorScheme::Dark) { colors.invertLightness(); LOG("Auto dark mode has been set"); } -#endif + + QStringList headerList; + headerList << tr("Rank") << tr("Name") << tr("Total Score"); + QList taskList = curContest->getTaskList(); for (auto &i : taskList) { headerList << i->getProblemTitle(); } - headerList << tr("Total Used Time (s)") << tr("Judging Time"); setColumnCount(taskList.size() + 5); setHorizontalHeaderLabels(headerList); horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + QList contestantList = curContest->getContestantList(); QList> sortList; QList fullScore; @@ -158,8 +158,6 @@ void ResultViewer::refreshViewer() { bg = colors.getColorPer(score, fullScore[j]); item(i, j + 3)->setBackground(bg); - - // qDebug() << i << j << bg; } else { item(i, j + 3)->setText(tr("Invalid")); } @@ -213,6 +211,7 @@ void ResultViewer::refreshViewer() { } } + setSortingEnabled(true); sortByColumn(0, Qt::AscendingOrder); } @@ -242,22 +241,24 @@ void ResultViewer::judgeSelected() { } auto *dialog = new JudgingDialog(this); - dialog->setModal(true); + emit requestEnterJudgeMode(); dialog->setContest(curContest); dialog->show(); dialog->judge(judgeList); delete dialog; refreshViewer(); + emit requestLeaveJudgeMode(); } void ResultViewer::judgeAll() { auto *dialog = new JudgingDialog(this); - dialog->setModal(true); + emit requestEnterJudgeMode(); dialog->setContest(curContest); dialog->show(); dialog->judgeAll(); delete dialog; refreshViewer(); + emit requestLeaveJudgeMode(); } void ResultViewer::judgeUnjudged() { @@ -282,12 +283,13 @@ void ResultViewer::judgeUnjudged() { } auto *dialog = new JudgingDialog(this); - dialog->setModal(true); + emit requestEnterJudgeMode(); dialog->setContest(curContest); dialog->show(); dialog->judge(judgeList); delete dialog; refreshViewer(); + emit requestLeaveJudgeMode(); } void ResultViewer::judgeGrey() { @@ -312,12 +314,13 @@ void ResultViewer::judgeGrey() { } auto *dialog = new JudgingDialog(this); - dialog->setModal(true); + emit requestEnterJudgeMode(); dialog->setContest(curContest); dialog->show(); dialog->judge(judgeList); delete dialog; refreshViewer(); + emit requestLeaveJudgeMode(); } void ResultViewer::judgeMagenta() { @@ -345,12 +348,13 @@ void ResultViewer::judgeMagenta() { } auto *dialog = new JudgingDialog(this); - dialog->setModal(true); + emit requestEnterJudgeMode(); dialog->setContest(curContest); dialog->show(); dialog->judge(judgeList); delete dialog; refreshViewer(); + emit requestLeaveJudgeMode(); } void ResultViewer::clearPath(const QString &curDir) { @@ -406,6 +410,7 @@ void ResultViewer::deleteContestant() { void ResultViewer::detailInformation() { QList selectionRange = selectedRanges(); + if (selectionRange.size() == 0) return; int index = selectionRange[0].topRow(); auto *dialog = new DetailDialog(this); dialog->setModal(true); diff --git a/src/resultviewer.h b/src/resultviewer.h index 3081919c..52be2c3b 100644 --- a/src/resultviewer.h +++ b/src/resultviewer.h @@ -44,4 +44,6 @@ class ResultViewer : public QTableWidget { signals: void contestantDeleted(); + void requestEnterJudgeMode(); + void requestLeaveJudgeMode(); }; From 24be60e1bfac2fb00bdc720d0cc6f1b0133c1f96 Mon Sep 17 00:00:00 2001 From: ZnPdCo Date: Mon, 22 Dec 2025 14:36:12 +0800 Subject: [PATCH 2/4] fmt --- src/resultviewer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/resultviewer.cpp b/src/resultviewer.cpp index d2ada79a..92c5632e 100644 --- a/src/resultviewer.cpp +++ b/src/resultviewer.cpp @@ -410,7 +410,8 @@ void ResultViewer::deleteContestant() { void ResultViewer::detailInformation() { QList selectionRange = selectedRanges(); - if (selectionRange.size() == 0) return; + if (selectionRange.size() == 0) + return; int index = selectionRange[0].topRow(); auto *dialog = new DetailDialog(this); dialog->setModal(true); From 3548d8638fb9d2ecbf066db2bf063c624c37461a Mon Sep 17 00:00:00 2001 From: ZnPdCo Date: Mon, 22 Dec 2025 14:39:40 +0800 Subject: [PATCH 3/4] fmt --- src/lemon.cpp | 8 ++++---- src/resultviewer.h | 4 ++-- src/statisticsbrowser.cpp | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/lemon.cpp b/src/lemon.cpp index 41a5d750..91b35517 100644 --- a/src/lemon.cpp +++ b/src/lemon.cpp @@ -610,7 +610,7 @@ void LemonLime::enterJudgeMode() { ui->resultViewer->clearSelection(); ui->resultViewer->setSelectionMode(QAbstractItemView::NoSelection); - menuBar()->setEnabled(false); + menuBar()->setEnabled(false); } void LemonLime::leaveJudgeMode() { @@ -621,7 +621,7 @@ void LemonLime::leaveJudgeMode() { ui->judgeUnjudgedButton->setEnabled(true); ui->resultViewer->setSelectionMode(QAbstractItemView::ExtendedSelection); - menuBar()->setEnabled(true); + menuBar()->setEnabled(true); } void LemonLime::saveContest(const QString &fileName) { @@ -906,8 +906,8 @@ void LemonLime::addTaskWithScoreScale(const QString &title, } } -auto LemonLime::compareFileName(const std::pair &a, - const std::pair &b) -> bool { +auto LemonLime::compareFileName(const std::pair &a, const std::pair &b) + -> bool { return (a.first.length() < b.first.length()) || (a.first.length() == b.first.length() && QString::localeAwareCompare(a.first, b.first) < 0); } diff --git a/src/resultviewer.h b/src/resultviewer.h index 52be2c3b..7065746a 100644 --- a/src/resultviewer.h +++ b/src/resultviewer.h @@ -44,6 +44,6 @@ class ResultViewer : public QTableWidget { signals: void contestantDeleted(); - void requestEnterJudgeMode(); - void requestLeaveJudgeMode(); + void requestEnterJudgeMode(); + void requestLeaveJudgeMode(); }; diff --git a/src/statisticsbrowser.cpp b/src/statisticsbrowser.cpp index a201ca3d..2aa83823 100644 --- a/src/statisticsbrowser.cpp +++ b/src/statisticsbrowser.cpp @@ -33,8 +33,8 @@ StatisticsBrowser::~StatisticsBrowser() { delete ui; } void StatisticsBrowser::setContest(Contest *contest) { curContest = contest; } -auto StatisticsBrowser::getScoreNormalChart(const QMap &scoreCount, int listSize, - int totalScore) -> QString { +auto StatisticsBrowser::getScoreNormalChart(const QMap &scoreCount, int listSize, int totalScore) + -> QString { QString buffer = ""; long long overallScoreSum = 0; double scoreDiscrim = 0; @@ -230,8 +230,8 @@ auto StatisticsBrowser::getTestcaseScoreChart(QList testCaseList, return buffer; } -auto StatisticsBrowser::checkValid(QList taskList, - const QList &contestantList) -> bool { +auto StatisticsBrowser::checkValid(QList taskList, const QList &contestantList) + -> bool { for (auto *i : taskList) { for (auto *j : i->getTestCaseList()) { if (j->getInputFiles().length() != j->getOutputFiles().length()) From 6b593a30781bac16138e45b4e2347a09bff3d13c Mon Sep 17 00:00:00 2001 From: ZnPdCo Date: Mon, 22 Dec 2025 14:46:24 +0800 Subject: [PATCH 4/4] fmt --- src/lemon.cpp | 4 ++-- src/statisticsbrowser.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lemon.cpp b/src/lemon.cpp index 91b35517..ba83d1a7 100644 --- a/src/lemon.cpp +++ b/src/lemon.cpp @@ -906,8 +906,8 @@ void LemonLime::addTaskWithScoreScale(const QString &title, } } -auto LemonLime::compareFileName(const std::pair &a, const std::pair &b) - -> bool { +auto LemonLime::compareFileName(const std::pair &a, + const std::pair &b) -> bool { return (a.first.length() < b.first.length()) || (a.first.length() == b.first.length() && QString::localeAwareCompare(a.first, b.first) < 0); } diff --git a/src/statisticsbrowser.cpp b/src/statisticsbrowser.cpp index 2aa83823..a201ca3d 100644 --- a/src/statisticsbrowser.cpp +++ b/src/statisticsbrowser.cpp @@ -33,8 +33,8 @@ StatisticsBrowser::~StatisticsBrowser() { delete ui; } void StatisticsBrowser::setContest(Contest *contest) { curContest = contest; } -auto StatisticsBrowser::getScoreNormalChart(const QMap &scoreCount, int listSize, int totalScore) - -> QString { +auto StatisticsBrowser::getScoreNormalChart(const QMap &scoreCount, int listSize, + int totalScore) -> QString { QString buffer = ""; long long overallScoreSum = 0; double scoreDiscrim = 0; @@ -230,8 +230,8 @@ auto StatisticsBrowser::getTestcaseScoreChart(QList testCaseList, return buffer; } -auto StatisticsBrowser::checkValid(QList taskList, const QList &contestantList) - -> bool { +auto StatisticsBrowser::checkValid(QList taskList, + const QList &contestantList) -> bool { for (auto *i : taskList) { for (auto *j : i->getTestCaseList()) { if (j->getInputFiles().length() != j->getOutputFiles().length())