diff --git a/addcompilerwizard.cpp b/addcompilerwizard.cpp new file mode 100644 index 0000000..96e81ff --- /dev/null +++ b/addcompilerwizard.cpp @@ -0,0 +1,503 @@ +#include "addcompilerwizard.h" +#include "ui_addcompilerwizard.h" +#include "compiler.h" + +AddCompilerWizard::AddCompilerWizard(QWidget *parent) : + QWizard(parent), + ui(new Ui::AddCompilerWizard) +{ + ui->setupUi(this); + + ui->sourceFileExtensions->setValidator(new QRegExpValidator(QRegExp("(\\w+;)*\\w+"), ui->sourceFileExtensions)); + ui->bytecodeFileExtensions->setValidator(new QRegExpValidator(QRegExp("(\\w+;)*\\w+"), ui->bytecodeFileExtensions)); + ui->javaMemoryLimit->setValidator(new QIntValidator(128, 2048, ui->javaMemoryLimit)); + +#ifdef Q_OS_LINUX + if (QFileInfo("/usr/bin/gcc").exists()) + ui->gccPath->setText("/usr/bin/gcc"); + if (QFileInfo("/usr/bin/g++").exists()) + ui->gppPath->setText("/usr/bin/g++"); + if (QFileInfo("/usr/bin/fpc").exists()) + ui->fpcPath->setText("/usr/bin/fpc"); + if (QFileInfo("/usr/bin/python").exists()) + ui->pythonPath->setText("/usr/bin/python"); +#endif + + connect(ui->typeSelect, SIGNAL(currentIndexChanged(int)), + this, SLOT(compilerTypeChanged())); + connect(ui->compilerSelectButton, SIGNAL(clicked()), + this, SLOT(selectCompilerLocation())); + connect(ui->interpreterSelectButton, SIGNAL(clicked()), + this, SLOT(selectInterpreterLocation())); + connect(ui->gccSelectButton, SIGNAL(clicked()), + this, SLOT(selectGccPath())); + connect(ui->gppSelectButton, SIGNAL(clicked()), + this, SLOT(selectGppPath())); + connect(ui->fpcSelectButton, SIGNAL(clicked()), + this, SLOT(selectFpcPath())); + connect(ui->fbcSelectButton, SIGNAL(clicked()), + this, SLOT(selectFbcPath())); + connect(ui->javacSelectButton, SIGNAL(clicked()), + this, SLOT(selectJavacPath())); + connect(ui->javaSelectButton, SIGNAL(clicked()), + this, SLOT(selectJavaPath())); + connect(ui->pythonSelectButton, SIGNAL(clicked()), + this, SLOT(selectPythonPath())); +} + +AddCompilerWizard::~AddCompilerWizard() +{ + delete ui; +} + +const QList& AddCompilerWizard::getCompilerList() const +{ + return compilerList; +} + +int AddCompilerWizard::nextId() const +{ + if (currentId() == 0) { + if (ui->customRadioButton->isChecked()) + return 1; + else + return 2; + } else + if (currentId() == 3) return -1; else return 3; +} + +bool AddCompilerWizard::validateCurrentPage() +{ + if (currentId() == 1) { + if (ui->compilerName->text().isEmpty()) { + ui->compilerName->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty compiler name!"), QMessageBox::Close); + return false; + } + if (ui->compilerLocation->isEnabled() && ui->compilerLocation->text().isEmpty()) { + ui->compilerLocation->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty compiler location!"), QMessageBox::Close); + return false; + } + if (ui->interpreterLocation->isEnabled() && ui->interpreterLocation->text().isEmpty()) { + ui->interpreterLocation->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty interpreter location!"), QMessageBox::Close); + return false; + } + if (ui->sourceFileExtensions->text().isEmpty()) { + ui->sourceFileExtensions->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty source file extensions!"), QMessageBox::Close); + return false; + } + if (ui->bytecodeFileExtensions->isEnabled() && ui->bytecodeFileExtensions->text().isEmpty()) { + ui->bytecodeFileExtensions->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty byte-code file extensions!"), QMessageBox::Close); + return false; + } + + QString text; + text += tr("[Custom Compiler]") + "\n"; + text += tr("Compiler Name: ") + ui->compilerName->text() + "\n"; + text += tr("Compiler Type: ") + ui->typeSelect->currentText() + "\n"; + if (ui->compilerLocation->isEnabled()) + text += tr("Compiler\'s Location: ") + ui->compilerLocation->text() + "\n"; + if (ui->interpreterLocation->isEnabled()) + text += tr("Interpreter\'s Location: ") + ui->interpreterLocation->text() + "\n"; + text += tr("Source File Extensions: ") + ui->sourceFileExtensions->text() + "\n"; + if (ui->bytecodeFileExtensions->isEnabled()) + text += tr("Byte-code File Extensions: ") + ui->bytecodeFileExtensions->text() + "\n"; + if (ui->defaultCompilerArguments->isEnabled()) + text += tr("Default Compiler\'s Arguments: ") + ui->defaultCompilerArguments->text() + "\n"; + if (ui->defaultInterpreterArguments->isEnabled()) + text += tr("Default Interpreter\'s Arguments: ") + ui->defaultInterpreterArguments->text() + "\n"; + ui->logViewer->setPlainText(text); + } + + if (currentId() == 2) { + if (ui->gccGroupBox->isEnabled() && ui->gccPath->text().isEmpty()) { + ui->gccPath->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty gcc path!"), QMessageBox::Close); + return false; + } + if (ui->gppGroupBox->isEnabled() && ui->gppPath->text().isEmpty()) { + ui->gppPath->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty g++ path!"), QMessageBox::Close); + return false; + } + if (ui->fpcGroupBox->isEnabled() && ui->fpcPath->text().isEmpty()) { + ui->fpcPath->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty fpc path!"), QMessageBox::Close); + return false; + } + if (ui->fbcGroupBox->isEnabled() && ui->fbcPath->text().isEmpty()) { + ui->fbcPath->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty fbc path!"), QMessageBox::Close); + return false; + } + if (ui->javaGroupBox->isEnabled() && ui->javacPath->text().isEmpty()) { + ui->javacPath->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty javac path!"), QMessageBox::Close); + return false; + } + if (ui->javaGroupBox->isEnabled() && ui->javaPath->text().isEmpty()) { + ui->javaPath->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty java path!"), QMessageBox::Close); + return false; + } + if (ui->pythonGroupBox->isEnabled() && ui->pythonPath->text().isEmpty()) { + ui->pythonPath->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty python path!"), QMessageBox::Close); + return false; + } + + QString text; + if (ui->gccGroupBox->isEnabled()) { + text += tr("[gcc Compiler]") + "\n"; + text += tr("gcc Path: ") + ui->gccPath->text() + "\n"; + if (ui->gccO2Check->isChecked()) + text += tr("Enable O2 Optimization") + "\n"; + text += "\n"; + } + if (ui->gppGroupBox->isEnabled()) { + text += tr("[g++ Compiler]") + "\n"; + text += tr("g++ Path: ") + ui->gppPath->text() + "\n"; + if (ui->gppO2Check->isChecked()) + text += tr("Enable O2 Optimization") + "\n"; + text += "\n"; + } + if (ui->fpcGroupBox->isEnabled()) { + text += tr("[fpc Compiler]") + "\n"; + text += tr("fpc Path: ") + ui->fpcPath->text() + "\n"; + if (ui->fpcO2Check->isChecked()) + text += tr("Enable O2 Optimization") + "\n"; + text += "\n"; + } + if (ui->fbcGroupBox->isEnabled()) { + text += tr("[fbc Compiler]") + "\n"; + text += tr("fbc Path: ") + ui->fbcPath->text() + "\n\n"; + } + if (ui->javaGroupBox->isEnabled()) { + text += tr("[Java Compiler]") + "\n"; + text += tr("javac Path: ") + ui->javacPath->text() + "\n"; + text += tr("java Path: ") + ui->javaPath->text() + "\n"; + text += tr("Memory Limit: %1 MB").arg(ui->javaMemoryLimit->text()) + "\n"; + text += "\n"; + } + if (ui->pythonGroupBox->isEnabled()) { + text += tr("[Python Compiler]") + "\n"; + text += tr("python Path: ") + ui->pythonPath->text() + "\n"; + if (ui->pythonBytecodeCheck->isChecked()) + text += tr("Generate Optimized Byte-code") + "\n"; + text += "\n"; + } + ui->logViewer->setPlainText(text); + } + + return true; +} + +void AddCompilerWizard::compilerTypeChanged() +{ + if (ui->typeSelect->currentIndex() == 0) { + ui->interpreterLocationLabel->setEnabled(false); + ui->interpreterLocation->setEnabled(false); + ui->interpreterSelectButton->setEnabled(false); + ui->defaultInterpreterArgumentsLabel->setEnabled(false); + ui->defaultInterpreterArguments->setEnabled(false); + } else { + ui->interpreterLocationLabel->setEnabled(true); + ui->interpreterLocation->setEnabled(true); + ui->interpreterSelectButton->setEnabled(true); + ui->defaultInterpreterArgumentsLabel->setEnabled(true); + ui->defaultInterpreterArguments->setEnabled(true); + } + + if (ui->typeSelect->currentIndex() == 1) { + ui->bytecodeFileExtensionsLabel->setEnabled(true); + ui->bytecodeFileExtensions->setEnabled(true); + } else { + ui->bytecodeFileExtensionsLabel->setEnabled(false); + ui->bytecodeFileExtensions->setEnabled(false); + } + + if (ui->typeSelect->currentIndex() == 2) { + ui->compilerLocationLabel->setEnabled(false); + ui->compilerLocation->setEnabled(false); + ui->compilerSelectButton->setEnabled(false); + ui->defaultCompilerArgumentsLabel->setEnabled(false); + ui->defaultCompilerArguments->setEnabled(false); + } else { + ui->compilerLocationLabel->setEnabled(true); + ui->compilerLocation->setEnabled(true); + ui->compilerSelectButton->setEnabled(true); + ui->defaultCompilerArgumentsLabel->setEnabled(true); + ui->defaultCompilerArguments->setEnabled(true); + } +} + +void AddCompilerWizard::selectCompilerLocation() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), tr("Executable files (*.exe)")); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), tr("Executable files (*.*)")); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->compilerLocation->setText(location); + } +} + +void AddCompilerWizard::selectInterpreterLocation() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Interpreter\'s Location"), + QDir::rootPath(), tr("Executable files (*.exe)")); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Interpreter\'s Location"), + QDir::rootPath(), tr("Executable files (*.*)")); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->interpreterLocation->setText(location); + } +} + +void AddCompilerWizard::selectGccPath() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "gcc (gcc.exe)"); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "gcc (gcc)"); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->gccPath->setText(location); + } +} + +void AddCompilerWizard::selectGppPath() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "g++ (g++.exe)"); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "g++ (g++)"); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->gppPath->setText(location); + } +} + +void AddCompilerWizard::selectFpcPath() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "fpc (fpc.exe)"); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "fpc (fpc)"); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->fpcPath->setText(location); + } +} + +void AddCompilerWizard::selectFbcPath() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "fbc (fbc.exe)"); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "fbc (fbc)"); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->fbcPath->setText(location); + } +} + +void AddCompilerWizard::selectJavacPath() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "javac (javac.exe)"); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), + QDir::rootPath(), "javac (javac)"); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->javacPath->setText(location); + } +} + +void AddCompilerWizard::selectJavaPath() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Interpreter\'s Location"), + QDir::rootPath(), "java (java.exe)"); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Interpreter\'s Location"), + QDir::rootPath(), "java (java)"); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->javaPath->setText(location); + } +} + +void AddCompilerWizard::selectPythonPath() +{ +#ifdef Q_OS_WIN32 + QString location = QFileDialog::getOpenFileName(this, tr("Select Interpreter\'s Location"), + QDir::rootPath(), "python (python.exe)"); +#endif + +#ifdef Q_OS_LINUX + QString location = QFileDialog::getOpenFileName(this, tr("Select Interpreter\'s Location"), + QDir::rootPath(), "python (python)"); +#endif + if (! location.isEmpty()) { + location = location.replace('/', QDir::separator()); + ui->pythonPath->setText(location); + } +} + +void AddCompilerWizard::accept() +{ + if (ui->customRadioButton->isChecked()) { + Compiler *compiler = new Compiler; + compiler->setCompilerType((Compiler::CompilerType)ui->typeSelect->currentIndex()); + compiler->setCompilerName(ui->compilerName->text()); + compiler->setCompilerLocation(ui->compilerLocation->text()); + compiler->setInterpreterLocation(ui->interpreterLocation->text()); + compiler->setSourceExtensions(ui->sourceFileExtensions->text()); + compiler->setBytecodeExtensions(ui->bytecodeFileExtensions->text()); + compiler->addConfiguration("default", + ui->defaultCompilerArguments->text(), + ui->defaultInterpreterArguments->text()); + compilerList.append(compiler); + } + + if (ui->builtinRadioButton->isChecked()) { + if (ui->gccGroupBox->isEnabled()) { + Compiler *compiler = new Compiler; + compiler->setCompilerName("gcc"); + compiler->setCompilerLocation(ui->gccPath->text()); + compiler->setSourceExtensions("c"); + if (ui->gccO2Check->isChecked()) + compiler->addConfiguration("default", "-o %s %s.* -O2", ""); + else + compiler->addConfiguration("default", "-o %s %s.*", ""); +#ifdef Q_OS_WIN32 + QProcessEnvironment environment; + QString path = QFileInfo(ui->gccPath->text()).absolutePath(); + path.replace('/', QDir::separator()); + environment.insert("PATH", path); + compiler->setEnvironment(environment); +#endif + compilerList.append(compiler); + } + + if (ui->gppGroupBox->isEnabled()) { + Compiler *compiler = new Compiler; + compiler->setCompilerName("g++"); + compiler->setCompilerLocation(ui->gppPath->text()); + compiler->setSourceExtensions("cpp;cc;cxx"); + if (ui->gccO2Check->isChecked()) + compiler->addConfiguration("default", "-o %s %s.* -O2", ""); + else + compiler->addConfiguration("default", "-o %s %s.*", ""); +#ifdef Q_OS_WIN32 + QProcessEnvironment environment; + QString path = QFileInfo(ui->gccPath->text()).absolutePath(); + path.replace('/', QDir::separator()); + environment.insert("PATH", path); + compiler->setEnvironment(environment); +#endif + compilerList.append(compiler); + } + + if (ui->fpcGroupBox->isEnabled()) { + Compiler *compiler = new Compiler; + compiler->setCompilerName("fpc"); + compiler->setCompilerLocation(ui->fpcPath->text()); + compiler->setSourceExtensions("pas;pp;inc"); + if (ui->gccO2Check->isChecked()) + compiler->addConfiguration("default", "%s.* -O2", ""); + else + compiler->addConfiguration("default", "%s.*", ""); + compilerList.append(compiler); + } + + if (ui->fbcGroupBox->isEnabled()) { + Compiler *compiler = new Compiler; + compiler->setCompilerName("fbc"); + compiler->setCompilerLocation(ui->fbcPath->text()); + compiler->setSourceExtensions("bas"); + compiler->addConfiguration("default", "%s.*", ""); + compilerList.append(compiler); + } + + if (ui->javaGroupBox->isEnabled()) { + Compiler *compiler = new Compiler; + compiler->setCompilerName("jdk"); + compiler->setCompilerType(Compiler::InterpretiveWithByteCode); + compiler->setCompilerLocation(ui->javacPath->text()); + compiler->setInterpreterLocation(ui->javaPath->text()); + compiler->setSourceExtensions("java"); + compiler->setBytecodeExtensions("class"); + compiler->setTimeLimitRatio(5); + compiler->setDisableMemoryLimitCheck(true); + compiler->addConfiguration("default", "%s.*", QString("-Xmx%1m %s").arg(ui->javaMemoryLimit->text())); + compilerList.append(compiler); + } + + if (ui->pythonGroupBox->isEnabled()) { + Compiler *compiler = new Compiler; + compiler->setCompilerName("python"); + compiler->setSourceExtensions("py"); + compiler->setTimeLimitRatio(10); + compiler->setMemoryLimitRatio(5); + if (ui->pythonBytecodeCheck->isChecked()) { + compiler->setCompilerType(Compiler::InterpretiveWithByteCode); + compiler->setCompilerLocation(ui->pythonPath->text()); + compiler->setInterpreterLocation(ui->pythonPath->text()); + compiler->setBytecodeExtensions("pyo"); + compiler->addConfiguration("default", "-O -m py_compile %s.*", "%s.pyo"); + } else { + compiler->setCompilerType(Compiler::InterpretiveWithoutByteCode); + compiler->setInterpreterLocation(ui->pythonPath->text()); + compiler->addConfiguration("default", "", "%s.*"); + } + compilerList.append(compiler); + } + } + + QWizard::accept(); +} diff --git a/addcompilerwizard.h b/addcompilerwizard.h new file mode 100644 index 0000000..274dd87 --- /dev/null +++ b/addcompilerwizard.h @@ -0,0 +1,43 @@ +#ifndef ADDCOMPILERWIZARD_H +#define ADDCOMPILERWIZARD_H + +#include +#include +#include + +namespace Ui { + class AddCompilerWizard; +} + +class Compiler; + +class AddCompilerWizard : public QWizard +{ + Q_OBJECT + +public: + explicit AddCompilerWizard(QWidget *parent = 0); + ~AddCompilerWizard(); + void accept(); + const QList& getCompilerList() const; + +private: + Ui::AddCompilerWizard *ui; + QList compilerList; + int nextId() const; + bool validateCurrentPage(); + +private slots: + void compilerTypeChanged(); + void selectCompilerLocation(); + void selectInterpreterLocation(); + void selectGccPath(); + void selectGppPath(); + void selectFpcPath(); + void selectFbcPath(); + void selectJavacPath(); + void selectJavaPath(); + void selectPythonPath(); +}; + +#endif // ADDCOMPILERWIZARD_H diff --git a/addcompilerwizard.ui b/addcompilerwizard.ui new file mode 100644 index 0000000..da77fc4 --- /dev/null +++ b/addcompilerwizard.ui @@ -0,0 +1,1097 @@ + + + AddCompilerWizard + + + + 0 + 0 + 457 + 415 + + + + + 457 + 415 + + + + Add Compilers Wizard + + + + + 8 + + + + + font-size: 10pt; +font-weight: bold; + + + Step I: Choose whether you want to use built-in configuration for certain compilers or customize a compiler's configuration. + + + true + + + + + + + + + 8 + + + + + font-size:9pt; + + + Custom Configuration + + + + + + + 0 + + + + + font-size:9pt; + + + Built-in Configuration (Tick the compilers you want to add) + + + true + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + + + + font-size:8pt; + + + gcc + + + true + + + + + + + font-size:8pt; + + + g++ + + + true + + + + + + + font-size:8pt; + + + fpc + + + true + + + + + + + font-size:8pt; + + + fbc + + + + + + + font-size:8pt; + + + jdk + + + + + + + font-size:8pt; + + + python + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 26 + + + + + + + + + + 9 + + + + + font-size: 10pt; +font-weight: bold; + + + Step II: Select compiler's location to configure it. + + + true + + + + + + + 10 + + + 9 + + + + + font-size:9pt; + + + Compiler Name + + + + + + + + 61 + 20 + + + + + 150 + 20 + + + + + + + + font-size:9pt; + + + Compiler Type + + + + + + + + 211 + 20 + + + + + Typical (Generate executable file) + + + + + Interpretive (Generate byte-code file) + + + + + Interpretive (Run source code directly) + + + + + + + + font-size:9pt; + + + Compiler's Location + + + + + + + + + + ... + + + + + + + false + + + font-size:9pt; + + + Interpreter's Location + + + + + + + false + + + + + + + false + + + ... + + + + + + + font-size:9pt; + + + Source File Extensions + + + + + + + + 61 + 20 + + + + + 81 + 20 + + + + + + + + false + + + font-size:9pt; + + + Byte-code File Extensions + + + + + + + false + + + + 61 + 20 + + + + + 81 + 20 + + + + + + + + font-size:9pt; + + + Default Compiler's Arguments + + + + + + + + + + false + + + font-size:9pt; + + + Default Interpreter's Arguments + + + + + + + false + + + + + + + + + Qt::Vertical + + + + 20 + 110 + + + + + + + + + + 8 + + + + + font-size: 10pt; +font-weight: bold; + + + Step II: Select compilers' locations to configure them. + + + true + + + + + + + 9 + + + + + + 1 + 0 + + + + + 0 + 81 + + + + + 16777215 + 81 + + + + font-size:9pt; + + + gcc + + + + + + 8 + + + + + + + + ... + + + + + + + + + font-size:8pt; + + + Enable O2 Optimization + + + + + + + + + + + 1 + 0 + + + + + 0 + 81 + + + + + 16777215 + 81 + + + + font-size:9pt; + + + g++ + + + + + + 8 + + + + + + + + ... + + + + + + + + + font-size:8pt; + + + Enable O2 Optimization + + + + + + + + + + + 1 + 0 + + + + + 0 + 79 + + + + + 16777215 + 79 + + + + font-size:9pt; + + + fpc + + + + + + 8 + + + + + + + + ... + + + + + + + + + font-size:8pt; + + + Enable O2 Optimization + + + + + + + + + + false + + + + 1 + 0 + + + + + 0 + 81 + + + + + 16777215 + 81 + + + + font-size:9pt; + + + fbc + + + + + + 8 + + + + + + + + ... + + + + + + + + + Qt::Vertical + + + + 20 + 16 + + + + + + + + + + + false + + + + 1 + 0 + + + + + 0 + 110 + + + + + 16777215 + 110 + + + + font-size:9pt; + + + Java + + + + + + 8 + + + + + font-size:8pt; + + + javac + + + + + + + + + + ... + + + + + + + font-size:8pt; + + + java + + + + + + + + + + ... + + + + + + + + + 8 + + + + + font-size:8pt; + + + Memory Limit + + + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + 512 + + + + + + + font-size:8pt; + + + MB + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + false + + + + 1 + 0 + + + + + 0 + 111 + + + + + 16777215 + 111 + + + + font-size:9pt; + + + Python + + + + + + 8 + + + + + + + + ... + + + + + + + + + font-size:8pt; + + + Generate Optimized Byte-code + + + + + + + Qt::Vertical + + + + 20 + 23 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 17 + + + + + + + + + + 10 + + + + + font-size: 10pt; +font-weight: bold; + + + Step III: Check the result and finish the wizard. + + + true + + + + + + + + 310 + 220 + + + + font-size:10pt; + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + builtinRadioButton + toggled(bool) + compilersCollection + setVisible(bool) + + + 79 + 105 + + + 134 + 149 + + + + + gccCheck + toggled(bool) + gccGroupBox + setEnabled(bool) + + + 68 + 114 + + + 116 + 74 + + + + + gppCheck + toggled(bool) + gppGroupBox + setEnabled(bool) + + + 118 + 114 + + + 339 + 74 + + + + + fpcCheck + toggled(bool) + fpcGroupBox + setEnabled(bool) + + + 167 + 114 + + + 116 + 164 + + + + + fbcCheck + toggled(bool) + fbcGroupBox + setEnabled(bool) + + + 214 + 114 + + + 339 + 164 + + + + + jdkCheck + toggled(bool) + javaGroupBox + setEnabled(bool) + + + 262 + 114 + + + 116 + 268 + + + + + pythonCheck + toggled(bool) + pythonGroupBox + setEnabled(bool) + + + 317 + 114 + + + 339 + 269 + + + + + diff --git a/addtestcaseswizard.ui b/addtestcaseswizard.ui index 72a49e9..06ca5e3 100644 --- a/addtestcaseswizard.ui +++ b/addtestcaseswizard.ui @@ -367,7 +367,7 @@ font-weight: bold; - :/icon/add.png:/icon/add.png + :/icon/add.ico:/icon/add.ico @@ -390,7 +390,7 @@ font-weight: bold; - :/icon/rod.png:/icon/rod.png + :/icon/rod.ico:/icon/rod.ico diff --git a/advancedcompilersettingsdialog.cpp b/advancedcompilersettingsdialog.cpp index f5e9266..2b9efaf 100644 --- a/advancedcompilersettingsdialog.cpp +++ b/advancedcompilersettingsdialog.cpp @@ -31,6 +31,8 @@ AdvancedCompilerSettingsDialog::AdvancedCompilerSettingsDialog(QWidget *parent) ui->bytecodeExtension->setValidator(new QRegExpValidator(QRegExp("(\\w+;)*\\w+"), ui->bytecodeExtension)); ui->configurationSelect->setLineEdit(new QLineEdit(this)); + connect(ui->buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), + this, SLOT(okayButtonClicked())); connect(ui->typeSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(compilerTypeChanged())); connect(ui->compilerLocation, SIGNAL(textChanged(QString)), @@ -96,6 +98,49 @@ Compiler* AdvancedCompilerSettingsDialog::getEditCompiler() const return editCompiler; } +void AdvancedCompilerSettingsDialog::okayButtonClicked() +{ + if (ui->compilerLocation->isEnabled() && ui->compilerLocation->text().isEmpty()) { + ui->compilerLocation->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty compiler\'s Location!"), QMessageBox::Close); + return; + } + if (ui->interpreterLocation->isEnabled() && ui->interpreterLocation->text().isEmpty()) { + ui->interpreterLocation->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty interpreter\'s Location!"), QMessageBox::Close); + return; + } + if (ui->bytecodeExtension->isEnabled() && ui->bytecodeExtension->text().isEmpty()) { + ui->bytecodeExtension->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty Byte-code Extensions!"), QMessageBox::Close); + return; + } + const QStringList &configurationNames = editCompiler->getConfigurationNames(); + for (int j = 0; j < configurationNames.size(); j ++) { + if (configurationNames[j].isEmpty()) { + ui->configurationSelect->setCurrentIndex(j); + ui->configurationSelect->setFocus(); + QMessageBox::warning(this, tr("Error"), tr("Empty configuration name!"), QMessageBox::Close); + return; + } + if (configurationNames.count(configurationNames[j]) > 1) { + ui->configurationSelect->setCurrentIndex(j); + ui->configurationSelect->setFocus(); + QMessageBox::warning(this, tr("Error"), + tr("Configuration %1 appears more than once!").arg(configurationNames[j]), + QMessageBox::Close); + return; + } + if (configurationNames[j] == "disable") { + ui->configurationSelect->setCurrentIndex(j); + ui->configurationSelect->setFocus(); + QMessageBox::warning(this, tr("Error"),tr("Invalid configuration name \"disable\"!"), QMessageBox::Close); + return; + } + } + accept(); +} + void AdvancedCompilerSettingsDialog::compilerTypeChanged() { editCompiler->setCompilerType((Compiler::CompilerType)ui->typeSelect->currentIndex()); @@ -104,10 +149,14 @@ void AdvancedCompilerSettingsDialog::compilerTypeChanged() ui->interpreterLabel->setEnabled(false); ui->interpreterLocation->setEnabled(false); ui->interpreterSelectButton->setEnabled(false); + ui->interpreterArgumentsLabel->setEnabled(false); + ui->interpreterArguments->setEnabled(false); } else { ui->interpreterLabel->setEnabled(true); ui->interpreterLocation->setEnabled(true); ui->interpreterSelectButton->setEnabled(true); + ui->interpreterArgumentsLabel->setEnabled(true); + ui->interpreterArguments->setEnabled(true); } if (editCompiler->getCompilerType() == Compiler::InterpretiveWithByteCode) { @@ -122,10 +171,14 @@ void AdvancedCompilerSettingsDialog::compilerTypeChanged() ui->compilerLabel->setEnabled(false); ui->compilerLocation->setEnabled(false); ui->compilerSelectButton->setEnabled(false); + ui->compilerArgumentsLabel->setEnabled(false); + ui->compilerArguments->setEnabled(false); } else { ui->compilerLabel->setEnabled(true); ui->compilerLocation->setEnabled(true); ui->compilerSelectButton->setEnabled(true); + ui->compilerArgumentsLabel->setEnabled(true); + ui->compilerArguments->setEnabled(true); } } diff --git a/advancedcompilersettingsdialog.h b/advancedcompilersettingsdialog.h index b7edd32..efb5909 100644 --- a/advancedcompilersettingsdialog.h +++ b/advancedcompilersettingsdialog.h @@ -45,6 +45,7 @@ class AdvancedCompilerSettingsDialog : public QDialog int configCount; private slots: + void okayButtonClicked(); void compilerTypeChanged(); void compilerLocationChanged(); void interpreterLocationChanged(); diff --git a/advancedcompilersettingsdialog.ui b/advancedcompilersettingsdialog.ui index cfabb1d..0eeda40 100644 --- a/advancedcompilersettingsdialog.ui +++ b/advancedcompilersettingsdialog.ui @@ -11,7 +11,7 @@ - Dialog + Compiler Settings @@ -356,22 +356,6 @@ font-weight:bold; - - buttonBox - accepted() - AdvancedCompilerSettingsDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - buttonBox rejected() diff --git a/assignmentthread.cpp b/assignmentthread.cpp index 4edc33a..7b50240 100644 --- a/assignmentthread.cpp +++ b/assignmentthread.cpp @@ -117,6 +117,7 @@ bool AssignmentThread::traditionalTaskPrepare() QList compilerList = settings->getCompilerList(); for (int i = 0; i < compilerList.size(); i ++) { + if (task->getCompilerConfiguration(compilerList[i]->getCompilerName()) == "disable") continue; QStringList filters = compilerList[i]->getSourceExtensions(); for (int j = 0; j < filters.size(); j ++) filters[j] = task->getSourceFileName() + "." + filters[j]; @@ -129,64 +130,104 @@ bool AssignmentThread::traditionalTaskPrepare() break; } } + if (! sourceFile.isEmpty()) { QDir(Settings::temporaryPath()).mkdir(contestantName); QFile::copy(Settings::sourcePath() + contestantName + QDir::separator() + sourceFile, Settings::temporaryPath() + contestantName + QDir::separator() + sourceFile); QStringList configurationNames = compilerList[i]->getConfigurationNames(); - QStringList configurationSettings = compilerList[i]->getCompilerArguments(); + QStringList compilerArguments = compilerList[i]->getCompilerArguments(); + QStringList interpreterArguments = compilerList[i]->getInterpreterArguments(); QString currentConfiguration = task->getCompilerConfiguration(compilerList[i]->getCompilerName()); for (int j = 0; j < configurationNames.size(); j ++) if (configurationNames[j] == currentConfiguration) { - QString arguments = configurationSettings[j]; - arguments.replace("%s", QString("\"") + QFileInfo(Settings::temporaryPath() + contestantName - + QDir::separator() + sourceFile).absoluteFilePath() + "\""); - arguments.replace("%e", QString("\"") + QFileInfo(Settings::temporaryPath() + contestantName - + QDir::separator() + task->getExecutableFileName()).absoluteFilePath() + "\""); - QProcess *compiler = new QProcess(this); - compiler->setProcessChannelMode(QProcess::MergedChannels); - compiler->setWorkingDirectory(Settings::temporaryPath()); - compilerPath = QFileInfo(compilerList[i]->getCompilerLocation()).absolutePath(); + timeLimitRatio = compilerList[i]->getTimeLimitRatio(); + memoryLimitRatio = compilerList[i]->getMemoryLimitRatio(); + disableMemoryLimitCheck = compilerList[i]->getDisableMemoryLimitCheck(); + environment = compilerList[i]->getEnvironment(); + QStringList values = environment.toStringList(); + for (int k = 0; k < values.size(); k ++) { + int tmp = values[k].indexOf("="); + QString variable = values[k].mid(0, tmp); + environment.insert(variable, + environment.value(variable) + ";" + + QProcessEnvironment::systemEnvironment().value(variable)); + } + + if (compilerList[i]->getCompilerType() == Compiler::Typical) { #ifdef Q_OS_WIN32 - QProcessEnvironment environment; - environment.insert("path", compilerPath + ";" + environment.value("path")); - compiler->setProcessEnvironment(environment); + executableFile = task->getSourceFileName() + ".exe"; #endif - compiler->start(QString("\"") + compilerList[i]->getCompilerLocation() + "\" " + arguments); - if (! compiler->waitForStarted(-1)) { - compileState = InvalidCompiler; - delete compiler; - break; +#ifdef Q_OS_LINUX + executableFile = task->getSourceFileName(); +#endif + } else { + executableFile = QString("\"") + compilerList[i]->getInterpreterLocation() + "\" "; + QString arguments = interpreterArguments[j]; + arguments.replace("%s.*", sourceFile); + arguments.replace("%s", task->getSourceFileName()); + executableFile += arguments; } - QElapsedTimer timer; - timer.start(); - bool flag = false; - while (timer.elapsed() < settings->getCompileTimeLimit()) { - if (compiler->state() != QProcess::Running) { - flag = true; + + if (compilerList[i]->getCompilerType() != Compiler::InterpretiveWithoutByteCode) { + QString arguments = compilerArguments[j]; + arguments.replace("%s.*", sourceFile); + arguments.replace("%s", task->getSourceFileName()); + QProcess *compiler = new QProcess(this); + compiler->setProcessChannelMode(QProcess::MergedChannels); + compiler->setProcessEnvironment(environment); + compiler->setWorkingDirectory(Settings::temporaryPath() + contestantName); + compiler->start(QString("\"") + compilerList[i]->getCompilerLocation() + "\" " + arguments); + if (! compiler->waitForStarted(-1)) { + compileState = InvalidCompiler; + delete compiler; break; } - QCoreApplication::processEvents(); - if (stopJudging) { - compiler->kill(); - delete compiler; - return false; + QElapsedTimer timer; + timer.start(); + bool flag = false; + while (timer.elapsed() < settings->getCompileTimeLimit()) { + if (compiler->state() != QProcess::Running) { + flag = true; + break; + } + QCoreApplication::processEvents(); + if (stopJudging) { + compiler->kill(); + delete compiler; + return false; + } + msleep(10); } - msleep(10); - } - if (! flag) { - compiler->kill(); - compileState = CompileTimeLimitExceeded; - } else - if (compiler->exitCode() != 0) { - compileState = CompileError; - compileMessage = QString::fromLocal8Bit(compiler->readAllStandardOutput().data()); + if (! flag) { + compiler->kill(); + compileState = CompileTimeLimitExceeded; } else - if (! QDir(Settings::temporaryPath() + contestantName).exists(task->getExecutableFileName())) - compileState = InvalidCompiler; - else - compileState = CompileSuccessfully; - delete compiler; + if (compiler->exitCode() != 0) { + compileState = CompileError; + compileMessage = QString::fromLocal8Bit(compiler->readAllStandardOutput().data()); + } else { + if (compilerList[i]->getCompilerType() == Compiler::Typical) { + if (! QDir(Settings::temporaryPath() + contestantName).exists(executableFile)) + compileState = InvalidCompiler; + else + compileState = CompileSuccessfully; + } else { + QStringList filters = compilerList[i]->getBytecodeExtensions(); + for (int k = 0; k < filters.size(); k ++) + filters[k] = QString("*.") + filters[k]; + if (QDir(Settings::temporaryPath() + contestantName).entryList(filters, QDir::Files).size() == 0) + compileState = InvalidCompiler; + else + compileState = CompileSuccessfully; + } + } + delete compiler; + } + + if (compilerList[i]->getCompilerType() == Compiler::InterpretiveWithoutByteCode) + compileState = CompileSuccessfully; + break; } break; @@ -268,17 +309,24 @@ void AssignmentThread::assign() JudgingThread *thread = new JudgingThread(); thread->setCheckRejudgeMode(checkRejudgeMode); if (checkRejudgeMode) - thread->setExtraTimeRation(0.2); + thread->setExtraTimeRatio(0.2); else - thread->setExtraTimeRation(0.2 * settings->getNumberOfThreads()); - thread->setCompilerPath(compilerPath); - thread->setWorkingDirectory(Settings::temporaryPath() - + QString("_%1.%2").arg(curTestCaseIndex).arg(curSingleCaseIndex) - + QDir::separator()); + thread->setExtraTimeRatio(0.2 * settings->getNumberOfThreads()); + QString workingDirectory = QDir(Settings::temporaryPath() + + QString("_%1.%2").arg(curTestCaseIndex).arg(curSingleCaseIndex)) + .absolutePath() + QDir::separator(); + thread->setWorkingDirectory(workingDirectory); + QDir(Settings::temporaryPath()).mkdir(QString("_%1.%2").arg(curTestCaseIndex).arg(curSingleCaseIndex)); + QStringList entryList = QDir(Settings::temporaryPath() + contestantName).entryList(QDir::Files); + for (int i = 0; i < entryList.size(); i ++) + QFile::copy(Settings::temporaryPath() + contestantName + QDir::separator() + entryList[i], + workingDirectory + entryList[i]); thread->setSpecialJudgeTimeLimit(settings->getSpecialJudgeTimeLimit()); if (task->getTaskType() == Task::Traditional) - thread->setExecutableFile(Settings::temporaryPath() + contestantName - + QDir::separator() + task->getExecutableFileName()); + if (executableFile[0] == '\"') + thread->setExecutableFile(executableFile); + else + thread->setExecutableFile(workingDirectory + executableFile); if (task->getTaskType() == Task::AnswersOnly) { QString fileName; fileName = QFileInfo(curTestCase->getInputFiles().at(curSingleCaseIndex)).completeBaseName(); @@ -286,7 +334,7 @@ void AssignmentThread::assign() thread->setAnswerFile(Settings::sourcePath() + contestantName + QDir::separator() + fileName); } thread->setTask(task); - QDir(Settings::temporaryPath()).mkdir(QString("_%1.%2").arg(curTestCaseIndex).arg(curSingleCaseIndex)); + connect(thread, SIGNAL(finished()), this, SLOT(threadFinished())); connect(this, SIGNAL(stopJudgingSignal()), thread, SLOT(stopJudgingSlot())); @@ -295,8 +343,12 @@ void AssignmentThread::assign() thread->setOutputFile(Settings::dataPath() + curTestCase->getOutputFiles().at(curSingleCaseIndex)); thread->setFullScore(curTestCase->getFullScore()); if (task->getTaskType() == Task::Traditional) { - thread->setTimeLimit(curTestCase->getTimeLimit()); - thread->setMemoryLimit(curTestCase->getMemoryLimit()); + thread->setEnvironment(environment); + thread->setTimeLimit(qCeil(curTestCase->getTimeLimit() * timeLimitRatio)); + if (disableMemoryLimitCheck) + thread->setMemoryLimit(-1); + else + thread->setMemoryLimit(qCeil(curTestCase->getMemoryLimit() * memoryLimitRatio)); } running[thread] = qMakePair(curTestCaseIndex, curSingleCaseIndex ++); thread->start(); @@ -324,7 +376,6 @@ void AssignmentThread::threadFinished() delete thread; emit singleCaseFinished(task->getTestCase(cur.first)->getTimeLimit(), cur.first, cur.second, int(result[cur.first][cur.second])); - QDir(Settings::temporaryPath()).rmdir(QString("_%1.%2").arg(cur.first).arg(cur.second)); assign(); } diff --git a/assignmentthread.h b/assignmentthread.h index f64c433..29cefdf 100644 --- a/assignmentthread.h +++ b/assignmentthread.h @@ -57,7 +57,11 @@ class AssignmentThread : public QThread CompileState compileState; QString compileMessage; QString sourceFile; - QString compilerPath; + QString executableFile; + double timeLimitRatio; + double memoryLimitRatio; + bool disableMemoryLimitCheck; + QProcessEnvironment environment; QList< QList > timeUsed; QList< QList > memoryUsed; QList< QList > score; diff --git a/compilerselectingdialog.cpp b/compilerselectingdialog.cpp deleted file mode 100644 index c1ed6fc..0000000 --- a/compilerselectingdialog.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************** - This file is part of Project Lemon - Copyright (C) 2011 Zhipeng Jia - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -***************************************************************************/ - -#include "compilerselectingdialog.h" -#include "ui_compilerselectingdialog.h" - -CompilerSelectingDialog::CompilerSelectingDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::CompilerSelectingDialog) -{ - ui->setupUi(this); - connect(ui->gccSelectButton, SIGNAL(clicked()), - this, SLOT(gccSelectButtonClicked())); - connect(ui->gppSelectButton, SIGNAL(clicked()), - this, SLOT(gppSelectButtonClicked())); - connect(ui->fpcSelectButton, SIGNAL(clicked()), - this, SLOT(fpcSelectButtonClicked())); -} - -CompilerSelectingDialog::~CompilerSelectingDialog() -{ - delete ui; -} - -void CompilerSelectingDialog::setGccPath(const QString &path) -{ - ui->gccPath->setText(path); -} - -void CompilerSelectingDialog::setGppPath(const QString &path) -{ - ui->gppPath->setText(path); -} - -void CompilerSelectingDialog::setFpcPath(const QString &path) -{ - ui->fpcPath->setText(path); -} - -QString CompilerSelectingDialog::getGccPath() const -{ - return ui->gccPath->text(); -} - -QString CompilerSelectingDialog::getGppPath() const -{ - return ui->gppPath->text(); -} - -QString CompilerSelectingDialog::getFpcPath() const -{ - return ui->fpcPath->text(); -} - -void CompilerSelectingDialog::gccSelectButtonClicked() -{ - QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), - QDir::rootPath(), "gcc (gcc.exe)"); - if (! location.isEmpty()) { - location.replace('/', QDir::separator()); - ui->gccPath->setText(location); - } -} - -void CompilerSelectingDialog::gppSelectButtonClicked() -{ - QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), - QDir::rootPath(), "g++ (g++.exe)"); - if (! location.isEmpty()) { - location.replace('/', QDir::separator()); - ui->gppPath->setText(location); - } -} - -void CompilerSelectingDialog::fpcSelectButtonClicked() -{ - QString location = QFileDialog::getOpenFileName(this, tr("Select Compiler\'s Location"), - QDir::rootPath(), "fpc (fpc.exe)"); - if (! location.isEmpty()) { - location.replace('/', QDir::separator()); - ui->fpcPath->setText(location); - } -} diff --git a/compilerselectingdialog.h b/compilerselectingdialog.h deleted file mode 100644 index 5e8682a..0000000 --- a/compilerselectingdialog.h +++ /dev/null @@ -1,53 +0,0 @@ -/*************************************************************************** - This file is part of Project Lemon - Copyright (C) 2011 Zhipeng Jia - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -***************************************************************************/ - -#ifndef COMPILERSELECTINGDIALOG_H -#define COMPILERSELECTINGDIALOG_H - -#include -#include -#include - -namespace Ui { - class CompilerSelectingDialog; -} - -class CompilerSelectingDialog : public QDialog -{ - Q_OBJECT - -public: - explicit CompilerSelectingDialog(QWidget *parent = 0); - ~CompilerSelectingDialog(); - void setGccPath(const QString&); - void setGppPath(const QString&); - void setFpcPath(const QString&); - QString getGccPath() const; - QString getGppPath() const; - QString getFpcPath() const; - -private: - Ui::CompilerSelectingDialog *ui; - -private slots: - void gccSelectButtonClicked(); - void gppSelectButtonClicked(); - void fpcSelectButtonClicked(); -}; - -#endif // COMPILERSELECTINGDIALOG_H diff --git a/compilerselectingdialog.ui b/compilerselectingdialog.ui deleted file mode 100644 index 8c0d603..0000000 --- a/compilerselectingdialog.ui +++ /dev/null @@ -1,140 +0,0 @@ - - - CompilerSelectingDialog - - - - 0 - 0 - 305 - 137 - - - - Select Compiler's Location - - - - 10 - - - - - 12 - - - 10 - - - - - font-size: 10pt; -font-weight: bold; - - - gcc - - - - - - - - - - ... - - - - - - - - - - ... - - - - - - - font-size: 10pt; -font-weight: bold; - - - fpc - - - - - - - - - - ... - - - - - - - font-size: 10pt; -font-weight: bold; - - - g++ - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - accepted() - CompilerSelectingDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - CompilerSelectingDialog - reject() - - - 152 - 118 - - - 152 - 69 - - - - - diff --git a/compilersettings.cpp b/compilersettings.cpp index cf092da..5c2cc81 100644 --- a/compilersettings.cpp +++ b/compilersettings.cpp @@ -19,6 +19,7 @@ #include "compilersettings.h" #include "ui_compilersettings.h" #include "advancedcompilersettingsdialog.h" +#include "addcompilerwizard.h" #include "settings.h" #include "compiler.h" @@ -29,6 +30,11 @@ CompilerSettings::CompilerSettings(QWidget *parent) : ui->setupUi(this); ui->sourceExtensions->setValidator(new QRegExpValidator(QRegExp("(\\w+;)*\\w+"), ui->sourceExtensions)); + deleteCompilerKeyAction = new QAction(ui->compilerList); + deleteCompilerKeyAction->setShortcutContext(Qt::WidgetShortcut); + deleteCompilerKeyAction->setShortcut(QKeySequence::Delete); + deleteCompilerKeyAction->setEnabled(false); + ui->compilerList->addAction(deleteCompilerKeyAction); connect(ui->moveUpButton, SIGNAL(clicked()), this, SLOT(moveUpCompiler())); @@ -46,6 +52,8 @@ CompilerSettings::CompilerSettings(QWidget *parent) : this, SLOT(compilerListCurrentRowChanged())); connect(ui->advancedButton, SIGNAL(clicked()), this, SLOT(advancedButtonClicked())); + connect(deleteCompilerKeyAction, SIGNAL(triggered()), + this, SLOT(deleteCompiler())); } CompilerSettings::~CompilerSettings() @@ -71,7 +79,7 @@ void CompilerSettings::resetEditSettings(Settings *settings) bool CompilerSettings::checkValid() { - /*const QList &compilerList = editSettings->getCompilerList(); + const QList &compilerList = editSettings->getCompilerList(); QStringList compilerNames; for (int i = 0; i < compilerList.size(); i ++) compilerNames.append(compilerList[i]->getCompilerName()); @@ -97,32 +105,7 @@ bool CompilerSettings::checkValid() QMessageBox::warning(this, tr("Error"), tr("Empty source file extensions!"), QMessageBox::Close); return false; } - if (compilerList[i]->getLocation().isEmpty()) { - ui->compilerList->setCurrentRow(i); - ui->location->setFocus(); - QMessageBox::warning(this, tr("Error"), tr("Empty compiler location!"), QMessageBox::Close); - return false; - } - const QStringList &configurationNames = compilerList[i]->getConfigurationNames(); - for (int j = 0; j < configurationNames.size(); j ++) { - if (configurationNames[j].isEmpty()) { - ui->compilerList->setCurrentRow(i); - ui->configurations->setCurrentIndex(j); - ui->configurations->setFocus(); - QMessageBox::warning(this, tr("Error"), tr("Empty configuration name!"), QMessageBox::Close); - return false; - } - if (configurationNames.count(configurationNames[j]) > 1) { - ui->compilerList->setCurrentRow(i); - ui->configurations->setCurrentIndex(j); - ui->configurations->setFocus(); - QMessageBox::warning(this, tr("Error"), - tr("Configuration %1 appears more than once!").arg(configurationNames[j]), - QMessageBox::Close); - return false; - } - } - }*/ + } return true; } @@ -150,19 +133,36 @@ void CompilerSettings::moveDownCompiler() void CompilerSettings::addCompiler() { - Compiler *compiler = new Compiler; - editSettings->addCompiler(compiler); - compiler->setCompilerName(tr("New compiler")); - compiler->addConfiguration("default", "", ""); - ui->compilerList->addItem(new QListWidgetItem(compiler->getCompilerName())); - ui->compilerList->setCurrentRow(ui->compilerList->count() - 1); - refreshItemState(); - ui->compilerName->setFocus(); - ui->compilerName->setSelection(0, ui->compilerName->text().length()); + AddCompilerWizard *wizard = new AddCompilerWizard(this); + if (wizard->exec() == QDialog::Accepted) { + QList compilerList = editSettings->getCompilerList(); + QStringList compilerNames; + for (int i = 0; i < compilerList.size(); i ++) + compilerNames.append(compilerList[i]->getCompilerName()); + compilerList = wizard->getCompilerList(); + for (int i = 0; i < compilerList.size(); i ++) { + if (compilerNames.contains(compilerList[i]->getCompilerName())) { + int cnt = 2; + QString name = compilerList[i]->getCompilerName(); + while (compilerNames.contains(QString("%1 (%2)").arg(name).arg(cnt))) + cnt ++; + compilerList[i]->setCompilerName(QString("%1 (%2)").arg(name).arg(cnt)); + } + editSettings->addCompiler(compilerList[i]); + ui->compilerList->addItem(new QListWidgetItem(compilerList[i]->getCompilerName())); + ui->compilerList->setCurrentRow(ui->compilerList->count() - 1); + refreshItemState(); + } + } + delete wizard; } void CompilerSettings::deleteCompiler() { + if (QMessageBox::question(this, tr("Lemon"), tr("Are you sure to delete compiler %1?") + .arg(curCompiler->getCompilerName()), + QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) + return; int index = ui->compilerList->currentRow(); delete ui->compilerList->item(index); editSettings->deleteCompiler(index); @@ -193,6 +193,7 @@ void CompilerSettings::refreshItemState() ui->compilerNameLabel->setEnabled(false); ui->sourceExtensionsLabel->setEnabled(false); ui->advancedButton->setEnabled(false); + deleteCompilerKeyAction->setEnabled(false); } else { if (ui->compilerList->currentRow() > 0) ui->moveUpButton->setEnabled(true); @@ -209,6 +210,7 @@ void CompilerSettings::refreshItemState() ui->compilerNameLabel->setEnabled(true); ui->sourceExtensionsLabel->setEnabled(true); ui->advancedButton->setEnabled(true); + deleteCompilerKeyAction->setEnabled(true); } } diff --git a/compilersettings.h b/compilersettings.h index fd5245a..1c9cc3c 100644 --- a/compilersettings.h +++ b/compilersettings.h @@ -44,6 +44,7 @@ class CompilerSettings : public QWidget Ui::CompilerSettings *ui; Settings *editSettings; Compiler *curCompiler; + QAction *deleteCompilerKeyAction; void setCurrentCompiler(Compiler*); void refreshItemState(); diff --git a/contest.h b/contest.h index 1bee36d..2a995d6 100644 --- a/contest.h +++ b/contest.h @@ -22,7 +22,7 @@ #include #include #include "globaltype.h" -#define MagicNumber 0x19950922 +#define MagicNumber 0x20101231 class Task; class Settings; diff --git a/detaildialog.cpp b/detaildialog.cpp index 9861495..4419e9d 100644 --- a/detaildialog.cpp +++ b/detaildialog.cpp @@ -167,9 +167,13 @@ QString DetailDialog::getCode(Contest *contest, Contestant *contestant) } htmlCode += QString("%1").arg(text); - if (! message[j][k].isEmpty()) + if (! message[j][k].isEmpty()) { + QString tmp = message[j][k]; + tmp.replace("\n", "\\n"); + tmp.replace("\"", "\\"); htmlCode += QString(" (...)") - .arg(message[j][k]); + .arg(tmp); + } htmlCode += ""; htmlCode += ""; diff --git a/judgingthread.cpp b/judgingthread.cpp index 3c248f8..bee9899 100644 --- a/judgingthread.cpp +++ b/judgingthread.cpp @@ -49,14 +49,14 @@ void JudgingThread::setCheckRejudgeMode(bool check) checkRejudgeMode = check; } -void JudgingThread::setExtraTimeRation(double ratio) +void JudgingThread::setExtraTimeRatio(double ratio) { extraTimeRatio = ratio; } -void JudgingThread::setCompilerPath(const QString &path) +void JudgingThread::setEnvironment(const QProcessEnvironment &env) { - compilerPath = path; + environment = env; } void JudgingThread::setWorkingDirectory(const QString &directory) @@ -459,13 +459,12 @@ void JudgingThread::runProgram() FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - QProcessEnvironment environment; - environment = QProcessEnvironment::systemEnvironment(); - environment.insert("path", compilerPath + ";" + environment.value("path")); - QString values = QString("PATH=") + environment.value("path"); - values += "\0\0"; + si.hStdError = CreateFile((const WCHAR*)((workingDirectory + "_tmperr").utf16()), GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &sa, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (! CreateProcess((const WCHAR*)(executableFile.utf16()), NULL, NULL, &sa, + QString values = environment.toStringList().join('\0') + '\0'; + if (! CreateProcess(NULL, (WCHAR*)(executableFile.utf16()), NULL, &sa, TRUE, HIGH_PRIORITY_CLASS | CREATE_NO_WINDOW, (LPVOID)(values.toLocal8Bit().data()), (const WCHAR*)(workingDirectory.utf16()), &si, &pi)) { if (task->getStandardInputCheck()) CloseHandle(si.hStdInput); @@ -485,19 +484,21 @@ void JudgingThread::runProgram() flag = true; break; } - PROCESS_MEMORY_COUNTERS info; - GetProcessMemoryInfo(pi.hProcess, &info, sizeof(info)); - memoryUsed = info.PeakWorkingSetSize; - if (memoryUsed > memoryLimit * 1024 * 1024) { - TerminateProcess(pi.hProcess, 0); - if (task->getStandardInputCheck()) CloseHandle(si.hStdInput); - if (task->getStandardOutputCheck()) CloseHandle(si.hStdOutput); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - score = 0; - result = MemoryLimitExceeded; - timeUsed = -1; - return; + if (memoryLimit != -1) { + PROCESS_MEMORY_COUNTERS info; + GetProcessMemoryInfo(pi.hProcess, &info, sizeof(info)); + memoryUsed = info.PeakWorkingSetSize; + if (memoryUsed > memoryLimit * 1024 * 1024) { + TerminateProcess(pi.hProcess, 0); + if (task->getStandardInputCheck()) CloseHandle(si.hStdInput); + if (task->getStandardOutputCheck()) CloseHandle(si.hStdOutput); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + score = 0; + result = MemoryLimitExceeded; + timeUsed = -1; + return; + } } QCoreApplication::processEvents(); if (stopJudging) { @@ -532,7 +533,11 @@ void JudgingThread::runProgram() CloseHandle(pi.hThread); score = 0; result = RunTimeError; - message = tr("Exit code is %1").arg(exitCode); + QFile file(workingDirectory + "_tmperr"); + if (file.open(QFile::ReadOnly)) { + QTextStream stream(&file); + message = stream.readAll(); + } timeUsed = -1; return; } @@ -554,6 +559,7 @@ void JudgingThread::runProgram() if (task->getStandardInputCheck()) CloseHandle(si.hStdInput); if (task->getStandardOutputCheck()) CloseHandle(si.hStdOutput); + CloseHandle(si.hStdError); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); #endif @@ -565,7 +571,8 @@ void JudgingThread::runProgram() if (task->getStandardOutputCheck()) program->setStandardOutputFile(workingDirectory + "_tmpout"); program->setWorkingDirectory(workingDirectory); - program->start(QFileInfo(executableFile).absoluteFilePath()); + program->setProcessEnvironment(environment); + program->start(executableFile); if (! program->waitForStarted(-1)) { delete program; score = 0; @@ -617,7 +624,7 @@ void JudgingThread::runProgram() if (program->exitCode() != 0) { score = 0; result = RunTimeError; - message = tr("Exit code is %1").arg(program->exitCode()); + message = QString::fromLocal8Bit(program->readAllStandardError().data()); timeUsed = -1; delete program; return; diff --git a/judgingthread.h b/judgingthread.h index b5c260a..80f8354 100644 --- a/judgingthread.h +++ b/judgingthread.h @@ -31,8 +31,8 @@ class JudgingThread : public QThread public: explicit JudgingThread(QObject *parent = 0); void setCheckRejudgeMode(bool); - void setExtraTimeRation(double); - void setCompilerPath(const QString&); + void setExtraTimeRatio(double); + void setEnvironment(const QProcessEnvironment&); void setWorkingDirectory(const QString&); void setSpecialJudgeTimeLimit(int); void setExecutableFile(const QString&); @@ -55,7 +55,7 @@ class JudgingThread : public QThread bool checkRejudgeMode; bool needRejudge; double extraTimeRatio; - QString compilerPath; + QProcessEnvironment environment; QString workingDirectory; QString executableFile; QString answerFile; diff --git a/lemon.cpp b/lemon.cpp index fb2b7cc..6ad3f37 100644 --- a/lemon.cpp +++ b/lemon.cpp @@ -25,7 +25,7 @@ #include "contestant.h" #include "settings.h" #include "optionsdialog.h" -#include "compilerselectingdialog.h" +#include "addcompilerwizard.h" #include "newcontestdialog.h" #include "opencontestdialog.h" #include "welcomedialog.h" @@ -146,91 +146,15 @@ void Lemon::closeEvent(QCloseEvent *event) void Lemon::welcome() { -/* QList compilerList = settings->getCompilerList(); - Compiler *gcc = 0, *gpp = 0, *fpc = 0; - for (int i = 0; i < compilerList.size(); i ++) { - if (compilerList[i]->getCompilerName() == "gcc") - gcc = compilerList[i]; - if (compilerList[i]->getCompilerName() == "g++") - gpp = compilerList[i]; - if (compilerList[i]->getCompilerName() == "fpc") - fpc = compilerList[i]; - } - -#ifdef Q_OS_WIN32 - if (! gcc | ! gpp | ! fpc) { - CompilerSelectingDialog *dialog = new CompilerSelectingDialog(this); - if (gcc) dialog->setGccPath(gcc->getLocation()); - if (gpp) dialog->setGppPath(gpp->getLocation()); - if (fpc) dialog->setFpcPath(fpc->getLocation()); - if (dialog->exec() == QDialog::Accepted) { - if (! dialog->getGccPath().isEmpty()) - if (! gcc) { - gcc = new Compiler; - settings->addCompiler(gcc); - gcc->setCompilerName("gcc"); - gcc->setLocation(dialog->getGccPath()); - gcc->setSourceExtensions("c"); - gcc->addConfiguration("default", "-o %e %s"); - gcc->addConfiguration("with O2", "-o %e %s -O2"); - } else - gcc->setLocation(dialog->getGccPath()); - if (! dialog->getGppPath().isEmpty()) - if (! gpp) { - gpp = new Compiler; - settings->addCompiler(gpp); - gpp->setCompilerName("g++"); - gpp->setLocation(dialog->getGppPath()); - gpp->setSourceExtensions("cpp"); - gpp->addConfiguration("default", "-o %e %s"); - gpp->addConfiguration("with O2", "-o %e %s -O2"); - } else - gpp->setLocation(dialog->getGppPath()); - if (! dialog->getFpcPath().isEmpty()) - if (! fpc) { - fpc = new Compiler; - settings->addCompiler(fpc); - fpc->setCompilerName("fpc"); - fpc->setLocation(dialog->getFpcPath()); - fpc->setSourceExtensions("pas"); - fpc->addConfiguration("default", "-o%e %s"); - fpc->addConfiguration("with O2", "-o%e %s -O2"); - } else - fpc->setLocation(dialog->getFpcPath()); + if (settings->getCompilerList().size() == 0) { + AddCompilerWizard *wizard = new AddCompilerWizard(this); + if (wizard->exec() == QDialog::Accepted) { + QList compilerList = wizard->getCompilerList(); + for (int i = 0; i < compilerList.size(); i ++) + settings->addCompiler(compilerList[i]); } - delete dialog; + delete wizard; } -#endif - -#ifdef Q_OS_LINUX - if (! gcc && QFileInfo("/usr/bin/gcc").exists()) { - gcc = new Compiler; - settings->addCompiler(gcc); - gcc->setCompilerName("gcc"); - gcc->setLocation("/usr/bin/gcc"); - gcc->setSourceExtensions("c"); - gcc->addConfiguration("default", "-o %e %s"); - gcc->addConfiguration("with O2", "-o %e %s -O2"); - } - if (! gpp && QFileInfo("/usr/bin/g++").exists()) { - gpp = new Compiler; - settings->addCompiler(gpp); - gpp->setCompilerName("g++"); - gpp->setLocation("/usr/bin/g++"); - gpp->setSourceExtensions("cpp"); - gpp->addConfiguration("default", "-o %e %s"); - gpp->addConfiguration("with O2", "-o %e %s -O2"); - } - if (! fpc && QFileInfo("/usr/bin/fpc").exists()) { - fpc = new Compiler; - settings->addCompiler(fpc); - fpc->setCompilerName("fpc"); - fpc->setLocation("/usr/bin/fpc"); - fpc->setSourceExtensions("pas"); - fpc->addConfiguration("default", "-o%e %s"); - fpc->addConfiguration("with O2", "-o%e %s -O2"); - } -#endif*/ WelcomeDialog *dialog = new WelcomeDialog(this); dialog->setRecentContest(settings->getRecentContest()); @@ -535,12 +459,6 @@ void Lemon::addTask(const QString &title, const QList > Task *newTask = new Task; newTask->setProblemTitle(title); newTask->setSourceFileName(title); -#ifdef Q_OS_WIN32 - newTask->setExecutableFileName(title + ".exe"); -#endif -#ifdef Q_OS_LINUX - newTask->setExecutableFileName(title); -#endif newTask->setInputFileName(title + ".in"); newTask->setOutputFileName(title + ".out"); newTask->refreshCompilerConfiguration(settings); @@ -729,7 +647,7 @@ void Lemon::makeSelfTest() out << QString("echo Input file: %1").arg(QFileInfo(outputFiles[k]).fileName()) << endl; if (taskList[i]->getTaskType() == Task::Traditional) { out << "timegetExecutableFileName() + "\""; + QString cmd = QString("\"") + taskList[i]->getSourceFileName() + ".exe" + "\""; if (taskList[i]->getStandardInputCheck()) cmd += QString(" <\"%1\"").arg(QFileInfo(inputFiles[k]).fileName()); if (taskList[i]->getStandardOutputCheck()) @@ -784,7 +702,7 @@ void Lemon::makeSelfTest() taskList[i]->getInputFileName()) << endl; out << QString("echo \"Input file: %1\"").arg(QFileInfo(outputFiles[k]).fileName()) << endl; if (taskList[i]->getTaskType() == Task::Traditional) { - QString cmd = QString("\"") + taskList[i]->getExecutableFileName() + "\""; + QString cmd = QString("\"") + taskList[i]->getSourceFileName() + "\""; if (taskList[i]->getStandardInputCheck()) cmd += QString(" <\"%1\"").arg(QFileInfo(inputFiles[k]).fileName()); if (taskList[i]->getStandardOutputCheck()) diff --git a/lemon.pro b/lemon.pro index d9a91f5..14bbe6d 100644 --- a/lemon.pro +++ b/lemon.pro @@ -48,14 +48,14 @@ SOURCES += main.cpp \ opencontestdialog.cpp \ welcomedialog.cpp \ addtaskdialog.cpp \ - compilerselectingdialog.cpp \ qtlockedfile/qtlockedfile.cpp \ qtsingleapplication/qtsinglecoreapplication.cpp \ qtsingleapplication/qtsingleapplication.cpp \ qtsingleapplication/qtlocalpeer.cpp \ advancedcompilersettingsdialog.cpp \ environmentvariablesdialog.cpp \ - editvariabledialog.cpp + editvariabledialog.cpp \ + addcompilerwizard.cpp win32:SOURCES += qtlockedfile/qtlockedfile_win.cpp unix:SOURCES += qtlockedfile/qtlockedfile_unix.cpp @@ -88,14 +88,14 @@ HEADERS += lemon.h \ welcomedialog.h \ linux_proc.h \ addtaskdialog.h \ - compilerselectingdialog.h \ qtlockedfile/qtlockedfile.h \ qtsingleapplication/qtsinglecoreapplication.h \ qtsingleapplication/qtsingleapplication.h \ qtsingleapplication/qtlocalpeer.h \ advancedcompilersettingsdialog.h \ environmentvariablesdialog.h \ - editvariabledialog.h + editvariabledialog.h \ + addcompilerwizard.h FORMS += lemon.ui \ taskeditwidget.ui \ @@ -112,10 +112,10 @@ FORMS += lemon.ui \ opencontestdialog.ui \ welcomedialog.ui \ addtaskdialog.ui \ - compilerselectingdialog.ui \ advancedcompilersettingsdialog.ui \ environmentvariablesdialog.ui \ - editvariabledialog.ui + editvariabledialog.ui \ + addcompilerwizard.ui TRANSLATIONS += lemon_zh_CN.ts @@ -130,9 +130,3 @@ RESOURCES += resource.qrc - - - - - - diff --git a/lemon_zh_CN.qm b/lemon_zh_CN.qm index 3fc3b1b..e1d325c 100644 Binary files a/lemon_zh_CN.qm and b/lemon_zh_CN.qm differ diff --git a/lemon_zh_CN.ts b/lemon_zh_CN.ts index f5d22e4..cf8877f 100644 --- a/lemon_zh_CN.ts +++ b/lemon_zh_CN.ts @@ -1,6 +1,354 @@ + + AddCompilerWizard + + + Add Compilers Wizard + 编译器添加向导 + + + + Step I: Choose whether you want to use built-in configuration for certain compilers or customize a compiler's configuration. + 步骤一:选择是自定义编译器还是使用预制的编译器配置。 + + + + Custom Configuration + 自定义编译器 + + + + Built-in Configuration (Tick the compilers you want to add) + 预制编译器配置(在你要添加的编译器上打钩) + + + + Step II: Select compiler's location to configure it. + 步骤二:选择编译器目录进行配置。 + + + + Compiler Name + 编译器名称 + + + + Compiler Type + 编译器类型 + + + + Typical (Generate executable file) + 传统型(生成可执行文件) + + + + Interpretive (Generate byte-code file) + 解释型(生成中间字节码) + + + + Interpretive (Run source code directly) + 解释型(直接运行源代码) + + + + Compiler's Location + 编译器位置 + + + + Interpreter's Location + 解释器位置 + + + + Source File Extensions + 源程序后缀名 + + + + Byte-code File Extensions + 中间字节码后缀名 + + + + Default Compiler's Arguments + 默认编译器参数 + + + + Default Interpreter's Arguments + 默认解释器参数 + + + + Step II: Select compilers' locations to configure them. + 步骤二:选择编译器路径进行配置。 + + + + + + + + + Enable O2 Optimization + 开始O2优化 + + + + Memory Limit + 空间限制 + + + + MB + MB + + + + + Generate Optimized Byte-code + 生成优化的字节码 + + + + Step III: Check the result and finish the wizard. + 步骤三:检查结果并完成向导。 + + + + + + + + + + + + + + + Error + 错误 + + + + Empty compiler name! + 编译器名称为空! + + + + Empty compiler location! + 编译器位置为空! + + + + Empty interpreter location! + 解释器位置为空! + + + + Empty source file extensions! + 源程序扩展名为空! + + + + Empty byte-code file extensions! + 中间字节码扩展名为空! + + + + [Custom Compiler] + 【自定义编译器】 + + + + Compiler Name: + 编译器名称: + + + + Compiler Type: + 编译器类型: + + + + Compiler's Location: + 编译器位置: + + + + Interpreter's Location: + 解释器位置: + + + + Source File Extensions: + 源程序后缀名: + + + + Byte-code File Extensions: + 中间字节码后缀名: + + + + Default Compiler's Arguments: + 默认编译器参数: + + + + Default Interpreter's Arguments: + 默认解释器参数: + + + + Empty gcc path! + gcc路径为空! + + + + Empty g++ path! + g++路径为空! + + + + Empty fpc path! + fpc路径为空! + + + + Empty fbc path! + fbc路径为空! + + + + Empty javac path! + javac路径为空! + + + + Empty java path! + java路径为空! + + + + Empty python path! + python路径为空! + + + + [gcc Compiler] + 【gcc编译器】 + + + + gcc Path: + gcc路径: + + + + [g++ Compiler] + 【g++编译器】 + + + + g++ Path: + g++路径: + + + + [fpc Compiler] + 【fpc编译器】 + + + + fpc Path: + fpc路径: + + + + [fbc Compiler] + 【fbc编译器】 + + + + fbc Path: + fbc路径: + + + + [Java Compiler] + 【Java编译器】 + + + + javac Path: + javac路径: + + + + java Path: + java路径: + + + + Memory Limit: %1 MB + 内存限制:%1 MB + + + + [Python Compiler] + 【Python编译器】 + + + + python Path: + python路径: + + + + + + + + + + + + + + + Select Compiler's Location + 选择编译器位置 + + + + + Executable files (*.exe) + 可执行文件 (*.exe) + + + + + Executable files (*.*) + 可执行文件 (*.*) + + + + + + + + + Select Interpreter's Location + 选择解释器位置 + + AddTaskDialog @@ -165,15 +513,172 @@ - CompilerSelectingDialog + AdvancedCompilerSettingsDialog + + + Compiler Settings + 编译器设置 + + + + Typical (Generate executable file) + 传统型(生成可执行文件) + + + + Interpretive (Generate byte-code file) + 解释型(生成中间字节码) + + + + Interpretive (Run source code directly) + 解释型(直接运行源代码) + + + + Location + 位置 + + + + Compiler + 编译器 + + + + Interpreter + 解释器 + + + + Byte-code File Extensions + 中间字节码后缀名 + + + + Time and Memory Limit + 时间、内存限制 + + + + Time Limit Ration + 时间限制比率 + + + + Memory Limit Ration + 内存限制比率 + + + + Disable Memory Limit + 取消内存限制 + + + + Arguments + 参数 + + + + Configuration + 配置 + + + + ... + ... + + + + Compiler's Arguments + 编译器参数 + + + + Interpreter's Arguments + 解释器参数 + - - - - + + Environment Variables + 环境变量 + + + + + Add new ... + 添加... + + + + + + + + + Error + 错误 + + + + Empty compiler's Location! + 编译器位置为空! + + + + Empty interpreter's Location! + 解释器位置为空! + + + + Empty Byte-code Extensions! + 中间字节码扩展名为空! + + + + Empty configuration name! + 配置名称为空! + + + + Configuration %1 appears more than once! + 配置%1出现多次! + + + + Invalid configuration name "disable"! + 非法配置名“disable”! + + + + Select Compiler's Location 选择编译器位置 + + + + Executable files (*.exe) + 可执行文件 (*.exe) + + + + + Executable files (*.*) + 可执行文件 (*.*) + + + + + Select Interpreter's Location + 选择解释器位置 + + + + New configuration %1 + 新建配置%1 + CompilerSettings @@ -183,106 +688,103 @@ Form - + Compiler Name 编译器名称 - + Source Extensions 源程序扩展名 - + + &Advanced + 高级 + + Location - 位置 + 位置 - Configurations - 配置 + 配置 - Arguments - 参数 + 参数 - (Use %s stands for source file name and %e stands for executable file name in argument list.) - (用%s表示源程序文件名,%e表示可执行文件名。) + (用%s表示源程序文件名,%e表示可执行文件名。) - - - - - - + + + Error 错误 - + Compiler %1 appears more than once! 编译器%1出现多次! - + Empty compiler name! 编译器名称为空! - + Empty source file extensions! 源程序扩展名为空! - + + Lemon + Lemon + + + + Are you sure to delete compiler %1? + 确定删除编译器%1吗? + + Empty compiler location! - 编译器位置为空! + 编译器位置为空! - Empty configuration name! - 配置名称为空! + 配置名称为空! - Configuration %1 appears more than once! - 配置%1出现多次! + 配置%1出现多次! - New compiler - 新建编译器 + 新建编译器 - - Add new ... - 添加... + 添加... - - Select Compiler's Location - 选择编译器位置 + 选择编译器位置 - Executable files (*.exe) - 可执行文件 (*.exe) + 可执行文件 (*.exe) - Executable files (*.*) - 可执行文件 (*.*) + 可执行文件 (*.*) - New configuration %1 - 新建配置%1 + 新建配置%1 @@ -302,30 +804,30 @@ 关闭 - + Contestant: %1 选手:%1 - + Task 试题 - + Rejudge 重新测试 - + Not judged 未测试 - + Cannot find valid source file 未找到源程序 @@ -333,157 +835,228 @@ - - - + + + Source file: 源程序: - + Compile time limit exceeded 编译超时 - + Cannot run given compiler 给定编译器无法运行 - + Compile error &nbsp;&nbsp;Compile error 编译错误 - + Test Case 测试点 - + Input File 输入文件 - + Result 测试结果 - + Time Used 运行用时 - + Memory Used 内存消耗 - + Score 得分 - + Correct Answer 答案正确 - + Wrong Answer 答案错误 - + Partly Correct 答案部分正确 - + Time Limit Exceeded 运行超时 - + Memory Limit Exceeded 超过空间限制 - + Cannot Start Program 无法运行程序 - + File Error 文件错误 - + Run Time Error 运行时错误 - + Invalid Special Judge 无效校验器 - + Special Judge Time Limit Exceeded 校验器运行超时 - + Special Judge Run Time Error 校验器运行时错误 - - - - + + + + Invalid 不可用 - + Return to top 返回顶部 - + Compile Message 编译信息 - + Message 信息 + + EditVariableDialog + + + Dialog + Dialog + + + + Variable Name + 变量名称 + + + + Variable Value + 变量的值 + + + + EnvironmentVariablesDialog + + + Extra Environment Variables + 额外的环境变量 + + + + Variable + 变量 + + + + Value + + + + + &Add + 添加 + + + + &Edit + 编辑 + + + + &Delete + 删除 + + + + Add New Variable + 添加新变量 + + + + Edit Variable + 编辑变量 + + + + Lemon + Lemon + + + + Are you sure to delete variable %1? + 确定删除变量%1? + + GeneralSettings @@ -752,7 +1325,7 @@ - + Cannot find standard input file 找不到标准输入文件 @@ -767,39 +1340,37 @@ 找不到标准输出文件 - + Cannot copy standard input file 无法复制标准输入文件 - - Exit code is %1 - 错误码为%1 + 错误码为%1 Lemon - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - + Lemon Lemon @@ -920,190 +1491,190 @@ 简体中文 - - - - + + + + Error 错误 - - - - - + + + + + Cannot open file %1 无法打开%1 - + File %1 is broken %1已损坏 - - + + Lemon - %1 Lemon - %1 - + Cannot make contest path 无法创建比赛目录 - + No task found 找不到任何试题 - + Cannot make directory 无法创建目录 - + Cannot write check.bat check.bat无法写入 - + Cannot write enter enter无法写入 - + Cannot write check.sh check.sh无法写入 - - - + + + Cannot copy %1 %1无法复制 - + Self-test folder has been made 创建完成 - - - + + + Export is done 导出完成 - + No contestant in current contest 不存在选手 - + No task in current contest 不存在试题 - + ;;Excel Workbook (*.xls) ;;Excel工作簿 (*.xls) - + Export Result 导出成绩 - + HTML Document (*.html);;CSV (*.csv) HTML文档 (*.html);;逗号分隔符 (*.csv) - + Contest Result 比赛结果 - + Rank List 排名表 - - - + + + Rank 排名 - - - + + + Name 名称 - - - + + + Total Score 总分 - - - - - - + + + + + + Invalid 不可用 - + Contestant: %1 选手:%1 - + A tiny judging environment for OI contest 简易OI竞赛测试环境 - + Version 1.0 Release v1.0 正式版 - + Build Date: %1 构建日期:%1 - + Copyright (c) 2011 Zhipeng Jia Copyright (c) 2011 Zhipeng Jia - + This program is under the <a href="http://www.gnu.org/licenses/gpl-3.0.html">GPLv3</a> license 本程序基于<a href="http://www.gnu.org/licenses/gpl-3.0.html">GPLv3</a>许可协议 - + Author's blog 作者博客 - + Google Code Page Google Code页面 - + About Lemon 关于Lemon @@ -1359,21 +1930,17 @@ - Executable File Name - 可执行文件名称 - - - Input File Name - 输入文件名 + Executable File Name + 可执行文件名称 - + Output File Name 输出文件名 - + Standard input 标准输入 @@ -1393,52 +1960,52 @@ 答案提交型 - + Standard output 标准输出 - + Comparison Mode 比较模式 - + Line-by-line mode 逐行比较模式 - + Real number mode 实数比较模式 - + Special judge mode 自定义校验器模式 - + Real Number Precision: 实数精度: - + digits - + Compiler Settings 编译器设置 - + Configuration: 配置: - + Extension of Contestant's Answer File 选手答案文件扩展名 diff --git a/settings.cpp b/settings.cpp index d384d59..ec305b0 100644 --- a/settings.cpp +++ b/settings.cpp @@ -233,23 +233,32 @@ void Settings::saveSettings() settings.setValue("OutputFileExtensions", outputFileExtensions); settings.endGroup(); - /*settings.beginWriteArray("CompilerSettings"); + settings.beginWriteArray("CompilerSettings"); for (int i = 0; i < compilerList.size(); i ++) { settings.setArrayIndex(i); + settings.setValue("CompilerType", (int)compilerList[i]->getCompilerType()); settings.setValue("CompilerName", compilerList[i]->getCompilerName()); settings.setValue("SourceExtensions", compilerList[i]->getSourceExtensions()); - settings.setValue("Location", compilerList[i]->getLocation()); + settings.setValue("CompilerLocation", compilerList[i]->getCompilerLocation()); + settings.setValue("InterpreterLocation", compilerList[i]->getInterpreterLocation()); + settings.setValue("BytecodeExtensions", compilerList[i]->getBytecodeExtensions()); + settings.setValue("TimeLimitRatio", compilerList[i]->getTimeLimitRatio()); + settings.setValue("MemoryLimitRatio", compilerList[i]->getMemoryLimitRatio()); + settings.setValue("DisableMemoryLimitCheck", compilerList[i]->getDisableMemoryLimitCheck()); QStringList configurationNames = compilerList[i]->getConfigurationNames(); - QStringList configurationSettings = compilerList[i]->getConfigurationSettings(); + QStringList compilerArguments = compilerList[i]->getCompilerArguments(); + QStringList interpreterArguments = compilerList[i]->getInterpreterArguments(); settings.beginWriteArray("Configuration"); for (int j = 0; j < configurationNames.size(); j ++) { settings.setArrayIndex(j); settings.setValue("Name", configurationNames[j]); - settings.setValue("Arguments", configurationSettings[j]); + settings.setValue("CompilerArguments", compilerArguments[j]); + settings.setValue("InterpreterArguments", interpreterArguments[j]); } + settings.setValue("EnvironmentVariables", compilerList[i]->getEnvironment().toStringList()); settings.endArray(); } - settings.endArray();*/ + settings.endArray(); settings.beginWriteArray("RecentContest"); for (int i = 0; i < recentContest.size(); i ++) { @@ -284,23 +293,39 @@ void Settings::loadSettings() outputFileExtensions = settings.value("OutputFileExtensions", QStringList() << "out" << "ans").toStringList(); settings.endGroup(); - /*int compilerCount = settings.beginReadArray("CompilerSettings"); + int compilerCount = settings.beginReadArray("CompilerSettings"); for (int i = 0; i < compilerCount; i ++) { settings.setArrayIndex(i); Compiler *compiler = new Compiler; + compiler->setCompilerType((Compiler::CompilerType)settings.value("CompilerType").toInt()); compiler->setCompilerName(settings.value("CompilerName").toString()); compiler->setSourceExtensions(settings.value("SourceExtensions").toStringList().join(";")); - compiler->setLocation(settings.value("Location").toString()); + compiler->setCompilerLocation(settings.value("CompilerLocation").toString()); + compiler->setInterpreterLocation(settings.value("InterpreterLocation").toString()); + compiler->setBytecodeExtensions(settings.value("BytecodeExtensions").toStringList().join(";")); + compiler->setTimeLimitRatio(settings.value("TimeLimitRatio").toDouble()); + compiler->setMemoryLimitRatio(settings.value("MemoryLimitRatio").toDouble()); + compiler->setDisableMemoryLimitCheck(settings.value("DisableMemoryLimitCheck").toBool()); int configurationCount = settings.beginReadArray("Configuration"); for (int j = 0; j < configurationCount; j ++) { settings.setArrayIndex(j); compiler->addConfiguration(settings.value("Name").toString(), - settings.value("Arguments").toString()); + settings.value("CompilerArguments").toString(), + settings.value("InterpreterArguments").toString()); + } + QStringList values = settings.value("EnvironmentVariables").toStringList(); + QProcessEnvironment environment; + for (int i = 0; i < values.size(); i ++) { + int tmp = values[i].indexOf('='); + QString variable = values[i].mid(0, tmp); + QString value = values[i].mid(tmp + 1); + environment.insert(variable, value); } + compiler->setEnvironment(environment); settings.endArray(); addCompiler(compiler); } - settings.endArray();*/ + settings.endArray(); int listCount = settings.beginReadArray("RecentContest"); for (int i = 0; i < listCount; i ++) { diff --git a/task.cpp b/task.cpp index efebe30..45d92fc 100644 --- a/task.cpp +++ b/task.cpp @@ -46,11 +46,6 @@ const QString& Task::getSourceFileName() const return sourceFileName; } -const QString& Task::getExecutableFileName() const -{ - return executableFileName; -} - const QString& Task::getInputFileName() const { return inputFileName; @@ -113,11 +108,6 @@ void Task::setSourceFileName(const QString &fileName) sourceFileName = fileName; } -void Task::setExecutableFileName(const QString &fileName) -{ - executableFileName = fileName; -} - void Task::setInputFileName(const QString &fileName) { inputFileName = fileName; @@ -225,7 +215,6 @@ void Task::writeToStream(QDataStream &out) { out << problemTitle; out << sourceFileName; - out << executableFileName; out << inputFileName; out << outputFileName; out << standardInputCheck; @@ -246,7 +235,6 @@ void Task::readFromStream(QDataStream &in) int tmp, count; in >> problemTitle; in >> sourceFileName; - in >> executableFileName; in >> inputFileName; in >> outputFileName; in >> standardInputCheck; diff --git a/task.h b/task.h index 904abe6..02518b5 100644 --- a/task.h +++ b/task.h @@ -37,7 +37,6 @@ class Task : public QObject const QList& getTestCaseList() const; const QString& getProblemTile() const; const QString& getSourceFileName() const; - const QString& getExecutableFileName() const; const QString& getInputFileName() const; const QString& getOutputFileName() const; bool getStandardInputCheck() const; @@ -51,7 +50,6 @@ class Task : public QObject void setProblemTitle(const QString&); void setSourceFileName(const QString&); - void setExecutableFileName(const QString&); void setInputFileName(const QString&); void setOutputFileName(const QString&); void setStandardInputCheck(bool); @@ -75,7 +73,6 @@ class Task : public QObject QList testCaseList; QString problemTitle; QString sourceFileName; - QString executableFileName; QString inputFileName; QString outputFileName; bool standardInputCheck; diff --git a/taskeditwidget.cpp b/taskeditwidget.cpp index d7c9386..9e42974 100644 --- a/taskeditwidget.cpp +++ b/taskeditwidget.cpp @@ -35,7 +35,6 @@ TaskEditWidget::TaskEditWidget(QWidget *parent) : ui->specialJudge, SLOT(refreshFileList())); ui->sourceFileName->setValidator(new QRegExpValidator(QRegExp("\\w+"), ui->sourceFileName)); - ui->executableFileName->setValidator(new QRegExpValidator(QRegExp("(\\w+)(\\.\\w+)?"), ui->executableFileName)); ui->inputFileName->setValidator(new QRegExpValidator(QRegExp("(\\w+)(\\.\\w+)?"), ui->inputFileName)); ui->outputFileName->setValidator(new QRegExpValidator(QRegExp("(\\w+)(\\.\\w+)?"), ui->outputFileName)); ui->answerFileExtension->setValidator(new QRegExpValidator(QRegExp("\\w+"), ui->answerFileExtension)); @@ -48,8 +47,6 @@ TaskEditWidget::TaskEditWidget(QWidget *parent) : this, SLOT(setToAnswersOnly(bool))); connect(ui->sourceFileName, SIGNAL(textChanged(QString)), this, SLOT(sourceFileNameChanged(QString))); - connect(ui->executableFileName, SIGNAL(textChanged(QString)), - this, SLOT(executableFileNameChanged(QString))); connect(ui->inputFileName, SIGNAL(textChanged(QString)), this, SLOT(inputFileNameChanged(QString))); connect(ui->outputFileName, SIGNAL(textChanged(QString)), @@ -105,7 +102,6 @@ void TaskEditWidget::setEditTask(Task *task) ui->sourceFileName->setEnabled(false); ui->sourceFileName->setText(editTask->getSourceFileName()); ui->sourceFileName->setEnabled(true); - ui->executableFileName->setText(task->getExecutableFileName()); ui->inputFileName->setText(editTask->getInputFileName()); ui->outputFileName->setText(editTask->getOutputFileName()); ui->comparisonMode->setCurrentIndex(int(editTask->getComparisonMode())); @@ -133,8 +129,6 @@ void TaskEditWidget::refreshWidgetState() bool check = editTask->getTaskType() == Task::Traditional; ui->sourceFileName->setEnabled(check); ui->sourceFileNameLabel->setEnabled(check); - ui->executableFileName->setEnabled(check); - ui->executableFileNameLabel->setEnabled(check); ui->inputFileName->setEnabled(check && ! editTask->getStandardInputCheck()); ui->inputFileNameLabel->setEnabled(check); ui->standardInputCheck->setEnabled(check); @@ -174,24 +168,12 @@ void TaskEditWidget::sourceFileNameChanged(const QString &text) if (! editTask) return; if (! ui->sourceFileName->isEnabled()) return; editTask->setSourceFileName(text); -#ifdef Q_OS_WIN32 - ui->executableFileName->setText(text + ".exe"); -#endif -#ifdef Q_OS_LINUX - ui->executableFileName->setText(text); -#endif if (ui->inputFileName->isEnabled()) ui->inputFileName->setText(text + "." + settings->getDefaultInputFileExtension()); if (ui->outputFileName->isEnabled()) ui->outputFileName->setText(text + "." + settings->getDefaultOutputFileExtension()); } -void TaskEditWidget::executableFileNameChanged(const QString &text) -{ - if (! editTask) return; - editTask->setExecutableFileName(text); -} - void TaskEditWidget::inputFileNameChanged(const QString &text) { if (! editTask) return; @@ -269,6 +251,7 @@ void TaskEditWidget::compilerSelectionChanged() if (! ui->compilersList->isEnabled()) return; ui->configurationSelect->setEnabled(false); ui->configurationSelect->clear(); + ui->configurationSelect->addItem("disable"); const QList &compilerList = settings->getCompilerList(); for (int i = 0; i < compilerList.size(); i ++) if (compilerList[i]->getCompilerName() == ui->compilersList->currentItem()->text()) diff --git a/taskeditwidget.h b/taskeditwidget.h index d602804..843bfcb 100644 --- a/taskeditwidget.h +++ b/taskeditwidget.h @@ -52,7 +52,6 @@ private slots: void setToTraditional(bool); void setToAnswersOnly(bool); void sourceFileNameChanged(const QString&); - void executableFileNameChanged(const QString&); void inputFileNameChanged(const QString&); void outputFileNameChanged(const QString&); void standardInputCheckChanged(); diff --git a/taskeditwidget.ui b/taskeditwidget.ui index d9ee6ce..3e7b714 100644 --- a/taskeditwidget.ui +++ b/taskeditwidget.ui @@ -112,26 +112,6 @@ font-weight: bold; - - - - 0 - 0 - - - - font-size: 9pt; -font-weight: bold; - - - Executable File Name - - - - - - - @@ -148,10 +128,10 @@ font-weight: bold; - + - + font-size: 9pt; @@ -161,7 +141,7 @@ font-weight: bold; - + @@ -178,10 +158,10 @@ font-weight: bold; - + - + font-size: 9pt; @@ -191,7 +171,7 @@ font-weight: bold; - + @@ -208,7 +188,7 @@ font-weight: bold; - + font-size: 9pt; @@ -230,7 +210,7 @@ font-weight: bold; - + @@ -311,7 +291,7 @@ font-weight: bold; - + @@ -357,7 +337,7 @@ font-weight: bold; - + 12 @@ -400,7 +380,7 @@ font-weight: bold; - + 10 @@ -471,7 +451,6 @@ font-weight: bold; problemTitle sourceFileName - executableFileName inputFileName standardInputCheck outputFileName