mirror of
https://github.com/huderlem/porymap.git
synced 2026-06-14 03:40:50 -05:00
Fix map duplication
This commit is contained in:
parent
ff04a41db2
commit
f1a4b78ca9
|
|
@ -117,6 +117,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_GenericError">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
|
|
|
|||
|
|
@ -25,15 +25,40 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>229</width>
|
||||
<height>306</height>
|
||||
<height>228</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="verticalSpacing">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_Name">
|
||||
<property name="text">
|
||||
<string>Map Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0" colspan="2">
|
||||
<widget class="QWidget" name="widget_HeaderData" native="true">
|
||||
<layout class="QVBoxLayout" name="layout_HeaderData">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_MapIDError">
|
||||
<widget class="QLabel" name="label_GroupError">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
|
@ -48,29 +73,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_LayoutID">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertPolicy::NoInsert</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="label_LayoutIDError">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="label_NameError">
|
||||
<property name="visible">
|
||||
|
|
@ -87,57 +89,22 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_MapID">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The constant that will be used to refer to this map. It cannot be the same as any other existing map, and it must start with the specified prefix.</p></body></html></string>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_LayoutID">
|
||||
<property name="text">
|
||||
<string>Layout ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_MapID">
|
||||
<widget class="QLabel" name="label_Group">
|
||||
<property name="text">
|
||||
<string>Map ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0" colspan="2">
|
||||
<widget class="QWidget" name="widget_HeaderData" native="true">
|
||||
<layout class="QVBoxLayout" name="layout_HeaderData">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_CanFlyTo">
|
||||
<property name="text">
|
||||
<string>Can Fly To</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_Name">
|
||||
<property name="text">
|
||||
<string>Map Name</string>
|
||||
<string>Map Group</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_Group">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The name of the group this map will be added to.</p></body></html></string>
|
||||
</property>
|
||||
<widget class="NoScrollComboBox" name="comboBox_LayoutID">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
|
@ -146,17 +113,7 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Name">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The name of the new map. The name cannot be the same as any other existing map.</p></body></html></string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<item row="8" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_CanFlyTo">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If checked, a Heal Location will be added to this map automatically.</p></body></html></string>
|
||||
|
|
@ -166,8 +123,8 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_GroupError">
|
||||
<item row="6" column="1">
|
||||
<widget class="QLabel" name="label_LayoutIDError">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
|
@ -182,24 +139,40 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="NewLayoutForm" name="newLayoutForm" native="true"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_Group">
|
||||
<property name="text">
|
||||
<string>Map Group</string>
|
||||
<item row="2" column="1">
|
||||
<widget class="NoScrollComboBox" name="comboBox_Group">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The name of the group this map will be added to.</p></body></html></string>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertPolicy::NoInsert</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_LayoutID">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_CanFlyTo">
|
||||
<property name="text">
|
||||
<string>Layout ID</string>
|
||||
<string>Can Fly To</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0" colspan="2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_Name">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The name of the new map. The name cannot be the same as any other existing map.</p></body></html></string>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
|
|
@ -218,6 +191,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_GenericError">
|
||||
<property name="visible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">color: rgb(255, 0, 0)</string>
|
||||
</property>
|
||||
|
|
|
|||
|
|
@ -74,7 +74,6 @@ public:
|
|||
QUndoStack editHistory;
|
||||
|
||||
// to simplify new layout settings transfer between functions
|
||||
// TODO: Make this the equivalent of struct MapHeader
|
||||
struct Settings {
|
||||
QString id;
|
||||
QString name;
|
||||
|
|
|
|||
|
|
@ -81,16 +81,6 @@ public:
|
|||
bool wildEncountersLoaded;
|
||||
bool saveEmptyMapsec;
|
||||
|
||||
struct NewMapSettings {
|
||||
QString name;
|
||||
QString id;
|
||||
QString group;
|
||||
bool canFlyTo;
|
||||
Layout::Settings layout;
|
||||
MapHeader header;
|
||||
};
|
||||
NewMapSettings newMapSettings;
|
||||
|
||||
void set_root(QString);
|
||||
|
||||
void clearMapCache();
|
||||
|
|
@ -132,10 +122,23 @@ public:
|
|||
bool readMapGroups();
|
||||
void addNewMapGroup(const QString &groupName);
|
||||
|
||||
struct NewMapSettings {
|
||||
QString name;
|
||||
QString group;
|
||||
bool canFlyTo;
|
||||
Layout::Settings layout;
|
||||
MapHeader header;
|
||||
};
|
||||
NewMapSettings newMapSettings;
|
||||
Layout::Settings newLayoutSettings;
|
||||
|
||||
QString getNewMapName() const;
|
||||
QString getNewLayoutName() const;
|
||||
void initNewMapSettings();
|
||||
void initNewLayoutSettings();
|
||||
|
||||
Map *createNewMap(const Project::NewMapSettings &mapSettings, const Map* toDuplicate = nullptr);
|
||||
Layout *createNewLayout(const Layout::Settings &layoutSettings, const Layout* toDuplicate = nullptr);
|
||||
NewMapSettings getNewMapSettings() const;
|
||||
Layout::Settings getNewLayoutSettings() const;
|
||||
bool isIdentifierUnique(const QString &identifier) const;
|
||||
QString getProjectTitle();
|
||||
|
||||
|
|
|
|||
|
|
@ -30,10 +30,7 @@ signals:
|
|||
private:
|
||||
Ui::NewLayoutDialog *ui;
|
||||
Project *project;
|
||||
Layout *importedLayout = nullptr;
|
||||
|
||||
static Layout::Settings settings;
|
||||
static bool initializedSettings;
|
||||
const Layout *layoutToCopy;
|
||||
|
||||
// Each of these validation functions will allow empty names up until `OK` is selected,
|
||||
// because clearing the text during editing is common and we don't want to flash errors for this.
|
||||
|
|
@ -41,7 +38,6 @@ private:
|
|||
bool validateName(bool allowEmpty = false);
|
||||
|
||||
void refresh();
|
||||
|
||||
void saveSettings();
|
||||
bool isExistingLayout() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ class NewMapDialog : public QDialog
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit NewMapDialog(Project *project, QWidget *parent = nullptr);
|
||||
explicit NewMapDialog(Project *project, const Map *mapToCopy = nullptr, QWidget *parent = nullptr);
|
||||
explicit NewMapDialog(Project *project, int mapListTab, const QString &mapListItem, QWidget *parent = nullptr);
|
||||
explicit NewMapDialog(Project *project, const Map *mapToCopy, QWidget *parent = nullptr);
|
||||
~NewMapDialog();
|
||||
|
||||
virtual void accept() override;
|
||||
|
|
@ -30,26 +30,21 @@ private:
|
|||
Project *project;
|
||||
CollapsibleSection *headerSection;
|
||||
MapHeaderForm *headerForm;
|
||||
Map *importedMap = nullptr;
|
||||
|
||||
static Project::NewMapSettings settings;
|
||||
static bool initializedSettings;
|
||||
const Map *mapToCopy;
|
||||
|
||||
// Each of these validation functions will allow empty names up until `OK` is selected,
|
||||
// because clearing the text during editing is common and we don't want to flash errors for this.
|
||||
bool validateMapID(bool allowEmpty = false);
|
||||
bool validateName(bool allowEmpty = false);
|
||||
bool validateGroup(bool allowEmpty = false);
|
||||
bool validateLayoutID(bool allowEmpty = false);
|
||||
|
||||
void setUI(const Project::NewMapSettings &settings);
|
||||
void refresh();
|
||||
void saveSettings();
|
||||
void setLayout(const Layout *mapLayout);
|
||||
|
||||
private slots:
|
||||
void dialogButtonClicked(QAbstractButton *button);
|
||||
void on_lineEdit_Name_textChanged(const QString &);
|
||||
void on_lineEdit_MapID_textChanged(const QString &);
|
||||
void on_comboBox_Group_currentTextChanged(const QString &text);
|
||||
void on_comboBox_LayoutID_currentTextChanged(const QString &text);
|
||||
};
|
||||
|
|
|
|||
127
src/project.cpp
127
src/project.cpp
|
|
@ -106,6 +106,9 @@ bool Project::load() {
|
|||
&& readEventGraphics()
|
||||
&& readSongNames()
|
||||
&& readMapGroups();
|
||||
|
||||
initNewLayoutSettings();
|
||||
initNewMapSettings();
|
||||
applyParsedLimits();
|
||||
return success;
|
||||
}
|
||||
|
|
@ -366,16 +369,24 @@ bool Project::loadMapData(Map* map) {
|
|||
Map *Project::createNewMap(const Project::NewMapSettings &settings, const Map* toDuplicate) {
|
||||
Map *map = toDuplicate ? new Map(*toDuplicate) : new Map;
|
||||
map->setName(settings.name);
|
||||
map->setConstantName(settings.id);
|
||||
map->setHeader(settings.header);
|
||||
map->setNeedsHealLocation(settings.canFlyTo);
|
||||
|
||||
// Generate a unique MAP constant.
|
||||
int suffix = 2;
|
||||
const QString baseMapConstant = Map::mapConstantFromName(map->name());
|
||||
QString mapConstant = baseMapConstant;
|
||||
while (!isIdentifierUnique(mapConstant)) {
|
||||
mapConstant = QString("%1_%2").arg(baseMapConstant).arg(suffix++);
|
||||
}
|
||||
map->setConstantName(mapConstant);
|
||||
|
||||
Layout *layout = this->mapLayouts.value(settings.layout.id);
|
||||
if (layout) {
|
||||
// Layout already exists
|
||||
map->setNeedsLayoutDir(false); // TODO: Remove this member?
|
||||
} else {
|
||||
layout = createNewLayout(settings.layout);
|
||||
layout = createNewLayout(settings.layout, toDuplicate ? toDuplicate->layout() : nullptr);
|
||||
}
|
||||
if (!layout) {
|
||||
delete map;
|
||||
|
|
@ -1960,60 +1971,6 @@ void Project::addNewMapGroup(const QString &groupName) {
|
|||
emit mapGroupAdded(groupName);
|
||||
}
|
||||
|
||||
Project::NewMapSettings Project::getNewMapSettings() const {
|
||||
// Ensure default name/ID doesn't already exist.
|
||||
int i = 0;
|
||||
QString newMapName;
|
||||
QString newMapId;
|
||||
do {
|
||||
newMapName = QString("NewMap%1").arg(++i);
|
||||
newMapId = Map::mapConstantFromName(newMapName);
|
||||
} while (!isIdentifierUnique(newMapName) || !isIdentifierUnique(newMapId));
|
||||
|
||||
NewMapSettings settings;
|
||||
settings.name = newMapName;
|
||||
settings.id = newMapId;
|
||||
settings.group = this->groupNames.at(0);
|
||||
settings.canFlyTo = false;
|
||||
settings.layout = getNewLayoutSettings();
|
||||
settings.layout.id = Layout::layoutConstantFromName(newMapName);
|
||||
settings.layout.name = Layout::layoutNameFromMapName(newMapName);
|
||||
settings.header.setSong(this->defaultSong);
|
||||
settings.header.setLocation(this->mapSectionIdNames.value(0, "0"));
|
||||
settings.header.setRequiresFlash(false);
|
||||
settings.header.setWeather(this->weatherNames.value(0, "0"));
|
||||
settings.header.setType(this->mapTypes.value(0, "0"));
|
||||
settings.header.setBattleScene(this->mapBattleScenes.value(0, "0"));
|
||||
settings.header.setShowsLocationName(true);
|
||||
settings.header.setAllowsRunning(false);
|
||||
settings.header.setAllowsBiking(false);
|
||||
settings.header.setAllowsEscaping(false);
|
||||
settings.header.setFloorNumber(0);
|
||||
return settings;
|
||||
}
|
||||
|
||||
Layout::Settings Project::getNewLayoutSettings() const {
|
||||
// Ensure default name/ID doesn't already exist.
|
||||
int i = 0;
|
||||
QString newLayoutName;
|
||||
QString newLayoutId;
|
||||
do {
|
||||
newLayoutName = QString("NewLayout%1").arg(++i);
|
||||
newLayoutId = Layout::layoutConstantFromName(newLayoutName);
|
||||
} while (!isIdentifierUnique(newLayoutId) || !isIdentifierUnique(newLayoutName));
|
||||
|
||||
Layout::Settings settings;
|
||||
settings.name = newLayoutName;
|
||||
settings.id = newLayoutId;
|
||||
settings.width = getDefaultMapDimension();
|
||||
settings.height = getDefaultMapDimension();
|
||||
settings.borderWidth = DEFAULT_BORDER_WIDTH;
|
||||
settings.borderHeight = DEFAULT_BORDER_HEIGHT;
|
||||
settings.primaryTilesetLabel = getDefaultPrimaryTilesetLabel();
|
||||
settings.secondaryTilesetLabel = getDefaultSecondaryTilesetLabel();
|
||||
return settings;
|
||||
}
|
||||
|
||||
// When we ask the user to provide a new identifier for something (like a map name or MAPSEC id)
|
||||
// we use this to make sure that it doesn't collide with any known identifiers first.
|
||||
// Porymap knows of many more identifiers than this, but for simplicity we only check the lists that users can add to via Porymap.
|
||||
|
|
@ -2040,6 +1997,64 @@ bool Project::isIdentifierUnique(const QString &identifier) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
QString Project::getNewMapName() const {
|
||||
// Ensure default name/ID doesn't already exist.
|
||||
int i = 0;
|
||||
QString newMapName;
|
||||
do {
|
||||
newMapName = QString("NewMap%1").arg(++i);
|
||||
} while (!isIdentifierUnique(newMapName) || !isIdentifierUnique(Map::mapConstantFromName(newMapName)));
|
||||
return newMapName;
|
||||
}
|
||||
|
||||
QString Project::getNewLayoutName() const {
|
||||
// Ensure default name/ID doesn't already exist.
|
||||
int i = 0;
|
||||
QString newLayoutName;
|
||||
do {
|
||||
newLayoutName = QString("NewLayout%1").arg(++i);
|
||||
} while (!isIdentifierUnique(newLayoutName) || !isIdentifierUnique(Layout::layoutConstantFromName(newLayoutName)));
|
||||
return newLayoutName;
|
||||
}
|
||||
|
||||
void Project::initNewMapSettings() {
|
||||
this->newMapSettings.name = getNewMapName();
|
||||
this->newMapSettings.group = this->groupNames.at(0);
|
||||
this->newMapSettings.canFlyTo = false;
|
||||
|
||||
this->newMapSettings.layout.name = Layout::layoutNameFromMapName(this->newMapSettings.name);
|
||||
this->newMapSettings.layout.id = Layout::layoutConstantFromName(this->newMapSettings.name);
|
||||
this->newMapSettings.layout.width = getDefaultMapDimension();
|
||||
this->newMapSettings.layout.height = getDefaultMapDimension();
|
||||
this->newMapSettings.layout.borderWidth = DEFAULT_BORDER_WIDTH;
|
||||
this->newMapSettings.layout.borderHeight = DEFAULT_BORDER_HEIGHT;
|
||||
this->newMapSettings.layout.primaryTilesetLabel = getDefaultPrimaryTilesetLabel();
|
||||
this->newMapSettings.layout.secondaryTilesetLabel = getDefaultSecondaryTilesetLabel();
|
||||
|
||||
this->newMapSettings.header.setSong(this->defaultSong);
|
||||
this->newMapSettings.header.setLocation(this->mapSectionIdNames.value(0, "0"));
|
||||
this->newMapSettings.header.setRequiresFlash(false);
|
||||
this->newMapSettings.header.setWeather(this->weatherNames.value(0, "0"));
|
||||
this->newMapSettings.header.setType(this->mapTypes.value(0, "0"));
|
||||
this->newMapSettings.header.setBattleScene(this->mapBattleScenes.value(0, "0"));
|
||||
this->newMapSettings.header.setShowsLocationName(true);
|
||||
this->newMapSettings.header.setAllowsRunning(false);
|
||||
this->newMapSettings.header.setAllowsBiking(false);
|
||||
this->newMapSettings.header.setAllowsEscaping(false);
|
||||
this->newMapSettings.header.setFloorNumber(0);
|
||||
}
|
||||
|
||||
void Project::initNewLayoutSettings() {
|
||||
this->newLayoutSettings.name = getNewLayoutName();
|
||||
this->newLayoutSettings.id = Layout::layoutConstantFromName(this->newLayoutSettings.name);
|
||||
this->newLayoutSettings.width = getDefaultMapDimension();
|
||||
this->newLayoutSettings.height = getDefaultMapDimension();
|
||||
this->newLayoutSettings.borderWidth = DEFAULT_BORDER_WIDTH;
|
||||
this->newLayoutSettings.borderHeight = DEFAULT_BORDER_HEIGHT;
|
||||
this->newLayoutSettings.primaryTilesetLabel = getDefaultPrimaryTilesetLabel();
|
||||
this->newLayoutSettings.secondaryTilesetLabel = getDefaultSecondaryTilesetLabel();
|
||||
}
|
||||
|
||||
Project::DataQualifiers Project::getDataQualifiers(QString text, QString label) {
|
||||
Project::DataQualifiers qualifiers;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,30 +9,56 @@
|
|||
|
||||
const QString lineEdit_ErrorStylesheet = "QLineEdit { background-color: rgba(255, 0, 0, 25%) }";
|
||||
|
||||
Layout::Settings NewLayoutDialog::settings = {};
|
||||
bool NewLayoutDialog::initializedSettings = false;
|
||||
|
||||
NewLayoutDialog::NewLayoutDialog(Project *project, QWidget *parent) :
|
||||
NewLayoutDialog(project, nullptr, parent)
|
||||
{}
|
||||
|
||||
NewLayoutDialog::NewLayoutDialog(Project *project, const Layout *layoutToCopy, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewLayoutDialog)
|
||||
ui(new Ui::NewLayoutDialog),
|
||||
layoutToCopy(layoutToCopy)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setModal(true);
|
||||
ui->setupUi(this);
|
||||
ui->label_GenericError->setVisible(false);
|
||||
this->project = project;
|
||||
|
||||
Layout::Settings newSettings = project->getNewLayoutSettings();
|
||||
if (!initializedSettings) {
|
||||
// The first time this dialog is opened we initialize all the default settings.
|
||||
settings = newSettings;
|
||||
initializedSettings = true;
|
||||
QString newName;
|
||||
QString newId;
|
||||
if (this->layoutToCopy && !this->layoutToCopy->name.isEmpty()) {
|
||||
// Duplicating a layout, the initial name will be the base layout's name
|
||||
// with a numbered suffix to make it unique.
|
||||
// Note: Layouts imported with AdvanceMap have no name, so they'll use the default new layout name instead.
|
||||
|
||||
// If the layout name ends with the default '_Layout' suffix we'll ignore it.
|
||||
// This is because (normally) the ID for these layouts will not have this suffix,
|
||||
// so you can end up in a situation where you might have Map_Layout and Map_2_Layout,
|
||||
// and if you try to duplicate Map_Layout the next available name (because of ID collisions)
|
||||
// would be Map_Layout_3 instead of Map_3_Layout.
|
||||
QString baseName = this->layoutToCopy->name;
|
||||
QString suffix = "_Layout";
|
||||
if (baseName.length() > suffix.length() && baseName.endsWith(suffix)) {
|
||||
baseName.truncate(baseName.length() - suffix.length());
|
||||
} else {
|
||||
suffix = "";
|
||||
}
|
||||
|
||||
int i = 2;
|
||||
do {
|
||||
newName = QString("%1_%2%3").arg(baseName).arg(i).arg(suffix);
|
||||
newId = QString("%1_%2").arg(this->layoutToCopy->id).arg(i);
|
||||
i++;
|
||||
} while (!project->isIdentifierUnique(newName) || !project->isIdentifierUnique(newId));
|
||||
} else {
|
||||
// On subsequent openings we only initialize the settings that should be unique,
|
||||
// preserving all other settings from the last time the dialog was open.
|
||||
settings.name = newSettings.name;
|
||||
settings.id = newSettings.id;
|
||||
newName = project->getNewLayoutName();
|
||||
newId = Layout::layoutConstantFromName(newName);
|
||||
}
|
||||
|
||||
// We reset these settings for every session with the new layout dialog.
|
||||
// The rest of the settings are preserved in the project between sessions.
|
||||
project->newLayoutSettings.name = newName;
|
||||
project->newLayoutSettings.id = newId;
|
||||
|
||||
ui->newLayoutForm->initUi(project);
|
||||
|
||||
// Identifiers can only contain word characters, and cannot start with a digit.
|
||||
|
|
@ -47,53 +73,34 @@ NewLayoutDialog::NewLayoutDialog(Project *project, QWidget *parent) :
|
|||
adjustSize();
|
||||
}
|
||||
|
||||
// Creating new layout from an existing layout (e.g. via AdvanceMap import, or duplicating from map list).
|
||||
NewLayoutDialog::NewLayoutDialog(Project *project, const Layout *layoutToCopy, QWidget *parent) :
|
||||
NewLayoutDialog(project, parent)
|
||||
{
|
||||
if (!layoutToCopy)
|
||||
return;
|
||||
|
||||
this->importedLayout = layoutToCopy->copy();
|
||||
if (!this->importedLayout->name.isEmpty()) {
|
||||
// If the layout we're duplicating has a name and ID we'll initialize the name/ID fields
|
||||
// using that name and add a suffix to make it unique.
|
||||
// Layouts imported with AdvanceMap won't have a name/ID.
|
||||
int i = 2;
|
||||
do {
|
||||
settings.name = QString("%1_%2").arg(this->importedLayout->name).arg(i);
|
||||
settings.id = QString("%1_%2").arg(this->importedLayout->id).arg(i);
|
||||
i++;
|
||||
} while (!this->project->isIdentifierUnique(settings.name) || !this->project->isIdentifierUnique(settings.id));
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
NewLayoutDialog::~NewLayoutDialog()
|
||||
{
|
||||
saveSettings();
|
||||
delete this->importedLayout;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void NewLayoutDialog::refresh() {
|
||||
if (this->importedLayout) {
|
||||
const Layout::Settings *settings = &this->project->newLayoutSettings;
|
||||
|
||||
if (this->layoutToCopy) {
|
||||
// If we're importing a layout then some settings will be enforced.
|
||||
ui->newLayoutForm->setSettings(this->importedLayout->settings());
|
||||
ui->newLayoutForm->setSettings(this->layoutToCopy->settings());
|
||||
ui->newLayoutForm->setDisabled(true);
|
||||
} else {
|
||||
ui->newLayoutForm->setSettings(settings);
|
||||
ui->newLayoutForm->setSettings(*settings);
|
||||
ui->newLayoutForm->setDisabled(false);
|
||||
}
|
||||
|
||||
ui->lineEdit_Name->setText(settings.name);
|
||||
ui->lineEdit_LayoutID->setText(settings.id);
|
||||
ui->lineEdit_Name->setText(settings->name);
|
||||
ui->lineEdit_LayoutID->setText(settings->id);
|
||||
}
|
||||
|
||||
void NewLayoutDialog::saveSettings() {
|
||||
settings = ui->newLayoutForm->settings();
|
||||
settings.id = ui->lineEdit_LayoutID->text();
|
||||
settings.name = ui->lineEdit_Name->text();
|
||||
Layout::Settings *settings = &this->project->newLayoutSettings;
|
||||
|
||||
*settings = ui->newLayoutForm->settings();
|
||||
settings->id = ui->lineEdit_LayoutID->text();
|
||||
settings->name = ui->lineEdit_Name->text();
|
||||
}
|
||||
|
||||
bool NewLayoutDialog::validateLayoutID(bool allowEmpty) {
|
||||
|
|
@ -146,7 +153,7 @@ void NewLayoutDialog::dialogButtonClicked(QAbstractButton *button) {
|
|||
if (role == QDialogButtonBox::RejectRole){
|
||||
reject();
|
||||
} else if (role == QDialogButtonBox::ResetRole) {
|
||||
settings = this->project->getNewLayoutSettings();
|
||||
this->project->initNewLayoutSettings();
|
||||
refresh();
|
||||
} else if (role == QDialogButtonBox::AcceptRole) {
|
||||
accept();
|
||||
|
|
@ -165,7 +172,7 @@ void NewLayoutDialog::accept() {
|
|||
// Update settings from UI
|
||||
saveSettings();
|
||||
|
||||
Layout *layout = this->project->createNewLayout(settings, this->importedLayout);
|
||||
Layout *layout = this->project->createNewLayout(this->project->newLayoutSettings, this->layoutToCopy);
|
||||
if (!layout) {
|
||||
ui->label_GenericError->setText(QString("Failed to create layout. See %1 for details.").arg(getLogPath()));
|
||||
ui->label_GenericError->setVisible(true);
|
||||
|
|
|
|||
|
|
@ -10,30 +10,41 @@
|
|||
|
||||
const QString lineEdit_ErrorStylesheet = "QLineEdit { background-color: rgba(255, 0, 0, 25%) }";
|
||||
|
||||
Project::NewMapSettings NewMapDialog::settings = {};
|
||||
bool NewMapDialog::initializedSettings = false;
|
||||
|
||||
NewMapDialog::NewMapDialog(Project *project, QWidget *parent) :
|
||||
NewMapDialog(project, nullptr, parent)
|
||||
{}
|
||||
|
||||
NewMapDialog::NewMapDialog(Project *project, const Map *mapToCopy, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewMapDialog)
|
||||
ui(new Ui::NewMapDialog),
|
||||
mapToCopy(mapToCopy)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setModal(true);
|
||||
ui->setupUi(this);
|
||||
ui->label_GenericError->setVisible(false);
|
||||
this->project = project;
|
||||
|
||||
Project::NewMapSettings newSettings = project->getNewMapSettings();
|
||||
if (!initializedSettings) {
|
||||
// The first time this dialog is opened we initialize all the default settings.
|
||||
settings = newSettings;
|
||||
initializedSettings = true;
|
||||
QString newMapName;
|
||||
QString newLayoutId;
|
||||
if (this->mapToCopy) {
|
||||
// Duplicating a map, the initial name will be the base map's name
|
||||
// with a numbered suffix to make it unique.
|
||||
int i = 2;
|
||||
do {
|
||||
newMapName = QString("%1_%2").arg(this->mapToCopy->name()).arg(i++);
|
||||
newLayoutId = Layout::layoutConstantFromName(newMapName);
|
||||
} while (!project->isIdentifierUnique(newMapName) || !project->isIdentifierUnique(newLayoutId));
|
||||
} else {
|
||||
// On subsequent openings we only initialize the settings that should be unique,
|
||||
// preserving all other settings from the last time the dialog was open.
|
||||
settings.name = newSettings.name;
|
||||
settings.id = newSettings.id;
|
||||
// Not duplicating a map, get a generic new map name.
|
||||
newMapName = project->getNewMapName();
|
||||
newLayoutId = Layout::layoutConstantFromName(newMapName);
|
||||
}
|
||||
|
||||
// We reset these settings for every session with the new map dialog.
|
||||
// The rest of the settings are preserved in the project between sessions.
|
||||
project->newMapSettings.name = newMapName;
|
||||
project->newMapSettings.layout.id = newLayoutId;
|
||||
|
||||
ui->newLayoutForm->initUi(project);
|
||||
|
||||
ui->comboBox_Group->addItems(project->groupNames);
|
||||
|
|
@ -43,7 +54,6 @@ NewMapDialog::NewMapDialog(Project *project, QWidget *parent) :
|
|||
static const QRegularExpression re("[A-Za-z_]+[\\w]*");
|
||||
auto validator = new QRegularExpressionValidator(re, this);
|
||||
ui->lineEdit_Name->setValidator(validator);
|
||||
ui->lineEdit_MapID->setValidator(validator);
|
||||
ui->comboBox_Group->setValidator(validator);
|
||||
ui->comboBox_LayoutID->setValidator(validator);
|
||||
|
||||
|
|
@ -60,7 +70,7 @@ NewMapDialog::NewMapDialog(Project *project, QWidget *parent) :
|
|||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewMapDialog::dialogButtonClicked);
|
||||
|
||||
setUI(settings);
|
||||
refresh();
|
||||
adjustSize(); // TODO: Save geometry?
|
||||
}
|
||||
|
||||
|
|
@ -79,52 +89,53 @@ NewMapDialog::NewMapDialog(Project *project, int mapListTab, const QString &mapL
|
|||
this->headerForm->setLocation(mapListItem);
|
||||
break;
|
||||
case MapListTab::Layouts:
|
||||
// We specifically lock the layout ID because otherwise the setting would be overwritten when
|
||||
// the user changes the map name (which will normally automatically update the layout ID to match).
|
||||
// For the Group/Area settings above we don't care if the user changes them afterwards.
|
||||
ui->comboBox_LayoutID->setTextItem(mapListItem);
|
||||
ui->comboBox_LayoutID->setDisabled(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NewMapDialog::NewMapDialog(Project *project, const Map *mapToCopy, QWidget *parent) :
|
||||
NewMapDialog(project, parent)
|
||||
{
|
||||
if (!mapToCopy)
|
||||
return;
|
||||
// TODO
|
||||
}
|
||||
|
||||
NewMapDialog::~NewMapDialog()
|
||||
{
|
||||
saveSettings();
|
||||
delete this->importedMap;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void NewMapDialog::setUI(const Project::NewMapSettings &settings) {
|
||||
ui->lineEdit_Name->setText(settings.name);
|
||||
ui->lineEdit_MapID->setText(settings.id);
|
||||
ui->comboBox_Group->setTextItem(settings.group);
|
||||
ui->comboBox_LayoutID->setTextItem(settings.layout.id);
|
||||
if (this->importedMap && this->importedMap->layout()) {
|
||||
// Reload the UI from the last-saved settings.
|
||||
void NewMapDialog::refresh() {
|
||||
const Project::NewMapSettings *settings = &this->project->newMapSettings;
|
||||
|
||||
ui->lineEdit_Name->setText(settings->name);
|
||||
ui->comboBox_Group->setTextItem(settings->group);
|
||||
|
||||
// If the layout combo box is disabled, it's because we're enforcing the setting. Leave it unchanged.
|
||||
if (ui->comboBox_LayoutID->isEnabled())
|
||||
ui->comboBox_LayoutID->setTextItem(settings->layout.id);
|
||||
|
||||
if (this->mapToCopy && this->mapToCopy->layout()) {
|
||||
// When importing a layout these settings shouldn't be changed.
|
||||
ui->newLayoutForm->setSettings(this->importedMap->layout()->settings());
|
||||
ui->newLayoutForm->setSettings(this->mapToCopy->layout()->settings());
|
||||
} else {
|
||||
ui->newLayoutForm->setSettings(settings.layout);
|
||||
ui->newLayoutForm->setSettings(settings->layout);
|
||||
}
|
||||
ui->checkBox_CanFlyTo->setChecked(settings.canFlyTo);
|
||||
this->headerForm->setHeaderData(settings.header);
|
||||
ui->checkBox_CanFlyTo->setChecked(settings->canFlyTo);
|
||||
this->headerForm->setHeaderData(settings->header);
|
||||
}
|
||||
|
||||
void NewMapDialog::saveSettings() {
|
||||
settings.name = ui->lineEdit_Name->text();
|
||||
settings.id = ui->lineEdit_MapID->text();
|
||||
settings.group = ui->comboBox_Group->currentText();
|
||||
settings.layout = ui->newLayoutForm->settings();
|
||||
settings.layout.id = ui->comboBox_LayoutID->currentText();
|
||||
// We don't provide full control for naming new layouts here (just via the ID).
|
||||
// If a user wants to explicitly name a layout they can create it individually before creating the map.
|
||||
settings.layout.name = Layout::layoutNameFromMapName(settings.name); // TODO: Verify uniqueness
|
||||
settings.canFlyTo = ui->checkBox_CanFlyTo->isChecked();
|
||||
settings.header = this->headerForm->headerData();
|
||||
Project::NewMapSettings *settings = &this->project->newMapSettings;
|
||||
|
||||
settings->name = ui->lineEdit_Name->text();
|
||||
settings->group = ui->comboBox_Group->currentText();
|
||||
settings->layout = ui->newLayoutForm->settings();
|
||||
settings->layout.id = ui->comboBox_LayoutID->currentText();
|
||||
settings->layout.name = Layout::layoutNameFromMapName(settings->name); // TODO: Verify uniqueness
|
||||
settings->canFlyTo = ui->checkBox_CanFlyTo->isChecked();
|
||||
settings->header = this->headerForm->headerData();
|
||||
|
||||
porymapConfig.newMapHeaderSectionExpanded = this->headerSection->isExpanded();
|
||||
}
|
||||
|
||||
|
|
@ -138,30 +149,6 @@ void NewMapDialog::setLayout(const Layout *layout) {
|
|||
}
|
||||
}
|
||||
|
||||
bool NewMapDialog::validateMapID(bool allowEmpty) {
|
||||
QString id = ui->lineEdit_MapID->text();
|
||||
const QString expectedPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_prefix);
|
||||
|
||||
QString errorText;
|
||||
if (id.isEmpty() || id == expectedPrefix) {
|
||||
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_MapID->text());
|
||||
} else if (!id.startsWith(expectedPrefix)) {
|
||||
errorText = QString("%1 must start with '%2'.").arg(ui->label_MapID->text()).arg(expectedPrefix);
|
||||
} else if (!this->project->isIdentifierUnique(id)) {
|
||||
errorText = QString("%1 '%2' is not unique.").arg(ui->label_MapID->text()).arg(id);
|
||||
}
|
||||
|
||||
bool isValid = errorText.isEmpty();
|
||||
ui->label_MapIDError->setText(errorText);
|
||||
ui->label_MapIDError->setVisible(!isValid);
|
||||
ui->lineEdit_MapID->setStyleSheet(!isValid ? lineEdit_ErrorStylesheet : "");
|
||||
return isValid;
|
||||
}
|
||||
|
||||
void NewMapDialog::on_lineEdit_MapID_textChanged(const QString &) {
|
||||
validateMapID(true);
|
||||
}
|
||||
|
||||
bool NewMapDialog::validateName(bool allowEmpty) {
|
||||
QString name = ui->lineEdit_Name->text();
|
||||
|
||||
|
|
@ -181,7 +168,6 @@ bool NewMapDialog::validateName(bool allowEmpty) {
|
|||
|
||||
void NewMapDialog::on_lineEdit_Name_textChanged(const QString &text) {
|
||||
validateName(true);
|
||||
ui->lineEdit_MapID->setText(Map::mapConstantFromName(text));
|
||||
if (ui->comboBox_LayoutID->isEnabled()) {
|
||||
ui->comboBox_LayoutID->setCurrentText(Layout::layoutConstantFromName(text));
|
||||
}
|
||||
|
|
@ -216,7 +202,7 @@ bool NewMapDialog::validateLayoutID(bool allowEmpty) {
|
|||
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_LayoutID->text());
|
||||
} else if (!this->project->isIdentifierUnique(layoutId)) {
|
||||
// Layout name is already in use by something. If we're duplicating a map this isn't allowed.
|
||||
if (this->importedMap) {
|
||||
if (this->mapToCopy) {
|
||||
errorText = QString("%1 is not unique.").arg(ui->label_LayoutID->text());
|
||||
// If we're not duplicating a map this is ok as long as it's the name of an existing layout.
|
||||
} else if (!this->project->layoutIds.contains(layoutId)) {
|
||||
|
|
@ -241,7 +227,8 @@ void NewMapDialog::dialogButtonClicked(QAbstractButton *button) {
|
|||
if (role == QDialogButtonBox::RejectRole){
|
||||
reject();
|
||||
} else if (role == QDialogButtonBox::ResetRole) {
|
||||
setUI(this->project->getNewMapSettings());
|
||||
this->project->initNewMapSettings();
|
||||
refresh();
|
||||
} else if (role == QDialogButtonBox::AcceptRole) {
|
||||
accept();
|
||||
}
|
||||
|
|
@ -251,7 +238,6 @@ void NewMapDialog::accept() {
|
|||
// Make sure to call each validation function so that all errors are shown at once.
|
||||
bool success = true;
|
||||
if (!ui->newLayoutForm->validate()) success = false;
|
||||
if (!validateMapID()) success = false;
|
||||
if (!validateName()) success = false;
|
||||
if (!validateGroup()) success = false;
|
||||
if (!validateLayoutID()) success = false;
|
||||
|
|
@ -261,7 +247,7 @@ void NewMapDialog::accept() {
|
|||
// Update settings from UI
|
||||
saveSettings();
|
||||
|
||||
Map *map = this->project->createNewMap(settings, this->importedMap);
|
||||
Map *map = this->project->createNewMap(this->project->newMapSettings, this->mapToCopy);
|
||||
if (!map) {
|
||||
ui->label_GenericError->setText(QString("Failed to create map. See %1 for details.").arg(getLogPath()));
|
||||
ui->label_GenericError->setVisible(true);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user