Merge remote-tracking branch 'origin/master' into fix827

# Conflicts:
#	src/mainwindow.cpp
This commit is contained in:
Marcus Huderle
2020-12-14 17:57:30 -06:00
43 changed files with 2263 additions and 271 deletions

View File

@@ -6,6 +6,8 @@
#include <QObject>
#include <QByteArrayList>
#include <QSize>
#include <QKeySequence>
#include <QMultiMap>
enum MapSortOrder {
Group = 0,
@@ -46,6 +48,8 @@ public:
this->monitorFiles = true;
this->regionMapDimensions = QSize(32, 20);
this->theme = "default";
this->textEditorOpenFolder = "";
this->textEditorGotoLine = "";
}
void setRecentProject(QString project);
void setRecentMap(QString map);
@@ -62,6 +66,8 @@ public:
void setMonitorFiles(bool monitor);
void setRegionMapDimensions(int width, int height);
void setTheme(QString theme);
void setTextEditorOpenFolder(const QString &command);
void setTextEditorGotoLine(const QString &command);
QString getRecentProject();
QString getRecentMap();
MapSortOrder getMapSortOrder();
@@ -77,6 +83,8 @@ public:
bool getMonitorFiles();
QSize getRegionMapDimensions();
QString getTheme();
QString getTextEditorOpenFolder();
QString getTextEditorGotoLine();
protected:
virtual QString getConfigFilepath() override;
virtual void parseConfigKeyValue(QString key, QString value) override;
@@ -108,6 +116,8 @@ private:
bool monitorFiles;
QSize regionMapDimensions;
QString theme;
QString textEditorOpenFolder;
QString textEditorGotoLine;
};
extern PorymapConfig porymapConfig;
@@ -193,4 +203,53 @@ private:
extern ProjectConfig projectConfig;
class QAction;
class Shortcut;
class ShortcutsConfig : public KeyValueConfigBase
{
public:
ShortcutsConfig() :
user_shortcuts({ }),
default_shortcuts({ })
{ }
virtual void reset() override { user_shortcuts.clear(); }
// Call this before applying user shortcuts so that the user can restore defaults.
void setDefaultShortcuts(const QObjectList &objects);
QList<QKeySequence> defaultShortcuts(const QObject *object) const;
void setUserShortcuts(const QObjectList &objects);
void setUserShortcuts(const QMultiMap<const QObject *, QKeySequence> &objects_keySequences);
QList<QKeySequence> userShortcuts(const QObject *object) const;
protected:
virtual QString getConfigFilepath() override;
virtual void parseConfigKeyValue(QString key, QString value) override;
virtual QMap<QString, QString> getKeyValueMap() override;
virtual void onNewConfigFileCreated() override { };
virtual void setUnreadKeys() override { };
private:
QMultiMap<QString, QKeySequence> user_shortcuts;
QMultiMap<QString, QKeySequence> default_shortcuts;
enum StoreType {
User,
Default
};
QString cfgKey(const QObject *object) const;
QList<QKeySequence> currentShortcuts(const QObject *object) const;
void storeShortcutsFromList(StoreType storeType, const QObjectList &objects);
void storeShortcuts(
StoreType storeType,
const QString &cfgKey,
const QList<QKeySequence> &keySequences);
};
extern ShortcutsConfig shortcutsConfig;
#endif // CONFIG_H

View File

@@ -32,10 +32,10 @@ public:
Event(const Event&);
Event(QJsonObject, QString);
public:
int x() {
int x() const {
return getInt("x");
}
int y() {
int y() const {
return getInt("y");
}
int elevation() {
@@ -47,16 +47,16 @@ public:
void setY(int y) {
put("y", y);
}
QString get(QString key) {
QString get(const QString &key) const {
return values.value(key);
}
int getInt(QString key) {
int getInt(const QString &key) const {
return values.value(key).toInt(nullptr, 0);
}
uint16_t getU16(QString key) {
uint16_t getU16(const QString &key) const {
return values.value(key).toUShort(nullptr, 0);
}
int16_t getS16(QString key) {
int16_t getS16(const QString &key) const {
return values.value(key).toShort(nullptr, 0);
}
void put(QString key, int value) {

View File

@@ -84,7 +84,8 @@ public:
void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
QList<Event*> getAllEvents();
QList<Event*> getAllEvents() const;
QStringList eventScriptLabels(const QString &event_group_type = QString()) const;
void removeEvent(Event*);
void addEvent(Event*);
QPixmap renderConnection(MapConnection, MapLayout *);

View File

@@ -41,7 +41,7 @@ class ParseUtil
public:
ParseUtil();
void set_root(QString);
QString readTextFile(QString);
static QString readTextFile(QString);
void strip_comment(QString*);
QList<QStringList>* parseAsm(QString);
int evaluateDefine(QString, QMap<QString, int>*);
@@ -55,6 +55,17 @@ public:
bool tryParseJsonFile(QJsonDocument *out, QString filepath);
bool ensureFieldsExist(QJsonObject obj, QList<QString> fields);
// Returns the 1-indexed line number for the definition of scriptLabel in the scripts file at filePath.
// Returns 0 if a definition for scriptLabel cannot be found.
static int getScriptLineNumber(const QString &filePath, const QString &scriptLabel);
static int getRawScriptLineNumber(QString text, const QString &scriptLabel);
static int getPoryScriptLineNumber(QString text, const QString &scriptLabel);
static QString &removeStringLiterals(QString &text);
static QString &removeLineComments(QString &text, const QString &commentSymbol);
static QString &removeLineComments(QString &text, const QStringList &commentSymbols);
static QStringList splitShellCommand(QStringView command);
private:
QString root;
QString text;

View File

@@ -66,7 +66,6 @@ public:
void displayMapBorder();
void displayMapGrid();
void displayWildMonTables();
void maskNonVisibleConnectionTiles();
void updateMapBorder();
void updateMapConnections();
@@ -85,6 +84,7 @@ public:
void addNewConnection();
void removeCurrentConnection();
void addNewWildMonGroup(QWidget *window);
void deleteWildMonGroup();
void updateDiveMap(QString mapName);
void updateEmergeMap(QString mapName);
void setSelectedConnectionFromMap(QString mapName);
@@ -155,6 +155,12 @@ public:
void shouldReselectEvents();
void scaleMapView(int);
public slots:
void openMapScripts() const;
void openScript(const QString &scriptLabel) const;
void openProjectInTextEditor() const;
void maskNonVisibleConnectionTiles();
private:
void setConnectionItemsVisible(bool);
void setBorderItemsVisible(bool, qreal = 1);
@@ -182,6 +188,10 @@ private:
QString getMovementPermissionText(uint16_t collision, uint16_t elevation);
QString getMetatileDisplayMessage(uint16_t metatileId);
bool eventLimitReached(Map *, QString);
void openInTextEditor(const QString &path, int lineNum = 0) const;
bool startDetachedProcess(const QString &command,
const QString &workingDirectory = QString(),
qint64 *pid = nullptr) const;
private slots:
void onMapStartPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
@@ -205,7 +215,6 @@ private slots:
void onHoveredMapMovementPermissionCleared();
void onSelectedMetatilesChanged();
void onWheelZoom(int);
void onMapRulerLengthChanged();
signals:
void objectsChanged();
@@ -214,6 +223,7 @@ signals:
void wildMonDataChanged();
void warpEventDoubleClicked(QString mapName, QString warpNum);
void currentMetatilesSelectionChanged();
void mapRulerStatusChanged(const QString &);
};
#endif // EDITOR_H

View File

@@ -22,6 +22,8 @@
#include "filterchildrenproxymodel.h"
#include "newmappopup.h"
#include "newtilesetdialog.h"
#include "shortcutseditor.h"
#include "preferenceeditor.h"
namespace Ui {
class MainWindow;
@@ -119,8 +121,6 @@ private slots:
void duplicate();
void openInTextEditor();
void onLoadMapRequested(QString, QString);
void onMapChanged(Map *map);
void onMapNeedsRedrawing();
@@ -129,6 +129,8 @@ private slots:
void openNewMapPopupWindow(int, QVariant);
void onNewMapCreated();
void onMapCacheCleared();
void onMapRulerStatusChanged(const QString &);
void applyUserShortcuts();
void on_action_NewMap_triggered();
void on_actionNew_Tileset_triggered();
@@ -148,6 +150,7 @@ private slots:
void on_actionUse_Encounter_Json_triggered(bool checked);
void on_actionMonitor_Project_Files_triggered(bool checked);
void on_actionUse_Poryscript_triggered(bool checked);
void on_actionEdit_Shortcuts_triggered();
void on_mainTabBar_tabBarClicked(int index);
@@ -164,7 +167,6 @@ private slots:
void on_actionMap_Shift_triggered();
void on_toolButton_deleteObject_clicked();
void on_toolButton_Open_Scripts_clicked();
void addNewEvent(QString);
void updateSelectedObjects();
@@ -208,6 +210,7 @@ private slots:
void on_lineEdit_filterBox_textChanged(const QString &arg1);
void moveEvent(QMoveEvent *event);
void closeEvent(QCloseEvent *);
void eventTabChanged(int index);
@@ -218,23 +221,28 @@ private slots:
void on_toolButton_ExpandAll_clicked();
void on_toolButton_CollapseAll_clicked();
void on_actionAbout_Porymap_triggered();
void on_actionThemes_triggered();
void on_pushButton_AddCustomHeaderField_clicked();
void on_pushButton_DeleteCustomHeaderField_clicked();
void on_tableWidget_CustomHeaderFields_cellChanged(int row, int column);
void on_horizontalSlider_MetatileZoom_valueChanged(int value);
void on_pushButton_NewWildMonGroup_clicked();
void on_pushButton_DeleteWildMonGroup_clicked();
void on_pushButton_ConfigureEncountersJSON_clicked();
void on_actionRegion_Map_Editor_triggered();
void on_actionEdit_Preferences_triggered();
void togglePreferenceSpecificUi();
private:
Ui::MainWindow *ui;
QLabel *label_MapRulerStatus;
TilesetEditor *tilesetEditor = nullptr;
RegionMapEditor *regionMapEditor = nullptr;
ShortcutsEditor *shortcutsEditor = nullptr;
MapImageExporter *mapImageExporter = nullptr;
FilterChildrenProxyModel *mapListProxyModel;
NewMapPopup *newmapprompt = nullptr;
PreferenceEditor *preferenceEditor = nullptr;
QStandardItemModel *mapListModel;
QList<QStandardItem*> *mapGroupItemsList;
QMap<QString, QModelIndex> mapListIndexes;
@@ -260,6 +268,7 @@ private:
DraggablePixmapItem *selectedHealspot;
QList<QAction *> registeredActions;
QVector<QToolButton *> openScriptButtons;
bool isProgrammaticEventTabChange;
bool projectHasUnsavedChanges;
@@ -291,11 +300,12 @@ private:
void initWindow();
void initCustomUI();
void initExtraShortcuts();
void initExtraSignals();
void initEditor();
void initMiscHeapObjects();
void initMapSortOrder();
void initShortcuts();
void initExtraShortcuts();
void setProjectSpecificUIVisibility();
void loadUserSettings();
void applyMapListFilter(QString filterText);
@@ -307,9 +317,16 @@ private:
void closeSupplementaryWindows();
void setWindowDisabled(bool);
void initTilesetEditor();
bool initRegionMapEditor();
void initShortcutsEditor();
void connectSubEditorsToShortcutsEditor();
bool isProjectOpen();
void showExportMapImageWindow(bool stitchMode);
void redrawMetatileSelection();
QObjectList shortcutableObjects() const;
};
enum MapListUserRoles {

View File

@@ -173,8 +173,10 @@ public:
QString fixPalettePath(QString path);
QString fixGraphicPath(QString path);
QString getScriptFileExtension(bool usePoryScript);
QString getScriptDefaultString(bool usePoryScript, QString mapName);
QString getScriptFileExtension(bool usePoryScript) const;
QString getScriptDefaultString(bool usePoryScript, QString mapName) const;
QString getMapScriptsFilePath(const QString &mapName) const;
QStringList getEventScriptsFilePaths() const;
bool loadMapBorder(Map *map);

View File

@@ -22,6 +22,7 @@ protected:
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void drawForeground(QPainter *painter, const QRectF &rect);
void moveEvent(QMoveEvent *event);
};
//Q_DECLARE_METATYPE(GraphicsView)

View File

@@ -2,8 +2,7 @@
#define MAPRULER_H
#include <QGraphicsObject>
#include <QPainter>
#include <QColor>
#include <QLine>
class MapRuler : public QGraphicsObject, private QLine
@@ -11,20 +10,14 @@ class MapRuler : public QGraphicsObject, private QLine
Q_OBJECT
public:
MapRuler(QColor innerColor = Qt::yellow, QColor borderColor = Qt::black) :
innerColor(innerColor),
borderColor(borderColor),
mapSize(QSize())
{
init();
}
void init();
// thickness is given in scene pixels
MapRuler(int thickness, QColor innerColor = Qt::yellow, QColor borderColor = Qt::black);
QRectF boundingRect() const override;
QPainterPath shape() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override;
bool eventFilter(QObject *, QEvent *event) override;
void setEnabled(bool enabled);
bool isAnchored() const { return anchored; }
bool isLocked() const { return locked; }
@@ -45,37 +38,33 @@ public:
// Ruler height in metatiles
int height() const { return qAbs(deltaY()); }
QString statusMessage;
public slots:
void mouseEvent(QGraphicsSceneMouseEvent *event);
void setMapDimensions(const QSize &size);
signals:
void statusChanged(const QString &statusMessage);
private:
QColor innerColor;
QColor borderColor;
const int thickness;
const qreal half_thickness;
const QColor innerColor;
const QColor borderColor;
QSize mapSize;
QRect xRuler;
QRect yRuler;
QRectF xRuler;
QRectF yRuler;
QLineF cornerTick;
bool anchored;
bool locked;
static int thickness;
void reset();
void setAnchor(const QPointF &scenePos);
void setEndPos(const QPointF &scenePos);
QPoint snapToWithinBounds(QPoint pos) const;
void setAnchor(const QPointF &scenePos, const QPoint &screenPos);
void endAnchor();
void setEndPos(const QPointF &scenePos, const QPoint &screenPos);
void showDimensions(const QPoint &screenPos) const;
void hideDimensions() const;
void updateGeometry();
void updateStatus(Qt::Corner corner);
int pixWidth() const { return width() * 16; }
int pixHeight() const { return height() * 16; }
signals:
void lengthChanged();
void deactivated(const QPoint &endPos);
};
#endif // MAPRULER_H

52
include/ui/multikeyedit.h Normal file
View File

@@ -0,0 +1,52 @@
#ifndef MULTIKEYEDIT_H
#define MULTIKEYEDIT_H
#include <QWidget>
#include <QKeySequenceEdit>
class QLineEdit;
// A collection of QKeySequenceEdit's laid out horizontally.
class MultiKeyEdit : public QWidget
{
Q_OBJECT
public:
MultiKeyEdit(QWidget *parent = nullptr, int fieldCount = 2);
bool eventFilter(QObject *watched, QEvent *event) override;
int fieldCount() const;
void setFieldCount(int count);
QList<QKeySequence> keySequences() const;
bool removeOne(const QKeySequence &keySequence);
bool contains(const QKeySequence &keySequence) const;
void setContextMenuPolicy(Qt::ContextMenuPolicy policy);
bool isClearButtonEnabled() const;
void setClearButtonEnabled(bool enable);
public slots:
void clear();
void setKeySequences(const QList<QKeySequence> &keySequences);
void addKeySequence(const QKeySequence &keySequence);
signals:
void keySequenceChanged(const QKeySequence &keySequence);
void editingFinished();
void customContextMenuRequested(const QPoint &pos);
private:
QVector<QKeySequenceEdit *> keySequenceEdit_vec;
QList<QKeySequence> keySequence_list; // Used to track changes
void addNewKeySequenceEdit();
void alignKeySequencesLeft();
void setFocusToLastNonEmptyKeySequenceEdit();
private slots:
void onEditingFinished();
void showDefaultContextMenu(QLineEdit *lineEdit, const QPoint &pos);
};
#endif // MULTIKEYEDIT_H

View File

@@ -0,0 +1,37 @@
#ifndef PREFERENCES_H
#define PREFERENCES_H
#include <QMainWindow>
class NoScrollComboBox;
class QAbstractButton;
namespace Ui {
class PreferenceEditor;
}
class PreferenceEditor : public QMainWindow
{
Q_OBJECT
public:
explicit PreferenceEditor(QWidget *parent = nullptr);
~PreferenceEditor();
signals:
void preferencesSaved();
void themeChanged(const QString &theme);
private:
Ui::PreferenceEditor *ui;
NoScrollComboBox *themeSelector;
void populateFields();
void saveFields();
private slots:
void dialogButtonClicked(QAbstractButton *button);
};
#endif // PREFERENCES_H

View File

@@ -47,6 +47,11 @@ public:
void resize(int width, int height);
QObjectList shortcutableObjects() const;
public slots:
void applyUserShortcuts();
private:
Ui::RegionMapEditor *ui;
Project *project;
@@ -81,6 +86,7 @@ private:
RegionMapPixmapItem *region_map_item = nullptr;
CityMapPixmapItem *city_map_item = nullptr;
void initShortcuts();
void displayRegionMap();
void displayRegionMapImage();
void displayRegionMapLayout();

71
include/ui/shortcut.h Normal file
View File

@@ -0,0 +1,71 @@
#ifndef SHORTCUT_H
#define SHORTCUT_H
#include <QObject>
#include <QKeySequence>
#include <QShortcut>
// Alternative to QShortcut that adds support for multiple key sequences.
// Use this to allow the shortcut to be editable in ShortcutsEditor.
class Shortcut : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QShortcut)
Q_PROPERTY(QKeySequence key READ key WRITE setKey)
Q_PROPERTY(QString whatsThis READ whatsThis WRITE setWhatsThis)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(bool autoRepeat READ autoRepeat WRITE setAutoRepeat)
Q_PROPERTY(Qt::ShortcutContext context READ context WRITE setContext)
public:
explicit Shortcut(QWidget *parent);
Shortcut(const QKeySequence &key, QWidget *parent,
const char *member = nullptr, const char *ambiguousMember = nullptr,
Qt::ShortcutContext shortcutContext = Qt::WindowShortcut);
Shortcut(const QList<QKeySequence> &keys, QWidget *parent,
const char *member = nullptr, const char *ambiguousMember = nullptr,
Qt::ShortcutContext shortcutContext = Qt::WindowShortcut);
~Shortcut();
void addKey(const QKeySequence &key);
void setKey(const QKeySequence &key);
QKeySequence key() const;
void addKeys(const QList<QKeySequence> &keys);
void setKeys(const QList<QKeySequence> &keys);
QList<QKeySequence> keys() const;
void setEnabled(bool enable);
bool isEnabled() const;
void setContext(Qt::ShortcutContext context);
Qt::ShortcutContext context() const;
void setWhatsThis(const QString &text);
QString whatsThis() const;
void setAutoRepeat(bool on);
bool autoRepeat() const;
int id() const;
QList<int> ids() const;
inline QWidget *parentWidget() const
{ return static_cast<QWidget *>(QObject::parent()); }
signals:
void activated();
void activatedAmbiguously();
protected:
bool event(QEvent *e) override;
private:
const char *sc_member;
const char *sc_ambiguousmember;
Qt::ShortcutContext sc_context;
QVector<QShortcut *> sc_vec;
};
#endif // SHORTCUT_H

View File

@@ -0,0 +1,60 @@
#ifndef SHORTCUTSEDITOR_H
#define SHORTCUTSEDITOR_H
#include "shortcut.h"
#include <QMainWindow>
#include <QDialog>
#include <QMap>
#include <QHash>
#include <QAction>
class QFormLayout;
class MultiKeyEdit;
class QAbstractButton;
namespace Ui {
class ShortcutsEditor;
}
class ShortcutsEditor : public QMainWindow
{
Q_OBJECT
public:
explicit ShortcutsEditor(QWidget *parent = nullptr);
explicit ShortcutsEditor(const QObjectList &shortcutableObjects, QWidget *parent = nullptr);
~ShortcutsEditor();
void setShortcutableObjects(const QObjectList &shortcutableObjects);
signals:
void shortcutsSaved();
private:
Ui::ShortcutsEditor *ui;
QWidget *main_container;
QMultiMap<QString, const QObject *> labels_objects;
QHash<QString, QFormLayout *> contexts_layouts;
QHash<MultiKeyEdit *, const QObject *> multiKeyEdits_objects;
void parseObjectList(const QObjectList &objectList);
QString getLabel(const QObject *object) const;
bool stringPropertyIsNotEmpty(const QObject *object, const char *name) const;
void populateMainContainer();
QString getShortcutContext(const QObject *object) const;
void addNewContextGroup(const QString &shortcutContext);
void addNewMultiKeyEdit(const QObject *object, const QString &shortcutContext);
QList<MultiKeyEdit *> siblings(MultiKeyEdit *multiKeyEdit) const;
void promptUserOnDuplicateFound(MultiKeyEdit *current, MultiKeyEdit *sender);
void removeKeySequence(const QKeySequence &keySequence, MultiKeyEdit *multiKeyEdit);
void saveShortcuts();
void resetShortcuts();
private slots:
void checkForDuplicates(const QKeySequence &keySequence);
void dialogButtonClicked(QAbstractButton *button);
};
#endif // SHORTCUTSEDITOR_H

View File

@@ -42,6 +42,11 @@ public:
void updateTilesets(QString primaryTilsetLabel, QString secondaryTilesetLabel);
bool selectMetatile(uint16_t metatileId);
QObjectList shortcutableObjects() const;
public slots:
void applyUserShortcuts();
private slots:
void onHoveredMetatileChanged(uint16_t);
void onHoveredMetatileCleared();
@@ -102,6 +107,8 @@ private:
void initTileSelector();
void initSelectedTileItem();
void initMetatileLayersItem();
void initShortcuts();
void initExtraShortcuts();
void restoreWindowState();
void initMetatileHistory();
void setTilesets(QString primaryTilesetLabel, QString secondaryTilesetLabel);
@@ -112,6 +119,7 @@ private:
void refresh();
void saveMetatileLabel();
void closeEvent(QCloseEvent*);
Ui::TilesetEditor *ui;
History<MetatileHistoryItem*> metatileHistory;
TilesetEditorMetatileSelector *metatileSelector = nullptr;