Make it easier to edit MAPSEC names, Area -> Location

This commit is contained in:
GriffinR 2024-12-28 01:51:40 -05:00
parent 72f37d8983
commit 90c904ecb9
24 changed files with 593 additions and 331 deletions

View File

@ -95,11 +95,11 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="mapListPage_Areas">
<widget class="QWidget" name="mapListPage_Locations">
<attribute name="title">
<string>Areas</string>
<string>Locations</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_Areas">
<layout class="QVBoxLayout" name="verticalLayout_Locations">
<property name="spacing">
<number>0</number>
</property>
@ -116,10 +116,10 @@
<number>0</number>
</property>
<item>
<widget class="MapListToolBar" name="mapListToolBar_Areas"/>
<widget class="MapListToolBar" name="mapListToolBar_Locations"/>
</item>
<item>
<widget class="MapTree" name="areaList">
<widget class="MapTree" name="locationList">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@ -3101,7 +3101,7 @@
<string>Ctrl+T</string>
</property>
</action>
<action name="actionSort_by_Area">
<action name="actionSort_by_Location">
<property name="checkable">
<bool>true</bool>
</property>
@ -3110,7 +3110,7 @@
<normaloff>:/icons/sort_alphabet.ico</normaloff>:/icons/sort_alphabet.ico</iconset>
</property>
<property name="text">
<string>Sort by &amp;Area</string>
<string>Sort by &amp;Location</string>
</property>
</action>
<action name="actionSort_by_Group">

View File

@ -57,14 +57,14 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="label_RequiresFlash">
<property name="text">
<string>Requires Flash</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_RequiresFlash">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, the player will need to use Flash to see fully on this map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -74,14 +74,14 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_Weather">
<property name="text">
<string>Weather</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="NoScrollComboBox" name="comboBox_Weather">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The default weather on this map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -94,14 +94,14 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label_Type">
<property name="text">
<string>Type</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="NoScrollComboBox" name="comboBox_Type">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The map type is a general attribute, which is used for many different things. For example, underground type maps will have a special transition effect when the player enters/exits the map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -114,14 +114,14 @@
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="label_BattleScene">
<property name="text">
<string>Battle Scene</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="NoScrollComboBox" name="comboBox_BattleScene">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This field is used to help determine what graphics to use in the background of battles on this map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -134,14 +134,14 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="label_ShowLocationName">
<property name="text">
<string>Show Location Name</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QCheckBox" name="checkBox_ShowLocationName">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, a map name popup will appear when the player enters this map. The name that appears on this popup depends on the Location field.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -151,14 +151,14 @@
</property>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="label_AllowRunning">
<property name="text">
<string>Allow Running</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QCheckBox" name="checkBox_AllowRunning">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, the player will be allowed to run on this map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -168,14 +168,14 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_AllowBiking">
<property name="text">
<string>Allow Biking</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QCheckBox" name="checkBox_AllowBiking">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, the player will be allowed to get on their bike on this map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -185,14 +185,14 @@
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="label_AllowEscaping">
<property name="text">
<string>Allow Dig &amp; Escape Rope</string>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="10" column="1">
<widget class="QCheckBox" name="checkBox_AllowEscaping">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If checked, the player will be allowed to use Dig or Escape Rope on this map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
@ -202,20 +202,30 @@
</property>
</widget>
</item>
<item row="10" column="0">
<item row="11" column="0">
<widget class="QLabel" name="label_FloorNumber">
<property name="text">
<string>Floor Number</string>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="11" column="1">
<widget class="NoScrollSpinBox" name="spinBox_FloorNumber">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Floor number to be used for maps with elevators.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_LocationName">
<property name="text">
<string>Location Name</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_LocationName"/>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewLocationDialog</class>
<widget class="QDialog" name="NewLocationDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>252</width>
<height>124</height>
</rect>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="form">
<layout class="QFormLayout" name="formLayout">
<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>
<item row="0" column="0">
<widget class="QLabel" name="label_IdName">
<property name="text">
<string>Location ID</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_IdName">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_IdNameError">
<property name="visible">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(255, 0, 0)</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_DisplayName"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_DisplayName">
<property name="text">
<string>Location Name</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NewNameDialog</class>
<widget class="QDialog" name="NewNameDialog">
<class>NewMapGroupDialog</class>
<widget class="QDialog" name="NewMapGroupDialog">
<property name="geometry">
<rect>
<x>0</x>
@ -32,7 +32,7 @@
<item row="0" column="0">
<widget class="QLabel" name="label_Name">
<property name="text">
<string>Name</string>
<string>Map Group Name</string>
</property>
</widget>
</item>

View File

@ -18,10 +18,10 @@
<item row="0" column="1">
<widget class="QFrame" name="frame_regionSelector">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
<enum>QFrame::Shadow::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
@ -46,14 +46,14 @@
<item>
<widget class="QComboBox" name="comboBox_regionSelector">
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
<enum>QComboBox::SizeAdjustPolicy::AdjustToContents</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -83,7 +83,7 @@
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
<enum>Qt::FocusPolicy::StrongFocus</enum>
</property>
<property name="minimum">
<number>10</number>
@ -95,10 +95,10 @@
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
<enum>QSlider::TickPosition::NoTicks</enum>
</property>
<property name="tickInterval">
<number>1</number>
@ -108,7 +108,7 @@
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -123,7 +123,7 @@
<item row="1" column="1">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="childrenCollapsible">
<bool>false</bool>
@ -160,7 +160,7 @@
<x>0</x>
<y>0</y>
<width>466</width>
<height>351</height>
<height>336</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_18">
@ -182,7 +182,7 @@
<item row="1" column="2">
<spacer name="horizontalSpacer_RMBI_East">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -207,17 +207,17 @@
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored</enum>
</property>
<property name="dragMode">
<enum>QGraphicsView::NoDrag</enum>
<enum>QGraphicsView::DragMode::NoDrag</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer_RMBI_North">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -230,7 +230,7 @@
<item row="2" column="1">
<spacer name="verticalSpacer_RMBI_South">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -243,7 +243,7 @@
<item row="1" column="0">
<spacer name="horizontalSpacer_RMBI_West">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -281,7 +281,7 @@
<x>0</x>
<y>0</y>
<width>466</width>
<height>351</height>
<height>336</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_19">
@ -315,17 +315,17 @@
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored</enum>
</property>
<property name="dragMode">
<enum>QGraphicsView::NoDrag</enum>
<enum>QGraphicsView::DragMode::NoDrag</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_RML_West">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -338,7 +338,7 @@
<item row="2" column="1">
<spacer name="verticalSpacer_RML_South">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -351,7 +351,7 @@
<item row="1" column="2">
<spacer name="horizontalSpacer_RML_East">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -364,7 +364,7 @@
<item row="0" column="1">
<spacer name="verticalSpacer_RML_North">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -402,7 +402,7 @@
<x>0</x>
<y>0</y>
<width>466</width>
<height>351</height>
<height>336</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_24">
@ -436,17 +436,17 @@
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored</enum>
</property>
<property name="dragMode">
<enum>QGraphicsView::NoDrag</enum>
<enum>QGraphicsView::DragMode::NoDrag</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_RME_West">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -459,7 +459,7 @@
<item row="2" column="1">
<spacer name="verticalSpacer_RME_South">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -472,7 +472,7 @@
<item row="1" column="2">
<spacer name="horizontalSpacer_RME_East">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -485,7 +485,7 @@
<item row="0" column="1">
<spacer name="verticalSpacer_RME_North">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -529,19 +529,19 @@
</size>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
<enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
<enum>Qt::ScrollBarPolicy::ScrollBarAsNeeded</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
<set>Qt::AlignmentFlag::AlignHCenter|Qt::AlignmentFlag::AlignTop</set>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_RM_Metatiles">
<property name="enabled">
@ -552,7 +552,7 @@
<x>8</x>
<y>0</y>
<width>278</width>
<height>342</height>
<height>327</height>
</rect>
</property>
<property name="sizePolicy">
@ -563,7 +563,7 @@
</property>
<layout class="QGridLayout" name="gridLayout_21">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
<enum>QLayout::SizeConstraint::SetDefaultConstraint</enum>
</property>
<property name="leftMargin">
<number>0</number>
@ -583,7 +583,7 @@
<item row="1" column="1">
<spacer name="verticalSpacer_RMM_South">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -596,7 +596,7 @@
<item row="0" column="2">
<spacer name="horizontalSpacer_RMM_East">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -618,20 +618,20 @@
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
<enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
<enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
<enum>QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<spacer name="horizontalSpacer_RMM_West">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -648,10 +648,10 @@
<item row="0" column="0">
<widget class="QFrame" name="frame_tileOptions">
<property name="frameShape">
<enum>QFrame::Panel</enum>
<enum>QFrame::Shape::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
<enum>QFrame::Shadow::Sunken</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
@ -681,7 +681,7 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBox_tilePalette">
<widget class="NoScrollSpinBox" name="spinBox_tilePalette">
<property name="maximum">
<number>15</number>
</property>
@ -719,10 +719,10 @@
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Shadow::Raised</enum>
</property>
<property name="lineWidth">
<number>1</number>
@ -747,7 +747,7 @@
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -760,10 +760,10 @@
<item>
<layout class="QGridLayout" name="gridLayout_22">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
<enum>QLayout::SizeConstraint::SetNoConstraint</enum>
</property>
<item row="0" column="1">
<widget class="NoScrollComboBox" name="comboBox_RM_ConnectedMap" native="true">
<widget class="NoScrollComboBox" name="comboBox_RM_ConnectedMap">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -771,10 +771,10 @@
</sizepolicy>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The section of the region map which the map is grouped under. This also determines the name of the map that is display when the player enters it.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The section of the region map which the map is grouped under. This also determines the name of the map that is displayed when the player enters it.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable" stdset="0">
<bool>true</bool>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
@ -803,7 +803,7 @@
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -816,10 +816,10 @@
<item>
<layout class="QGridLayout" name="gridLayout_8">
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_RM_LayoutHeight"/>
<widget class="NoScrollSpinBox" name="spinBox_RM_LayoutHeight"/>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_RM_LayoutWidth"/>
<widget class="NoScrollSpinBox" name="spinBox_RM_LayoutWidth"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_7">
@ -862,10 +862,10 @@
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Shadow::Raised</enum>
</property>
<property name="lineWidth">
<number>1</number>
@ -874,15 +874,15 @@
<item>
<layout class="QGridLayout" name="gridLayout_23">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
<enum>QLayout::SizeConstraint::SetNoConstraint</enum>
</property>
<item row="3" column="1">
<item row="2" column="1">
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Shadow::Raised</enum>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
@ -893,10 +893,10 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_RM_Entry_width"/>
<widget class="NoScrollSpinBox" name="spinBox_RM_Entry_width"/>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_RM_Entry_height"/>
<widget class="NoScrollSpinBox" name="spinBox_RM_Entry_height"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
@ -909,7 +909,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="NoScrollComboBox" name="comboBox_RM_Entry_MapSection" native="true">
<widget class="NoScrollComboBox" name="comboBox_RM_Entry_MapSection">
<property name="enabled">
<bool>true</bool>
</property>
@ -922,25 +922,25 @@
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The section of the region map which the map is grouped under. This also determines the name of the map that is display when the player enters it.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable" stdset="0">
<bool>true</bool>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_RM_CityMap_2">
<item row="2" column="0">
<widget class="QLabel" name="label_Dimensions">
<property name="text">
<string>Dimensions</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="1" column="1">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Shadow::Raised</enum>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
@ -951,10 +951,10 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_RM_Entry_x"/>
<widget class="NoScrollSpinBox" name="spinBox_RM_Entry_x"/>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinBox_RM_Entry_y"/>
<widget class="NoScrollSpinBox" name="spinBox_RM_Entry_y"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
@ -966,7 +966,7 @@
</layout>
</widget>
</item>
<item row="2" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_RM_Location">
<property name="text">
<string>Location</string>
@ -980,16 +980,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Map Name</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_RM_MapName"/>
</item>
</layout>
</item>
<item>
@ -1002,7 +992,7 @@
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -1037,7 +1027,7 @@
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
<enum>Qt::FocusPolicy::StrongFocus</enum>
</property>
<property name="minimum">
<number>10</number>
@ -1049,10 +1039,10 @@
<number>30</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="tickPosition">
<enum>QSlider::NoTicks</enum>
<enum>QSlider::TickPosition::NoTicks</enum>
</property>
<property name="tickInterval">
<number>1</number>
@ -1062,7 +1052,7 @@
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@ -1082,7 +1072,7 @@
<x>0</x>
<y>0</y>
<width>957</width>
<height>22</height>
<height>37</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
@ -1180,9 +1170,14 @@
<customwidgets>
<customwidget>
<class>NoScrollComboBox</class>
<extends>QWidget</extends>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
</customwidget>
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -33,7 +33,6 @@ struct LayoutSquare
struct MapSectionEntry
{
QString name = "";
int x = 0;
int y = 0;
int width = 1;

View File

@ -190,6 +190,7 @@ private slots:
void onNewMapCreated(Map *newMap, const QString &groupName);
void onNewMapGroupCreated(const QString &groupName);
void onNewMapSectionCreated(const QString &idName);
void onMapSectionDisplayNameChanged(const QString &idName, const QString &displayName);
void onNewLayoutCreated(Layout *layout);
void onNewTilesetCreated(Tileset *tileset);
void onMapLoaded(Map *map);
@ -311,8 +312,8 @@ private:
QPointer<FilterChildrenProxyModel> groupListProxyModel = nullptr;
QPointer<MapGroupModel> mapGroupModel = nullptr;
QPointer<FilterChildrenProxyModel> areaListProxyModel = nullptr;
QPointer<MapAreaModel> mapAreaModel = nullptr;
QPointer<FilterChildrenProxyModel> locationListProxyModel = nullptr;
QPointer<MapLocationModel> mapLocationModel = nullptr;
QPointer<FilterChildrenProxyModel> layoutListProxyModel = nullptr;
QPointer<LayoutTreeModel> layoutTreeModel = nullptr;
@ -357,7 +358,7 @@ private:
void openNewLayoutDialog();
void openDuplicateLayoutDialog(const QString &layoutId);
void openNewMapGroupDialog();
void openNewAreaDialog();
void openNewLocationDialog();
void openSubWindow(QWidget * window);
void scrollMapList(MapTree *list, const QString &itemName);
void scrollMapListToCurrentMap(MapTree *list);
@ -446,7 +447,7 @@ struct MapViewTab {
struct MapListTab {
enum {
Groups = 0, Areas, Layouts
Groups = 0, Locations, Layouts
};
};

View File

@ -62,6 +62,7 @@ public:
QStringList bgEventFacingDirections;
QStringList trainerTypes;
QStringList globalScriptLabels;
QStringList mapSectionIdNamesSaveOrder;
QStringList mapSectionIdNames;
QMap<QString, MapSectionEntry> regionMapEntries;
QMap<QString, QMap<QString, uint16_t>> metatileLabelsMap;
@ -79,7 +80,6 @@ public:
int pokemonMaxLevel;
int maxEncounterRate;
bool wildEncountersLoaded;
bool saveEmptyMapsec;
void set_root(QString);
@ -156,8 +156,10 @@ public:
bool readSpeciesIconPaths();
QMap<QString, QString> speciesToIconPath;
void addNewMapsec(const QString &name);
void removeMapsec(const QString &name);
void addNewMapsec(const QString &idName);
void removeMapsec(const QString &idName);
QString getMapsecDisplayName(const QString &idName) const { return this->mapSectionDisplayNames.value(idName); }
void setMapsecDisplayName(const QString &idName, const QString &displayName);
bool hasUnsavedChanges();
bool hasUnsavedDataChanges = false;
@ -253,8 +255,13 @@ public:
bool calculateDefaultMapSize();
static int getMaxObjectEvents();
static QString getEmptyMapsecName();
static QString getMapGroupPrefix();
static void numericalModeSort(QStringList &list);
private:
QMap<QString, QString> mapSectionDisplayNames;
void updateLayout(Layout *);
void setNewLayoutBlockdata(Layout *layout);
@ -282,6 +289,7 @@ signals:
void tilesetCreated(Tileset *newTileset);
void mapGroupAdded(const QString &groupName);
void mapSectionAdded(const QString &idName);
void mapSectionDisplayNameChanged(const QString &idName, const QString &displayName);
void mapSectionIdNamesChanged(const QStringList &idNames);
void mapsExcluded(const QStringList &excludedMapNames);
};

View File

@ -25,7 +25,7 @@ public:
explicit MapHeaderForm(QWidget *parent = nullptr);
~MapHeaderForm();
void init(const Project * project);
void setProject(Project * project, bool allowProjectChanges = true);
void clear();
void setHeader(MapHeader *header);
@ -34,6 +34,7 @@ public:
void setSong(const QString &song);
void setLocation(const QString &location);
void setLocationName(const QString &locationName);
void setRequiresFlash(bool requiresFlash);
void setWeather(const QString &weather);
void setType(const QString &type);
@ -46,6 +47,7 @@ public:
QString song() const;
QString location() const;
QString locationName() const;
bool requiresFlash() const;
QString weather() const;
QString type() const;
@ -56,14 +58,18 @@ public:
bool allowsEscaping() const;
int floorNumber() const;
void setLocations(QStringList locations);
private:
Ui::MapHeaderForm *ui;
QPointer<MapHeader> m_header = nullptr;
QPointer<Project> m_project = nullptr;
bool m_allowProjectChanges = true;
void setLocations(const QStringList &locations);
void updateLocationName();
void onSongUpdated(const QString &song);
void onLocationChanged(const QString &location);
void onLocationNameChanged(const QString &locationName);
void onWeatherChanged(const QString &weather);
void onTypeChanged(const QString &type);
void onBattleSceneChanged(const QString &battleScene);

View File

@ -68,7 +68,8 @@ public:
virtual QModelIndex indexOf(const QString &itemName) const;
virtual void removeItemAt(const QModelIndex &index);
virtual QStandardItem *getItem(const QModelIndex &index) const;
virtual QStandardItem *itemAt(const QModelIndex &index) const;
virtual QStandardItem *itemAt(const QString &itemName) const;
virtual QVariant data(const QModelIndex &index, int role) const override;
@ -124,12 +125,14 @@ signals:
class MapAreaModel : public MapListModel {
class MapLocationModel : public MapListModel {
Q_OBJECT
public:
MapAreaModel(Project *project, QObject *parent = nullptr);
~MapAreaModel() {}
MapLocationModel(Project *project, QObject *parent = nullptr);
~MapLocationModel() {}
QStandardItem *createMapFolderItem(const QString &folderName, QStandardItem *folder) override;
protected:
void removeItem(QStandardItem *item) override;

View File

@ -0,0 +1,34 @@
#ifndef NEWLOCATIONDIALOG_H
#define NEWLOCATIONDIALOG_H
#include <QDialog>
#include <QAbstractButton>
#include <QPointer>
class Project;
namespace Ui {
class NewLocationDialog;
}
class NewLocationDialog : public QDialog
{
Q_OBJECT
public:
explicit NewLocationDialog(Project *project = nullptr, QWidget *parent = nullptr);
~NewLocationDialog();
virtual void accept() override;
private:
Ui::NewLocationDialog *ui;
QPointer<Project> project = nullptr;
const QString namePrefix;
bool validateIdName(bool allowEmpty = false);
void onIdNameChanged(const QString &name);
void dialogButtonClicked(QAbstractButton *button);
};
#endif // NEWLOCATIONDIALOG_H

View File

@ -1,5 +1,5 @@
#ifndef NEWNAMEDIALOG_H
#define NEWNAMEDIALOG_H
#ifndef NEWMAPGROUPDIALOG_H
#define NEWMAPGROUPDIALOG_H
/*
This is a generic dialog for requesting a new unique name from the user.
@ -11,30 +11,26 @@
class Project;
namespace Ui {
class NewNameDialog;
class NewMapGroupDialog;
}
class NewNameDialog : public QDialog
class NewMapGroupDialog : public QDialog
{
Q_OBJECT
public:
explicit NewNameDialog(const QString &label, const QString &prefix = "", Project *project = nullptr, QWidget *parent = nullptr);
~NewNameDialog();
explicit NewMapGroupDialog(Project *project = nullptr, QWidget *parent = nullptr);
~NewMapGroupDialog();
virtual void accept() override;
signals:
void applied(const QString &newName);
private:
Ui::NewNameDialog *ui;
Ui::NewMapGroupDialog *ui;
Project *project = nullptr;
const QString namePrefix;
bool validateName(bool allowEmpty = false);
void onNameChanged(const QString &name);
void dialogButtonClicked(QAbstractButton *button);
};
#endif // NEWNAMEDIALOG_H
#endif // NEWMAPGROUPDIALOG_H

View File

@ -44,8 +44,6 @@ public:
bool reconfigure();
void setLocations(const QStringList &locations);
QObjectList shortcutableObjects() const;
public slots:
@ -118,6 +116,7 @@ private:
void displayRegionMapEntryOptions();
void updateRegionMapEntryOptions(QString);
void setRegionMap(RegionMap *map);
void setLocations(const QStringList &locations);
void restoreWindowState();
void closeEvent(QCloseEvent* event);
@ -135,7 +134,7 @@ private slots:
void on_tabWidget_Region_Map_currentChanged(int);
void on_pushButton_RM_Options_delete_clicked();
void on_comboBox_RM_ConnectedMap_textActivated(const QString &);
void on_comboBox_RM_Entry_MapSection_textActivated(const QString &);
void on_comboBox_RM_Entry_MapSection_currentTextChanged(const QString &);
void on_comboBox_regionSelector_textActivated(const QString &);
void on_comboBox_layoutLayer_textActivated(const QString &);
void on_spinBox_RM_Entry_x_valueChanged(int);
@ -150,7 +149,6 @@ private slots:
void on_checkBox_tileVFlip_stateChanged(int);
void on_verticalSlider_Zoom_Map_Image_valueChanged(int);
void on_verticalSlider_Zoom_Image_Tiles_valueChanged(int);
void on_lineEdit_RM_MapName_textEdited(const QString &);
void onHoveredRegionMapTileChanged(int x, int y);
void onHoveredRegionMapTileCleared();
void mouseEvent_region_map(QGraphicsSceneMouseEvent *event, RegionMapPixmapItem *item);

View File

@ -104,7 +104,8 @@ SOURCES += src/core/advancemapparser.cpp \
src/ui/neweventtoolbutton.cpp \
src/ui/newlayoutdialog.cpp \
src/ui/newlayoutform.cpp \
src/ui/newnamedialog.cpp \
src/ui/newlocationdialog.cpp \
src/ui/newmapgroupdialog.cpp \
src/ui/noscrollcombobox.cpp \
src/ui/noscrollspinbox.cpp \
src/ui/montabwidget.cpp \
@ -212,7 +213,8 @@ HEADERS += include/core/advancemapparser.h \
include/ui/neweventtoolbutton.h \
include/ui/newlayoutdialog.h \
include/ui/newlayoutform.h \
include/ui/newnamedialog.h \
include/ui/newlocationdialog.h \
include/ui/newmapgroupdialog.h \
include/ui/noscrollcombobox.h \
include/ui/noscrollspinbox.h \
include/ui/montabwidget.h \
@ -259,8 +261,9 @@ FORMS += forms/mainwindow.ui \
forms/maplisttoolbar.ui \
forms/newlayoutdialog.ui \
forms/newlayoutform.ui \
forms/newnamedialog.ui \
forms/newlocationdialog.ui \
forms/newmapconnectiondialog.ui \
forms/newmapgroupdialog.ui \
forms/prefabcreationdialog.ui \
forms/prefabframe.ui \
forms/tileseteditor.ui \

View File

@ -25,7 +25,8 @@
#include "filedialog.h"
#include "newmapdialog.h"
#include "newtilesetdialog.h"
#include "newnamedialog.h"
#include "newmapgroupdialog.h"
#include "newlocationdialog.h"
#include "message.h"
#include <QClipboard>
@ -425,32 +426,32 @@ void MainWindow::initMapList() {
// Connect tool bars to lists
ui->mapListToolBar_Groups->setList(ui->mapList);
ui->mapListToolBar_Areas->setList(ui->areaList);
ui->mapListToolBar_Locations->setList(ui->locationList);
ui->mapListToolBar_Layouts->setList(ui->layoutList);
// Left-clicking on items in the map list opens the corresponding map/layout.
connect(ui->mapList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem);
connect(ui->areaList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem);
connect(ui->layoutList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem);
connect(ui->mapList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem);
connect(ui->locationList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem);
connect(ui->layoutList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem);
// Right-clicking on items in the map list brings up a context menu.
connect(ui->mapList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu);
connect(ui->areaList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu);
connect(ui->layoutList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu);
connect(ui->mapList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu);
connect(ui->locationList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu);
connect(ui->layoutList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu);
// Only the groups list allows reorganizing folder contents, editing folder names, etc.
ui->mapListToolBar_Areas->setEditsAllowedButtonVisible(false);
ui->mapListToolBar_Locations->setEditsAllowedButtonVisible(false);
ui->mapListToolBar_Layouts->setEditsAllowedButtonVisible(false);
// When map list search filter is cleared we want the current map/layout in the editor to be visible in the list.
connect(ui->mapListToolBar_Groups, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentMap);
connect(ui->mapListToolBar_Areas, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentMap);
connect(ui->mapListToolBar_Layouts, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentLayout);
connect(ui->mapListToolBar_Groups, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentMap);
connect(ui->mapListToolBar_Locations, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentMap);
connect(ui->mapListToolBar_Layouts, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentLayout);
// Connect the "add folder" button in each of the map lists
connect(ui->mapListToolBar_Groups, &MapListToolBar::addFolderClicked, this, &MainWindow::openNewMapGroupDialog);
connect(ui->mapListToolBar_Areas, &MapListToolBar::addFolderClicked, this, &MainWindow::openNewAreaDialog);
connect(ui->mapListToolBar_Layouts, &MapListToolBar::addFolderClicked, this, &MainWindow::openNewLayoutDialog);
connect(ui->mapListToolBar_Groups, &MapListToolBar::addFolderClicked, this, &MainWindow::openNewMapGroupDialog);
connect(ui->mapListToolBar_Locations, &MapListToolBar::addFolderClicked, this, &MainWindow::openNewLocationDialog);
connect(ui->mapListToolBar_Layouts, &MapListToolBar::addFolderClicked, this, &MainWindow::openNewLayoutDialog);
connect(ui->mapListContainer, &QTabWidget::currentChanged, this, &MainWindow::saveMapListTab);
}
@ -628,7 +629,7 @@ bool MainWindow::openProject(QString dir, bool initial) {
connect(project, &Project::tilesetCreated, this, &MainWindow::onNewTilesetCreated);
connect(project, &Project::mapGroupAdded, this, &MainWindow::onNewMapGroupCreated);
connect(project, &Project::mapSectionAdded, this, &MainWindow::onNewMapSectionCreated);
connect(project, &Project::mapSectionIdNamesChanged, this, &MainWindow::setLocationComboBoxes);
connect(project, &Project::mapSectionDisplayNameChanged, this, &MainWindow::onMapSectionDisplayNameChanged);
connect(project, &Project::mapsExcluded, this, &MainWindow::showMapsExcludedAlert);
this->editor->setProject(project);
@ -1058,7 +1059,7 @@ void MainWindow::on_comboBox_LayoutSelector_currentTextChanged(const QString &te
bool MainWindow::setProjectUI() {
Project *project = editor->project;
this->mapHeaderForm->init(project);
this->mapHeaderForm->setProject(project);
// Set up project comboboxes
const QSignalBlocker b_PrimaryTileset(ui->comboBox_PrimaryTileset);
@ -1108,10 +1109,10 @@ bool MainWindow::setProjectUI() {
this->ui->mapList->setItemDelegateForColumn(0, new GroupNameDelegate(this->editor->project, this));
connect(this->mapGroupModel, &MapGroupModel::dragMoveCompleted, this->ui->mapList, &MapTree::removeSelected);
this->mapAreaModel = new MapAreaModel(editor->project);
this->areaListProxyModel = new FilterChildrenProxyModel();
areaListProxyModel->setSourceModel(this->mapAreaModel);
ui->areaList->setModel(areaListProxyModel);
this->mapLocationModel = new MapLocationModel(editor->project);
this->locationListProxyModel = new FilterChildrenProxyModel();
locationListProxyModel->setSourceModel(this->mapLocationModel);
ui->locationList->setModel(locationListProxyModel);
this->layoutTreeModel = new LayoutTreeModel(editor->project);
this->layoutListProxyModel = new FilterChildrenProxyModel();
@ -1143,8 +1144,8 @@ void MainWindow::clearProjectUI() {
// Clear map models
delete this->mapGroupModel;
delete this->groupListProxyModel;
delete this->mapAreaModel;
delete this->areaListProxyModel;
delete this->mapLocationModel;
delete this->locationListProxyModel;
delete this->layoutTreeModel;
delete this->layoutListProxyModel;
resetMapListFilters();
@ -1197,14 +1198,14 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
QAction* addToFolderAction = nullptr;
QAction* deleteFolderAction = nullptr;
QAction* openItemAction = nullptr;
QAction* copyDisplayNameAction = nullptr;
QAction* copyListNameAction = nullptr;
QAction* copyToolTipAction = nullptr;
if (itemType == "map_name") {
// Right-clicking on a map.
openItemAction = menu.addAction("Open Map");
menu.addSeparator();
copyDisplayNameAction = menu.addAction("Copy Map Name");
copyListNameAction = menu.addAction("Copy Map Name");
copyToolTipAction = menu.addAction("Copy Map ID");
menu.addSeparator();
connect(menu.addAction("Duplicate Map"), &QAction::triggered, [this, itemName] {
@ -1219,18 +1220,19 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
deleteFolderAction = menu.addAction("Delete Map Group");
} else if (itemType == "map_section") {
// Right-clicking on a MAPSEC folder
addToFolderAction = menu.addAction("Add New Map to Area");
addToFolderAction = menu.addAction("Add New Map to Location");
menu.addSeparator();
copyDisplayNameAction = menu.addAction("Copy Area Name");
copyListNameAction = menu.addAction("Copy Location ID Name");
copyToolTipAction = menu.addAction("Copy Location In-Game Name");
menu.addSeparator();
deleteFolderAction = menu.addAction("Delete Area");
deleteFolderAction = menu.addAction("Delete Location");
if (itemName == this->editor->project->getEmptyMapsecName())
deleteFolderAction->setEnabled(false); // Disallow deleting the default name
} else if (itemType == "map_layout") {
// Right-clicking on a map layout
openItemAction = menu.addAction("Open Layout");
menu.addSeparator();
copyDisplayNameAction = menu.addAction("Copy Layout Name");
copyListNameAction = menu.addAction("Copy Layout Name");
copyToolTipAction = menu.addAction("Copy Layout ID");
menu.addSeparator();
connect(menu.addAction("Duplicate Layout"), &QAction::triggered, [this, itemName] {
@ -1263,8 +1265,8 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
openMapListItem(index);
});
}
if (copyDisplayNameAction) {
connect(copyDisplayNameAction, &QAction::triggered, [this, selectedItem] {
if (copyListNameAction) {
connect(copyListNameAction, &QAction::triggered, [this, selectedItem] {
setClipboardData(selectedItem->text());
});
}
@ -1278,18 +1280,6 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) {
menu.exec(QCursor::pos());
}
void MainWindow::openNewMapGroupDialog() {
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", projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix), this->editor->project, this);
connect(dialog, &NewNameDialog::applied, this->editor->project, &Project::addNewMapsec);
dialog->open();
}
void MainWindow::onNewMapCreated(Map *newMap, const QString &groupName) {
logInfo(QString("Created a new map named %1.").arg(newMap->name()));
@ -1301,7 +1291,7 @@ void MainWindow::onNewMapCreated(Map *newMap, const QString &groupName) {
// Add new map to the map lists
this->mapGroupModel->insertMapItem(newMap->name(), groupName);
this->mapAreaModel->insertMapItem(newMap->name(), newMap->header()->location());
this->mapLocationModel->insertMapItem(newMap->name(), newMap->header()->location());
this->layoutTreeModel->insertMapItem(newMap->name(), newMap->layout()->id);
// Refresh any combo box that displays map names and persists between maps
@ -1344,14 +1334,14 @@ void MainWindow::onNewMapGroupCreated(const QString &groupName) {
}
void MainWindow::onNewMapSectionCreated(const QString &idName) {
// Add new map section to the Areas map list view
this->mapAreaModel->insertMapFolderItem(idName);
// Add new map section to the Locations map list view
this->mapLocationModel->insertMapFolderItem(idName);
}
void MainWindow::setLocationComboBoxes(const QStringList &locations) {
this->mapHeaderForm->setLocations(locations);
if (this->regionMapEditor)
this->regionMapEditor->setLocations(locations);
void MainWindow::onMapSectionDisplayNameChanged(const QString &idName, const QString &displayName) {
// Update the tool tip in the map list that shows the MAPSEC's in-game name.
QStandardItem *item = this->mapLocationModel->itemAt(idName);
if (item) item->setToolTip(displayName);
}
void MainWindow::onNewTilesetCreated(Tileset *tileset) {
@ -1371,6 +1361,16 @@ void MainWindow::onNewTilesetCreated(Tileset *tileset) {
}
}
void MainWindow::openNewMapGroupDialog() {
auto dialog = new NewMapGroupDialog(this->editor->project, this);
dialog->open();
}
void MainWindow::openNewLocationDialog() {
auto dialog = new NewLocationDialog(this->editor->project, this);
dialog->open();
}
void MainWindow::openNewMapDialog() {
auto dialog = new NewMapDialog(this->editor->project, this);
dialog->open();
@ -1505,7 +1505,7 @@ void MainWindow::updateMapList() {
activeItemName = this->editor->map->name();
} else {
ui->mapList->clearSelection();
ui->areaList->clearSelection();
ui->locationList->clearSelection();
if (this->editor->layout) {
activeItemName = this->editor->layout->id;
@ -1515,11 +1515,11 @@ void MainWindow::updateMapList() {
}
this->mapGroupModel->setActiveItem(activeItemName);
this->mapAreaModel->setActiveItem(activeItemName);
this->mapLocationModel->setActiveItem(activeItemName);
this->layoutTreeModel->setActiveItem(activeItemName);
this->groupListProxyModel->layoutChanged();
this->areaListProxyModel->layoutChanged();
this->locationListProxyModel->layoutChanged();
this->layoutListProxyModel->layoutChanged();
}
@ -1813,6 +1813,7 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index)
clickToolButtonFromEditAction(editor->objectEditAction);
} else if (index == MainTab::Connections) {
editor->setEditingConnections();
ui->graphicsView_Connections->setFocus(); // Avoid opening tab with focus on something editable
} else if (index == MainTab::WildPokemon) {
editor->setEditingEncounters();
}
@ -2706,9 +2707,9 @@ void MainWindow::initTilesetEditor() {
MapListToolBar* MainWindow::getCurrentMapListToolBar() {
switch (ui->mapListContainer->currentIndex()) {
case MapListTab::Groups: return ui->mapListToolBar_Groups;
case MapListTab::Areas: return ui->mapListToolBar_Areas;
case MapListTab::Layouts: return ui->mapListToolBar_Layouts;
case MapListTab::Groups: return ui->mapListToolBar_Groups;
case MapListTab::Locations: return ui->mapListToolBar_Locations;
case MapListTab::Layouts: return ui->mapListToolBar_Layouts;
default: return nullptr;
}
}
@ -2724,7 +2725,7 @@ MapTree* MainWindow::getCurrentMapList() {
// When the search filter is cleared the map lists will (if possible) display the currently-selected map/layout.
void MainWindow::resetMapListFilters() {
ui->mapListToolBar_Groups->clearFilter();
ui->mapListToolBar_Areas->clearFilter();
ui->mapListToolBar_Locations->clearFilter();
ui->mapListToolBar_Layouts->clearFilter();
}

View File

@ -727,16 +727,16 @@ void Project::saveRegionMapSections() {
const QString emptyMapsecName = getEmptyMapsecName();
OrderedJson::array mapSectionArray;
for (const auto &idName : this->mapSectionIdNames) {
if (!this->saveEmptyMapsec && idName == emptyMapsecName)
continue;
for (const auto &idName : this->mapSectionIdNamesSaveOrder) {
OrderedJson::object mapSectionObj;
mapSectionObj["id"] = idName;
if (this->mapSectionDisplayNames.contains(idName)) {
mapSectionObj["name"] = this->mapSectionDisplayNames.value(idName);
}
if (this->regionMapEntries.contains(idName)) {
MapSectionEntry entry = this->regionMapEntries.value(idName);
mapSectionObj["name"] = entry.name;
mapSectionObj["x"] = entry.x;
mapSectionObj["y"] = entry.y;
mapSectionObj["width"] = entry.width;
@ -2129,8 +2129,8 @@ bool Project::readTilesetLabels() {
}
}
this->primaryTilesetLabels.sort();
this->secondaryTilesetLabels.sort();
numericalModeSort(this->primaryTilesetLabels);
numericalModeSort(this->secondaryTilesetLabels);
bool success = true;
if (this->secondaryTilesetLabels.isEmpty()) {
@ -2332,8 +2332,9 @@ bool Project::readFieldmapMasks() {
bool Project::readRegionMapSections() {
this->mapSectionIdNames.clear();
this->mapSectionIdNamesSaveOrder.clear();
this->mapSectionDisplayNames.clear();
this->regionMapEntries.clear();
this->saveEmptyMapsec = false;
const QString defaultName = getEmptyMapsecName();
const QString requiredPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix);
@ -2371,17 +2372,15 @@ bool Project::readRegionMapSections() {
}
this->mapSectionIdNames.append(idName);
if (idName == defaultName) {
// The default map section (MAPSEC_NONE) isn't normally present in the region map sections data file.
// We append this name to mapSectionIdNames ourselves if it isn't present.
// We need to record whether we found it in the data file, so that we can preserve the data when we save the file later.
this->saveEmptyMapsec = true;
}
this->mapSectionIdNamesSaveOrder.append(idName);
if (mapSectionObj.contains("name"))
this->mapSectionDisplayNames.insert(idName, ParseUtil::jsonToQString(mapSectionObj["name"]));
// Map sections may have additional data indicating their position on the region map.
// If they have this data, we can add them to the region map entry list.
bool hasRegionMapData = true;
static const QSet<QString> regionMapFieldNames = { "name", "x", "y", "width", "height" };
static const QSet<QString> regionMapFieldNames = { "x", "y", "width", "height" };
for (auto fieldName : regionMapFieldNames) {
if (!mapSectionObj.contains(fieldName)) {
hasRegionMapData = false;
@ -2392,7 +2391,6 @@ bool Project::readRegionMapSections() {
continue;
MapSectionEntry entry;
entry.name = ParseUtil::jsonToQString(mapSectionObj["name"]);
entry.x = ParseUtil::jsonToInt(mapSectionObj["x"]);
entry.y = ParseUtil::jsonToInt(mapSectionObj["y"]);
entry.width = ParseUtil::jsonToInt(mapSectionObj["width"]);
@ -2405,6 +2403,7 @@ bool Project::readRegionMapSections() {
if (!this->mapSectionIdNames.contains(defaultName)) {
this->mapSectionIdNames.append(defaultName);
}
numericalModeSort(this->mapSectionIdNames);
return true;
}
@ -2413,29 +2412,47 @@ QString Project::getEmptyMapsecName() {
return projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix) + projectConfig.getIdentifier(ProjectIdentifier::define_map_section_empty);
}
QString Project::getMapGroupPrefix() {
// We could expose this to users, but it's never enforced so it probably won't affect anyone.
return QStringLiteral("gMapGroup_");
}
// This function assumes a valid and unique name
void Project::addNewMapsec(const QString &name) {
if (this->mapSectionIdNames.last() == getEmptyMapsecName()) {
void Project::addNewMapsec(const QString &idName) {
if (this->mapSectionIdNamesSaveOrder.last() == getEmptyMapsecName()) {
// If the default map section name (MAPSEC_NONE) is last in the list we'll keep it last in the list.
this->mapSectionIdNames.insert(this->mapSectionIdNames.length() - 1, name);
this->mapSectionIdNamesSaveOrder.insert(this->mapSectionIdNames.length() - 1, idName);
} else {
this->mapSectionIdNames.append(name);
this->mapSectionIdNamesSaveOrder.append(idName);
}
this->mapSectionIdNames.append(idName);
numericalModeSort(this->mapSectionIdNames);
this->hasUnsavedDataChanges = true;
emit mapSectionAdded(name);
emit mapSectionAdded(idName);
emit mapSectionIdNamesChanged(this->mapSectionIdNames);
}
void Project::removeMapsec(const QString &name) {
if (!this->mapSectionIdNames.contains(name) || name == getEmptyMapsecName())
void Project::removeMapsec(const QString &idName) {
if (!this->mapSectionIdNames.contains(idName) || idName == getEmptyMapsecName())
return;
this->mapSectionIdNames.removeOne(name);
this->mapSectionIdNames.removeOne(idName);
this->mapSectionIdNamesSaveOrder.removeOne(idName);
this->hasUnsavedDataChanges = true;
emit mapSectionIdNamesChanged(this->mapSectionIdNames);
}
void Project::setMapsecDisplayName(const QString &idName, const QString &displayName) {
if (this->mapSectionDisplayNames[idName] == displayName)
return;
this->mapSectionDisplayNames[idName] = displayName;
this->hasUnsavedDataChanges = true;
emit mapSectionDisplayNameChanged(idName, displayName);
}
// Read the constants to preserve any "unused" heal locations when writing the file later
bool Project::readHealLocationConstants() {
this->healLocationNameToValue.clear();
@ -2704,7 +2721,7 @@ bool Project::readSongNames() {
// Song names don't have a very useful order (esp. if we include SE_* values), so sort them alphabetically.
// The default song should be the first in the list, not the first alphabetically, so save that before sorting.
this->defaultSong = this->songNames.value(0, "0");
this->songNames.sort();
numericalModeSort(this->songNames);
return true;
}
@ -3139,3 +3156,14 @@ bool Project::hasUnsavedChanges() {
}
return false;
}
// TODO: This belongs in a more general utility file, once we have one.
// Sometimes we want to sort names alphabetically to make them easier to find in large combo box lists.
// QStringList::sort (as of writing) can only sort numbers in lexical order, which has an undesirable
// effect (e.g. MAPSEC_ROUTE_10 comes after MAPSEC_ROUTE_1, rather than MAPSEC_ROUTE_9).
// We can use QCollator to sort these lists with better handling for numbers.
void Project::numericalModeSort(QStringList &list) {
QCollator collator;
collator.setNumericMode(true);
std::sort(list.begin(), list.end(), collator);
}

View File

@ -12,18 +12,24 @@ MapHeaderForm::MapHeaderForm(QWidget *parent)
ui->spinBox_FloorNumber->setMinimum(INT_MIN);
ui->spinBox_FloorNumber->setMaximum(INT_MAX);
// When the UI is updated, sync those changes to the tracked MapHeader (if there is one)
// The layout for this UI keeps fields at their size hint, which is a little short for the line edit.
ui->lineEdit_LocationName->setMinimumWidth(ui->comboBox_Location->sizeHint().width());
connect(ui->comboBox_Song, &QComboBox::currentTextChanged, this, &MapHeaderForm::onSongUpdated);
connect(ui->comboBox_Location, &QComboBox::currentTextChanged, this, &MapHeaderForm::onLocationChanged);
connect(ui->comboBox_Weather, &QComboBox::currentTextChanged, this, &MapHeaderForm::onWeatherChanged);
connect(ui->comboBox_Type, &QComboBox::currentTextChanged, this, &MapHeaderForm::onTypeChanged);
connect(ui->comboBox_BattleScene, &QComboBox::currentTextChanged, this, &MapHeaderForm::onBattleSceneChanged);
connect(ui->checkBox_RequiresFlash, &QCheckBox::stateChanged, this, &MapHeaderForm::onRequiresFlashChanged);
connect(ui->checkBox_ShowLocationName, &QCheckBox::stateChanged, this, &MapHeaderForm::onShowLocationNameChanged);
connect(ui->checkBox_AllowRunning, &QCheckBox::stateChanged, this, &MapHeaderForm::onAllowRunningChanged);
connect(ui->checkBox_AllowBiking, &QCheckBox::stateChanged, this, &MapHeaderForm::onAllowBikingChanged);
connect(ui->checkBox_AllowEscaping, &QCheckBox::stateChanged, this, &MapHeaderForm::onAllowEscapingChanged);
connect(ui->spinBox_FloorNumber, QOverload<int>::of(&QSpinBox::valueChanged), this, &MapHeaderForm::onFloorNumberChanged);
connect(ui->lineEdit_LocationName, &QLineEdit::textChanged, this, &MapHeaderForm::onLocationNameChanged);
}
MapHeaderForm::~MapHeaderForm()
@ -31,35 +37,39 @@ MapHeaderForm::~MapHeaderForm()
delete ui;
}
void MapHeaderForm::init(const Project * project) {
void MapHeaderForm::setProject(Project * project, bool allowChanges) {
clear();
if (!project)
if (m_project) {
m_project->disconnect(this);
}
m_project = project;
m_allowProjectChanges = allowChanges;
if (!m_project)
return;
// Populate combo boxes
const QSignalBlocker b_Song(ui->comboBox_Song);
ui->comboBox_Song->clear();
ui->comboBox_Song->addItems(project->songNames);
ui->comboBox_Song->addItems(m_project->songNames);
const QSignalBlocker b_Weather(ui->comboBox_Weather);
ui->comboBox_Weather->clear();
ui->comboBox_Weather->addItems(project->weatherNames);
ui->comboBox_Weather->addItems(m_project->weatherNames);
const QSignalBlocker b_Type(ui->comboBox_Type);
ui->comboBox_Type->clear();
ui->comboBox_Type->addItems(project->mapTypes);
ui->comboBox_Type->addItems(m_project->mapTypes);
const QSignalBlocker b_BattleScene(ui->comboBox_BattleScene);
ui->comboBox_BattleScene->clear();
ui->comboBox_BattleScene->addItems(project->mapBattleScenes);
ui->comboBox_BattleScene->addItems(m_project->mapBattleScenes);
QStringList locations = project->mapSectionIdNames;
locations.sort();
const QSignalBlocker b_Locations(ui->comboBox_Location);
ui->comboBox_Location->clear();
ui->comboBox_Location->addItems(locations);
ui->comboBox_Location->addItems(m_project->mapSectionIdNames);
// Hide config-specific settings
@ -74,12 +84,13 @@ void MapHeaderForm::init(const Project * project) {
bool floorNumEnabled = projectConfig.floorNumberEnabled;
ui->spinBox_FloorNumber->setVisible(floorNumEnabled);
ui->label_FloorNumber->setVisible(floorNumEnabled);
// If the project changes any of the displayed data, update it accordingly.
connect(m_project, &Project::mapSectionIdNamesChanged, this, &MapHeaderForm::setLocations);
connect(m_project, &Project::mapSectionDisplayNameChanged, this, &MapHeaderForm::updateLocationName);
}
// Unlike other combo boxes in the map header form, locations can be added or removed externally.
void MapHeaderForm::setLocations(QStringList locations) {
locations.sort();
void MapHeaderForm::setLocations(const QStringList &locations) {
const QSignalBlocker b(ui->comboBox_Location);
const QString before = ui->comboBox_Location->currentText();
ui->comboBox_Location->clear();
@ -136,6 +147,7 @@ void MapHeaderForm::setHeaderData(const MapHeader &header) {
setAllowsBiking(header.allowsBiking());
setAllowsEscaping(header.allowsEscaping());
setFloorNumber(header.floorNumber());
updateLocationName();
}
MapHeader MapHeaderForm::headerData() const {
@ -158,9 +170,14 @@ MapHeader MapHeaderForm::headerData() const {
return header;
}
void MapHeaderForm::updateLocationName() {
setLocationName(m_project ? m_project->getMapsecDisplayName(location()) : QString());
}
// Set data in UI
void MapHeaderForm::setSong(const QString &song) { ui->comboBox_Song->setCurrentText(song); }
void MapHeaderForm::setLocation(const QString &location) { ui->comboBox_Location->setCurrentText(location); }
void MapHeaderForm::setLocationName(const QString &locationName) { ui->lineEdit_LocationName->setText(locationName); }
void MapHeaderForm::setRequiresFlash(bool requiresFlash) { ui->checkBox_RequiresFlash->setChecked(requiresFlash); }
void MapHeaderForm::setWeather(const QString &weather) { ui->comboBox_Weather->setCurrentText(weather); }
void MapHeaderForm::setType(const QString &type) { ui->comboBox_Type->setCurrentText(type); }
@ -174,6 +191,7 @@ void MapHeaderForm::setFloorNumber(int floorNumber) { ui->spinBox_F
// Read data from UI
QString MapHeaderForm::song() const { return ui->comboBox_Song->currentText(); }
QString MapHeaderForm::location() const { return ui->comboBox_Location->currentText(); }
QString MapHeaderForm::locationName() const { return ui->lineEdit_LocationName->text(); }
bool MapHeaderForm::requiresFlash() const { return ui->checkBox_RequiresFlash->isChecked(); }
QString MapHeaderForm::weather() const { return ui->comboBox_Weather->currentText(); }
QString MapHeaderForm::type() const { return ui->comboBox_Type->currentText(); }
@ -186,7 +204,6 @@ int MapHeaderForm::floorNumber() const { return ui->spinBox_FloorNumber->
// Send changes in UI to tracked MapHeader (if there is one)
void MapHeaderForm::onSongUpdated(const QString &song) { if (m_header) m_header->setSong(song); }
void MapHeaderForm::onLocationChanged(const QString &location) { if (m_header) m_header->setLocation(location); }
void MapHeaderForm::onWeatherChanged(const QString &weather) { if (m_header) m_header->setWeather(weather); }
void MapHeaderForm::onTypeChanged(const QString &type) { if (m_header) m_header->setType(type); }
void MapHeaderForm::onBattleSceneChanged(const QString &battleScene) { if (m_header) m_header->setBattleScene(battleScene); }
@ -196,3 +213,14 @@ void MapHeaderForm::onAllowRunningChanged(int selected) { if (m_hea
void MapHeaderForm::onAllowBikingChanged(int selected) { if (m_header) m_header->setAllowsBiking(selected == Qt::Checked); }
void MapHeaderForm::onAllowEscapingChanged(int selected) { if (m_header) m_header->setAllowsEscaping(selected == Qt::Checked); }
void MapHeaderForm::onFloorNumberChanged(int offset) { if (m_header) m_header->setFloorNumber(offset); }
void MapHeaderForm::onLocationChanged(const QString &location) {
if (m_header) m_header->setLocation(location);
updateLocationName();
}
void MapHeaderForm::onLocationNameChanged(const QString &locationName) {
if (m_project && m_allowProjectChanges) {
// The location name is actually part of the project, not the map header.
// If the field is changed in the UI we can push these changes to the project.
m_project->setMapsecDisplayName(location(), locationName);
}
}

View File

@ -56,7 +56,7 @@ MapListModel::MapListModel(Project *project, QObject *parent) : QStandardItemMod
this->emptyMapFolderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On);
}
QStandardItem *MapListModel::getItem(const QModelIndex &index) const {
QStandardItem *MapListModel::itemAt(const QModelIndex &index) const {
if (index.isValid()) {
QStandardItem *item = static_cast<QStandardItem*>(index.internalPointer());
if (item)
@ -65,6 +65,13 @@ QStandardItem *MapListModel::getItem(const QModelIndex &index) const {
return this->root;
}
QStandardItem *MapListModel::itemAt(const QString &itemName) const {
QModelIndex index = this->indexOf(itemName);
if (!index.isValid())
return nullptr;
return this->itemAt(index)->child(index.row(), index.column());
}
QModelIndex MapListModel::indexOf(const QString &itemName) const {
if (this->mapItems.contains(itemName))
return this->mapItems.value(itemName)->index();
@ -76,7 +83,7 @@ QModelIndex MapListModel::indexOf(const QString &itemName) const {
}
void MapListModel::removeItemAt(const QModelIndex &index) {
QStandardItem *item = this->getItem(index)->child(index.row(), index.column());
QStandardItem *item = this->itemAt(index)->child(index.row(), index.column());
if (!item)
return;
@ -153,7 +160,7 @@ QVariant MapListModel::data(const QModelIndex &index, int role) const {
int row = index.row();
int col = index.column();
const QStandardItem *item = this->getItem(index)->child(row, col);
const QStandardItem *item = this->itemAt(index)->child(row, col);
const QString type = item->data(MapListUserRoles::TypeRole).toString();
const QString name = item->data(MapListUserRoles::NameRole).toString();
@ -179,7 +186,7 @@ QVariant MapListModel::data(const QModelIndex &index, int role) const {
QWidget *GroupNameDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const {
QLineEdit *editor = new QLineEdit(parent);
editor->setPlaceholderText("gMapGroup_");
editor->setPlaceholderText(Project::getMapGroupPrefix());
editor->setValidator(new IdentifierValidator(parent));
editor->setFrame(false);
return editor;
@ -388,13 +395,13 @@ QVariant MapGroupModel::data(const QModelIndex &index, int role) const {
int row = index.row();
int col = index.column();
const QStandardItem *item = this->getItem(index)->child(row, col);
const QStandardItem *item = this->itemAt(index)->child(row, col);
const QString type = item->data(MapListUserRoles::TypeRole).toString();
const QString name = item->data(MapListUserRoles::NameRole).toString();
if (role == Qt::DisplayRole) {
if (type == "map_name") {
return QString("[%1.%2] ").arg(this->getItem(index)->row()).arg(row, 2, 10, QLatin1Char('0')) + name;
return QString("[%1.%2] ").arg(this->itemAt(index)->row()).arg(row, 2, 10, QLatin1Char('0')) + name;
}
else if (type == this->folderTypeName) {
return name;
@ -417,7 +424,7 @@ bool MapGroupModel::setData(const QModelIndex &index, const QVariant &value, int
MapAreaModel::MapAreaModel(Project *project, QObject *parent) : MapListModel(project, parent) {
MapLocationModel::MapLocationModel(Project *project, QObject *parent) : MapListModel(project, parent) {
this->folderTypeName = "map_section";
for (const auto &idName : this->project->mapSectionIdNames) {
@ -431,11 +438,17 @@ MapAreaModel::MapAreaModel(Project *project, QObject *parent) : MapListModel(pro
sort(0, Qt::AscendingOrder);
}
void MapAreaModel::removeItem(QStandardItem *item) {
void MapLocationModel::removeItem(QStandardItem *item) {
this->project->removeMapsec(item->data(MapListUserRoles::NameRole).toString());
this->removeRow(item->row());
}
QStandardItem *MapLocationModel::createMapFolderItem(const QString &folderName, QStandardItem *folder) {
folder = MapListModel::createMapFolderItem(folderName, folder);
folder->setToolTip(this->project->getMapsecDisplayName(folderName));
return folder;
}
LayoutTreeModel::LayoutTreeModel(Project *project, QObject *parent) : MapListModel(project, parent) {
@ -477,7 +490,7 @@ QVariant LayoutTreeModel::data(const QModelIndex &index, int role) const {
int row = index.row();
int col = index.column();
const QStandardItem *item = this->getItem(index)->child(row, col);
const QStandardItem *item = this->itemAt(index)->child(row, col);
const QString type = item->data(MapListUserRoles::TypeRole).toString();
const QString name = item->data(MapListUserRoles::NameRole).toString();

View File

@ -0,0 +1,79 @@
#include "newlocationdialog.h"
#include "ui_newlocationdialog.h"
#include "project.h"
#include "validator.h"
const QString lineEdit_ErrorStylesheet = "QLineEdit { background-color: rgba(255, 0, 0, 25%) }";
NewLocationDialog::NewLocationDialog(Project* project, QWidget *parent) :
QDialog(parent),
ui(new Ui::NewLocationDialog),
namePrefix(projectConfig.getIdentifier(ProjectIdentifier::define_map_section_prefix))
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
this->project = project;
ui->lineEdit_IdName->setValidator(new IdentifierValidator(namePrefix, this));
ui->lineEdit_IdName->setText(namePrefix);
connect(ui->lineEdit_IdName, &QLineEdit::textChanged, this, &NewLocationDialog::onIdNameChanged);
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewLocationDialog::dialogButtonClicked);
adjustSize();
}
NewLocationDialog::~NewLocationDialog()
{
delete ui;
}
void NewLocationDialog::onIdNameChanged(const QString &idName) {
validateIdName(true);
// Extract a presumed display name from the ID name
QString displayName = idName;
if (displayName.startsWith(namePrefix))
displayName.remove(0, namePrefix.length());
displayName.replace("_", " ");
ui->lineEdit_DisplayName->setText(displayName);
}
bool NewLocationDialog::validateIdName(bool allowEmpty) {
const QString name = ui->lineEdit_IdName->text();
QString errorText;
if (name.isEmpty() || name == namePrefix) {
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_IdName->text());
} else if (!this->project->isIdentifierUnique(name)) {
errorText = QString("%1 '%2' is not unique.").arg(ui->label_IdName->text()).arg(name);
}
bool isValid = errorText.isEmpty();
ui->label_IdNameError->setText(errorText);
ui->label_IdNameError->setVisible(!isValid);
ui->lineEdit_IdName->setStyleSheet(!isValid ? lineEdit_ErrorStylesheet : "");
return isValid;
}
void NewLocationDialog::dialogButtonClicked(QAbstractButton *button) {
auto role = ui->buttonBox->buttonRole(button);
if (role == QDialogButtonBox::RejectRole){
reject();
} else if (role == QDialogButtonBox::AcceptRole) {
accept();
}
}
void NewLocationDialog::accept() {
if (!validateIdName())
return;
const QString idName = ui->lineEdit_IdName->text();
const QString displayName = ui->lineEdit_DisplayName->text();
this->project->addNewMapsec(idName);
this->project->setMapsecDisplayName(idName, displayName);
QDialog::accept();
}

View File

@ -53,7 +53,7 @@ NewMapDialog::NewMapDialog(Project *project, const Map *mapToCopy, QWidget *pare
// Create a collapsible section that has all the map header data.
this->headerForm = new MapHeaderForm();
this->headerForm->init(project);
this->headerForm->setProject(project, false);
auto sectionLayout = new QVBoxLayout();
sectionLayout->addWidget(this->headerForm);
@ -77,13 +77,13 @@ NewMapDialog::NewMapDialog(Project *project, int mapListTab, const QString &mapL
case MapListTab::Groups:
ui->comboBox_Group->setTextItem(mapListItem);
break;
case MapListTab::Areas:
case MapListTab::Locations:
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.
// For the Group/Location settings above we don't care if the user changes them afterwards.
ui->comboBox_LayoutID->setTextItem(mapListItem);
ui->comboBox_LayoutID->setDisabled(true);
break;
@ -252,5 +252,9 @@ void NewMapDialog::accept() {
return;
}
ui->label_GenericError->setVisible(false);
// If the location name field was changed, update the project for that too.
this->project->setMapsecDisplayName(this->headerForm->location(), this->headerForm->locationName());
QDialog::accept();
}

View File

@ -1,48 +1,43 @@
#include "newnamedialog.h"
#include "ui_newnamedialog.h"
#include "newmapgroupdialog.h"
#include "ui_newmapgroupdialog.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, const QString &prefix, Project* project, QWidget *parent) :
NewMapGroupDialog::NewMapGroupDialog(Project* project, QWidget *parent) :
QDialog(parent),
ui(new Ui::NewNameDialog),
namePrefix(prefix)
ui(new Ui::NewMapGroupDialog)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
this->project = project;
if (!label.isEmpty())
ui->label_Name->setText(label);
ui->lineEdit_Name->setValidator(new IdentifierValidator(this));
ui->lineEdit_Name->setText(Project::getMapGroupPrefix());
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);
connect(ui->lineEdit_Name, &QLineEdit::textChanged, this, &NewMapGroupDialog::onNameChanged);
connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &NewMapGroupDialog::dialogButtonClicked);
adjustSize();
}
NewNameDialog::~NewNameDialog()
NewMapGroupDialog::~NewMapGroupDialog()
{
delete ui;
}
void NewNameDialog::onNameChanged(const QString &) {
void NewMapGroupDialog::onNameChanged(const QString &) {
validateName(true);
}
bool NewNameDialog::validateName(bool allowEmpty) {
bool NewMapGroupDialog::validateName(bool allowEmpty) {
const QString name = ui->lineEdit_Name->text();
QString errorText;
if (name.isEmpty() || name == namePrefix) {
if (name.isEmpty()) {
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_Name->text());
} else if (this->project && !this->project->isIdentifierUnique(name)) {
} else if (!this->project->isIdentifierUnique(name)) {
errorText = QString("%1 '%2' is not unique.").arg(ui->label_Name->text()).arg(name);
}
@ -53,7 +48,7 @@ bool NewNameDialog::validateName(bool allowEmpty) {
return isValid;
}
void NewNameDialog::dialogButtonClicked(QAbstractButton *button) {
void NewMapGroupDialog::dialogButtonClicked(QAbstractButton *button) {
auto role = ui->buttonBox->buttonRole(button);
if (role == QDialogButtonBox::RejectRole){
reject();
@ -62,10 +57,11 @@ void NewNameDialog::dialogButtonClicked(QAbstractButton *button) {
}
}
void NewNameDialog::accept() {
void NewMapGroupDialog::accept() {
if (!validateName())
return;
emit applied(ui->lineEdit_Name->text());
this->project->addNewMapGroup(ui->lineEdit_Name->text());
QDialog::accept();
}

View File

@ -293,7 +293,7 @@ QStringList ProjectSettingsEditor::getWarpBehaviorsList() {
void ProjectSettingsEditor::setWarpBehaviorsList(QStringList list) {
list.removeDuplicates();
list.sort();
Project::numericalModeSort(list);
ui->textEdit_WarpBehaviors->setText(list.join("\n"));
}

View File

@ -28,6 +28,7 @@ RegionMapEditor::RegionMapEditor(QWidget *parent, Project *project) :
this->setAttribute(Qt::WA_DeleteOnClose);
this->ui->setupUi(this);
this->project = project;
connect(this->project, &Project::mapSectionIdNamesChanged, this, &RegionMapEditor::setLocations);
this->configFilepath = QString("%1/%2").arg(this->project->root).arg(projectConfig.getFilePath(ProjectFilePath::json_region_porymap_cfg));
this->initShortcuts();
this->restoreWindowState();
@ -728,8 +729,12 @@ void RegionMapEditor::displayRegionMapEntryOptions() {
void RegionMapEditor::updateRegionMapEntryOptions(QString section) {
if (!this->region_map->layoutEnabled()) return;
const QSignalBlocker b_X(this->ui->spinBox_RM_Entry_x);
const QSignalBlocker b_Y(this->ui->spinBox_RM_Entry_y);
const QSignalBlocker b_W(this->ui->spinBox_RM_Entry_width);
const QSignalBlocker b_H(this->ui->spinBox_RM_Entry_height);
bool enabled = (section != this->region_map->default_map_section) && this->region_map_entries.contains(section);
this->ui->lineEdit_RM_MapName->setEnabled(enabled);
this->ui->spinBox_RM_Entry_x->setEnabled(enabled);
this->ui->spinBox_RM_Entry_y->setEnabled(enabled);
this->ui->spinBox_RM_Entry_width->setEnabled(enabled);
@ -737,56 +742,31 @@ void RegionMapEditor::updateRegionMapEntryOptions(QString section) {
this->ui->pushButton_entryActivate->setEnabled(section != this->region_map->default_map_section);
this->ui->pushButton_entryActivate->setText(enabled ? "Remove" : "Add");
this->ui->lineEdit_RM_MapName->blockSignals(true);
this->ui->spinBox_RM_Entry_x->blockSignals(true);
this->ui->spinBox_RM_Entry_y->blockSignals(true);
this->ui->spinBox_RM_Entry_width->blockSignals(true);
this->ui->spinBox_RM_Entry_height->blockSignals(true);
this->ui->comboBox_RM_Entry_MapSection->setCurrentText(section);
this->activeEntry = section;
this->region_map_entries_item->currentSection = section;
MapSectionEntry entry = enabled ? this->region_map_entries[section] : MapSectionEntry();
this->ui->lineEdit_RM_MapName->setText(entry.name);
this->ui->spinBox_RM_Entry_x->setValue(entry.x);
this->ui->spinBox_RM_Entry_y->setValue(entry.y);
this->ui->spinBox_RM_Entry_width->setValue(entry.width);
this->ui->spinBox_RM_Entry_height->setValue(entry.height);
this->ui->lineEdit_RM_MapName->blockSignals(false);
this->ui->spinBox_RM_Entry_x->blockSignals(false);
this->ui->spinBox_RM_Entry_y->blockSignals(false);
this->ui->spinBox_RM_Entry_width->blockSignals(false);
this->ui->spinBox_RM_Entry_height->blockSignals(false);
}
void RegionMapEditor::on_pushButton_entryActivate_clicked() {
QString section = this->ui->comboBox_RM_Entry_MapSection->currentText();
if (section == this->region_map->default_map_section) return;
MapSectionEntry oldEntry = this->region_map->getEntry(section);
if (this->region_map_entries.contains(section)) {
// disable
MapSectionEntry oldEntry = this->region_map->getEntry(section);
this->region_map->removeEntry(section);
MapSectionEntry newEntry = this->region_map->getEntry(section);
RemoveEntry *commit = new RemoveEntry(this->region_map, section, oldEntry, newEntry);
this->region_map->editHistory.push(commit);
updateRegionMapEntryOptions(section);
this->ui->pushButton_entryActivate->setText("Add");
this->region_map->editHistory.push(new RemoveEntry(this->region_map, section, oldEntry, MapSectionEntry()));
} else {
// enable
MapSectionEntry oldEntry = this->region_map->getEntry(section);
MapSectionEntry entry = MapSectionEntry();
entry.valid = true;
this->region_map->setEntry(section, entry);
MapSectionEntry newEntry = this->region_map->getEntry(section);
AddEntry *commit = new AddEntry(this->region_map, section, oldEntry, newEntry);
this->region_map->editHistory.push(commit);
updateRegionMapEntryOptions(section);
this->ui->pushButton_entryActivate->setText("Remove");
MapSectionEntry newEntry = MapSectionEntry();
newEntry.valid = true;
this->region_map->editHistory.push(new AddEntry(this->region_map, section, oldEntry, newEntry));
}
updateRegionMapEntryOptions(section);
}
void RegionMapEditor::displayRegionMapTileSelector() {
@ -932,7 +912,7 @@ void RegionMapEditor::on_tabWidget_Region_Map_currentChanged(int index) {
break;
case 2:
this->ui->verticalSlider_Zoom_Image_Tiles->setVisible(false);
on_comboBox_RM_Entry_MapSection_textActivated(ui->comboBox_RM_Entry_MapSection->currentText());
on_comboBox_RM_Entry_MapSection_currentTextChanged(ui->comboBox_RM_Entry_MapSection->currentText());
break;
}
}
@ -943,7 +923,7 @@ void RegionMapEditor::on_comboBox_RM_ConnectedMap_textActivated(const QString &m
onRegionMapLayoutSelectedTileChanged(this->currIndex);// re-draw layout image
}
void RegionMapEditor::on_comboBox_RM_Entry_MapSection_textActivated(const QString &text) {
void RegionMapEditor::on_comboBox_RM_Entry_MapSection_currentTextChanged(const QString &text) {
this->activeEntry = text;
this->region_map_entries_item->currentSection = text;
updateRegionMapEntryOptions(text);
@ -1046,15 +1026,6 @@ void RegionMapEditor::on_spinBox_RM_LayoutHeight_valueChanged(int value) {
}
}
void RegionMapEditor::on_lineEdit_RM_MapName_textEdited(const QString &text) {
if (!this->region_map_entries.contains(activeEntry)) return;
MapSectionEntry oldEntry = this->region_map_entries[activeEntry];
this->region_map_entries[activeEntry].name = text;
MapSectionEntry newEntry = this->region_map_entries[activeEntry];
EditEntry *commit = new EditEntry(this->region_map, activeEntry, oldEntry, newEntry);
this->region_map->editHistory.push(commit);
}
void RegionMapEditor::on_pushButton_RM_Options_delete_clicked() {
int index = this->region_map->tilemapToLayoutIndex(this->currIndex);
QList<LayoutSquare> oldLayout = this->region_map->getLayout(this->region_map->getLayer());
@ -1147,7 +1118,7 @@ void RegionMapEditor::on_action_Swap_triggered() {
connect(&buttonBox, &QDialogButtonBox::accepted, [&popup, &oldSecBox, &newSecBox, &beforeSection, &afterSection](){
beforeSection = oldSecBox->currentText();
afterSection = newSecBox->currentText();
if (!beforeSection.isEmpty() && !afterSection.isEmpty()) {
if (!beforeSection.isEmpty() && !afterSection.isEmpty() && beforeSection != afterSection) {
popup.accept();
}
});
@ -1186,7 +1157,7 @@ void RegionMapEditor::on_action_Replace_triggered() {
connect(&buttonBox, &QDialogButtonBox::accepted, [&popup, &oldSecBox, &newSecBox, &beforeSection, &afterSection](){
beforeSection = oldSecBox->currentText();
afterSection = newSecBox->currentText();
if (!beforeSection.isEmpty() && !afterSection.isEmpty()) {
if (!beforeSection.isEmpty() && !afterSection.isEmpty() && beforeSection != afterSection) {
popup.accept();
}
});

View File

@ -8,7 +8,7 @@ void RegionMapEntriesPixmapItem::draw() {
int entry_x, entry_y, entry_w, entry_h;
if (!entry.valid || entry.name == region_map->default_map_section) {
if (!entry.valid || currentSection == region_map->default_map_section) {
entry_x = entry_y = 0;
entry_w = entry_h = 1;
} else {