- 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:
parent
facdb59c66
commit
a1614cef68
3
NEWS.md
3
NEWS.md
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ¤t, 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 ¤t, 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue