diff --git a/forms/mainwindow.ui b/forms/mainwindow.ui index 93f5756e..7f85664d 100644 --- a/forms/mainwindow.ui +++ b/forms/mainwindow.ui @@ -10,12 +10,6 @@ 747 - - - 0 - 0 - - porymap @@ -71,12 +65,6 @@ true - - - 0 - 0 - - :/icons/sort_alphabet.ico:/icons/sort_alphabet.ico @@ -88,7 +76,7 @@ - QToolButton::MenuButtonPopup + QToolButton::InstantPopup Qt::ToolButtonIconOnly @@ -111,7 +99,7 @@ - 24 + 12 20 @@ -122,12 +110,6 @@ true - - - 0 - 0 - - @@ -2391,6 +2373,45 @@ Tileset Editor + + + true + + + + :/icons/sort_alphabet.ico:/icons/sort_alphabet.ico + + + Sort by &Name + + + + + true + + + + :/icons/sort_number.ico:/icons/sort_number.ico + + + Sort by &Group + + + Sort by Group + + + + + true + + + + :/icons/sort_map.ico:/icons/sort_map.ico + + + Sort by &Layout + + diff --git a/include/mainwindow.h b/include/mainwindow.h index 1eb1ed43..7e295e19 100644 --- a/include/mainwindow.h +++ b/include/mainwindow.h @@ -13,6 +13,7 @@ #include "map.h" #include "editor.h" #include "tileseteditor.h" +#include "filterchildrenproxymodel.h" namespace Ui { class MainWindow; @@ -128,19 +129,32 @@ private slots: void on_actionTileset_Editor_triggered(); + void mapSortOrder_changed(QAction *action); + + void on_lineEdit_filterBox_textChanged(const QString &arg1); + private: Ui::MainWindow *ui; TilesetEditor *tilesetEditor = nullptr; + FilterChildrenProxyModel *mapListProxyModel; QStandardItemModel *mapListModel; - QList *mapGroupsModel; + QList *mapGroupItemsList; QMap mapListIndexes; Editor *editor = nullptr; QIcon* mapIcon; QIcon* mapEditedIcon; + + enum MapSortOrder { + Group = 0, + Name = 1, + Layout = 2, + } mapSortOrder; + void setMap(QString, bool scrollTreeView = false); void redrawMapScene(); void loadDataStructures(); void populateMapList(); + void sortMapList(); QString getExistingDirectory(QString); void openProject(QString dir); QString getDefaultMap(); @@ -157,14 +171,18 @@ private: void initExtraShortcuts(); void initExtraSignals(); void initEditor(); + void initMiscHeapObjects(); + void initMapSortOrder(); void loadUserSettings(); void openRecentProject(); void updateTilesetEditor(); + + bool isProjectOpen(); }; enum MapListUserRoles { GroupRole = Qt::UserRole + 1, // Used to hold the map group number. - TypeRole = Qt::UserRole + 2, // Used to differentiate between the different layers of the map list tree view. + TypeRole, // Used to differentiate between the different layers of the map list tree view. }; #endif // MAINWINDOW_H diff --git a/include/project.h b/include/project.h index fa4ee2ed..c3d1bc66 100644 --- a/include/project.h +++ b/include/project.h @@ -64,6 +64,9 @@ public: QString getNewMapName(); QString getProjectTitle(); + QString readMapLayoutId(QString map_name); + QString readMapLocation(QString map_name); + QList* getLabelMacros(QList*, QString); QStringList* getLabelValues(QList*, QString); void readMapHeader(Map*); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8dbc04e3..3d7579b0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -39,6 +39,8 @@ MainWindow::MainWindow(QWidget *parent) : this->initExtraSignals(); this->initExtraShortcuts(); this->initEditor(); + this->initMiscHeapObjects(); + this->initMapSortOrder(); this->openRecentProject(); on_toolButton_Paint_clicked(); @@ -72,12 +74,89 @@ void MainWindow::initEditor() { this->loadUserSettings(); } +void MainWindow::initMiscHeapObjects() { + mapIcon = new QIcon; + mapIcon->addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off); + mapIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal, QIcon::On); + + mapEditedIcon = new QIcon; + mapEditedIcon->addFile(QStringLiteral(":/icons/map_edited.ico"), QSize(), QIcon::Normal, QIcon::Off); + mapEditedIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal , QIcon::On); + + mapListModel = new QStandardItemModel; + mapGroupItemsList = new QList; + mapListProxyModel = new FilterChildrenProxyModel; + + mapListProxyModel->setSourceModel(mapListModel); + ui->mapList->setModel(mapListProxyModel); +} + +void MainWindow::initMapSortOrder() { + QMenu *mapSortOrderMenu = new QMenu(); + QActionGroup *mapSortOrderActionGroup = new QActionGroup(ui->toolButton_MapSortOrder); + + mapSortOrderMenu->addAction(ui->actionSort_by_Group); + mapSortOrderMenu->addAction(ui->actionSort_by_Name); + mapSortOrderMenu->addAction(ui->actionSort_by_Layout); + ui->toolButton_MapSortOrder->setMenu(mapSortOrderMenu); + + mapSortOrderActionGroup->addAction(ui->actionSort_by_Group); + mapSortOrderActionGroup->addAction(ui->actionSort_by_Name); + mapSortOrderActionGroup->addAction(ui->actionSort_by_Layout); + + connect(ui->toolButton_MapSortOrder, &QToolButton::triggered, this, &MainWindow::mapSortOrder_changed); + + QAction* sortOrder = ui->toolButton_MapSortOrder->menu()->actions()[mapSortOrder]; + ui->toolButton_MapSortOrder->setIcon(sortOrder->icon()); + sortOrder->setChecked(true); +} + +void MainWindow::mapSortOrder_changed(QAction *action) +{ + QSettings settings; + + QList items = ui->toolButton_MapSortOrder->menu()->actions(); + int i = 0; + for (; i < items.count(); i++) + { + if(items[i] == action) + { + break; + } + } + + if (i != mapSortOrder) + { + ui->toolButton_MapSortOrder->setIcon(action->icon()); + mapSortOrder = static_cast(i); + settings.setValue("map_sort_order", i); + + if (isProjectOpen()) + { + sortMapList(); + } + } +} + +void MainWindow::on_lineEdit_filterBox_textChanged(const QString &arg1) +{ + mapListProxyModel->setFilterRegExp(QRegExp(arg1, Qt::CaseInsensitive, QRegExp::FixedString)); + ui->mapList->expandToDepth(0); + ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(editor->map->name)), true); +} + void MainWindow::loadUserSettings() { QSettings settings; bool betterCursors = settings.contains("cursor_mode") && settings.value("cursor_mode") != "0"; ui->actionBetter_Cursors->setChecked(betterCursors); this->editor->settings->betterCursors = betterCursors; + + if (!settings.contains("map_sort_order")) + { + settings.setValue("map_sort_order", 0); + } + mapSortOrder = static_cast(settings.value("map_sort_order").toInt()); } void MainWindow::openRecentProject() { @@ -99,11 +178,7 @@ void MainWindow::openProject(QString dir) { this->statusBar()->showMessage(QString("Opening project %1").arg(dir)); - bool already_open = ( - (editor && editor != nullptr) - && (editor->project && editor->project != nullptr) - && (editor->project->root == dir) - ); + bool already_open = isProjectOpen() && (editor->project->root == dir); if (!already_open) { editor->project = new Project; editor->project->root = dir; @@ -120,6 +195,11 @@ void MainWindow::openProject(QString dir) { this->statusBar()->showMessage(QString("Opened project %1").arg(dir)); } +bool MainWindow::isProjectOpen() { + return (editor && editor != nullptr) + && (editor->project && editor->project != nullptr); +} + QString MainWindow::getDefaultMap() { if (editor && editor->project) { QList names = editor->project->groupedMapNames; @@ -181,15 +261,15 @@ void MainWindow::setMap(QString map_name, bool scrollTreeView) { return; } if (editor->map != nullptr && !editor->map->name.isNull()) { - ui->mapList->setExpanded(mapListIndexes.value(editor->map->name), false); + ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(editor->map->name)), false); } - ui->mapList->setExpanded(mapListIndexes.value(map_name), true); + ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name)), true); editor->setMap(map_name); redrawMapScene(); displayMapProperties(); if (scrollTreeView) { - ui->mapList->setCurrentIndex(mapListIndexes.value(map_name)); + ui->mapList->setCurrentIndex(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name))); ui->mapList->scrollTo(ui->mapList->currentIndex(), QAbstractItemView::PositionAtCenter); } @@ -258,6 +338,7 @@ void MainWindow::openWarpMap(QString map_name, QString warp_num) { } // Open the destination map, and select the target warp event. + mapListProxyModel->setFilterRegExp(QString::null); setMap(map_name, true); QList warp_events = editor->map->events["warp_event_group"]; if (warp_events.length() > warpNum) { @@ -416,6 +497,11 @@ void MainWindow::loadDataStructures() { } void MainWindow::populateMapList() { + editor->project->readMapGroups(); + sortMapList(); +} + +void MainWindow::sortMapList() { Project *project = editor->project; QIcon mapFolderIcon; @@ -424,37 +510,93 @@ void MainWindow::populateMapList() { QIcon folderIcon; folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off); - folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On); + //folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On); - mapIcon = new QIcon; - mapIcon->addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off); - mapIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal, QIcon::On); + ui->mapList->setUpdatesEnabled(false); + mapListModel->clear(); + mapGroupItemsList->clear(); + QStandardItem *root = mapListModel->invisibleRootItem(); - mapEditedIcon = new QIcon; - mapEditedIcon->addFile(QStringLiteral(":/icons/map_edited.ico"), QSize(), QIcon::Normal, QIcon::Off); - mapEditedIcon->addFile(QStringLiteral(":/icons/map_opened.ico"), QSize(), QIcon::Normal , QIcon::On); - - mapListModel = new QStandardItemModel; - mapGroupsModel = new QList; - - project->readMapGroups(); - for (int i = 0; i < project->groupNames->length(); i++) { - QString group_name = project->groupNames->value(i); - QStandardItem *group = new QStandardItem; - group->setText(group_name); - group->setIcon(mapFolderIcon); - group->setEditable(false); - group->setData(group_name, Qt::UserRole); - group->setData("map_group", MapListUserRoles::TypeRole); - group->setData(i, MapListUserRoles::GroupRole); - mapListModel->appendRow(group); - mapGroupsModel->append(group); - QStringList names = project->groupedMapNames.value(i); - for (int j = 0; j < names.length(); j++) { - QString map_name = names.value(j); - QStandardItem *map = createMapItem(map_name, i, j); - group->appendRow(map); - mapListIndexes.insert(map_name, map->index()); + switch (mapSortOrder) + { + case MapSortOrder::Group: + for (int i = 0; i < project->groupNames->length(); i++) { + QString group_name = project->groupNames->value(i); + QStandardItem *group = new QStandardItem; + group->setText(group_name); + group->setIcon(mapFolderIcon); + group->setEditable(false); + group->setData(group_name, Qt::UserRole); + group->setData("map_group", MapListUserRoles::TypeRole); + group->setData(i, MapListUserRoles::GroupRole); + root->appendRow(group); + mapGroupItemsList->append(group); + QStringList names = project->groupedMapNames.value(i); + for (int j = 0; j < names.length(); j++) { + QString map_name = names.value(j); + QStandardItem *map = createMapItem(map_name, i, j); + group->appendRow(map); + mapListIndexes.insert(map_name, map->index()); + } + } + break; + case MapSortOrder::Name: + { + QMap mapsecToGroupNum; + for (int i = 0; i < project->regionMapSections->length(); i++) { + QString mapsec_name = project->regionMapSections->value(i); + QStandardItem *mapsec = new QStandardItem; + mapsec->setText(mapsec_name); + mapsec->setIcon(folderIcon); + mapsec->setEditable(false); + mapsec->setData(mapsec_name, Qt::UserRole); + mapsec->setData("map_sec", MapListUserRoles::TypeRole); + mapsec->setData(i, MapListUserRoles::GroupRole); + root->appendRow(mapsec); + mapGroupItemsList->append(mapsec); + mapsecToGroupNum.insert(mapsec_name, i); + } + for (int i = 0; i < project->groupNames->length(); i++) { + QStringList names = project->groupedMapNames.value(i); + for (int j = 0; j < names.length(); j++) { + QString map_name = names.value(j); + QStandardItem *map = createMapItem(map_name, i, j); + QString location = project->readMapLocation(map_name); + QStandardItem *mapsecItem = mapGroupItemsList->at(mapsecToGroupNum[location]); + mapsecItem->setIcon(mapFolderIcon); + mapsecItem->appendRow(map); + mapListIndexes.insert(map_name, map->index()); + } + } + break; + } + case MapSortOrder::Layout: + { + for (int i = 0; i < project->mapLayoutsTable.length(); i++) { + QString layoutName = project->mapLayoutsTable.value(i); + QStandardItem *layout = new QStandardItem; + layout->setText(layoutName); + layout->setIcon(folderIcon); + layout->setEditable(false); + layout->setData(layoutName, Qt::UserRole); + layout->setData("map_layout", MapListUserRoles::TypeRole); + layout->setData(i, MapListUserRoles::GroupRole); + root->appendRow(layout); + mapGroupItemsList->append(layout); + } + for (int i = 0; i < project->groupNames->length(); i++) { + QStringList names = project->groupedMapNames.value(i); + for (int j = 0; j < names.length(); j++) { + QString map_name = names.value(j); + QStandardItem *map = createMapItem(map_name, i, j); + QString layoutId = project->readMapLayoutId(map_name); + QStandardItem *layoutItem = mapGroupItemsList->at(layoutId.toInt() - 1); + layoutItem->setIcon(mapFolderIcon); + layoutItem->appendRow(map); + mapListIndexes.insert(map_name, map->index()); + } + } + break; } } @@ -463,7 +605,6 @@ void MainWindow::populateMapList() { connect(ui->mapList, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onOpenMapListContextMenu(const QPoint &))); - ui->mapList->setModel(mapListModel); ui->mapList->setUpdatesEnabled(true); ui->mapList->expandToDepth(0); ui->mapList->repaint(); @@ -481,7 +622,7 @@ QStandardItem* MainWindow::createMapItem(QString mapName, int groupNum, int inGr void MainWindow::onOpenMapListContextMenu(const QPoint &point) { - QModelIndex index = ui->mapList->indexAt(point); + QModelIndex index = mapListProxyModel->mapToSource(ui->mapList->indexAt(point)); if (!index.isValid()) { return; } @@ -507,7 +648,7 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point) void MainWindow::onAddNewMapToGroupClick(QAction* triggeredAction) { int groupNum = triggeredAction->data().toInt(); - QStandardItem* groupItem = mapGroupsModel->at(groupNum); + QStandardItem* groupItem = mapGroupItemsList->at(groupNum); QString newMapName = editor->project->getNewMapName(); Map* newMap = editor->project->addNewMapToGroup(newMapName, groupNum); diff --git a/src/project.cpp b/src/project.cpp index f1168123..7b298d5c 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -189,6 +189,36 @@ void Project::readMapHeader(Map* map) { map->battle_scene = header->value(12); } +QString Project::readMapLayoutId(QString map_name) { + if (map_cache->contains(map_name)) { + return map_cache->value(map_name)->layout_id; + } + + ParseUtil *parser = new ParseUtil; + + QString header_text = readTextFile(root + "/data/maps/" + map_name + "/header.inc"); + if (header_text.isNull()) { + return QString::null; + } + QStringList *header = getLabelValues(parser->parseAsm(header_text), map_name); + return header->value(5); +} + +QString Project::readMapLocation(QString map_name) { + if (map_cache->contains(map_name)) { + return map_cache->value(map_name)->location; + } + + ParseUtil *parser = new ParseUtil; + + QString header_text = readTextFile(root + "/data/maps/" + map_name + "/header.inc"); + if (header_text.isNull()) { + return QString::null; + } + QStringList *header = getLabelValues(parser->parseAsm(header_text), map_name); + return header->value(6); +} + void Project::setNewMapHeader(Map* map, int mapIndex) { map->layout_label = QString("%1_Layout").arg(map->name); map->events_label = QString("%1_MapEvents").arg(map->name);;