- enhancement: display problem case running time

- enhancement: set problem case input/expected output file
  - enhancement: auto position cursor in expected with output's cursor
This commit is contained in:
Roy Qu 2022-03-29 18:06:24 +08:00
parent facdb59c66
commit a1614cef68
12 changed files with 990 additions and 602 deletions

View File

@ -8,6 +8,9 @@ Red Panda C++ Version 1.0.2
- enhancement: timeout for problem case test
- enhancement: slightly reduce start up time
- enhancement: use icon to indicate missing project files in the project view
- enhancement: display problem case running time
- enhancement: set problem case input/expected output file
- enhancement: auto position cursor in expected with output's cursor
Red Panda C++ Version 1.0.1
- fix: only convert project icon file when it's filename doesn't end with ".ico"

File diff suppressed because it is too large Load Diff

View File

@ -54,7 +54,11 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
});
QProcess process;
bool errorOccurred = false;
QByteArray readed;
QByteArray buffer;
QByteArray output;
int noOutputTime = 0;
QElapsedTimer elapsedTimer;
process.setProgram(mFilename);
process.setArguments(splitProcessCommand(mArguments));
process.setWorkingDirectory(mWorkDir);
@ -84,14 +88,13 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
process.start();
process.waitForStarted(5000);
if (process.state()==QProcess::Running) {
if (fileExists(problemCase->inputFileName))
process.write(readFileToByteArray(problemCase->inputFileName));
else
process.write(problemCase->input.toUtf8());
process.closeWriteChannel();
}
QByteArray readed;
QByteArray buffer;
QByteArray output;
int noOutputTime = 0;
QElapsedTimer elapsedTimer;
elapsedTimer.start();
while (true) {
process.waitForFinished(mWaitForFinishTime);
@ -127,6 +130,7 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
noOutputTime += mWaitForFinishTime;
}
}
problemCase->runningTime=elapsedTimer.elapsed();
if (mExecTimeouted) {
problemCase->output = tr("Case Timeout");
emit resetOutput(problemCase->getId(), problemCase->output);

View File

@ -249,7 +249,6 @@ int main(int argc, char *argv[])
// qputenv("QT_DEVICE_PIXEL_RATIO ","auto");
// qputenv("QT_AUTO_SCREEN_SCALE_FACTOR","false");
//#endif
QApplication app(argc, argv);
QFile tempFile(QDir::tempPath()+QDir::separator()+"RedPandaDevCppStartUp.lock");
{
@ -389,6 +388,7 @@ int main(int argc, char *argv[])
tempFile.close();
tempFile.remove();
}
int retCode = app.exec();
QString configDir = pSettings->dirs().config();
// save settings

View File

@ -67,7 +67,8 @@
#include <QTextBlock>
#include <QTranslator>
#include <QFileIconProvider>
#include <MainWindow.h>
#include "MainWindow.h"
#include <QScrollBar>
#include "settingsdialog/settingsdialog.h"
#include "compiler/compilermanager.h"
@ -277,11 +278,11 @@ MainWindow::MainWindow(QWidget *parent)
mOJProblemSetNameCounter=1;
mOJProblemSetModel.rename(tr("Problem Set %1").arg(mOJProblemSetNameCounter));
ui->lstProblemSet->setModel(&mOJProblemSetModel);
ui->lstProblemCases->setModel(&mOJProblemModel);
ui->tblProblemCases->setModel(&mOJProblemModel);
connect(ui->lstProblemSet->selectionModel(),
&QItemSelectionModel::currentRowChanged,
this, &MainWindow::onProblemSetIndexChanged);
connect(ui->lstProblemCases->selectionModel(),
connect(ui->tblProblemCases->selectionModel(),
&QItemSelectionModel::currentRowChanged,
this, &MainWindow::onProblemCaseIndexChanged);
connect(&mOJProblemSetModel, &OJProblemSetModel::problemNameChanged,
@ -1382,6 +1383,11 @@ void MainWindow::updateActionIcons()
pIconsManager->setIcon(ui->btnRunAllProblemCases, IconsManager::ACTION_PROBLEM_RUN_CASES);
pIconsManager->setIcon(ui->btnCaseValidateOptions, IconsManager::ACTION_MISC_GEAR);
pIconsManager->setIcon(ui->btnProblemCaseClearInputFileName, IconsManager::ACTION_MISC_CLEAN);
pIconsManager->setIcon(ui->btnProblemCaseInputFileName, IconsManager::ACTION_MISC_FOLDER);
pIconsManager->setIcon(ui->btnProblemCaseClearExpectedOutputFileName, IconsManager::ACTION_MISC_CLEAN);
pIconsManager->setIcon(ui->btnProblemCaseExpectedOutputFileName, IconsManager::ACTION_MISC_FOLDER);
mProblem_Properties->setIcon(pIconsManager->getIcon(IconsManager::ACTION_PROBLEM_PROPERTIES));
@ -1559,7 +1565,7 @@ void MainWindow::runExecutable(const QString &exeName,const QString &filename,Ru
ui->tabMessages->setCurrentWidget(ui->tabProblem);
}
} else if (runType == RunType::CurrentProblemCase) {
QModelIndex index = ui->lstProblemCases->currentIndex();
QModelIndex index = ui->tblProblemCases->currentIndex();
if (index.isValid()) {
POJProblemCase problemCase =mOJProblemModel.getCase(index.row());
mCompilerManager->runProblem(exeName,params,QFileInfo(exeName).absolutePath(),
@ -3141,7 +3147,7 @@ void MainWindow::onProblemSetIndexChanged(const QModelIndex &current, const QMod
mOJProblemModel.setProblem(problem);
updateProblemTitle();
if (mOJProblemModel.count()>0) {
ui->lstProblemCases->setCurrentIndex(mOJProblemModel.index(0,0));
ui->tblProblemCases->setCurrentIndex(mOJProblemModel.index(0,0));
} else {
onProblemCaseIndexChanged(QModelIndex(),QModelIndex());
}
@ -3163,18 +3169,32 @@ void MainWindow::onProblemCaseIndexChanged(const QModelIndex &current, const QMo
if (idx.isValid()) {
POJProblemCase problemCase = mOJProblemModel.getCase(idx.row());
if (problemCase) {
ui->btnProblemCaseInputFileName->setEnabled(false);
ui->txtProblemCaseInputFileName->setEnabled(false);
ui->btnRemoveProblemCase->setEnabled(true);
ui->txtProblemCaseInput->setPlainText(problemCase->input);
ui->txtProblemCaseInput->setReadOnly(false);
ui->txtProblemCaseExpected->setPlainText(problemCase->expected);
ui->txtProblemCaseExpected->setReadOnly(false);
ui->btnProblemCaseInputFileName->setEnabled(true);
fillProblemCaseInputAndExpected(problemCase);
ui->txtProblemCaseOutput->clear();
ui->txtProblemCaseOutput->setPlainText(problemCase->output);
updateProblemCaseOutput(problemCase);
return;
}
}
ui->btnProblemCaseClearInputFileName->setVisible(false);
ui->btnProblemCaseInputFileName->setEnabled(false);
ui->txtProblemCaseInputFileName->setEnabled(false);
ui->txtProblemCaseInputFileName->clear();
ui->txtProblemCaseInputFileName->setToolTip("");
ui->btnProblemCaseClearExpectedOutputFileName->setVisible(false);
ui->btnProblemCaseExpectedOutputFileName->setEnabled(false);
ui->txtProblemCaseExpectedOutputFileName->setEnabled(false);
ui->txtProblemCaseExpectedOutputFileName->clear();
ui->txtProblemCaseExpectedOutputFileName->setToolTip("");
ui->btnRemoveProblemCase->setEnabled(false);
ui->txtProblemCaseInputFileName->clear();
ui->btnProblemCaseInputFileName->setEnabled(false);
ui->txtProblemCaseInput->clear();
ui->txtProblemCaseInput->setReadOnly(true);
ui->txtProblemCaseExpected->clear();
@ -4606,9 +4626,9 @@ void MainWindow::onOJProblemCaseStarted(const QString& id,int current, int total
POJProblemCase problemCase = mOJProblemModel.getCase(row);
problemCase->testState = ProblemCaseTestState::Testing;
mOJProblemModel.update(row);
QModelIndex idx = ui->lstProblemCases->currentIndex();
QModelIndex idx = ui->tblProblemCases->currentIndex();
if (!idx.isValid() || row != idx.row()) {
ui->lstProblemCases->setCurrentIndex(mOJProblemModel.index(row,0));
ui->tblProblemCases->setCurrentIndex(mOJProblemModel.index(row,0));
}
ui->txtProblemCaseOutput->clear();
}
@ -5922,6 +5942,38 @@ void MainWindow::newProjectUnitFile()
updateProjectView();
}
void MainWindow::fillProblemCaseInputAndExpected(const POJProblemCase &problemCase)
{
ui->btnProblemCaseInputFileName->setEnabled(true);
if (fileExists(problemCase->inputFileName)) {
ui->txtProblemCaseInput->setReadOnly(true);
ui->txtProblemCaseInput->setPlainText(readFileToByteArray(problemCase->inputFileName));
ui->btnProblemCaseClearInputFileName->setVisible(true);
ui->txtProblemCaseInputFileName->setText(extractFileName(problemCase->inputFileName));
ui->txtProblemCaseInputFileName->setToolTip(problemCase->inputFileName);
} else {
ui->txtProblemCaseInput->setReadOnly(false);
ui->txtProblemCaseInput->setPlainText(problemCase->input);
ui->btnProblemCaseClearInputFileName->setVisible(false);
ui->txtProblemCaseInputFileName->clear();
ui->txtProblemCaseInputFileName->setToolTip("");
}
ui->btnProblemCaseExpectedOutputFileName->setEnabled(true);
if (fileExists(problemCase->expectedOutputFileName)) {
ui->txtProblemCaseExpected->setReadOnly(true);
ui->txtProblemCaseExpected->setPlainText(readFileToByteArray(problemCase->expectedOutputFileName));
ui->btnProblemCaseClearExpectedOutputFileName->setVisible(true);
ui->txtProblemCaseExpectedOutputFileName->setText(extractFileName(problemCase->expectedOutputFileName));
ui->txtProblemCaseExpectedOutputFileName->setToolTip(problemCase->inputFileName);
} else {
ui->txtProblemCaseExpected->setReadOnly(false);
ui->txtProblemCaseExpected->setPlainText(problemCase->expected);
ui->btnProblemCaseClearExpectedOutputFileName->setVisible(false);
ui->txtProblemCaseExpectedOutputFileName->clear();
ui->txtProblemCaseExpectedOutputFileName->setToolTip("");
}
}
void MainWindow::doFilesViewRemoveFile(const QModelIndex &index)
{
if (!index.isValid())
@ -6166,7 +6218,11 @@ void MainWindow::updateProblemCaseOutput(POJProblemCase problemCase)
{
if (problemCase->testState == ProblemCaseTestState::Failed) {
QStringList output = textToLines(problemCase->output);
QStringList expected = textToLines(problemCase->expected);
QStringList expected;
if (fileExists(problemCase->expectedOutputFileName))
expected = readFileToLines(problemCase->expectedOutputFileName);
else
expected = textToLines(problemCase->expected);
for (int i=0;i<output.count();i++) {
if (i>=expected.count() || output[i]!=expected[i]) {
QTextBlock block = ui->txtProblemCaseOutput->document()->findBlockByLineNumber(i);
@ -6192,10 +6248,11 @@ void MainWindow::updateProblemCaseOutput(POJProblemCase problemCase)
void MainWindow::applyCurrentProblemCaseChanges()
{
QModelIndex idx = ui->lstProblemCases->currentIndex();
QModelIndex idx = ui->tblProblemCases->currentIndex();
if (idx.isValid()) {
POJProblemCase problemCase = mOJProblemModel.getCase(idx.row());
if (problemCase) {
if (!fileExists(problemCase->inputFileName))
problemCase->input = ui->txtProblemCaseInput->toPlainText();
problemCase->expected = ui->txtProblemCaseExpected->toPlainText();
}
@ -6495,7 +6552,7 @@ void MainWindow::on_btnAddProblem_clicked()
int startCount = mOJProblemSetModel.count();
QString name;
while (true) {
name = tr("Problem %1").arg(startCount);
name = tr("Problem %1").arg(startCount+1);
if (!mOJProblemSetModel.problemNameUsed(name))
break;
}
@ -6565,7 +6622,7 @@ void MainWindow::on_btnAddProblemCase_clicked()
int startCount = mOJProblemModel.count();
QString name;
while (true) {
name = tr("Problem Case %1").arg(startCount);
name = tr("Problem Case %1").arg(startCount+1);
if (!mOJProblemSetModel.problemNameUsed(name))
break;
}
@ -6573,7 +6630,7 @@ void MainWindow::on_btnAddProblemCase_clicked()
problemCase->name = name;
problemCase->testState = ProblemCaseTestState::NotTested;
mOJProblemModel.addCase(problemCase);
ui->lstProblemCases->setCurrentIndex(mOJProblemModel.index(mOJProblemModel.count()-1));
ui->tblProblemCases->setCurrentIndex(mOJProblemModel.index(mOJProblemModel.count()-1,0));
}
void MainWindow::on_btnRunAllProblemCases_clicked()
@ -6595,7 +6652,7 @@ void MainWindow::on_actionC_Reference_triggered()
void MainWindow::on_btnRemoveProblemCase_clicked()
{
QModelIndex idx = ui->lstProblemCases->currentIndex();
QModelIndex idx = ui->tblProblemCases->currentIndex();
if (idx.isValid()) {
mOJProblemModel.removeCase(idx.row());
}
@ -7322,3 +7379,74 @@ void MainWindow::on_actionMatch_Bracket_triggered()
}
}
void MainWindow::on_btnProblemCaseInputFileName_clicked()
{
QString fileName = QFileDialog::getOpenFileName(
this,
tr("Choose Input Data File"),
QString(),
tr("All files (*.*)"));
if (!fileName.isEmpty()) {
QModelIndex idx = ui->tblProblemCases->currentIndex();
POJProblemCase problemCase = mOJProblemModel.getCase(idx.row());
if (!problemCase)
return;
if (problemCase->inputFileName == fileName)
return;
problemCase->inputFileName = fileName;
fillProblemCaseInputAndExpected(problemCase);
}
}
void MainWindow::on_btnProblemCaseClearExpectedOutputFileName_clicked()
{
QModelIndex idx = ui->tblProblemCases->currentIndex();
POJProblemCase problemCase = mOJProblemModel.getCase(idx.row());
if (!problemCase)
return;
problemCase->expectedOutputFileName = "";
fillProblemCaseInputAndExpected(problemCase);
}
void MainWindow::on_btnProblemCaseClearInputFileName_clicked()
{
QModelIndex idx = ui->tblProblemCases->currentIndex();
POJProblemCase problemCase = mOJProblemModel.getCase(idx.row());
if (!problemCase)
return;
problemCase->inputFileName = "";
fillProblemCaseInputAndExpected(problemCase);
}
void MainWindow::on_btnProblemCaseExpectedOutputFileName_clicked()
{
QString fileName = QFileDialog::getOpenFileName(
this,
tr("Choose Expected Output Data File"),
QString(),
tr("All files (*.*)"));
if (!fileName.isEmpty()) {
QModelIndex idx = ui->tblProblemCases->currentIndex();
POJProblemCase problemCase = mOJProblemModel.getCase(idx.row());
if (!problemCase)
return;
if (problemCase->expectedOutputFileName == fileName)
return;
problemCase->expectedOutputFileName = fileName;
fillProblemCaseInputAndExpected(problemCase);
}
}
void MainWindow::on_txtProblemCaseOutput_cursorPositionChanged()
{
QTextCursor cursor = ui->txtProblemCaseOutput->textCursor();
int val = ui->txtProblemCaseOutput->verticalScrollBar()->value();
ui->txtProblemCaseExpected->setTextCursor(cursor);
ui->txtProblemCaseExpected->verticalScrollBar()->setValue(val);
}

View File

@ -254,6 +254,7 @@ private:
void prepareTabInfosData();
void prepareTabMessagesData();
void newProjectUnitFile();
void fillProblemCaseInputAndExpected(const POJProblemCase &problemCase);
void doFilesViewRemoveFile(const QModelIndex& index);
@ -646,6 +647,16 @@ private slots:
void on_actionMatch_Bracket_triggered();
void on_btnProblemCaseInputFileName_clicked();
void on_btnProblemCaseClearExpectedOutputFileName_clicked();
void on_btnProblemCaseClearInputFileName_clicked();
void on_btnProblemCaseExpectedOutputFileName_clicked();
void on_txtProblemCaseOutput_cursorPositionChanged();
private:
Ui::MainWindow *ui;
EditorList *mEditorList;

View File

@ -1338,13 +1338,22 @@
</widget>
</item>
<item>
<widget class="QListView" name="lstProblemCases">
<widget class="QTableView" name="tblProblemCases">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>200</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
</layout>
@ -1363,6 +1372,80 @@
<property name="bottomMargin">
<number>0</number>
</property>
<item row="2" column="1">
<widget class="QPlainTextEdit" name="txtProblemCaseOutput">
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPlainTextEdit" name="txtProblemCaseExpected">
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QWidget" name="widget_7" native="true">
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="1">
<widget class="QLineEdit" name="txtProblemCaseInputFileName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Input</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QToolButton" name="btnProblemCaseInputFileName">
<property name="toolTip">
<string>Choose Input File</string>
</property>
<property name="text">
<string>Choose Input File</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/053-open.png</normaloff>:/icons/images/newlook24/053-open.png</iconset>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QToolButton" name="btnProblemCaseClearInputFileName">
<property name="text">
<string>Clear</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/008-close.png</normaloff>:/icons/images/newlook24/008-close.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
@ -1370,39 +1453,68 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Input</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Expected</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPlainTextEdit" name="txtProblemCaseOutput">
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QPlainTextEdit" name="txtProblemCaseInput">
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPlainTextEdit" name="txtProblemCaseExpected">
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
<item row="0" column="2">
<widget class="QWidget" name="widget_8" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_18">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Expected</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="txtProblemCaseExpectedOutputFileName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnProblemCaseClearExpectedOutputFileName">
<property name="toolTip">
<string>Clear</string>
</property>
<property name="text">
<string>Clear</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/008-close.png</normaloff>:/icons/images/newlook24/008-close.png</iconset>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnProblemCaseExpectedOutputFileName">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/icons/images/newlook24/053-open.png</normaloff>:/icons/images/newlook24/053-open.png</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
@ -1422,7 +1534,7 @@
<x>0</x>
<y>0</y>
<width>1114</width>
<height>25</height>
<height>26</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">

View File

@ -31,8 +31,11 @@ struct OJProblemCase {
QString name;
QString input;
QString expected;
QString inputFileName;
QString expectedOutputFileName;
ProblemCaseTestState testState; // no persistence
QString output; // no persistence
int runningTime;
OJProblemCase();
public:

View File

@ -556,6 +556,13 @@ QStringList readFileToLines(const QString &fileName)
ok=false;
break;
}
if (s.endsWith("\r\n")) {
s.remove(s.length()-2,2);
} else if (s.endsWith("\r")) {
s.remove(s.length()-1,1);
} else if (s.endsWith("\n")){
s.remove(s.length()-1,1);
}
result.append(s);
}
if (!ok) {
@ -569,6 +576,13 @@ QStringList readFileToLines(const QString &fileName)
result.clear();
break;
}
if (s.endsWith("\r\n")) {
s.remove(s.length()-2,2);
} else if (s.endsWith("\r")) {
s.remove(s.length()-1,1);
} else if (s.endsWith("\n")){
s.remove(s.length()-1,1);
}
result.append(s);
}
}

View File

@ -112,6 +112,17 @@ void OJProblemSetModel::saveToFile(const QString &fileName)
QJsonObject caseObj;
caseObj["name"]=problemCase->name;
caseObj["input"]=problemCase->input;
QString path = problemCase->inputFileName;
QString prefix = includeTrailingPathDelimiter(extractFileDir(fileName));
if (path.startsWith(prefix, PATH_SENSITIVITY)) {
path = "%ProblemSetPath%/"+ path.mid(prefix.length());
}
caseObj["input_filename"]=path;
path = problemCase->expectedOutputFileName;
if (path.startsWith(prefix, PATH_SENSITIVITY)) {
path = "%ProblemSetPath%/"+ path.mid(prefix.length());
}
caseObj["expected_output_filename"]=path;
caseObj["expected"]=problemCase->expected;
cases.append(caseObj);
}
@ -160,6 +171,18 @@ void OJProblemSetModel::loadFromFile(const QString &fileName)
problemCase->name = caseObj["name"].toString();
problemCase->input = caseObj["input"].toString();
problemCase->expected = caseObj["expected"].toString();
QString path = caseObj["input_filename"].toString();
if (path.startsWith("%ProblemSetPath%/")) {
path = includeTrailingPathDelimiter(extractFileDir(fileName))+
path.mid(QLatin1String("%ProblemSetPath%/").size());
}
problemCase->inputFileName=path;
path = caseObj["expected_output_filename"].toString();
if (path.startsWith("%ProblemSetPath%/")) {
path = includeTrailingPathDelimiter(extractFileDir(fileName))+
path.mid(QLatin1String("%ProblemSetPath%/").size());
}
problemCase->expectedOutputFileName=path;
problemCase->testState = ProblemCaseTestState::NotTested;
problem->cases.append(problemCase);
}
@ -216,7 +239,7 @@ Qt::ItemFlags OJProblemSetModel::flags(const QModelIndex &) const
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
}
OJProblemModel::OJProblemModel(QObject *parent): QAbstractListModel(parent)
OJProblemModel::OJProblemModel(QObject *parent): QAbstractTableModel(parent)
{
}
@ -348,8 +371,11 @@ QVariant OJProblemModel::data(const QModelIndex &index, int role) const
return QVariant();
if (mProblem==nullptr)
return QVariant();
switch (index.column()) {
case 0:
if (role == Qt::DisplayRole || role == Qt::EditRole) {
return mProblem->cases[index.row()]->name;
POJProblemCase problemCase = mProblem->cases[index.row()];
return problemCase->name;
} else if (role == Qt::DecorationRole) {
switch (mProblem->cases[index.row()]->testState) {
case ProblemCaseTestState::Failed:
@ -362,6 +388,19 @@ QVariant OJProblemModel::data(const QModelIndex &index, int role) const
return QVariant();
}
}
break;
case 1:
if (role == Qt::DisplayRole) {
POJProblemCase problemCase = mProblem->cases[index.row()];
if (problemCase->testState == ProblemCaseTestState::Passed
|| problemCase->testState == ProblemCaseTestState::Failed)
return problemCase->runningTime/1000.0;
else
return "";
}
break;
}
return QVariant();
}
@ -369,9 +408,11 @@ bool OJProblemModel::setData(const QModelIndex &index, const QVariant &value, in
{
if (!index.isValid())
return false;
if (index.column()!=0)
return false;
if (mProblem==nullptr)
return false;
if (role == Qt::DisplayRole || role == Qt::EditRole) {
if (role == Qt::EditRole ) {
QString s = value.toString();
if (!s.isEmpty()) {
mProblem->cases[index.row()]->name = s;
@ -381,7 +422,28 @@ bool OJProblemModel::setData(const QModelIndex &index, const QVariant &value, in
return false;
}
Qt::ItemFlags OJProblemModel::flags(const QModelIndex &) const
Qt::ItemFlags OJProblemModel::flags(const QModelIndex &idx) const
{
return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
Qt::ItemFlags flags=Qt::ItemIsEnabled | Qt::ItemIsSelectable;
if (idx.column()==0)
flags |= Qt::ItemIsEditable ;
return flags;
}
int OJProblemModel::columnCount(const QModelIndex &parent) const
{
return 2;
}
QVariant OJProblemModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
switch (section) {
case 0:
return tr("Name");
case 1:
return tr("Time(sec)");
}
}
return QVariant();
}

View File

@ -17,11 +17,11 @@
#ifndef OJPROBLEMSETMODEL_H
#define OJPROBLEMSETMODEL_H
#include <QAbstractListModel>
#include <QAbstractTableModel>
#include <memory>
#include "../problems/ojproblemset.h"
class OJProblemModel: public QAbstractListModel {
class OJProblemModel: public QAbstractTableModel {
Q_OBJECT
public:
explicit OJProblemModel(QObject *parent = nullptr);
@ -47,6 +47,11 @@ public:
QVariant data(const QModelIndex &index, int role) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
// QAbstractItemModel interface
public:
int columnCount(const QModelIndex &parent) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
};
class OJProblemSetModel : public QAbstractListModel

View File

@ -1,14 +1,18 @@
win32-msvc{
#win32-msvc{
# CONFIG += c++11
# CONFIG -= app_bundle
#} else {
# TEMPLATE = app
# CONFIG += windows
# CONFIG -= app_bundle
# CONFIG -= qt
#}
CONFIG += c++11
CONFIG -= app_bundle
DEFINES -= UNICODE
} else {
TEMPLATE = app
CONFIG += windows
CONFIG -= app_bundle
CONFIG -= qt
}
DEFINES -= UNICODE
isEmpty(APP_NAME) {
APP_NAME = RedPandaCPP
}