- enhancement: Show memory usage for problem cases.
This commit is contained in:
parent
325fe71567
commit
2520ddf8f5
2
NEWS.md
2
NEWS.md
|
@ -10,6 +10,8 @@ Red Panda C++ Version 2.6
|
|||
- enhancement: When current file is the project's makefile, show project's compiler set in the toolbar.
|
||||
- enhancement: Prevent error of "del" to stop make when rebuild project.
|
||||
- enhancement: Import FPS (free problem set) files.
|
||||
- enhancement: Show current problem's description in the problem list's mouse tip.
|
||||
- enhancement: Show memory usage for problem cases.
|
||||
|
||||
Red Panda C++ Version 2.5
|
||||
|
||||
|
|
|
@ -316,27 +316,40 @@ void CompilerManager::run(
|
|||
}
|
||||
|
||||
|
||||
void CompilerManager::runProblem(const QString &filename, const QString &arguments, const QString &workDir, POJProblemCase problemCase)
|
||||
void CompilerManager::runProblem(const QString &filename, const QString &arguments, const QString &workDir, POJProblemCase problemCase,
|
||||
const POJProblem& problem
|
||||
)
|
||||
{
|
||||
QMutexLocker locker(&mRunnerMutex);
|
||||
doRunProblem(filename, arguments, workDir, QVector<POJProblemCase> {problemCase});
|
||||
doRunProblem(filename, arguments, workDir, QVector<POJProblemCase> {problemCase}, problem);
|
||||
|
||||
}
|
||||
|
||||
void CompilerManager::runProblem(const QString &filename, const QString &arguments, const QString &workDir, const QVector<POJProblemCase>& problemCases)
|
||||
void CompilerManager::runProblem(const QString &filename, const QString &arguments, const QString &workDir, const QVector<POJProblemCase>& problemCases,
|
||||
const POJProblem& problem
|
||||
)
|
||||
{
|
||||
QMutexLocker locker(&mRunnerMutex);
|
||||
doRunProblem(filename, arguments, workDir, problemCases);
|
||||
doRunProblem(filename, arguments, workDir, problemCases, problem);
|
||||
}
|
||||
void CompilerManager::doRunProblem(const QString &filename, const QString &arguments, const QString &workDir, const QVector<POJProblemCase>& problemCases)
|
||||
void CompilerManager::doRunProblem(const QString &filename, const QString &arguments, const QString &workDir, const QVector<POJProblemCase>& problemCases,
|
||||
const POJProblem& problem)
|
||||
{
|
||||
if (mRunner!=nullptr) {
|
||||
return;
|
||||
}
|
||||
OJProblemCasesRunner * execRunner = new OJProblemCasesRunner(filename,arguments,workDir,problemCases);
|
||||
mRunner = execRunner;
|
||||
if (pSettings->executor().enableCaseTimeout())
|
||||
if (pSettings->executor().enableCaseLimit()) {
|
||||
execRunner->setExecTimeout(pSettings->executor().caseTimeout());
|
||||
execRunner->setMemoryLimit(pSettings->executor().caseMemoryLimit()*1024); //convert kb to bytes
|
||||
}
|
||||
size_t timeLimit = problem->getTimeLimit();
|
||||
size_t memoryLimit = problem->getMemoryLimit();
|
||||
if (timeLimit>0)
|
||||
execRunner->setExecTimeout(timeLimit);
|
||||
if (memoryLimit)
|
||||
execRunner->setMemoryLimit(memoryLimit);
|
||||
connect(mRunner, &Runner::finished, this ,&CompilerManager::onRunnerTerminated);
|
||||
connect(mRunner, &Runner::finished, mRunner ,&Runner::deleteLater);
|
||||
connect(mRunner, &Runner::finished, pMainWindow ,&MainWindow::onRunProblemFinished);
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
class Runner;
|
||||
class Project;
|
||||
class Compiler;
|
||||
struct OJProblem;
|
||||
using POJProblem = std::shared_ptr<OJProblem>;
|
||||
struct OJProblemCase;
|
||||
using POJProblemCase = std::shared_ptr<OJProblemCase>;
|
||||
class CompilerManager : public QObject
|
||||
|
@ -47,8 +49,13 @@ public:
|
|||
const QString& arguments,
|
||||
const QString& workDir,
|
||||
const QStringList& extraBinDir);
|
||||
void runProblem(const QString& filename, const QString& arguments, const QString& workDir, POJProblemCase problemCase);
|
||||
void runProblem(const QString& filename, const QString& arguments, const QString& workDir, const QVector<POJProblemCase> &problemCases);
|
||||
void runProblem(
|
||||
const QString& filename, const QString& arguments, const QString& workDir, POJProblemCase problemCase,
|
||||
const POJProblem& problem
|
||||
);
|
||||
void runProblem(const QString& filename, const QString& arguments, const QString& workDir, const QVector<POJProblemCase> &problemCases,
|
||||
const POJProblem& problem
|
||||
);
|
||||
void stopRun();
|
||||
void stopAllRunners();
|
||||
void stopPausing();
|
||||
|
@ -67,7 +74,9 @@ signals:
|
|||
void signalStopAllRunners();
|
||||
|
||||
private slots:
|
||||
void doRunProblem(const QString& filename, const QString& arguments, const QString& workDir, const QVector<POJProblemCase> &problemCases);
|
||||
void doRunProblem(const QString& filename, const QString& arguments, const QString& workDir, const QVector<POJProblemCase> &problemCases,
|
||||
const POJProblem& problem
|
||||
);
|
||||
void onRunnerTerminated();
|
||||
void onRunnerPausing();
|
||||
void onCompileFinished();
|
||||
|
|
|
@ -21,12 +21,16 @@
|
|||
#include "../widgets/ojproblemsetmodel.h"
|
||||
#include <QElapsedTimer>
|
||||
#include <QProcess>
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include <psapi.h>
|
||||
#endif
|
||||
|
||||
|
||||
OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
||||
const QVector<POJProblemCase>& problemCases, QObject *parent):
|
||||
Runner(filename,arguments,workDir,parent),
|
||||
mExecTimeout(-1)
|
||||
mExecTimeout(0),
|
||||
mMemoryLimit(0)
|
||||
{
|
||||
mProblemCases = problemCases;
|
||||
mBufferSize = 8192;
|
||||
|
@ -37,7 +41,8 @@ OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QStrin
|
|||
OJProblemCasesRunner::OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
||||
POJProblemCase problemCase, QObject *parent):
|
||||
Runner(filename,arguments,workDir,parent),
|
||||
mExecTimeout(-1)
|
||||
mExecTimeout(0),
|
||||
mMemoryLimit(0)
|
||||
{
|
||||
mProblemCases.append(problemCase);
|
||||
mBufferSize = 8192;
|
||||
|
@ -88,6 +93,12 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
|
|||
problemCase->output.clear();
|
||||
process.start();
|
||||
process.waitForStarted(5000);
|
||||
#ifdef Q_OS_WIN
|
||||
HANDLE hProcess = NULL;
|
||||
if (process.processId()!=0) {
|
||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,process.processId());
|
||||
}
|
||||
#endif
|
||||
if (process.state()==QProcess::Running) {
|
||||
if (fileExists(problemCase->inputFileName))
|
||||
process.write(readFileToByteArray(problemCase->inputFileName));
|
||||
|
@ -133,8 +144,22 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
|
|||
}
|
||||
}
|
||||
problemCase->runningTime=elapsedTimer.elapsed();
|
||||
problemCase->runningMemory = 0;
|
||||
#ifdef Q_OS_WIN
|
||||
if (hProcess!=NULL) {
|
||||
PROCESS_MEMORY_COUNTERS counter{0};
|
||||
counter.cb = sizeof(counter);
|
||||
if (GetProcessMemoryInfo(hProcess,&counter,
|
||||
sizeof(counter))){
|
||||
problemCase->runningMemory = counter.PeakWorkingSetSize;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (execTimeouted) {
|
||||
problemCase->output = tr("Case Timeout");
|
||||
problemCase->output = tr("Time limit exceeded!");
|
||||
emit resetOutput(problemCase->getId(), problemCase->output);
|
||||
} else if (mMemoryLimit>0 && problemCase->runningMemory>mMemoryLimit) {
|
||||
problemCase->output = tr("Memory limit exceeded!");
|
||||
emit resetOutput(problemCase->getId(), problemCase->output);
|
||||
} else {
|
||||
if (process.state() == QProcess::ProcessState::NotRunning)
|
||||
|
@ -142,6 +167,7 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
|
|||
emit newOutputGetted(problemCase->getId(),QString::fromLocal8Bit(buffer));
|
||||
output.append(buffer);
|
||||
problemCase->output = QString::fromLocal8Bit(output);
|
||||
|
||||
if (errorOccurred) {
|
||||
//qDebug()<<"process error:"<<process.error();
|
||||
switch (process.error()) {
|
||||
|
@ -192,6 +218,11 @@ void OJProblemCasesRunner::setExecTimeout(int newExecTimeout)
|
|||
mExecTimeout = newExecTimeout;
|
||||
}
|
||||
|
||||
void OJProblemCasesRunner::setMemoryLimit(size_t limit)
|
||||
{
|
||||
mMemoryLimit = limit;
|
||||
}
|
||||
|
||||
int OJProblemCasesRunner::waitForFinishTime() const
|
||||
{
|
||||
return mWaitForFinishTime;
|
||||
|
|
|
@ -26,9 +26,11 @@ class OJProblemCasesRunner : public Runner
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
||||
const QVector<POJProblemCase>& problemCases, QObject *parent = nullptr);
|
||||
const QVector<POJProblemCase>& problemCases,
|
||||
QObject *parent = nullptr);
|
||||
explicit OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir,
|
||||
POJProblemCase problemCase, QObject *parent = nullptr);
|
||||
POJProblemCase problemCase,
|
||||
QObject *parent = nullptr);
|
||||
//max size of output buffer
|
||||
int bufferSize() const;
|
||||
void setBufferSize(int newBufferSize);
|
||||
|
@ -43,6 +45,8 @@ public:
|
|||
int execTimeout() const;
|
||||
void setExecTimeout(int newExecTimeout);
|
||||
|
||||
void setMemoryLimit(size_t limit);
|
||||
|
||||
signals:
|
||||
void caseStarted(const QString &caseId, int current, int total);
|
||||
void caseFinished(const QString &caseId, int current, int total);
|
||||
|
@ -60,6 +64,7 @@ private:
|
|||
int mBufferSize;
|
||||
int mOutputRefreshTime;
|
||||
int mExecTimeout;
|
||||
size_t mMemoryLimit;
|
||||
};
|
||||
|
||||
#endif // OJPROBLEMCASESRUNNER_H
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
#ifdef Q_OS_WIN
|
||||
#include <QMimeDatabase>
|
||||
#include <QMimeType>
|
||||
#include <QToolTip>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
@ -1933,7 +1934,8 @@ void MainWindow::runExecutable(
|
|||
POJProblem problem = mOJProblemModel.problem();
|
||||
if (problem) {
|
||||
mCompilerManager->runProblem(exeName,params,QFileInfo(exeName).absolutePath(),
|
||||
problem->cases);
|
||||
problem->cases,
|
||||
problem);
|
||||
stretchMessagesPanel(true);
|
||||
ui->tabMessages->setCurrentWidget(ui->tabProblem);
|
||||
}
|
||||
|
@ -1941,8 +1943,10 @@ void MainWindow::runExecutable(
|
|||
QModelIndex index = ui->tblProblemCases->currentIndex();
|
||||
if (index.isValid()) {
|
||||
POJProblemCase problemCase =mOJProblemModel.getCase(index.row());
|
||||
POJProblem problem = mOJProblemModel.problem();
|
||||
mCompilerManager->runProblem(exeName,params,QFileInfo(exeName).absolutePath(),
|
||||
problemCase);
|
||||
problemCase,
|
||||
problem);
|
||||
stretchMessagesPanel(true);
|
||||
ui->tabMessages->setCurrentWidget(ui->tabProblem);
|
||||
}
|
||||
|
@ -2675,6 +2679,20 @@ void MainWindow::buildContextMenus()
|
|||
connect(mProblem_OpenSource, &QAction::triggered, this,
|
||||
&MainWindow::onProblemOpenSource);
|
||||
|
||||
mProblem_Rename=createActionFor(
|
||||
tr("Rename Problem"),
|
||||
ui->lstProblemSet
|
||||
);
|
||||
connect(mProblem_Rename, &QAction::triggered, this,
|
||||
&MainWindow::onProblemRename);
|
||||
|
||||
mProblem_GotoUrl=createActionFor(
|
||||
tr("Goto Url"),
|
||||
ui->lstProblemSet
|
||||
);
|
||||
connect(mProblem_GotoUrl, &QAction::triggered, this,
|
||||
&MainWindow::onProblemGotoUrl);
|
||||
|
||||
//context menu signal for the problem list view
|
||||
ui->tblProblemCases->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(ui->tblProblemCases, &QWidget::customContextMenuRequested,
|
||||
|
@ -3558,6 +3576,9 @@ void MainWindow::onLstProblemSetContextMenu(const QPoint &pos)
|
|||
QMenu menu(this);
|
||||
QModelIndex idx = ui->lstProblemSet->currentIndex();
|
||||
mProblem_Properties->setEnabled(idx.isValid());
|
||||
mProblem_Rename->setEnabled(idx.isValid());
|
||||
menu.addAction(mProblem_Rename);
|
||||
menu.addAction(mProblem_GotoUrl);
|
||||
if (idx.isValid()) {
|
||||
POJProblem problem = mOJProblemSetModel.problem(idx.row());
|
||||
QMenu * menuSetAnswer = new QMenu(&menu);
|
||||
|
@ -3614,7 +3635,11 @@ void MainWindow::onLstProblemSetContextMenu(const QPoint &pos)
|
|||
});
|
||||
menuSetAnswer->addAction(action);
|
||||
menu.addMenu(menuSetAnswer);
|
||||
mProblem_GotoUrl->setEnabled(!problem->url.isEmpty());
|
||||
mProblem_OpenSource->setEnabled(!problem->answerProgram.isEmpty());
|
||||
} else {
|
||||
mProblem_GotoUrl->setEnabled(false);
|
||||
mProblem_OpenSource->setEnabled(false);
|
||||
}
|
||||
menu.addAction(mProblem_OpenSource);
|
||||
menu.addAction(mProblem_Properties);
|
||||
|
@ -4044,15 +4069,9 @@ void MainWindow::onProblemProperties()
|
|||
if (!problem)
|
||||
return;
|
||||
OJProblemPropertyWidget dialog;
|
||||
dialog.setName(problem->name);
|
||||
dialog.setUrl(problem->url);
|
||||
dialog.setDescription(problem->description);
|
||||
dialog.loadFromProblem(problem);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
problem->url = dialog.url();
|
||||
problem->description = dialog.description();
|
||||
if (problem == mOJProblemModel.problem()) {
|
||||
updateProblemTitle();
|
||||
}
|
||||
dialog.saveToProblem(problem);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4069,6 +4088,27 @@ void MainWindow::onProblemOpenSource()
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::onProblemRename()
|
||||
{
|
||||
QModelIndex idx = ui->lstProblemSet->currentIndex();
|
||||
if (!idx.isValid())
|
||||
return;
|
||||
ui->lstProblemSet->edit(idx);
|
||||
}
|
||||
|
||||
void MainWindow::onProblemGotoUrl()
|
||||
{
|
||||
QModelIndex idx = ui->lstProblemSet->currentIndex();
|
||||
if (!idx.isValid())
|
||||
return;
|
||||
POJProblem problem=mOJProblemSetModel.problem(idx.row());
|
||||
if (!problem)
|
||||
return;
|
||||
if (!problem->url.isEmpty()) {
|
||||
QDesktopServices::openUrl(problem->url);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onLableProblemSetContextMenuRequested()
|
||||
{
|
||||
QString newName = QInputDialog::getText(
|
||||
|
@ -8920,12 +8960,13 @@ void MainWindow::on_btnImportFPS_clicked()
|
|||
try {
|
||||
QList<POJProblem> problems = importFreeProblemSet(fileName);
|
||||
mOJProblemSetModel.addProblems(problems);
|
||||
ui->lblProblemSet->setText(mOJProblemSetModel.name());
|
||||
ui->lstProblemSet->setCurrentIndex(mOJProblemSetModel.index(0,0));
|
||||
} catch (FileError& error) {
|
||||
QMessageBox::critical(this,tr("Load Error"),
|
||||
error.reason());
|
||||
}
|
||||
}
|
||||
ui->lblProblemSet->setText(mOJProblemSetModel.name());
|
||||
ui->lstProblemSet->setCurrentIndex(mOJProblemSetModel.index(0,0));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -348,6 +348,9 @@ private slots:
|
|||
void onFilesViewRename();
|
||||
void onProblemProperties();
|
||||
void onProblemOpenSource();
|
||||
void onProblemRename();
|
||||
void onProblemGotoUrl();
|
||||
|
||||
void onLableProblemSetContextMenuRequested();
|
||||
void onBookmarkRemove();
|
||||
void onBookmarkRemoveAll();
|
||||
|
@ -881,6 +884,9 @@ private:
|
|||
//action for problem set
|
||||
QAction * mProblem_OpenSource;
|
||||
QAction * mProblem_Properties;
|
||||
QAction * mProblem_Rename;
|
||||
QAction * mProblem_GotoUrl;
|
||||
|
||||
|
||||
//action for problem
|
||||
QAction * mProblem_RunCurrentCase;
|
||||
|
|
|
@ -912,7 +912,7 @@
|
|||
<enum>QTabWidget::South</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
|
|
|
@ -35,17 +35,27 @@ QList<POJProblem> importFreeProblemSet(const QString &filename)
|
|||
currentCase->name = QObject::tr("Problem Case %1").arg(currentProblem->cases.count()+1);
|
||||
} else if (currentProblem &&
|
||||
xml.name()=="time_limit") {
|
||||
currentEleName = xml.name().toString();
|
||||
foreach (const QXmlStreamAttribute& attr, xml.attributes()) {
|
||||
if (attr.name() == "unit" && attr.value()=="ms") {
|
||||
currentEleName = attr.name().toString();
|
||||
if (attr.name() == "unit") {
|
||||
if (attr.value()=="ms")
|
||||
currentProblem->timeLimitUnit = ProblemTimeLimitUnit::Milliseconds;
|
||||
else if (attr.value()=="s")
|
||||
currentProblem->timeLimitUnit = ProblemTimeLimitUnit::Seconds;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (currentProblem &&
|
||||
xml.name()=="memory_limit") {
|
||||
currentEleName = xml.name().toString();
|
||||
foreach (const QXmlStreamAttribute& attr, xml.attributes()) {
|
||||
if (attr.name() == "unit" && attr.value()=="mb") {
|
||||
currentEleName = attr.name().toString();
|
||||
if (attr.name() == "unit") {
|
||||
if (attr.value()=="mb")
|
||||
currentProblem->memoryLimitUnit = ProblemMemoryLimitUnit::MB;
|
||||
else if (attr.value()=="kb")
|
||||
currentProblem->memoryLimitUnit = ProblemMemoryLimitUnit::KB;
|
||||
else if (attr.value()=="gb")
|
||||
currentProblem->memoryLimitUnit = ProblemMemoryLimitUnit::GB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +80,7 @@ QList<POJProblem> importFreeProblemSet(const QString &filename)
|
|||
} else if (currentProblem && currentEleName=="hint") {
|
||||
currentProblem->hint = xml.text().toString();
|
||||
} else if (currentProblem && currentEleName=="title") {
|
||||
currentProblem->name = xml.text().toString().trimmed();
|
||||
currentProblem->name = xml.text().toString().trimmed().replace(" "," ");
|
||||
} else if (currentProblem && currentEleName=="url") {
|
||||
currentProblem->url = xml.text().toString().trimmed();
|
||||
} else if (currentProblem && currentEleName=="time_limit") {
|
||||
|
|
|
@ -28,3 +28,34 @@ const QString &OJProblemCase::getId() const
|
|||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
size_t OJProblem::getTimeLimit()
|
||||
{
|
||||
switch(timeLimitUnit) {
|
||||
case ProblemTimeLimitUnit::Seconds:
|
||||
return timeLimit*1000;
|
||||
default:
|
||||
return timeLimit;
|
||||
}
|
||||
}
|
||||
|
||||
size_t OJProblem::getMemoryLimit()
|
||||
{
|
||||
switch(memoryLimitUnit) {
|
||||
case ProblemMemoryLimitUnit::KB:
|
||||
return memoryLimit*1024;
|
||||
case ProblemMemoryLimitUnit::MB:
|
||||
return memoryLimit*1024*1024;
|
||||
default:
|
||||
return memoryLimit*1024*1024*1024;
|
||||
}
|
||||
}
|
||||
|
||||
OJProblem::OJProblem() :
|
||||
timeLimit(0),
|
||||
memoryLimit(0),
|
||||
timeLimitUnit(ProblemTimeLimitUnit::Milliseconds),
|
||||
memoryLimitUnit(ProblemMemoryLimitUnit::MB)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,17 @@ enum class ProblemCaseTestState {
|
|||
Failed
|
||||
};
|
||||
|
||||
enum class ProblemTimeLimitUnit {
|
||||
Seconds,
|
||||
Milliseconds
|
||||
};
|
||||
|
||||
enum class ProblemMemoryLimitUnit {
|
||||
KB,
|
||||
MB,
|
||||
GB
|
||||
};
|
||||
|
||||
struct OJProblemCase {
|
||||
QString name;
|
||||
QString input;
|
||||
|
@ -35,9 +46,10 @@ struct OJProblemCase {
|
|||
QString expectedOutputFileName;
|
||||
ProblemCaseTestState testState; // no persistence
|
||||
QString output; // no persistence
|
||||
int runningTime;
|
||||
int firstDiffLine;
|
||||
int outputLineCounts;
|
||||
size_t runningTime; // no persistence
|
||||
size_t runningMemory; // no persistence;
|
||||
int firstDiffLine; // no persistence
|
||||
int outputLineCounts; // no persistence
|
||||
int expectedLineCounts;
|
||||
OJProblemCase();
|
||||
|
||||
|
@ -56,9 +68,14 @@ struct OJProblem {
|
|||
QString description;
|
||||
QString hint;
|
||||
QString answerProgram;
|
||||
int timeLimit; // ms
|
||||
int memoryLimit; // mb
|
||||
size_t timeLimit;
|
||||
size_t memoryLimit;
|
||||
ProblemTimeLimitUnit timeLimitUnit;
|
||||
ProblemMemoryLimitUnit memoryLimitUnit;
|
||||
QVector<POJProblemCase> cases;
|
||||
size_t getTimeLimit();
|
||||
size_t getMemoryLimit();
|
||||
OJProblem();
|
||||
};
|
||||
|
||||
using POJProblem = std::shared_ptr<OJProblem>;
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include <QStandardPaths>
|
||||
#include <QScreen>
|
||||
#include <QDesktopWidget>
|
||||
#include <QHash>
|
||||
#include <iterator>
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <sys/sysinfo.h>
|
||||
#endif
|
||||
|
@ -334,6 +332,11 @@ int Settings::_Base::intValue(const QString &key, int defaultValue)
|
|||
return value(key,defaultValue).toInt();
|
||||
}
|
||||
|
||||
unsigned int Settings::_Base::uintValue(const QString &key, unsigned int defaultValue)
|
||||
{
|
||||
return value(key,defaultValue).toUInt();
|
||||
}
|
||||
|
||||
QStringList Settings::_Base::stringListValue(const QString &key, const QStringList &defaultValue)
|
||||
{
|
||||
return value(key,defaultValue).toStringList();
|
||||
|
@ -3478,24 +3481,34 @@ void Settings::Executor::setCaseEditorFontOnlyMonospaced(bool newCaseEditorFontO
|
|||
mCaseEditorFontOnlyMonospaced = newCaseEditorFontOnlyMonospaced;
|
||||
}
|
||||
|
||||
int Settings::Executor::caseTimeout() const
|
||||
size_t Settings::Executor::caseTimeout() const
|
||||
{
|
||||
return mCaseTimeout;
|
||||
}
|
||||
|
||||
void Settings::Executor::setCaseTimeout(int newCaseTimeout)
|
||||
void Settings::Executor::setCaseTimeout(size_t newCaseTimeout)
|
||||
{
|
||||
mCaseTimeout = newCaseTimeout;
|
||||
}
|
||||
|
||||
bool Settings::Executor::enableCaseTimeout() const
|
||||
size_t Settings::Executor::caseMemoryLimit() const
|
||||
{
|
||||
return mEnableCaseTimeout;
|
||||
return mCaseMemoryLimit;
|
||||
}
|
||||
|
||||
void Settings::Executor::setEnableCaseTimeout(bool newEnableCaseTimeout)
|
||||
void Settings::Executor::setCaseMemoryLimit(size_t newCaseMemoryLimit)
|
||||
{
|
||||
mEnableCaseTimeout = newEnableCaseTimeout;
|
||||
mCaseMemoryLimit = newCaseMemoryLimit;
|
||||
}
|
||||
|
||||
bool Settings::Executor::enableCaseLimit() const
|
||||
{
|
||||
return mEnableCaseLimit;
|
||||
}
|
||||
|
||||
void Settings::Executor::setEnableCaseLimit(bool newValue)
|
||||
{
|
||||
mEnableCaseLimit = newValue;
|
||||
}
|
||||
|
||||
int Settings::Executor::caseEditorFontSize() const
|
||||
|
@ -3555,8 +3568,9 @@ void Settings::Executor::doSave()
|
|||
saveValue("case_editor_font_size",mCaseEditorFontSize);
|
||||
saveValue("case_editor_font_only_monospaced",mCaseEditorFontOnlyMonospaced);
|
||||
saveValue("case_timeout_ms", mCaseTimeout);
|
||||
saveValue("case_memory_limit",mCaseMemoryLimit);
|
||||
remove("case_timeout");
|
||||
saveValue("enable_case_timeout", mEnableCaseTimeout);
|
||||
saveValue("enable_case_limit", mEnableCaseLimit);
|
||||
}
|
||||
|
||||
bool Settings::Executor::pauseConsole() const
|
||||
|
@ -3595,8 +3609,14 @@ void Settings::Executor::doLoad()
|
|||
if (case_timeout>0)
|
||||
mCaseTimeout = case_timeout*1000;
|
||||
else
|
||||
mCaseTimeout = intValue("case_timeout_ms", 2000);
|
||||
mEnableCaseTimeout = boolValue("enable_case_timeout", true);
|
||||
mCaseTimeout = uintValue("case_timeout_ms", 2000); //2000ms
|
||||
mCaseMemoryLimit = uintValue("case_memory_limit",0); // kb
|
||||
|
||||
mEnableCaseLimit = boolValue("enable_case_limit", true);
|
||||
//compatibility
|
||||
if (boolValue("enable_time_limit", true)) {
|
||||
mEnableCaseLimit=true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ private:
|
|||
bool boolValue(const QString &key, bool defaultValue);
|
||||
QSize sizeValue(const QString &key);
|
||||
int intValue(const QString &key, int defaultValue);
|
||||
unsigned int uintValue(const QString &key, unsigned int defaultValue);
|
||||
QStringList stringListValue(const QString &key, const QStringList& defaultValue=QStringList());
|
||||
QSet<QString> stringSetValue(const QString &key);
|
||||
QColor colorValue(const QString &key, const QColor& defaultValue);
|
||||
|
@ -874,11 +875,14 @@ public:
|
|||
bool caseEditorFontOnlyMonospaced() const;
|
||||
void setCaseEditorFontOnlyMonospaced(bool newCaseEditorFontOnlyMonospaced);
|
||||
|
||||
bool enableCaseTimeout() const;
|
||||
void setEnableCaseTimeout(bool newEnableCaseTimeout);
|
||||
bool enableCaseLimit() const;
|
||||
void setEnableCaseLimit(bool newValue);
|
||||
|
||||
int caseTimeout() const;
|
||||
void setCaseTimeout(int newCaseTimeout);
|
||||
size_t caseTimeout() const;
|
||||
void setCaseTimeout(size_t newCaseTimeout);
|
||||
|
||||
size_t caseMemoryLimit() const;
|
||||
void setCaseMemoryLimit(size_t newCaseMemoryLimit);
|
||||
|
||||
private:
|
||||
// general
|
||||
|
@ -897,8 +901,9 @@ public:
|
|||
QString mCaseEditorFontName;
|
||||
int mCaseEditorFontSize;
|
||||
bool mCaseEditorFontOnlyMonospaced;
|
||||
bool mEnableCaseTimeout;
|
||||
int mCaseTimeout;
|
||||
bool mEnableCaseLimit;
|
||||
size_t mCaseTimeout; //ms
|
||||
size_t mCaseMemoryLimit; //kb
|
||||
|
||||
protected:
|
||||
void doSave() override;
|
||||
|
|
|
@ -41,9 +41,10 @@ void ExecutorProblemSetWidget::doLoad()
|
|||
ui->cbFont->setCurrentFont(QFont(pSettings->executor().caseEditorFontName()));
|
||||
ui->spinFontSize->setValue(pSettings->executor().caseEditorFontSize());
|
||||
ui->chkOnlyMonospaced->setChecked(pSettings->executor().caseEditorFontOnlyMonospaced());
|
||||
ui->grpEnableTimeout->setChecked(pSettings->executor().enableCaseTimeout());
|
||||
ui->grpEnableTimeout->setChecked(pSettings->executor().enableCaseLimit());
|
||||
|
||||
ui->spinCaseTimeout->setValue(pSettings->executor().caseTimeout());
|
||||
ui->spinMemoryLimit->setValue(pSettings->executor().caseMemoryLimit());
|
||||
}
|
||||
|
||||
void ExecutorProblemSetWidget::doSave()
|
||||
|
@ -55,8 +56,10 @@ void ExecutorProblemSetWidget::doSave()
|
|||
pSettings->executor().setCaseEditorFontName(ui->cbFont->currentFont().family());
|
||||
pSettings->executor().setCaseEditorFontOnlyMonospaced(ui->chkOnlyMonospaced->isChecked());
|
||||
pSettings->executor().setCaseEditorFontSize(ui->spinFontSize->value());
|
||||
pSettings->executor().setEnableCaseTimeout(ui->grpEnableTimeout->isChecked());
|
||||
pSettings->executor().setEnableCaseLimit(ui->grpEnableTimeout->isChecked());
|
||||
pSettings->executor().setCaseTimeout(ui->spinCaseTimeout->value());
|
||||
pSettings->executor().setCaseMemoryLimit(ui->spinMemoryLimit->value());
|
||||
|
||||
pSettings->executor().save();
|
||||
pMainWindow->applySettings();
|
||||
}
|
||||
|
|
|
@ -75,13 +75,20 @@
|
|||
<item>
|
||||
<widget class="QGroupBox" name="grpEnableTimeout">
|
||||
<property name="title">
|
||||
<string>Timeout for Case Valdation</string>
|
||||
<string>Case Valdation Limit</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Time Limit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinCaseTimeout">
|
||||
<property name="specialValueText">
|
||||
<string/>
|
||||
|
@ -90,7 +97,7 @@
|
|||
<string>ms</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>100</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000000</number>
|
||||
|
@ -100,7 +107,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
|
@ -113,6 +120,23 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Memory Limit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinMemoryLimit">
|
||||
<property name="suffix">
|
||||
<string>kb</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -1867,7 +1867,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Timeout for Case Valdation</source>
|
||||
<translation>Tempo limite para validação de caso</translation>
|
||||
<translation type="vanished">Tempo limite para validação de caso</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Case Editor Font</source>
|
||||
|
@ -1889,6 +1889,22 @@
|
|||
<source>ms</source>
|
||||
<translation>ms</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Case Valdation Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Time Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Memory Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>kb</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>FileAssociationModel</name>
|
||||
|
@ -4737,7 +4753,15 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FPS Problem Set Files (*.fps)</source>
|
||||
<source>Rename Problem</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Goto Url</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FPS Problem Set Files (*.fps;*.xml)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
@ -4932,7 +4956,7 @@
|
|||
<name>OJProblemCasesRunner</name>
|
||||
<message>
|
||||
<source>Case Timeout</source>
|
||||
<translation>Tempo esgotado para o caso</translation>
|
||||
<translation type="vanished">Tempo esgotado para o caso</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The runner process '%1' failed to start.</source>
|
||||
|
@ -4950,6 +4974,14 @@
|
|||
<source>An error occurred when attempting to read from the runner process.</source>
|
||||
<translation>Falhar ao tentar ler a execução do processo.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Time limit exceeded!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Memory limit exceeded!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OJProblemModel</name>
|
||||
|
@ -4961,6 +4993,10 @@
|
|||
<source>Time(ms)</source>
|
||||
<translation>Tempo(ms)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Memory(kb)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OJProblemPropertyWidget</name>
|
||||
|
@ -4988,6 +5024,34 @@
|
|||
<source>Cancel</source>
|
||||
<translation>Cancelar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Time Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Memory Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>sec</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ms</source>
|
||||
<translation type="unfinished">ms</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>KB</source>
|
||||
<translation type="unfinished">KB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MB</source>
|
||||
<translation type="unfinished">MB</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>GB</source>
|
||||
<translation type="unfinished">GB</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Project</name>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1754,10 +1754,6 @@
|
|||
<source>Ignore spaces when validating problem cases</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Timeout for Case Valdation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Case Editor Font</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -1778,6 +1774,22 @@
|
|||
<source>ms</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Case Valdation Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Time Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Memory Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>kb</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>FileAssociationModel</name>
|
||||
|
@ -4578,7 +4590,15 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FPS Problem Set Files (*.fps)</source>
|
||||
<source>Rename Problem</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Goto Url</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>FPS Problem Set Files (*.fps;*.xml)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
|
@ -4759,10 +4779,6 @@
|
|||
</context>
|
||||
<context>
|
||||
<name>OJProblemCasesRunner</name>
|
||||
<message>
|
||||
<source>Case Timeout</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The runner process '%1' failed to start.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
|
@ -4779,6 +4795,14 @@
|
|||
<source>An error occurred when attempting to read from the runner process.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Time limit exceeded!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Memory limit exceeded!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OJProblemModel</name>
|
||||
|
@ -4790,6 +4814,10 @@
|
|||
<source>Time(ms)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Memory(kb)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>OJProblemPropertyWidget</name>
|
||||
|
@ -4817,6 +4845,34 @@
|
|||
<source>Cancel</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Time Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Memory Limit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>sec</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>ms</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>KB</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>MB</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>GB</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Project</name>
|
||||
|
|
|
@ -16,12 +16,22 @@
|
|||
*/
|
||||
#include "ojproblempropertywidget.h"
|
||||
#include "ui_ojproblempropertywidget.h"
|
||||
#include "../problems/ojproblemset.h"
|
||||
|
||||
OJProblemPropertyWidget::OJProblemPropertyWidget(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::OJProblemPropertyWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
QFont f = ui->lbName->font();
|
||||
f.setPixelSize(f.pixelSize()+2);
|
||||
f.setBold(true);
|
||||
ui->lbName->setFont(f);
|
||||
ui->cbTimeLimitUnit->addItem(tr("sec"));
|
||||
ui->cbTimeLimitUnit->addItem(tr("ms"));
|
||||
ui->cbMemoryLimitUnit->addItem(tr("KB"));
|
||||
ui->cbMemoryLimitUnit->addItem(tr("MB"));
|
||||
ui->cbMemoryLimitUnit->addItem(tr("GB"));
|
||||
}
|
||||
|
||||
OJProblemPropertyWidget::~OJProblemPropertyWidget()
|
||||
|
@ -29,38 +39,55 @@ OJProblemPropertyWidget::~OJProblemPropertyWidget()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void OJProblemPropertyWidget::setName(const QString &name)
|
||||
void OJProblemPropertyWidget::loadFromProblem(POJProblem problem)
|
||||
{
|
||||
QFont f = ui->lbName->font();
|
||||
f.setPixelSize(f.pixelSize()+2);
|
||||
f.setBold(true);
|
||||
ui->lbName->setFont(f);
|
||||
ui->lbName->setText(name);
|
||||
if (!problem)
|
||||
return;
|
||||
ui->lbName->setText(problem->name);
|
||||
ui->txtURL->setText(problem->url);
|
||||
ui->txtDescription->setHtml(problem->description);
|
||||
ui->spinMemoryLimit->setValue(problem->memoryLimit);
|
||||
ui->spinTimeLimit->setValue(problem->timeLimit);
|
||||
switch(problem->timeLimitUnit) {
|
||||
case ProblemTimeLimitUnit::Seconds:
|
||||
ui->cbTimeLimitUnit->setCurrentText(tr("sec"));
|
||||
break;
|
||||
case ProblemTimeLimitUnit::Milliseconds:
|
||||
ui->cbTimeLimitUnit->setCurrentText(tr("ms"));
|
||||
break;
|
||||
}
|
||||
switch(problem->memoryLimitUnit) {
|
||||
case ProblemMemoryLimitUnit::KB:
|
||||
ui->cbTimeLimitUnit->setCurrentText(tr("KB"));
|
||||
break;
|
||||
case ProblemMemoryLimitUnit::MB:
|
||||
ui->cbTimeLimitUnit->setCurrentText(tr("MB"));
|
||||
break;
|
||||
case ProblemMemoryLimitUnit::GB:
|
||||
ui->cbTimeLimitUnit->setCurrentText(tr("GB"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OJProblemPropertyWidget::setUrl(const QString &url)
|
||||
void OJProblemPropertyWidget::saveToProblem(POJProblem problem)
|
||||
{
|
||||
ui->txtURL->setText(url);
|
||||
}
|
||||
|
||||
void OJProblemPropertyWidget::setDescription(const QString &description)
|
||||
{
|
||||
ui->txtDescription->setHtml(description);
|
||||
}
|
||||
|
||||
QString OJProblemPropertyWidget::name()
|
||||
{
|
||||
return ui->lbName->text();
|
||||
}
|
||||
|
||||
QString OJProblemPropertyWidget::url()
|
||||
{
|
||||
return ui->txtURL->text();
|
||||
}
|
||||
|
||||
QString OJProblemPropertyWidget::description()
|
||||
{
|
||||
return ui->txtDescription->toHtml();
|
||||
if (!problem)
|
||||
return;
|
||||
problem->name = ui->lbName->text();
|
||||
problem->url = ui->txtURL->text();
|
||||
problem->description = ui->txtDescription->toHtml();
|
||||
problem->memoryLimit = ui->spinMemoryLimit->value();
|
||||
problem->timeLimit = ui->spinTimeLimit->value();
|
||||
if (ui->cbTimeLimitUnit->currentText()=="sec")
|
||||
problem->timeLimitUnit = ProblemTimeLimitUnit::Seconds;
|
||||
else
|
||||
problem->timeLimitUnit = ProblemTimeLimitUnit::Milliseconds;
|
||||
if (ui->cbTimeLimitUnit->currentText()=="KB")
|
||||
problem->memoryLimitUnit = ProblemMemoryLimitUnit::KB;
|
||||
else if (ui->cbTimeLimitUnit->currentText()=="MB")
|
||||
problem->memoryLimitUnit = ProblemMemoryLimitUnit::MB;
|
||||
else
|
||||
problem->memoryLimitUnit = ProblemMemoryLimitUnit::GB;
|
||||
}
|
||||
|
||||
void OJProblemPropertyWidget::on_btnOk_clicked()
|
||||
|
|
|
@ -18,11 +18,14 @@
|
|||
#define OJPROBLEMPROPERTYWIDGET_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui {
|
||||
class OJProblemPropertyWidget;
|
||||
}
|
||||
|
||||
class OJProblem;
|
||||
using POJProblem = std::shared_ptr<OJProblem>;
|
||||
class OJProblemPropertyWidget : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -30,12 +33,8 @@ class OJProblemPropertyWidget : public QDialog
|
|||
public:
|
||||
explicit OJProblemPropertyWidget(QWidget *parent = nullptr);
|
||||
~OJProblemPropertyWidget();
|
||||
void setName(const QString& name);
|
||||
void setUrl(const QString& url);
|
||||
void setDescription(const QString& description);
|
||||
QString name();
|
||||
QString url();
|
||||
QString description();
|
||||
void loadFromProblem(POJProblem problem);
|
||||
void saveToProblem(POJProblem problem);
|
||||
|
||||
private slots:
|
||||
void on_btnOk_clicked();
|
||||
|
|
|
@ -6,39 +6,107 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
<width>460</width>
|
||||
<height>364</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0" columnminimumwidth="0,0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="txtURL"/>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="lbName">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="txtURL"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Description</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QTextEdit" name="txtDescription"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QWidget" name="widget_2" 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="2" column="2">
|
||||
<widget class="QComboBox" name="cbMemoryLimitUnit"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Time Limit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Memory Limit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinTimeLimit">
|
||||
<property name="maximum">
|
||||
<number>9999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinMemoryLimit">
|
||||
<property name="maximum">
|
||||
<number>9999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<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>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="cbTimeLimitUnit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
|
@ -83,9 +151,6 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QTextEdit" name="txtDescription"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
|
|
@ -125,6 +125,10 @@ void OJProblemSetModel::saveToFile(const QString &fileName, int currentIndex)
|
|||
problemObj["name"]=problem->name;
|
||||
problemObj["url"]=problem->url;
|
||||
problemObj["description"]=problem->description;
|
||||
problemObj["time_limit"]=(int)problem->timeLimit;
|
||||
problemObj["memory_limit"]=(int)problem->memoryLimit;
|
||||
problemObj["time_limit_unit"]=(int)problem->timeLimitUnit;
|
||||
problemObj["memory_limit_unit"]=(int)problem->memoryLimitUnit;
|
||||
if (fileExists(problem->answerProgram))
|
||||
problemObj["answer_program"] = problem->answerProgram;
|
||||
QJsonArray cases;
|
||||
|
@ -184,6 +188,11 @@ void OJProblemSetModel::loadFromFile(const QString &fileName, int& currentIndex)
|
|||
POJProblem problem = std::make_shared<OJProblem>();
|
||||
problem->name = problemObj["name"].toString();
|
||||
problem->url = problemObj["url"].toString();
|
||||
problem->timeLimit = problemObj["time_limit"].toInt();
|
||||
problem->memoryLimit = problemObj["memory_limit"].toInt();
|
||||
problem->timeLimitUnit = (ProblemTimeLimitUnit)problemObj["time_limit_unit"].toInt();
|
||||
problem->memoryLimitUnit = (ProblemMemoryLimitUnit)problemObj["memory_limit_unit"].toInt();
|
||||
|
||||
problem->description = problemObj["description"].toString();
|
||||
problem->answerProgram = problemObj["answer_program"].toString();
|
||||
QJsonArray casesArray = problemObj["cases"].toArray();
|
||||
|
@ -252,6 +261,15 @@ QVariant OJProblemSetModel::data(const QModelIndex &index, int role) const
|
|||
return QVariant();
|
||||
if (role == Qt::DisplayRole || role == Qt::EditRole) {
|
||||
return mProblemSet.problems[index.row()]->name;
|
||||
} else if (role == Qt::ToolTipRole) {
|
||||
POJProblem problem = mProblemSet.problems[index.row()];
|
||||
|
||||
QString s;
|
||||
s=QString("<h3>%1</h3>").arg(problem->name);
|
||||
if (!problem->description.isEmpty())
|
||||
s+=problem->description;
|
||||
|
||||
return s;
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -479,6 +497,16 @@ QVariant OJProblemModel::data(const QModelIndex &index, int role) const
|
|||
return "";
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (role == Qt::DisplayRole) {
|
||||
POJProblemCase problemCase = mProblem->cases[index.row()];
|
||||
if (problemCase->testState == ProblemCaseTestState::Passed
|
||||
|| problemCase->testState == ProblemCaseTestState::Failed)
|
||||
return problemCase->runningMemory/1024;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
|
@ -515,7 +543,7 @@ Qt::ItemFlags OJProblemModel::flags(const QModelIndex &idx) const
|
|||
|
||||
int OJProblemModel::columnCount(const QModelIndex &/*parent*/) const
|
||||
{
|
||||
return 2;
|
||||
return 3;
|
||||
}
|
||||
|
||||
QVariant OJProblemModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
|
@ -526,6 +554,8 @@ QVariant OJProblemModel::headerData(int section, Qt::Orientation orientation, in
|
|||
return tr("Name");
|
||||
case 1:
|
||||
return tr("Time(ms)");
|
||||
case 2:
|
||||
return tr("Memory(kb)");
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
|
|
Loading…
Reference in New Issue