work save: problem set ui done
This commit is contained in:
parent
bb10a83942
commit
46b95c03ae
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -205,6 +205,18 @@ MainWindow::MainWindow(QWidget *parent)
|
||||||
ui->searchView,&QTreeView::expandAll);
|
ui->searchView,&QTreeView::expandAll);
|
||||||
ui->replacePanel->setVisible(false);
|
ui->replacePanel->setVisible(false);
|
||||||
|
|
||||||
|
mOJProblemSetNameCounter++;
|
||||||
|
mOJProblemSetModel.rename(tr("Problem Set %1").arg(mOJProblemSetNameCounter));
|
||||||
|
ui->lstProblemSet->setModel(&mOJProblemSetModel);
|
||||||
|
ui->lstProblemCases->setModel(&mOJProblemModel);
|
||||||
|
connect(ui->lstProblemSet->selectionModel(),
|
||||||
|
&QItemSelectionModel::currentRowChanged,
|
||||||
|
this, &MainWindow::onProblemSetIndexChanged);
|
||||||
|
connect(ui->lstProblemCases->selectionModel(),
|
||||||
|
&QItemSelectionModel::currentRowChanged,
|
||||||
|
this, &MainWindow::onProblemCaseIndexChanged);
|
||||||
|
ui->tabProblem->setVisible(false);
|
||||||
|
|
||||||
//files view
|
//files view
|
||||||
ui->treeFiles->setModel(&mFileSystemModel);
|
ui->treeFiles->setModel(&mFileSystemModel);
|
||||||
mFileSystemModel.setReadOnly(true);
|
mFileSystemModel.setReadOnly(true);
|
||||||
|
@ -2503,6 +2515,63 @@ void MainWindow::onFilesViewContextMenu(const QPoint &pos)
|
||||||
menu.exec(ui->treeFiles->mapToGlobal(pos));
|
menu.exec(ui->treeFiles->mapToGlobal(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::onProblemSetIndexChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||||
|
{
|
||||||
|
QModelIndex idx = current;
|
||||||
|
// if (previous.isValid()) {
|
||||||
|
// QModelIndex caseIdx = ui->lstProblemCases->currentIndex();
|
||||||
|
// if (caseIdx.isValid()) {
|
||||||
|
// POJProblemCase problemCase = mOJProblemModel.getCase(caseIdx.row());
|
||||||
|
// problemCase->input = ui->txtProblemCaseInput->toPlainText();
|
||||||
|
// problemCase->expected = ui->txtProblemCaseExpected->toPlainText();
|
||||||
|
// problemCase->output = ui->txtProblemCaseOutput->toPlainText();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (!idx.isValid()) {
|
||||||
|
ui->btnRemoveProblem->setEnabled(false);
|
||||||
|
ui->tabProblem->setVisible(false);
|
||||||
|
} else {
|
||||||
|
ui->btnRemoveProblem->setEnabled(true);
|
||||||
|
POJProblem problem = mOJProblemSetModel.problem(idx.row());
|
||||||
|
mOJProblemModel.setProblem(problem);
|
||||||
|
ui->lblProblem->setText(problem->name);
|
||||||
|
ui->tabProblem->setVisible(true);
|
||||||
|
openCloseBottomPanel(true);
|
||||||
|
ui->tabMessages->setCurrentWidget(ui->tabProblem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::onProblemCaseIndexChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||||
|
{
|
||||||
|
QModelIndex idx = current;
|
||||||
|
if (previous.isValid()) {
|
||||||
|
POJProblemCase problemCase = mOJProblemModel.getCase(previous.row());
|
||||||
|
problemCase->input = ui->txtProblemCaseInput->toPlainText();
|
||||||
|
problemCase->expected = ui->txtProblemCaseExpected->toPlainText();
|
||||||
|
problemCase->output = ui->txtProblemCaseOutput->toPlainText();
|
||||||
|
}
|
||||||
|
if (idx.isValid()) {
|
||||||
|
POJProblemCase problemCase = mOJProblemModel.getCase(idx.row());
|
||||||
|
if (problemCase) {
|
||||||
|
ui->btnRemoveProblemCase->setEnabled(true);
|
||||||
|
ui->txtProblemCaseInput->setText(problemCase->input);
|
||||||
|
ui->txtProblemCaseInput->setReadOnly(false);
|
||||||
|
ui->txtProblemCaseExpected->setText(problemCase->expected);
|
||||||
|
ui->txtProblemCaseExpected->setReadOnly(false);
|
||||||
|
ui->txtProblemCaseOutput->setText(problemCase->output);
|
||||||
|
ui->txtProblemCaseOutput->setReadOnly(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ui->btnRemoveProblemCase->setEnabled(false);
|
||||||
|
ui->txtProblemCaseInput->clear();
|
||||||
|
ui->txtProblemCaseInput->setReadOnly(true);
|
||||||
|
ui->txtProblemCaseExpected->clear();
|
||||||
|
ui->txtProblemCaseExpected->setReadOnly(true);
|
||||||
|
ui->txtProblemCaseOutput->clear();
|
||||||
|
ui->txtProblemCaseOutput->setReadOnly(true);
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::onShowInsertCodeSnippetMenu()
|
void MainWindow::onShowInsertCodeSnippetMenu()
|
||||||
{
|
{
|
||||||
mMenuInsertCodeSnippet->clear();
|
mMenuInsertCodeSnippet->clear();
|
||||||
|
@ -4819,3 +4888,88 @@ void MainWindow::on_actionRun_Parameters_triggered()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_btnNewProblemSet_clicked()
|
||||||
|
{
|
||||||
|
mOJProblemSetNameCounter++;
|
||||||
|
mOJProblemSetModel.create(tr("Problem Set %1").arg(mOJProblemSetNameCounter));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_btnAddProblem_clicked()
|
||||||
|
{
|
||||||
|
int startCount = mOJProblemSetModel.count();
|
||||||
|
QString name;
|
||||||
|
while (true) {
|
||||||
|
name = tr("Problem %1").arg(startCount);
|
||||||
|
if (!mOJProblemSetModel.problemNameUsed(name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
POJProblem problem = std::make_shared<OJProblem>();
|
||||||
|
problem->name = name;
|
||||||
|
mOJProblemSetModel.addProblem(problem);
|
||||||
|
ui->lstProblemSet->setCurrentIndex(mOJProblemSetModel.index(mOJProblemSetModel.count()-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_btnRemoveProblem_clicked()
|
||||||
|
{
|
||||||
|
QModelIndex idx = ui->lstProblemSet->currentIndex();
|
||||||
|
if (!idx.isValid())
|
||||||
|
return;
|
||||||
|
mOJProblemSetModel.removeProblem(idx.row());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_btnSaveProblemSet_clicked()
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(
|
||||||
|
this,
|
||||||
|
tr("Save Problem Set"),
|
||||||
|
QDir().absolutePath(),
|
||||||
|
tr("Problem Set Files (*.pbs)"));
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
try {
|
||||||
|
mOJProblemSetModel.saveToFile(fileName);
|
||||||
|
} catch (FileError& error) {
|
||||||
|
QMessageBox::critical(this,tr("Save Error"),
|
||||||
|
error.reason());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_btnLoadProblemSet_clicked()
|
||||||
|
{
|
||||||
|
QString fileName = QFileDialog::getOpenFileName(
|
||||||
|
this,
|
||||||
|
tr("Load Problem Set"),
|
||||||
|
QDir().absolutePath(),
|
||||||
|
tr("Problem Set Files (*.pbs)"));
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
try {
|
||||||
|
mOJProblemSetModel.loadFromFile(fileName);
|
||||||
|
} catch (FileError& error) {
|
||||||
|
QMessageBox::critical(this,tr("Load Error"),
|
||||||
|
error.reason());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_btnAddProblemCase_clicked()
|
||||||
|
{
|
||||||
|
int startCount = mOJProblemModel.count();
|
||||||
|
QString name;
|
||||||
|
while (true) {
|
||||||
|
name = tr("Problem Case %1").arg(startCount);
|
||||||
|
if (!mOJProblemSetModel.problemNameUsed(name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
POJProblemCase problemCase = std::make_shared<OJProblemCase>();
|
||||||
|
problemCase->name = name;
|
||||||
|
problemCase->testState = ProblemCaseTestState::NoTested;
|
||||||
|
mOJProblemModel.addCase(problemCase);
|
||||||
|
ui->lstProblemCases->setCurrentIndex(mOJProblemModel.index(mOJProblemModel.count()-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "toolsmanager.h"
|
#include "toolsmanager.h"
|
||||||
#include "widgets/labelwithmenu.h"
|
#include "widgets/labelwithmenu.h"
|
||||||
#include "widgets/bookmarkmodel.h"
|
#include "widgets/bookmarkmodel.h"
|
||||||
|
#include "widgets/ojproblemsetmodel.h"
|
||||||
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
@ -211,6 +212,8 @@ private slots:
|
||||||
void onDebugConsoleContextMenu(const QPoint& pos);
|
void onDebugConsoleContextMenu(const QPoint& pos);
|
||||||
void onFileEncodingContextMenu(const QPoint& pos);
|
void onFileEncodingContextMenu(const QPoint& pos);
|
||||||
void onFilesViewContextMenu(const QPoint& pos);
|
void onFilesViewContextMenu(const QPoint& pos);
|
||||||
|
void onProblemSetIndexChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||||
|
void onProblemCaseIndexChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||||
|
|
||||||
void onShowInsertCodeSnippetMenu();
|
void onShowInsertCodeSnippetMenu();
|
||||||
|
|
||||||
|
@ -433,6 +436,18 @@ private slots:
|
||||||
|
|
||||||
void on_actionRun_Parameters_triggered();
|
void on_actionRun_Parameters_triggered();
|
||||||
|
|
||||||
|
void on_btnNewProblemSet_clicked();
|
||||||
|
|
||||||
|
void on_btnAddProblem_clicked();
|
||||||
|
|
||||||
|
void on_btnRemoveProblem_clicked();
|
||||||
|
|
||||||
|
void on_btnSaveProblemSet_clicked();
|
||||||
|
|
||||||
|
void on_btnLoadProblemSet_clicked();
|
||||||
|
|
||||||
|
void on_btnAddProblemCase_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
EditorList *mEditorList;
|
EditorList *mEditorList;
|
||||||
|
@ -473,6 +488,9 @@ private:
|
||||||
PTodoParser mTodoParser;
|
PTodoParser mTodoParser;
|
||||||
PToolsManager mToolsManager;
|
PToolsManager mToolsManager;
|
||||||
QFileSystemModel mFileSystemModel;
|
QFileSystemModel mFileSystemModel;
|
||||||
|
OJProblemSetModel mOJProblemSetModel;
|
||||||
|
OJProblemModel mOJProblemModel;
|
||||||
|
int mOJProblemSetNameCounter;
|
||||||
|
|
||||||
bool mCheckSyntaxInBack;
|
bool mCheckSyntaxInBack;
|
||||||
bool mOpenClosingBottomPanel;
|
bool mOpenClosingBottomPanel;
|
||||||
|
|
|
@ -306,8 +306,11 @@
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnNewProblemSet">
|
<widget class="QToolButton" name="btnNewProblemSet">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>New Problem Set</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>New Problem Set</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="icons.qrc">
|
<iconset resource="icons.qrc">
|
||||||
|
@ -317,8 +320,11 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnAddProblem">
|
<widget class="QToolButton" name="btnAddProblem">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Add Problem</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>Add Problem</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="icons.qrc">
|
<iconset resource="icons.qrc">
|
||||||
|
@ -328,8 +334,11 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnRemoveProblem">
|
<widget class="QToolButton" name="btnRemoveProblem">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Remove Problem</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>Remove Problem</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="icons.qrc">
|
<iconset resource="icons.qrc">
|
||||||
|
@ -339,8 +348,11 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnSaveProblemSet">
|
<widget class="QToolButton" name="btnSaveProblemSet">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Save Problem Set</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>Save Problem Set</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="icons.qrc">
|
<iconset resource="icons.qrc">
|
||||||
|
@ -350,8 +362,11 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnLoadProblemSet">
|
<widget class="QToolButton" name="btnLoadProblemSet">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Load Problem Set</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>Load Problem Set</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="icons.qrc">
|
<iconset resource="icons.qrc">
|
||||||
|
@ -1099,7 +1114,7 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="lblProblem">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Problem</string>
|
<string>Problem</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -1146,8 +1161,11 @@
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnAddProblemCase">
|
<widget class="QToolButton" name="btnAddProblemCase">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Add Probem Case</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>Add Probem Case</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="icons.qrc">
|
<iconset resource="icons.qrc">
|
||||||
|
@ -1157,8 +1175,11 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="btnRemoveProblemCase">
|
<widget class="QToolButton" name="btnRemoveProblemCase">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Remove Problem Case</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>...</string>
|
<string>Remove Problem Case</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="icons.qrc">
|
<iconset resource="icons.qrc">
|
||||||
|
@ -1166,6 +1187,41 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="btnRunCurrentProblemCase">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Run Current Case</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Run Current Case</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="icons.qrc">
|
||||||
|
<normaloff>:/icons/images/newlook24/069-run.png</normaloff>:/icons/images/newlook24/069-run.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="btnRunAllProblemCases">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Run All Cases</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Run All Cases</string>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="icons.qrc">
|
||||||
|
<normaloff>:/icons/images/newlook24/021-Debug-Continue.png</normaloff>:/icons/images/newlook24/021-Debug-Continue.png</iconset>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_4">
|
<spacer name="horizontalSpacer_4">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
|
@ -1,26 +1,240 @@
|
||||||
#include "ojproblemsetmodel.h"
|
#include "ojproblemsetmodel.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include "../utils.h"
|
||||||
|
|
||||||
OJProblemSetModel::OJProblemSetModel(QObject *parent) : QAbstractListModel(parent)
|
OJProblemSetModel::OJProblemSetModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OJProblemCaseModel::OJProblemCaseModel(QObject *parent): QAbstractListModel(parent)
|
void OJProblemSetModel::clear()
|
||||||
|
{
|
||||||
|
beginRemoveRows(QModelIndex(),0,mProblemSet.problems.count()-1);
|
||||||
|
mProblemSet.problems.clear();
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
int OJProblemSetModel::count()
|
||||||
|
{
|
||||||
|
return mProblemSet.problems.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemSetModel::create(const QString& name)
|
||||||
|
{
|
||||||
|
mProblemSet.name = name;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemSetModel::rename(const QString &newName)
|
||||||
|
{
|
||||||
|
if (mProblemSet.name!=newName)
|
||||||
|
mProblemSet.name = newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString OJProblemSetModel::name()
|
||||||
|
{
|
||||||
|
return mProblemSet.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemSetModel::addProblem(POJProblem problem)
|
||||||
|
{
|
||||||
|
beginInsertRows(QModelIndex(), mProblemSet.problems.count(), mProblemSet.problems.count());
|
||||||
|
mProblemSet.problems.append(problem);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
POJProblem OJProblemSetModel::problem(int index)
|
||||||
|
{
|
||||||
|
return mProblemSet.problems[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemSetModel::removeProblem(int index)
|
||||||
|
{
|
||||||
|
Q_ASSERT(index>=0 && index < mProblemSet.problems.count());
|
||||||
|
mProblemSet.problems.removeAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OJProblemSetModel::problemNameUsed(const QString &name)
|
||||||
|
{
|
||||||
|
foreach (const POJProblem& problem, mProblemSet.problems) {
|
||||||
|
if (name == problem->name)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemSetModel::removeAllProblems()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemSetModel::saveToFile(const QString &fileName)
|
||||||
|
{
|
||||||
|
QFile file(fileName);
|
||||||
|
if (file.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||||
|
QJsonObject obj;
|
||||||
|
obj["name"]=mProblemSet.name;
|
||||||
|
QJsonArray problemsArray;
|
||||||
|
foreach (const POJProblem& problem, mProblemSet.problems) {
|
||||||
|
QJsonObject problemObj;
|
||||||
|
problemObj["name"]=problem->name;
|
||||||
|
QJsonArray cases;
|
||||||
|
foreach (const POJProblemCase& problemCase, problem->cases) {
|
||||||
|
QJsonObject caseObj;
|
||||||
|
caseObj["name"]=problemCase->name;
|
||||||
|
caseObj["input"]=problemCase->input;
|
||||||
|
caseObj["expected"]=problemCase->expected;
|
||||||
|
cases.append(caseObj);
|
||||||
|
}
|
||||||
|
problemObj["cases"]=cases;
|
||||||
|
problemsArray.append(problemObj);
|
||||||
|
}
|
||||||
|
obj["problems"]=problemsArray;
|
||||||
|
QJsonDocument doc;
|
||||||
|
doc.setObject(obj);
|
||||||
|
file.write(doc.toJson());
|
||||||
|
file.close();
|
||||||
|
} else {
|
||||||
|
throw FileError(QObject::tr("Can't open file '%1' for read.")
|
||||||
|
.arg(fileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemSetModel::loadFromFile(const QString &fileName)
|
||||||
|
{
|
||||||
|
QFile file(fileName);
|
||||||
|
if (file.open(QFile::ReadOnly)) {
|
||||||
|
QByteArray content = file.readAll();
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument doc(QJsonDocument::fromJson(content,&error));
|
||||||
|
if (error.error!=QJsonParseError::NoError) {
|
||||||
|
throw FileError(QObject::tr("Can't parse problem set file '%1':%2")
|
||||||
|
.arg(fileName)
|
||||||
|
.arg(error.errorString()));
|
||||||
|
}
|
||||||
|
beginResetModel();
|
||||||
|
QJsonObject obj = doc.object();
|
||||||
|
mProblemSet.name = obj["name"].toString();
|
||||||
|
mProblemSet.problems.clear();
|
||||||
|
QJsonArray problemsArray = obj["problems"].toArray();
|
||||||
|
foreach (const QJsonValue& problemVal, problemsArray) {
|
||||||
|
QJsonObject problemObj = problemVal.toObject();
|
||||||
|
POJProblem problem = std::make_shared<OJProblem>();
|
||||||
|
problem->name = problemObj["name"].toString();
|
||||||
|
QJsonArray casesArray = problemObj["cases"].toArray();
|
||||||
|
foreach (const QJsonValue& caseVal, casesArray) {
|
||||||
|
QJsonObject caseObj = caseVal.toObject();
|
||||||
|
POJProblemCase problemCase = std::make_shared<OJProblemCase>();
|
||||||
|
problemCase->name = caseObj["name"].toString();
|
||||||
|
problemCase->input = caseObj["input"].toString();
|
||||||
|
problemCase->expected = caseObj["expected"].toString();
|
||||||
|
problemCase->testState = ProblemCaseTestState::NoTested;
|
||||||
|
problem->cases.append(problemCase);
|
||||||
|
}
|
||||||
|
mProblemSet.problems.append(problem);
|
||||||
|
}
|
||||||
|
endResetModel();
|
||||||
|
} else {
|
||||||
|
throw FileError(QObject::tr("Can't open file '%1' for read.")
|
||||||
|
.arg(fileName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int OJProblemSetModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return mProblemSet.problems.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant OJProblemSetModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
return mProblemSet.problems[index.row()]->name;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
OJProblemModel::OJProblemModel(QObject *parent): QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const POJProbelm &OJProblemCaseModel::problem() const
|
const POJProblem &OJProblemModel::problem() const
|
||||||
{
|
{
|
||||||
return mProblem;
|
return mProblem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OJProblemCaseModel::setProblem(const POJProbelm &newProblem)
|
void OJProblemModel::setProblem(const POJProblem &newProblem)
|
||||||
{
|
{
|
||||||
mProblem = newProblem;
|
if (newProblem!=mProblem) {
|
||||||
|
beginResetModel();
|
||||||
|
mProblem = newProblem;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int OJProblemCaseModel::rowCount(const QModelIndex &parent) const
|
void OJProblemModel::addCase(POJProblemCase problemCase)
|
||||||
{
|
{
|
||||||
|
if (mProblem==nullptr)
|
||||||
|
return;
|
||||||
|
beginInsertRows(QModelIndex(),mProblem->cases.count(),mProblem->cases.count());
|
||||||
|
mProblem->cases.append(problemCase);
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemModel::removeCase(int index)
|
||||||
|
{
|
||||||
|
if (mProblem==nullptr)
|
||||||
|
return;
|
||||||
|
Q_ASSERT(index >= 0 && index < mProblem->cases.count());
|
||||||
|
beginRemoveRows(QModelIndex(),index,index);
|
||||||
|
mProblem->cases.removeAt(index);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
POJProblemCase OJProblemModel::getCase(int index)
|
||||||
|
{
|
||||||
|
if (mProblem==nullptr)
|
||||||
|
return POJProblemCase();
|
||||||
|
return mProblem->cases[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void OJProblemModel::clear()
|
||||||
|
{
|
||||||
|
if (mProblem==nullptr)
|
||||||
|
return;
|
||||||
|
beginRemoveRows(QModelIndex(),0,mProblem->cases.count()-1);
|
||||||
|
mProblem->cases.clear();
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
int OJProblemModel::count()
|
||||||
|
{
|
||||||
|
if (mProblem == nullptr)
|
||||||
|
return 0;
|
||||||
|
return mProblem->cases.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int OJProblemModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
if (mProblem==nullptr)
|
||||||
|
return 0;
|
||||||
|
return mProblem->cases.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant OJProblemModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
if (mProblem==nullptr)
|
||||||
|
return QVariant();
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
return mProblem->cases[index.row()]->name;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,9 @@ struct OJProblemCase {
|
||||||
QString name;
|
QString name;
|
||||||
QString input;
|
QString input;
|
||||||
QString expected;
|
QString expected;
|
||||||
ProblemCaseTestState testState;
|
|
||||||
|
QString output; // no persistence
|
||||||
|
ProblemCaseTestState testState; // no persistence
|
||||||
};
|
};
|
||||||
|
|
||||||
using POJProblemCase = std::shared_ptr<OJProblemCase>;
|
using POJProblemCase = std::shared_ptr<OJProblemCase>;
|
||||||
|
@ -24,17 +26,27 @@ struct OJProblem {
|
||||||
QVector<POJProblemCase> cases;
|
QVector<POJProblemCase> cases;
|
||||||
};
|
};
|
||||||
|
|
||||||
using POJProbelm = std::shared_ptr<OJProblem>;
|
using POJProblem = std::shared_ptr<OJProblem>;
|
||||||
|
|
||||||
class OJProblemCaseModel: public QAbstractListModel {
|
struct OJProblemSet {
|
||||||
|
QString name;
|
||||||
|
QVector<POJProblem> problems;
|
||||||
|
};
|
||||||
|
|
||||||
|
class OJProblemModel: public QAbstractListModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit OJProblemCaseModel(QObject *parent = nullptr);
|
explicit OJProblemModel(QObject *parent = nullptr);
|
||||||
const POJProbelm &problem() const;
|
const POJProblem &problem() const;
|
||||||
void setProblem(const POJProbelm &newProblem);
|
void setProblem(const POJProblem &newProblem);
|
||||||
|
void addCase(POJProblemCase problemCase);
|
||||||
|
void removeCase(int index);
|
||||||
|
POJProblemCase getCase(int index);
|
||||||
|
void clear();
|
||||||
|
int count();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
POJProbelm mProblem;
|
POJProblem mProblem;
|
||||||
|
|
||||||
// QAbstractItemModel interface
|
// QAbstractItemModel interface
|
||||||
public:
|
public:
|
||||||
|
@ -47,6 +59,25 @@ class OJProblemSetModel : public QAbstractListModel
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit OJProblemSetModel(QObject *parent = nullptr);
|
explicit OJProblemSetModel(QObject *parent = nullptr);
|
||||||
|
void clear();
|
||||||
|
int count();
|
||||||
|
void create(const QString& name);
|
||||||
|
void rename(const QString& newName);
|
||||||
|
QString name();
|
||||||
|
void addProblem(POJProblem problem);
|
||||||
|
POJProblem problem(int index);
|
||||||
|
void removeProblem(int index);
|
||||||
|
bool problemNameUsed(const QString& name);
|
||||||
|
void removeAllProblems();
|
||||||
|
void saveToFile(const QString& fileName);
|
||||||
|
void loadFromFile(const QString& fileName);
|
||||||
|
private:
|
||||||
|
OJProblemSet mProblemSet;
|
||||||
|
|
||||||
|
// QAbstractItemModel interface
|
||||||
|
public:
|
||||||
|
int rowCount(const QModelIndex &parent) const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // OJPROBLEMSETMODEL_H
|
#endif // OJPROBLEMSETMODEL_H
|
||||||
|
|
Loading…
Reference in New Issue