Add validation to the new project wizard
This commit is contained in:
parent
681eb55db3
commit
9730ef773e
@ -9,17 +9,21 @@ add_library(
|
|||||||
NostalgiaStudio
|
NostalgiaStudio
|
||||||
SHARED
|
SHARED
|
||||||
newwizard.cpp
|
newwizard.cpp
|
||||||
|
project.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
NostalgiaStudio
|
NostalgiaStudio
|
||||||
Qt5::Core
|
Qt5::Core
|
||||||
Qt5::Widgets
|
Qt5::Widgets
|
||||||
|
${OxFS_LIBRARY}
|
||||||
|
${OxStd_LIBRARY}
|
||||||
)
|
)
|
||||||
|
|
||||||
install(
|
install(
|
||||||
FILES
|
FILES
|
||||||
newwizard.hpp
|
newwizard.hpp
|
||||||
|
project.hpp
|
||||||
DESTINATION
|
DESTINATION
|
||||||
include/nostalgia/studio/lib
|
include/nostalgia/studio/lib
|
||||||
)
|
)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <QFileDialog>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
@ -18,16 +18,22 @@
|
|||||||
namespace nostalgia {
|
namespace nostalgia {
|
||||||
namespace studio {
|
namespace studio {
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
WizardSelect::WizardSelect() {
|
WizardSelect::WizardSelect() {
|
||||||
m_listWidget = new QListWidget(this);
|
m_listWidget = new QListWidget(this);
|
||||||
auto layout = new QVBoxLayout(this);
|
auto layout = new QVBoxLayout(this);
|
||||||
layout->addWidget(m_listWidget);
|
layout->addWidget(m_listWidget);
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
connect(m_listWidget, &QListWidget::activated, this, &WizardSelect::itemSelected);
|
connect(m_listWidget, &QListWidget::currentRowChanged, this, &WizardSelect::itemSelected);
|
||||||
connect(m_listWidget, &QListWidget::clicked, this, &WizardSelect::itemSelected);
|
connect(m_listWidget, &QListWidget::itemSelectionChanged, [this]() {
|
||||||
|
m_complete = true;
|
||||||
|
emit completeChanged();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
connect(m_listWidget, &QListWidget::doubleClicked, [this]() {
|
||||||
|
wizard()->next();
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WizardSelect::initializePage() {
|
void WizardSelect::initializePage() {
|
||||||
@ -44,80 +50,174 @@ bool WizardSelect::isComplete() const {
|
|||||||
return m_complete;
|
return m_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WizardSelect::isFinalPage() const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int WizardSelect::nextId() const {
|
int WizardSelect::nextId() const {
|
||||||
return m_nextId;
|
return m_nextId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WizardSelect::itemSelected(const QModelIndex &idx) {
|
void WizardSelect::itemSelected(int row) {
|
||||||
m_complete = true;
|
if (row > -1) {
|
||||||
auto w = wizard();
|
auto w = wizard();
|
||||||
|
|
||||||
if (nextId() > -1) {
|
if (nextId() > -1) {
|
||||||
w->removePage(nextId());
|
w->removePage(nextId());
|
||||||
m_nextId = -1;
|
m_nextId = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto selected = m_listWidget->currentItem()->text();
|
auto selected = m_listWidget->currentItem()->text();
|
||||||
if (m_options.contains(selected)) {
|
if (m_options.contains(selected)) {
|
||||||
m_nextId = w->addPage(m_options[selected]());
|
m_nextId = w->addPage(m_options[selected]());
|
||||||
// for some reason the continue button only appears correctly after remove runs
|
// for some reason the continue button only appears correctly after remove runs
|
||||||
w->removePage(nextId());
|
w->removePage(nextId());
|
||||||
m_nextId = w->addPage(m_options[selected]());
|
m_nextId = w->addPage(m_options[selected]());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WizardFormPage::WizardFormPage() {
|
||||||
Wizard::FormPage::FormPage() {
|
|
||||||
m_layout = new QGridLayout(this);
|
m_layout = new QGridLayout(this);
|
||||||
m_layout->setColumnMinimumWidth(0, 20);
|
m_layout->setColumnMinimumWidth(0, 20);
|
||||||
this->setLayout(m_layout);
|
this->setLayout(m_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
Wizard::FormPage::~FormPage() {
|
WizardFormPage::~WizardFormPage() {
|
||||||
for (auto l : m_subLayout) {
|
for (auto l : m_subLayout) {
|
||||||
delete l;
|
delete l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wizard::FormPage::addLineEdit(QString displayName, QString fieldName) {
|
void WizardFormPage::initializePage() {
|
||||||
|
for (auto it = m_fields.begin(); it != m_fields.end(); it++) {
|
||||||
|
auto key = it.key();
|
||||||
|
auto le = m_fields[key].lineEdit;
|
||||||
|
auto defaultVal = it.value().defaultValue;
|
||||||
|
if (le) {
|
||||||
|
le->setText(defaultVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WizardFormPage::validatePage() {
|
||||||
|
bool retval = true;
|
||||||
|
|
||||||
|
// check validators
|
||||||
|
for (auto f : m_fields) {
|
||||||
|
if (f.validator != nullptr) {
|
||||||
|
if (f.validator(f.lineEdit->text()) != 0) {
|
||||||
|
retval = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear error
|
||||||
|
if (retval) {
|
||||||
|
showValidationError("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WizardFormPage::addLineEdit(QString displayName, QString fieldName, QString defaultVal) {
|
||||||
auto lbl = new QLabel(displayName, this);
|
auto lbl = new QLabel(displayName, this);
|
||||||
auto le = new QLineEdit(this);
|
auto le = new QLineEdit(this);
|
||||||
lbl->setBuddy(le);
|
lbl->setBuddy(le);
|
||||||
|
|
||||||
m_layout->addWidget(lbl, currentLine, 0);
|
m_layout->addWidget(lbl, m_currentLine, 0);
|
||||||
m_layout->addWidget(le, currentLine, 1);
|
m_layout->addWidget(le, m_currentLine, 1);
|
||||||
|
|
||||||
|
m_fields[fieldName].defaultValue = defaultVal;
|
||||||
|
m_fields[fieldName].lineEdit = le;
|
||||||
|
|
||||||
registerField(fieldName, le);
|
registerField(fieldName, le);
|
||||||
|
|
||||||
currentLine++;
|
connect(le, &QLineEdit::textChanged, [this, fieldName, le](QString txt) {
|
||||||
|
if (m_fields[fieldName].value == "" && txt != "") {
|
||||||
|
m_validFields++;
|
||||||
|
} else if (m_fields[fieldName].value != "" && txt == "") {
|
||||||
|
m_validFields--;
|
||||||
|
}
|
||||||
|
m_fields[fieldName].value = txt;
|
||||||
|
emit completeChanged();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
m_currentLine++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wizard::FormPage::addFileBrowse(QString displayName, QString fieldName, QString defaultVal) {
|
void WizardFormPage::addDirBrowse(QString displayName, QString fieldName, QString defaultVal) {
|
||||||
auto layout = new QHBoxLayout();
|
auto layout = new QHBoxLayout();
|
||||||
auto lbl = new QLabel(displayName, this);
|
auto lbl = new QLabel(displayName, this);
|
||||||
auto le = new QLineEdit(this);
|
auto le = new QLineEdit("", this);
|
||||||
auto btn = new QPushButton("Browse...", this);
|
auto btn = new QPushButton("Browse...", this);
|
||||||
lbl->setBuddy(le);
|
lbl->setBuddy(le);
|
||||||
|
|
||||||
layout->addWidget(le);
|
layout->addWidget(le);
|
||||||
layout->addWidget(btn);
|
layout->addWidget(btn);
|
||||||
m_layout->addWidget(lbl, currentLine, 0);
|
m_layout->addWidget(lbl, m_currentLine, 0);
|
||||||
m_layout->addLayout(layout, currentLine, 1);
|
m_layout->addLayout(layout, m_currentLine, 1);
|
||||||
|
|
||||||
m_subLayout.push_back(layout);
|
m_subLayout.push_back(layout);
|
||||||
|
m_fields[fieldName].defaultValue = defaultVal;
|
||||||
|
m_fields[fieldName].lineEdit = le;
|
||||||
|
m_fields[fieldName].validator = [this](QString path) {
|
||||||
|
if (!QDir(path).exists()) {
|
||||||
|
showValidationError(tr("Specified Project Path directory does not exist."));
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
registerField(fieldName, le);
|
registerField(fieldName, le);
|
||||||
|
|
||||||
currentLine++;
|
connect(le, &QLineEdit::textChanged, [this, fieldName, le](QString txt) {
|
||||||
|
if (m_fields[fieldName].value == "" && txt != "") {
|
||||||
|
m_validFields++;
|
||||||
|
} else if (m_fields[fieldName].value != "" && txt == "") {
|
||||||
|
m_validFields--;
|
||||||
|
}
|
||||||
|
m_fields[fieldName].value = txt;
|
||||||
|
emit completeChanged();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
connect(btn, &QPushButton::clicked, [this, defaultVal, le]() {
|
||||||
|
auto p = QFileDialog::getExistingDirectory(this, tr("Select Directory..."), defaultVal);
|
||||||
|
if (p != "") {
|
||||||
|
le->setText(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
m_currentLine++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WizardFormPage::showValidationError(QString msg) {
|
||||||
|
// create label if it is null
|
||||||
|
if (!m_errorMsg) {
|
||||||
|
m_errorMsg = new QLabel(this);
|
||||||
|
m_layout->addWidget(m_errorMsg, m_currentLine, 0, m_currentLine, 2);
|
||||||
|
|
||||||
|
// set text color
|
||||||
|
auto pal = m_errorMsg->palette();
|
||||||
|
pal.setColor(m_errorMsg->backgroundRole(), Qt::red);
|
||||||
|
pal.setColor(m_errorMsg->foregroundRole(), Qt::red);
|
||||||
|
m_errorMsg->setPalette(pal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set message
|
||||||
|
if (msg != "") {
|
||||||
|
m_errorMsg->setText(tr("Error: ") + msg);
|
||||||
|
} else {
|
||||||
|
m_errorMsg->setText("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Wizard::Wizard(QWidget *parent): QWizard(parent) {
|
Wizard::Wizard(QWidget *parent): QWizard(parent) {
|
||||||
setWindowTitle(tr("New..."));
|
setWindowTitle(tr("New..."));
|
||||||
|
setModal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <QDir>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
|
#include <QLabel>
|
||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
@ -30,41 +32,54 @@ class WizardSelect: public QWizardPage {
|
|||||||
public:
|
public:
|
||||||
WizardSelect();
|
WizardSelect();
|
||||||
|
|
||||||
void initializePage();
|
|
||||||
|
|
||||||
void addOption(QString name, std::function<QWizardPage*()> makePage);
|
void addOption(QString name, std::function<QWizardPage*()> makePage);
|
||||||
|
|
||||||
bool isComplete() const;
|
void initializePage() override;
|
||||||
|
|
||||||
bool isFinalPage() const;
|
bool isComplete() const override;
|
||||||
|
|
||||||
int nextId() const;
|
int nextId() const override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void itemSelected(const QModelIndex &idx);
|
void itemSelected(int row);
|
||||||
|
};
|
||||||
|
|
||||||
|
class WizardFormPage: public QWizardPage {
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
struct Field {
|
||||||
|
QString defaultValue = "";
|
||||||
|
QString value = "";
|
||||||
|
QLineEdit *lineEdit = nullptr;
|
||||||
|
std::function<int(QString)> validator;
|
||||||
|
};
|
||||||
|
QLabel *m_errorMsg = nullptr;
|
||||||
|
QGridLayout *m_layout = nullptr;
|
||||||
|
QVector<QLayout*> m_subLayout;
|
||||||
|
QMap<QString, Field> m_fields;
|
||||||
|
int m_currentLine = 0;
|
||||||
|
int m_validFields = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
WizardFormPage();
|
||||||
|
|
||||||
|
~WizardFormPage();
|
||||||
|
|
||||||
|
void initializePage() override;
|
||||||
|
|
||||||
|
bool validatePage() override;
|
||||||
|
|
||||||
|
void addLineEdit(QString displayName, QString fieldName, QString defaultVal = "");
|
||||||
|
|
||||||
|
void addDirBrowse(QString displayName, QString fieldName, QString defaultVal = QDir::homePath());
|
||||||
|
|
||||||
|
void showValidationError(QString msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Wizard: public QWizard {
|
class Wizard: public QWizard {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
|
||||||
class FormPage: public QWizardPage {
|
|
||||||
private:
|
|
||||||
QGridLayout *m_layout = nullptr;
|
|
||||||
QVector<QLayout*> m_subLayout;
|
|
||||||
int currentLine = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
FormPage();
|
|
||||||
|
|
||||||
~FormPage();
|
|
||||||
|
|
||||||
void addLineEdit(QString displayName, QString fieldName);
|
|
||||||
|
|
||||||
void addFileBrowse(QString displayName, QString fieldName, QString defaultVal = "");
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Wizard(QWidget *parent = 0);
|
Wizard(QWidget *parent = 0);
|
||||||
};
|
};
|
||||||
|
33
src/studio/lib/project.cpp
Normal file
33
src/studio/lib/project.cpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016-2017 gtalent2@gmail.com
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QDir>
|
||||||
|
#include <ox/fs/filesystem.hpp>
|
||||||
|
#include <project.hpp>
|
||||||
|
|
||||||
|
namespace nostalgia {
|
||||||
|
namespace studio {
|
||||||
|
|
||||||
|
using namespace ox::fs;
|
||||||
|
|
||||||
|
void Project::create(QString path) {
|
||||||
|
QDir().mkpath(path);
|
||||||
|
|
||||||
|
size_t buffLen = 1024;
|
||||||
|
m_romBuff = new QByteArray(buffLen, 0);
|
||||||
|
FileSystem32::format(m_romBuff->data(), buffLen, true);
|
||||||
|
|
||||||
|
QFile file(path + "/ROM.oxfs");
|
||||||
|
file.open(QIODevice::WriteOnly);
|
||||||
|
file.write(*m_romBuff);
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
25
src/studio/lib/project.hpp
Normal file
25
src/studio/lib/project.hpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016-2017 gtalent2@gmail.com
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace nostalgia {
|
||||||
|
namespace studio {
|
||||||
|
|
||||||
|
class Project: public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
QByteArray *m_romBuff = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void create(QString path);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,6 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
@ -20,8 +19,6 @@
|
|||||||
namespace nostalgia {
|
namespace nostalgia {
|
||||||
namespace studio {
|
namespace studio {
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
MainWindow::MainWindow(NostalgiaStudioProfile config, QWidget *parent) {
|
MainWindow::MainWindow(NostalgiaStudioProfile config, QWidget *parent) {
|
||||||
auto screenSize = QApplication::desktop()->screenGeometry();
|
auto screenSize = QApplication::desktop()->screenGeometry();
|
||||||
|
|
||||||
@ -93,9 +90,9 @@ void MainWindow::showNewWizard() {
|
|||||||
auto ws = new WizardSelect();
|
auto ws = new WizardSelect();
|
||||||
wizard.addPage(ws);
|
wizard.addPage(ws);
|
||||||
ws->addOption(tr("Project"), []() {
|
ws->addOption(tr("Project"), []() {
|
||||||
auto pg = new Wizard::FormPage();
|
auto pg = new WizardFormPage();
|
||||||
pg->addLineEdit(tr("Project &Name"), "projectName");
|
pg->addLineEdit(tr("Project &Name:"), "projectName*");
|
||||||
pg->addFileBrowse(tr("Project &Path"), "projectPath");
|
pg->addDirBrowse(tr("Project &Path:"), "projectPath*");
|
||||||
return pg;
|
return pg;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user