- enhancement: set font for problem case input/output textedits

- enhancement: when run problem cases, updates output immediately
This commit is contained in:
Roy Qu 2021-12-15 19:12:16 +08:00
parent f0960f0dcb
commit 436a299ebb
12 changed files with 254 additions and 10 deletions

View File

@ -1,5 +1,7 @@
Version 0.11.2 For Dev-C++ 7 Beta Version 0.11.2 For Dev-C++ 7 Beta
- fix: button "run all problem cases" not disabled when compiling or debugging - fix: button "run all problem cases" not disabled when compiling or debugging
- enhancement: set font for problem case input/output textedits
- enhancement: when run problem cases, updates output immediately
Version 0.11.1 For Dev-C++ 7 Beta Version 0.11.1 For Dev-C++ 7 Beta
- enhancement: Problem's test case shouldn't accept rich text inputs - enhancement: Problem's test case shouldn't accept rich text inputs

View File

@ -245,6 +245,7 @@ void CompilerManager::runProblem(const QString &filename, const QString &argumen
if (mRunner!=nullptr) { if (mRunner!=nullptr) {
return; return;
} }
OJProblemCasesRunner * execRunner = new OJProblemCasesRunner(filename,arguments,workDir,problemCase); OJProblemCasesRunner * execRunner = new OJProblemCasesRunner(filename,arguments,workDir,problemCase);
mRunner = execRunner; mRunner = execRunner;
connect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated); connect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
@ -268,6 +269,7 @@ void CompilerManager::runProblem(const QString &filename, const QString &argumen
connect(mRunner, &Runner::runErrorOccurred, pMainWindow ,&MainWindow::onRunErrorOccured); connect(mRunner, &Runner::runErrorOccurred, pMainWindow ,&MainWindow::onRunErrorOccured);
connect(execRunner, &OJProblemCasesRunner::caseStarted, pMainWindow, &MainWindow::onOJProblemCaseStarted); connect(execRunner, &OJProblemCasesRunner::caseStarted, pMainWindow, &MainWindow::onOJProblemCaseStarted);
connect(execRunner, &OJProblemCasesRunner::caseFinished, pMainWindow, &MainWindow::onOJProblemCaseFinished); connect(execRunner, &OJProblemCasesRunner::caseFinished, pMainWindow, &MainWindow::onOJProblemCaseFinished);
connect(execRunner, &OJProblemCasesRunner::newOutputLineGetted, pMainWindow, &MainWindow::onOJProblemCaseNewOutputLineGetted);
mRunner->start(); mRunner->start();
} }

View File

@ -106,8 +106,25 @@ void ExecutableRunner::run()
process.closeReadChannel(QProcess::StandardOutput); process.closeReadChannel(QProcess::StandardOutput);
process.closeReadChannel(QProcess::StandardError); process.closeReadChannel(QProcess::StandardError);
process.closeWriteChannel(); process.closeWriteChannel();
#ifdef Q_OS_WIN
if (!mStartConsole) {
process.terminate(); process.terminate();
if (process.waitForFinished(1000)) {
break;
}
}
#else
process.terminate();
if (process.waitForFinished(1000)) {
break;
}
#endif
for (int i=0;i<10;i++) {
process.kill(); process.kill();
if (process.waitForFinished(100)) {
break;
}
}
break; break;
} }
if (errorOccurred) if (errorOccurred)

View File

@ -47,22 +47,30 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
} }
env.insert("PATH",path); env.insert("PATH",path);
process.setProcessEnvironment(env); process.setProcessEnvironment(env);
process.setCreateProcessArgumentsModifier([this](QProcess::CreateProcessArguments * args){
args->flags |= CREATE_NEW_CONSOLE;
args->startupInfo -> dwFlags |= STARTF_USESHOWWINDOW;
args->startupInfo->wShowWindow = SW_HIDE;
});
process.setProcessChannelMode(QProcess::MergedChannels); process.setProcessChannelMode(QProcess::MergedChannels);
process.connect(&process, &QProcess::errorOccurred, process.connect(&process, &QProcess::errorOccurred,
[&](){ [&](){
errorOccurred= true; errorOccurred= true;
}); });
problemCase->output.clear(); problemCase->output.clear();
process.start(); process.start(QProcess::ReadWrite|QProcess::Unbuffered);
process.waitForStarted(5000); process.waitForStarted(5000);
if (process.state()==QProcess::Running) { if (process.state()==QProcess::Running) {
process.write(problemCase->input.toUtf8()); process.write(problemCase->input.toUtf8());
process.closeWriteChannel(); process.closeWriteChannel();
} }
QByteArray readed; QByteArray readed;
QByteArray buffer;
QStringList outputLines;
while (true) { while (true) {
process.waitForFinished(1000); process.waitForFinished(100);
readed += process.readAll(); readed = process.readAll();
buffer += readed;
if (process.state()!=QProcess::Running) { if (process.state()!=QProcess::Running) {
break; break;
} }
@ -76,8 +84,30 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
} }
if (errorOccurred) if (errorOccurred)
break; break;
QList<QByteArray> lines = splitByteArrayToLines(buffer);
qDebug()<<"----do buffer----";
qDebug()<<readed;
qDebug()<<buffer;
qDebug()<<lines.count();
if (lines.count()>=2) {
for (int i=0;i<lines.count()-1;i++) {
QString line = QString::fromLocal8Bit(lines[i]);
emit newOutputLineGetted(problemCase->getId(),line);
outputLines.append(line);
}
buffer = lines.last();
while (buffer.endsWith('\0')) {
buffer.remove(buffer.length()-1,1);
}
}
}
buffer += process.readAll();
QList<QByteArray> lines = splitByteArrayToLines(buffer);
for (int i=0;i<lines.count();i++) {
QString line = QString::fromLocal8Bit(lines[i]);
emit newOutputLineGetted(problemCase->getId(),line);
outputLines.append(line);
} }
readed += process.readAll();
if (errorOccurred) { if (errorOccurred) {
//qDebug()<<"process error:"<<process.error(); //qDebug()<<"process error:"<<process.error();
switch (process.error()) { switch (process.error()) {
@ -101,7 +131,7 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
break; break;
} }
} }
problemCase->output = QString::fromUtf8(readed); problemCase->output = linesToText(outputLines);
} }
void OJProblemCasesRunner::run() void OJProblemCasesRunner::run()

View File

@ -16,6 +16,7 @@ public:
signals: signals:
void caseStarted(const QString& id, int current, int total); void caseStarted(const QString& id, int current, int total);
void caseFinished(const QString& id, int current, int total); void caseFinished(const QString& id, int current, int total);
void newOutputLineGetted(const QString&id, const QString& newOutputLine);
private: private:
void runCase(int index, POJProblemCase problemCase); void runCase(int index, POJProblemCase problemCase);
private: private:

View File

@ -545,6 +545,13 @@ void MainWindow::applySettings()
qApp->setFont(font); qApp->setFont(font);
this->setFont(font); this->setFont(font);
QFont caseEditorFont(pSettings->executor().caseEditorFontName(),
pSettings->executor().caseEditorFontSize());
font.setStyleStrategy(QFont::PreferAntialias);
ui->txtProblemCaseInput->setFont(caseEditorFont);
ui->txtProblemCaseOutput->setFont(caseEditorFont);
ui->txtProblemCaseExpected->setFont(caseEditorFont);
mTcpServer.close(); mTcpServer.close();
int idxProblem = ui->tabMessages->indexOf(ui->tabProblem); int idxProblem = ui->tabMessages->indexOf(ui->tabProblem);
ui->tabMessages->setTabEnabled(idxProblem,pSettings->executor().enableProblemSet()); ui->tabMessages->setTabEnabled(idxProblem,pSettings->executor().enableProblemSet());
@ -1193,7 +1200,6 @@ void MainWindow::runExecutable(const QString &exeName,const QString &filename,Ru
} }
} }
updateCompileActions();
QString params; QString params;
if (pSettings->executor().useParams()) { if (pSettings->executor().useParams()) {
params = pSettings->executor().params(); params = pSettings->executor().params();
@ -1221,6 +1227,7 @@ void MainWindow::runExecutable(const QString &exeName,const QString &filename,Ru
ui->tabMessages->setCurrentWidget(ui->tabProblem); ui->tabMessages->setCurrentWidget(ui->tabProblem);
} }
} }
updateCompileActions();
updateAppTitle(); updateAppTitle();
} }
@ -3719,6 +3726,7 @@ void MainWindow::onOJProblemCaseStarted(const QString& id,int current, int total
POJProblemCase problemCase = mOJProblemModel.getCase(row); POJProblemCase problemCase = mOJProblemModel.getCase(row);
problemCase->testState = ProblemCaseTestState::Testing; problemCase->testState = ProblemCaseTestState::Testing;
mOJProblemModel.update(row); mOJProblemModel.update(row);
ui->txtProblemCaseOutput->clear();
} }
} }
@ -3744,6 +3752,11 @@ void MainWindow::onOJProblemCaseFinished(const QString& id, int current, int tot
// ui->lblProblem->setText(mOJProblemModel.getProblemTitle()); // ui->lblProblem->setText(mOJProblemModel.getProblemTitle());
} }
void MainWindow::onOJProblemCaseNewOutputLineGetted(const QString &id, const QString &line)
{
ui->txtProblemCaseOutput->append(line);
}
void MainWindow::cleanUpCPUDialog() void MainWindow::cleanUpCPUDialog()
{ {
CPUDialog* ptr=mCPUDialog; CPUDialog* ptr=mCPUDialog;

View File

@ -174,6 +174,7 @@ public slots:
void onRunProblemFinished(); void onRunProblemFinished();
void onOJProblemCaseStarted(const QString& id, int current, int total); void onOJProblemCaseStarted(const QString& id, int current, int total);
void onOJProblemCaseFinished(const QString& id, int current, int total); void onOJProblemCaseFinished(const QString& id, int current, int total);
void onOJProblemCaseNewOutputLineGetted(const QString& id, const QString& line);
void cleanUpCPUDialog(); void cleanUpCPUDialog();
void onDebugCommandInput(const QString& command); void onDebugCommandInput(const QString& command);
void onDebugEvaluateInput(); void onDebugEvaluateInput();

View File

@ -2878,6 +2878,36 @@ void Settings::Executor::setIgnoreSpacesWhenValidatingCases(bool newIgnoreSpaces
mIgnoreSpacesWhenValidatingCases = newIgnoreSpacesWhenValidatingCases; mIgnoreSpacesWhenValidatingCases = newIgnoreSpacesWhenValidatingCases;
} }
bool Settings::Executor::caseEditorFontOnlyMonospaced() const
{
return mCaseEditorFontOnlyMonospaced;
}
void Settings::Executor::setCaseEditorFontOnlyMonospaced(bool newCaseEditorFontOnlyMonospaced)
{
mCaseEditorFontOnlyMonospaced = newCaseEditorFontOnlyMonospaced;
}
int Settings::Executor::caseEditorFontSize() const
{
return mCaseEditorFontSize;
}
void Settings::Executor::setCaseEditorFontSize(int newCaseEditorFontSize)
{
mCaseEditorFontSize = newCaseEditorFontSize;
}
const QString &Settings::Executor::caseEditorFontName() const
{
return mCaseEditorFontName;
}
void Settings::Executor::setCaseEditorFontName(const QString &newCaseEditorFontName)
{
mCaseEditorFontName = newCaseEditorFontName;
}
bool Settings::Executor::enableCompetitiveCompanion() const bool Settings::Executor::enableCompetitiveCompanion() const
{ {
return mEnableCompetitiveCompanion; return mEnableCompetitiveCompanion;
@ -2911,6 +2941,9 @@ void Settings::Executor::doSave()
saveValue("enable_competivie_companion", mEnableCompetitiveCompanion); saveValue("enable_competivie_companion", mEnableCompetitiveCompanion);
saveValue("competitive_companion_port", mCompetivieCompanionPort); saveValue("competitive_companion_port", mCompetivieCompanionPort);
saveValue("ignore_spaces_when_validating_cases", mIgnoreSpacesWhenValidatingCases); saveValue("ignore_spaces_when_validating_cases", mIgnoreSpacesWhenValidatingCases);
saveValue("case_editor_font_name",mCaseEditorFontName);
saveValue("case_editor_font_size",mCaseEditorFontSize);
saveValue("case_editor_font_only_monospaced",mCaseEditorFontOnlyMonospaced);
} }
bool Settings::Executor::pauseConsole() const bool Settings::Executor::pauseConsole() const
@ -2936,6 +2969,9 @@ void Settings::Executor::doLoad()
mEnableCompetitiveCompanion = boolValue("enable_competivie_companion",true); mEnableCompetitiveCompanion = boolValue("enable_competivie_companion",true);
mCompetivieCompanionPort = intValue("competitive_companion_port",10045); mCompetivieCompanionPort = intValue("competitive_companion_port",10045);
mIgnoreSpacesWhenValidatingCases = boolValue("ignore_spaces_when_validating_cases",false); mIgnoreSpacesWhenValidatingCases = boolValue("ignore_spaces_when_validating_cases",false);
mCaseEditorFontName = stringValue("case_editor_font_name","consolas");
mCaseEditorFontSize = intValue("case_editor_font_size",14);
mCaseEditorFontOnlyMonospaced = boolValue("case_editor_font_only_monospaced",true);
} }

View File

@ -797,6 +797,15 @@ public:
bool ignoreSpacesWhenValidatingCases() const; bool ignoreSpacesWhenValidatingCases() const;
void setIgnoreSpacesWhenValidatingCases(bool newIgnoreSpacesWhenValidatingCases); void setIgnoreSpacesWhenValidatingCases(bool newIgnoreSpacesWhenValidatingCases);
const QString &caseEditorFontName() const;
void setCaseEditorFontName(const QString &newCaseEditorFontName);
int caseEditorFontSize() const;
void setCaseEditorFontSize(int newCaseEditorFontSize);
bool caseEditorFontOnlyMonospaced() const;
void setCaseEditorFontOnlyMonospaced(bool newCaseEditorFontOnlyMonospaced);
private: private:
// general // general
bool mPauseConsole; bool mPauseConsole;
@ -811,6 +820,9 @@ public:
bool mEnableCompetitiveCompanion; bool mEnableCompetitiveCompanion;
int mCompetivieCompanionPort; int mCompetivieCompanionPort;
bool mIgnoreSpacesWhenValidatingCases; bool mIgnoreSpacesWhenValidatingCases;
QString mCaseEditorFontName;
int mCaseEditorFontSize;
bool mCaseEditorFontOnlyMonospaced;
protected: protected:
void doSave() override; void doSave() override;

View File

@ -21,6 +21,10 @@ void ExecutorProblemSetWidget::doLoad()
ui->grpCompetitiveCompanion->setChecked(pSettings->executor().enableCompetitiveCompanion()); ui->grpCompetitiveCompanion->setChecked(pSettings->executor().enableCompetitiveCompanion());
ui->spinPortNumber->setValue(pSettings->executor().competivieCompanionPort()); ui->spinPortNumber->setValue(pSettings->executor().competivieCompanionPort());
ui->chkIgnoreSpacesWhenValidatingCases->setChecked(pSettings->executor().ignoreSpacesWhenValidatingCases()); ui->chkIgnoreSpacesWhenValidatingCases->setChecked(pSettings->executor().ignoreSpacesWhenValidatingCases());
ui->cbFont->setCurrentFont(QFont(pSettings->executor().caseEditorFontName()));
ui->spinFontSize->setValue(pSettings->executor().caseEditorFontSize());
ui->chkOnlyMonospaced->setChecked(pSettings->executor().caseEditorFontOnlyMonospaced());
} }
void ExecutorProblemSetWidget::doSave() void ExecutorProblemSetWidget::doSave()
@ -29,6 +33,19 @@ void ExecutorProblemSetWidget::doSave()
pSettings->executor().setEnableCompetitiveCompanion(ui->grpCompetitiveCompanion->isChecked()); pSettings->executor().setEnableCompetitiveCompanion(ui->grpCompetitiveCompanion->isChecked());
pSettings->executor().setCompetivieCompanionPort(ui->spinPortNumber->value()); pSettings->executor().setCompetivieCompanionPort(ui->spinPortNumber->value());
pSettings->executor().setIgnoreSpacesWhenValidatingCases(ui->chkIgnoreSpacesWhenValidatingCases->isChecked()); pSettings->executor().setIgnoreSpacesWhenValidatingCases(ui->chkIgnoreSpacesWhenValidatingCases->isChecked());
pSettings->executor().setCaseEditorFontName(ui->cbFont->currentFont().family());
pSettings->executor().setCaseEditorFontOnlyMonospaced(ui->chkOnlyMonospaced->isChecked());
pSettings->executor().setCaseEditorFontSize(ui->spinFontSize->value());
pSettings->executor().save(); pSettings->executor().save();
pMainWindow->applySettings(); pMainWindow->applySettings();
} }
void ExecutorProblemSetWidget::on_chkOnlyMonospaced_stateChanged(int )
{
if (ui->chkOnlyMonospaced->isChecked()) {
ui->cbFont->setFontFilters(QFontComboBox::FontFilter::MonospacedFonts);
} else {
ui->cbFont->setFontFilters(QFontComboBox::FontFilter::AllFonts);
}
}

View File

@ -21,6 +21,8 @@ private:
protected: protected:
void doLoad() override; void doLoad() override;
void doSave() override; void doSave() override;
private slots:
void on_chkOnlyMonospaced_stateChanged(int arg1);
}; };
#endif // EXECUTORPROBLEMSETWIDGET_H #endif // EXECUTORPROBLEMSETWIDGET_H

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>545</width>
<height>300</height> <height>445</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -72,6 +72,117 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<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="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Font Size:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Font:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QWidget" name="widget_3" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<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="QSpinBox" name="spinFontSize"/>
</item>
<item>
<spacer name="horizontalSpacer_3">
<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>
<item row="0" column="1">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<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="QFontComboBox" name="cbFont">
<property name="editable">
<bool>false</bool>
</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>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkOnlyMonospaced">
<property name="text">
<string>Only Monospaced</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">