diff --git a/forms/newtilesetdialog.ui b/forms/newtilesetdialog.ui
index 3b898761..13996c73 100644
--- a/forms/newtilesetdialog.ui
+++ b/forms/newtilesetdialog.ui
@@ -33,14 +33,14 @@
0
-
-
+
Name
-
-
+
true
@@ -60,27 +60,13 @@
-
-
-
- Symbol Name
-
-
-
- -
-
-
-
-
-
-
- -
Type
- -
+
-
false
@@ -97,17 +83,17 @@
- -
+
-
Checkerboard Fill
- -
+
-
- -
+
-
Qt::Orientation::Vertical
diff --git a/include/core/validator.h b/include/core/validator.h
new file mode 100644
index 00000000..f5f2ef91
--- /dev/null
+++ b/include/core/validator.h
@@ -0,0 +1,66 @@
+#ifndef VALIDATOR_H
+#define VALIDATOR_H
+
+/*
+ This file contains our subclasses of QValidator.
+
+ - PrefixValidator is for input widgets that want to enforce a particular prefix.
+ It differs from a QRegularExpressionValidator with a prefix in the regex because
+ it will automatically enforce the prefix in fixup() if it isn't present.
+ It's preferable to QLineEdit's input mask because it won't affect cursor behavior.
+
+ - IdentifierValidator is for validating that input text can be used for the name of an identifier in the project.
+ (i.e., starts with a letter or underscore, then may continue with letters, numbers, or underscores).
+ Unless a prefix is specified this is a normal QRegularExpressionValidator, we only have a subclass because we use it so often.
+
+ - UppercaseValidator is just a validator that uppercases input text.
+*/
+
+#include
+
+class PrefixValidator : public QRegularExpressionValidator {
+ Q_OBJECT
+
+public:
+ explicit PrefixValidator(const QString &prefix, QObject *parent = nullptr)
+ : QRegularExpressionValidator(parent), m_prefix(prefix) {};
+ explicit PrefixValidator(const QString &prefix, const QRegularExpression &re, QObject *parent = nullptr)
+ : QRegularExpressionValidator(re, parent), m_prefix(prefix) {};
+ ~PrefixValidator() {};
+
+ virtual QValidator::State validate(QString &input, int &) const override;
+ virtual void fixup(QString &input) const override;
+
+ QString prefix() const { return m_prefix; }
+ void setPrefix(const QString &prefix);
+
+ bool isValid(QString &input) const;
+
+private:
+ QString m_prefix;
+
+ bool missingPrefix(const QString &input) const;
+};
+
+class IdentifierValidator : public PrefixValidator {
+ Q_OBJECT
+
+public:
+ explicit IdentifierValidator(QObject *parent = nullptr)
+ : PrefixValidator("", re_identifier, parent) {};
+ explicit IdentifierValidator(const QString &prefix, QObject *parent = nullptr)
+ : PrefixValidator(prefix, re_identifier, parent) {};
+ ~IdentifierValidator() {};
+
+private:
+ static const QRegularExpression re_identifier;
+};
+
+class UppercaseValidator : public QValidator {
+ virtual QValidator::State validate(QString &input, int &) const override {
+ input = input.toUpper();
+ return QValidator::Acceptable;
+ }
+};
+
+#endif // VALIDATOR_H
diff --git a/include/project.h b/include/project.h
index 9c9fdf33..fefa1f34 100644
--- a/include/project.h
+++ b/include/project.h
@@ -140,9 +140,9 @@ public:
Map *createNewMap(const Project::NewMapSettings &mapSettings, const Map* toDuplicate = nullptr);
Layout *createNewLayout(const Layout::Settings &layoutSettings, const Layout* toDuplicate = nullptr);
- Tileset *createNewTileset(const QString &friendlyName, bool secondary, bool checkerboardFill);
+ Tileset *createNewTileset(QString name, bool secondary, bool checkerboardFill);
bool isIdentifierUnique(const QString &identifier) const;
- bool isValidNewIdentifier(const QString &identifier) const;
+ bool isValidNewIdentifier(QString identifier) const;
QString toUniqueIdentifier(const QString &identifier) const;
QString getProjectTitle();
diff --git a/include/ui/aboutporymap.h b/include/ui/aboutporymap.h
index 28b06249..f960ab8c 100644
--- a/include/ui/aboutporymap.h
+++ b/include/ui/aboutporymap.h
@@ -2,7 +2,6 @@
#define ABOUTPORYMAP_H
#include
-#include
#include
namespace Ui {
diff --git a/include/ui/colorinputwidget.h b/include/ui/colorinputwidget.h
index cd871e0b..527794d9 100644
--- a/include/ui/colorinputwidget.h
+++ b/include/ui/colorinputwidget.h
@@ -2,7 +2,6 @@
#define COLORINPUTWIDGET_H
#include
-#include
namespace Ui {
class ColorInputWidget;
diff --git a/include/ui/maplistmodels.h b/include/ui/maplistmodels.h
index 920bf9ba..53a79f4d 100644
--- a/include/ui/maplistmodels.h
+++ b/include/ui/maplistmodels.h
@@ -54,9 +54,6 @@ private:
};
-
-class QRegularExpressionValidator;
-
class MapListModel : public QStandardItemModel {
Q_OBJECT
diff --git a/include/ui/newnamedialog.h b/include/ui/newnamedialog.h
index 23979fc5..4abe02df 100644
--- a/include/ui/newnamedialog.h
+++ b/include/ui/newnamedialog.h
@@ -19,11 +19,9 @@ class NewNameDialog : public QDialog
Q_OBJECT
public:
- explicit NewNameDialog(const QString &label, Project *project, QWidget *parent = nullptr);
+ explicit NewNameDialog(const QString &label, const QString &prefix = "", Project *project = nullptr, QWidget *parent = nullptr);
~NewNameDialog();
- void setNamePrefix(const QString &prefix);
-
virtual void accept() override;
signals:
@@ -32,7 +30,7 @@ signals:
private:
Ui::NewNameDialog *ui;
Project *project = nullptr;
- const QString symbolPrefix;
+ const QString namePrefix;
bool validateName(bool allowEmpty = false);
void onNameChanged(const QString &name);
diff --git a/include/ui/newtilesetdialog.h b/include/ui/newtilesetdialog.h
index 06012708..374c85a7 100644
--- a/include/ui/newtilesetdialog.h
+++ b/include/ui/newtilesetdialog.h
@@ -27,7 +27,7 @@ private:
const QString symbolPrefix;
bool validateName(bool allowEmpty = false);
- void onFriendlyNameChanged(const QString &friendlyName);
+ void onNameChanged(const QString &name);
void dialogButtonClicked(QAbstractButton *button);
};
diff --git a/include/ui/tileseteditor.h b/include/ui/tileseteditor.h
index 32bdc97f..5cd6205e 100644
--- a/include/ui/tileseteditor.h
+++ b/include/ui/tileseteditor.h
@@ -120,9 +120,7 @@ private slots:
void on_horizontalSlider_TilesZoom_valueChanged(int value);
private:
- void initUi();
void setAttributesUi();
- void setMetatileLabelValidator();
void initMetatileSelector();
void initTileSelector();
void initSelectedTileItem();
diff --git a/porymap.pro b/porymap.pro
index 171ea48d..5ba1e6e0 100644
--- a/porymap.pro
+++ b/porymap.pro
@@ -39,6 +39,7 @@ SOURCES += src/core/advancemapparser.cpp \
src/core/parseutil.cpp \
src/core/tile.cpp \
src/core/tileset.cpp \
+ src/core/validator.cpp \
src/core/regionmap.cpp \
src/core/wildmoninfo.cpp \
src/core/editcommands.cpp \
@@ -146,6 +147,7 @@ HEADERS += include/core/advancemapparser.h \
include/core/parseutil.h \
include/core/tile.h \
include/core/tileset.h \
+ include/core/validator.h \
include/core/regionmap.h \
include/core/wildmoninfo.h \
include/core/editcommands.h \
diff --git a/src/config.cpp b/src/config.cpp
index 234a0a33..bcfa3489 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -2,6 +2,7 @@
#include "log.h"
#include "shortcut.h"
#include "map.h"
+#include "validator.h"
#include
#include
#include
@@ -952,10 +953,8 @@ void ProjectConfig::setIdentifier(ProjectIdentifier id, QString text) {
const QString idName = defaultIdentifiers.value(id).first;
if (idName.startsWith("define_") || idName.startsWith("symbol_")) {
// Validate the input for the identifier, depending on the type.
- static const QRegularExpression re("[A-Za-z_]+[\\w]*");
- auto validator = QRegularExpressionValidator(re);
- int temp = 0;
- if (validator.validate(text, temp) != QValidator::Acceptable) {
+ IdentifierValidator validator;
+ if (!validator.isValid(text)) {
logError(QString("The name '%1' for project identifier '%2' is invalid. It must only contain word characters, and cannot start with a digit.").arg(text).arg(idName));
return;
}
diff --git a/src/core/tileset.cpp b/src/core/tileset.cpp
index cf21a675..e79e7706 100644
--- a/src/core/tileset.cpp
+++ b/src/core/tileset.cpp
@@ -4,6 +4,7 @@
#include "log.h"
#include "config.h"
#include "imageproviders.h"
+#include "validator.h"
#include
#include
@@ -180,10 +181,8 @@ bool Tileset::setMetatileLabel(int metatileId, QString label, Tileset *primaryTi
if (!tileset)
return false;
- static const QRegularExpression expression("[_A-Za-z0-9]*$");
- QRegularExpressionValidator validator(expression);
- int pos = 0;
- if (validator.validate(label, pos) != QValidator::Acceptable)
+ IdentifierValidator validator;
+ if (!validator.isValid(label))
return false;
tileset->metatileLabels[metatileId] = label;
diff --git a/src/core/validator.cpp b/src/core/validator.cpp
new file mode 100644
index 00000000..b3b36589
--- /dev/null
+++ b/src/core/validator.cpp
@@ -0,0 +1,30 @@
+#include "validator.h"
+
+// Identifiers must only contain word characters, and cannot start with a digit.
+const QRegularExpression IdentifierValidator::re_identifier = QRegularExpression("[A-Za-z_]+[\\w]*");
+
+
+bool PrefixValidator::missingPrefix(const QString &input) const {
+ return !m_prefix.isEmpty() && !input.startsWith(m_prefix);
+}
+
+QValidator::State PrefixValidator::validate(QString &input, int &pos) const {
+ auto state = QRegularExpressionValidator::validate(input, pos);
+ if (state == QValidator::Acceptable) {
+ // This input could be valid. If there's a prefix we should require it now.
+ if (missingPrefix(input))
+ state = QValidator::Intermediate;
+ }
+ return state;
+}
+
+void PrefixValidator::fixup(QString &input) const {
+ QRegularExpressionValidator::fixup(input);
+ if (missingPrefix(input))
+ input.prepend(m_prefix);
+}
+
+bool PrefixValidator::isValid(QString &input) const {
+ int pos = 0;
+ return validate(input, pos) == QValidator::Acceptable;
+}
diff --git a/src/editor.cpp b/src/editor.cpp
index e13f76eb..56914c30 100644
--- a/src/editor.cpp
+++ b/src/editor.cpp
@@ -11,6 +11,7 @@
#include "config.h"
#include "scripting.h"
#include "customattributestable.h"
+#include "validator.h"
#include
#include
#include
@@ -299,9 +300,7 @@ void Editor::addNewWildMonGroup(QWidget *window) {
QLineEdit *lineEdit = new QLineEdit();
lineEdit->setClearButtonEnabled(true);
form.addRow(new QLabel("Group Base Label:"), lineEdit);
- static const QRegularExpression re_validChars("[_A-Za-z0-9]*");
- QRegularExpressionValidator *validator = new QRegularExpressionValidator(re_validChars);
- lineEdit->setValidator(validator);
+ lineEdit->setValidator(new IdentifierValidator(lineEdit));
connect(lineEdit, &QLineEdit::textChanged, [this, &lineEdit, &buttonBox](QString text){
if (this->project->encounterGroupLabels.contains(text)) {
lineEdit->setStyleSheet("QLineEdit { background-color: rgba(255, 0, 0, 25%) }");
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 65a323e2..50c8beae 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -1310,14 +1310,13 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
}
void MainWindow::openNewMapGroupDialog() {
- auto dialog = new NewNameDialog("New Group Name", this->editor->project, this);
+ auto dialog = new NewNameDialog("New Group Name", "", this->editor->project, this);
connect(dialog, &NewNameDialog::applied, this->editor->project, &Project::addNewMapGroup);
dialog->open();
}
void MainWindow::openNewAreaDialog() {
- auto dialog = new NewNameDialog("New Area Name", this->editor->project, this);
- dialog->setNamePrefix(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix));
+ auto dialog = new NewNameDialog("New Area Name", projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix), this->editor->project, this);
connect(dialog, &NewNameDialog::applied, this->editor->project, &Project::addNewMapsec);
dialog->open();
}
diff --git a/src/project.cpp b/src/project.cpp
index 0a66c0e8..efc591e4 100644
--- a/src/project.cpp
+++ b/src/project.cpp
@@ -8,7 +8,7 @@
#include "tileset.h"
#include "map.h"
#include "filedialog.h"
-
+#include "validator.h"
#include "orderedjson.h"
#include
@@ -1453,9 +1453,15 @@ void Project::readTilesetPaths(Tileset* tileset) {
}
}
-Tileset *Project::createNewTileset(const QString &friendlyName, bool secondary, bool checkerboardFill) {
+Tileset *Project::createNewTileset(QString name, bool secondary, bool checkerboardFill) {
+ const QString prefix = projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix);
+ if (!name.startsWith(prefix)) {
+ logError(QString("Tileset name '%1' doesn't begin with the prefix '%2'.").arg(name).arg(prefix));
+ return nullptr;
+ }
+
auto tileset = new Tileset();
- tileset->name = projectConfig.getIdentifier(ProjectIdentifier::symbol_tilesets_prefix) + friendlyName;
+ tileset->name = name;
tileset->is_secondary = secondary;
// Create tileset directories
@@ -1527,10 +1533,11 @@ Tileset *Project::createNewTileset(const QString &friendlyName, bool secondary,
this->tilesetLabelsOrdered.append(tileset->name);
// TODO: Ideally we wouldn't save new Tilesets immediately
- // Append to tileset specific files
- tileset->appendToHeaders(this->root, friendlyName, this->usingAsmTilesets);
- tileset->appendToGraphics(this->root, friendlyName, this->usingAsmTilesets);
- tileset->appendToMetatiles(this->root, friendlyName, this->usingAsmTilesets);
+ // Append to tileset specific files. Strip prefix from name to get base name for use in other symbols.
+ name.remove(0, prefix.length());
+ tileset->appendToHeaders(this->root, name, this->usingAsmTilesets);
+ tileset->appendToGraphics(this->root, name, this->usingAsmTilesets);
+ tileset->appendToMetatiles(this->root, name, this->usingAsmTilesets);
tileset->save();
@@ -1966,12 +1973,10 @@ bool Project::isIdentifierUnique(const QString &identifier) const {
return true;
}
-// For some arbitrary string, return true if it's both a valid identifier name
-// and not one that's already in-use.
-bool Project::isValidNewIdentifier(const QString &identifier) const {
- static const QRegularExpression re_identifier("[A-Za-z_]+[\\w]*");
- QRegularExpressionMatch match = re_identifier.match(identifier);
- return match.hasMatch() && isIdentifierUnique(identifier);
+// For some arbitrary string, return true if it's both a valid identifier name and not one that's already in-use.
+bool Project::isValidNewIdentifier(QString identifier) const {
+ IdentifierValidator validator;
+ return validator.isValid(identifier) && isIdentifierUnique(identifier);
}
// Assumes 'identifier' is a valid name. If 'identifier' is unique, returns 'identifier'.
diff --git a/src/ui/colorinputwidget.cpp b/src/ui/colorinputwidget.cpp
index 8b40be27..6ed587aa 100644
--- a/src/ui/colorinputwidget.cpp
+++ b/src/ui/colorinputwidget.cpp
@@ -1,16 +1,10 @@
#include "colorinputwidget.h"
#include "ui_colorinputwidget.h"
#include "colorpicker.h"
+#include "validator.h"
#include
-class HexCodeValidator : public QValidator {
- virtual QValidator::State validate(QString &input, int &) const override {
- input = input.toUpper();
- return QValidator::Acceptable;
- }
-};
-
static inline int rgb5(int rgb) { return round(static_cast(rgb * 31) / 255.0); }
static inline int rgb8(int rgb) { return round(rgb * 255. / 31.); }
static inline int gbaRed(int rgb) { return rgb & 0x1f; }
@@ -43,8 +37,8 @@ void ColorInputWidget::init() {
connect(ui->spinBox_Green, QOverload::of(&QSpinBox::valueChanged), this, &ColorInputWidget::setRgbFromSpinners);
connect(ui->spinBox_Blue, QOverload::of(&QSpinBox::valueChanged), this, &ColorInputWidget::setRgbFromSpinners);
- static const HexCodeValidator hexValidator;
- ui->lineEdit_Hex->setValidator(&hexValidator);
+ static const UppercaseValidator uppercaseValidator;
+ ui->lineEdit_Hex->setValidator(&uppercaseValidator);
connect(ui->lineEdit_Hex, &QLineEdit::textEdited, this, &ColorInputWidget::setRgbFromHexString);
// We have separate signals for when color input editing finishes.
diff --git a/src/ui/maplistmodels.cpp b/src/ui/maplistmodels.cpp
index dc1e3d7e..a46dfc58 100644
--- a/src/ui/maplistmodels.cpp
+++ b/src/ui/maplistmodels.cpp
@@ -1,11 +1,11 @@
#include "maplistmodels.h"
+#include "validator.h"
+#include "project.h"
+#include "filterchildrenproxymodel.h"
#include
#include
-#include "project.h"
-#include "filterchildrenproxymodel.h"
-
void MapTree::removeSelected() {
@@ -179,9 +179,8 @@ QVariant MapListModel::data(const QModelIndex &index, int role) const {
QWidget *GroupNameDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const {
QLineEdit *editor = new QLineEdit(parent);
- static const QRegularExpression expression("[A-Za-z_]+[\\w]*");
editor->setPlaceholderText("gMapGroup_");
- editor->setValidator(new QRegularExpressionValidator(expression, parent));
+ editor->setValidator(new IdentifierValidator(parent));
editor->setFrame(false);
return editor;
}
diff --git a/src/ui/newlayoutdialog.cpp b/src/ui/newlayoutdialog.cpp
index 086bc346..226df897 100644
--- a/src/ui/newlayoutdialog.cpp
+++ b/src/ui/newlayoutdialog.cpp
@@ -2,6 +2,7 @@
#include "maplayout.h"
#include "ui_newlayoutdialog.h"
#include "config.h"
+#include "validator.h"
#include
#include
@@ -34,9 +35,7 @@ NewLayoutDialog::NewLayoutDialog(Project *project, const Layout *layoutToCopy, Q
ui->newLayoutForm->initUi(project);
- // Identifiers can only contain word characters, and cannot start with a digit.
- static const QRegularExpression re("[A-Za-z_]+[\\w]*");
- auto validator = new QRegularExpressionValidator(re, this);
+ auto validator = new IdentifierValidator(this);
ui->lineEdit_Name->setValidator(validator);
ui->lineEdit_LayoutID->setValidator(validator);
diff --git a/src/ui/newmapdialog.cpp b/src/ui/newmapdialog.cpp
index caf98060..2d1fa46f 100644
--- a/src/ui/newmapdialog.cpp
+++ b/src/ui/newmapdialog.cpp
@@ -3,6 +3,7 @@
#include "mainwindow.h"
#include "ui_newmapdialog.h"
#include "config.h"
+#include "validator.h"
#include
#include
@@ -45,9 +46,7 @@ NewMapDialog::NewMapDialog(Project *project, const Map *mapToCopy, QWidget *pare
ui->comboBox_Group->addItems(project->groupNames);
ui->comboBox_LayoutID->addItems(project->layoutIds);
- // Identifiers can only contain word characters, and cannot start with a digit.
- static const QRegularExpression re("[A-Za-z_]+[\\w]*");
- auto validator = new QRegularExpressionValidator(re, this);
+ auto validator = new IdentifierValidator(this);
ui->lineEdit_Name->setValidator(validator);
ui->comboBox_Group->setValidator(validator);
ui->comboBox_LayoutID->setValidator(validator);
diff --git a/src/ui/newnamedialog.cpp b/src/ui/newnamedialog.cpp
index 8f9cdc42..842bf4b7 100644
--- a/src/ui/newnamedialog.cpp
+++ b/src/ui/newnamedialog.cpp
@@ -2,12 +2,14 @@
#include "ui_newnamedialog.h"
#include "project.h"
#include "imageexport.h"
+#include "validator.h"
const QString lineEdit_ErrorStylesheet = "QLineEdit { background-color: rgba(255, 0, 0, 25%) }";
-NewNameDialog::NewNameDialog(const QString &label, Project* project, QWidget *parent) :
+NewNameDialog::NewNameDialog(const QString &label, const QString &prefix, Project* project, QWidget *parent) :
QDialog(parent),
- ui(new Ui::NewNameDialog)
+ ui(new Ui::NewNameDialog),
+ namePrefix(prefix)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
@@ -16,10 +18,8 @@ NewNameDialog::NewNameDialog(const QString &label, Project* project, QWidget *pa
if (!label.isEmpty())
ui->label_Name->setText(label);
- // Identifiers must only contain word characters, and cannot start with a digit.
- static const QRegularExpression expression("[A-Za-z_]+[\\w]*");
- QRegularExpressionValidator *validator = new QRegularExpressionValidator(expression, this);
- ui->lineEdit_Name->setValidator(validator);
+ ui->lineEdit_Name->setValidator(new IdentifierValidator(namePrefix, this));
+ ui->lineEdit_Name->setText(namePrefix);
connect(ui->lineEdit_Name, &QLineEdit::textChanged, this, &NewNameDialog::onNameChanged);
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewNameDialog::dialogButtonClicked);
@@ -32,10 +32,6 @@ NewNameDialog::~NewNameDialog()
delete ui;
}
-void NewNameDialog::setNamePrefix(const QString &) {
- //TODO
-}
-
void NewNameDialog::onNameChanged(const QString &) {
validateName(true);
}
@@ -44,9 +40,9 @@ bool NewNameDialog::validateName(bool allowEmpty) {
const QString name = ui->lineEdit_Name->text();
QString errorText;
- if (name.isEmpty()) {
+ if (name.isEmpty() || name == namePrefix) {
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_Name->text());
- } else if (!this->project->isIdentifierUnique(name)) {
+ } else if (this->project && !this->project->isIdentifierUnique(name)) {
errorText = QString("%1 '%2' is not unique.").arg(ui->label_Name->text()).arg(name);
}
diff --git a/src/ui/newtilesetdialog.cpp b/src/ui/newtilesetdialog.cpp
index 1e8c569f..049b317d 100644
--- a/src/ui/newtilesetdialog.cpp
+++ b/src/ui/newtilesetdialog.cpp
@@ -2,6 +2,7 @@
#include "ui_newtilesetdialog.h"
#include "project.h"
#include "imageexport.h"
+#include "validator.h"
const QString lineEdit_ErrorStylesheet = "QLineEdit { background-color: rgba(255, 0, 0, 25%) }";
@@ -15,15 +16,11 @@ NewTilesetDialog::NewTilesetDialog(Project* project, QWidget *parent) :
this->project = project;
ui->checkBox_CheckerboardFill->setChecked(porymapConfig.tilesetCheckerboardFill);
- ui->label_SymbolNameDisplay->setText(this->symbolPrefix);
- ui->comboBox_Type->setMinimumContentsLength(12);
+ ui->comboBox_Type->setMinimumContentsLength(12 + this->symbolPrefix.length());
+ ui->lineEdit_Name->setValidator(new IdentifierValidator(this->symbolPrefix, this));
+ ui->lineEdit_Name->setText(this->symbolPrefix);
- //only allow characters valid for a symbol
- static const QRegularExpression expression("[A-Za-z_]+[\\w]*");
- QRegularExpressionValidator *validator = new QRegularExpressionValidator(expression, this);
- ui->lineEdit_FriendlyName->setValidator(validator);
-
- connect(ui->lineEdit_FriendlyName, &QLineEdit::textChanged, this, &NewTilesetDialog::onFriendlyNameChanged);
+ connect(ui->lineEdit_Name, &QLineEdit::textChanged, this, &NewTilesetDialog::onNameChanged);
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewTilesetDialog::dialogButtonClicked);
adjustSize();
@@ -35,28 +32,24 @@ NewTilesetDialog::~NewTilesetDialog()
delete ui;
}
-void NewTilesetDialog::onFriendlyNameChanged(const QString &friendlyName) {
- // When the tileset name is changed, update this label to display the full symbol name.
- ui->label_SymbolNameDisplay->setText(this->symbolPrefix + friendlyName);
-
+void NewTilesetDialog::onNameChanged(const QString &) {
validateName(true);
}
bool NewTilesetDialog::validateName(bool allowEmpty) {
- const QString friendlyName = ui->lineEdit_FriendlyName->text();
- const QString symbolName = ui->label_SymbolNameDisplay->text();
+ const QString name = ui->lineEdit_Name->text();
QString errorText;
- if (friendlyName.isEmpty()) {
- if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_FriendlyName->text());
- } else if (!this->project->isIdentifierUnique(symbolName)) {
- errorText = QString("%1 '%2' is not unique.").arg(ui->label_SymbolName->text()).arg(symbolName);
+ if (name.isEmpty() || name == symbolPrefix) {
+ if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_Name->text());
+ } else if (!this->project->isIdentifierUnique(name)) {
+ errorText = QString("%1 '%2' is not unique.").arg(ui->label_Name->text()).arg(name);
}
bool isValid = errorText.isEmpty();
ui->label_NameError->setText(errorText);
ui->label_NameError->setVisible(!isValid);
- ui->lineEdit_FriendlyName->setStyleSheet(!isValid ? lineEdit_ErrorStylesheet : "");
+ ui->lineEdit_Name->setStyleSheet(!isValid ? lineEdit_ErrorStylesheet : "");
return isValid;
}
@@ -74,7 +67,7 @@ void NewTilesetDialog::accept() {
return;
bool secondary = ui->comboBox_Type->currentIndex() == 1;
- Tileset *tileset = this->project->createNewTileset(ui->lineEdit_FriendlyName->text(), secondary, ui->checkBox_CheckerboardFill->isChecked());
+ Tileset *tileset = this->project->createNewTileset(ui->lineEdit_Name->text(), secondary, ui->checkBox_CheckerboardFill->isChecked());
if (!tileset) {
ui->label_GenericError->setText(QString("Failed to create tileset. See %1 for details.").arg(getLogPath()));
ui->label_GenericError->setVisible(true);
diff --git a/src/ui/projectsettingseditor.cpp b/src/ui/projectsettingseditor.cpp
index 58d808ca..d01a3351 100644
--- a/src/ui/projectsettingseditor.cpp
+++ b/src/ui/projectsettingseditor.cpp
@@ -114,11 +114,6 @@ void ProjectSettingsEditor::initUi() {
ui->lineEdit_BorderMetatiles->setValidator(validator_HexList);
this->setBorderMetatilesUi(projectConfig.useCustomBorderSize);
- // Validate that the text added to the warp behavior list could be a valid define
- // (we don't care whether it actually is a metatile behavior define)
- static const QRegularExpression expression_Word("^[A-Za-z0-9_]*$");
- QRegularExpressionValidator *validator_Word = new QRegularExpressionValidator(expression_Word);
- ui->comboBox_WarpBehaviors->setValidator(validator_Word);
ui->textEdit_WarpBehaviors->setTextColor(Qt::gray);
// Set spin box limits
diff --git a/src/ui/tileseteditor.cpp b/src/ui/tileseteditor.cpp
index 0603e8cb..fab59928 100644
--- a/src/ui/tileseteditor.cpp
+++ b/src/ui/tileseteditor.cpp
@@ -8,6 +8,7 @@
#include "config.h"
#include "shortcut.h"
#include "filedialog.h"
+#include "validator.h"
#include
#include
#include
@@ -20,9 +21,25 @@ TilesetEditor::TilesetEditor(Project *project, Layout *layout, QWidget *parent)
layout(layout),
hasUnsavedChanges(false)
{
- this->setAttribute(Qt::WA_DeleteOnClose);
- this->setTilesets(this->layout->tileset_primary_label, this->layout->tileset_secondary_label);
- this->initUi();
+ setAttribute(Qt::WA_DeleteOnClose);
+ setTilesets(this->layout->tileset_primary_label, this->layout->tileset_secondary_label);
+ ui->setupUi(this);
+
+ this->tileXFlip = ui->checkBox_xFlip->isChecked();
+ this->tileYFlip = ui->checkBox_yFlip->isChecked();
+ this->paletteId = ui->spinBox_paletteSelector->value();
+ ui->spinBox_paletteSelector->setMinimum(0);
+ ui->spinBox_paletteSelector->setMaximum(Project::getNumPalettesTotal() - 1);
+ ui->lineEdit_metatileLabel->setValidator(new IdentifierValidator(this));
+
+ setAttributesUi();
+ initMetatileSelector();
+ initMetatileLayersItem();
+ initTileSelector();
+ initSelectedTileItem();
+ initShortcuts();
+ this->metatileSelector->select(0);
+ restoreWindowState();
}
TilesetEditor::~TilesetEditor()
@@ -92,26 +109,6 @@ void TilesetEditor::setTilesets(QString primaryTilesetLabel, QString secondaryTi
this->initMetatileHistory();
}
-void TilesetEditor::initUi() {
- ui->setupUi(this);
- this->tileXFlip = ui->checkBox_xFlip->isChecked();
- this->tileYFlip = ui->checkBox_yFlip->isChecked();
- this->paletteId = ui->spinBox_paletteSelector->value();
- this->ui->spinBox_paletteSelector->setMinimum(0);
- this->ui->spinBox_paletteSelector->setMaximum(Project::getNumPalettesTotal() - 1);
-
- this->setAttributesUi();
- this->setMetatileLabelValidator();
-
- this->initMetatileSelector();
- this->initMetatileLayersItem();
- this->initTileSelector();
- this->initSelectedTileItem();
- this->initShortcuts();
- this->metatileSelector->select(0);
- this->restoreWindowState();
-}
-
void TilesetEditor::setAttributesUi() {
// Behavior
if (projectConfig.metatileBehaviorMask) {
@@ -171,13 +168,6 @@ void TilesetEditor::setAttributesUi() {
this->ui->frame_Properties->adjustSize();
}
-void TilesetEditor::setMetatileLabelValidator() {
- //only allow characters valid for a symbol
- static const QRegularExpression expression("[_A-Za-z0-9]*$");
- QRegularExpressionValidator *validator = new QRegularExpressionValidator(expression);
- this->ui->lineEdit_metatileLabel->setValidator(validator);
-}
-
void TilesetEditor::initMetatileSelector()
{
this->metatileSelector = new TilesetEditorMetatileSelector(this->primaryTileset, this->secondaryTileset, this->layout);