Merge pull request #41 from Diegoisawesome/master

Add map filtering and sorting
This commit is contained in:
Marcus Huderle 2018-10-05 17:41:49 -05:00 committed by GitHub
commit cbeb79b7f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 480 additions and 93 deletions

View file

@ -10,12 +10,6 @@
<height>747</height> <height>747</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle"> <property name="windowTitle">
<string>porymap</string> <string>porymap</string>
</property> </property>
@ -26,6 +20,107 @@
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<widget class="QWidget" name="mapListContainer" native="true">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item>
<widget class="QToolButton" name="toolButton_MapSortOrder">
<property name="enabled">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../resources/images.qrc">
<normaloff>:/icons/sort_alphabet.ico</normaloff>:/icons/sort_alphabet.ico</iconset>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonIconOnly</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>12</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="lineEdit_filterBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string/>
</property>
<property name="placeholderText">
<string>Filter maps...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeView" name="mapList"> <widget class="QTreeView" name="mapList">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@ -49,6 +144,9 @@
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
</widget> </widget>
</item>
</layout>
</widget>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
@ -378,8 +476,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>469</width> <width>481</width>
<height>608</height> <height>606</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_8"> <layout class="QGridLayout" name="gridLayout_8">
@ -687,8 +785,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>324</width> <width>300</width>
<height>77</height> <height>70</height>
</rect> </rect>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_7"> <layout class="QHBoxLayout" name="horizontalLayout_7">
@ -799,8 +897,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>307</width> <width>304</width>
<height>387</height> <height>372</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1116,8 +1214,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>381</width> <width>385</width>
<height>657</height> <height>655</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_7"> <layout class="QGridLayout" name="gridLayout_7">
@ -1294,8 +1392,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>432</width> <width>428</width>
<height>596</height> <height>586</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -1914,8 +2012,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>826</width> <width>829</width>
<height>557</height> <height>552</height>
</rect> </rect>
</property> </property>
<layout class="QGridLayout" name="gridLayout_14"> <layout class="QGridLayout" name="gridLayout_14">
@ -2087,7 +2185,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1117</width> <width>1117</width>
<height>21</height> <height>20</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
@ -2275,6 +2373,45 @@
<string>Tileset Editor</string> <string>Tileset Editor</string>
</property> </property>
</action> </action>
<action name="actionSort_by_Name">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../resources/images.qrc">
<normaloff>:/icons/sort_alphabet.ico</normaloff>:/icons/sort_alphabet.ico</iconset>
</property>
<property name="text">
<string>Sort by &amp;Name</string>
</property>
</action>
<action name="actionSort_by_Group">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../resources/images.qrc">
<normaloff>:/icons/sort_number.ico</normaloff>:/icons/sort_number.ico</iconset>
</property>
<property name="text">
<string>Sort by &amp;Group</string>
</property>
<property name="toolTip">
<string>Sort by Group</string>
</property>
</action>
<action name="actionSort_by_Layout">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../resources/images.qrc">
<normaloff>:/icons/sort_map.ico</normaloff>:/icons/sort_map.ico</iconset>
</property>
<property name="text">
<string>Sort by &amp;Layout</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

View file

@ -0,0 +1,17 @@
#ifndef FILTERCHILDRENPROXYMODEL_H
#define FILTERCHILDRENPROXYMODEL_H
#include <QSortFilterProxyModel>
class FilterChildrenProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit FilterChildrenProxyModel(QObject *parent = nullptr);
protected:
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const;
};
#endif // FILTERCHILDRENPROXYMODEL_H

View file

@ -13,6 +13,7 @@
#include "map.h" #include "map.h"
#include "editor.h" #include "editor.h"
#include "tileseteditor.h" #include "tileseteditor.h"
#include "filterchildrenproxymodel.h"
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
@ -128,18 +129,32 @@ private slots:
void on_actionTileset_Editor_triggered(); void on_actionTileset_Editor_triggered();
void mapSortOrder_changed(QAction *action);
void on_lineEdit_filterBox_textChanged(const QString &arg1);
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
TilesetEditor *tilesetEditor = nullptr; TilesetEditor *tilesetEditor = nullptr;
FilterChildrenProxyModel *mapListProxyModel;
QStandardItemModel *mapListModel; QStandardItemModel *mapListModel;
QList<QStandardItem*> *mapGroupsModel; QList<QStandardItem*> *mapGroupItemsList;
QMap<QString, QModelIndex> mapListIndexes; QMap<QString, QModelIndex> mapListIndexes;
Editor *editor = nullptr; Editor *editor = nullptr;
QIcon* mapIcon; QIcon* mapIcon;
QIcon* mapEditedIcon;
enum MapSortOrder {
Group = 0,
Name = 1,
Layout = 2,
} mapSortOrder;
void setMap(QString, bool scrollTreeView = false); void setMap(QString, bool scrollTreeView = false);
void redrawMapScene(); void redrawMapScene();
void loadDataStructures(); void loadDataStructures();
void populateMapList(); void populateMapList();
void sortMapList();
QString getExistingDirectory(QString); QString getExistingDirectory(QString);
void openProject(QString dir); void openProject(QString dir);
QString getDefaultMap(); QString getDefaultMap();
@ -156,14 +171,18 @@ private:
void initExtraShortcuts(); void initExtraShortcuts();
void initExtraSignals(); void initExtraSignals();
void initEditor(); void initEditor();
void initMiscHeapObjects();
void initMapSortOrder();
void loadUserSettings(); void loadUserSettings();
void openRecentProject(); void openRecentProject();
void updateTilesetEditor(); void updateTilesetEditor();
bool isProjectOpen();
}; };
enum MapListUserRoles { enum MapListUserRoles {
GroupRole = Qt::UserRole + 1, // Used to hold the map group number. 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 #endif // MAINWINDOW_H

View file

@ -64,6 +64,9 @@ public:
QString getNewMapName(); QString getNewMapName();
QString getProjectTitle(); QString getProjectTitle();
QString readMapLayoutId(QString map_name);
QString readMapLocation(QString map_name);
QList<QStringList>* getLabelMacros(QList<QStringList>*, QString); QList<QStringList>* getLabelMacros(QList<QStringList>*, QString);
QStringList* getLabelValues(QList<QStringList>*, QString); QStringList* getLabelValues(QList<QStringList>*, QString);
void readMapHeader(Map*); void readMapHeader(Map*);

View file

@ -17,6 +17,7 @@ ICON = resources/icons/porymap-icon-1.ico
SOURCES += src/core/block.cpp \ SOURCES += src/core/block.cpp \
src/core/blockdata.cpp \ src/core/blockdata.cpp \
src/core/event.cpp \ src/core/event.cpp \
src/core/filterchildrenproxymodel.cpp \
src/core/heallocation.cpp \ src/core/heallocation.cpp \
src/core/historyitem.cpp \ src/core/historyitem.cpp \
src/core/map.cpp \ src/core/map.cpp \
@ -54,6 +55,7 @@ SOURCES += src/core/block.cpp \
HEADERS += include/core/block.h \ HEADERS += include/core/block.h \
include/core/blockdata.h \ include/core/blockdata.h \
include/core/event.h \ include/core/event.h \
include/core/filterchildrenproxymodel.h \
include/core/heallocation.h \ include/core/heallocation.h \
include/core/history.h \ include/core/history.h \
include/core/historyitem.h \ include/core/historyitem.h \

View file

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -3,9 +3,7 @@
<file>icons/folder.ico</file> <file>icons/folder.ico</file>
<file>icons/folder_closed.ico</file> <file>icons/folder_closed.ico</file>
<file>icons/folder_closed_map.ico</file> <file>icons/folder_closed_map.ico</file>
<file>icons/folder_image.ico</file>
<file>icons/folder_map.ico</file> <file>icons/folder_map.ico</file>
<file>icons/image.ico</file>
<file>icons/map.ico</file> <file>icons/map.ico</file>
<file>icons/cursor.ico</file> <file>icons/cursor.ico</file>
<file>icons/fill_color.ico</file> <file>icons/fill_color.ico</file>
@ -23,5 +21,12 @@
<file>icons/shift.ico</file> <file>icons/shift.ico</file>
<file>icons/shift_cursor.ico</file> <file>icons/shift_cursor.ico</file>
<file>icons/porymap-icon-1.ico</file> <file>icons/porymap-icon-1.ico</file>
<file>icons/folder_map_edited.ico</file>
<file>icons/folder_map_opened.ico</file>
<file>icons/map_edited.ico</file>
<file>icons/map_opened.ico</file>
<file>icons/sort_alphabet.ico</file>
<file>icons/sort_map.ico</file>
<file>icons/sort_number.ico</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -0,0 +1,35 @@
#include "filterchildrenproxymodel.h"
FilterChildrenProxyModel::FilterChildrenProxyModel(QObject *parent) :
QSortFilterProxyModel(parent)
{
}
bool FilterChildrenProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
// custom behaviour :
if(filterRegExp().isEmpty() == false)
{
// get source-model index for current row
QModelIndex source_index = sourceModel()->index(source_row, this->filterKeyColumn(), source_parent) ;
if(source_index.isValid())
{
// if any of children matches the filter, then current index matches the filter as well
int i, nb = sourceModel()->rowCount(source_index);
for (i = 0; i < nb; ++i)
{
if (filterAcceptsRow(i, source_index))
{
return true;
}
}
// check current index itself
QString key = sourceModel()->data(source_index, filterRole()).toString();
QString parentKey = sourceModel()->data(source_parent, filterRole()).toString();
return key.contains(filterRegExp()) || parentKey.contains(filterRegExp());
}
}
// parent call for initial behaviour
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}

View file

@ -39,6 +39,8 @@ MainWindow::MainWindow(QWidget *parent) :
this->initExtraSignals(); this->initExtraSignals();
this->initExtraShortcuts(); this->initExtraShortcuts();
this->initEditor(); this->initEditor();
this->initMiscHeapObjects();
this->initMapSortOrder();
this->openRecentProject(); this->openRecentProject();
on_toolButton_Paint_clicked(); on_toolButton_Paint_clicked();
@ -50,7 +52,7 @@ MainWindow::~MainWindow()
} }
void MainWindow::initExtraShortcuts() { void MainWindow::initExtraShortcuts() {
new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo())); new QShortcut(QKeySequence("Ctrl+Shift+Z"), this, SLOT(redo()));
new QShortcut(QKeySequence("Ctrl+0"), this, SLOT(resetMapViewScale())); new QShortcut(QKeySequence("Ctrl+0"), this, SLOT(resetMapViewScale()));
ui->actionZoom_In->setShortcuts({QKeySequence("Ctrl++"), QKeySequence("Ctrl+=")}); ui->actionZoom_In->setShortcuts({QKeySequence("Ctrl++"), QKeySequence("Ctrl+=")});
} }
@ -72,12 +74,89 @@ void MainWindow::initEditor() {
this->loadUserSettings(); 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<QStandardItem*>;
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<QAction*> 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<MapSortOrder>(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() { void MainWindow::loadUserSettings() {
QSettings settings; QSettings settings;
bool betterCursors = settings.contains("cursor_mode") && settings.value("cursor_mode") != "0"; bool betterCursors = settings.contains("cursor_mode") && settings.value("cursor_mode") != "0";
ui->actionBetter_Cursors->setChecked(betterCursors); ui->actionBetter_Cursors->setChecked(betterCursors);
this->editor->settings->betterCursors = betterCursors; this->editor->settings->betterCursors = betterCursors;
if (!settings.contains("map_sort_order"))
{
settings.setValue("map_sort_order", 0);
}
mapSortOrder = static_cast<MapSortOrder>(settings.value("map_sort_order").toInt());
} }
void MainWindow::openRecentProject() { void MainWindow::openRecentProject() {
@ -99,11 +178,7 @@ void MainWindow::openProject(QString dir) {
this->statusBar()->showMessage(QString("Opening project %1").arg(dir)); this->statusBar()->showMessage(QString("Opening project %1").arg(dir));
bool already_open = ( bool already_open = isProjectOpen() && (editor->project->root == dir);
(editor && editor != nullptr)
&& (editor->project && editor->project != nullptr)
&& (editor->project->root == dir)
);
if (!already_open) { if (!already_open) {
editor->project = new Project; editor->project = new Project;
editor->project->root = dir; editor->project->root = dir;
@ -120,6 +195,11 @@ void MainWindow::openProject(QString dir) {
this->statusBar()->showMessage(QString("Opened project %1").arg(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() { QString MainWindow::getDefaultMap() {
if (editor && editor->project) { if (editor && editor->project) {
QList<QStringList> names = editor->project->groupedMapNames; QList<QStringList> names = editor->project->groupedMapNames;
@ -180,15 +260,22 @@ void MainWindow::setMap(QString map_name, bool scrollTreeView) {
if (map_name.isNull()) { if (map_name.isNull()) {
return; return;
} }
if (editor->map != nullptr && !editor->map->name.isNull()) {
ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(editor->map->name)), false);
}
editor->setMap(map_name); editor->setMap(map_name);
redrawMapScene(); redrawMapScene();
displayMapProperties(); displayMapProperties();
if (scrollTreeView) { if (scrollTreeView) {
ui->mapList->setCurrentIndex(mapListIndexes.value(map_name)); // Make sure we clear the filter first so we actually have a scroll target
mapListProxyModel->setFilterRegExp(QString::null);
ui->mapList->setCurrentIndex(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name)));
ui->mapList->scrollTo(ui->mapList->currentIndex(), QAbstractItemView::PositionAtCenter); ui->mapList->scrollTo(ui->mapList->currentIndex(), QAbstractItemView::PositionAtCenter);
} }
ui->mapList->setExpanded(mapListProxyModel->mapFromSource(mapListIndexes.value(map_name)), true);
setWindowTitle(map_name + " - " + editor->project->getProjectTitle()); setWindowTitle(map_name + " - " + editor->project->getProjectTitle());
connect(editor->map, SIGNAL(mapChanged(Map*)), this, SLOT(onMapChanged(Map *))); connect(editor->map, SIGNAL(mapChanged(Map*)), this, SLOT(onMapChanged(Map *)));
@ -412,6 +499,11 @@ void MainWindow::loadDataStructures() {
} }
void MainWindow::populateMapList() { void MainWindow::populateMapList() {
editor->project->readMapGroups();
sortMapList();
}
void MainWindow::sortMapList() {
Project *project = editor->project; Project *project = editor->project;
QIcon mapFolderIcon; QIcon mapFolderIcon;
@ -420,27 +512,16 @@ void MainWindow::populateMapList() {
QIcon folderIcon; QIcon folderIcon;
folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off); folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off);
//folderIcon.addFile(QStringLiteral(":/icons/folder.ico"), QSize(), QIcon::Normal, QIcon::On);
mapIcon = new QIcon; ui->mapList->setUpdatesEnabled(false);
mapIcon->addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off); mapListModel->clear();
mapIcon->addFile(QStringLiteral(":/icons/image.ico"), QSize(), QIcon::Normal, QIcon::On); mapGroupItemsList->clear();
QStandardItem *root = mapListModel->invisibleRootItem();
mapListModel = new QStandardItemModel; switch (mapSortOrder)
mapGroupsModel = new QList<QStandardItem*>; {
case MapSortOrder::Group:
QStandardItem *entry = new QStandardItem;
entry->setText(project->getProjectTitle());
entry->setIcon(folderIcon);
entry->setEditable(false);
mapListModel->appendRow(entry);
QStandardItem *maps = new QStandardItem;
maps->setText("maps");
maps->setIcon(folderIcon);
maps->setEditable(false);
entry->appendRow(maps);
project->readMapGroups();
for (int i = 0; i < project->groupNames->length(); i++) { for (int i = 0; i < project->groupNames->length(); i++) {
QString group_name = project->groupNames->value(i); QString group_name = project->groupNames->value(i);
QStandardItem *group = new QStandardItem; QStandardItem *group = new QStandardItem;
@ -450,8 +531,8 @@ void MainWindow::populateMapList() {
group->setData(group_name, Qt::UserRole); group->setData(group_name, Qt::UserRole);
group->setData("map_group", MapListUserRoles::TypeRole); group->setData("map_group", MapListUserRoles::TypeRole);
group->setData(i, MapListUserRoles::GroupRole); group->setData(i, MapListUserRoles::GroupRole);
maps->appendRow(group); root->appendRow(group);
mapGroupsModel->append(group); mapGroupItemsList->append(group);
QStringList names = project->groupedMapNames.value(i); QStringList names = project->groupedMapNames.value(i);
for (int j = 0; j < names.length(); j++) { for (int j = 0; j < names.length(); j++) {
QString map_name = names.value(j); QString map_name = names.value(j);
@ -460,15 +541,74 @@ void MainWindow::populateMapList() {
mapListIndexes.insert(map_name, map->index()); mapListIndexes.insert(map_name, map->index());
} }
} }
break;
case MapSortOrder::Name:
{
QMap<QString, int> 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;
}
}
// Right-clicking on items in the map list tree view brings up a context menu. // Right-clicking on items in the map list tree view brings up a context menu.
ui->mapList->setContextMenuPolicy(Qt::CustomContextMenu); ui->mapList->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->mapList, SIGNAL(customContextMenuRequested(const QPoint &)), connect(ui->mapList, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(onOpenMapListContextMenu(const QPoint &))); this, SLOT(onOpenMapListContextMenu(const QPoint &)));
ui->mapList->setModel(mapListModel);
ui->mapList->setUpdatesEnabled(true); ui->mapList->setUpdatesEnabled(true);
ui->mapList->expandToDepth(2); ui->mapList->expandToDepth(0);
ui->mapList->repaint(); ui->mapList->repaint();
} }
@ -484,7 +624,7 @@ QStandardItem* MainWindow::createMapItem(QString mapName, int groupNum, int inGr
void MainWindow::onOpenMapListContextMenu(const QPoint &point) void MainWindow::onOpenMapListContextMenu(const QPoint &point)
{ {
QModelIndex index = ui->mapList->indexAt(point); QModelIndex index = mapListProxyModel->mapToSource(ui->mapList->indexAt(point));
if (!index.isValid()) { if (!index.isValid()) {
return; return;
} }
@ -510,7 +650,7 @@ void MainWindow::onOpenMapListContextMenu(const QPoint &point)
void MainWindow::onAddNewMapToGroupClick(QAction* triggeredAction) void MainWindow::onAddNewMapToGroupClick(QAction* triggeredAction)
{ {
int groupNum = triggeredAction->data().toInt(); int groupNum = triggeredAction->data().toInt();
QStandardItem* groupItem = mapGroupsModel->at(groupNum); QStandardItem* groupItem = mapGroupItemsList->at(groupNum);
QString newMapName = editor->project->getNewMapName(); QString newMapName = editor->project->getNewMapName();
Map* newMap = editor->project->addNewMapToGroup(newMapName, groupNum); Map* newMap = editor->project->addNewMapToGroup(newMapName, groupNum);
@ -571,10 +711,9 @@ void MainWindow::markEdited(QModelIndex index) {
QString map_name = data.toString(); QString map_name = data.toString();
if (editor->project) { if (editor->project) {
if (editor->project->map_cache->contains(map_name)) { if (editor->project->map_cache->contains(map_name)) {
// Just mark anything that's been opened for now. if (editor->project->map_cache->value(map_name)->hasUnsavedChanges()) {
// TODO if (project->getMap()->saved) mapListModel->itemFromIndex(mapListIndexes.value(map_name))->setIcon(*mapEditedIcon);
//ui->mapList->setExpanded(index, true); }
ui->mapList->setExpanded(index, editor->project->map_cache->value(map_name)->hasUnsavedChanges());
} }
} }
} }

View file

@ -189,6 +189,36 @@ void Project::readMapHeader(Map* map) {
map->battle_scene = header->value(12); 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) { void Project::setNewMapHeader(Map* map, int mapIndex) {
map->layout_label = QString("%1_Layout").arg(map->name); map->layout_label = QString("%1_Layout").arg(map->name);
map->events_label = QString("%1_MapEvents").arg(map->name);; map->events_label = QString("%1_MapEvents").arg(map->name);;
@ -961,9 +991,9 @@ void Project::loadTilesetMetatiles(Tileset* tileset) {
int num_metatiles = tileset->metatiles->count(); int num_metatiles = tileset->metatiles->count();
int num_metatileAttrs = data.length() / 2; int num_metatileAttrs = data.length() / 2;
if (num_metatiles != num_metatileAttrs) { if (num_metatiles != num_metatileAttrs) {
qDebug() << QString("Metatile count %1 does not match metatile attribute count %2").arg(num_metatiles).arg(num_metatileAttrs); qDebug() << QString("Metatile count %1 does not match metatile attribute count %2 in %3").arg(num_metatiles).arg(num_metatileAttrs).arg(tileset->name);
if (num_metatiles > num_metatileAttrs) if (num_metatileAttrs > num_metatiles)
num_metatiles = num_metatileAttrs; num_metatileAttrs = num_metatiles;
} }
for (int i = 0; i < num_metatileAttrs; i++) { for (int i = 0; i < num_metatileAttrs; i++) {
int value = (static_cast<unsigned char>(data.at(i * 2 + 1)) << 8) | static_cast<unsigned char>(data.at(i * 2)); int value = (static_cast<unsigned char>(data.at(i * 2 + 1)) << 8) | static_cast<unsigned char>(data.at(i * 2));