- enhancement: Problem Set Support
- enhancement: Competitive Companion Support
This commit is contained in:
parent
f28aac649b
commit
47f10a2105
2
NEWS.md
2
NEWS.md
|
@ -4,6 +4,8 @@ Version 0.7.7
|
|||
- fix: can't parse old c-style enum variable definition like "enum Test test;"
|
||||
- fix: remove the file change monitor if it's remove from the disk
|
||||
- fix: don't test if a file is writable before save to it (because qt can't do that test reliably).
|
||||
- enhancement: Problem Set
|
||||
- enhancement: Competitive Companion Support
|
||||
|
||||
Version 0.7.6
|
||||
- change: don't auto insert a new line when input an enter between '(' and ')' or between '[' and ']' (indent instead)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
QT += core gui printsupport
|
||||
QT += core gui printsupport network
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase)
|
|||
if (errorOccurred)
|
||||
break;
|
||||
}
|
||||
readed += process.readAll();
|
||||
if (errorOccurred) {
|
||||
//qDebug()<<"process error:"<<process.error();
|
||||
switch (process.error()) {
|
||||
|
|
|
@ -26,10 +26,14 @@
|
|||
#include <QDragEnterEvent>
|
||||
#include <QFileDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
#include <QTcpSocket>
|
||||
#include <QTranslator>
|
||||
|
||||
#include "settingsdialog/settingsdialog.h"
|
||||
|
@ -209,6 +213,7 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
ui->btnRemoveProblem->setEnabled(false);
|
||||
ui->btnRemoveProblemCase->setEnabled(false);
|
||||
|
||||
//problem set
|
||||
mOJProblemSetNameCounter=1;
|
||||
mOJProblemSetModel.rename(tr("Problem Set %1").arg(mOJProblemSetNameCounter));
|
||||
ui->lstProblemSet->setModel(&mOJProblemSetModel);
|
||||
|
@ -222,6 +227,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
connect(&mOJProblemSetModel, &OJProblemSetModel::problemNameChanged,
|
||||
this , &MainWindow::onProblemNameChanged);
|
||||
ui->pbProblemCases->setVisible(false);
|
||||
connect(&mTcpServer,&QTcpServer::newConnection,
|
||||
this, &MainWindow::onNewProblemConnection);
|
||||
|
||||
//files view
|
||||
ui->treeFiles->setModel(&mFileSystemModel);
|
||||
|
@ -528,6 +535,12 @@ void MainWindow::applySettings()
|
|||
font.setStyleStrategy(QFont::PreferAntialias);
|
||||
qApp->setFont(font);
|
||||
this->setFont(font);
|
||||
|
||||
if (!mTcpServer.listen(QHostAddress::LocalHost,10045)) {
|
||||
QMessageBox::critical(nullptr,
|
||||
tr("Listen failed"),
|
||||
tr("Can't listen to port %1").arg(10045));
|
||||
}
|
||||
updateDebuggerSettings();
|
||||
}
|
||||
|
||||
|
@ -2535,11 +2548,12 @@ void MainWindow::onProblemSetIndexChanged(const QModelIndex ¤t, const QMod
|
|||
ui->txtProblemCaseInput->clear();
|
||||
ui->txtProblemCaseOutput->clear();
|
||||
ui->tabProblem->setEnabled(false);
|
||||
ui->lblProblem->clear();
|
||||
} else {
|
||||
ui->btnRemoveProblem->setEnabled(true);
|
||||
POJProblem problem = mOJProblemSetModel.problem(idx.row());
|
||||
mOJProblemModel.setProblem(problem);
|
||||
ui->lblProblem->setText(problem->name);
|
||||
ui->lblProblem->setText(mOJProblemModel.getTitle());
|
||||
ui->lstProblemCases->setCurrentIndex(mOJProblemModel.index(0,0));
|
||||
openCloseBottomPanel(true);
|
||||
ui->tabMessages->setCurrentWidget(ui->tabProblem);
|
||||
|
@ -2582,10 +2596,53 @@ void MainWindow::onProblemNameChanged(int index)
|
|||
QModelIndex idx = ui->lstProblemSet->currentIndex();
|
||||
if (idx.isValid() && index == idx.row()) {
|
||||
POJProblem problem = mOJProblemSetModel.problem(idx.row());
|
||||
ui->lblProblem->setText(problem->name);
|
||||
ui->lblProblem->setText(mOJProblemModel.getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onNewProblemConnection()
|
||||
{
|
||||
QTcpSocket* clientConnection = mTcpServer.nextPendingConnection();
|
||||
mTcpServer.connect(clientConnection, &QAbstractSocket::disconnected,
|
||||
clientConnection, &QObject::deleteLater);
|
||||
QByteArray content;
|
||||
while (clientConnection->state() == QTcpSocket::ConnectedState) {
|
||||
clientConnection->waitForReadyRead();
|
||||
content += clientConnection->readAll();
|
||||
}
|
||||
content += clientConnection->readAll();
|
||||
content = getHTTPBody(content);
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(content,&error);
|
||||
if (error.error!=QJsonParseError::NoError) {
|
||||
qDebug()<<"Read http content failed!";
|
||||
qDebug()<<error.errorString();
|
||||
return;
|
||||
}
|
||||
QJsonObject obj=doc.object();
|
||||
QString name = obj["name"].toString();
|
||||
if (!mOJProblemSetModel.problemNameUsed(name)) {
|
||||
POJProblem problem = std::make_shared<OJProblem>();
|
||||
problem->name = name;
|
||||
problem->url = obj["url"].toString();
|
||||
QJsonArray caseArray = obj["tests"].toArray();
|
||||
foreach ( const QJsonValue& val, caseArray) {
|
||||
QJsonObject caseObj = val.toObject();
|
||||
POJProblemCase problemCase = std::make_shared<OJProblemCase>();
|
||||
problemCase->testState = ProblemCaseTestState::NotTested;
|
||||
problemCase->name = tr("Problem Case %1").arg(problem->cases.count()+1);
|
||||
problemCase->input = caseObj["input"].toString();
|
||||
problemCase->expected = caseObj["output"].toString();
|
||||
problem->cases.append(problemCase);
|
||||
}
|
||||
mOJProblemSetModel.addProblem(problem);
|
||||
if (!ui->lstProblemSet->currentIndex().isValid()) {
|
||||
ui->lstProblemSet->setCurrentIndex(mOJProblemSetModel.index(0,0));
|
||||
}
|
||||
}
|
||||
clientConnection->disconnectFromHost();
|
||||
}
|
||||
|
||||
void MainWindow::onShowInsertCodeSnippetMenu()
|
||||
{
|
||||
mMenuInsertCodeSnippet->clear();
|
||||
|
@ -3386,6 +3443,7 @@ void MainWindow::onOJProblemCaseFinished(const QString &id, int current, int tot
|
|||
}
|
||||
ui->pbProblemCases->setMaximum(total);
|
||||
ui->pbProblemCases->setValue(current);
|
||||
ui->lblProblem->setText(mOJProblemModel.getTitle());
|
||||
}
|
||||
|
||||
void MainWindow::cleanUpCPUDialog()
|
||||
|
@ -4973,8 +5031,9 @@ void MainWindow::on_btnNewProblemSet_clicked()
|
|||
tr("The current problem set is not empty.")
|
||||
+"<br />"
|
||||
+tr("Do you want to save it?"),
|
||||
QMessageBox::Yes | QMessageBox::No)!=QMessageBox::Yes)
|
||||
return;
|
||||
QMessageBox::Yes | QMessageBox::No)==QMessageBox::Yes) {
|
||||
on_btnSaveProblemSet_clicked();
|
||||
}
|
||||
}
|
||||
mOJProblemSetNameCounter++;
|
||||
mOJProblemSetModel.create(tr("Problem Set %1").arg(mOJProblemSetNameCounter));
|
||||
|
@ -5056,7 +5115,7 @@ void MainWindow::on_btnAddProblemCase_clicked()
|
|||
}
|
||||
POJProblemCase problemCase = std::make_shared<OJProblemCase>();
|
||||
problemCase->name = name;
|
||||
problemCase->testState = ProblemCaseTestState::NoTested;
|
||||
problemCase->testState = ProblemCaseTestState::NotTested;
|
||||
mOJProblemModel.addCase(problemCase);
|
||||
ui->lstProblemCases->setCurrentIndex(mOJProblemModel.index(mOJProblemModel.count()-1));
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
#include <QFileSystemModel>
|
||||
#include <QTcpServer>
|
||||
#include "common.h"
|
||||
#include "widgets/searchresultview.h"
|
||||
#include "widgets/classbrowser.h"
|
||||
|
@ -227,6 +228,7 @@ private slots:
|
|||
void onProblemSetIndexChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void onProblemCaseIndexChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void onProblemNameChanged(int index);
|
||||
void onNewProblemConnection();
|
||||
|
||||
void onShowInsertCodeSnippetMenu();
|
||||
|
||||
|
@ -524,6 +526,7 @@ private:
|
|||
bool mClosing;
|
||||
bool mSystemTurnedOff;
|
||||
QPoint mEditorContextMenuPos;
|
||||
QTcpServer mTcpServer;
|
||||
|
||||
//actions for compile issue table
|
||||
QAction * mTableIssuesCopyAction;
|
||||
|
|
|
@ -1129,6 +1129,9 @@
|
|||
<property name="text">
|
||||
<string>Problem</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <QVector>
|
||||
|
||||
enum class ProblemCaseTestState {
|
||||
NoTested,
|
||||
NotTested,
|
||||
Testing,
|
||||
Passed,
|
||||
Failed
|
||||
|
@ -30,6 +30,7 @@ using POJProblemCase = std::shared_ptr<OJProblemCase>;
|
|||
|
||||
struct OJProblem {
|
||||
QString name;
|
||||
QString url;
|
||||
QVector<POJProblemCase> cases;
|
||||
};
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <QStringList>
|
||||
|
||||
#define DEVCPP_VERSION "0.7.6"
|
||||
#define DEVCPP_VERSION "0.7.7"
|
||||
|
||||
#define APP_SETTSINGS_FILENAME "redpandacpp.ini"
|
||||
#ifdef Q_OS_WIN
|
||||
|
|
|
@ -844,3 +844,11 @@ QByteArray ReadFileToByteArray(const QString &fileName)
|
|||
}
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray getHTTPBody(const QByteArray& content) {
|
||||
int i= content.indexOf("\r\n\r\n");
|
||||
if (i>=0) {
|
||||
return content.mid(i+4);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -166,6 +166,7 @@ QString TrimRight(const QString& s);
|
|||
QString TrimLeft(const QString& s);
|
||||
bool StringIsBlank(const QString& s);
|
||||
int compareFileModifiedTime(const QString& filename1, const QString& filename2);
|
||||
QByteArray getHTTPBody(const QByteArray& content);
|
||||
|
||||
//void changeTheme(const QString& themeName);
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
<property name="text">
|
||||
<string><html><head/><body><p>Based on Qt %1 (%2)</p><p>Build time: %3 %4</p><p>Copyright 2020-2021 royqh1979@gmail.com</p><p>Homepage: <a href="https://sourceforge.net/projects/dev-cpp-2020/"><span style=" text-decoration: underline; color:#007af4;">https://sourceforge.net/projects/dev-cpp-2020/</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -86,6 +86,7 @@ void OJProblemSetModel::saveToFile(const QString &fileName)
|
|||
foreach (const POJProblem& problem, mProblemSet.problems) {
|
||||
QJsonObject problemObj;
|
||||
problemObj["name"]=problem->name;
|
||||
problemObj["url"]=problem->url;
|
||||
QJsonArray cases;
|
||||
foreach (const POJProblemCase& problemCase, problem->cases) {
|
||||
QJsonObject caseObj;
|
||||
|
@ -129,6 +130,7 @@ void OJProblemSetModel::loadFromFile(const QString &fileName)
|
|||
QJsonObject problemObj = problemVal.toObject();
|
||||
POJProblem problem = std::make_shared<OJProblem>();
|
||||
problem->name = problemObj["name"].toString();
|
||||
problem->url = problemObj["url"].toString();
|
||||
QJsonArray casesArray = problemObj["cases"].toArray();
|
||||
foreach (const QJsonValue& caseVal, casesArray) {
|
||||
QJsonObject caseObj = caseVal.toObject();
|
||||
|
@ -136,7 +138,7 @@ void OJProblemSetModel::loadFromFile(const QString &fileName)
|
|||
problemCase->name = caseObj["name"].toString();
|
||||
problemCase->input = caseObj["input"].toString();
|
||||
problemCase->expected = caseObj["expected"].toString();
|
||||
problemCase->testState = ProblemCaseTestState::NoTested;
|
||||
problemCase->testState = ProblemCaseTestState::NotTested;
|
||||
problem->cases.append(problemCase);
|
||||
}
|
||||
mProblemSet.problems.append(problem);
|
||||
|
@ -272,6 +274,24 @@ void OJProblemModel::update(int row)
|
|||
emit dataChanged(index(row,0),index(row,0));
|
||||
}
|
||||
|
||||
QString OJProblemModel::getTitle()
|
||||
{
|
||||
if (!mProblem)
|
||||
return "";
|
||||
int total = mProblem->cases.count();
|
||||
int passed = 0;
|
||||
foreach (const POJProblemCase& problemCase, mProblem->cases) {
|
||||
if (problemCase->testState == ProblemCaseTestState::Passed)
|
||||
passed ++ ;
|
||||
}
|
||||
QString title = QString("%1 (%2/%3)").arg(mProblem->name)
|
||||
.arg(passed).arg(total);
|
||||
if (!mProblem->url.isEmpty()) {
|
||||
title = QString("<a href=\"%1\">%2</a>").arg(mProblem->url,title);
|
||||
}
|
||||
return title;
|
||||
}
|
||||
|
||||
int OJProblemModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
if (mProblem==nullptr)
|
||||
|
|
|
@ -19,6 +19,7 @@ public:
|
|||
void clear();
|
||||
int count();
|
||||
void update(int row);
|
||||
QString getTitle();
|
||||
|
||||
private:
|
||||
POJProblem mProblem;
|
||||
|
|
Loading…
Reference in New Issue