Merge branch 'dev' into version-check

This commit is contained in:
GriffinR
2025-05-04 15:09:12 -04:00
committed by GitHub
36 changed files with 339 additions and 562 deletions

View File

@@ -103,6 +103,7 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
- Fix exporting a timelapse sometimes altering the state of the current map's edit history.
- Stop sliders in the Palette Editor from creating a bunch of edit history when used.
- Fix scrolling on some containers locking up when the mouse stops over a spin box or combo box.
- Fix the selection index for some combo boxes differing from their displayed text.
- Fix some file dialogs returning to an incorrect window when closed.
- Fix bug where reloading a layout would overwrite all unsaved changes.
- Fix bug where layout json and blockdata could be saved separately leading to inconsistent data.

View File

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>383</width>
<width>388</width>
<height>121</height>
</rect>
</property>
@@ -53,6 +53,9 @@
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>

View File

@@ -1,319 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EventPropertiesFrame</class>
<widget class="QFrame" name="EventPropertiesFrame">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>284</width>
<height>146</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>284</width>
<height>90</height>
</size>
</property>
<property name="windowTitle">
<string>Frame</string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_spritePixmap">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="indent">
<number>-1</number>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSpinBox" name="spinBox_index">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>The index of the event currently being inspected.</string>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_name">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Id</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QHBoxLayout" name="x">
<item>
<widget class="QLabel" name="label_x">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="NoScrollSpinBox" name="spinBox_x">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The X coordinate of this object.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>-32768</number>
</property>
<property name="maximum">
<number>32767</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="y">
<item>
<widget class="QLabel" name="label_y">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="NoScrollSpinBox" name="spinBox_y">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The Y coordinate of this object.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>-32768</number>
</property>
<property name="maximum">
<number>32767</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="z">
<item>
<widget class="QLabel" name="label_z">
<property name="text">
<string>Z</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="NoScrollSpinBox" name="spinBox_z">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The elevation of this object.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="maximum">
<number>15</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="sprite" native="true">
<layout class="QFormLayout" name="formLayout_sprite">
<property name="rowWrapPolicy">
<enum>QFormLayout::WrapLongRows</enum>
</property>
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_sprite">
<property name="text">
<string>Sprite</string>
</property>
<property name="buddy">
<cstring>comboBox_sprite</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="NoScrollComboBox" name="comboBox_sprite">
<property name="enabled">
<bool>true</bool>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The sprite graphics to use for this object.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="editable">
<bool>true</bool>
</property>
<property name="currentText">
<string/>
</property>
<property name="maxVisibleItems">
<number>25</number>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContentsOnFirstShow</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
</customwidget>
<customwidget>
<class>NoScrollSpinBox</class>
<extends>QSpinBox</extends>
<header>noscrollspinbox.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>spinBox_x</tabstop>
<tabstop>spinBox_y</tabstop>
<tabstop>spinBox_z</tabstop>
<tabstop>comboBox_sprite</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -3,7 +3,7 @@
<class>LoadingScreen</class>
<widget class="QWidget" name="LoadingScreen">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
<enum>Qt::WindowModality::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
@@ -17,7 +17,7 @@
<cursorShape>BusyCursor</cursorShape>
</property>
<property name="contextMenuPolicy">
<enum>Qt::NoContextMenu</enum>
<enum>Qt::ContextMenuPolicy::NoContextMenu</enum>
</property>
<property name="windowTitle">
<string>Form</string>
@@ -35,7 +35,7 @@
<string>porymap</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
@@ -50,14 +50,14 @@
<string>Version X.x.x</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -70,16 +70,16 @@
<item>
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
<enum>QFrame::Shape::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
<enum>QFrame::Shadow::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -105,7 +105,7 @@
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
@@ -121,7 +121,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>
@@ -134,23 +134,16 @@
<item>
<widget class="QFrame" name="frame">
<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="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="labelLoading">
<property name="text">
<string>Loading.....</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="labelText">
<property name="text">
<string>TextLabel</string>
<string>Loading....</string>
</property>
</widget>
</item>

View File

@@ -2733,7 +2733,10 @@
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_EncounterGroupLabel">
<widget class="NoScrollComboBox" name="comboBox_EncounterGroupLabel">
<property name="editable">
<bool>false</bool>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::SizeAdjustPolicy::AdjustToContents</enum>
</property>

View File

@@ -10,6 +10,9 @@
<height>380</height>
</rect>
</property>
<property name="focusPolicy">
<enum>Qt::FocusPolicy::ClickFocus</enum>
</property>
<property name="windowTitle">
<string>Form</string>
</property>

View File

@@ -197,7 +197,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox_Species">
<widget class="NoScrollComboBox" name="comboBox_Species">
<property name="editable">
<bool>true</bool>
</property>
@@ -237,6 +237,11 @@
<extends>QGraphicsView</extends>
<header>QtCharts</header>
</customwidget>
<customwidget>
<class>NoScrollComboBox</class>
<extends>QComboBox</extends>
<header>noscrollcombobox.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../resources/images.qrc"/>

View File

@@ -34,15 +34,6 @@ class HiddenItemEvent;
class SecretBaseEvent;
class HealLocationEvent;
class EventVisitor {
public:
virtual void nothing() { }
virtual void visitObject(ObjectEvent *) = 0;
virtual void visitTrigger(TriggerEvent *) = 0;
virtual void visitSign(SignEvent *) = 0;
};
///
/// Event base class -- purely virtual
///
@@ -121,8 +112,6 @@ public:
void modify();
virtual void accept(EventVisitor *) { }
void setX(int newX) { this->x = newX; }
void setY(int newY) { this->y = newY; }
void setZ(int newZ) { this->elevation = newZ; }
@@ -150,6 +139,8 @@ public:
virtual QSet<QString> getExpectedFields() = 0;
virtual QStringList getScripts() const { return QStringList(); }
QJsonObject getCustomAttributes() const { return this->customAttributes; }
void setCustomAttributes(const QJsonObject &newCustomAttributes) { this->customAttributes = newCustomAttributes; }
@@ -222,8 +213,6 @@ public:
virtual Event *duplicate() const override;
virtual void accept(EventVisitor *visitor) override { visitor->visitObject(this); }
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
@@ -233,6 +222,8 @@ public:
virtual QSet<QString> getExpectedFields() override;
virtual QStringList getScripts() const override { return {getScript()}; }
virtual QPixmap loadPixmap(Project *project) override;
void setGfx(QString newGfx) { this->gfx = newGfx; }
@@ -392,8 +383,6 @@ public:
virtual Event *duplicate() const override;
virtual void accept(EventVisitor *visitor) override { visitor->visitTrigger(this); }
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
@@ -403,6 +392,8 @@ public:
virtual QSet<QString> getExpectedFields() override;
virtual QStringList getScripts() const override { return {getScriptLabel()}; }
void setScriptVar(QString newScriptVar) { this->scriptVar = newScriptVar; }
QString getScriptVar() const { return this->scriptVar; }
@@ -490,8 +481,6 @@ public:
virtual Event *duplicate() const override;
virtual void accept(EventVisitor *visitor) override { visitor->visitSign(this); }
virtual EventFrame *createEventFrame() override;
virtual OrderedJson::object buildEventJson(Project *project) override;
@@ -501,6 +490,8 @@ public:
virtual QSet<QString> getExpectedFields() override;
virtual QStringList getScripts() const override { return {getScriptLabel()}; }
void setFacingDirection(QString newFacingDirection) { this->facingDirection = newFacingDirection; }
QString getFacingDirection() const { return this->facingDirection; }
@@ -633,21 +624,4 @@ inline uint qHash(const Event::Group &key, uint seed = 0) {
return qHash(static_cast<int>(key), seed);
}
///
/// Keeps track of scripts
///
class ScriptTracker : public EventVisitor {
public:
virtual void visitObject(ObjectEvent *object) override { this->scripts << object->getScript(); };
virtual void visitTrigger(TriggerEvent *trigger) override { this->scripts << trigger->getScriptLabel(); };
virtual void visitSign(SignEvent *sign) override { this->scripts << sign->getScriptLabel(); };
QStringList getScripts() const { return this->scripts; }
private:
QStringList scripts;
};
#endif // EVENTS_H

View File

@@ -13,6 +13,7 @@
#include <QPixmap>
#include <QObject>
#include <QGraphicsPixmapItem>
#include <QFileSystemWatcher>
#include <math.h>
#define DEFAULT_BORDER_WIDTH 2
@@ -56,7 +57,7 @@ public:
MapHeader* header() const { return m_header; }
void setSharedEventsMap(const QString &sharedEventsMap) { m_sharedEventsMap = sharedEventsMap; }
void setSharedScriptsMap(const QString &sharedScriptsMap) { m_sharedScriptsMap = sharedScriptsMap; }
void setSharedScriptsMap(const QString &sharedScriptsMap);
QString sharedEventsMap() const { return m_sharedEventsMap; }
QString sharedScriptsMap() const { return m_sharedScriptsMap; }
@@ -75,14 +76,15 @@ public:
Event* getEvent(Event::Group group, const QString &idName) const;
QStringList getEventIdNames(Event::Group group) const;
int getNumEvents(Event::Group group = Event::Group::None) const;
QStringList getScriptLabels(Event::Group group = Event::Group::None);
QString getScriptsFilePath() const;
void openScript(QString label);
void removeEvent(Event *);
void addEvent(Event *);
int getIndexOfEvent(Event *) const;
bool hasEvent(Event *) const;
QStringList getScriptLabels(Event::Group group = Event::Group::None);
QString getScriptsFilePath() const;
void openScript(const QString &label);
void deleteConnections();
QList<MapConnection*> getConnections() const { return m_connections; }
MapConnection* getConnection(const QString &direction) const;
@@ -108,7 +110,7 @@ private:
QString m_sharedEventsMap = "";
QString m_sharedScriptsMap = "";
QStringList m_scriptsFileLabels;
QStringList m_scriptLabels;
QJsonObject m_customAttributes;
MapHeader *m_header = nullptr;
@@ -131,10 +133,14 @@ private:
QList<MapConnection*> m_connections;
QSet<MapConnection*> m_ownedConnections;
QUndoStack *m_editHistory = nullptr;
QPointer<QUndoStack> m_editHistory;
QPointer<QFileSystemWatcher> m_scriptFileWatcher;
void invalidateScripts();
signals:
void modified();
void scriptsModified();
void mapDimensionsChanged(const QSize &size);
void openScriptRequested(QString label);
void connectionAdded(MapConnection*);

View File

@@ -43,8 +43,13 @@ class ParseUtil
{
public:
ParseUtil();
void setRoot(const QString &dir) { this->root = dir; }
void setUpdatesSplashScreen(bool updates) { this->updatesSplashScreen = updates; }
static QString readTextFile(const QString &path, QString *error = nullptr);
QString loadTextFile(const QString &path, QString *error = nullptr);
bool cacheFile(const QString &path, QString *error = nullptr);
void clearFileCache() { this->fileCache.clear(); }
static int textFileLineCount(const QString &path);
@@ -105,6 +110,8 @@ private:
QHash<QString, int> globalDefineValues;
QHash<QString, QString> globalDefineExpressions;
bool updatesSplashScreen = false;
int evaluateDefine(const QString &identifier, bool *ok = nullptr);
int evaluateExpression(const QString &expression);
QList<Token> tokenizeExpression(QString expression);
@@ -114,6 +121,7 @@ private:
void recordErrors(const QStringList &errors);
void logRecordedErrors();
QString createErrorMessage(const QString &message, const QString &expression);
void updateSplashScreen(QString path);
struct ParsedDefines {
QHash<QString,QString> expressions; // Map of all define names encountered to their expressions
@@ -123,7 +131,6 @@ private:
QHash<QString, int> evaluateCDefines(const QString &filename, const QSet<QString> &filterList, bool useRegex, QString *error);
bool defineNameMatchesFilter(const QString &name, const QSet<QString> &filterList) const;
bool defineNameMatchesFilter(const QString &name, const QSet<QRegularExpression> &filterList) const;
QString loadTextFile(const QString &path, QString *error = nullptr);
QString pathWithRoot(const QString &path);
static const QRegularExpression re_incScriptLabel;

View File

@@ -67,9 +67,9 @@ public:
bool saveTilesImage();
bool savePalettes();
bool appendToHeaders(QString root, QString friendlyName, bool usingAsm);
bool appendToGraphics(QString root, QString friendlyName, bool usingAsm);
bool appendToMetatiles(QString root, QString friendlyName, bool usingAsm);
bool appendToHeaders(const QString &filepath, const QString &friendlyName, bool usingAsm);
bool appendToGraphics(const QString &filepath, const QString &friendlyName, bool usingAsm);
bool appendToMetatiles(const QString &filepath, const QString &friendlyName, bool usingAsm);
void setTilesImage(const QImage &image);

View File

@@ -309,7 +309,10 @@ private:
void setNewLayoutBlockdata(Layout *layout);
void setNewLayoutBorder(Layout *layout);
void ignoreWatchedFileTemporarily(QString filepath);
void watchFile(const QString &filename);
void watchFiles(const QStringList &filenames);
void ignoreWatchedFileTemporarily(const QString &filepath);
void ignoreWatchedFilesTemporarily(const QStringList &filepaths);
void recordFileChange(const QString &filepath);
void resetFileCache();

View File

@@ -2,6 +2,7 @@
#define DIVINGMAPPIXMAPITEM_H
#include "mapconnection.h"
#include "noscrollcombobox.h"
#include <QGraphicsPixmapItem>
#include <QPointer>
@@ -10,7 +11,7 @@
class DivingMapPixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
public:
DivingMapPixmapItem(MapConnection *connection, QComboBox *combo);
DivingMapPixmapItem(MapConnection *connection, NoScrollComboBox *combo);
~DivingMapPixmapItem();
MapConnection* connection() const { return m_connection; }
@@ -18,7 +19,7 @@ public:
private:
QPointer<MapConnection> m_connection;
QPointer<QComboBox> m_combo;
QPointer<NoScrollComboBox> m_combo;
void setComboText(const QString &text);
static QPixmap getBasePixmap(MapConnection* connection);

View File

@@ -56,9 +56,11 @@ protected:
bool populated = false;
bool initialized = false;
bool connected = false;
QPointer<Project> project;
void populateDropdown(NoScrollComboBox * combo, const QStringList &items);
void populateScriptDropdown(NoScrollComboBox * combo, Project * project);
void populateMapNameDropdown(NoScrollComboBox * combo, Project * project);
void populateIdNameDropdown(NoScrollComboBox * combo, Project * project, const QString &mapName, Event::Group group);
private:

View File

@@ -18,8 +18,10 @@ public:
explicit PorymapLoadingScreen(QWidget *parent = nullptr);
~PorymapLoadingScreen();
void setPixmap(QPixmap pixmap);
void showMessage(QString text);
void setPixmap(const QPixmap &pixmap);
void showMessage(const QString &text);
void showMessage(const QString &prefix, const QString &text);
void showLoadingMessage(const QString &text);
void start();
void stop ();

View File

@@ -12,6 +12,7 @@
#include "mapheader.h"
#include "project.h"
#include "noscrollcombobox.h"
namespace Ui {
class MapHeaderForm;
@@ -64,7 +65,7 @@ private:
QPointer<Project> m_project = nullptr;
bool m_allowProjectChanges = true;
void setText(QComboBox *combo, const QString &text) const;
void setText(NoScrollComboBox *combo, const QString &text) const;
void setText(QLineEdit *lineEdit, const QString &text) const;
void setLocations(const QStringList &locations);
void updateLocationName();

View File

@@ -114,7 +114,7 @@ QString Event::typeToString(Event::Type type) {
}
QPixmap Event::loadPixmap(Project *project) {
this->pixmap = project->getEventPixmap(this->getEventGroup());
this->pixmap = project ? project->getEventPixmap(this->getEventGroup()) : QPixmap();
this->usesDefaultPixmap = true;
return this->pixmap;
}
@@ -226,7 +226,7 @@ QSet<QString> ObjectEvent::getExpectedFields() {
}
QPixmap ObjectEvent::loadPixmap(Project *project) {
this->pixmap = project->getEventPixmap(this->gfx, this->movement);
this->pixmap = project ? project->getEventPixmap(this->gfx, this->movement) : QPixmap();
if (!this->pixmap.isNull()) {
this->usesDefaultPixmap = false;
return this->pixmap;
@@ -316,7 +316,7 @@ QSet<QString> CloneObjectEvent::getExpectedFields() {
QPixmap CloneObjectEvent::loadPixmap(Project *project) {
// Try to get the targeted object to clone
Map *clonedMap = project->loadMap(this->targetMap);
Map *clonedMap = project ? project->loadMap(this->targetMap) : nullptr;
Event *clonedEvent = clonedMap ? clonedMap->getEvent(Event::Group::Object, this->targetID) : nullptr;
if (clonedEvent && clonedEvent->getEventType() == Event::Type::Object) {
@@ -324,10 +324,13 @@ QPixmap CloneObjectEvent::loadPixmap(Project *project) {
ObjectEvent *clonedObject = dynamic_cast<ObjectEvent *>(clonedEvent);
this->gfx = clonedObject->getGfx();
this->movement = clonedObject->getMovement();
} else {
} else if (project) {
// Invalid object specified, use default graphics data (as would be shown in-game)
this->gfx = project->gfxDefines.key(0, "0");
this->movement = project->movementTypes.value(0, "0");
} else {
this->gfx = "0";
this->movement = "0";
}
return ObjectEvent::loadPixmap(project);
}

View File

@@ -14,6 +14,10 @@
Map::Map(QObject *parent) : QObject(parent)
{
m_editHistory = new QUndoStack(this);
m_scriptFileWatcher = new QFileSystemWatcher(this);
connect(m_scriptFileWatcher, &QFileSystemWatcher::fileChanged, this, &Map::invalidateScripts);
resetEvents();
m_header = new MapHeader(this);
@@ -120,35 +124,40 @@ QPixmap Map::renderConnection(const QString &direction, Layout * fromLayout) {
return connectionPixmap.copy(bounds.x() * 16, bounds.y() * 16, bounds.width() * 16, bounds.height() * 16);
}
void Map::openScript(QString label) {
void Map::openScript(const QString &label) {
emit openScriptRequested(label);
}
void Map::setSharedScriptsMap(const QString &sharedScriptsMap) {
if (m_sharedScriptsMap == sharedScriptsMap)
return;
m_sharedScriptsMap = sharedScriptsMap;
invalidateScripts();
}
void Map::invalidateScripts() {
m_scriptsLoaded = false;
emit scriptsModified();
}
QStringList Map::getScriptLabels(Event::Group group) {
if (!m_scriptsLoaded) {
m_scriptsFileLabels = ParseUtil::getGlobalScriptLabels(getScriptsFilePath());
const QString scriptsFilePath = getScriptsFilePath();
m_scriptLabels = ParseUtil::getGlobalScriptLabels(scriptsFilePath);
m_scriptsLoaded = true;
// Track the scripts file for changes. Path may have changed, so stop tracking old files.
m_scriptFileWatcher->removePaths(m_scriptFileWatcher->files());
m_scriptFileWatcher->addPath(scriptsFilePath);
}
QStringList scriptLabels;
QStringList scriptLabels = m_scriptLabels;
// Get script labels currently in-use by the map's events
if (group == Event::Group::None) {
ScriptTracker scriptTracker;
for (const auto &event : getEvents()) {
event->accept(&scriptTracker);
}
scriptLabels = scriptTracker.getScripts();
} else {
ScriptTracker scriptTracker;
for (const auto &event : m_events.value(group)) {
event->accept(&scriptTracker);
}
scriptLabels = scriptTracker.getScripts();
// Add script labels currently in-use by the map's events
for (const auto &event : getEvents(group)) {
scriptLabels.append(event->getScripts());
}
// Add labels from the map's scripts file
scriptLabels.append(m_scriptsFileLabels);
scriptLabels.sort(Qt::CaseInsensitive);
scriptLabels.removeAll("");
scriptLabels.removeAll("0");

View File

@@ -56,9 +56,17 @@ QString ParseUtil::createErrorMessage(const QString &message, const QString &exp
return QString("%1:%2:%3: %4").arg(this->file).arg(lineNum).arg(colNum).arg(message);
}
void ParseUtil::updateSplashScreen(QString path) {
if (!this->updatesSplashScreen)
return;
if (path.startsWith(this->root)) {
path.remove(0, this->root.length());
}
porysplash->showLoadingMessage(path);
}
QString ParseUtil::readTextFile(const QString &path, QString *error) {
// splash screen message
porysplash->showMessage(path);
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
if (error) *error = file.errorString();
@@ -80,6 +88,8 @@ QString ParseUtil::readTextFile(const QString &path, QString *error) {
// Note that this doesn't insert any parsed files into the file cache, and we don't
// want it to (we read a lot of files only once, storing them all is a waste of memory).
QString ParseUtil::loadTextFile(const QString &path, QString *error) {
updateSplashScreen(path);
auto it = this->fileCache.constFind(path);
if (it != this->fileCache.constEnd()) {
// Load text file from cache
@@ -89,6 +99,8 @@ QString ParseUtil::loadTextFile(const QString &path, QString *error) {
}
bool ParseUtil::cacheFile(const QString &path, QString *error) {
updateSplashScreen(path);
this->fileCache.insert(path, readTextFile(pathWithRoot(path), error));
return !error || error->isEmpty();
}
@@ -732,6 +744,8 @@ QStringList ParseUtil::getLabelValues(const QList<QStringList> &list, const QStr
}
bool ParseUtil::tryParseJsonFile(QJsonDocument *out, const QString &filepath, QString *error) {
updateSplashScreen(filepath);
QFile file(pathWithRoot(filepath));
if (!file.open(QIODevice::ReadOnly)) {
if (error) *error = file.errorString();

View File

@@ -249,12 +249,10 @@ QList<QRgb> Tileset::getPalette(int paletteId, Tileset *primaryTileset, Tileset
return paletteTable;
}
bool Tileset::appendToHeaders(QString root, QString friendlyName, bool usingAsm) {
QString headersFile = root + "/" + (usingAsm ? projectConfig.getFilePath(ProjectFilePath::tilesets_headers_asm)
: projectConfig.getFilePath(ProjectFilePath::tilesets_headers));
QFile file(headersFile);
bool Tileset::appendToHeaders(const QString &filepath, const QString &friendlyName, bool usingAsm) {
QFile file(filepath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
logError(QString("Could not write to file \"%1\"").arg(headersFile));
logError(QString("Could not write to file \"%1\"").arg(filepath));
return false;
}
QString isSecondaryStr = this->is_secondary ? "TRUE" : "FALSE";
@@ -294,12 +292,10 @@ bool Tileset::appendToHeaders(QString root, QString friendlyName, bool usingAsm)
return true;
}
bool Tileset::appendToGraphics(QString root, QString friendlyName, bool usingAsm) {
QString graphicsFile = root + "/" + (usingAsm ? projectConfig.getFilePath(ProjectFilePath::tilesets_graphics_asm)
: projectConfig.getFilePath(ProjectFilePath::tilesets_graphics));
QFile file(graphicsFile);
bool Tileset::appendToGraphics(const QString &filepath, const QString &friendlyName, bool usingAsm) {
QFile file(filepath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
logError(QString("Could not write to file \"%1\"").arg(graphicsFile));
logError(QString("Could not write to file \"%1\"").arg(filepath));
return false;
}
@@ -332,12 +328,10 @@ bool Tileset::appendToGraphics(QString root, QString friendlyName, bool usingAsm
return true;
}
bool Tileset::appendToMetatiles(QString root, QString friendlyName, bool usingAsm) {
QString metatileFile = root + "/" + (usingAsm ? projectConfig.getFilePath(ProjectFilePath::tilesets_metatiles_asm)
: projectConfig.getFilePath(ProjectFilePath::tilesets_metatiles));
QFile file(metatileFile);
bool Tileset::appendToMetatiles(const QString &filepath, const QString &friendlyName, bool usingAsm) {
QFile file(filepath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
logError(QString("Could not write to file \"%1\"").arg(metatileFile));
logError(QString("Could not write to file \"%1\"").arg(filepath));
return false;
}

View File

@@ -238,7 +238,7 @@ void Editor::displayWildMonTables() {
labelComboStrings.sort();
labelCombo->addItems(labelComboStrings);
labelCombo->setCurrentText(labelCombo->itemText(0));
labelCombo->setCurrentIndex(0);
QStackedWidget *stack = ui->stackedWidget_WildMons;
int labelIndex = 0;
@@ -495,7 +495,9 @@ void Editor::configureEncounterJSON(QWidget *window) {
QFrame *slotChoiceFrame = new QFrame;
QVBoxLayout *slotChoiceLayout = new QVBoxLayout;
if (useGroups) {
QComboBox *groupCombo = new QComboBox;
auto groupCombo = new NoScrollComboBox;
groupCombo->setEditable(false);
groupCombo->setMinimumContentsLength(10);
connect(groupCombo, QOverload<const QString &>::of(&QComboBox::textActivated), [&tempFields, &currentField, &updateTotal, index](QString newGroupName) {
for (EncounterField &field : tempFields) {
if (field.name == currentField.name) {
@@ -526,7 +528,7 @@ void Editor::configureEncounterJSON(QWidget *window) {
break;
}
}
groupCombo->setCurrentText(currentGroupName);
groupCombo->setTextItem(currentGroupName);
slotChoiceLayout->addWidget(groupCombo);
}
slotChoiceLayout->addWidget(chanceSpinner);
@@ -982,7 +984,7 @@ QString Editor::getDivingMapName(const QString &direction) const {
void Editor::onDivingMapEditingFinished(NoScrollComboBox *combo, const QString &direction) {
if (!setDivingMapName(combo->currentText(), direction)) {
// If user input was invalid, restore the combo to the previously-valid text.
combo->setCurrentText(getDivingMapName(direction));
combo->setTextItem(getDivingMapName(direction));
}
}
@@ -1163,7 +1165,7 @@ void Editor::onHoveredMapMetatileChanged(const QPoint &pos) {
void Editor::onHoveredMapMetatileCleared() {
this->setCursorRectVisible(false);
if (!map_item->getEditsEnabled()) {
if (map_item->getEditsEnabled()) {
this->ui->statusBar->clearMessage();
}
Scripting::cb_BlockHoverCleared();
@@ -1281,8 +1283,8 @@ bool Editor::setLayout(QString layoutId) {
ui->comboBox_PrimaryTileset->blockSignals(true);
ui->comboBox_SecondaryTileset->blockSignals(true);
ui->comboBox_PrimaryTileset->setCurrentText(this->layout->tileset_primary_label);
ui->comboBox_SecondaryTileset->setCurrentText(this->layout->tileset_secondary_label);
ui->comboBox_PrimaryTileset->setTextItem(this->layout->tileset_primary_label);
ui->comboBox_SecondaryTileset->setTextItem(this->layout->tileset_secondary_label);
ui->comboBox_PrimaryTileset->blockSignals(false);
ui->comboBox_SecondaryTileset->blockSignals(false);

View File

@@ -657,13 +657,15 @@ bool MainWindow::openProject(QString dir, bool initial) {
this->statusBar()->showMessage(openMessage);
logInfo(openMessage);
porysplash->start();
porysplash->showLoadingMessage("config");
userConfig.projectDir = dir;
userConfig.load();
projectConfig.projectDir = dir;
projectConfig.load();
porysplash->start();
porysplash->showLoadingMessage("custom scripts");
Scripting::init(this);
// Create the project
@@ -681,6 +683,7 @@ bool MainWindow::openProject(QString dir, bool initial) {
this->editor->setProject(project);
// Make sure project looks reasonable before attempting to load it
porysplash->showMessage("Verifying project");
if (isInvalidProject(this->editor->project)) {
delete this->editor->project;
porysplash->stop();
@@ -719,6 +722,7 @@ bool MainWindow::openProject(QString dir, bool initial) {
}
bool MainWindow::loadProjectData() {
porysplash->showLoadingMessage("project");
bool success = editor->project->load();
Scripting::populateGlobalObject(this);
return success;
@@ -786,6 +790,12 @@ bool MainWindow::checkProjectVersion(Project *project) {
}
void MainWindow::showProjectOpenFailure() {
if (!this->isVisible()){
// The main window is not visible during the initial project open; the splash screen is busy providing visual feedback.
// If project opening fails we can immediately display the empty main window (which we need anyway to parent messages to).
restoreWindowState();
show();
}
RecentErrorMessage::show(QStringLiteral("There was an error opening the project."), this);
}
@@ -807,6 +817,8 @@ bool MainWindow::isProjectOpen() {
}
bool MainWindow::setInitialMap() {
porysplash->showMessage("Opening initial map");
const QString recent = userConfig.recentMapOrLayout;
if (editor->project->mapNames.contains(recent)) {
// User recently had a map open that still exists.
@@ -1182,8 +1194,8 @@ void MainWindow::displayMapProperties() {
const QSignalBlocker b_PrimaryTileset(ui->comboBox_PrimaryTileset);
const QSignalBlocker b_SecondaryTileset(ui->comboBox_SecondaryTileset);
ui->comboBox_PrimaryTileset->setCurrentText(editor->map->layout()->tileset_primary_label);
ui->comboBox_SecondaryTileset->setCurrentText(editor->map->layout()->tileset_secondary_label);
ui->comboBox_PrimaryTileset->setTextItem(editor->map->layout()->tileset_primary_label);
ui->comboBox_SecondaryTileset->setTextItem(editor->map->layout()->tileset_secondary_label);
ui->mapCustomAttributesFrame->table()->setAttributes(editor->map->customAttributes());
}
@@ -1203,7 +1215,7 @@ void MainWindow::on_comboBox_LayoutSelector_currentTextChanged(const QString &te
// New layout failed to load, restore previous layout
const QSignalBlocker b(ui->comboBox_LayoutSelector);
ui->comboBox_LayoutSelector->setCurrentText(this->editor->map->layout()->id);
ui->comboBox_LayoutSelector->setTextItem(this->editor->map->layout()->id);
return;
}
this->editor->map->setLayout(layout);
@@ -1219,12 +1231,14 @@ void MainWindow::onLayoutSelectorEditingFinished() {
const QString text = ui->comboBox_LayoutSelector->currentText();
if (!this->editor->project->mapLayouts.contains(text)) {
const QSignalBlocker b(ui->comboBox_LayoutSelector);
ui->comboBox_LayoutSelector->setCurrentText(this->editor->layout->id);
ui->comboBox_LayoutSelector->setTextItem(this->editor->layout->id);
}
}
// Update the UI using information we've read from the user's project files.
bool MainWindow::setProjectUI() {
porysplash->showLoadingMessage("project UI");
Project *project = editor->project;
this->mapHeaderForm->setProject(project);
@@ -2722,7 +2736,7 @@ void MainWindow::openWildMonTable(const QString &mapName, const QString &groupNa
if (userSetMap(mapName)) {
// Switch to the correct main tab, wild encounter group, and wild encounter type tab.
on_mainTabBar_tabBarClicked(MainTab::WildPokemon);
ui->comboBox_EncounterGroupLabel->setCurrentText(groupName);
ui->comboBox_EncounterGroupLabel->setTextItem(groupName);
QWidget *w = ui->stackedWidget_WildMons->currentWidget();
if (w) static_cast<MonTabWidget *>(w)->setCurrentField(fieldName);
}

View File

@@ -187,6 +187,7 @@ int Project::getSupportedMajorVersion(QString *errorOut) {
}
bool Project::load() {
this->parser.setUpdatesSplashScreen(true);
resetFileCache();
this->disabledSettingsNames.clear();
bool success = readGlobalConstants()
@@ -227,6 +228,7 @@ bool Project::load() {
initNewMapSettings();
applyParsedLimits();
}
this->parser.setUpdatesSplashScreen(false);
return success;
}
@@ -247,7 +249,9 @@ void Project::resetFileCache() {
projectConfig.getFilePath(ProjectFilePath::global_fieldmap),
};
for (const auto &path : filepaths) {
this->parser.cacheFile(path);
if (this->parser.cacheFile(path)) {
watchFile(path);
}
}
}
@@ -327,6 +331,7 @@ QSet<QString> Project::getTopLevelMapFields() const {
bool Project::readMapJson(const QString &mapName, QJsonDocument * out) {
const QString mapFilepath = QString("%1%2/map.json").arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders)).arg(mapName);
watchFile(mapFilepath);
QString error;
if (!parser.tryParseJsonFile(out, mapFilepath, &error)) {
logError(QString("Failed to read map data from '%1': %2").arg(mapFilepath).arg(error));
@@ -597,7 +602,7 @@ bool Project::readMapLayouts() {
clearMapLayouts();
const QString layoutsFilepath = projectConfig.getFilePath(ProjectFilePath::json_layouts);
fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(layoutsFilepath));
watchFile(layoutsFilepath);
QJsonDocument layoutsDoc;
QString error;
if (!parser.tryParseJsonFile(&layoutsDoc, layoutsFilepath, &error)) {
@@ -751,11 +756,26 @@ bool Project::saveMapLayouts() {
return true;
}
void Project::ignoreWatchedFileTemporarily(QString filepath) {
void Project::watchFile(const QString &filename) {
this->fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(filename));
}
void Project::watchFiles(const QStringList &filenames) {
for (const auto &filename : filenames)
watchFile(filename);
}
void Project::ignoreWatchedFileTemporarily(const QString &filepath) {
// Ignore any file-change events for this filepath for the next 5 seconds.
this->modifiedFileTimestamps.insert(filepath, QDateTime::currentMSecsSinceEpoch() + 5000);
}
void Project::ignoreWatchedFilesTemporarily(const QStringList &filepaths) {
for (const auto &filepath : filepaths) {
ignoreWatchedFileTemporarily(filepath);
}
}
void Project::recordFileChange(const QString &filepath) {
if (this->modifiedFiles.contains(filepath)) {
// We already recorded a change to this file
@@ -1366,6 +1386,8 @@ bool Project::saveMap(Map *map, bool skipLayout) {
// Custom header fields.
OrderedJson::append(&mapObj, map->customAttributes());
ignoreWatchedFileTemporarily(mapFilepath);
OrderedJson mapJson(mapObj);
OrderedJsonDoc jsonDoc(&mapJson);
jsonDoc.dump(&mapFile);
@@ -1565,12 +1587,25 @@ Tileset *Project::createNewTileset(QString name, bool secondary, bool checkerboa
labelList->insert(i, tileset->name);
this->tilesetLabelsOrdered.append(tileset->name);
// Append to tileset specific files.
// TODO: Ideally we wouldn't save new Tilesets immediately
// Append to tileset specific files. Strip prefix from name to get base name for use in other symbols.
name.remove(0, prefix.length());
tileset->appendToHeaders(this->root, name, this->usingAsmTilesets);
tileset->appendToGraphics(this->root, name, this->usingAsmTilesets);
tileset->appendToMetatiles(this->root, name, this->usingAsmTilesets);
QString headersFilepath = this->root + "/";
QString graphicsFilepath = this->root + "/";
QString metatilesFilepath = this->root + "/";
if (this->usingAsmTilesets) {
headersFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_headers_asm));
graphicsFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_graphics_asm));
metatilesFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_metatiles_asm));
} else {
headersFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_headers));
graphicsFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_graphics));
metatilesFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_metatiles));
}
ignoreWatchedFilesTemporarily({headersFilepath, graphicsFilepath, metatilesFilepath});
name.remove(0, prefix.length()); // Strip prefix from name to get base name for use in other symbols.
tileset->appendToHeaders(headersFilepath, name, this->usingAsmTilesets);
tileset->appendToGraphics(graphicsFilepath, name, this->usingAsmTilesets);
tileset->appendToMetatiles(metatilesFilepath, name, this->usingAsmTilesets);
tileset->save();
@@ -1594,7 +1629,7 @@ bool Project::readTilesetMetatileLabels() {
unusedMetatileLabels.clear();
QString metatileLabelsFilename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_labels);
fileWatcher.addPath(root + "/" + metatileLabelsFilename);
watchFile(metatileLabelsFilename);
const QSet<QString> regexList = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_metatile_label_prefix))};
const auto defines = parser.readCDefinesByRegex(metatileLabelsFilename, regexList);
@@ -1702,7 +1737,7 @@ bool Project::readWildMonData() {
const QString encounterRateFile = projectConfig.getFilePath(ProjectFilePath::wild_encounter);
const QString maxEncounterRateName = projectConfig.getIdentifier(ProjectIdentifier::define_max_encounter_rate);
fileWatcher.addPath(QString("%1/%2").arg(root).arg(encounterRateFile));
watchFile(encounterRateFile);
auto defines = parser.readCDefinesByName(encounterRateFile, {maxEncounterRateName});
if (defines.contains(maxEncounterRateName))
this->maxEncounterRate = defines.value(maxEncounterRateName)/16;
@@ -1711,8 +1746,7 @@ bool Project::readWildMonData() {
const QString levelRangeFile = projectConfig.getFilePath(ProjectFilePath::constants_pokemon);
const QString minLevelName = projectConfig.getIdentifier(ProjectIdentifier::define_min_level);
const QString maxLevelName = projectConfig.getIdentifier(ProjectIdentifier::define_max_level);
fileWatcher.addPath(QString("%1/%2").arg(root).arg(levelRangeFile));
watchFile(levelRangeFile);
defines = parser.readCDefinesByName(levelRangeFile, {minLevelName, maxLevelName});
if (defines.contains(minLevelName))
this->pokemonMinLevel = defines.value(minLevelName);
@@ -1724,7 +1758,7 @@ bool Project::readWildMonData() {
// Read encounter data
const QString wildMonJsonFilepath = projectConfig.getFilePath(ProjectFilePath::json_wild_encounters);
fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(wildMonJsonFilepath));
watchFile(wildMonJsonFilepath);
OrderedJson::object wildMonObj;
QString error;
@@ -1881,7 +1915,7 @@ bool Project::readMapGroups() {
this->customMapGroupsData = QJsonObject();
const QString filepath = projectConfig.getFilePath(ProjectFilePath::json_map_groups);
fileWatcher.addPath(root + "/" + filepath);
watchFile(filepath);
QJsonDocument mapGroupsDoc;
QString error;
if (!parser.tryParseJsonFile(&mapGroupsDoc, filepath, &error)) {
@@ -2184,7 +2218,7 @@ bool Project::readTilesetLabels() {
// If the tileset headers file is missing, the user may still have the old assembly format.
this->usingAsmTilesets = true;
QString asm_filename = projectConfig.getFilePath(ProjectFilePath::tilesets_headers_asm);
QString text = parser.readTextFile(this->root + "/" + asm_filename);
QString text = parser.loadTextFile(asm_filename);
if (text.isEmpty()) {
logError(QString("Failed to read tileset labels from '%1' or '%2'.").arg(filename).arg(asm_filename));
return false;
@@ -2231,7 +2265,7 @@ bool Project::readFieldmapProperties() {
const QString mapOffsetHeightName = projectConfig.getIdentifier(ProjectIdentifier::define_map_offset_height);
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_fieldmap);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
const auto defines = parser.readCDefinesByName(filename, { numTilesPrimaryName,
numTilesTotalName,
numMetatilesPrimaryName,
@@ -2335,8 +2369,7 @@ bool Project::readFieldmapMasks() {
const QString behaviorMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_behavior);
const QString layerTypeMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_layer);
const QString globalFieldmap = projectConfig.getFilePath(ProjectFilePath::global_fieldmap);
fileWatcher.addPath(root + "/" + globalFieldmap);
const QString globalFieldmap = projectConfig.getFilePath(ProjectFilePath::global_fieldmap); // File already being watched
const auto defines = parser.readCDefinesByName(globalFieldmap, { metatileIdMaskName,
collisionMaskName,
elevationMaskName,
@@ -2391,7 +2424,7 @@ bool Project::readFieldmapMasks() {
const QString layerTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_layer);
const QString encounterTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_encounter);
const QString terrainTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_terrain);
fileWatcher.addPath(root + "/" + srcFieldmap);
watchFile(srcFieldmap);
bool ok;
// Read terrain type mask
@@ -2469,7 +2502,7 @@ bool Project::readRegionMapSections() {
logError(QString("Failed to read region map sections from '%1': %2").arg(filepath).arg(error));
return false;
}
fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(filepath));
watchFile(filepath);
QJsonObject mapSectionsGlobalObj = doc.object();
QJsonArray mapSections = mapSectionsGlobalObj.take("map_sections").toArray();
@@ -2633,7 +2666,7 @@ bool Project::readHealLocations() {
logError(QString("Failed to read heal locations from '%1': %2").arg(filepath).arg(error));
return false;
}
fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(filepath));
watchFile(filepath);
QJsonObject healLocationsObj = doc.object();
QJsonArray healLocations = healLocationsObj.take("heal_locations").toArray();
@@ -2656,7 +2689,7 @@ bool Project::readHealLocations() {
bool Project::readItemNames() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_items);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->itemNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_items)}, &error);
if (!error.isEmpty())
@@ -2666,7 +2699,7 @@ bool Project::readItemNames() {
bool Project::readFlagNames() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_flags);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->flagNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_flags)}, &error);
if (!error.isEmpty())
@@ -2676,7 +2709,7 @@ bool Project::readFlagNames() {
bool Project::readVarNames() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_vars);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->varNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_vars)}, &error);
if (!error.isEmpty())
@@ -2686,7 +2719,7 @@ bool Project::readVarNames() {
bool Project::readMovementTypes() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_event_movement);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->movementTypes = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_movement_types)}, &error);
if (!error.isEmpty())
@@ -2696,7 +2729,7 @@ bool Project::readMovementTypes() {
bool Project::readInitialFacingDirections() {
QString filename = projectConfig.getFilePath(ProjectFilePath::initial_facing_table);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->facingDirections = parser.readNamedIndexCArray(filename, projectConfig.getIdentifier(ProjectIdentifier::symbol_facing_directions), &error);
if (!error.isEmpty())
@@ -2706,7 +2739,7 @@ bool Project::readInitialFacingDirections() {
bool Project::readMapTypes() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types);
fileWatcher.addPath(root + "/" + filename);
// File already being watched
QString error;
this->mapTypes = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_map_types)}, &error);
if (!error.isEmpty())
@@ -2716,7 +2749,7 @@ bool Project::readMapTypes() {
bool Project::readMapBattleScenes() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types);
fileWatcher.addPath(root + "/" + filename);
// File already being watched
QString error;
this->mapBattleScenes = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_battle_scenes)}, &error);
if (!error.isEmpty())
@@ -2726,7 +2759,7 @@ bool Project::readMapBattleScenes() {
bool Project::readWeatherNames() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->weatherNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_weather)}, &error);
if (!error.isEmpty())
@@ -2739,7 +2772,7 @@ bool Project::readCoordEventWeatherNames() {
return true;
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->coordEventWeatherNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_coord_event_weather)}, &error);
if (!error.isEmpty())
@@ -2752,7 +2785,7 @@ bool Project::readSecretBaseIds() {
return true;
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_secret_bases);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->secretBaseIds = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_secret_bases)}, &error);
if (!error.isEmpty())
@@ -2762,7 +2795,7 @@ bool Project::readSecretBaseIds() {
bool Project::readBgEventFacingDirections() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_event_bg);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->bgEventFacingDirections = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_sign_facing_directions)}, &error);
if (!error.isEmpty())
@@ -2772,7 +2805,7 @@ bool Project::readBgEventFacingDirections() {
bool Project::readTrainerTypes() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_trainer_types);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->trainerTypes = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_trainer_types)}, &error);
if (!error.isEmpty())
@@ -2785,7 +2818,7 @@ bool Project::readMetatileBehaviors() {
this->metatileBehaviorMapInverse.clear();
QString filename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_behaviors);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
const auto defines = parser.readCDefinesByRegex(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_behaviors)}, &error);
if (defines.isEmpty() && projectConfig.metatileBehaviorMask) {
@@ -2807,7 +2840,7 @@ bool Project::readMetatileBehaviors() {
bool Project::readSongNames() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_songs);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
this->songNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_music)}, &error);
if (!error.isEmpty())
@@ -2822,7 +2855,7 @@ bool Project::readSongNames() {
bool Project::readObjEventGfxConstants() {
QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_events);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
QString error;
const auto defines = parser.readCDefinesByRegex(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_obj_event_gfx)}, &error);
if (!error.isEmpty())
@@ -2838,7 +2871,7 @@ bool Project::readObjEventGfxConstants() {
bool Project::readMiscellaneousConstants() {
const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_global);
const QString maxObjectEventsName = projectConfig.getIdentifier(ProjectIdentifier::define_obj_event_count);
fileWatcher.addPath(root + "/" + filename);
watchFile(filename);
const auto defines = parser.readCDefinesByName(filename, {maxObjectEventsName});
this->maxObjectEvents = 64; // Default value
@@ -2965,7 +2998,7 @@ bool Project::readEventGraphics() {
const QString gfxInfoFilepath = projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_info);
const QString picTablesFilepath = projectConfig.getFilePath(ProjectFilePath::data_obj_event_pic_tables);
const QString gfxFilepath = projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx);
fileWatcher.addPaths({pointersFilepath, gfxInfoFilepath, picTablesFilepath, gfxFilepath});
watchFiles({pointersFilepath, gfxInfoFilepath, picTablesFilepath, gfxFilepath});
// Read the table mapping OBJ_EVENT_GFX constants to the names of pointers to data about their graphics.
const QString pointersName = projectConfig.getIdentifier(ProjectIdentifier::symbol_obj_event_gfx_pointers);
@@ -3166,14 +3199,14 @@ bool Project::readSpeciesIconPaths() {
// Read map of species constants to icon names
const QString srcfilename = projectConfig.getFilePath(ProjectFilePath::pokemon_icon_table);
fileWatcher.addPath(this->root + "/" + srcfilename);
watchFile(srcfilename);
const QString tableName = projectConfig.getIdentifier(ProjectIdentifier::symbol_pokemon_icon_table);
const QMap<QString, QString> monIconNames = parser.readNamedIndexCArray(srcfilename, tableName);
// Read species constants. If this fails we can get them from the icon table (but we shouldn't rely on it).
const QString speciesPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_species_prefix);
const QString constantsFilename = projectConfig.getFilePath(ProjectFilePath::constants_species);
fileWatcher.addPath(this->root + "/" + constantsFilename);
watchFile(constantsFilename);
this->speciesNames = parser.readCDefineNames(constantsFilename, {QString("\\b%1").arg(speciesPrefix)});
if (this->speciesNames.isEmpty()) {
this->speciesNames = monIconNames.keys();
@@ -3186,7 +3219,7 @@ bool Project::readSpeciesIconPaths() {
// do this on request in Project::getDefaultSpeciesIconPath.
if (!monIconNames.isEmpty()) {
const QString iconGraphicsFile = projectConfig.getFilePath(ProjectFilePath::data_pokemon_gfx);
fileWatcher.addPath(this->root + "/" + iconGraphicsFile);
watchFile(iconGraphicsFile);
QMap<QString, QString> iconNameToFilepath = parser.readCIncbinMulti(iconGraphicsFile);
for (auto i = monIconNames.constBegin(); i != monIconNames.constEnd(); i++) {

View File

@@ -8,20 +8,20 @@ AboutPorymap::AboutPorymap(QWidget *parent) :
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
static const QString commitHash = PORYMAP_LATEST_COMMIT;
this->ui->label_Version->setText(getVersionString());
layout()->setSizeConstraint(QLayout::SetFixedSize);
}
QString AboutPorymap::getVersionString() {
static const QString commitHash = PORYMAP_LATEST_COMMIT;
return QString("Version %1%2\nQt %3 (%4)\n%5")
static const QString commitHash = QStringLiteral(PORYMAP_LATEST_COMMIT);
static const QString versionString = QString("Version %1%2\nQt %3 (%4)\n%5")
.arg(QCoreApplication::applicationVersion())
.arg(commitHash.isEmpty() ? "" : QString(" (%1)").arg(commitHash))
.arg(QStringLiteral(QT_VERSION_STR))
.arg(QSysInfo::buildCpuArchitecture())
.arg(QStringLiteral(__DATE__));
return versionString;
}
AboutPorymap::~AboutPorymap()

View File

@@ -106,7 +106,7 @@ void ConnectionsListItem::commitDirection() {
if (MapConnection::isDiving(direction)) {
// Diving maps are displayed separately, no support right now for replacing a list item with a diving map.
// For now just restore the original direction.
ui->comboBox_Direction->setCurrentText(this->connection->direction());
ui->comboBox_Direction->setTextItem(this->connection->direction());
return;
}

View File

@@ -1,7 +1,7 @@
#include "divingmappixmapitem.h"
#include "config.h"
DivingMapPixmapItem::DivingMapPixmapItem(MapConnection *connection, QComboBox *combo)
DivingMapPixmapItem::DivingMapPixmapItem(MapConnection *connection, NoScrollComboBox *combo)
: QGraphicsPixmapItem(getBasePixmap(connection))
{
m_connection = connection;
@@ -38,5 +38,5 @@ void DivingMapPixmapItem::onTargetMapChanged() {
}
void DivingMapPixmapItem::setComboText(const QString &text) {
if (m_combo) m_combo->setCurrentText(text);
if (m_combo) m_combo->setTextItem(text);
}

View File

@@ -28,7 +28,7 @@ QWidget *SpeciesComboDelegate::createEditor(QWidget *parent, const QStyleOptionV
void SpeciesComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
QString species = index.data(Qt::EditRole).toString();
NoScrollComboBox *combo = static_cast<NoScrollComboBox *>(editor);
combo->setCurrentText(species);
combo->setTextItem(species);
}
void SpeciesComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {

View File

@@ -152,8 +152,12 @@ void EventFrame::initialize() {
this->label_icon->setPixmap(this->event->getPixmap());
}
void EventFrame::populate(Project *) {
void EventFrame::populate(Project *project) {
this->populated = true;
if (this->project && this->project != project) {
this->project->disconnect(this);
}
this->project = project;
}
void EventFrame::invalidateConnections() {
@@ -166,6 +170,10 @@ void EventFrame::invalidateUi() {
void EventFrame::invalidateValues() {
this->populated = false;
if (this->isVisible()) {
// Repopulate immediately
this->populate(this->project);
}
}
void EventFrame::setActive(bool active) {
@@ -181,19 +189,20 @@ void EventFrame::populateDropdown(NoScrollComboBox * combo, const QStringList &i
const QString savedText = combo->currentText();
combo->clear();
combo->addItems(items);
combo->setCurrentText(savedText);
combo->setTextItem(savedText);
}
void EventFrame::populateScriptDropdown(NoScrollComboBox * combo, Project * project) {
// The script dropdown and autocomplete are populated with scripts used by the map's events and from its scripts file.
if (!this->event->getMap())
Map *map = this->event ? this->event->getMap() : nullptr;
if (!map)
return;
QStringList scripts = this->event->getMap()->getScriptLabels(this->event->getEventGroup());
QStringList scripts = map->getScriptLabels(this->event->getEventGroup());
populateDropdown(combo, scripts);
// Depending on the settings, the autocomplete may also contain all global scripts.
if (porymapConfig.loadAllEventScripts) {
if (project && porymapConfig.loadAllEventScripts) {
project->insertGlobalScriptLabels(scripts);
}
@@ -209,14 +218,23 @@ void EventFrame::populateScriptDropdown(NoScrollComboBox * combo, Project * proj
combo->setCompleter(completer);
// If the project changes the script labels, update the EventFrame.
// TODO: At the moment this only happens when the user changes script settings (i.e. when 'porymapConfig.loadAllEventScripts' changes).
// This should ultimately be connected to a file watcher so that we can also update the dropdown when the scripts file changes.
connect(project, &Project::eventScriptLabelsRead, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
// If the script labels change then we need to update the EventFrame.
if (project) connect(project, &Project::eventScriptLabelsRead, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
connect(map, &Map::scriptsModified, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
}
void EventFrame::populateMapNameDropdown(NoScrollComboBox * combo, Project * project) {
if (!project)
return;
populateDropdown(combo, project->mapNames);
// This frame type displays map names, so when a new map is created we need to repopulate it.
connect(project, &Project::mapCreated, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
}
void EventFrame::populateIdNameDropdown(NoScrollComboBox * combo, Project * project, const QString &mapName, Event::Group group) {
if (!project->mapNames.contains(mapName))
if (!project || !project->mapNames.contains(mapName))
return;
Map *map = project->loadMap(mapName);
@@ -325,7 +343,6 @@ void ObjectFrame::connectSignals(MainWindow *window) {
if (this->connected) return;
EventFrame::connectSignals(window);
Project *project = window->editor->project;
// local id
this->line_edit_local_id->disconnect();
@@ -336,18 +353,18 @@ void ObjectFrame::connectSignals(MainWindow *window) {
// sprite update
this->combo_sprite->disconnect();
connect(this->combo_sprite, &QComboBox::currentTextChanged, [this, project](const QString &text) {
connect(this->combo_sprite, &QComboBox::currentTextChanged, [this](const QString &text) {
this->object->setGfx(text);
this->object->getPixmapItem()->render(project);
this->object->getPixmapItem()->render(this->project);
this->object->modify();
});
connect(this->object->getPixmapItem(), &EventPixmapItem::rendered, this->label_icon, &QLabel::setPixmap);
// movement
this->combo_movement->disconnect();
connect(this->combo_movement, &QComboBox::currentTextChanged, [this, project](const QString &text) {
connect(this->combo_movement, &QComboBox::currentTextChanged, [this](const QString &text) {
this->object->setMovement(text);
this->object->getPixmapItem()->render(project);
this->object->getPixmapItem()->render(this->project);
this->object->modify();
});
@@ -419,7 +436,7 @@ void ObjectFrame::initialize() {
this->spinner_radius_y->setValue(this->object->getRadiusY());
// script
this->combo_script->setCurrentText(this->object->getScript());
this->combo_script->setTextItem(this->object->getScript());
if (porymapConfig.textEditorGotoLine.isEmpty())
this->button_script->hide();
@@ -430,7 +447,7 @@ void ObjectFrame::initialize() {
this->combo_trainer_type->setTextItem(this->object->getTrainerType());
// sight berry
this->combo_radius_treeid->setCurrentText(this->object->getSightRadiusBerryTreeID());
this->combo_radius_treeid->setTextItem(this->object->getSightRadiusBerryTreeID());
}
void ObjectFrame::populate(Project *project) {
@@ -498,7 +515,6 @@ void CloneObjectFrame::connectSignals(MainWindow *window) {
if (this->connected) return;
EventFrame::connectSignals(window);
Project *project = window->editor->project;
// local id
this->line_edit_local_id->disconnect();
@@ -512,26 +528,23 @@ void CloneObjectFrame::connectSignals(MainWindow *window) {
// target map
this->combo_target_map->disconnect();
connect(this->combo_target_map, &QComboBox::currentTextChanged, [this, project](const QString &mapName) {
connect(this->combo_target_map, &QComboBox::currentTextChanged, [this](const QString &mapName) {
this->clone->setTargetMap(mapName);
this->clone->getPixmapItem()->render(project);
this->combo_sprite->setCurrentText(this->clone->getGfx());
this->clone->getPixmapItem()->render(this->project);
this->combo_sprite->setTextItem(this->clone->getGfx());
this->clone->modify();
populateIdNameDropdown(this->combo_target_id, project, mapName, Event::Group::Object);
populateIdNameDropdown(this->combo_target_id, this->project, mapName, Event::Group::Object);
});
connect(window, &MainWindow::mapOpened, this, &CloneObjectFrame::tryInvalidateIdDropdown, Qt::UniqueConnection);
// target id
this->combo_target_id->disconnect();
connect(this->combo_target_id, &QComboBox::currentTextChanged, [this, project](const QString &text) {
connect(this->combo_target_id, &QComboBox::currentTextChanged, [this](const QString &text) {
this->clone->setTargetID(text);
this->clone->getPixmapItem()->render(project);
this->combo_sprite->setCurrentText(this->clone->getGfx());
this->clone->getPixmapItem()->render(this->project);
this->combo_sprite->setTextItem(this->clone->getGfx());
this->clone->modify();
});
// This frame type displays map names, so when a new map is created we need to repopulate it.
connect(project, &Project::mapCreated, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
}
void CloneObjectFrame::tryInvalidateIdDropdown(Map *map) {
@@ -552,10 +565,10 @@ void CloneObjectFrame::initialize() {
this->line_edit_local_id->setText(this->clone->getIdName());
// sprite
this->combo_sprite->setCurrentText(this->clone->getGfx());
this->combo_sprite->setTextItem(this->clone->getGfx());
// target id
this->combo_target_id->setCurrentText(this->clone->getTargetID());
this->combo_target_id->setTextItem(this->clone->getTargetID());
// target map
this->combo_target_map->setTextItem(this->clone->getTargetMap());
@@ -567,7 +580,7 @@ void CloneObjectFrame::populate(Project *project) {
const QSignalBlocker blocker(this);
EventFrame::populate(project);
populateDropdown(this->combo_target_map, project->mapNames);
populateMapNameDropdown(this->combo_target_map, project);
populateIdNameDropdown(this->combo_target_id, project, this->clone->getTargetMap(), Event::Group::Object);
}
@@ -618,7 +631,6 @@ void WarpFrame::connectSignals(MainWindow *window) {
if (this->connected) return;
EventFrame::connectSignals(window);
Project *project = window->editor->project;
// id
this->line_edit_id->disconnect();
@@ -629,10 +641,10 @@ void WarpFrame::connectSignals(MainWindow *window) {
// dest map
this->combo_dest_map->disconnect();
connect(this->combo_dest_map, &QComboBox::currentTextChanged, [this, project](const QString &mapName) {
connect(this->combo_dest_map, &QComboBox::currentTextChanged, [this](const QString &mapName) {
this->warp->setDestinationMap(mapName);
this->warp->modify();
populateIdNameDropdown(this->combo_dest_warp, project, mapName, Event::Group::Warp);
populateIdNameDropdown(this->combo_dest_warp, this->project, mapName, Event::Group::Warp);
});
connect(window, &MainWindow::mapOpened, this, &WarpFrame::tryInvalidateIdDropdown, Qt::UniqueConnection);
@@ -646,9 +658,6 @@ void WarpFrame::connectSignals(MainWindow *window) {
// warning
this->warning->disconnect();
connect(this->warning, &QPushButton::clicked, window, &MainWindow::onWarpBehaviorWarningClicked);
// This frame type displays map names, so when a new map is created we need to repopulate it.
connect(project, &Project::mapCreated, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
}
void WarpFrame::tryInvalidateIdDropdown(Map *map) {
@@ -672,7 +681,7 @@ void WarpFrame::initialize() {
this->combo_dest_map->setTextItem(this->warp->getDestinationMap());
// dest id
this->combo_dest_warp->setCurrentText(this->warp->getDestinationWarpID());
this->combo_dest_warp->setTextItem(this->warp->getDestinationWarpID());
}
void WarpFrame::populate(Project *project) {
@@ -681,7 +690,7 @@ void WarpFrame::populate(Project *project) {
const QSignalBlocker blocker(this);
EventFrame::populate(project);
populateDropdown(this->combo_dest_map, project->mapNames);
populateMapNameDropdown(this->combo_dest_map, project);
populateIdNameDropdown(this->combo_dest_warp, project, this->warp->getDestinationMap(), Event::Group::Warp);
}
@@ -753,13 +762,13 @@ void TriggerFrame::initialize() {
EventFrame::initialize();
// script
this->combo_script->setCurrentText(this->trigger->getScriptLabel());
this->combo_script->setTextItem(this->trigger->getScriptLabel());
// var
this->combo_var->setTextItem(this->trigger->getScriptVar());
// var value
this->combo_var_value->setCurrentText(this->trigger->getScriptVarValue());
this->combo_var_value->setTextItem(this->trigger->getScriptVarValue());
}
void TriggerFrame::populate(Project *project) {
@@ -876,7 +885,7 @@ void SignFrame::initialize() {
this->combo_facing_dir->setTextItem(this->sign->getFacingDirection());
// script
this->combo_script->setCurrentText(this->sign->getScriptLabel());
this->combo_script->setTextItem(this->sign->getScriptLabel());
}
void SignFrame::populate(Project *project) {
@@ -1102,7 +1111,6 @@ void HealLocationFrame::connectSignals(MainWindow *window) {
if (this->connected) return;
EventFrame::connectSignals(window);
Project *project = window->editor->project;
this->line_edit_id->disconnect();
connect(this->line_edit_id, &QLineEdit::textChanged, [this](const QString &text) {
@@ -1111,10 +1119,10 @@ void HealLocationFrame::connectSignals(MainWindow *window) {
});
this->combo_respawn_map->disconnect();
connect(this->combo_respawn_map, &QComboBox::currentTextChanged, [this, project](const QString &mapName) {
connect(this->combo_respawn_map, &QComboBox::currentTextChanged, [this](const QString &mapName) {
this->healLocation->setRespawnMapName(mapName);
this->healLocation->modify();
populateIdNameDropdown(this->combo_respawn_npc, project, mapName, Event::Group::Object);
populateIdNameDropdown(this->combo_respawn_npc, this->project, mapName, Event::Group::Object);
});
connect(window, &MainWindow::mapOpened, this, &HealLocationFrame::tryInvalidateIdDropdown, Qt::UniqueConnection);
@@ -1123,9 +1131,6 @@ void HealLocationFrame::connectSignals(MainWindow *window) {
this->healLocation->setRespawnNPC(text);
this->healLocation->modify();
});
// This frame type displays map names, so when a new map is created we need to repopulate it.
connect(project, &Project::mapCreated, this, &EventFrame::invalidateValues, Qt::UniqueConnection);
}
void HealLocationFrame::tryInvalidateIdDropdown(Map *map) {
@@ -1158,7 +1163,7 @@ void HealLocationFrame::populate(Project *project) {
EventFrame::populate(project);
if (projectConfig.healLocationRespawnDataEnabled) {
populateDropdown(this->combo_respawn_map, project->mapNames);
populateMapNameDropdown(this->combo_respawn_map, project);
populateIdNameDropdown(this->combo_respawn_npc, project, this->healLocation->getRespawnMapName(), Event::Group::Object);
}
}

View File

@@ -144,7 +144,7 @@ void GridSettingsDialog::updateInput() {
ui->colorInput->setColor(m_settings->color.rgb());
const QSignalBlocker b_Style(ui->comboBox_Style);
ui->comboBox_Style->setCurrentText(GridSettings::getStyleName(m_settings->style));
ui->comboBox_Style->setTextItem(GridSettings::getStyleName(m_settings->style));
}
void GridSettingsDialog::setWidth(int value) {

View File

@@ -43,18 +43,37 @@ void PorymapLoadingScreen::stop () {
this->hide();
}
void PorymapLoadingScreen::setPixmap(QPixmap pixmap) {
void PorymapLoadingScreen::setPixmap(const QPixmap &pixmap) {
if (!this->isVisible()) return;
this->ui->labelPixmap->setPixmap(pixmap);
}
void PorymapLoadingScreen::showMessage(QString text) {
// Displays the message 'prefixtext...'. The 'text' portion may be elided if it's too long.
void PorymapLoadingScreen::showMessage(const QString &prefix, const QString &text) {
if (!this->isVisible()) return;
this->ui->labelText->setText(text.mid(text.lastIndexOf("/") + 1));
// Limit text (excluding prefix) to avoid increasing the splash screen's width.
static const QFontMetrics fontMetrics = this->ui->labelText->fontMetrics();
static const int maxWidth = this->ui->labelText->width() + 1;
int prefixWidth = fontMetrics.horizontalAdvance(prefix);
QString message = fontMetrics.elidedText(text + QStringLiteral("..."), Qt::ElideLeft, qMax(maxWidth - prefixWidth, 0));
message.prepend(prefix);
this->ui->labelText->setText(message);
QApplication::processEvents();
}
// Displays the message 'text...'
void PorymapLoadingScreen::showMessage(const QString &text) {
showMessage("", text);
}
// Displays the message 'Loading text...'
void PorymapLoadingScreen::showLoadingMessage(const QString &text) {
showMessage(QStringLiteral("Loading "), text);
}
void PorymapLoadingScreen::updateFrame() {
this->frame = (this->frame + 1) % this->splashImage.frameCount();
this->setPixmap(QPixmap::fromImage(this->splashImage.frame(this->frame)));

View File

@@ -1,6 +1,5 @@
#include "mapheaderform.h"
#include "ui_mapheaderform.h"
#include "project.h"
MapHeaderForm::MapHeaderForm(QWidget *parent)
: QWidget(parent)
@@ -94,7 +93,7 @@ void MapHeaderForm::setLocations(const QStringList &locations) {
const QString before = ui->comboBox_Location->currentText();
ui->comboBox_Location->clear();
ui->comboBox_Location->addItems(locations);
ui->comboBox_Location->setCurrentText(before);
ui->comboBox_Location->setTextItem(before);
}
// Assign a MapHeader that the form will keep in sync with the UI.
@@ -187,10 +186,10 @@ void MapHeaderForm::setAllowsBiking(bool allowsBiking) { ui->checkBox_
void MapHeaderForm::setAllowsEscaping(bool allowsEscaping) { ui->checkBox_AllowEscaping->setChecked(allowsEscaping); }
void MapHeaderForm::setFloorNumber(int floorNumber) { ui->spinBox_FloorNumber->setValue(floorNumber); }
// If we always call setText / setCurrentText the user's cursor may move to the end of the text while they're typing.
void MapHeaderForm::setText(QComboBox *combo, const QString &text) const {
// If we always call setText / setTextItem the user's cursor may move to the end of the text while they're typing.
void MapHeaderForm::setText(NoScrollComboBox *combo, const QString &text) const {
if (combo->currentText() != text)
combo->setCurrentText(text);
combo->setTextItem(text);
}
void MapHeaderForm::setText(QLineEdit *lineEdit, const QString &text) const {
if (lineEdit->text() != text)

View File

@@ -101,11 +101,11 @@ void MapImageExporter::setModeSpecificUi() {
ui->comboBox_MapSelection->clear();
if (m_map) {
ui->comboBox_MapSelection->addItems(m_project->mapNames);
ui->comboBox_MapSelection->setCurrentText(m_map->name());
ui->comboBox_MapSelection->setTextItem(m_map->name());
ui->label_MapSelection->setText(m_mode == ImageExporterMode::Stitch ? QStringLiteral("Starting Map") : QStringLiteral("Map"));
} else if (m_layout) {
ui->comboBox_MapSelection->addItems(m_project->layoutIds);
ui->comboBox_MapSelection->setCurrentText(m_layout->id);
ui->comboBox_MapSelection->setTextItem(m_layout->id);
ui->label_MapSelection->setText(QStringLiteral("Layout"));
}
@@ -146,7 +146,7 @@ void MapImageExporter::setLayout(Layout *layout) {
void MapImageExporter::setSelectionText(const QString &text) {
const QSignalBlocker b(ui->comboBox_MapSelection);
ui->comboBox_MapSelection->setCurrentText(text);
ui->comboBox_MapSelection->setTextItem(text);
updateMapSelection();
}
@@ -171,7 +171,7 @@ void MapImageExporter::updateMapSelection() {
// Ensure text in the combo box remains valid
const QSignalBlocker b(ui->comboBox_MapSelection);
ui->comboBox_MapSelection->setCurrentText(m_map ? m_map->name() : m_layout->id);
ui->comboBox_MapSelection->setTextItem(m_map ? m_map->name() : m_layout->id);
if (m_map != oldMap && (!m_map || !oldMap)) {
// Switching to or from layout-only mode

View File

@@ -167,7 +167,7 @@ void NewMapDialog::on_lineEdit_Name_textChanged(const QString &text) {
// Changing the map name updates the layout ID field to match.
if (ui->comboBox_LayoutID->isEnabled()) {
ui->comboBox_LayoutID->setCurrentText(Layout::layoutConstantFromName(text));
ui->comboBox_LayoutID->setTextItem(Layout::layoutConstantFromName(text));
}
}

View File

@@ -44,7 +44,7 @@ void PreferenceEditor::initFields() {
}
void PreferenceEditor::updateFields() {
themeSelector->setCurrentText(porymapConfig.theme);
themeSelector->setTextItem(porymapConfig.theme);
if (porymapConfig.eventSelectionShapeMode == QGraphicsPixmapItem::MaskShape) {
ui->radioButton_OnSprite->setChecked(true);
} else if (porymapConfig.eventSelectionShapeMode == QGraphicsPixmapItem::BoundingRectShape) {

View File

@@ -657,7 +657,7 @@ void RegionMapEditor::displayRegionMapLayoutOptions() {
void RegionMapEditor::updateRegionMapLayoutOptions(int index) {
const QSignalBlocker b_ConnectedMap(ui->comboBox_RM_ConnectedMap);
this->ui->comboBox_RM_ConnectedMap->setCurrentText(this->region_map->squareMapSection(index));
this->ui->comboBox_RM_ConnectedMap->setTextItem(this->region_map->squareMapSection(index));
this->ui->pushButton_RM_Options_delete->setEnabled(this->region_map->squareHasMap(index));
@@ -736,7 +736,7 @@ 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->comboBox_RM_Entry_MapSection->setCurrentText(section);
this->ui->comboBox_RM_Entry_MapSection->setTextItem(section);
this->activeEntry = section;
this->region_map_entries_item->currentSection = section;
MapSectionEntry entry = enabled ? this->region_map_entries[section] : MapSectionEntry();
@@ -1296,11 +1296,11 @@ void RegionMapEditor::setLocations(const QStringList &locations) {
auto before = ui->comboBox_RM_ConnectedMap->currentText();
ui->comboBox_RM_ConnectedMap->clear();
ui->comboBox_RM_ConnectedMap->addItems(locations);
ui->comboBox_RM_ConnectedMap->setCurrentText(before);
ui->comboBox_RM_ConnectedMap->setTextItem(before);
const QSignalBlocker b_MapSection(ui->comboBox_RM_Entry_MapSection);
before = ui->comboBox_RM_Entry_MapSection->currentText();
ui->comboBox_RM_Entry_MapSection->clear();
ui->comboBox_RM_Entry_MapSection->addItems(locations);
ui->comboBox_RM_Entry_MapSection->setCurrentText(before);
ui->comboBox_RM_Entry_MapSection->setTextItem(before);
}

View File

@@ -312,7 +312,7 @@ QBarSet* WildMonChart::createLevelDistributionBarSet(const QString &species, con
const QSignalBlocker blocker1(ui->groupBox_Species);
const QSignalBlocker blocker2(ui->comboBox_Species);
ui->groupBox_Species->setChecked(true);
ui->comboBox_Species->setCurrentText(species);
ui->comboBox_Species->setTextItem(species);
refreshLevelDistributionChart();
});
}