diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index bc03f823..44d69d30 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -6,8 +6,8 @@ 0 0 - 1287 - 936 + 1298 + 963 @@ -30,7 +30,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -45,7 +45,7 @@ 0 - + Groups @@ -66,140 +66,7 @@ 0 - - - 0 - - - 3 - - - 3 - - - 3 - - - - - <html><head/><body><p>Toggle hide all empty map folders</p></body></html> - - - - - - - :/icons/folder_eye_open.ico - :/icons/folder_eye_closed.ico:/icons/folder_eye_open.ico - - - true - - - QToolButton::InstantPopup - - - true - - - - - - - <html><head/><body><p>Expand all map folders</p></body></html> - - - - - - - :/icons/expand_all.ico:/icons/expand_all.ico - - - QToolButton::InstantPopup - - - true - - - - - - - <html><head/><body><p>Collapse all map list folders</p></body></html> - - - - - - - :/icons/collapse_all.ico:/icons/collapse_all.ico - - - QToolButton::InstantPopup - - - true - - - - - - - <html><head/><body><p>Toggle editability of group folders</p></body></html> - - - - - - - :/icons/lock_edit.ico - :/icons/unlock_edit.ico:/icons/lock_edit.ico - - - true - - - QToolButton::InstantPopup - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 12 - 20 - - - - - - - - true - - - - - - Filter... - - - true - - - - + @@ -216,10 +83,10 @@ - QAbstractItemView::SingleSelection + QAbstractItemView::SelectionMode::SingleSelection - QAbstractItemView::SelectItems + QAbstractItemView::SelectionBehavior::SelectItems false @@ -228,7 +95,7 @@ - + Areas @@ -249,116 +116,7 @@ 0 - - - 0 - - - 3 - - - 3 - - - 3 - - - - - <html><head/><body><p>Toggle hide all empty mapsection folders</p></body></html> - - - - - - - :/icons/folder_eye_open.ico - :/icons/folder_eye_closed.ico:/icons/folder_eye_open.ico - - - true - - - QToolButton::InstantPopup - - - true - - - - - - - <html><head/><body><p>Expand all map folders</p></body></html> - - - - - - - :/icons/expand_all.ico:/icons/expand_all.ico - - - QToolButton::InstantPopup - - - true - - - - - - - <html><head/><body><p>Collapse all map list folders</p></body></html> - - - - - - - :/icons/collapse_all.ico:/icons/collapse_all.ico - - - QToolButton::InstantPopup - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 12 - 20 - - - - - - - - true - - - - - - Filter... - - - true - - - - + @@ -375,10 +133,10 @@ - QAbstractItemView::SingleSelection + QAbstractItemView::SelectionMode::SingleSelection - QAbstractItemView::SelectItems + QAbstractItemView::SelectionBehavior::SelectItems false @@ -387,7 +145,7 @@ - + Layouts @@ -408,116 +166,7 @@ 0 - - - 0 - - - 3 - - - 3 - - - 3 - - - - - <html><head/><body><p>Toggle hide all unused layouts</p></body></html> - - - - - - - :/icons/folder_eye_open.ico - :/icons/folder_eye_closed.ico:/icons/folder_eye_open.ico - - - true - - - QToolButton::InstantPopup - - - true - - - - - - - <html><head/><body><p>Expand all layout folders</p></body></html> - - - - - - - :/icons/expand_all.ico:/icons/expand_all.ico - - - QToolButton::InstantPopup - - - true - - - - - - - <html><head/><body><p>Collapse all layout folders</p></body></html> - - - - - - - :/icons/collapse_all.ico:/icons/collapse_all.ico - - - QToolButton::InstantPopup - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Preferred - - - - 12 - 20 - - - - - - - - true - - - - - - Filter... - - - true - - - - + @@ -534,10 +183,10 @@ - QAbstractItemView::SingleSelection + QAbstractItemView::SelectionMode::SingleSelection - QAbstractItemView::SelectItems + QAbstractItemView::SelectionBehavior::SelectItems false @@ -581,7 +230,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -633,7 +282,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -643,10 +292,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised 1 @@ -670,10 +319,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -722,10 +371,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -746,10 +395,10 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Raised + QFrame::Shadow::Raised @@ -930,7 +579,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -953,10 +602,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -1004,7 +653,7 @@ - QLayout::SetNoConstraint + QLayout::SizeConstraint::SetNoConstraint 3 @@ -1033,17 +682,17 @@ 30 - Qt::Horizontal + Qt::Orientation::Horizontal - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain @@ -1067,7 +716,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -1104,10 +753,10 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain true @@ -1117,8 +766,8 @@ 0 0 - 420 - 77 + 424 + 79 @@ -1140,7 +789,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1162,17 +811,17 @@ <html><head/><body><p>The border is a 2x2 metatile which is repeated outside of the map layout's boundary. Draw on this border area to modify it.</p></body></html> - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1223,10 +872,10 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain true @@ -1236,8 +885,8 @@ 0 0 - 420 - 78 + 424 + 79 @@ -1259,7 +908,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1284,17 +933,17 @@ - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1318,19 +967,19 @@ - Qt::ScrollBarAlwaysOn + Qt::ScrollBarPolicy::ScrollBarAlwaysOn - Qt::ScrollBarAsNeeded + Qt::ScrollBarPolicy::ScrollBarAsNeeded - QAbstractScrollArea::AdjustIgnored + QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored true - Qt::AlignHCenter|Qt::AlignTop + Qt::AlignmentFlag::AlignHCenter|Qt::AlignmentFlag::AlignTop @@ -1338,10 +987,10 @@ - 0 + 8 0 - 409 - 440 + 412 + 446 @@ -1369,7 +1018,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1391,20 +1040,20 @@ - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - QAbstractScrollArea::AdjustIgnored + QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1417,7 +1066,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -1444,10 +1093,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -1460,7 +1109,7 @@ - Qt::StrongFocus + Qt::FocusPolicy::StrongFocus <html><head/><body><p>Primary Tileset</p><p>Defines the first 0x200 metatiles available for the map.</p></body></html> @@ -1480,7 +1129,7 @@ - Qt::StrongFocus + Qt::FocusPolicy::StrongFocus <html><head/><body><p>Secondary Tileset</p><p>Defines the second 0x200 metatiles available for the map.</p></body></html> @@ -1493,10 +1142,10 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Raised + QFrame::Shadow::Raised @@ -1538,7 +1187,7 @@ - QLayout::SetDefaultConstraint + QLayout::SizeConstraint::SetDefaultConstraint 3 @@ -1569,8 +1218,8 @@ 0 0 - 424 - 627 + 428 + 633 @@ -1592,7 +1241,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1617,17 +1266,17 @@ - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1640,7 +1289,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -1666,7 +1315,7 @@ 30 - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1682,17 +1331,17 @@ 50 - Qt::Horizontal + Qt::Orientation::Horizontal - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -1718,7 +1367,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1779,7 +1428,7 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true @@ -1789,8 +1438,8 @@ 0 0 - 379 - 732 + 383 + 744 @@ -1812,10 +1461,10 @@ <html><head/><body><p>No prefabs have been created for the currently-used tilesets. Create some by using the button above!</p><p>Prefabs are &quot;prefabricated&quot; metatile selections that are used for easy selecting of complicated map structures. For example, a useful prefab could be a building or tree formation, which would otherwise be annoying to paint with the regular metatile picker.</p></body></html> - Qt::RichText + Qt::TextFormat::RichText - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop true @@ -1888,10 +1537,10 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Raised + QFrame::Shadow::Raised 0 @@ -1928,7 +1577,7 @@ :/icons/add.ico:/icons/add.ico - Qt::ToolButtonTextBesideIcon + Qt::ToolButtonStyle::ToolButtonTextBesideIcon @@ -1951,7 +1600,7 @@ :/icons/delete.ico:/icons/delete.ico - Qt::ToolButtonTextBesideIcon + Qt::ToolButtonStyle::ToolButtonTextBesideIcon false @@ -1961,7 +1610,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -1996,7 +1645,7 @@ There are no events on the current map. - Qt::AlignCenter + Qt::AlignmentFlag::AlignCenter @@ -2062,7 +1711,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -2077,13 +1726,13 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -2091,7 +1740,7 @@ 0 0 100 - 30 + 16 @@ -2156,7 +1805,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -2171,13 +1820,13 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -2185,7 +1834,7 @@ 0 0 100 - 30 + 16 @@ -2250,7 +1899,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -2265,13 +1914,13 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -2279,7 +1928,7 @@ 0 0 100 - 30 + 16 @@ -2350,7 +1999,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -2365,13 +2014,13 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -2379,7 +2028,7 @@ 0 0 100 - 30 + 16 @@ -2444,7 +2093,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -2459,13 +2108,13 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -2473,7 +2122,7 @@ 0 0 100 - 30 + 16 @@ -2513,13 +2162,13 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame true - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop @@ -2582,14 +2231,14 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised - QFormLayout::FieldsStayAtSizeHint + QFormLayout::FieldGrowthPolicy::FieldsStayAtSizeHint 12 @@ -2793,10 +2442,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -2809,10 +2458,10 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain @@ -2844,7 +2493,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -2925,10 +2574,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -2940,10 +2589,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -3008,7 +2657,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -3093,7 +2742,7 @@ 30 - Qt::Horizontal + Qt::Orientation::Horizontal @@ -3109,7 +2758,7 @@ 30 - Qt::Horizontal + Qt::Orientation::Horizontal @@ -3141,7 +2790,7 @@ 30 - Qt::Horizontal + Qt::Orientation::Horizontal @@ -3172,7 +2821,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -3188,22 +2837,22 @@ false - Qt::ScrollBarAsNeeded + Qt::ScrollBarPolicy::ScrollBarAsNeeded - Qt::ScrollBarAsNeeded + Qt::ScrollBarPolicy::ScrollBarAsNeeded - QAbstractScrollArea::AdjustIgnored + QAbstractScrollArea::SizeAdjustPolicy::AdjustIgnored - QGraphicsView::NoDrag + QGraphicsView::DragMode::NoDrag - QGraphicsView::AnchorUnderMouse + QGraphicsView::ViewportAnchor::AnchorUnderMouse - QGraphicsView::AnchorUnderMouse + QGraphicsView::ViewportAnchor::AnchorUnderMouse @@ -3214,10 +2863,10 @@ - QFrame::StyledPanel + QFrame::Shape::StyledPanel - QFrame::Raised + QFrame::Shadow::Raised @@ -3234,10 +2883,10 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - Qt::ScrollBarAlwaysOff + Qt::ScrollBarPolicy::ScrollBarAlwaysOff true @@ -3247,8 +2896,8 @@ 0 0 - 365 - 651 + 204 + 16 @@ -3270,7 +2919,7 @@ - Qt::Vertical + Qt::Orientation::Vertical @@ -3298,19 +2947,19 @@ - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Raised + QFrame::Shadow::Raised - QFrame::NoFrame + QFrame::Shape::NoFrame - QFrame::Plain + QFrame::Shadow::Plain @@ -3323,7 +2972,7 @@ - QComboBox::AdjustToContents + QComboBox::SizeAdjustPolicy::AdjustToContents @@ -3364,7 +3013,7 @@ - Qt::Horizontal + Qt::Orientation::Horizontal @@ -3416,8 +3065,8 @@ 0 0 - 1287 - 22 + 1298 + 37 @@ -3788,7 +3437,7 @@ Check for Updates... - QAction::ApplicationSpecificRole + QAction::MenuRole::ApplicationSpecificRole @@ -3868,6 +3517,12 @@ QGraphicsView
mapview.h
+ + MapListToolBar + QFrame +
maplisttoolbar.h
+ 1 +
diff --git a/forms/maplisttoolbar.ui b/forms/maplisttoolbar.ui new file mode 100644 index 00000000..6f753ea8 --- /dev/null +++ b/forms/maplisttoolbar.ui @@ -0,0 +1,172 @@ + + + MapListToolBar + + + + 0 + 0 + 274 + 32 + + + + Form + + + + 0 + + + 3 + + + 3 + + + 0 + + + 3 + + + + + Add a folder to the list. + + + + :/icons/folder_add.ico:/icons/folder_add.ico + + + QToolButton::ToolButtonPopupMode::InstantPopup + + + true + + + + + + + Hide empty folders in the list. + + + + :/icons/folder_eye_open.ico + :/icons/folder_eye_closed.ico:/icons/folder_eye_open.ico + + + true + + + QToolButton::ToolButtonPopupMode::InstantPopup + + + true + + + + + + + Expand all folders in the list. + + + + + + + :/icons/expand_all.ico:/icons/expand_all.ico + + + QToolButton::ToolButtonPopupMode::InstantPopup + + + true + + + + + + + Collapse all folders in the list. + + + + + + + :/icons/collapse_all.ico:/icons/collapse_all.ico + + + QToolButton::ToolButtonPopupMode::InstantPopup + + + true + + + + + + + Toggle editability of folders in the list. + + + + + + + :/icons/lock_edit.ico + :/icons/unlock_edit.ico:/icons/lock_edit.ico + + + true + + + QToolButton::ToolButtonPopupMode::InstantPopup + + + true + + + + + + + Qt::Orientation::Horizontal + + + QSizePolicy::Policy::Preferred + + + + 12 + 19 + + + + + + + + true + + + + + + Filter... + + + true + + + + + + + + + + diff --git a/include/mainwindow.h b/include/mainwindow.h index 06b9bf78..e0bf7177 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -173,11 +173,6 @@ private slots: void on_action_Open_Project_triggered(); void on_action_Reload_Project_triggered(); void on_action_Close_Project_triggered(); - - void on_mapList_activated(const QModelIndex &index); - void on_areaList_activated(const QModelIndex &index); - void on_layoutList_activated(const QModelIndex &index); - void on_action_Save_Project_triggered(); void openWarpMap(QString map_name, int event_id, Event::Group event_group); @@ -275,10 +270,6 @@ private slots: void on_actionTileset_Editor_triggered(); - void on_lineEdit_filterBox_textChanged(const QString &arg1); - void on_lineEdit_filterBox_Areas_textChanged(const QString &arg1); - void on_lineEdit_filterBox_Layouts_textChanged(const QString &arg1); - void moveEvent(QMoveEvent *event); void closeEvent(QCloseEvent *); @@ -292,19 +283,9 @@ private slots: void on_slider_EmergeMapOpacity_valueChanged(int value); void on_horizontalSlider_CollisionTransparency_valueChanged(int value); - void do_HideShow(); - void do_ExpandAll(); - void do_CollapseAll(); - void on_toolButton_HideShow_Groups_clicked(); - void on_toolButton_ExpandAll_Groups_clicked(); - void on_toolButton_CollapseAll_Groups_clicked(); - void on_toolButton_EnableDisable_EditGroups_clicked(); - void on_toolButton_HideShow_Areas_clicked(); - void on_toolButton_ExpandAll_Areas_clicked(); - void on_toolButton_CollapseAll_Areas_clicked(); - void on_toolButton_HideShow_Layouts_clicked(); - void on_toolButton_ExpandAll_Layouts_clicked(); - void on_toolButton_CollapseAll_Layouts_clicked(); + void mapListShortcut_ToggleEmptyFolders(); + void mapListShortcut_ExpandAll(); + void mapListShortcut_CollapseAll(); void on_actionAbout_Porymap_triggered(); void on_actionOpen_Log_File_triggered(); @@ -347,14 +328,12 @@ private: QPointer gridSettingsDialog = nullptr; QPointer customScriptsEditor = nullptr; - FilterChildrenProxyModel *groupListProxyModel; - MapGroupModel *mapGroupModel; - - FilterChildrenProxyModel *areaListProxyModel; - MapAreaModel *mapAreaModel; - - FilterChildrenProxyModel *layoutListProxyModel; - LayoutTreeModel *layoutTreeModel; + QPointer groupListProxyModel = nullptr; + QPointer mapGroupModel = nullptr; + QPointer areaListProxyModel = nullptr; + QPointer mapAreaModel = nullptr; + QPointer layoutListProxyModel = nullptr; + QPointer layoutTreeModel = nullptr; QPointer updatePromoter = nullptr; QPointer networkAccessManager = nullptr; @@ -375,9 +354,10 @@ private: bool tilesetNeedsRedraw = false; bool setLayout(QString layoutId); - bool setMap(QString, bool scroll = false); + bool setMap(QString); void unsetMap(); - bool userSetMap(QString, bool scrollTreeView = false); + bool userSetLayout(QString layoutId); + bool userSetMap(QString); void redrawMapScene(); void redrawLayoutScene(); void refreshMapScene(); @@ -389,7 +369,10 @@ private: void clearProjectUI(); void openSubWindow(QWidget * window); - void scrollTreeView(QString itemName); + void scrollMapList(MapTree *list, QString itemName); + void scrollMapListToCurrentMap(MapTree *list); + void scrollMapListToCurrentLayout(MapTree *list); + void resetMapListFilters(); QString getExistingDirectory(QString); bool openProject(QString dir, bool initial = false); bool closeProject(); @@ -403,31 +386,29 @@ private: void refreshRecentProjectsMenu(); void updateMapList(); - void mapListAddItem(); - void mapListRemoveItem(); void mapListAddGroup(); void mapListAddLayout(); void mapListAddArea(); void mapListRemoveGroup(); void mapListRemoveArea(); void mapListRemoveLayout(); + void openMapListItem(const QModelIndex &index); void displayMapProperties(); void checkToolButtons(); void clickToolButtonFromEditAction(Editor::EditAction editAction); - void showWindowTitle(); + void updateWindowTitle(); void initWindow(); void initCustomUI(); void initExtraSignals(); void initEditor(); void initMiscHeapObjects(); - void initMapSortOrder(); + void initMapList(); void initShortcuts(); void initExtraShortcuts(); void loadUserSettings(); - void applyMapListFilter(QString filterText); void restoreWindowState(); void setTheme(QString); void updateTilesetEditor(); @@ -447,6 +428,7 @@ private: double getMetatilesZoomScale(); void redrawMetatileSelection(); void scrollMetatileSelectorToSelection(); + MapListToolBar* getCurrentMapListToolBar(); QObjectList shortcutableObjects() const; void addCustomHeaderValue(QString key, QJsonValue value, bool isNew = false); diff --git a/include/ui/filterchildrenproxymodel.h b/include/ui/filterchildrenproxymodel.h index 5853d625..d9eed7af 100644 --- a/include/ui/filterchildrenproxymodel.h +++ b/include/ui/filterchildrenproxymodel.h @@ -9,7 +9,7 @@ class FilterChildrenProxyModel : public QSortFilterProxyModel public: explicit FilterChildrenProxyModel(QObject *parent = nullptr); - void toggleHideEmpty() { this->hideEmpty = !this->hideEmpty; } + bool toggleHideEmpty() { return this->hideEmpty = !this->hideEmpty; } protected: bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const; private: diff --git a/include/ui/maplistmodels.h b/include/ui/maplistmodels.h index d99c8815..8d00c492 100644 --- a/include/ui/maplistmodels.h +++ b/include/ui/maplistmodels.h @@ -53,7 +53,17 @@ private: class QRegularExpressionValidator; -class MapGroupModel : public QStandardItemModel { +class MapListModel : public QStandardItemModel { + Q_OBJECT + +public: + MapListModel(QObject *parent = nullptr) : QStandardItemModel(parent) {}; + ~MapListModel() { } + + virtual QModelIndex indexOf(QString id) const = 0; +}; + +class MapGroupModel : public MapListModel { Q_OBJECT public: @@ -80,7 +90,7 @@ public: void removeGroup(int groupIndex); QStandardItem *getItem(const QModelIndex &index) const; - QModelIndex indexOfMap(QString mapName); + virtual QModelIndex indexOf(QString mapName) const override; void initialize(); @@ -103,7 +113,7 @@ signals: -class MapAreaModel : public QStandardItemModel { +class MapAreaModel : public MapListModel { Q_OBJECT public: @@ -123,7 +133,7 @@ public: void removeArea(int groupIndex); QStandardItem *getItem(const QModelIndex &index) const; - QModelIndex indexOfMap(QString mapName); + virtual QModelIndex indexOf(QString mapName) const override; void initialize(); @@ -143,7 +153,7 @@ signals: -class LayoutTreeModel : public QStandardItemModel { +class LayoutTreeModel : public MapListModel { Q_OBJECT public: @@ -162,7 +172,7 @@ public: QStandardItem *insertMapItem(QString mapName, QString layoutId); QStandardItem *getItem(const QModelIndex &index) const; - QModelIndex indexOfLayout(QString layoutName); + virtual QModelIndex indexOf(QString layoutName) const override; void initialize(); diff --git a/include/ui/maplisttoolbar.h b/include/ui/maplisttoolbar.h new file mode 100644 index 00000000..c66b0d80 --- /dev/null +++ b/include/ui/maplisttoolbar.h @@ -0,0 +1,49 @@ +#ifndef MAPLISTTOOLBAR_H +#define MAPLISTTOOLBAR_H + +#include "maplistmodels.h" +#include "filterchildrenproxymodel.h" + +#include +#include + +namespace Ui { +class MapListToolBar; +} + +class MapListToolBar : public QFrame +{ + Q_OBJECT + +public: + explicit MapListToolBar(QWidget *parent = nullptr); + ~MapListToolBar(); + + MapTree* list() const { return m_list; } + void setList(MapTree *list); + + void setEditsAllowedButtonHidden(bool hidden); + + void toggleEmptyFolders(); + void expandList(); + void collapseList(); + void toggleEditsAllowed(); + + void applyFilter(const QString &filterText); + void clearFilter(); + void setFilterLocked(bool locked) { m_filterLocked = locked; } + bool isFilterLocked() const { return m_filterLocked; } + +signals: + void filterCleared(MapTree*); + void addFolderClicked(); + +private: + Ui::MapListToolBar *ui; + QPointer m_list; + bool m_filterLocked = false; + + void setEditsAllowed(bool allowed); +}; + +#endif // MAPLISTTOOLBAR_H diff --git a/porymap.pro b/porymap.pro index d65bdf07..1b1c693e 100644 --- a/porymap.pro +++ b/porymap.pro @@ -75,6 +75,7 @@ SOURCES += src/core/block.cpp \ src/ui/eventfilters.cpp \ src/ui/filterchildrenproxymodel.cpp \ src/ui/maplistmodels.cpp \ + src/ui/maplisttoolbar.cpp \ src/ui/graphicsview.cpp \ src/ui/imageproviders.cpp \ src/ui/layoutpixmapitem.cpp \ @@ -174,6 +175,7 @@ HEADERS += include/core/block.h \ include/ui/eventfilters.h \ include/ui/filterchildrenproxymodel.h \ include/ui/maplistmodels.h \ + include/ui/maplisttoolbar.h \ include/ui/graphicsview.h \ include/ui/imageproviders.h \ include/ui/layoutpixmapitem.h \ @@ -229,6 +231,7 @@ FORMS += forms/mainwindow.ui \ forms/colorinputwidget.ui \ forms/connectionslistitem.ui \ forms/gridsettingsdialog.ui \ + forms/maplisttoolbar.ui \ forms/newmapconnectiondialog.ui \ forms/prefabcreationdialog.ui \ forms/prefabframe.ui \ diff --git a/resources/icons/collapse_all.ico b/resources/icons/collapse_all.ico index f6c7f315..806f2435 100644 Binary files a/resources/icons/collapse_all.ico and b/resources/icons/collapse_all.ico differ diff --git a/resources/icons/expand_all.ico b/resources/icons/expand_all.ico index 0707936c..ca913a13 100644 Binary files a/resources/icons/expand_all.ico and b/resources/icons/expand_all.ico differ diff --git a/resources/icons/folder_add.ico b/resources/icons/folder_add.ico new file mode 100755 index 00000000..d881adf8 Binary files /dev/null and b/resources/icons/folder_add.ico differ diff --git a/resources/icons/folder_closed_map.ico b/resources/icons/folder_closed_map.ico index 27f9810b..d299acb7 100644 Binary files a/resources/icons/folder_closed_map.ico and b/resources/icons/folder_closed_map.ico differ diff --git a/resources/images.qrc b/resources/images.qrc index 15650a65..a89535a9 100644 --- a/resources/images.qrc +++ b/resources/images.qrc @@ -10,6 +10,7 @@ icons/file_put.ico icons/fill_color_cursor.ico icons/fill_color.ico + icons/folder_add.ico icons/folder_closed_map.ico icons/folder_closed.ico icons/folder_eye_closed.ico diff --git a/src/core/map.cpp b/src/core/map.cpp index 01ab95b0..8067b9a7 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -257,7 +257,7 @@ void Map::clean() { } bool Map::hasUnsavedChanges() { - return !editHistory.isClean() || !this->layout->editHistory.isClean() || hasUnsavedDataChanges || !isPersistedToFile; + return !editHistory.isClean() || this->layout->hasUnsavedChanges() || hasUnsavedDataChanges || !isPersistedToFile; } void Map::pruneEditHistory() { diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 08cdaf8c..14a255c2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -119,7 +119,7 @@ void MainWindow::initWindow() { this->initExtraSignals(); this->initEditor(); this->initMiscHeapObjects(); - this->initMapSortOrder(); + this->initMapList(); this->initShortcuts(); this->restoreWindowState(); @@ -166,15 +166,15 @@ void MainWindow::initExtraShortcuts() { shortcutToggle_Smart_Paths->setObjectName("shortcutToggle_Smart_Paths"); shortcutToggle_Smart_Paths->setWhatsThis("Toggle Smart Paths"); - auto *shortcutHide_Show = new Shortcut(QKeySequence(), this, SLOT(do_HideShow())); + auto *shortcutHide_Show = new Shortcut(QKeySequence(), this, SLOT(mapListShortcut_ToggleEmptyFolders())); shortcutHide_Show->setObjectName("shortcutHide_Show"); shortcutHide_Show->setWhatsThis("Map List: Hide/Show Empty Folders"); - auto *shortcutExpand_All = new Shortcut(QKeySequence(), this, SLOT(do_ExpandAll())); + auto *shortcutExpand_All = new Shortcut(QKeySequence(), this, SLOT(mapListShortcut_ExpandAll())); shortcutExpand_All->setObjectName("shortcutExpand_All"); shortcutExpand_All->setWhatsThis("Map List: Expand all folders"); - auto *shortcutCollapse_All = new Shortcut(QKeySequence(), this, SLOT(do_CollapseAll())); + auto *shortcutCollapse_All = new Shortcut(QKeySequence(), this, SLOT(mapListShortcut_CollapseAll())); shortcutCollapse_All->setObjectName("shortcutCollapse_All"); shortcutCollapse_All->setWhatsThis("Map List: Collapse all folders"); @@ -240,44 +240,9 @@ void MainWindow::initCustomUI() { ui->mainTabBar->addTab(mainTabNames.value(i)); ui->mainTabBar->setTabIcon(i, mainTabIcons.value(i)); } - - WheelFilter *wheelFilter = new WheelFilter(this); - ui->mainTabBar->installEventFilter(wheelFilter); - this->ui->mapListContainer->tabBar()->installEventFilter(wheelFilter); - - // Create buttons for adding and removing items from the mapList - QFrame *frame = new QFrame(this->ui->mapListContainer); - frame->setFrameShape(QFrame::NoFrame); - QHBoxLayout *layout = new QHBoxLayout(frame); - - QPushButton *buttonAdd = new QPushButton(QIcon(":/icons/add.ico"), ""); - connect(buttonAdd, &QPushButton::clicked, [this]() { this->mapListAddItem(); }); - QPushButton *buttonRemove = new QPushButton(QIcon(":/icons/delete.ico"), ""); - connect(buttonRemove, &QPushButton::clicked, [this]() { this->mapListRemoveItem(); }); - - layout->addWidget(buttonAdd); - layout->addWidget(buttonRemove); - - layout->setSpacing(0); - layout->setContentsMargins(0, 0, 0, 0); - - this->ui->mapListContainer->setCornerWidget(frame, Qt::TopRightCorner); } void MainWindow::initExtraSignals() { - // Right-clicking on items in the map list tree view brings up a context menu. - ui->mapList->setContextMenuPolicy(Qt::CustomContextMenu); - connect(ui->mapList, &QTreeView::customContextMenuRequested, - this, &MainWindow::onOpenMapListContextMenu); - - ui->areaList->setContextMenuPolicy(Qt::CustomContextMenu); - connect(ui->areaList, &QTreeView::customContextMenuRequested, - this, &MainWindow::onOpenMapListContextMenu); - - ui->layoutList->setContextMenuPolicy(Qt::CustomContextMenu); - connect(ui->layoutList, &QTreeView::customContextMenuRequested, - this, &MainWindow::onOpenMapListContextMenu); - // other signals connect(ui->newEventToolButton, &NewEventToolButton::newEventAdded, this, &MainWindow::addNewEvent); connect(ui->tabWidget_EventType, &QTabWidget::currentChanged, this, &MainWindow::eventTabChanged); @@ -381,7 +346,7 @@ void MainWindow::initEditor() { ui->menuEdit->addAction(showHistory); // Toggle an asterisk in the window title when the undo state is changed - connect(&editor->editGroup, &QUndoGroup::indexChanged, this, &MainWindow::showWindowTitle); + connect(&editor->editGroup, &QUndoGroup::indexChanged, this, &MainWindow::updateWindowTitle); // selecting objects from the spinners connect(this->ui->spinner_ObjectID, QOverload::of(&QSpinBox::valueChanged), [this](int value) { @@ -405,37 +370,104 @@ void MainWindow::initMiscHeapObjects() { ui->tabWidget_EventType->clear(); } -void MainWindow::initMapSortOrder() { - this->ui->mapListContainer->setCurrentIndex(static_cast(porymapConfig.mapSortOrder)); +void MainWindow::initMapList() { + ui->mapListContainer->setCurrentIndex(static_cast(porymapConfig.mapSortOrder)); + + WheelFilter *wheelFilter = new WheelFilter(this); + ui->mainTabBar->installEventFilter(wheelFilter); + ui->mapListContainer->tabBar()->installEventFilter(wheelFilter); + + // Create buttons for adding and removing items from the mapList + QFrame *buttonFrame = new QFrame(this->ui->mapListContainer); + buttonFrame->setFrameShape(QFrame::NoFrame); + + QHBoxLayout *layout = new QHBoxLayout(buttonFrame); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + + // Create add map/layout button + QPushButton *buttonAdd = new QPushButton(QIcon(":/icons/add.ico"), ""); + connect(buttonAdd, &QPushButton::clicked, this, &MainWindow::on_action_NewMap_triggered); + layout->addWidget(buttonAdd); + + /* TODO: Remove button disabled, no current support for deleting maps/layouts + // Create remove map/layout button + QPushButton *buttonRemove = new QPushButton(QIcon(":/icons/delete.ico"), ""); + connect(buttonRemove, &QPushButton::clicked, this, &MainWindow::deleteCurrentMapOrLayout); + layout->addWidget(buttonRemove); + */ + + ui->mapListContainer->setCornerWidget(buttonFrame, Qt::TopRightCorner); + + // Connect tool bars to lists + ui->mapListToolBar_Groups->setList(ui->mapList); + ui->mapListToolBar_Areas->setList(ui->areaList); + ui->mapListToolBar_Layouts->setList(ui->layoutList); + + // Left-clicking on items in the map list opens the corresponding map/layout. + connect(ui->mapList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem); + connect(ui->areaList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem); + connect(ui->layoutList, &QAbstractItemView::activated, this, &MainWindow::openMapListItem); + + // Right-clicking on items in the map list brings up a context menu. + ui->mapList->setContextMenuPolicy(Qt::CustomContextMenu); + ui->areaList->setContextMenuPolicy(Qt::CustomContextMenu); + ui->layoutList->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->mapList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu); + connect(ui->areaList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu); + connect(ui->layoutList, &QTreeView::customContextMenuRequested, this, &MainWindow::onOpenMapListContextMenu); + + // Only the groups list allows reorganizing folder contents, editing folder names, etc. + ui->mapListToolBar_Areas->setEditsAllowedButtonHidden(true); + ui->mapListToolBar_Layouts->setEditsAllowedButtonHidden(true); + + // When map list search filter is cleared we want the current map/layout in the editor to be visible in the list. + connect(ui->mapListToolBar_Groups, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentMap); + connect(ui->mapListToolBar_Areas, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentMap); + connect(ui->mapListToolBar_Layouts, &MapListToolBar::filterCleared, this, &MainWindow::scrollMapListToCurrentLayout); + + // Connect the "add folder" button in each of the map lists + connect(ui->mapListToolBar_Groups, &MapListToolBar::addFolderClicked, this, &MainWindow::mapListAddGroup); + connect(ui->mapListToolBar_Areas, &MapListToolBar::addFolderClicked, this, &MainWindow::mapListAddArea); + connect(ui->mapListToolBar_Layouts, &MapListToolBar::addFolderClicked, this, &MainWindow::mapListAddLayout); } -void MainWindow::showWindowTitle() { +void MainWindow::updateWindowTitle() { + if (!editor || !editor->project) { + setWindowTitle(QCoreApplication::applicationName()); + return; + } + + const QString projectName = editor->project->getProjectTitle(); + if (!editor->layout) { + setWindowTitle(projectName); + return; + } + if (editor->map) { setWindowTitle(QString("%1%2 - %3") .arg(editor->map->hasUnsavedChanges() ? "* " : "") .arg(editor->map->name) - .arg(editor->project->getProjectTitle()) + .arg(projectName) ); - } - else if (editor->layout) { + } else { setWindowTitle(QString("%1%2 - %3") .arg(editor->layout->hasUnsavedChanges() ? "* " : "") .arg(editor->layout->name) - .arg(editor->project->getProjectTitle()) + .arg(projectName) ); } - if (editor && editor->layout) { - // For some reason (perhaps on Qt < 6?) we had to clear the icon first here or mainTabBar wouldn't display correctly. - ui->mainTabBar->setTabIcon(MainTab::Map, QIcon()); - QPixmap pixmap = editor->layout->pixmap; - if (!pixmap.isNull()) { - ui->mainTabBar->setTabIcon(MainTab::Map, QIcon(pixmap)); - } else { - ui->mainTabBar->setTabIcon(MainTab::Map, QIcon(QStringLiteral(":/icons/map.ico"))); - } + // For some reason (perhaps on Qt < 6?) we had to clear the icon first here or mainTabBar wouldn't display correctly. + ui->mainTabBar->setTabIcon(MainTab::Map, QIcon()); + + QPixmap pixmap = editor->layout->pixmap; + if (!pixmap.isNull()) { + ui->mainTabBar->setTabIcon(MainTab::Map, QIcon(pixmap)); + } else { + ui->mainTabBar->setTabIcon(MainTab::Map, QIcon(QStringLiteral(":/icons/map.ico"))); } - updateMapList(); + updateMapList(); // TODO: Why is this function responsible for this } void MainWindow::markMapEdited() { @@ -448,52 +480,7 @@ void MainWindow::markSpecificMapEdited(Map* map) { map->hasUnsavedDataChanges = true; if (editor && editor->map == map) - showWindowTitle(); -} - -void MainWindow::on_lineEdit_filterBox_textChanged(const QString &text) { - this->applyMapListFilter(text); -} - -void MainWindow::on_lineEdit_filterBox_Areas_textChanged(const QString &text) { - this->applyMapListFilter(text); -} - -void MainWindow::on_lineEdit_filterBox_Layouts_textChanged(const QString &text) { - this->applyMapListFilter(text); -} - -void MainWindow::applyMapListFilter(QString filterText) { - FilterChildrenProxyModel *proxy; - QTreeView *list; - QModelIndex sourceIndex; - switch (porymapConfig.mapSortOrder) { - case MapSortOrder::SortByGroup: - proxy = this->groupListProxyModel; - list = this->ui->mapList; - sourceIndex = mapGroupModel->indexOfMap(editor->map->name); - break; - case MapSortOrder::SortByArea: - proxy = this->areaListProxyModel; - list = this->ui->areaList; - sourceIndex = mapAreaModel->indexOfMap(editor->map->name); - break; - case MapSortOrder::SortByLayout: - proxy = this->layoutListProxyModel; - list = this->ui->layoutList; - sourceIndex = layoutTreeModel->indexOfLayout(editor->layout->id); - break; - } - - proxy->setFilterRegularExpression(QRegularExpression(filterText, QRegularExpression::CaseInsensitiveOption)); - if (filterText.isEmpty()) { - list->collapseAll(); - } else { - list->expandToDepth(0); - } - - list->setExpanded(proxy->mapFromSource(sourceIndex), true); - list->scrollTo(proxy->mapFromSource(sourceIndex), QAbstractItemView::PositionAtCenter); + updateWindowTitle(); } void MainWindow::loadUserSettings() { @@ -640,7 +627,7 @@ bool MainWindow::openProject(QString dir, bool initial) { // Only create the config files once the project has opened successfully in case the user selected an invalid directory this->editor->project->saveConfig(); - showWindowTitle(); + updateWindowTitle(); this->statusBar()->showMessage(QString("Opened %1").arg(projectString)); porymapConfig.projectManuallyClosed = false; @@ -702,7 +689,7 @@ bool MainWindow::setInitialMap() { const QString recent = userConfig.recentMapOrLayout; if (editor->project->mapNames.contains(recent)) { // User recently had a map open that still exists. - if (setMap(recent, true)) + if (setMap(recent)) return true; } else if (editor->project->mapLayoutsTable.contains(recent)) { // User recently had a layout open that still exists. @@ -712,7 +699,7 @@ bool MainWindow::setInitialMap() { // Failed to open recent map/layout, or no recent map/layout. Try opening maps then layouts sequentially. for (const auto &name : editor->project->mapNames) { - if (name != recent && setMap(name, true)) + if (name != recent && setMap(name)) return true; } for (const auto &id : editor->project->mapLayoutsTable) { @@ -808,7 +795,7 @@ void MainWindow::unsetMap() { // setMap, but with a visible error message in case of failure. // Use when the user is specifically requesting a map to open. -bool MainWindow::userSetMap(QString map_name, bool scrollTreeView) { +bool MainWindow::userSetMap(QString map_name) { if (editor->map && editor->map->name == map_name) return true; // Already set @@ -819,7 +806,7 @@ bool MainWindow::userSetMap(QString map_name, bool scrollTreeView) { return false; } - if (!setMap(map_name, scrollTreeView)) { + if (!setMap(map_name)) { QMessageBox msgBox(this); QString errorMsg = QString("There was an error opening map %1. Please see %2 for full error details.\n\n%3") .arg(map_name) @@ -831,7 +818,7 @@ bool MainWindow::userSetMap(QString map_name, bool scrollTreeView) { return true; } -bool MainWindow::setMap(QString map_name, bool scroll) { +bool MainWindow::setMap(QString map_name) { // if map name is empty, clear & disable map ui if (map_name.isEmpty()) { unsetMap(); @@ -851,7 +838,7 @@ bool MainWindow::setMap(QString map_name, bool scroll) { } if (editor->map && !editor->map->name.isNull()) { - ui->mapList->setExpanded(groupListProxyModel->mapFromSource(mapGroupModel->indexOfMap(map_name)), false); + ui->mapList->setExpanded(groupListProxyModel->mapFromSource(mapGroupModel->indexOf(map_name)), false); } setLayoutOnlyMode(false); @@ -859,12 +846,8 @@ bool MainWindow::setMap(QString map_name, bool scroll) { refreshMapScene(); displayMapProperties(); - - if (scroll) { - scrollTreeView(map_name); - } - - showWindowTitle(); + updateWindowTitle(); + resetMapListFilters(); connect(editor->map, &Map::mapNeedsRedrawing, this, &MainWindow::onMapNeedsRedrawing, Qt::UniqueConnection); connect(editor->map, &Map::modified, this, &MainWindow::markMapEdited, Qt::UniqueConnection); @@ -892,12 +875,28 @@ void MainWindow::setLayoutOnlyMode(bool layoutOnly) { this->ui->comboBox_LayoutSelector->setEnabled(mapEditingEnabled); } +// setLayout, but with a visible error message in case of failure. +// Use when the user is specifically requesting a layout to open. +bool MainWindow::userSetLayout(QString layoutId) { + if (!setLayout(layoutId)) { + QMessageBox msgBox(this); + QString errorMsg = QString("There was an error opening layout %1. Please see %2 for full error details.\n\n%3") + .arg(layoutId) + .arg(getLogPath()) + .arg(getMostRecentError()); + msgBox.critical(nullptr, "Error Opening Layout", errorMsg); + return false; + } + return true; +} + bool MainWindow::setLayout(QString layoutId) { if (this->editor->map) logInfo("Switching to a layout-only editing mode. Disabling map-related edits."); - setMap(QString()); + unsetMap(); + // TODO: Using the 'id' instead of the layout name here is inconsistent with how we treat maps. logInfo(QString("Setting layout to '%1'").arg(layoutId)); if (!this->editor->setLayout(layoutId)) { @@ -907,8 +906,8 @@ bool MainWindow::setLayout(QString layoutId) { layoutTreeModel->setLayout(layoutId); refreshMapScene(); - showWindowTitle(); - updateMapList(); + updateWindowTitle(); + resetMapListFilters(); connect(editor->layout, &Layout::needsRedrawing, this, &MainWindow::onLayoutNeedsRedrawing, Qt::UniqueConnection); @@ -969,7 +968,7 @@ void MainWindow::openWarpMap(QString map_name, int event_id, Event::Group event_ } // Open the destination map. - if (!userSetMap(map_name, true)) + if (!userSetMap(map_name)) return; // Select the target event. @@ -1229,7 +1228,7 @@ bool MainWindow::setProjectUI() { this->layoutListProxyModel->setSourceModel(this->layoutTreeModel); ui->layoutList->setModel(layoutListProxyModel); - on_toolButton_EnableDisable_EditGroups_clicked(); + //on_toolButton_EnableDisable_EditGroups_clicked();//TODO return true; } @@ -1245,8 +1244,7 @@ void MainWindow::clearProjectUI() { const QSignalBlocker blocker7(ui->comboBox_Type); const QSignalBlocker blocker8(ui->comboBox_DiveMap); const QSignalBlocker blocker9(ui->comboBox_EmergeMap); - const QSignalBlocker blockerA(ui->lineEdit_filterBox); - const QSignalBlocker blockerB(ui->comboBox_LayoutSelector); + const QSignalBlocker blockerA(ui->comboBox_LayoutSelector); ui->comboBox_Song->clear(); ui->comboBox_Location->clear(); @@ -1257,49 +1255,51 @@ void MainWindow::clearProjectUI() { ui->comboBox_Type->clear(); ui->comboBox_DiveMap->clear(); ui->comboBox_EmergeMap->clear(); - ui->lineEdit_filterBox->clear(); ui->comboBox_LayoutSelector->clear(); // Clear map models - if (this->mapGroupModel) { - delete this->mapGroupModel; - this->mapGroupModel = nullptr; - delete this->groupListProxyModel; - this->groupListProxyModel = nullptr; - } - if (this->mapAreaModel) { - delete this->mapAreaModel; - this->mapAreaModel = nullptr; - delete this->areaListProxyModel; - this->areaListProxyModel = nullptr; - } - if (this->layoutTreeModel) { - delete this->layoutTreeModel; - this->layoutTreeModel = nullptr; - delete this->layoutListProxyModel; - this->layoutListProxyModel = nullptr; - } + delete this->mapGroupModel; + delete this->groupListProxyModel; + delete this->mapAreaModel; + delete this->areaListProxyModel; + delete this->layoutTreeModel; + delete this->layoutListProxyModel; + resetMapListFilters(); Event::clearIcons(); } -void MainWindow::scrollTreeView(QString itemName) { - switch (ui->mapListContainer->currentIndex()) { - case MapListTab::Groups: - groupListProxyModel->setFilterRegularExpression(QString()); - ui->mapList->setCurrentIndex(groupListProxyModel->mapFromSource(mapGroupModel->indexOfMap(itemName))); - ui->mapList->scrollTo(ui->mapList->currentIndex(), QAbstractItemView::PositionAtCenter); - break; - case MapListTab::Areas: - areaListProxyModel->setFilterRegularExpression(QString()); - ui->areaList->setCurrentIndex(areaListProxyModel->mapFromSource(mapAreaModel->indexOfMap(itemName))); - ui->areaList->scrollTo(ui->areaList->currentIndex(), QAbstractItemView::PositionAtCenter); - break; - case MapListTab::Layouts: - layoutListProxyModel->setFilterRegularExpression(QString()); - ui->layoutList->setCurrentIndex(layoutListProxyModel->mapFromSource(layoutTreeModel->indexOfLayout(itemName))); - ui->layoutList->scrollTo(ui->layoutList->currentIndex(), QAbstractItemView::PositionAtCenter); - break; +void MainWindow::scrollMapList(MapTree *list, QString itemName) { + if (!list || itemName.isEmpty()) + return; + auto model = static_cast(list->model()); + if (!model) + return; + auto sourceModel = static_cast(model->sourceModel()); + if (!sourceModel) + return; + QModelIndex sourceIndex = sourceModel->indexOf(itemName); + if (!sourceIndex.isValid()) + return; + QModelIndex index = model->mapFromSource(sourceIndex); + if (!index.isValid()) + return; + + list->setCurrentIndex(index); + list->setExpanded(index, true); + list->scrollTo(index, QAbstractItemView::PositionAtCenter); +} + +void MainWindow::scrollMapListToCurrentMap(MapTree *list) { + if (this->editor->map) { + scrollMapList(list, this->editor->map->name); + } +} + +// TODO: Initial scrolling doesn't center the layout on launch if it's not the current tab. +void MainWindow::scrollMapListToCurrentLayout(MapTree *list) { + if (this->editor->layout) { + scrollMapList(list, this->editor->layout->id); } } @@ -1346,6 +1346,7 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) { QStandardItem *selectedItem = model->itemFromIndex(index); if (selectedItem->parent()) { + // TODO: Right-click delete on maps? return; } @@ -1376,6 +1377,7 @@ void MainWindow::mapListAddGroup() { connect(&newItemButtonBox, &QDialogButtonBox::accepted, [&](){ if (!this->editor->project->groupNames.contains(newNameEdit->text())) dialog.accept(); + // TODO: Else display error? }); QFormLayout form(&dialog); @@ -1390,6 +1392,8 @@ void MainWindow::mapListAddGroup() { } } +// TODO: Pull this all out into a custom window. Connect that to an action in the main menu as well. +// (or, re-use the new map dialog with some tweaks) void MainWindow::mapListAddLayout() { if (!editor || !editor->project) return; @@ -1421,6 +1425,7 @@ void MainWindow::mapListAddLayout() { errorMessageLabel->setStyleSheet("QLabel { background-color: rgba(255, 0, 0, 25%) }"); QString errorMessage; + // TODO: Select default tilesets QComboBox *primaryCombo = new QComboBox(&dialog); primaryCombo->addItems(this->editor->project->primaryTilesetLabels); QComboBox *secondaryCombo = new QComboBox(&dialog); @@ -1529,14 +1534,19 @@ void MainWindow::mapListAddArea() { newNameEdit->setValidator(new QRegularExpressionValidator(re_validChars, newNameEdit)); connect(&newItemButtonBox, &QDialogButtonBox::accepted, [&](){ - if (!this->editor->project->mapSectionNameToValue.contains(newNameEdit->text())) + if (!this->editor->project->mapSectionNameToValue.contains(newNameDisplay->text())) dialog.accept(); + // TODO: Else display error? }); + QLabel *newNameEditLabel = new QLabel("New Map Section Name", &dialog); + QLabel *newNameDisplayLabel = new QLabel("Constant Name", &dialog); + newNameDisplayLabel->setEnabled(false); + QFormLayout form(&dialog); - form.addRow("New Map Section Name", newNameEdit); - form.addRow("Constant Name", newNameDisplay); + form.addRow(newNameEditLabel, newNameEdit); + form.addRow(newNameDisplayLabel, newNameDisplay); form.addRow(&newItemButtonBox); if (dialog.exec() == QDialog::Accepted) { @@ -1545,22 +1555,7 @@ void MainWindow::mapListAddArea() { } } -void MainWindow::mapListAddItem() { - if (!this->editor || !this->editor->project) return; - - switch (this->ui->mapListContainer->currentIndex()) { - case MapListTab::Groups: - this->mapListAddGroup(); - break; - case MapListTab::Areas: - this->mapListAddArea(); - break; - case MapListTab::Layouts: - this->mapListAddLayout(); - break; - } -} - +// TODO: Connect to right-click on map group folder in list void MainWindow::mapListRemoveGroup() { QItemSelectionModel *selectionModel = this->ui->mapList->selectionModel(); if (selectionModel->hasSelection()) { @@ -1579,6 +1574,7 @@ void MainWindow::mapListRemoveGroup() { } } +// TODO: Decide what to do about this. Currently unused. void MainWindow::mapListRemoveArea() { QItemSelectionModel *selectionModel = this->ui->areaList->selectionModel(); if (selectionModel->hasSelection()) { @@ -1597,27 +1593,11 @@ void MainWindow::mapListRemoveArea() { } } +// TODO: Connect to right-click on layout void MainWindow::mapListRemoveLayout() { // TODO: consider this in the future } -void MainWindow::mapListRemoveItem() { - if (!this->editor || !this->editor->project) return; - - switch (this->ui->mapListContainer->currentIndex()) { - case MapListTab::Groups: - this->mapListRemoveGroup(); - break; - case MapListTab::Areas: - // Disabled - // this->mapListRemoveArea(); - break; - case MapListTab::Layouts: - // Disabled - // this->mapListRemoveLayout(); - break; - } -} void MainWindow::onAddNewMapToGroupClick(QAction* triggeredAction) { if (!triggeredAction) return; @@ -1661,7 +1641,7 @@ void MainWindow::onNewMapCreated() { this->mapAreaModel->insertMapItem(newMapName, newMap->location, newMapGroup); this->layoutTreeModel->insertMapItem(newMapName, newMap->layout->id); - setMap(newMapName, true); + setMap(newMapName); // Refresh any combo box that displays map names and persists between maps // (other combo boxes like for warp destinations are repopulated when the map changes). @@ -1877,51 +1857,42 @@ void MainWindow::currentMetatilesSelectionChanged() { scrollMetatileSelectorToSelection(); } +// TODO: Redundant. Remove void MainWindow::on_mapListContainer_currentChanged(int index) { switch (index) { case MapListTab::Groups: porymapConfig.mapSortOrder = MapSortOrder::SortByGroup; - if (this->editor && this->editor->map) scrollTreeView(this->editor->map->name); break; case MapListTab::Areas: porymapConfig.mapSortOrder = MapSortOrder::SortByArea; - if (this->editor && this->editor->map) scrollTreeView(this->editor->map->name); break; case MapListTab::Layouts: porymapConfig.mapSortOrder = MapSortOrder::SortByLayout; - if (this->editor && this->editor->layout) scrollTreeView(this->editor->layout->id); break; } } -void MainWindow::on_mapList_activated(const QModelIndex &index) { - QVariant data = index.data(Qt::UserRole); - if (index.data(MapListUserRoles::TypeRole) == "map_name" && !data.isNull()) { - QString mapName = data.toString(); - userSetMap(mapName); - } -} - -void MainWindow::on_areaList_activated(const QModelIndex &index) { - on_mapList_activated(index); -} - -void MainWindow::on_layoutList_activated(const QModelIndex &index) { - if (!index.isValid()) return; +void MainWindow::openMapListItem(const QModelIndex &index) { + if (!index.isValid()) + return; QVariant data = index.data(Qt::UserRole); - if (index.data(MapListUserRoles::TypeRole) == "map_layout" && !data.isNull()) { - QString layoutId = data.toString(); + if (data.isNull()) + return; - if (!setLayout(layoutId)) { - QMessageBox msgBox(this); - QString errorMsg = QString("There was an error opening layout %1. Please see %2 for full error details.\n\n%3") - .arg(layoutId) - .arg(getLogPath()) - .arg(getMostRecentError()); - msgBox.critical(nullptr, "Error Opening Layout", errorMsg); - } + // Normally when a new map/layout is opened the search filters are cleared and the lists will scroll to display that map/layout in the list. + // We don't want to do this when the user interacts with a list directly, so we temporarily prevent changes to the search filter. + auto toolbar = getCurrentMapListToolBar(); + if (toolbar) toolbar->setFilterLocked(true); + + QString type = index.data(MapListUserRoles::TypeRole).toString(); + if (type == "map_name") { + userSetMap(data.toString()); + } else if (type == "map_layout") { + userSetLayout(data.toString()); } + + if (toolbar) toolbar->setFilterLocked(false); } void MainWindow::updateMapList() { @@ -1930,8 +1901,7 @@ void MainWindow::updateMapList() { this->groupListProxyModel->layoutChanged(); this->mapAreaModel->setMap(this->editor->map->name); this->areaListProxyModel->layoutChanged(); - } - else { + } else { this->mapGroupModel->setMap(QString()); this->groupListProxyModel->layoutChanged(); this->ui->mapList->clearSelection(); @@ -1943,8 +1913,7 @@ void MainWindow::updateMapList() { if (this->editor->layout) { this->layoutTreeModel->setLayout(this->editor->layout->id); this->layoutListProxyModel->layoutChanged(); - } - else { + } else { this->layoutTreeModel->setLayout(QString()); this->layoutListProxyModel->layoutChanged(); this->ui->layoutList->clearSelection(); @@ -1953,14 +1922,12 @@ void MainWindow::updateMapList() { void MainWindow::on_action_Save_Project_triggered() { editor->saveProject(); - updateMapList(); - showWindowTitle(); + updateWindowTitle(); } void MainWindow::on_action_Save_triggered() { editor->save(); - updateMapList(); - showWindowTitle(); + updateWindowTitle(); } void MainWindow::duplicate() { @@ -2884,7 +2851,7 @@ void MainWindow::clickToolButtonFromEditAction(Editor::EditAction editAction) { void MainWindow::onOpenConnectedMap(MapConnection *connection) { if (!connection) return; - if (userSetMap(connection->targetMapName(), true)) + if (userSetMap(connection->targetMapName())) editor->setSelectedConnection(connection->findMirror()); } @@ -2904,6 +2871,7 @@ void MainWindow::onMapLoaded(Map *map) { connect(map, &Map::modified, [this, map] { this->markSpecificMapEdited(map); }); } +// TODO: editor->layout below? and redrawLayoutScene? void MainWindow::onTilesetsSaved(QString primaryTilesetLabel, QString secondaryTilesetLabel) { // If saved tilesets are currently in-use, update them and redraw // Otherwise overwrite the cache for the saved tileset @@ -3042,13 +3010,13 @@ void MainWindow::on_pushButton_ConfigureEncountersJSON_clicked() { void MainWindow::on_button_OpenDiveMap_clicked() { const QString mapName = ui->comboBox_DiveMap->currentText(); if (editor->project->mapNames.contains(mapName)) - userSetMap(mapName, true); + userSetMap(mapName); } void MainWindow::on_button_OpenEmergeMap_clicked() { const QString mapName = ui->comboBox_EmergeMap->currentText(); if (editor->project->mapNames.contains(mapName)) - userSetMap(mapName, true); + userSetMap(mapName); } void MainWindow::on_comboBox_DiveMap_currentTextChanged(const QString &mapName) { @@ -3211,124 +3179,36 @@ void MainWindow::initTilesetEditor() { connect(this->tilesetEditor, &TilesetEditor::tilesetsSaved, this, &MainWindow::onTilesetsSaved); } -void MainWindow::do_ExpandAll() { +MapListToolBar* MainWindow::getCurrentMapListToolBar() { switch (ui->mapListContainer->currentIndex()) { - case MapListTab::Groups: - this->on_toolButton_ExpandAll_Groups_clicked(); - break; - case MapListTab::Areas: - this->on_toolButton_ExpandAll_Areas_clicked(); - break; - case MapListTab::Layouts: - this->on_toolButton_ExpandAll_Layouts_clicked(); - break; + case MapListTab::Groups: return ui->mapListToolBar_Groups; + case MapListTab::Areas: return ui->mapListToolBar_Areas; + case MapListTab::Layouts: return ui->mapListToolBar_Layouts; + default: return nullptr; } } -void MainWindow::do_CollapseAll() { - switch (ui->mapListContainer->currentIndex()) { - case MapListTab::Groups: - this->on_toolButton_CollapseAll_Groups_clicked(); - break; - case MapListTab::Areas: - this->on_toolButton_CollapseAll_Areas_clicked(); - break; - case MapListTab::Layouts: - this->on_toolButton_CollapseAll_Layouts_clicked(); - break; - } +// Clear the search filters on all the map lists. +// When the search filter is cleared the map lists will (if possible) display the currently-selected map/layout. +void MainWindow::resetMapListFilters() { + ui->mapListToolBar_Groups->clearFilter(); + ui->mapListToolBar_Areas->clearFilter(); + ui->mapListToolBar_Layouts->clearFilter(); } -// TODO: Save this state in porymapConfig -void MainWindow::do_HideShow() { - switch (ui->mapListContainer->currentIndex()) { - case MapListTab::Groups: - this->on_toolButton_HideShow_Groups_clicked(); - break; - case MapListTab::Areas: - this->on_toolButton_HideShow_Areas_clicked(); - break; - case MapListTab::Layouts: - this->on_toolButton_HideShow_Layouts_clicked(); - break; - } +void MainWindow::mapListShortcut_ExpandAll() { + auto toolbar = getCurrentMapListToolBar(); + if (toolbar) toolbar->expandList(); } -void MainWindow::on_toolButton_HideShow_Groups_clicked() { - if (ui->mapList) { - this->groupListProxyModel->toggleHideEmpty(); - this->groupListProxyModel->setFilterRegularExpression(this->ui->lineEdit_filterBox->text()); - } +void MainWindow::mapListShortcut_CollapseAll() { + auto toolbar = getCurrentMapListToolBar(); + if (toolbar) toolbar->collapseList(); } -void MainWindow::on_toolButton_ExpandAll_Groups_clicked() { - if (ui->mapList) { - ui->mapList->expandToDepth(0); - } -} - -void MainWindow::on_toolButton_CollapseAll_Groups_clicked() { - if (ui->mapList) { - ui->mapList->collapseAll(); - } -} - -// TODO: Save this state in porymapConfig -void MainWindow::on_toolButton_EnableDisable_EditGroups_clicked() { - this->ui->mapList->clearSelection(); - if (this->ui->toolButton_EnableDisable_EditGroups->isChecked()) { - ui->mapList->setSelectionMode(QAbstractItemView::ExtendedSelection); - ui->mapList->setDragEnabled(true); - ui->mapList->setAcceptDrops(true); - ui->mapList->setDropIndicatorShown(true); - ui->mapList->setDragDropMode(QAbstractItemView::InternalMove); - ui->mapList->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); - } else { - ui->mapList->setSelectionMode(QAbstractItemView::NoSelection); - ui->mapList->setDragEnabled(false); - ui->mapList->setAcceptDrops(false); - ui->mapList->setDropIndicatorShown(false); - ui->mapList->setDragDropMode(QAbstractItemView::NoDragDrop); - ui->mapList->setEditTriggers(QAbstractItemView::NoEditTriggers); - } -} - -void MainWindow::on_toolButton_HideShow_Areas_clicked() { - if (ui->areaList) { - this->areaListProxyModel->toggleHideEmpty(); - this->areaListProxyModel->setFilterRegularExpression(this->ui->lineEdit_filterBox->text()); - } -} - -void MainWindow::on_toolButton_ExpandAll_Areas_clicked() { - if (ui->areaList) { - ui->areaList->expandToDepth(0); - } -} - -void MainWindow::on_toolButton_CollapseAll_Areas_clicked() { - if (ui->areaList) { - ui->areaList->collapseAll(); - } -} - -void MainWindow::on_toolButton_HideShow_Layouts_clicked() { - if (ui->layoutList) { - this->layoutListProxyModel->toggleHideEmpty(); - this->layoutListProxyModel->setFilterRegularExpression(this->ui->lineEdit_filterBox->text()); - } -} - -void MainWindow::on_toolButton_ExpandAll_Layouts_clicked() { - if (ui->layoutList) { - ui->layoutList->expandToDepth(0); - } -} - -void MainWindow::on_toolButton_CollapseAll_Layouts_clicked() { - if (ui->layoutList) { - ui->layoutList->collapseAll(); - } +void MainWindow::mapListShortcut_ToggleEmptyFolders() { + auto toolbar = getCurrentMapListToolBar(); + if (toolbar) toolbar->toggleEmptyFolders(); } void MainWindow::on_actionAbout_Porymap_triggered() @@ -3646,7 +3526,7 @@ bool MainWindow::closeProject() { editor->closeProject(); clearProjectUI(); setWindowDisabled(true); - setWindowTitle(QCoreApplication::applicationName()); + updateWindowTitle(); return true; } diff --git a/src/ui/maplistmodels.cpp b/src/ui/maplistmodels.cpp index 7e0d7e62..e9fbaa1f 100644 --- a/src/ui/maplistmodels.cpp +++ b/src/ui/maplistmodels.cpp @@ -44,7 +44,7 @@ void GroupNameDelegate::updateEditorGeometry(QWidget *editor, const QStyleOption -MapGroupModel::MapGroupModel(Project *project, QObject *parent) : QStandardItemModel(parent) { +MapGroupModel::MapGroupModel(Project *project, QObject *parent) : MapListModel(parent) { this->project = project; this->root = this->invisibleRootItem(); @@ -283,7 +283,7 @@ QStandardItem *MapGroupModel::getItem(const QModelIndex &index) const { return this->root; } -QModelIndex MapGroupModel::indexOfMap(QString mapName) { +QModelIndex MapGroupModel::indexOf(QString mapName) const { if (this->mapItems.contains(mapName)) { return this->mapItems[mapName]->index(); } @@ -366,7 +366,7 @@ bool MapGroupModel::setData(const QModelIndex &index, const QVariant &value, int -MapAreaModel::MapAreaModel(Project *project, QObject *parent) : QStandardItemModel(parent) { +MapAreaModel::MapAreaModel(Project *project, QObject *parent) : MapListModel(parent) { this->project = project; this->root = this->invisibleRootItem(); @@ -461,7 +461,7 @@ QStandardItem *MapAreaModel::getItem(const QModelIndex &index) const { return this->root; } -QModelIndex MapAreaModel::indexOfMap(QString mapName) { +QModelIndex MapAreaModel::indexOf(QString mapName) const { if (this->mapItems.contains(mapName)) { return this->mapItems[mapName]->index(); } @@ -531,7 +531,7 @@ QVariant MapAreaModel::data(const QModelIndex &index, int role) const { -LayoutTreeModel::LayoutTreeModel(Project *project, QObject *parent) : QStandardItemModel(parent) { +LayoutTreeModel::LayoutTreeModel(Project *project, QObject *parent) : MapListModel(parent) { this->project = project; this->root = this->invisibleRootItem(); @@ -609,7 +609,7 @@ QStandardItem *LayoutTreeModel::getItem(const QModelIndex &index) const { return this->root; } -QModelIndex LayoutTreeModel::indexOfLayout(QString layoutName) { +QModelIndex LayoutTreeModel::indexOf(QString layoutName) const { if (this->layoutItems.contains(layoutName)) { return this->layoutItems[layoutName]->index(); } diff --git a/src/ui/maplisttoolbar.cpp b/src/ui/maplisttoolbar.cpp new file mode 100644 index 00000000..4dd26ecd --- /dev/null +++ b/src/ui/maplisttoolbar.cpp @@ -0,0 +1,121 @@ +#include "maplisttoolbar.h" +#include "ui_maplisttoolbar.h" +#include "editor.h" + +#include + +MapListToolBar::MapListToolBar(QWidget *parent) + : QFrame(parent) + , ui(new Ui::MapListToolBar) +{ + ui->setupUi(this); + + connect(ui->button_ToggleEmptyFolders, &QAbstractButton::clicked, this, &MapListToolBar::toggleEmptyFolders); + connect(ui->button_AddFolder, &QAbstractButton::clicked, this, &MapListToolBar::addFolderClicked); // TODO: Tool tip + connect(ui->button_ExpandAll, &QAbstractButton::clicked, this, &MapListToolBar::expandList); + connect(ui->button_CollapseAll, &QAbstractButton::clicked, this, &MapListToolBar::collapseList); + connect(ui->button_ToggleEdit, &QAbstractButton::clicked, this, &MapListToolBar::toggleEditsAllowed); + connect(ui->lineEdit_filterBox, &QLineEdit::textChanged, this, &MapListToolBar::applyFilter); +} + +MapListToolBar::~MapListToolBar() +{ + delete ui; +} + +void MapListToolBar::setList(MapTree *list) { + m_list = list; + + // Sync list with current button states + setEditsAllowed(ui->button_ToggleEdit->isChecked()); + // TODO: Empty folders +} + +void MapListToolBar::setEditsAllowedButtonHidden(bool hidden) { + ui->button_ToggleEdit->setVisible(!hidden); +} + +void MapListToolBar::setEditsAllowed(bool allowed) { + if (!m_list) + return; + + if (allowed) { + m_list->setSelectionMode(QAbstractItemView::ExtendedSelection); + m_list->setDragEnabled(true); + m_list->setAcceptDrops(true); + m_list->setDropIndicatorShown(true); + m_list->setDragDropMode(QAbstractItemView::InternalMove); + m_list->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); + } else { + m_list->setSelectionMode(QAbstractItemView::NoSelection); + m_list->setDragEnabled(false); + m_list->setAcceptDrops(false); + m_list->setDropIndicatorShown(false); + m_list->setDragDropMode(QAbstractItemView::NoDragDrop); + m_list->setEditTriggers(QAbstractItemView::NoEditTriggers); + } +} + +// TODO: Sync the UI in each of these + +void MapListToolBar::toggleEmptyFolders() { + if (!m_list) + return; + + auto model = static_cast(m_list->model()); + if (!model) + return; + + bool hidden = model->toggleHideEmpty(); + model->setFilterRegularExpression(ui->lineEdit_filterBox->text()); + + // Update tool tip to reflect what will happen if the button is pressed. + const QString toolTip = QString("%1 empty folders in the list.").arg(hidden ? "Show" : "Hide"); + ui->button_ToggleEmptyFolders->setToolTip(toolTip); + + // Display message to let user know what just happened (if there are no empty folders visible it's not obvious). + const QString message = QString("%1 empty folders!").arg(hidden ? "Hiding" : "Showing"); + QToolTip::showText(ui->button_ToggleEmptyFolders->mapToGlobal(QPoint(0, 0)), message); +} + +void MapListToolBar::expandList() { + if (m_list) + m_list->expandToDepth(0); +} + +void MapListToolBar::collapseList() { + if (m_list) { + m_list->collapseAll(); + } +} + +// TODO: Save this state in porymapConfig? +// TODO: This isn't actually toggling anything, it's just updating based on the button +void MapListToolBar::toggleEditsAllowed() { + if (m_list) { + m_list->clearSelection(); + } + setEditsAllowed(ui->button_ToggleEdit->isChecked()); +} + +void MapListToolBar::applyFilter(const QString &filterText) { + if (!m_list || m_filterLocked) + return; + + const QSignalBlocker b(ui->lineEdit_filterBox); + ui->lineEdit_filterBox->setText(filterText); + + auto model = static_cast(m_list->model()); + if (model) model->setFilterRegularExpression(QRegularExpression(filterText, QRegularExpression::CaseInsensitiveOption)); + + if (filterText.isEmpty()) { + m_list->collapseAll(); + emit filterCleared(m_list); + } else { + m_list->expandToDepth(0); + } +} + +void MapListToolBar::clearFilter() { + applyFilter(""); +}